summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-05 14:50:51 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-05 14:50:51 -0700
commit41844e36206be90cd4d962ea49b0abc3612a99d0 (patch)
treece0b3a3403bc6abdb28f52779d0d7b57a51a5c86
parent5691f0e9a3e7855832d5fd094801bf600347c2d0 (diff)
parentfc1e2c8ea85e109acf09e74789e9b852f6eed251 (diff)
Merge tag 'staging-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging and IIO updates from Greg KH: "Here is the big staging and IIO driver pull request for 4.9-rc1. There are a lot of patches in here, the majority due to the drivers/staging/greybus/ subsystem being merged in with full development history that went back a few years, in order to preserve the work that those developers did over time. Lots and lots of tiny cleanups happened in the tree as well, due to the Outreachy application process and lots of other developers showing up for the first time to clean code up. Along with those changes, we deleted a wireless driver, and added a raspberrypi driver (currently marked broken), and lots of new iio drivers. Overall the tree still shrunk with more lines removed than added, about 10 thousand lines removed in total. Full details are in the very long shortlog below. All of this has been in the linux-next tree with no issues. There will be some merge problems with other subsystem trees, but those are all minor problems and shouldn't be hard to work out when they happen (MAINTAINERS and some lustre build problems with the IB tree)" And furter from me asking for clarification about greybus: "Right now there is a phone from Motorola shipping with this code (a slightly older version, but the same tree), so even though Ara is not alive in the same form, the functionality is happening. We are working with the developers of that phone to merge the newer stuff in with their fork so they can use the upstream version in future versions of their phone product line. Toshiba has at least one chip shipping in their catalog that needs/uses this protocol over a Unipro link, and rumor has it that there might be more in the future. There are also other users of the greybus protocols, there is a talk next week at ELC that shows how it is being used across a network connection to control a device, and previous ELC talks have showed the protocol stack being used over USB to drive embedded Linux boards. I've also talked to some people who are starting to work to add a host controller driver to control arduinos as the greybus PHY protocols are very useful to control a serial/i2c/spio/whatever device across a random physical link, as it is a way to have a self-describing device be attached to a host without needing manual configuration. So yes, people are using it, and there is still the chance that it will show up in a phone/laptop/tablet/whatever from Google in the future as well, the tech isn't dead, even if the original large phone project happens to be" * tag 'staging-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (3703 commits) Staging: fbtft: Fix bug in fbtft-core staging: rtl8188eu: fix double unlock error in rtw_resume_process() staging:r8188eu: remove GEN_MLME_EXT_HANDLER macro staging:r8188eu: remove GEN_DRV_CMD_HANDLER macro staging:r8188eu: remove GEN_EVT_CODE macro staging:r8188eu: remove GEN_CMD_CODE macro staging:r8188eu: remove pkt_newalloc member of the recv_buf structure staging:r8188eu: remove rtw_handle_dualmac declaration staging:r8188eu: remove (RGTRY|BSSID)_(OFT|SZ) macros staging:r8188eu: change rtl8188e_process_phy_info function argument type Staging: fsl-mc: Remove blank lines Staging: fsl-mc: Fix unaligned * in block comments Staging: comedi: Align the * in block comments Staging : ks7010 : Fix block comments warninig Staging: vt6655: Remove explicit NULL comparison using Coccinelle staging: rtl8188eu: core: rtw_xmit: Use macros instead of constants staging: rtl8188eu: core: rtw_xmit: Move constant of the right side staging: dgnc: Fix lines longer than 80 characters Staging: dgnc: constify attribute_group structures Staging: most: hdm-dim2: constify attribute_group structures ...
-rw-r--r--.mailmap1
-rw-r--r--Documentation/devicetree/bindings/i2c/trivial-devices.txt2
-rw-r--r--Documentation/devicetree/bindings/iio/accel/dmard06.txt19
-rw-r--r--Documentation/devicetree/bindings/iio/accel/kionix,kxsd9.txt22
-rw-r--r--Documentation/devicetree/bindings/iio/adc/mt6577_auxadc.txt29
-rw-r--r--Documentation/devicetree/bindings/iio/adc/ti-adc12138.txt37
-rw-r--r--Documentation/devicetree/bindings/iio/adc/ti-adc161s626.txt16
-rw-r--r--Documentation/devicetree/bindings/iio/chemical/atlas,orp-sm.txt22
-rw-r--r--Documentation/devicetree/bindings/iio/magnetometer/ak8974.txt29
-rw-r--r--Documentation/devicetree/bindings/iio/pressure/zpa2326.txt31
-rw-r--r--Documentation/devicetree/bindings/iio/proximity/sx9500.txt24
-rw-r--r--Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt21
-rw-r--r--Documentation/devicetree/bindings/soc/mediatek/auxadc.txt21
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--Documentation/driver-model/devres.txt4
-rw-r--r--MAINTAINERS96
-rw-r--r--drivers/android/binder.c7
-rw-r--r--drivers/dma-buf/Kconfig13
-rw-r--r--drivers/dma-buf/Makefile1
-rw-r--r--drivers/dma-buf/sw_sync.c (renamed from drivers/staging/android/sw_sync.c)37
-rw-r--r--drivers/dma-buf/sync_debug.c (renamed from drivers/staging/android/sync_debug.c)2
-rw-r--r--drivers/dma-buf/sync_debug.h (renamed from drivers/staging/android/sync_debug.h)2
-rw-r--r--drivers/dma-buf/sync_trace.h (renamed from drivers/staging/android/trace/sync.h)6
-rw-r--r--drivers/iio/accel/Kconfig56
-rw-r--r--drivers/iio/accel/Makefile5
-rw-r--r--drivers/iio/accel/bma180.c9
-rw-r--r--drivers/iio/accel/dmard06.c241
-rw-r--r--drivers/iio/accel/dmard09.c157
-rw-r--r--drivers/iio/accel/kxcjk-1013.c1
-rw-r--r--drivers/iio/accel/kxsd9-i2c.c64
-rw-r--r--drivers/iio/accel/kxsd9-spi.c56
-rw-r--r--drivers/iio/accel/kxsd9.c435
-rw-r--r--drivers/iio/accel/kxsd9.h12
-rw-r--r--drivers/iio/accel/mc3230.c211
-rw-r--r--drivers/iio/accel/mma7660.c1
-rw-r--r--drivers/iio/accel/mxc6255.c4
-rw-r--r--drivers/iio/accel/ssp_accel_sensor.c2
-rw-r--r--drivers/iio/adc/Kconfig61
-rw-r--r--drivers/iio/adc/Makefile5
-rw-r--r--drivers/iio/adc/ad7266.c4
-rw-r--r--drivers/iio/adc/ad7298.c20
-rw-r--r--drivers/iio/adc/ad7793.c10
-rw-r--r--drivers/iio/adc/at91_adc.c13
-rw-r--r--drivers/iio/adc/ina2xx-adc.c5
-rw-r--r--drivers/iio/adc/ltc2485.c148
-rw-r--r--drivers/iio/adc/men_z188_adc.c2
-rw-r--r--drivers/iio/adc/mt6577_auxadc.c291
-rw-r--r--drivers/iio/adc/nau7802.c2
-rw-r--r--drivers/iio/adc/stx104.c (renamed from drivers/iio/dac/stx104.c)153
-rw-r--r--drivers/iio/adc/ti-adc12138.c552
-rw-r--r--drivers/iio/adc/ti-adc161s626.c248
-rw-r--r--drivers/iio/adc/ti-ads1015.c2
-rw-r--r--drivers/iio/adc/ti-ads8688.c4
-rw-r--r--drivers/iio/buffer/industrialio-buffer-cb.c24
-rw-r--r--drivers/iio/buffer/industrialio-triggered-buffer.c42
-rw-r--r--drivers/iio/chemical/Kconfig1
-rw-r--r--drivers/iio/chemical/atlas-ph-sensor.c81
-rw-r--r--drivers/iio/chemical/vz89x.c201
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-trigger.c29
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_buffer.c2
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_core.c53
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_trigger.c4
-rw-r--r--drivers/iio/dac/Kconfig29
-rw-r--r--drivers/iio/dac/Makefile3
-rw-r--r--drivers/iio/dac/ad5755.c2
-rw-r--r--drivers/iio/dac/ad8801.c239
-rw-r--r--drivers/iio/dac/cio-dac.c144
-rw-r--r--drivers/iio/gyro/ssp_gyro_sensor.c2
-rw-r--r--drivers/iio/humidity/Kconfig8
-rw-r--r--drivers/iio/industrialio-core.c3
-rw-r--r--drivers/iio/industrialio-event.c8
-rw-r--r--drivers/iio/industrialio-trigger.c95
-rw-r--r--drivers/iio/light/Kconfig19
-rw-r--r--drivers/iio/light/Makefile1
-rw-r--r--drivers/iio/light/si1145.c1404
-rw-r--r--drivers/iio/light/us5182d.c2
-rw-r--r--drivers/iio/light/vcnl4000.c72
-rw-r--r--drivers/iio/magnetometer/Kconfig16
-rw-r--r--drivers/iio/magnetometer/Makefile1
-rw-r--r--drivers/iio/magnetometer/ak8974.c860
-rw-r--r--drivers/iio/magnetometer/mag3110.c23
-rw-r--r--drivers/iio/pressure/Kconfig22
-rw-r--r--drivers/iio/pressure/Makefile3
-rw-r--r--drivers/iio/pressure/ms5611_core.c6
-rw-r--r--drivers/iio/pressure/zpa2326.c1735
-rw-r--r--drivers/iio/pressure/zpa2326.h89
-rw-r--r--drivers/iio/pressure/zpa2326_i2c.c99
-rw-r--r--drivers/iio/pressure/zpa2326_spi.c103
-rw-r--r--drivers/iio/proximity/sx9500.c9
-rw-r--r--drivers/iio/temperature/Kconfig16
-rw-r--r--drivers/iio/temperature/Makefile1
-rw-r--r--drivers/iio/temperature/maxim_thermocouple.c281
-rw-r--r--drivers/staging/Kconfig6
-rw-r--r--drivers/staging/Makefile3
-rw-r--r--drivers/staging/android/Kconfig13
-rw-r--r--drivers/staging/android/Makefile1
-rw-r--r--drivers/staging/android/ion/Kconfig12
-rw-r--r--drivers/staging/android/ion/Makefile4
-rw-r--r--drivers/staging/android/ion/devicetree.txt51
-rw-r--r--drivers/staging/android/ion/hisilicon/hi6220_ion.c195
-rw-r--r--drivers/staging/android/ion/ion-ioctl.c177
-rw-r--r--drivers/staging/android/ion/ion.c388
-rw-r--r--drivers/staging/android/ion/ion.h41
-rw-r--r--drivers/staging/android/ion/ion_carveout_heap.c43
-rw-r--r--drivers/staging/android/ion/ion_chunk_heap.c29
-rw-r--r--drivers/staging/android/ion/ion_cma_heap.c36
-rw-r--r--drivers/staging/android/ion/ion_dummy_driver.c10
-rw-r--r--drivers/staging/android/ion/ion_heap.c10
-rw-r--r--drivers/staging/android/ion/ion_of.c185
-rw-r--r--drivers/staging/android/ion/ion_of.h37
-rw-r--r--drivers/staging/android/ion/ion_page_pool.c12
-rw-r--r--drivers/staging/android/ion/ion_priv.h131
-rw-r--r--drivers/staging/android/ion/ion_system_heap.c239
-rw-r--r--drivers/staging/android/ion/ion_test.c23
-rw-r--r--drivers/staging/android/lowmemorykiller.c13
-rw-r--r--drivers/staging/android/uapi/ion.h69
-rw-r--r--drivers/staging/comedi/comedi_fops.c8
-rw-r--r--drivers/staging/comedi/drivers.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c141
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3501.c85
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c3
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas64.c577
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c73
-rw-r--r--drivers/staging/comedi/drivers/dt2811.c4
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c4
-rw-r--r--drivers/staging/comedi/drivers/gsc_hpdi.c2
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.c15
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.h290
-rw-r--r--drivers/staging/comedi/drivers/ni_670x.c62
-rw-r--r--drivers/staging/comedi/drivers/ni_at_a2150.c273
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c176
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio16d.c106
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c58
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c67
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c171
-rw-r--r--drivers/staging/comedi/drivers/ni_pcimio.c216
-rw-r--r--drivers/staging/comedi/drivers/ni_usb6501.c4
-rw-r--r--drivers/staging/comedi/drivers/plx9080.h95
-rw-r--r--drivers/staging/comedi/drivers/s626.c287
-rw-r--r--drivers/staging/comedi/drivers/s626.h4
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c4
-rw-r--r--drivers/staging/comedi/drivers/vmk80xx.c12
-rw-r--r--drivers/staging/dgnc/dgnc_cls.c647
-rw-r--r--drivers/staging/dgnc/dgnc_driver.c226
-rw-r--r--drivers/staging/dgnc/dgnc_driver.h19
-rw-r--r--drivers/staging/dgnc/dgnc_neo.c130
-rw-r--r--drivers/staging/dgnc/dgnc_sysfs.c185
-rw-r--r--drivers/staging/dgnc/dgnc_tty.c180
-rw-r--r--drivers/staging/dgnc/dgnc_tty.h3
-rw-r--r--drivers/staging/emxx_udc/emxx_udc.c20
-rw-r--r--drivers/staging/emxx_udc/emxx_udc.h2
-rw-r--r--drivers/staging/fbtft/fb_agm1264k-fl.c4
-rw-r--r--drivers/staging/fbtft/fb_ili9320.c4
-rw-r--r--drivers/staging/fbtft/fb_ili9325.c10
-rw-r--r--drivers/staging/fbtft/fb_pcd8544.c4
-rw-r--r--drivers/staging/fbtft/fb_s6d02a1.c14
-rw-r--r--drivers/staging/fbtft/fb_s6d1121.c8
-rw-r--r--drivers/staging/fbtft/fb_ssd1289.c10
-rw-r--r--drivers/staging/fbtft/fb_ssd1306.c23
-rw-r--r--drivers/staging/fbtft/fb_ssd1331.c40
-rw-r--r--drivers/staging/fbtft/fb_ssd1351.c14
-rw-r--r--drivers/staging/fbtft/fb_st7735r.c43
-rw-r--r--drivers/staging/fbtft/fb_tls8204.c59
-rw-r--r--drivers/staging/fbtft/fb_uc1611.c12
-rw-r--r--drivers/staging/fbtft/fb_watterott.c8
-rw-r--r--drivers/staging/fbtft/fbtft-bus.c3
-rw-r--r--drivers/staging/fbtft/fbtft-core.c30
-rw-r--r--drivers/staging/fbtft/fbtft.h26
-rw-r--r--drivers/staging/fbtft/fbtft_device.c36
-rw-r--r--drivers/staging/fsl-mc/bus/Makefile7
-rw-r--r--drivers/staging/fsl-mc/bus/dpbp.c60
-rw-r--r--drivers/staging/fsl-mc/bus/dpmcp.c2
-rw-r--r--drivers/staging/fsl-mc/bus/dpmng-cmd.h15
-rw-r--r--drivers/staging/fsl-mc/bus/dpmng.c61
-rw-r--r--drivers/staging/fsl-mc/bus/dprc-cmd.h15
-rw-r--r--drivers/staging/fsl-mc/bus/dprc-driver.c71
-rw-r--r--drivers/staging/fsl-mc/bus/dprc.c89
-rw-r--r--drivers/staging/fsl-mc/bus/fsl-mc-allocator.c (renamed from drivers/staging/fsl-mc/bus/mc-allocator.c)213
-rw-r--r--drivers/staging/fsl-mc/bus/fsl-mc-bus.c (renamed from drivers/staging/fsl-mc/bus/mc-bus.c)83
-rw-r--r--drivers/staging/fsl-mc/bus/fsl-mc-msi.c (renamed from drivers/staging/fsl-mc/bus/mc-msi.c)8
-rw-r--r--drivers/staging/fsl-mc/bus/fsl-mc-private.h52
-rw-r--r--drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c6
-rw-r--r--drivers/staging/fsl-mc/bus/mc-io.c320
-rw-r--r--drivers/staging/fsl-mc/bus/mc-sys.c155
-rw-r--r--drivers/staging/fsl-mc/include/dpbp-cmd.h60
-rw-r--r--drivers/staging/fsl-mc/include/mc-bus.h (renamed from drivers/staging/fsl-mc/include/mc-private.h)91
-rw-r--r--drivers/staging/fsl-mc/include/mc-sys.h15
-rw-r--r--drivers/staging/fsl-mc/include/mc.h13
-rw-r--r--drivers/staging/fwserial/fwserial.c6
-rw-r--r--drivers/staging/gdm724x/gdm_lte.c2
-rw-r--r--drivers/staging/gdm724x/gdm_mux.h4
-rw-r--r--drivers/staging/gdm724x/gdm_tty.c1
-rw-r--r--drivers/staging/gdm724x/gdm_usb.c8
-rw-r--r--drivers/staging/gdm724x/gdm_usb.h6
-rw-r--r--drivers/staging/gdm724x/hci_packet.h1
-rw-r--r--drivers/staging/gdm724x/netlink_k.c11
-rw-r--r--drivers/staging/greybus/Documentation/firmware/authenticate.c139
-rw-r--r--drivers/staging/greybus/Documentation/firmware/firmware-management333
-rw-r--r--drivers/staging/greybus/Documentation/firmware/firmware.c262
-rw-r--r--drivers/staging/greybus/Documentation/sysfs-bus-greybus275
-rw-r--r--drivers/staging/greybus/Kconfig219
-rw-r--r--drivers/staging/greybus/Makefile96
-rw-r--r--drivers/staging/greybus/arche-apb-ctrl.c522
-rw-r--r--drivers/staging/greybus/arche-platform.c827
-rw-r--r--drivers/staging/greybus/arche_platform.h39
-rw-r--r--drivers/staging/greybus/arpc.h109
-rw-r--r--drivers/staging/greybus/audio_apbridgea.c207
-rw-r--r--drivers/staging/greybus/audio_apbridgea.h156
-rw-r--r--drivers/staging/greybus/audio_codec.c1132
-rw-r--r--drivers/staging/greybus/audio_codec.h283
-rw-r--r--drivers/staging/greybus/audio_gb.c228
-rw-r--r--drivers/staging/greybus/audio_manager.c184
-rw-r--r--drivers/staging/greybus/audio_manager.h83
-rw-r--r--drivers/staging/greybus/audio_manager_module.c258
-rw-r--r--drivers/staging/greybus/audio_manager_private.h28
-rw-r--r--drivers/staging/greybus/audio_manager_sysfs.c102
-rw-r--r--drivers/staging/greybus/audio_module.c482
-rw-r--r--drivers/staging/greybus/audio_topology.c1443
-rw-r--r--drivers/staging/greybus/authentication.c429
-rw-r--r--drivers/staging/greybus/bootrom.c524
-rw-r--r--drivers/staging/greybus/bundle.c253
-rw-r--r--drivers/staging/greybus/bundle.h90
-rw-r--r--drivers/staging/greybus/camera.c1400
-rw-r--r--drivers/staging/greybus/connection.c938
-rw-r--r--drivers/staging/greybus/connection.h129
-rw-r--r--drivers/staging/greybus/control.c635
-rw-r--r--drivers/staging/greybus/control.h65
-rw-r--r--drivers/staging/greybus/core.c361
-rw-r--r--drivers/staging/greybus/debugfs.c31
-rw-r--r--drivers/staging/greybus/es2.c1597
-rw-r--r--drivers/staging/greybus/firmware.h42
-rw-r--r--drivers/staging/greybus/fw-core.c312
-rw-r--r--drivers/staging/greybus/fw-download.c465
-rw-r--r--drivers/staging/greybus/fw-management.c721
-rw-r--r--drivers/staging/greybus/gb-camera.h127
-rw-r--r--drivers/staging/greybus/gbphy.c360
-rw-r--r--drivers/staging/greybus/gbphy.h110
-rw-r--r--drivers/staging/greybus/gpio.c766
-rw-r--r--drivers/staging/greybus/greybus.h154
-rw-r--r--drivers/staging/greybus/greybus_authentication.h120
-rw-r--r--drivers/staging/greybus/greybus_firmware.h120
-rw-r--r--drivers/staging/greybus/greybus_id.h26
-rw-r--r--drivers/staging/greybus/greybus_manifest.h177
-rw-r--r--drivers/staging/greybus/greybus_protocols.h2268
-rw-r--r--drivers/staging/greybus/greybus_trace.h531
-rw-r--r--drivers/staging/greybus/hd.c257
-rw-r--r--drivers/staging/greybus/hd.h90
-rw-r--r--drivers/staging/greybus/hid.c536
-rw-r--r--drivers/staging/greybus/i2c.c343
-rw-r--r--drivers/staging/greybus/interface.c1316
-rw-r--r--drivers/staging/greybus/interface.h88
-rw-r--r--drivers/staging/greybus/light.c1361
-rw-r--r--drivers/staging/greybus/log.c132
-rw-r--r--drivers/staging/greybus/loopback.c1364
-rw-r--r--drivers/staging/greybus/manifest.c535
-rw-r--r--drivers/staging/greybus/manifest.h16
-rw-r--r--drivers/staging/greybus/module.c238
-rw-r--r--drivers/staging/greybus/module.h34
-rw-r--r--drivers/staging/greybus/operation.c1239
-rw-r--r--drivers/staging/greybus/operation.h210
-rw-r--r--drivers/staging/greybus/power_supply.c1141
-rw-r--r--drivers/staging/greybus/pwm.c338
-rw-r--r--drivers/staging/greybus/raw.c381
-rw-r--r--drivers/staging/greybus/sdio.c884
-rw-r--r--drivers/staging/greybus/spi.c79
-rw-r--r--drivers/staging/greybus/spilib.c565
-rw-r--r--drivers/staging/greybus/spilib.h24
-rw-r--r--drivers/staging/greybus/svc.c1486
-rw-r--r--drivers/staging/greybus/svc.h109
-rw-r--r--drivers/staging/greybus/svc_watchdog.c198
-rw-r--r--drivers/staging/greybus/timesync.c1357
-rw-r--r--drivers/staging/greybus/timesync.h45
-rw-r--r--drivers/staging/greybus/timesync_platform.c82
-rw-r--r--drivers/staging/greybus/tools/.gitignore1
-rw-r--r--drivers/staging/greybus/tools/Android.mk10
-rw-r--r--drivers/staging/greybus/tools/Makefile31
-rw-r--r--drivers/staging/greybus/tools/README.loopback198
-rwxr-xr-xdrivers/staging/greybus/tools/lbtest168
-rw-r--r--drivers/staging/greybus/tools/loopback_test.c1000
-rw-r--r--drivers/staging/greybus/uart.c1075
-rw-r--r--drivers/staging/greybus/usb.c247
-rw-r--r--drivers/staging/greybus/vibrator.c249
-rw-r--r--drivers/staging/gs_fpgaboot/gs_fpgaboot.c4
-rw-r--r--drivers/staging/gs_fpgaboot/gs_fpgaboot.h5
-rw-r--r--drivers/staging/gs_fpgaboot/io.h2
-rw-r--r--drivers/staging/i4l/act2000/act2000_isa.c12
-rw-r--r--drivers/staging/i4l/act2000/capi.c12
-rw-r--r--drivers/staging/i4l/act2000/capi.h10
-rw-r--r--drivers/staging/i4l/act2000/module.c5
-rw-r--r--drivers/staging/i4l/icn/icn.c186
-rw-r--r--drivers/staging/i4l/pcbit/capi.c4
-rw-r--r--drivers/staging/i4l/pcbit/drv.c16
-rw-r--r--drivers/staging/i4l/pcbit/edss1.c7
-rw-r--r--drivers/staging/i4l/pcbit/layer2.c8
-rw-r--r--drivers/staging/iio/accel/sca3000.h1
-rw-r--r--drivers/staging/iio/accel/sca3000_core.c244
-rw-r--r--drivers/staging/iio/adc/ad7280a.c2
-rw-r--r--drivers/staging/iio/impedance-analyzer/ad5933.c38
-rw-r--r--drivers/staging/iio/light/isl29018.c138
-rw-r--r--drivers/staging/iio/light/isl29028.c103
-rw-r--r--drivers/staging/iio/light/tsl2583.c2
-rw-r--r--drivers/staging/iio/meter/ade7754.c59
-rw-r--r--drivers/staging/iio/meter/ade7758_ring.c10
-rw-r--r--drivers/staging/iio/meter/ade7854.c40
-rw-r--r--drivers/staging/ks7010/eap_packet.h34
-rw-r--r--drivers/staging/ks7010/ks7010_sdio.c160
-rw-r--r--drivers/staging/ks7010/ks_hostif.c158
-rw-r--r--drivers/staging/ks7010/ks_hostif.h121
-rw-r--r--drivers/staging/ks7010/ks_wlan.h8
-rw-r--r--drivers/staging/ks7010/ks_wlan_ioctl.h6
-rw-r--r--drivers/staging/ks7010/ks_wlan_net.c121
-rw-r--r--drivers/staging/ks7010/michael_mic.c32
-rw-r--r--drivers/staging/ks7010/michael_mic.h7
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs.h6
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h10
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h3
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_private.h21
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lib-lnet.h65
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lib-types.h7
-rw-r--r--drivers/staging/lustre/include/linux/lnet/types.h16
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c16
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h18
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c201
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c5
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h8
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c48
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c207
-rw-r--r--drivers/staging/lustre/lnet/libcfs/debug.c9
-rw-r--r--drivers/staging/lustre/lnet/libcfs/fail.c6
-rw-r--r--drivers/staging/lustre/lnet/libcfs/libcfs_string.c2
-rw-r--r--drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c17
-rw-r--r--drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c4
-rw-r--r--drivers/staging/lustre/lnet/lnet/api-ni.c46
-rw-r--r--drivers/staging/lustre/lnet/lnet/config.c14
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-md.c30
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-move.c363
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-msg.c18
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-socket.c21
-rw-r--r--drivers/staging/lustre/lnet/lnet/lo.c39
-rw-r--r--drivers/staging/lustre/lnet/lnet/router.c20
-rw-r--r--drivers/staging/lustre/lnet/selftest/brw_test.c4
-rw-r--r--drivers/staging/lustre/lnet/selftest/conrpc.c15
-rw-r--r--drivers/staging/lustre/lnet/selftest/console.c2
-rw-r--r--drivers/staging/lustre/lnet/selftest/console.h1
-rw-r--r--drivers/staging/lustre/lnet/selftest/framework.c4
-rw-r--r--drivers/staging/lustre/lnet/selftest/rpc.c8
-rw-r--r--drivers/staging/lustre/lustre/fid/fid_lib.c2
-rw-r--r--drivers/staging/lustre/lustre/fid/fid_request.c8
-rw-r--r--drivers/staging/lustre/lustre/fid/lproc_fid.c2
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_internal.h19
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_request.c57
-rw-r--r--drivers/staging/lustre/lustre/include/cl_object.h108
-rw-r--r--drivers/staging/lustre/lustre/include/interval_tree.h26
-rw-r--r--drivers/staging/lustre/lustre/include/linux/lustre_lite.h91
-rw-r--r--drivers/staging/lustre/lustre/include/linux/lustre_user.h66
-rw-r--r--drivers/staging/lustre/lustre/include/lprocfs_status.h143
-rw-r--r--drivers/staging/lustre/lustre/include/lu_object.h38
-rw-r--r--drivers/staging/lustre/lustre/include/lustre/lustre_idl.h486
-rw-r--r--drivers/staging/lustre/lustre/include/lustre/lustre_ioctl.h412
-rw-r--r--drivers/staging/lustre/lustre/include/lustre/lustre_user.h329
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_cfg.h26
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_compat.h (renamed from drivers/staging/lustre/lustre/include/linux/lustre_compat25.h)6
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_dlm.h16
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_dlm_flags.h36
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_eacl.h1
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_fid.h32
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_handles.h5
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_import.h24
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_lib.h318
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_linkea.h79
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_lite.h97
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_lmv.h184
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_log.h3
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_mdc.h52
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_mds.h3
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_net.h102
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_param.h3
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_patchless_compat.h (renamed from drivers/staging/lustre/lustre/include/linux/lustre_patchless_compat.h)0
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_req_layout.h23
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_ver.h19
-rw-r--r--drivers/staging/lustre/lustre/include/obd.h390
-rw-r--r--drivers/staging/lustre/lustre/include/obd_class.h195
-rw-r--r--drivers/staging/lustre/lustre/include/obd_support.h34
-rw-r--r--drivers/staging/lustre/lustre/ldlm/interval_tree.c100
-rw-r--r--drivers/staging/lustre/lustre/ldlm/l_lock.c4
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_extent.c4
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_flock.c109
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_internal.h20
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_lib.c32
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_lock.c84
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c28
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_pool.c49
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_request.c119
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_resource.c53
-rw-r--r--drivers/staging/lustre/lustre/llite/Makefile2
-rw-r--r--drivers/staging/lustre/lustre/llite/dcache.c61
-rw-r--r--drivers/staging/lustre/lustre/llite/dir.c899
-rw-r--r--drivers/staging/lustre/lustre/llite/file.c678
-rw-r--r--drivers/staging/lustre/lustre/llite/glimpse.c1
-rw-r--r--drivers/staging/lustre/lustre/llite/lcommon_cl.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/lcommon_misc.c1
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_close.c1
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_internal.h356
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_lib.c715
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_mmap.c8
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_nfs.c70
-rw-r--r--drivers/staging/lustre/lustre/llite/lproc_llite.c221
-rw-r--r--drivers/staging/lustre/lustre/llite/namei.c378
-rw-r--r--drivers/staging/lustre/lustre/llite/range_lock.c233
-rw-r--r--drivers/staging/lustre/lustre/llite/range_lock.h82
-rw-r--r--drivers/staging/lustre/lustre/llite/rw.c37
-rw-r--r--drivers/staging/lustre/lustre/llite/rw26.c28
-rw-r--r--drivers/staging/lustre/lustre/llite/statahead.c1439
-rw-r--r--drivers/staging/lustre/lustre/llite/super25.c7
-rw-r--r--drivers/staging/lustre/lustre/llite/symlink.c13
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_dev.c7
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_internal.h15
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_io.c31
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_lock.c1
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_object.c15
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_page.c26
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_req.c5
-rw-r--r--drivers/staging/lustre/lustre/llite/xattr.c338
-rw-r--r--drivers/staging/lustre/lustre/llite/xattr_cache.c25
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_fld.c16
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_intent.c365
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_internal.h126
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_obd.c1484
-rw-r--r--drivers/staging/lustre/lustre/lmv/lproc_lmv.c4
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_cl_internal.h14
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_dev.c1
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_ea.c17
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_internal.h9
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_io.c25
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_merge.c39
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_obd.c349
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_object.c50
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_pack.c60
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_page.c12
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_pool.c18
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_request.c78
-rw-r--r--drivers/staging/lustre/lustre/lov/lovsub_object.c6
-rw-r--r--drivers/staging/lustre/lustre/mdc/lproc_mdc.c17
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_internal.h63
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_lib.c236
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_locks.c176
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_reint.c36
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_request.c725
-rw-r--r--drivers/staging/lustre/lustre/mgc/mgc_request.c27
-rw-r--r--drivers/staging/lustre/lustre/obdclass/Makefile2
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_io.c19
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_object.c50
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_page.c30
-rw-r--r--drivers/staging/lustre/lustre/obdclass/class_obd.c57
-rw-r--r--drivers/staging/lustre/lustre/obdclass/debug.c4
-rw-r--r--drivers/staging/lustre/lustre/obdclass/genops.c148
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linkea.c201
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linux/linux-module.c6
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c2
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c5
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog.c10
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_cat.c10
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_internal.h5
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_obd.c1
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_swab.c26
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lprocfs_status.c150
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lu_object.c240
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lustre_handles.c13
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lustre_peer.c1
-rw-r--r--drivers/staging/lustre/lustre/obdclass/obd_config.c48
-rw-r--r--drivers/staging/lustre/lustre/obdclass/obd_mount.c41
-rw-r--r--drivers/staging/lustre/lustre/obdclass/obdo.c13
-rw-r--r--drivers/staging/lustre/lustre/obdecho/echo_client.c170
-rw-r--r--drivers/staging/lustre/lustre/obdecho/echo_internal.h4
-rw-r--r--drivers/staging/lustre/lustre/osc/lproc_osc.c41
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_cache.c279
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_cl_internal.h6
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_internal.h9
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_io.c46
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_lock.c4
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_object.c7
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_page.c278
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_request.c400
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/client.c127
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/connection.c5
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/events.c6
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/import.c332
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/layout.c100
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c4
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/niobuf.c36
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/pack_generic.c245
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/pers.c6
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/pinger.c1
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h9
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c4
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/recover.c2
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec.c26
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c24
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_config.c1
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_gc.c5
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_plain.c32
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/service.c47
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/wiretest.c745
-rw-r--r--drivers/staging/media/bcm2048/radio-bcm2048.c14
-rw-r--r--drivers/staging/media/cxd2099/cxd2099.c2
-rw-r--r--drivers/staging/media/davinci_vpfe/davinci_vpfe_user.h36
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_isif.c8
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_resizer.c2
-rw-r--r--drivers/staging/media/davinci_vpfe/vpfe_video.c14
-rw-r--r--drivers/staging/media/lirc/lirc_bt829.c7
-rw-r--r--drivers/staging/media/lirc/lirc_imon.c37
-rw-r--r--drivers/staging/media/lirc/lirc_parallel.c6
-rw-r--r--drivers/staging/media/lirc/lirc_sasem.c26
-rw-r--r--drivers/staging/most/Documentation/ABI/sysfs-class-most.txt134
-rw-r--r--drivers/staging/most/aim-cdev/cdev.c62
-rw-r--r--drivers/staging/most/aim-network/networking.c26
-rw-r--r--drivers/staging/most/aim-sound/sound.c11
-rw-r--r--drivers/staging/most/aim-v4l2/video.c123
-rw-r--r--drivers/staging/most/hdm-dim2/dim2_hal.c185
-rw-r--r--drivers/staging/most/hdm-dim2/dim2_hal.h9
-rw-r--r--drivers/staging/most/hdm-dim2/dim2_hdm.c108
-rw-r--r--drivers/staging/most/hdm-dim2/dim2_reg.h11
-rw-r--r--drivers/staging/most/hdm-dim2/dim2_sysfs.c2
-rw-r--r--drivers/staging/most/hdm-usb/hdm_usb.c502
-rw-r--r--drivers/staging/most/mostcore/core.c128
-rw-r--r--drivers/staging/most/mostcore/mostcore.h6
-rw-r--r--drivers/staging/netlogic/xlr_net.c14
-rw-r--r--drivers/staging/octeon-usb/Kconfig2
-rw-r--r--drivers/staging/octeon-usb/octeon-hcd.c1
-rw-r--r--drivers/staging/octeon/ethernet-mdio.c1
-rw-r--r--drivers/staging/octeon/ethernet-rgmii.c5
-rw-r--r--drivers/staging/octeon/ethernet-rx.c181
-rw-r--r--drivers/staging/octeon/ethernet-util.h7
-rw-r--r--drivers/staging/octeon/ethernet.c113
-rw-r--r--drivers/staging/octeon/octeon-ethernet.h2
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c2
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_ap.c132
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_cmd.c42
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_debug.c731
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_efuse.c99
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_ieee80211.c245
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_ioctl_set.c13
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_mlme.c70
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_mlme_ext.c337
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_pwrctrl.c20
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_recv.c6
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_rf.c1
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_security.c1
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_sreset.c11
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_wlan_util.c48
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_xmit.c65
-rw-r--r--drivers/staging/rtl8188eu/hal/bb_cfg.c18
-rw-r--r--drivers/staging/rtl8188eu/hal/hal_intf.c230
-rw-r--r--drivers/staging/rtl8188eu/hal/odm.c237
-rw-r--r--drivers/staging/rtl8188eu/hal/phy.c76
-rw-r--r--drivers/staging/rtl8188eu/hal/rf.c16
-rw-r--r--drivers/staging/rtl8188eu/hal/rf_cfg.c11
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c96
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_dm.c115
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c67
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c9
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188eu_led.c10
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c6
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c73
-rw-r--r--drivers/staging/rtl8188eu/hal/usb_halinit.c202
-rw-r--r--drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h18
-rw-r--r--drivers/staging/rtl8188eu/include/HalHWImg8188E_FW.h29
-rw-r--r--drivers/staging/rtl8188eu/include/basic_types.h4
-rw-r--r--drivers/staging/rtl8188eu/include/drv_types.h65
-rw-r--r--drivers/staging/rtl8188eu/include/hal_intf.h84
-rw-r--r--drivers/staging/rtl8188eu/include/ieee80211.h273
-rw-r--r--drivers/staging/rtl8188eu/include/odm.h18
-rw-r--r--drivers/staging/rtl8188eu/include/osdep_intf.h1
-rw-r--r--drivers/staging/rtl8188eu/include/osdep_service.h9
-rw-r--r--drivers/staging/rtl8188eu/include/phy.h6
-rw-r--r--drivers/staging/rtl8188eu/include/recv_osdep.h4
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_cmd.h32
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_dm.h3
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_hal.h7
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_led.h2
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_recv.h5
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_xmit.h5
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_ap.h1
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_cmd.h94
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_debug.h121
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_efuse.h12
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_event.h23
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_ht.h9
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_ioctl.h15
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_mlme.h36
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_mlme_ext.h93
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_pwrctrl.h17
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_recv.h8
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_security.h6
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_sreset.h1
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_xmit.h9
-rw-r--r--drivers/staging/rtl8188eu/include/usb_hal.h21
-rw-r--r--drivers/staging/rtl8188eu/include/usb_ops_linux.h17
-rw-r--r--drivers/staging/rtl8188eu/include/wifi.h30
-rw-r--r--drivers/staging/rtl8188eu/include/wlan_bssdef.h83
-rw-r--r--drivers/staging/rtl8188eu/os_dep/ioctl_linux.c53
-rw-r--r--drivers/staging/rtl8188eu/os_dep/os_intfs.c424
-rw-r--r--drivers/staging/rtl8188eu/os_dep/osdep_service.c11
-rw-r--r--drivers/staging/rtl8188eu/os_dep/recv_linux.c1
-rw-r--r--drivers/staging/rtl8188eu/os_dep/usb_intf.c40
-rw-r--r--drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c49
-rw-r--r--drivers/staging/rtl8188eu/os_dep/xmit_linux.c2
-rw-r--r--drivers/staging/rtl8192e/dot11d.c12
-rw-r--r--drivers/staging/rtl8192e/dot11d.h5
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c8
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c2
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c6
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_cam.c4
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_core.c42
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_core.h12
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_ps.c8
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_wx.c120
-rw-r--r--drivers/staging/rtl8192e/rtl819x_Qos.h3
-rw-r--r--drivers/staging/rtl8192e/rtl819x_TSProc.c5
-rw-r--r--drivers/staging/rtl8192e/rtllib.h12
-rw-r--r--drivers/staging/rtl8192e/rtllib_module.c2
-rw-r--r--drivers/staging/rtl8192e/rtllib_softmac.c99
-rw-r--r--drivers/staging/rtl8192e/rtllib_softmac_wx.c34
-rw-r--r--drivers/staging/rtl8192e/rtllib_tx.c75
-rw-r--r--drivers/staging/rtl8192e/rtllib_wx.c10
-rw-r--r--drivers/staging/rtl8192u/ieee80211/Makefile3
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211.h4
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c2
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c18
-rw-r--r--drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c6
-rw-r--r--drivers/staging/rtl8192u/r8192U.h4
-rw-r--r--drivers/staging/rtl8192u/r8192U_core.c84
-rw-r--r--drivers/staging/rtl8192u/r8192U_dm.c6
-rw-r--r--drivers/staging/rtl8712/ieee80211.c25
-rw-r--r--drivers/staging/rtl8712/os_intfs.c6
-rw-r--r--drivers/staging/rtl8712/osdep_intf.h2
-rw-r--r--drivers/staging/rtl8712/osdep_service.h7
-rw-r--r--drivers/staging/rtl8712/recv_linux.c1
-rw-r--r--drivers/staging/rtl8712/rtl8712_cmd.c14
-rw-r--r--drivers/staging/rtl8712/rtl8712_efuse.c2
-rw-r--r--drivers/staging/rtl8712/rtl8712_led.c410
-rw-r--r--drivers/staging/rtl8712/rtl8712_recv.c66
-rw-r--r--drivers/staging/rtl8712/rtl8712_recv.h18
-rw-r--r--drivers/staging/rtl8712/rtl8712_spec.h3
-rw-r--r--drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h27
-rw-r--r--drivers/staging/rtl8712/rtl8712_xmit.c11
-rw-r--r--drivers/staging/rtl8712/rtl871x_cmd.c76
-rw-r--r--drivers/staging/rtl8712/rtl871x_cmd.h277
-rw-r--r--drivers/staging/rtl8712/rtl871x_ht.h3
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl.h3
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl_linux.c4
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl_set.c12
-rw-r--r--drivers/staging/rtl8712/rtl871x_led.h15
-rw-r--r--drivers/staging/rtl8712/rtl871x_mlme.c30
-rw-r--r--drivers/staging/rtl8712/rtl871x_mlme.h12
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp.c3
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp.h3
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp_ioctl.h39
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h33
-rw-r--r--drivers/staging/rtl8712/rtl871x_pwrctrl.c27
-rw-r--r--drivers/staging/rtl8712/rtl871x_pwrctrl.h10
-rw-r--r--drivers/staging/rtl8712/rtl871x_recv.c24
-rw-r--r--drivers/staging/rtl8712/rtl871x_recv.h9
-rw-r--r--drivers/staging/rtl8712/rtl871x_security.h24
-rw-r--r--drivers/staging/rtl8712/rtl871x_sta_mgt.c3
-rw-r--r--drivers/staging/rtl8712/rtl871x_xmit.c18
-rw-r--r--drivers/staging/rtl8712/rtl871x_xmit.h12
-rw-r--r--drivers/staging/rtl8712/usb_halinit.c3
-rw-r--r--drivers/staging/rtl8712/usb_intf.c14
-rw-r--r--drivers/staging/rtl8712/usb_ops_linux.c92
-rw-r--r--drivers/staging/rtl8712/wifi.h15
-rw-r--r--drivers/staging/rtl8712/wlan_bssdef.h6
-rw-r--r--drivers/staging/rtl8712/xmit_linux.c17
-rw-r--r--drivers/staging/rtl8723au/Kconfig33
-rw-r--r--drivers/staging/rtl8723au/Makefile53
-rw-r--r--drivers/staging/rtl8723au/TODO16
-rw-r--r--drivers/staging/rtl8723au/core/rtw_ap.c1738
-rw-r--r--drivers/staging/rtl8723au/core/rtw_cmd.c1470
-rw-r--r--drivers/staging/rtl8723au/core/rtw_efuse.c538
-rw-r--r--drivers/staging/rtl8723au/core/rtw_ieee80211.c855
-rw-r--r--drivers/staging/rtl8723au/core/rtw_mlme.c2314
-rw-r--r--drivers/staging/rtl8723au/core/rtw_mlme_ext.c6187
-rw-r--r--drivers/staging/rtl8723au/core/rtw_pwrctrl.c606
-rw-r--r--drivers/staging/rtl8723au/core/rtw_recv.c2204
-rw-r--r--drivers/staging/rtl8723au/core/rtw_security.c1630
-rw-r--r--drivers/staging/rtl8723au/core/rtw_sreset.c214
-rw-r--r--drivers/staging/rtl8723au/core/rtw_sta_mgt.c439
-rw-r--r--drivers/staging/rtl8723au/core/rtw_wlan_util.c1537
-rw-r--r--drivers/staging/rtl8723au/core/rtw_xmit.c2341
-rw-r--r--drivers/staging/rtl8723au/hal/Hal8723PwrSeq.c80
-rw-r--r--drivers/staging/rtl8723au/hal/Hal8723UHWImg_CE.c136
-rw-r--r--drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c1097
-rw-r--r--drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c565
-rw-r--r--drivers/staging/rtl8723au/hal/HalHWImg8723A_MAC.c187
-rw-r--r--drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c259
-rw-r--r--drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c156
-rw-r--r--drivers/staging/rtl8723au/hal/hal_com.c853
-rw-r--r--drivers/staging/rtl8723au/hal/hal_intf.c42
-rw-r--r--drivers/staging/rtl8723au/hal/odm.c1732
-rw-r--r--drivers/staging/rtl8723au/hal/odm_HWConfig.c396
-rw-r--r--drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c88
-rw-r--r--drivers/staging/rtl8723au/hal/odm_debug.c39
-rw-r--r--drivers/staging/rtl8723au/hal/odm_interface.c49
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c11265
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_cmd.c755
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_dm.c194
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c2076
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c961
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c503
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_rxdesc.c69
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_sreset.c55
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723au_recv.c267
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723au_xmit.c520
-rw-r--r--drivers/staging/rtl8723au/hal/usb_halinit.c1269
-rw-r--r--drivers/staging/rtl8723au/hal/usb_ops_linux.c690
-rw-r--r--drivers/staging/rtl8723au/include/Hal8723APhyCfg.h162
-rw-r--r--drivers/staging/rtl8723au/include/Hal8723APhyReg.h1078
-rw-r--r--drivers/staging/rtl8723au/include/Hal8723PwrSeq.h126
-rw-r--r--drivers/staging/rtl8723au/include/Hal8723UHWImg_CE.h29
-rw-r--r--drivers/staging/rtl8723au/include/HalDMOutSrc8723A.h64
-rw-r--r--drivers/staging/rtl8723au/include/HalHWImg8723A_BB.h38
-rw-r--r--drivers/staging/rtl8723au/include/HalHWImg8723A_FW.h28
-rw-r--r--drivers/staging/rtl8723au/include/HalHWImg8723A_MAC.h26
-rw-r--r--drivers/staging/rtl8723au/include/HalHWImg8723A_RF.h25
-rw-r--r--drivers/staging/rtl8723au/include/HalPwrSeqCmd.h130
-rw-r--r--drivers/staging/rtl8723au/include/HalVerDef.h114
-rw-r--r--drivers/staging/rtl8723au/include/drv_types.h274
-rw-r--r--drivers/staging/rtl8723au/include/hal_com.h182
-rw-r--r--drivers/staging/rtl8723au/include/hal_intf.h115
-rw-r--r--drivers/staging/rtl8723au/include/ieee80211.h341
-rw-r--r--drivers/staging/rtl8723au/include/ioctl_cfg80211.h66
-rw-r--r--drivers/staging/rtl8723au/include/mlme_osdep.h24
-rw-r--r--drivers/staging/rtl8723au/include/odm.h860
-rw-r--r--drivers/staging/rtl8723au/include/odm_HWConfig.h153
-rw-r--r--drivers/staging/rtl8723au/include/odm_RegConfig8723A.h27
-rw-r--r--drivers/staging/rtl8723au/include/odm_RegDefine11N.h165
-rw-r--r--drivers/staging/rtl8723au/include/odm_debug.h117
-rw-r--r--drivers/staging/rtl8723au/include/odm_interface.h62
-rw-r--r--drivers/staging/rtl8723au/include/odm_precomp.h49
-rw-r--r--drivers/staging/rtl8723au/include/odm_reg.h111
-rw-r--r--drivers/staging/rtl8723au/include/osdep_intf.h45
-rw-r--r--drivers/staging/rtl8723au/include/osdep_service.h88
-rw-r--r--drivers/staging/rtl8723au/include/recv_osdep.h36
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h1627
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_bt_intf.h69
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_cmd.h158
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_dm.h137
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_hal.h538
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_pg.h98
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_recv.h65
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_rf.h58
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_spec.h2148
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_sreset.h24
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_xmit.h225
-rw-r--r--drivers/staging/rtl8723au/include/rtw_ap.h51
-rw-r--r--drivers/staging/rtl8723au/include/rtw_cmd.h815
-rw-r--r--drivers/staging/rtl8723au/include/rtw_debug.h191
-rw-r--r--drivers/staging/rtl8723au/include/rtw_eeprom.h135
-rw-r--r--drivers/staging/rtl8723au/include/rtw_efuse.h109
-rw-r--r--drivers/staging/rtl8723au/include/rtw_event.h74
-rw-r--r--drivers/staging/rtl8723au/include/rtw_ht.h42
-rw-r--r--drivers/staging/rtl8723au/include/rtw_io.h237
-rw-r--r--drivers/staging/rtl8723au/include/rtw_mlme.h340
-rw-r--r--drivers/staging/rtl8723au/include/rtw_mlme_ext.h683
-rw-r--r--drivers/staging/rtl8723au/include/rtw_pwrctrl.h241
-rw-r--r--drivers/staging/rtl8723au/include/rtw_recv.h305
-rw-r--r--drivers/staging/rtl8723au/include/rtw_rf.h102
-rw-r--r--drivers/staging/rtl8723au/include/rtw_security.h331
-rw-r--r--drivers/staging/rtl8723au/include/rtw_sreset.h36
-rw-r--r--drivers/staging/rtl8723au/include/rtw_version.h1
-rw-r--r--drivers/staging/rtl8723au/include/rtw_xmit.h385
-rw-r--r--drivers/staging/rtl8723au/include/sta_info.h373
-rw-r--r--drivers/staging/rtl8723au/include/usb_ops.h68
-rw-r--r--drivers/staging/rtl8723au/include/usb_ops_linux.h41
-rw-r--r--drivers/staging/rtl8723au/include/wifi.h84
-rw-r--r--drivers/staging/rtl8723au/include/wlan_bssdef.h123
-rw-r--r--drivers/staging/rtl8723au/include/xmit_osdep.h38
-rw-r--r--drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c3348
-rw-r--r--drivers/staging/rtl8723au/os_dep/mlme_linux.c81
-rw-r--r--drivers/staging/rtl8723au/os_dep/os_intfs.c852
-rw-r--r--drivers/staging/rtl8723au/os_dep/recv_linux.c165
-rw-r--r--drivers/staging/rtl8723au/os_dep/usb_intf.c627
-rw-r--r--drivers/staging/rtl8723au/os_dep/usb_ops_linux.c233
-rw-r--r--drivers/staging/rtl8723au/os_dep/xmit_linux.c154
-rw-r--r--drivers/staging/rts5208/ms.c85
-rw-r--r--drivers/staging/rts5208/ms.h1
-rw-r--r--drivers/staging/rts5208/rtsx.c63
-rw-r--r--drivers/staging/rts5208/rtsx.h24
-rw-r--r--drivers/staging/rts5208/rtsx_card.c45
-rw-r--r--drivers/staging/rts5208/rtsx_chip.c18
-rw-r--r--drivers/staging/rts5208/rtsx_chip.h90
-rw-r--r--drivers/staging/rts5208/rtsx_scsi.c28
-rw-r--r--drivers/staging/rts5208/rtsx_sys.h2
-rw-r--r--drivers/staging/rts5208/rtsx_transport.h1
-rw-r--r--drivers/staging/rts5208/sd.c183
-rw-r--r--drivers/staging/rts5208/spi.c3
-rw-r--r--drivers/staging/rts5208/spi.h1
-rw-r--r--drivers/staging/rts5208/xd.c44
-rw-r--r--drivers/staging/slicoss/slic.h75
-rw-r--r--drivers/staging/slicoss/slichw.h409
-rw-r--r--drivers/staging/slicoss/slicoss.c646
-rw-r--r--drivers/staging/sm750fb/ddk750_chip.c106
-rw-r--r--drivers/staging/sm750fb/ddk750_chip.h2
-rw-r--r--drivers/staging/sm750fb/ddk750_display.c15
-rw-r--r--drivers/staging/sm750fb/ddk750_display.h94
-rw-r--r--drivers/staging/sm750fb/ddk750_dvi.c8
-rw-r--r--drivers/staging/sm750fb/ddk750_hwi2c.c2
-rw-r--r--drivers/staging/sm750fb/ddk750_mode.c33
-rw-r--r--drivers/staging/sm750fb/ddk750_power.c6
-rw-r--r--drivers/staging/sm750fb/ddk750_sii164.c7
-rw-r--r--drivers/staging/sm750fb/ddk750_swi2c.c14
-rw-r--r--drivers/staging/sm750fb/sm750.c2
-rw-r--r--drivers/staging/sm750fb/sm750.h16
-rw-r--r--drivers/staging/sm750fb/sm750_accel.c100
-rw-r--r--drivers/staging/sm750fb/sm750_hw.c114
-rw-r--r--drivers/staging/speakup/devsynth.c2
-rw-r--r--drivers/staging/speakup/kobjects.c17
-rw-r--r--drivers/staging/speakup/synth.c6
-rw-r--r--drivers/staging/speakup/varhandlers.c6
-rw-r--r--drivers/staging/unisys/include/channel.h221
-rw-r--r--drivers/staging/unisys/include/channel_guid.h55
-rw-r--r--drivers/staging/unisys/include/diagchannel.h38
-rw-r--r--drivers/staging/unisys/include/guestlinuxdebug.h180
-rw-r--r--drivers/staging/unisys/include/iochannel.h1
-rw-r--r--drivers/staging/unisys/include/periodic_work.h40
-rw-r--r--drivers/staging/unisys/include/vbushelper.h46
-rw-r--r--drivers/staging/unisys/include/version.h45
-rw-r--r--drivers/staging/unisys/include/visorbus.h111
-rw-r--r--drivers/staging/unisys/visorbus/Makefile1
-rw-r--r--drivers/staging/unisys/visorbus/controlvmchannel.h76
-rw-r--r--drivers/staging/unisys/visorbus/controlvmcompletionstatus.h101
-rw-r--r--drivers/staging/unisys/visorbus/iovmcall_gnuc.h48
-rw-r--r--drivers/staging/unisys/visorbus/periodic_work.c204
-rw-r--r--drivers/staging/unisys/visorbus/vbuschannel.h211
-rw-r--r--drivers/staging/unisys/visorbus/vbusdeviceinfo.h213
-rw-r--r--drivers/staging/unisys/visorbus/visorbus_main.c841
-rw-r--r--drivers/staging/unisys/visorbus/visorbus_private.h99
-rw-r--r--drivers/staging/unisys/visorbus/visorchannel.c573
-rw-r--r--drivers/staging/unisys/visorbus/visorchipset.c1593
-rw-r--r--drivers/staging/unisys/visorbus/vmcallinterface.h190
-rw-r--r--drivers/staging/unisys/visorhba/visorhba_main.c70
-rw-r--r--drivers/staging/unisys/visorinput/ultrainputreport.h2
-rw-r--r--drivers/staging/unisys/visorinput/visorinput.c149
-rw-r--r--drivers/staging/unisys/visornic/visornic_main.c100
-rw-r--r--drivers/staging/vc04_services/Kconfig9
-rw-r--r--drivers/staging/vc04_services/Makefile14
-rw-r--r--drivers/staging/vc04_services/interface/vchi/connections/connection.h328
-rw-r--r--drivers/staging/vc04_services/interface/vchi/message_drivers/message.h204
-rw-r--r--drivers/staging/vc04_services/interface/vchi/vchi.h378
-rw-r--r--drivers/staging/vc04_services/interface/vchi/vchi_cfg.h224
-rw-r--r--drivers/staging/vc04_services/interface/vchi/vchi_cfg_internal.h71
-rw-r--r--drivers/staging/vc04_services/interface/vchi/vchi_common.h175
-rw-r--r--drivers/staging/vc04_services/interface/vchi/vchi_mh.h42
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq.h40
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835.h42
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c586
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c2903
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h220
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_build_info.h37
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_cfg.h69
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c120
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.h50
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c3934
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h712
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c383
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h52
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_genversion87
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_if.h189
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h131
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c458
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_killable.h69
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_memdrv.h71
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_pagelist.h58
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c860
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c156
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.h82
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_version.c59
-rw-r--r--drivers/staging/vme/devices/vme_pio2_core.c12
-rw-r--r--drivers/staging/vme/devices/vme_user.c2
-rw-r--r--drivers/staging/vt6655/baseband.c2
-rw-r--r--drivers/staging/vt6655/card.c4
-rw-r--r--drivers/staging/vt6655/channel.c3
-rw-r--r--drivers/staging/vt6655/device_main.c12
-rw-r--r--drivers/staging/vt6655/key.c10
-rw-r--r--drivers/staging/vt6655/key.h2
-rw-r--r--drivers/staging/vt6655/power.c12
-rw-r--r--drivers/staging/vt6655/rf.c19
-rw-r--r--drivers/staging/vt6655/rxtx.c49
-rw-r--r--drivers/staging/vt6656/baseband.h4
-rw-r--r--drivers/staging/vt6656/card.c75
-rw-r--r--drivers/staging/vt6656/dpc.c15
-rw-r--r--drivers/staging/vt6656/dpc.h2
-rw-r--r--drivers/staging/vt6656/main_usb.c12
-rw-r--r--drivers/staging/vt6656/usbpipe.c5
-rw-r--r--drivers/staging/wilc1000/TODO1
-rw-r--r--drivers/staging/wilc1000/coreconfigurator.h6
-rw-r--r--drivers/staging/wilc1000/host_interface.c9
-rw-r--r--drivers/staging/wilc1000/linux_wlan.c1
-rw-r--r--drivers/staging/wilc1000/wilc_debugfs.c31
-rw-r--r--drivers/staging/wilc1000/wilc_spi.c33
-rw-r--r--drivers/staging/wilc1000/wilc_wfi_cfgoperations.c2
-rw-r--r--drivers/staging/wilc1000/wilc_wfi_netdevice.h2
-rw-r--r--drivers/staging/wilc1000/wilc_wlan.c13
-rw-r--r--drivers/staging/wilc1000/wilc_wlan.h2
-rw-r--r--drivers/staging/wilc1000/wilc_wlan_if.h1
-rw-r--r--drivers/staging/wlan-ng/cfg80211.c151
-rw-r--r--drivers/staging/wlan-ng/hfa384x.h904
-rw-r--r--drivers/staging/wlan-ng/hfa384x_usb.c307
-rw-r--r--drivers/staging/wlan-ng/p80211conv.c8
-rw-r--r--drivers/staging/wlan-ng/p80211metadef.h19
-rw-r--r--drivers/staging/wlan-ng/p80211metastruct.h248
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.c88
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.h43
-rw-r--r--drivers/staging/wlan-ng/p80211req.c95
-rw-r--r--drivers/staging/wlan-ng/p80211req.h2
-rw-r--r--drivers/staging/wlan-ng/p80211types.h261
-rw-r--r--drivers/staging/wlan-ng/p80211wep.c6
-rw-r--r--drivers/staging/wlan-ng/prism2fw.c50
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.c62
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.h51
-rw-r--r--drivers/staging/wlan-ng/prism2mib.c622
-rw-r--r--drivers/staging/wlan-ng/prism2sta.c261
-rw-r--r--drivers/staging/wlan-ng/prism2usb.c38
-rw-r--r--drivers/staging/xgifb/XGI_main_26.c13
-rw-r--r--drivers/staging/xgifb/vb_setmode.c49
-rw-r--r--include/linux/hid-sensor-hub.h1
-rw-r--r--include/linux/iio/consumer.h12
-rw-r--r--include/linux/iio/iio.h3
-rw-r--r--include/linux/iio/trigger.h26
-rw-r--r--include/linux/iio/triggered_buffer.h8
-rw-r--r--tools/iio/iio_utils.c11
-rw-r--r--tools/iio/lsiio.c3
932 files changed, 81784 insertions, 91805 deletions
diff --git a/.mailmap b/.mailmap
index 1dab0a156489..967f88210b12 100644
--- a/.mailmap
+++ b/.mailmap
@@ -160,6 +160,7 @@ Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
Viresh Kumar <vireshk@kernel.org> <viresh.kumar@st.com>
Viresh Kumar <vireshk@kernel.org> <viresh.linux@gmail.com>
Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com>
+Vlad Dogaru <ddvlad@gmail.com> <vlad.dogaru@intel.com>
Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@virtuozzo.com>
Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@parallels.com>
Takashi YOSHII <takashi.yoshii.zj@renesas.com>
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index 5c70ce9c1954..1416c6a0d2cd 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -38,6 +38,7 @@ dallas,ds4510 CPU Supervisor with Nonvolatile Memory and Programmable I/O
dallas,ds75 Digital Thermometer and Thermostat
dlg,da9053 DA9053: flexible system level PMIC with multicore support
dlg,da9063 DA9063: system PMIC for quad-core application processors
+domintech,dmard09 DMARD09: 3-axis Accelerometer
epson,rx8010 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
epson,rx8025 High-Stability. I2C-Bus INTERFACE REAL TIME CLOCK MODULE
epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
@@ -56,6 +57,7 @@ maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
mc,rv3029c2 Real Time Clock Module with I2C-Bus
+mcube,mc3230 mCube 3-axis 8-bit digital accelerometer
microchip,mcp4531-502 Microchip 7-bit Single I2C Digital Potentiometer (5k)
microchip,mcp4531-103 Microchip 7-bit Single I2C Digital Potentiometer (10k)
microchip,mcp4531-503 Microchip 7-bit Single I2C Digital Potentiometer (50k)
diff --git a/Documentation/devicetree/bindings/iio/accel/dmard06.txt b/Documentation/devicetree/bindings/iio/accel/dmard06.txt
new file mode 100644
index 000000000000..ce105a12c645
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/accel/dmard06.txt
@@ -0,0 +1,19 @@
+Device tree bindings for Domintech DMARD05, DMARD06, DMARD07 accelerometers
+
+Required properties:
+ - compatible : Should be "domintech,dmard05"
+ or "domintech,dmard06"
+ or "domintech,dmard07"
+ - reg : I2C address of the chip. Should be 0x1c
+
+Example:
+ &i2c1 {
+ /* ... */
+
+ accelerometer@1c {
+ compatible = "domintech,dmard06";
+ reg = <0x1c>;
+ };
+
+ /* ... */
+ };
diff --git a/Documentation/devicetree/bindings/iio/accel/kionix,kxsd9.txt b/Documentation/devicetree/bindings/iio/accel/kionix,kxsd9.txt
new file mode 100644
index 000000000000..b25bf3a77e0f
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/accel/kionix,kxsd9.txt
@@ -0,0 +1,22 @@
+Kionix KXSD9 Accelerometer device tree bindings
+
+Required properties:
+ - compatible: should be set to "kionix,kxsd9"
+ - reg: i2c slave address
+
+Optional properties:
+ - vdd-supply: The input supply for VDD
+ - iovdd-supply: The input supply for IOVDD
+ - interrupts: The movement detection interrupt
+ - mount-matrix: See mount-matrix.txt
+
+Example:
+
+kxsd9@18 {
+ compatible = "kionix,kxsd9";
+ reg = <0x18>;
+ interrupt-parent = <&foo>;
+ interrupts = <57 IRQ_TYPE_EDGE_FALLING>;
+ iovdd-supply = <&bar>;
+ vdd-supply = <&baz>;
+};
diff --git a/Documentation/devicetree/bindings/iio/adc/mt6577_auxadc.txt b/Documentation/devicetree/bindings/iio/adc/mt6577_auxadc.txt
new file mode 100644
index 000000000000..68c45cbbe3d9
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/mt6577_auxadc.txt
@@ -0,0 +1,29 @@
+* Mediatek AUXADC - Analog to Digital Converter on Mediatek mobile soc (mt65xx/mt81xx/mt27xx)
+===============
+
+The Auxiliary Analog/Digital Converter (AUXADC) is an ADC found
+in some Mediatek SoCs which among other things measures the temperatures
+in the SoC. It can be used directly with register accesses, but it is also
+used by thermal controller which reads the temperatures from the AUXADC
+directly via its own bus interface. See
+Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
+for the Thermal Controller which holds a phandle to the AUXADC.
+
+Required properties:
+ - compatible: Should be one of:
+ - "mediatek,mt2701-auxadc": For MT2701 family of SoCs
+ - "mediatek,mt8173-auxadc": For MT8173 family of SoCs
+ - reg: Address range of the AUXADC unit.
+ - clocks: Should contain a clock specifier for each entry in clock-names
+ - clock-names: Should contain "main".
+ - #io-channel-cells: Should be 1, see ../iio-bindings.txt
+
+Example:
+
+auxadc: adc@11001000 {
+ compatible = "mediatek,mt2701-auxadc";
+ reg = <0 0x11001000 0 0x1000>;
+ clocks = <&pericfg CLK_PERI_AUXADC>;
+ clock-names = "main";
+ #io-channel-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc12138.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc12138.txt
new file mode 100644
index 000000000000..049a1d36f013
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/ti-adc12138.txt
@@ -0,0 +1,37 @@
+* Texas Instruments' ADC12130/ADC12132/ADC12138
+
+Required properties:
+ - compatible: Should be one of
+ * "ti,adc12130"
+ * "ti,adc12132"
+ * "ti,adc12138"
+ - reg: SPI chip select number for the device
+ - interrupts: Should contain interrupt for EOC (end of conversion)
+ - clocks: phandle to conversion clock input
+ - spi-max-frequency: Definision as per
+ Documentation/devicetree/bindings/spi/spi-bus.txt
+ - vref-p-supply: The regulator supply for positive analog voltage reference
+
+Optional properties:
+ - vref-n-supply: The regulator supply for negative analog voltage reference
+ (Note that this must not go below GND or exceed vref-p)
+ If not specified, this is assumed to be analog ground.
+ - ti,acquisition-time: The number of conversion clock periods for the S/H's
+ acquisition time. Should be one of 6, 10, 18, 34. If not specified,
+ default value of 10 is used.
+ For high source impedances, this value can be increased to 18 or 34.
+ For less ADC accuracy and/or slower CCLK frequencies this value may be
+ decreased to 6. See section 6.0 INPUT SOURCE RESISTANCE in the
+ datasheet for details.
+
+Example:
+adc@0 {
+ compatible = "ti,adc12138";
+ reg = <0>;
+ interrupts = <28 IRQ_TYPE_EDGE_RISING>;
+ interrupt-parent = <&gpio1>;
+ clocks = <&cclk>;
+ vref-p-supply = <&ldo4_reg>;
+ spi-max-frequency = <5000000>;
+ ti,acquisition-time = <6>;
+};
diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc161s626.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc161s626.txt
new file mode 100644
index 000000000000..9ed2315781e4
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/ti-adc161s626.txt
@@ -0,0 +1,16 @@
+* Texas Instruments ADC141S626 and ADC161S626 chips
+
+Required properties:
+ - compatible: Should be "ti,adc141s626" or "ti,adc161s626"
+ - reg: spi chip select number for the device
+
+Recommended properties:
+ - spi-max-frequency: Definition as per
+ Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Example:
+adc@0 {
+ compatible = "ti,adc161s626";
+ reg = <0>;
+ spi-max-frequency = <4300000>;
+};
diff --git a/Documentation/devicetree/bindings/iio/chemical/atlas,orp-sm.txt b/Documentation/devicetree/bindings/iio/chemical/atlas,orp-sm.txt
new file mode 100644
index 000000000000..5d8b687d5edc
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/chemical/atlas,orp-sm.txt
@@ -0,0 +1,22 @@
+* Atlas Scientific ORP-SM OEM sensor
+
+https://www.atlas-scientific.com/_files/_datasheets/_oem/ORP_oem_datasheet.pdf
+
+Required properties:
+
+ - compatible: must be "atlas,orp-sm"
+ - reg: the I2C address of the sensor
+ - interrupt-parent: should be the phandle for the interrupt controller
+ - interrupts: the sole interrupt generated by the device
+
+ Refer to interrupt-controller/interrupts.txt for generic interrupt client
+ node bindings.
+
+Example:
+
+atlas@66 {
+ compatible = "atlas,orp-sm";
+ reg = <0x66>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <16 2>;
+};
diff --git a/Documentation/devicetree/bindings/iio/magnetometer/ak8974.txt b/Documentation/devicetree/bindings/iio/magnetometer/ak8974.txt
new file mode 100644
index 000000000000..77d5aba1bd8c
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/magnetometer/ak8974.txt
@@ -0,0 +1,29 @@
+* Asahi Kasei AK8974 magnetometer sensor
+
+Required properties:
+
+- compatible : should be "asahi-kasei,ak8974"
+- reg : the I2C address of the magnetometer
+
+Optional properties:
+
+- avdd-supply: regulator supply for the analog voltage
+ (see regulator/regulator.txt)
+- dvdd-supply: regulator supply for the digital voltage
+ (see regulator/regulator.txt)
+- interrupts: data ready (DRDY) and interrupt (INT1) lines
+ from the chip, the DRDY interrupt must be placed first.
+ The interrupts can be triggered on rising or falling
+ edges alike.
+- mount-matrix: an optional 3x3 mounting rotation matrix
+
+Example:
+
+ak8974@0f {
+ compatible = "asahi-kasei,ak8974";
+ reg = <0x0f>;
+ avdd-supply = <&foo_reg>;
+ dvdd-supply = <&bar_reg>;
+ interrupts = <0 IRQ_TYPE_EDGE_RISING>,
+ <1 IRQ_TYPE_EDGE_RISING>;
+};
diff --git a/Documentation/devicetree/bindings/iio/pressure/zpa2326.txt b/Documentation/devicetree/bindings/iio/pressure/zpa2326.txt
new file mode 100644
index 000000000000..fb85de676e03
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/pressure/zpa2326.txt
@@ -0,0 +1,31 @@
+Murata ZPA2326 pressure sensor
+
+Pressure sensor from Murata with SPI and I2C bus interfaces.
+
+Required properties:
+- compatible: "murata,zpa2326"
+- reg: the I2C address or SPI chip select the device will respond to
+
+Recommended properties for SPI bus usage:
+- spi-max-frequency: maximum SPI bus frequency as documented in
+ Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Optional properties:
+- vref-supply: an optional regulator that needs to be on to provide VREF
+ power to the sensor
+- vdd-supply: an optional regulator that needs to be on to provide VDD
+ power to the sensor
+- interrupt-parent: phandle to the parent interrupt controller as documented in
+ Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+- interrupts: interrupt mapping for IRQ as documented in
+ Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example:
+
+zpa2326@5c {
+ compatible = "murata,zpa2326";
+ reg = <0x5c>;
+ interrupt-parent = <&gpio>;
+ interrupts = <12>;
+ vdd-supply = <&ldo_1v8_gnss>;
+};
diff --git a/Documentation/devicetree/bindings/iio/proximity/sx9500.txt b/Documentation/devicetree/bindings/iio/proximity/sx9500.txt
new file mode 100644
index 000000000000..b301dd2b35da
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/proximity/sx9500.txt
@@ -0,0 +1,24 @@
+Semtech's SX9500 capacitive proximity button device driver
+
+Required properties:
+ - compatible: must be "semtech,sx9500"
+ - reg: i2c address where to find the device
+ - interrupt-parent : should be the phandle for the interrupt controller
+ - interrupts : the sole interrupt generated by the device
+
+ Refer to interrupt-controller/interrupts.txt for generic
+ interrupt client node bindings.
+
+Optional properties:
+ - reset-gpios: Reference to the GPIO connected to the device's active
+ low reset pin.
+
+Example:
+
+sx9500@28 {
+ compatible = "semtech,sx9500";
+ reg = <0x28>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
+ reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+};
diff --git a/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt b/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt
new file mode 100644
index 000000000000..28bc5c4d965b
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/temperature/maxim_thermocouple.txt
@@ -0,0 +1,21 @@
+Maxim thermocouple support
+
+* https://datasheets.maximintegrated.com/en/ds/MAX6675.pdf
+* https://datasheets.maximintegrated.com/en/ds/MAX31855.pdf
+
+Required properties:
+
+ - compatible: must be "maxim,max31855" or "maxim,max6675"
+ - reg: SPI chip select number for the device
+ - spi-max-frequency: must be 4300000
+ - spi-cpha: must be defined for max6675 to enable SPI mode 1
+
+ Refer to spi/spi-bus.txt for generic SPI slave bindings.
+
+Example:
+
+ max31855@0 {
+ compatible = "maxim,max31855";
+ reg = <0>;
+ spi-max-frequency = <4300000>;
+ };
diff --git a/Documentation/devicetree/bindings/soc/mediatek/auxadc.txt b/Documentation/devicetree/bindings/soc/mediatek/auxadc.txt
deleted file mode 100644
index bdb782918a72..000000000000
--- a/Documentation/devicetree/bindings/soc/mediatek/auxadc.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MediaTek AUXADC
-===============
-
-The Auxiliary Analog/Digital Converter (AUXADC) is an ADC found
-in some Mediatek SoCs which among other things measures the temperatures
-in the SoC. It can be used directly with register accesses, but it is also
-used by thermal controller which reads the temperatures from the AUXADC
-directly via its own bus interface. See
-Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
-for the Thermal Controller which holds a phandle to the AUXADC.
-
-Required properties:
-- compatible: Must be "mediatek,mt8173-auxadc"
-- reg: Address range of the AUXADC unit
-
-Example:
-
-auxadc: auxadc@11001000 {
- compatible = "mediatek,mt8173-auxadc";
- reg = <0 0x11001000 0 0x1000>;
-};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 851e2caf9ae0..77e985f21707 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -76,6 +76,7 @@ digilent Diglent, Inc.
dlg Dialog Semiconductor
dlink D-Link Corporation
dmo Data Modul AG
+domintech Domintech Co., Ltd.
dptechnics DPTechnics
dragino Dragino Technology Co., Limited
ea Embedded Artists AB
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index b0d775d28e97..75bc5b8add2f 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -266,8 +266,12 @@ IIO
devm_iio_device_unregister()
devm_iio_kfifo_allocate()
devm_iio_kfifo_free()
+ devm_iio_triggered_buffer_setup()
+ devm_iio_triggered_buffer_cleanup()
devm_iio_trigger_alloc()
devm_iio_trigger_free()
+ devm_iio_trigger_register()
+ devm_iio_trigger_unregister()
devm_iio_channel_get()
devm_iio_channel_release()
devm_iio_channel_get_all()
diff --git a/MAINTAINERS b/MAINTAINERS
index 4f4d56123099..841ffa3833ff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -819,11 +819,11 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained
F: sound/aoa/
-APEX EMBEDDED SYSTEMS STX104 DAC DRIVER
+APEX EMBEDDED SYSTEMS STX104 IIO DRIVER
M: William Breathitt Gray <vilhelm.gray@gmail.com>
L: linux-iio@vger.kernel.org
S: Maintained
-F: drivers/iio/dac/stx104.c
+F: drivers/iio/adc/stx104.c
APM DRIVER
M: Jiri Kosina <jikos@kernel.org>
@@ -1993,6 +1993,13 @@ S: Maintained
F: drivers/media/i2c/as3645a.c
F: include/media/i2c/as3645a.h
+ASAHI KASEI AK8974 DRIVER
+M: Linus Walleij <linus.walleij@linaro.org>
+L: linux-iio@vger.kernel.org
+W: http://www.akm.com/
+S: Supported
+F: drivers/iio/magnetometer/ak8974.c
+
ASC7621 HARDWARE MONITOR DRIVER
M: George Joseph <george.joseph@fairview5.com>
L: linux-hwmon@vger.kernel.org
@@ -5318,6 +5325,77 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/aeroflex/
+GREYBUS SUBSYSTEM
+M: Johan Hovold <johan@kernel.org>
+M: Alex Elder <elder@kernel.org>
+M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+S: Maintained
+F: drivers/staging/greybus/
+
+GREYBUS AUDIO PROTOCOLS DRIVERS
+M: Vaibhav Agarwal <vaibhav.sr@gmail.com>
+M: Mark Greer <mgreer@animalcreek.com>
+S: Maintained
+F: drivers/staging/greybus/audio_apbridgea.c
+F: drivers/staging/greybus/audio_apbridgea.h
+F: drivers/staging/greybus/audio_codec.c
+F: drivers/staging/greybus/audio_codec.h
+F: drivers/staging/greybus/audio_gb.c
+F: drivers/staging/greybus/audio_manager.c
+F: drivers/staging/greybus/audio_manager.h
+F: drivers/staging/greybus/audio_manager_module.c
+F: drivers/staging/greybus/audio_manager_private.h
+F: drivers/staging/greybus/audio_manager_sysfs.c
+F: drivers/staging/greybus/audio_module.c
+F: drivers/staging/greybus/audio_topology.c
+
+GREYBUS PROTOCOLS DRIVERS
+M: Rui Miguel Silva <rmfrfs@gmail.com>
+S: Maintained
+F: drivers/staging/greybus/sdio.c
+F: drivers/staging/greybus/light.c
+F: drivers/staging/greybus/gpio.c
+F: drivers/staging/greybus/power_supply.c
+F: drivers/staging/greybus/spi.c
+F: drivers/staging/greybus/spilib.c
+
+GREYBUS PROTOCOLS DRIVERS
+M: Bryan O'Donoghue <pure.logic@nexus-software.ie>
+S: Maintained
+F: drivers/staging/greybus/loopback.c
+F: drivers/staging/greybus/timesync.c
+F: drivers/staging/greybus/timesync_platform.c
+
+GREYBUS PROTOCOLS DRIVERS
+M: Viresh Kumar <vireshk@kernel.org>
+S: Maintained
+F: drivers/staging/greybus/authentication.c
+F: drivers/staging/greybus/bootrom.c
+F: drivers/staging/greybus/firmware.h
+F: drivers/staging/greybus/fw-core.c
+F: drivers/staging/greybus/fw-download.c
+F: drivers/staging/greybus/fw-managament.c
+F: drivers/staging/greybus/greybus_authentication.h
+F: drivers/staging/greybus/greybus_firmware.h
+F: drivers/staging/greybus/hid.c
+F: drivers/staging/greybus/i2c.c
+F: drivers/staging/greybus/spi.c
+F: drivers/staging/greybus/spilib.c
+F: drivers/staging/greybus/spilib.h
+
+GREYBUS PROTOCOLS DRIVERS
+M: David Lin <dtwlin@gmail.com>
+S: Maintained
+F: drivers/staging/greybus/uart.c
+F: drivers/staging/greybus/log.c
+
+GREYBUS PLATFORM DRIVERS
+M: Vaibhav Hiremath <hvaibhav.linux@gmail.com>
+S: Maintained
+F: drivers/staging/greybus/arche-platform.c
+F: drivers/staging/greybus/arche-apb-ctrl.c
+F: drivers/staging/greybus/arche_platform.h
+
GSPCA FINEPIX SUBDRIVER
M: Frank Zago <frank@zago.net>
L: linux-media@vger.kernel.org
@@ -7548,6 +7626,12 @@ L: linux-iio@vger.kernel.org
S: Maintained
F: drivers/iio/potentiometer/mcp4531.c
+MEASUREMENT COMPUTING CIO-DAC IIO DRIVER
+M: William Breathitt Gray <vilhelm.gray@gmail.com>
+L: linux-iio@vger.kernel.org
+S: Maintained
+F: drivers/iio/dac/cio-dac.c
+
MEDIA DRIVERS FOR RENESAS - FCP
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
@@ -11263,6 +11347,7 @@ F: drivers/staging/media/lirc/
STAGING - LUSTRE PARALLEL FILESYSTEM
M: Oleg Drokin <oleg.drokin@intel.com>
M: Andreas Dilger <andreas.dilger@intel.com>
+M: James Simmons <jsimmons@infradead.org>
L: lustre-devel@lists.lustre.org (moderated for non-subscribers)
W: http://wiki.lustre.org/
S: Maintained
@@ -11289,13 +11374,6 @@ M: Florian Schilhabel <florian.c.schilhabel@googlemail.com>.
S: Odd Fixes
F: drivers/staging/rtl8712/
-STAGING - REALTEK RTL8723U WIRELESS DRIVER
-M: Larry Finger <Larry.Finger@lwfinger.net>
-M: Jes Sorensen <Jes.Sorensen@redhat.com>
-L: linux-wireless@vger.kernel.org
-S: Maintained
-F: drivers/staging/rtl8723au/
-
STAGING - SILICON MOTION SM750 FRAME BUFFER DRIVER
M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
M: Teddy Wang <teddy.wang@siliconmotion.com>
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 16288e777ec3..562af94bec35 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -59,7 +59,6 @@ static struct dentry *binder_debugfs_dir_entry_proc;
static struct binder_node *binder_context_mgr_node;
static kuid_t binder_context_mgr_uid = INVALID_UID;
static int binder_last_id;
-static struct workqueue_struct *binder_deferred_workqueue;
#define BINDER_DEBUG_ENTRY(name) \
static int binder_##name##_open(struct inode *inode, struct file *file) \
@@ -3227,7 +3226,7 @@ binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer)
if (hlist_unhashed(&proc->deferred_work_node)) {
hlist_add_head(&proc->deferred_work_node,
&binder_deferred_list);
- queue_work(binder_deferred_workqueue, &binder_deferred_work);
+ schedule_work(&binder_deferred_work);
}
mutex_unlock(&binder_deferred_lock);
}
@@ -3679,10 +3678,6 @@ static int __init binder_init(void)
{
int ret;
- binder_deferred_workqueue = create_singlethread_workqueue("binder");
- if (!binder_deferred_workqueue)
- return -ENOMEM;
-
binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);
if (binder_debugfs_dir_entry_root)
binder_debugfs_dir_entry_proc = debugfs_create_dir("proc",
diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig
index 25bcfa0b474f..2585821b24ab 100644
--- a/drivers/dma-buf/Kconfig
+++ b/drivers/dma-buf/Kconfig
@@ -17,4 +17,17 @@ config SYNC_FILE
Files fds, to the DRM driver for example. More details at
Documentation/sync_file.txt.
+config SW_SYNC
+ bool "Sync File Validation Framework"
+ default n
+ depends on SYNC_FILE
+ depends on DEBUG_FS
+ ---help---
+ A sync object driver that uses a 32bit counter to coordinate
+ synchronization. Useful when there is no hardware primitive backing
+ the synchronization.
+
+ WARNING: improper use of this can result in deadlocking kernel
+ drivers from userspace. Intended for test and debug only.
+
endmenu
diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
index f353db213a81..210a10bfad2b 100644
--- a/drivers/dma-buf/Makefile
+++ b/drivers/dma-buf/Makefile
@@ -1,2 +1,3 @@
obj-y := dma-buf.o fence.o reservation.o seqno-fence.o fence-array.o
obj-$(CONFIG_SYNC_FILE) += sync_file.o
+obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o
diff --git a/drivers/staging/android/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 115c9174705f..62e8e6dc7953 100644
--- a/drivers/staging/android/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -1,5 +1,5 @@
/*
- * drivers/dma-buf/sw_sync.c
+ * Sync File validation framework
*
* Copyright (C) 2012 Google, Inc.
*
@@ -23,8 +23,38 @@
#include "sync_debug.h"
#define CREATE_TRACE_POINTS
-#include "trace/sync.h"
+#include "sync_trace.h"
+/*
+ * SW SYNC validation framework
+ *
+ * A sync object driver that uses a 32bit counter to coordinate
+ * synchronization. Useful when there is no hardware primitive backing
+ * the synchronization.
+ *
+ * To start the framework just open:
+ *
+ * <debugfs>/sync/sw_sync
+ *
+ * That will create a sync timeline, all fences created under this timeline
+ * file descriptor will belong to the this timeline.
+ *
+ * The 'sw_sync' file can be opened many times as to create different
+ * timelines.
+ *
+ * Fences can be created with SW_SYNC_IOC_CREATE_FENCE ioctl with struct
+ * sw_sync_ioctl_create_fence as parameter.
+ *
+ * To increment the timeline counter, SW_SYNC_IOC_INC ioctl should be used
+ * with the increment as u32. This will update the last signaled value
+ * from the timeline and signal any fence that has a seqno smaller or equal
+ * to it.
+ *
+ * struct sw_sync_ioctl_create_fence
+ * @value: the seqno to initialise the fence with
+ * @name: the name of the new sync point
+ * @fence: return the fd of the new sync_file with the created fence
+ */
struct sw_sync_create_fence_data {
__u32 value;
char name[32];
@@ -35,6 +65,7 @@ struct sw_sync_create_fence_data {
#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\
struct sw_sync_create_fence_data)
+
#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32)
static const struct fence_ops timeline_fence_ops;
@@ -176,7 +207,7 @@ static void timeline_fence_release(struct fence *fence)
spin_lock_irqsave(fence->lock, flags);
list_del(&pt->child_list);
- if (WARN_ON_ONCE(!list_empty(&pt->active_list)))
+ if (!list_empty(&pt->active_list))
list_del(&pt->active_list);
spin_unlock_irqrestore(fence->lock, flags);
diff --git a/drivers/staging/android/sync_debug.c b/drivers/dma-buf/sync_debug.c
index 4c5a85595a85..fab95204cf74 100644
--- a/drivers/staging/android/sync_debug.c
+++ b/drivers/dma-buf/sync_debug.c
@@ -1,5 +1,5 @@
/*
- * drivers/base/sync.c
+ * Sync File validation framework and debug information
*
* Copyright (C) 2012 Google, Inc.
*
diff --git a/drivers/staging/android/sync_debug.h b/drivers/dma-buf/sync_debug.h
index fab66396d421..d269aa6783aa 100644
--- a/drivers/staging/android/sync_debug.h
+++ b/drivers/dma-buf/sync_debug.h
@@ -1,5 +1,5 @@
/*
- * include/linux/sync.h
+ * Sync File validation framework and debug infomation
*
* Copyright (C) 2012 Google, Inc.
*
diff --git a/drivers/staging/android/trace/sync.h b/drivers/dma-buf/sync_trace.h
index 6b5ce9640ddd..d13d59ff1b85 100644
--- a/drivers/staging/android/trace/sync.h
+++ b/drivers/dma-buf/sync_trace.h
@@ -1,11 +1,11 @@
#undef TRACE_SYSTEM
-#define TRACE_INCLUDE_PATH ../../drivers/staging/android/trace
-#define TRACE_SYSTEM sync
+#define TRACE_INCLUDE_PATH ../../drivers/dma-buf
+#define TRACE_SYSTEM sync_trace
#if !defined(_TRACE_SYNC_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_SYNC_H
-#include "../sync_debug.h"
+#include "sync_debug.h"
#include <linux/tracepoint.h>
TRACE_EVENT(sync_timeline,
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 78f148ea9d9f..2b791fe1e2bc 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -52,6 +52,27 @@ config BMC150_ACCEL_SPI
tristate
select REGMAP_SPI
+config DMARD06
+ tristate "Domintech DMARD06 Digital Accelerometer Driver"
+ depends on OF || COMPILE_TEST
+ depends on I2C
+ help
+ Say yes here to build support for the Domintech low-g tri-axial
+ digital accelerometers: DMARD05, DMARD06, DMARD07.
+
+ To compile this driver as a module, choose M here: the
+ module will be called dmard06.
+
+config DMARD09
+ tristate "Domintech DMARD09 3-axis Accelerometer Driver"
+ depends on I2C
+ help
+ Say yes here to get support for the Domintech DMARD09 3-axis
+ accelerometer.
+
+ Choosing M will build the driver as a module. If so, the module
+ will be called dmard09.
+
config HID_SENSOR_ACCEL_3D
depends on HID_SENSOR_HUB
select IIO_BUFFER
@@ -98,14 +119,35 @@ config IIO_ST_ACCEL_SPI_3AXIS
config KXSD9
tristate "Kionix KXSD9 Accelerometer Driver"
- depends on SPI
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for the Kionix KXSD9 accelerometer.
- Currently this only supports the device via an SPI interface.
+ It can be accessed using an (optional) SPI or I2C interface.
To compile this driver as a module, choose M here: the module
will be called kxsd9.
+config KXSD9_SPI
+ tristate "Kionix KXSD9 SPI transport"
+ depends on KXSD9
+ depends on SPI
+ default KXSD9
+ select REGMAP_SPI
+ help
+ Say yes here to enable the Kionix KXSD9 accelerometer
+ SPI transport channel.
+
+config KXSD9_I2C
+ tristate "Kionix KXSD9 I2C transport"
+ depends on KXSD9
+ depends on I2C
+ default KXSD9
+ select REGMAP_I2C
+ help
+ Say yes here to enable the Kionix KXSD9 accelerometer
+ I2C transport channel.
+
config KXCJK1013
tristate "Kionix 3-Axis Accelerometer Driver"
depends on I2C
@@ -119,6 +161,16 @@ config KXCJK1013
To compile this driver as a module, choose M here: the module will
be called kxcjk-1013.
+config MC3230
+ tristate "mCube MC3230 Digital Accelerometer Driver"
+ depends on I2C
+ help
+ Say yes here to build support for the mCube MC3230 low-g tri-axial
+ digital accelerometer.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mc3230.
+
config MMA7455
tristate
select IIO_BUFFER
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 6cedbecca2ee..f5d3ddee619e 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -8,9 +8,14 @@ obj-$(CONFIG_BMA220) += bma220_spi.o
obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
+obj-$(CONFIG_DMARD06) += dmard06.o
+obj-$(CONFIG_DMARD09) += dmard09.o
obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
obj-$(CONFIG_KXSD9) += kxsd9.o
+obj-$(CONFIG_KXSD9_SPI) += kxsd9-spi.o
+obj-$(CONFIG_KXSD9_I2C) += kxsd9-i2c.o
+obj-$(CONFIG_MC3230) += mc3230.o
obj-$(CONFIG_MMA7455) += mma7455_core.o
obj-$(CONFIG_MMA7455_I2C) += mma7455_i2c.o
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index e3f88ba5faf3..0890934ef66f 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -469,13 +469,14 @@ static int bma180_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
mutex_lock(&data->mutex);
- if (iio_buffer_enabled(indio_dev)) {
- mutex_unlock(&data->mutex);
- return -EBUSY;
- }
ret = bma180_get_data_reg(data, chan->scan_index);
mutex_unlock(&data->mutex);
+ iio_device_release_direct_mode(indio_dev);
if (ret < 0)
return ret;
*val = sign_extend32(ret >> chan->scan_type.shift,
diff --git a/drivers/iio/accel/dmard06.c b/drivers/iio/accel/dmard06.c
new file mode 100644
index 000000000000..656ca8e1927f
--- /dev/null
+++ b/drivers/iio/accel/dmard06.c
@@ -0,0 +1,241 @@
+/*
+ * IIO driver for Domintech DMARD06 accelerometer
+ *
+ * Copyright (C) 2016 Aleksei Mamlin <mamlinav@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+
+#define DMARD06_DRV_NAME "dmard06"
+
+/* Device data registers */
+#define DMARD06_CHIP_ID_REG 0x0f
+#define DMARD06_TOUT_REG 0x40
+#define DMARD06_XOUT_REG 0x41
+#define DMARD06_YOUT_REG 0x42
+#define DMARD06_ZOUT_REG 0x43
+#define DMARD06_CTRL1_REG 0x44
+
+/* Device ID value */
+#define DMARD05_CHIP_ID 0x05
+#define DMARD06_CHIP_ID 0x06
+#define DMARD07_CHIP_ID 0x07
+
+/* Device values */
+#define DMARD05_AXIS_SCALE_VAL 15625
+#define DMARD06_AXIS_SCALE_VAL 31250
+#define DMARD06_TEMP_CENTER_VAL 25
+#define DMARD06_SIGN_BIT 7
+
+/* Device power modes */
+#define DMARD06_MODE_NORMAL 0x27
+#define DMARD06_MODE_POWERDOWN 0x00
+
+/* Device channels */
+#define DMARD06_ACCEL_CHANNEL(_axis, _reg) { \
+ .type = IIO_ACCEL, \
+ .address = _reg, \
+ .channel2 = IIO_MOD_##_axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .modified = 1, \
+}
+
+#define DMARD06_TEMP_CHANNEL(_reg) { \
+ .type = IIO_TEMP, \
+ .address = _reg, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_OFFSET), \
+}
+
+struct dmard06_data {
+ struct i2c_client *client;
+ u8 chip_id;
+};
+
+static const struct iio_chan_spec dmard06_channels[] = {
+ DMARD06_ACCEL_CHANNEL(X, DMARD06_XOUT_REG),
+ DMARD06_ACCEL_CHANNEL(Y, DMARD06_YOUT_REG),
+ DMARD06_ACCEL_CHANNEL(Z, DMARD06_ZOUT_REG),
+ DMARD06_TEMP_CHANNEL(DMARD06_TOUT_REG),
+};
+
+static int dmard06_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct dmard06_data *dmard06 = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = i2c_smbus_read_byte_data(dmard06->client,
+ chan->address);
+ if (ret < 0) {
+ dev_err(&dmard06->client->dev,
+ "Error reading data: %d\n", ret);
+ return ret;
+ }
+
+ *val = sign_extend32(ret, DMARD06_SIGN_BIT);
+
+ if (dmard06->chip_id == DMARD06_CHIP_ID)
+ *val = *val >> 1;
+
+ switch (chan->type) {
+ case IIO_ACCEL:
+ return IIO_VAL_INT;
+ case IIO_TEMP:
+ if (dmard06->chip_id != DMARD06_CHIP_ID)
+ *val = *val / 2;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_OFFSET:
+ switch (chan->type) {
+ case IIO_TEMP:
+ *val = DMARD06_TEMP_CENTER_VAL;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->type) {
+ case IIO_ACCEL:
+ *val = 0;
+ if (dmard06->chip_id == DMARD06_CHIP_ID)
+ *val2 = DMARD06_AXIS_SCALE_VAL;
+ else
+ *val2 = DMARD05_AXIS_SCALE_VAL;
+ return IIO_VAL_INT_PLUS_MICRO;
+ default:
+ return -EINVAL;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info dmard06_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = dmard06_read_raw,
+};
+
+static int dmard06_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret;
+ struct iio_dev *indio_dev;
+ struct dmard06_data *dmard06;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "I2C check functionality failed\n");
+ return -ENXIO;
+ }
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*dmard06));
+ if (!indio_dev) {
+ dev_err(&client->dev, "Failed to allocate iio device\n");
+ return -ENOMEM;
+ }
+
+ dmard06 = iio_priv(indio_dev);
+ dmard06->client = client;
+
+ ret = i2c_smbus_read_byte_data(dmard06->client, DMARD06_CHIP_ID_REG);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error reading chip id: %d\n", ret);
+ return ret;
+ }
+
+ if (ret != DMARD05_CHIP_ID && ret != DMARD06_CHIP_ID &&
+ ret != DMARD07_CHIP_ID) {
+ dev_err(&client->dev, "Invalid chip id: %02d\n", ret);
+ return -ENODEV;
+ }
+
+ dmard06->chip_id = ret;
+
+ i2c_set_clientdata(client, indio_dev);
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->name = DMARD06_DRV_NAME;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = dmard06_channels;
+ indio_dev->num_channels = ARRAY_SIZE(dmard06_channels);
+ indio_dev->info = &dmard06_info;
+
+ return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int dmard06_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct dmard06_data *dmard06 = iio_priv(indio_dev);
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(dmard06->client, DMARD06_CTRL1_REG,
+ DMARD06_MODE_POWERDOWN);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int dmard06_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct dmard06_data *dmard06 = iio_priv(indio_dev);
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(dmard06->client, DMARD06_CTRL1_REG,
+ DMARD06_MODE_NORMAL);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(dmard06_pm_ops, dmard06_suspend, dmard06_resume);
+#define DMARD06_PM_OPS (&dmard06_pm_ops)
+#else
+#define DMARD06_PM_OPS NULL
+#endif
+
+static const struct i2c_device_id dmard06_id[] = {
+ { "dmard05", 0 },
+ { "dmard06", 0 },
+ { "dmard07", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, dmard06_id);
+
+static const struct of_device_id dmard06_of_match[] = {
+ { .compatible = "domintech,dmard05" },
+ { .compatible = "domintech,dmard06" },
+ { .compatible = "domintech,dmard07" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, dmard06_of_match);
+
+static struct i2c_driver dmard06_driver = {
+ .probe = dmard06_probe,
+ .id_table = dmard06_id,
+ .driver = {
+ .name = DMARD06_DRV_NAME,
+ .of_match_table = of_match_ptr(dmard06_of_match),
+ .pm = DMARD06_PM_OPS,
+ },
+};
+module_i2c_driver(dmard06_driver);
+
+MODULE_AUTHOR("Aleksei Mamlin <mamlinav@gmail.com>");
+MODULE_DESCRIPTION("Domintech DMARD06 accelerometer driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/dmard09.c b/drivers/iio/accel/dmard09.c
new file mode 100644
index 000000000000..d3a28f96565c
--- /dev/null
+++ b/drivers/iio/accel/dmard09.c
@@ -0,0 +1,157 @@
+/*
+ * IIO driver for the 3-axis accelerometer Domintech DMARD09.
+ *
+ * Copyright (c) 2016, Jelle van der Waa <jelle@vdwaa.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#include <asm/unaligned.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+
+#define DMARD09_DRV_NAME "dmard09"
+
+#define DMARD09_REG_CHIPID 0x18
+#define DMARD09_REG_STAT 0x0A
+#define DMARD09_REG_X 0x0C
+#define DMARD09_REG_Y 0x0E
+#define DMARD09_REG_Z 0x10
+#define DMARD09_CHIPID 0x95
+
+#define DMARD09_BUF_LEN 8
+#define DMARD09_AXIS_X 0
+#define DMARD09_AXIS_Y 1
+#define DMARD09_AXIS_Z 2
+#define DMARD09_AXIS_X_OFFSET ((DMARD09_AXIS_X + 1) * 2)
+#define DMARD09_AXIS_Y_OFFSET ((DMARD09_AXIS_Y + 1 )* 2)
+#define DMARD09_AXIS_Z_OFFSET ((DMARD09_AXIS_Z + 1) * 2)
+
+struct dmard09_data {
+ struct i2c_client *client;
+};
+
+#define DMARD09_CHANNEL(_axis, offset) { \
+ .type = IIO_ACCEL, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .modified = 1, \
+ .address = offset, \
+ .channel2 = IIO_MOD_##_axis, \
+}
+
+static const struct iio_chan_spec dmard09_channels[] = {
+ DMARD09_CHANNEL(X, DMARD09_AXIS_X_OFFSET),
+ DMARD09_CHANNEL(Y, DMARD09_AXIS_Y_OFFSET),
+ DMARD09_CHANNEL(Z, DMARD09_AXIS_Z_OFFSET),
+};
+
+static int dmard09_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct dmard09_data *data = iio_priv(indio_dev);
+ u8 buf[DMARD09_BUF_LEN];
+ int ret;
+ s16 accel;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ /*
+ * Read from the DMAR09_REG_STAT register, since the chip
+ * caches reads from the individual X, Y, Z registers.
+ */
+ ret = i2c_smbus_read_i2c_block_data(data->client,
+ DMARD09_REG_STAT,
+ DMARD09_BUF_LEN, buf);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg %d\n",
+ DMARD09_REG_STAT);
+ return ret;
+ }
+
+ accel = get_unaligned_le16(&buf[chan->address]);
+
+ /* Remove lower 3 bits and sign extend */
+ accel <<= 4;
+ accel >>= 7;
+
+ *val = accel;
+
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info dmard09_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = dmard09_read_raw,
+};
+
+static int dmard09_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret;
+ struct iio_dev *indio_dev;
+ struct dmard09_data *data;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev) {
+ dev_err(&client->dev, "iio allocation failed\n");
+ return -ENOMEM;
+ }
+
+ data = iio_priv(indio_dev);
+ data->client = client;
+
+ ret = i2c_smbus_read_byte_data(data->client, DMARD09_REG_CHIPID);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error reading chip id %d\n", ret);
+ return ret;
+ }
+
+ if (ret != DMARD09_CHIPID) {
+ dev_err(&client->dev, "Invalid chip id %d\n", ret);
+ return -ENODEV;
+ }
+
+ i2c_set_clientdata(client, indio_dev);
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->name = DMARD09_DRV_NAME;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = dmard09_channels;
+ indio_dev->num_channels = ARRAY_SIZE(dmard09_channels);
+ indio_dev->info = &dmard09_info;
+
+ return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static const struct i2c_device_id dmard09_id[] = {
+ { "dmard09", 0},
+ { },
+};
+
+MODULE_DEVICE_TABLE(i2c, dmard09_id);
+
+static struct i2c_driver dmard09_driver = {
+ .driver = {
+ .name = DMARD09_DRV_NAME
+ },
+ .probe = dmard09_probe,
+ .id_table = dmard09_id,
+};
+
+module_i2c_driver(dmard09_driver);
+
+MODULE_AUTHOR("Jelle van der Waa <jelle@vdwaa.nl>");
+MODULE_DESCRIPTION("DMARD09 3-axis accelerometer driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index 765a72362dc6..3f968c46e667 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -1392,6 +1392,7 @@ static const struct acpi_device_id kx_acpi_match[] = {
{"KXCJ1013", KXCJK1013},
{"KXCJ1008", KXCJ91008},
{"KXCJ9000", KXCJ91008},
+ {"KIOX000A", KXCJ91008},
{"KXTJ1009", KXTJ21009},
{"SMO8500", KXCJ91008},
{ },
diff --git a/drivers/iio/accel/kxsd9-i2c.c b/drivers/iio/accel/kxsd9-i2c.c
new file mode 100644
index 000000000000..95e20855d2ef
--- /dev/null
+++ b/drivers/iio/accel/kxsd9-i2c.c
@@ -0,0 +1,64 @@
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/regmap.h>
+
+#include "kxsd9.h"
+
+static int kxsd9_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ static const struct regmap_config config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0x0e,
+ };
+ struct regmap *regmap;
+
+ regmap = devm_regmap_init_i2c(i2c, &config);
+ if (IS_ERR(regmap)) {
+ dev_err(&i2c->dev, "Failed to register i2c regmap %d\n",
+ (int)PTR_ERR(regmap));
+ return PTR_ERR(regmap);
+ }
+
+ return kxsd9_common_probe(&i2c->dev,
+ regmap,
+ i2c->name);
+}
+
+static int kxsd9_i2c_remove(struct i2c_client *client)
+{
+ return kxsd9_common_remove(&client->dev);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id kxsd9_of_match[] = {
+ { .compatible = "kionix,kxsd9", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, kxsd9_of_match);
+#else
+#define kxsd9_of_match NULL
+#endif
+
+static const struct i2c_device_id kxsd9_i2c_id[] = {
+ {"kxsd9", 0},
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, kxsd9_i2c_id);
+
+static struct i2c_driver kxsd9_i2c_driver = {
+ .driver = {
+ .name = "kxsd9",
+ .of_match_table = of_match_ptr(kxsd9_of_match),
+ .pm = &kxsd9_dev_pm_ops,
+ },
+ .probe = kxsd9_i2c_probe,
+ .remove = kxsd9_i2c_remove,
+ .id_table = kxsd9_i2c_id,
+};
+module_i2c_driver(kxsd9_i2c_driver);
diff --git a/drivers/iio/accel/kxsd9-spi.c b/drivers/iio/accel/kxsd9-spi.c
new file mode 100644
index 000000000000..b7d0078fd00e
--- /dev/null
+++ b/drivers/iio/accel/kxsd9-spi.c
@@ -0,0 +1,56 @@
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+
+#include "kxsd9.h"
+
+static int kxsd9_spi_probe(struct spi_device *spi)
+{
+ static const struct regmap_config config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0x0e,
+ };
+ struct regmap *regmap;
+
+ spi->mode = SPI_MODE_0;
+ regmap = devm_regmap_init_spi(spi, &config);
+ if (IS_ERR(regmap)) {
+ dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
+ __func__, PTR_ERR(regmap));
+ return PTR_ERR(regmap);
+ }
+
+ return kxsd9_common_probe(&spi->dev,
+ regmap,
+ spi_get_device_id(spi)->name);
+}
+
+static int kxsd9_spi_remove(struct spi_device *spi)
+{
+ return kxsd9_common_remove(&spi->dev);
+}
+
+static const struct spi_device_id kxsd9_spi_id[] = {
+ {"kxsd9", 0},
+ { },
+};
+MODULE_DEVICE_TABLE(spi, kxsd9_spi_id);
+
+static struct spi_driver kxsd9_spi_driver = {
+ .driver = {
+ .name = "kxsd9",
+ .pm = &kxsd9_dev_pm_ops,
+ },
+ .probe = kxsd9_spi_probe,
+ .remove = kxsd9_spi_remove,
+ .id_table = kxsd9_spi_id,
+};
+module_spi_driver(kxsd9_spi_driver);
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
+MODULE_DESCRIPTION("Kionix KXSD9 SPI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c
index 9d72d4bcf5e9..9af60ac70738 100644
--- a/drivers/iio/accel/kxsd9.c
+++ b/drivers/iio/accel/kxsd9.c
@@ -12,19 +12,25 @@
* I have a suitable wire made up.
*
* TODO: Support the motion detector
- * Uses register address incrementing so could have a
- * heavily optimized ring buffer access function.
*/
#include <linux/device.h>
#include <linux/kernel.h>
-#include <linux/spi/spi.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/module.h>
-
+#include <linux/regmap.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+
+#include "kxsd9.h"
#define KXSD9_REG_X 0x00
#define KXSD9_REG_Y 0x02
@@ -33,28 +39,45 @@
#define KXSD9_REG_RESET 0x0a
#define KXSD9_REG_CTRL_C 0x0c
-#define KXSD9_FS_MASK 0x03
+#define KXSD9_CTRL_C_FS_MASK 0x03
+#define KXSD9_CTRL_C_FS_8G 0x00
+#define KXSD9_CTRL_C_FS_6G 0x01
+#define KXSD9_CTRL_C_FS_4G 0x02
+#define KXSD9_CTRL_C_FS_2G 0x03
+#define KXSD9_CTRL_C_MOT_LAT BIT(3)
+#define KXSD9_CTRL_C_MOT_LEV BIT(4)
+#define KXSD9_CTRL_C_LP_MASK 0xe0
+#define KXSD9_CTRL_C_LP_NONE 0x00
+#define KXSD9_CTRL_C_LP_2000HZC BIT(5)
+#define KXSD9_CTRL_C_LP_2000HZB BIT(6)
+#define KXSD9_CTRL_C_LP_2000HZA (BIT(5)|BIT(6))
+#define KXSD9_CTRL_C_LP_1000HZ BIT(7)
+#define KXSD9_CTRL_C_LP_500HZ (BIT(7)|BIT(5))
+#define KXSD9_CTRL_C_LP_100HZ (BIT(7)|BIT(6))
+#define KXSD9_CTRL_C_LP_50HZ (BIT(7)|BIT(6)|BIT(5))
#define KXSD9_REG_CTRL_B 0x0d
-#define KXSD9_REG_CTRL_A 0x0e
-#define KXSD9_READ(a) (0x80 | (a))
-#define KXSD9_WRITE(a) (a)
+#define KXSD9_CTRL_B_CLK_HLD BIT(7)
+#define KXSD9_CTRL_B_ENABLE BIT(6)
+#define KXSD9_CTRL_B_ST BIT(5) /* Self-test */
+
+#define KXSD9_REG_CTRL_A 0x0e
-#define KXSD9_STATE_RX_SIZE 2
-#define KXSD9_STATE_TX_SIZE 2
/**
* struct kxsd9_state - device related storage
- * @buf_lock: protect the rx and tx buffers.
- * @us: spi device
- * @rx: single rx buffer storage
- * @tx: single tx buffer storage
- **/
+ * @dev: pointer to the parent device
+ * @map: regmap to the device
+ * @orientation: mounting matrix, flipped axis etc
+ * @regs: regulators for this device, VDD and IOVDD
+ * @scale: the current scaling setting
+ */
struct kxsd9_state {
- struct mutex buf_lock;
- struct spi_device *us;
- u8 rx[KXSD9_STATE_RX_SIZE] ____cacheline_aligned;
- u8 tx[KXSD9_STATE_TX_SIZE];
+ struct device *dev;
+ struct regmap *map;
+ struct iio_mount_matrix orientation;
+ struct regulator_bulk_data regs[2];
+ u8 scale;
};
#define KXSD9_SCALE_2G "0.011978"
@@ -65,6 +88,14 @@ struct kxsd9_state {
/* reverse order */
static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 };
+#define KXSD9_ZERO_G_OFFSET -2048
+
+/*
+ * Regulator names
+ */
+static const char kxsd9_reg_vdd[] = "vdd";
+static const char kxsd9_reg_iovdd[] = "iovdd";
+
static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
{
int ret, i;
@@ -79,42 +110,17 @@ static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
if (!foundit)
return -EINVAL;
- mutex_lock(&st->buf_lock);
- ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
+ ret = regmap_update_bits(st->map,
+ KXSD9_REG_CTRL_C,
+ KXSD9_CTRL_C_FS_MASK,
+ i);
if (ret < 0)
goto error_ret;
- st->tx[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C);
- st->tx[1] = (ret & ~KXSD9_FS_MASK) | i;
- ret = spi_write(st->us, st->tx, 2);
-error_ret:
- mutex_unlock(&st->buf_lock);
- return ret;
-}
+ /* Cached scale when the sensor is powered down */
+ st->scale = i;
-static int kxsd9_read(struct iio_dev *indio_dev, u8 address)
-{
- int ret;
- struct kxsd9_state *st = iio_priv(indio_dev);
- struct spi_transfer xfers[] = {
- {
- .bits_per_word = 8,
- .len = 1,
- .delay_usecs = 200,
- .tx_buf = st->tx,
- }, {
- .bits_per_word = 8,
- .len = 2,
- .rx_buf = st->rx,
- },
- };
-
- mutex_lock(&st->buf_lock);
- st->tx[0] = KXSD9_READ(address);
- ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
- if (!ret)
- ret = (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0);
- mutex_unlock(&st->buf_lock);
+error_ret:
return ret;
}
@@ -136,6 +142,9 @@ static int kxsd9_write_raw(struct iio_dev *indio_dev,
long mask)
{
int ret = -EINVAL;
+ struct kxsd9_state *st = iio_priv(indio_dev);
+
+ pm_runtime_get_sync(st->dev);
if (mask == IIO_CHAN_INFO_SCALE) {
/* Check no integer component */
@@ -144,6 +153,9 @@ static int kxsd9_write_raw(struct iio_dev *indio_dev,
ret = kxsd9_write_scale(indio_dev, val2);
}
+ pm_runtime_mark_last_busy(st->dev);
+ pm_runtime_put_autosuspend(st->dev);
+
return ret;
}
@@ -153,46 +165,154 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev,
{
int ret = -EINVAL;
struct kxsd9_state *st = iio_priv(indio_dev);
+ unsigned int regval;
+ __be16 raw_val;
+ u16 nval;
+
+ pm_runtime_get_sync(st->dev);
switch (mask) {
case IIO_CHAN_INFO_RAW:
- ret = kxsd9_read(indio_dev, chan->address);
- if (ret < 0)
+ ret = regmap_bulk_read(st->map, chan->address, &raw_val,
+ sizeof(raw_val));
+ if (ret)
goto error_ret;
- *val = ret;
+ nval = be16_to_cpu(raw_val);
+ /* Only 12 bits are valid */
+ nval >>= 4;
+ *val = nval;
+ ret = IIO_VAL_INT;
+ break;
+ case IIO_CHAN_INFO_OFFSET:
+ /* This has a bias of -2048 */
+ *val = KXSD9_ZERO_G_OFFSET;
ret = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
- ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
+ ret = regmap_read(st->map,
+ KXSD9_REG_CTRL_C,
+ &regval);
if (ret < 0)
goto error_ret;
*val = 0;
- *val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK];
+ *val2 = kxsd9_micro_scales[regval & KXSD9_CTRL_C_FS_MASK];
ret = IIO_VAL_INT_PLUS_MICRO;
break;
}
error_ret:
+ pm_runtime_mark_last_busy(st->dev);
+ pm_runtime_put_autosuspend(st->dev);
+
return ret;
};
-#define KXSD9_ACCEL_CHAN(axis) \
+
+static irqreturn_t kxsd9_trigger_handler(int irq, void *p)
+{
+ const struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct kxsd9_state *st = iio_priv(indio_dev);
+ int ret;
+ /* 4 * 16bit values AND timestamp */
+ __be16 hw_values[8];
+
+ ret = regmap_bulk_read(st->map,
+ KXSD9_REG_X,
+ &hw_values,
+ 8);
+ if (ret) {
+ dev_err(st->dev,
+ "error reading data\n");
+ return ret;
+ }
+
+ iio_push_to_buffers_with_timestamp(indio_dev,
+ hw_values,
+ iio_get_time_ns(indio_dev));
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int kxsd9_buffer_preenable(struct iio_dev *indio_dev)
+{
+ struct kxsd9_state *st = iio_priv(indio_dev);
+
+ pm_runtime_get_sync(st->dev);
+
+ return 0;
+}
+
+static int kxsd9_buffer_postdisable(struct iio_dev *indio_dev)
+{
+ struct kxsd9_state *st = iio_priv(indio_dev);
+
+ pm_runtime_mark_last_busy(st->dev);
+ pm_runtime_put_autosuspend(st->dev);
+
+ return 0;
+}
+
+static const struct iio_buffer_setup_ops kxsd9_buffer_setup_ops = {
+ .preenable = kxsd9_buffer_preenable,
+ .postenable = iio_triggered_buffer_postenable,
+ .predisable = iio_triggered_buffer_predisable,
+ .postdisable = kxsd9_buffer_postdisable,
+};
+
+static const struct iio_mount_matrix *
+kxsd9_get_mount_matrix(const struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan)
+{
+ struct kxsd9_state *st = iio_priv(indio_dev);
+
+ return &st->orientation;
+}
+
+static const struct iio_chan_spec_ext_info kxsd9_ext_info[] = {
+ IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, kxsd9_get_mount_matrix),
+ { },
+};
+
+#define KXSD9_ACCEL_CHAN(axis, index) \
{ \
.type = IIO_ACCEL, \
.modified = 1, \
.channel2 = IIO_MOD_##axis, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_OFFSET), \
+ .ext_info = kxsd9_ext_info, \
.address = KXSD9_REG_##axis, \
+ .scan_index = index, \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = 12, \
+ .storagebits = 16, \
+ .shift = 4, \
+ .endianness = IIO_BE, \
+ }, \
}
static const struct iio_chan_spec kxsd9_channels[] = {
- KXSD9_ACCEL_CHAN(X), KXSD9_ACCEL_CHAN(Y), KXSD9_ACCEL_CHAN(Z),
+ KXSD9_ACCEL_CHAN(X, 0),
+ KXSD9_ACCEL_CHAN(Y, 1),
+ KXSD9_ACCEL_CHAN(Z, 2),
{
.type = IIO_VOLTAGE,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.indexed = 1,
.address = KXSD9_REG_AUX,
- }
+ .scan_index = 3,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 12,
+ .storagebits = 16,
+ .shift = 4,
+ .endianness = IIO_BE,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(4),
};
static const struct attribute_group kxsd9_attribute_group = {
@@ -203,17 +323,69 @@ static int kxsd9_power_up(struct kxsd9_state *st)
{
int ret;
- st->tx[0] = 0x0d;
- st->tx[1] = 0x40;
- ret = spi_write(st->us, st->tx, 2);
+ /* Enable the regulators */
+ ret = regulator_bulk_enable(ARRAY_SIZE(st->regs), st->regs);
+ if (ret) {
+ dev_err(st->dev, "Cannot enable regulators\n");
+ return ret;
+ }
+
+ /* Power up */
+ ret = regmap_write(st->map,
+ KXSD9_REG_CTRL_B,
+ KXSD9_CTRL_B_ENABLE);
if (ret)
return ret;
- st->tx[0] = 0x0c;
- st->tx[1] = 0x9b;
- return spi_write(st->us, st->tx, 2);
+ /*
+ * Set 1000Hz LPF, 2g fullscale, motion wakeup threshold 1g,
+ * latched wakeup
+ */
+ ret = regmap_write(st->map,
+ KXSD9_REG_CTRL_C,
+ KXSD9_CTRL_C_LP_1000HZ |
+ KXSD9_CTRL_C_MOT_LEV |
+ KXSD9_CTRL_C_MOT_LAT |
+ st->scale);
+ if (ret)
+ return ret;
+
+ /*
+ * Power-up time depends on the LPF setting, but typ 15.9 ms, let's
+ * set 20 ms to allow for some slack.
+ */
+ msleep(20);
+
+ return 0;
};
+static int kxsd9_power_down(struct kxsd9_state *st)
+{
+ int ret;
+
+ /*
+ * Set into low power mode - since there may be more users of the
+ * regulators this is the first step of the power saving: it will
+ * make sure we conserve power even if there are others users on the
+ * regulators.
+ */
+ ret = regmap_update_bits(st->map,
+ KXSD9_REG_CTRL_B,
+ KXSD9_CTRL_B_ENABLE,
+ 0);
+ if (ret)
+ return ret;
+
+ /* Disable the regulators */
+ ret = regulator_bulk_disable(ARRAY_SIZE(st->regs), st->regs);
+ if (ret) {
+ dev_err(st->dev, "Cannot disable regulators\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static const struct iio_info kxsd9_info = {
.read_raw = &kxsd9_read_raw,
.write_raw = &kxsd9_write_raw,
@@ -221,57 +393,136 @@ static const struct iio_info kxsd9_info = {
.driver_module = THIS_MODULE,
};
-static int kxsd9_probe(struct spi_device *spi)
+/* Four channels apart from timestamp, scan mask = 0x0f */
+static const unsigned long kxsd9_scan_masks[] = { 0xf, 0 };
+
+int kxsd9_common_probe(struct device *dev,
+ struct regmap *map,
+ const char *name)
{
struct iio_dev *indio_dev;
struct kxsd9_state *st;
+ int ret;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
- spi_set_drvdata(spi, indio_dev);
+ st->dev = dev;
+ st->map = map;
- st->us = spi;
- mutex_init(&st->buf_lock);
indio_dev->channels = kxsd9_channels;
indio_dev->num_channels = ARRAY_SIZE(kxsd9_channels);
- indio_dev->name = spi_get_device_id(spi)->name;
- indio_dev->dev.parent = &spi->dev;
+ indio_dev->name = name;
+ indio_dev->dev.parent = dev;
indio_dev->info = &kxsd9_info;
indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->available_scan_masks = kxsd9_scan_masks;
+
+ /* Read the mounting matrix, if present */
+ ret = of_iio_read_mount_matrix(dev,
+ "mount-matrix",
+ &st->orientation);
+ if (ret)
+ return ret;
+
+ /* Fetch and turn on regulators */
+ st->regs[0].supply = kxsd9_reg_vdd;
+ st->regs[1].supply = kxsd9_reg_iovdd;
+ ret = devm_regulator_bulk_get(dev,
+ ARRAY_SIZE(st->regs),
+ st->regs);
+ if (ret) {
+ dev_err(dev, "Cannot get regulators\n");
+ return ret;
+ }
+ /* Default scaling */
+ st->scale = KXSD9_CTRL_C_FS_2G;
- spi->mode = SPI_MODE_0;
- spi_setup(spi);
kxsd9_power_up(st);
- return iio_device_register(indio_dev);
+ ret = iio_triggered_buffer_setup(indio_dev,
+ iio_pollfunc_store_time,
+ kxsd9_trigger_handler,
+ &kxsd9_buffer_setup_ops);
+ if (ret) {
+ dev_err(dev, "triggered buffer setup failed\n");
+ goto err_power_down;
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto err_cleanup_buffer;
+
+ dev_set_drvdata(dev, indio_dev);
+
+ /* Enable runtime PM */
+ pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ /*
+ * Set autosuspend to two orders of magnitude larger than the
+ * start-up time. 20ms start-up time means 2000ms autosuspend,
+ * i.e. 2 seconds.
+ */
+ pm_runtime_set_autosuspend_delay(dev, 2000);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_put(dev);
+
+ return 0;
+
+err_cleanup_buffer:
+ iio_triggered_buffer_cleanup(indio_dev);
+err_power_down:
+ kxsd9_power_down(st);
+
+ return ret;
}
+EXPORT_SYMBOL(kxsd9_common_probe);
-static int kxsd9_remove(struct spi_device *spi)
+int kxsd9_common_remove(struct device *dev)
{
- iio_device_unregister(spi_get_drvdata(spi));
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct kxsd9_state *st = iio_priv(indio_dev);
+
+ iio_triggered_buffer_cleanup(indio_dev);
+ iio_device_unregister(indio_dev);
+ pm_runtime_get_sync(dev);
+ pm_runtime_put_noidle(dev);
+ pm_runtime_disable(dev);
+ kxsd9_power_down(st);
return 0;
}
+EXPORT_SYMBOL(kxsd9_common_remove);
-static const struct spi_device_id kxsd9_id[] = {
- {"kxsd9", 0},
- { },
-};
-MODULE_DEVICE_TABLE(spi, kxsd9_id);
+#ifdef CONFIG_PM
+static int kxsd9_runtime_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct kxsd9_state *st = iio_priv(indio_dev);
-static struct spi_driver kxsd9_driver = {
- .driver = {
- .name = "kxsd9",
- },
- .probe = kxsd9_probe,
- .remove = kxsd9_remove,
- .id_table = kxsd9_id,
+ return kxsd9_power_down(st);
+}
+
+static int kxsd9_runtime_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct kxsd9_state *st = iio_priv(indio_dev);
+
+ return kxsd9_power_up(st);
+}
+#endif /* CONFIG_PM */
+
+const struct dev_pm_ops kxsd9_dev_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(kxsd9_runtime_suspend,
+ kxsd9_runtime_resume, NULL)
};
-module_spi_driver(kxsd9_driver);
+EXPORT_SYMBOL(kxsd9_dev_pm_ops);
MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
-MODULE_DESCRIPTION("Kionix KXSD9 SPI driver");
+MODULE_DESCRIPTION("Kionix KXSD9 driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/kxsd9.h b/drivers/iio/accel/kxsd9.h
new file mode 100644
index 000000000000..7e8a28168310
--- /dev/null
+++ b/drivers/iio/accel/kxsd9.h
@@ -0,0 +1,12 @@
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+#define KXSD9_STATE_RX_SIZE 2
+#define KXSD9_STATE_TX_SIZE 2
+
+int kxsd9_common_probe(struct device *dev,
+ struct regmap *map,
+ const char *name);
+int kxsd9_common_remove(struct device *dev);
+
+extern const struct dev_pm_ops kxsd9_dev_pm_ops;
diff --git a/drivers/iio/accel/mc3230.c b/drivers/iio/accel/mc3230.c
new file mode 100644
index 000000000000..4ea2ff623a6d
--- /dev/null
+++ b/drivers/iio/accel/mc3230.c
@@ -0,0 +1,211 @@
+/**
+ * mCube MC3230 3-Axis Accelerometer
+ *
+ * Copyright (c) 2016 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * IIO driver for mCube MC3230; 7-bit I2C address: 0x4c.
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define MC3230_REG_XOUT 0x00
+#define MC3230_REG_YOUT 0x01
+#define MC3230_REG_ZOUT 0x02
+
+#define MC3230_REG_MODE 0x07
+#define MC3230_MODE_OPCON_MASK 0x03
+#define MC3230_MODE_OPCON_WAKE 0x01
+#define MC3230_MODE_OPCON_STANDBY 0x03
+
+#define MC3230_REG_CHIP_ID 0x18
+#define MC3230_CHIP_ID 0x01
+
+#define MC3230_REG_PRODUCT_CODE 0x3b
+#define MC3230_PRODUCT_CODE 0x19
+
+/*
+ * The accelerometer has one measurement range:
+ *
+ * -1.5g - +1.5g (8-bit, signed)
+ *
+ * scale = (1.5 + 1.5) * 9.81 / (2^8 - 1) = 0.115411765
+ */
+
+static const int mc3230_nscale = 115411765;
+
+#define MC3230_CHANNEL(reg, axis) { \
+ .type = IIO_ACCEL, \
+ .address = reg, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+}
+
+static const struct iio_chan_spec mc3230_channels[] = {
+ MC3230_CHANNEL(MC3230_REG_XOUT, X),
+ MC3230_CHANNEL(MC3230_REG_YOUT, Y),
+ MC3230_CHANNEL(MC3230_REG_ZOUT, Z),
+};
+
+struct mc3230_data {
+ struct i2c_client *client;
+};
+
+static int mc3230_set_opcon(struct mc3230_data *data, int opcon)
+{
+ int ret;
+ struct i2c_client *client = data->client;
+
+ ret = i2c_smbus_read_byte_data(client, MC3230_REG_MODE);
+ if (ret < 0) {
+ dev_err(&client->dev, "failed to read mode reg: %d\n", ret);
+ return ret;
+ }
+
+ ret &= ~MC3230_MODE_OPCON_MASK;
+ ret |= opcon;
+
+ ret = i2c_smbus_write_byte_data(client, MC3230_REG_MODE, ret);
+ if (ret < 0) {
+ dev_err(&client->dev, "failed to write mode reg: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mc3230_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct mc3230_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = i2c_smbus_read_byte_data(data->client, chan->address);
+ if (ret < 0)
+ return ret;
+ *val = sign_extend32(ret, 7);
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ *val2 = mc3230_nscale;
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info mc3230_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = mc3230_read_raw,
+};
+
+static int mc3230_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret;
+ struct iio_dev *indio_dev;
+ struct mc3230_data *data;
+
+ /* First check chip-id and product-id */
+ ret = i2c_smbus_read_byte_data(client, MC3230_REG_CHIP_ID);
+ if (ret != MC3230_CHIP_ID)
+ return (ret < 0) ? ret : -ENODEV;
+
+ ret = i2c_smbus_read_byte_data(client, MC3230_REG_PRODUCT_CODE);
+ if (ret != MC3230_PRODUCT_CODE)
+ return (ret < 0) ? ret : -ENODEV;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev) {
+ dev_err(&client->dev, "iio allocation failed!\n");
+ return -ENOMEM;
+ }
+
+ data = iio_priv(indio_dev);
+ data->client = client;
+ i2c_set_clientdata(client, indio_dev);
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->info = &mc3230_info;
+ indio_dev->name = "mc3230";
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = mc3230_channels;
+ indio_dev->num_channels = ARRAY_SIZE(mc3230_channels);
+
+ ret = mc3230_set_opcon(data, MC3230_MODE_OPCON_WAKE);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&client->dev, "device_register failed\n");
+ mc3230_set_opcon(data, MC3230_MODE_OPCON_STANDBY);
+ }
+
+ return ret;
+}
+
+static int mc3230_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+ iio_device_unregister(indio_dev);
+
+ return mc3230_set_opcon(iio_priv(indio_dev), MC3230_MODE_OPCON_STANDBY);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mc3230_suspend(struct device *dev)
+{
+ struct mc3230_data *data;
+
+ data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+
+ return mc3230_set_opcon(data, MC3230_MODE_OPCON_STANDBY);
+}
+
+static int mc3230_resume(struct device *dev)
+{
+ struct mc3230_data *data;
+
+ data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+
+ return mc3230_set_opcon(data, MC3230_MODE_OPCON_WAKE);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(mc3230_pm_ops, mc3230_suspend, mc3230_resume);
+
+static const struct i2c_device_id mc3230_i2c_id[] = {
+ {"mc3230", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, mc3230_i2c_id);
+
+static struct i2c_driver mc3230_driver = {
+ .driver = {
+ .name = "mc3230",
+ .pm = &mc3230_pm_ops,
+ },
+ .probe = mc3230_probe,
+ .remove = mc3230_remove,
+ .id_table = mc3230_i2c_id,
+};
+
+module_i2c_driver(mc3230_driver);
+
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
+MODULE_DESCRIPTION("mCube MC3230 3-Axis Accelerometer driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/accel/mma7660.c b/drivers/iio/accel/mma7660.c
index 0acdee516973..03beadf14ad3 100644
--- a/drivers/iio/accel/mma7660.c
+++ b/drivers/iio/accel/mma7660.c
@@ -251,6 +251,7 @@ static const struct i2c_device_id mma7660_i2c_id[] = {
{"mma7660", 0},
{}
};
+MODULE_DEVICE_TABLE(i2c, mma7660_i2c_id);
static const struct acpi_device_id mma7660_acpi_id[] = {
{"MMA7660", 0},
diff --git a/drivers/iio/accel/mxc6255.c b/drivers/iio/accel/mxc6255.c
index 97ccde722e7b..0abad6948201 100644
--- a/drivers/iio/accel/mxc6255.c
+++ b/drivers/iio/accel/mxc6255.c
@@ -154,7 +154,7 @@ static int mxc6255_probe(struct i2c_client *client,
return ret;
}
- if (chip_id != MXC6255_CHIP_ID) {
+ if ((chip_id & 0x1f) != MXC6255_CHIP_ID) {
dev_err(&client->dev, "Invalid chip id %x\n", chip_id);
return -ENODEV;
}
@@ -171,12 +171,14 @@ static int mxc6255_probe(struct i2c_client *client,
}
static const struct acpi_device_id mxc6255_acpi_match[] = {
+ {"MXC6225", 0},
{"MXC6255", 0},
{ }
};
MODULE_DEVICE_TABLE(acpi, mxc6255_acpi_match);
static const struct i2c_device_id mxc6255_id[] = {
+ {"mxc6225", 0},
{"mxc6255", 0},
{ }
};
diff --git a/drivers/iio/accel/ssp_accel_sensor.c b/drivers/iio/accel/ssp_accel_sensor.c
index 4ae05fce9f24..31db00970fa0 100644
--- a/drivers/iio/accel/ssp_accel_sensor.c
+++ b/drivers/iio/accel/ssp_accel_sensor.c
@@ -74,7 +74,7 @@ static int ssp_accel_write_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
-static struct iio_info ssp_accel_iio_info = {
+static const struct iio_info ssp_accel_iio_info = {
.read_raw = &ssp_accel_read_raw,
.write_raw = &ssp_accel_write_raw,
};
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 767577298ee3..7edcf3238620 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -264,6 +264,15 @@ config LPC18XX_ADC
To compile this driver as a module, choose M here: the module will be
called lpc18xx_adc.
+config LTC2485
+ tristate "Linear Technology LTC2485 ADC driver"
+ depends on I2C
+ help
+ Say yes here to build support for Linear Technology LTC2485 ADC.
+
+ To compile this driver as a module, choose M here: the module will be
+ called ltc2485.
+
config MAX1027
tristate "Maxim max1027 ADC driver"
depends on SPI
@@ -317,6 +326,19 @@ config MCP3422
This driver can also be built as a module. If so, the module will be
called mcp3422.
+config MEDIATEK_MT6577_AUXADC
+ tristate "MediaTek AUXADC driver"
+ depends on ARCH_MEDIATEK || COMPILE_TEST
+ depends on HAS_IOMEM
+ help
+ Say yes here to enable support for MediaTek mt65xx AUXADC.
+
+ The driver supports immediate mode operation to read from one of sixteen
+ channels (external or internal).
+
+ This driver can also be built as a module. If so, the module will be
+ called mt6577_auxadc.
+
config MEN_Z188_ADC
tristate "MEN 16z188 ADC IP Core support"
depends on MCB
@@ -397,6 +419,21 @@ config ROCKCHIP_SARADC
To compile this driver as a module, choose M here: the
module will be called rockchip_saradc.
+config STX104
+ tristate "Apex Embedded Systems STX104 driver"
+ depends on X86 && ISA_BUS_API
+ select GPIOLIB
+ help
+ Say yes here to build support for the Apex Embedded Systems STX104
+ integrated analog PC/104 card.
+
+ This driver supports the 16 channels of single-ended (8 channels of
+ differential) analog inputs, 2 channels of analog output, 4 digital
+ inputs, and 4 digital outputs provided by the STX104.
+
+ The base port addresses for the devices may be configured via the base
+ array module parameter.
+
config TI_ADC081C
tristate "Texas Instruments ADC081C/ADC101C/ADC121C family"
depends on I2C
@@ -417,6 +454,18 @@ config TI_ADC0832
This driver can also be built as a module. If so, the module will be
called ti-adc0832.
+config TI_ADC12138
+ tristate "Texas Instruments ADC12130/ADC12132/ADC12138"
+ depends on SPI
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ If you say yes here you get support for Texas Instruments ADC12130,
+ ADC12132 and ADC12138 chips.
+
+ This driver can also be built as a module. If so, the module will be
+ called ti-adc12138.
+
config TI_ADC128S052
tristate "Texas Instruments ADC128S052/ADC122S021/ADC124S021"
depends on SPI
@@ -427,6 +476,18 @@ config TI_ADC128S052
This driver can also be built as a module. If so, the module will be
called ti-adc128s052.
+config TI_ADC161S626
+ tristate "Texas Instruments ADC161S626 1-channel differential ADC"
+ depends on SPI
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ If you say yes here you get support for Texas Instruments ADC141S626,
+ and ADC161S626 chips.
+
+ This driver can also be built as a module. If so, the module will be
+ called ti-adc161s626.
+
config TI_ADS1015
tristate "Texas Instruments ADS1015 ADC"
depends on I2C && !SENSORS_ADS1015
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 0ba0d500eedb..7a40c04c311f 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -27,10 +27,12 @@ obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o
obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o
+obj-$(CONFIG_LTC2485) += ltc2485.o
obj-$(CONFIG_MAX1027) += max1027.o
obj-$(CONFIG_MAX1363) += max1363.o
obj-$(CONFIG_MCP320X) += mcp320x.o
obj-$(CONFIG_MCP3422) += mcp3422.o
+obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o
obj-$(CONFIG_NAU7802) += nau7802.o
@@ -38,9 +40,12 @@ obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
+obj-$(CONFIG_STX104) += stx104.o
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o
+obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o
obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
+obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o
obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o
obj-$(CONFIG_TI_ADS8688) += ti-ads8688.o
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c
index c0f6a98fd9bd..b8d5cfd57ec4 100644
--- a/drivers/iio/adc/ad7266.c
+++ b/drivers/iio/adc/ad7266.c
@@ -481,7 +481,7 @@ error_free_gpios:
if (!st->fixed_addr)
gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios));
error_disable_reg:
- if (!IS_ERR_OR_NULL(st->reg))
+ if (!IS_ERR(st->reg))
regulator_disable(st->reg);
return ret;
@@ -496,7 +496,7 @@ static int ad7266_remove(struct spi_device *spi)
iio_triggered_buffer_cleanup(indio_dev);
if (!st->fixed_addr)
gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios));
- if (!IS_ERR_OR_NULL(st->reg))
+ if (!IS_ERR(st->reg))
regulator_disable(st->reg);
return 0;
diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c
index 10ec8fce395f..e399bf04c73a 100644
--- a/drivers/iio/adc/ad7298.c
+++ b/drivers/iio/adc/ad7298.c
@@ -239,16 +239,16 @@ static int ad7298_read_raw(struct iio_dev *indio_dev,
switch (m) {
case IIO_CHAN_INFO_RAW:
- mutex_lock(&indio_dev->mlock);
- if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
- ret = -EBUSY;
- } else {
- if (chan->address == AD7298_CH_TEMP)
- ret = ad7298_scan_temp(st, val);
- else
- ret = ad7298_scan_direct(st, chan->address);
- }
- mutex_unlock(&indio_dev->mlock);
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
+ if (chan->address == AD7298_CH_TEMP)
+ ret = ad7298_scan_temp(st, val);
+ else
+ ret = ad7298_scan_direct(st, chan->address);
+
+ iio_device_release_direct_mode(indio_dev);
if (ret < 0)
return ret;
diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c
index 847789bae821..e6706a09e100 100644
--- a/drivers/iio/adc/ad7793.c
+++ b/drivers/iio/adc/ad7793.c
@@ -519,11 +519,9 @@ static int ad7793_write_raw(struct iio_dev *indio_dev,
int ret, i;
unsigned int tmp;
- mutex_lock(&indio_dev->mlock);
- if (iio_buffer_enabled(indio_dev)) {
- mutex_unlock(&indio_dev->mlock);
- return -EBUSY;
- }
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
switch (mask) {
case IIO_CHAN_INFO_SCALE:
@@ -548,7 +546,7 @@ static int ad7793_write_raw(struct iio_dev *indio_dev,
ret = -EINVAL;
}
- mutex_unlock(&indio_dev->mlock);
+ iio_device_release_direct_mode(indio_dev);
return ret;
}
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
index 0438c68015e8..bbdac07f4aaa 100644
--- a/drivers/iio/adc/at91_adc.c
+++ b/drivers/iio/adc/at91_adc.c
@@ -113,6 +113,7 @@
#define AT91_ADC_TSMR_TSAV (3 << 4) /* Averages samples */
#define AT91_ADC_TSMR_TSAV_(x) ((x) << 4)
#define AT91_ADC_TSMR_SCTIM (0x0f << 16) /* Switch closure time */
+#define AT91_ADC_TSMR_SCTIM_(x) ((x) << 16)
#define AT91_ADC_TSMR_PENDBC (0x0f << 28) /* Pen Debounce time */
#define AT91_ADC_TSMR_PENDBC_(x) ((x) << 28)
#define AT91_ADC_TSMR_NOTSDMA (1 << 22) /* No Touchscreen DMA */
@@ -150,6 +151,7 @@
#define MAX_RLPOS_BITS 10
#define TOUCH_SAMPLE_PERIOD_US_RL 10000 /* 10ms, the SoC can't keep up with 2ms */
#define TOUCH_SHTIM 0xa
+#define TOUCH_SCTIM_US 10 /* 10us for the Touchscreen Switches Closure Time */
/**
* struct at91_adc_reg_desc - Various informations relative to registers
@@ -1001,7 +1003,9 @@ static void atmel_ts_close(struct input_dev *dev)
static int at91_ts_hw_init(struct at91_adc_state *st, u32 adc_clk_khz)
{
+ struct iio_dev *idev = iio_priv_to_dev(st);
u32 reg = 0;
+ u32 tssctim = 0;
int i = 0;
/* a Pen Detect Debounce Time is necessary for the ADC Touch to avoid
@@ -1034,11 +1038,20 @@ static int at91_ts_hw_init(struct at91_adc_state *st, u32 adc_clk_khz)
return 0;
}
+ /* Touchscreen Switches Closure time needed for allowing the value to
+ * stabilize.
+ * Switch Closure Time = (TSSCTIM * 4) ADCClock periods
+ */
+ tssctim = DIV_ROUND_UP(TOUCH_SCTIM_US * adc_clk_khz / 1000, 4);
+ dev_dbg(&idev->dev, "adc_clk at: %d KHz, tssctim at: %d\n",
+ adc_clk_khz, tssctim);
+
if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE)
reg = AT91_ADC_TSMR_TSMODE_4WIRE_PRESS;
else
reg = AT91_ADC_TSMR_TSMODE_5WIRE;
+ reg |= AT91_ADC_TSMR_SCTIM_(tssctim) & AT91_ADC_TSMR_SCTIM;
reg |= AT91_ADC_TSMR_TSAV_(st->caps->ts_filter_average)
& AT91_ADC_TSMR_TSAV;
reg |= AT91_ADC_TSMR_PENDBC_(st->ts_pendbc) & AT91_ADC_TSMR_PENDBC;
diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c
index 955f3fdaf519..59b7d76e1ad2 100644
--- a/drivers/iio/adc/ina2xx-adc.c
+++ b/drivers/iio/adc/ina2xx-adc.c
@@ -114,7 +114,6 @@ struct ina2xx_chip_info {
struct mutex state_lock;
unsigned int shunt_resistor;
int avg;
- s64 prev_ns; /* track buffer capture time, check for underruns */
int int_time_vbus; /* Bus voltage integration time uS */
int int_time_vshunt; /* Shunt voltage integration time uS */
bool allow_async_readout;
@@ -509,8 +508,6 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev)
iio_push_to_buffers_with_timestamp(indio_dev,
(unsigned int *)data, time_a);
- chip->prev_ns = time_a;
-
return (unsigned long)(time_b - time_a) / 1000;
};
@@ -554,8 +551,6 @@ static int ina2xx_buffer_enable(struct iio_dev *indio_dev)
dev_dbg(&indio_dev->dev, "Async readout mode: %d\n",
chip->allow_async_readout);
- chip->prev_ns = iio_get_time_ns(indio_dev);
-
chip->task = kthread_run(ina2xx_capture_thread, (void *)indio_dev,
"%s:%d-%uus", indio_dev->name, indio_dev->id,
sampling_us);
diff --git a/drivers/iio/adc/ltc2485.c b/drivers/iio/adc/ltc2485.c
new file mode 100644
index 000000000000..eab91f12454a
--- /dev/null
+++ b/drivers/iio/adc/ltc2485.c
@@ -0,0 +1,148 @@
+/*
+ * ltc2485.c - Driver for Linear Technology LTC2485 ADC
+ *
+ * Copyright (C) 2016 Alison Schofield <amsfield22@gmail.com>
+ *
+ * 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.
+ *
+ * Datasheet: http://cds.linear.com/docs/en/datasheet/2485fd.pdf
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+/* Power-on configuration: rejects both 50/60Hz, operates at 1x speed */
+#define LTC2485_CONFIG_DEFAULT 0
+
+struct ltc2485_data {
+ struct i2c_client *client;
+ ktime_t time_prev; /* last conversion */
+};
+
+static void ltc2485_wait_conv(struct ltc2485_data *data)
+{
+ const unsigned int conv_time = 147; /* conversion time ms */
+ unsigned int time_elapsed;
+
+ /* delay if conversion time not passed since last read or write */
+ time_elapsed = ktime_ms_delta(ktime_get(), data->time_prev);
+
+ if (time_elapsed < conv_time)
+ msleep(conv_time - time_elapsed);
+}
+
+static int ltc2485_read(struct ltc2485_data *data, int *val)
+{
+ struct i2c_client *client = data->client;
+ __be32 buf = 0;
+ int ret;
+
+ ltc2485_wait_conv(data);
+
+ ret = i2c_master_recv(client, (char *)&buf, 4);
+ if (ret < 0) {
+ dev_err(&client->dev, "i2c_master_recv failed\n");
+ return ret;
+ }
+ data->time_prev = ktime_get();
+ *val = sign_extend32(be32_to_cpu(buf) >> 6, 24);
+
+ return ret;
+}
+
+static int ltc2485_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct ltc2485_data *data = iio_priv(indio_dev);
+ int ret;
+
+ if (mask == IIO_CHAN_INFO_RAW) {
+ ret = ltc2485_read(data, val);
+ if (ret < 0)
+ return ret;
+
+ return IIO_VAL_INT;
+
+ } else if (mask == IIO_CHAN_INFO_SCALE) {
+ *val = 5000; /* on board vref millivolts */
+ *val2 = 25; /* 25 (24 + sign) data bits */
+ return IIO_VAL_FRACTIONAL_LOG2;
+
+ } else {
+ return -EINVAL;
+ }
+}
+
+static const struct iio_chan_spec ltc2485_channel[] = {
+ {
+ .type = IIO_VOLTAGE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE)
+ },
+};
+
+static const struct iio_info ltc2485_info = {
+ .read_raw = ltc2485_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static int ltc2485_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct iio_dev *indio_dev;
+ struct ltc2485_data *data;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
+ I2C_FUNC_SMBUS_WRITE_BYTE))
+ return -EOPNOTSUPP;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ data->client = client;
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->name = id->name;
+ indio_dev->info = &ltc2485_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = ltc2485_channel;
+ indio_dev->num_channels = ARRAY_SIZE(ltc2485_channel);
+
+ ret = i2c_smbus_write_byte(data->client, LTC2485_CONFIG_DEFAULT);
+ if (ret < 0)
+ return ret;
+
+ data->time_prev = ktime_get();
+
+ return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static const struct i2c_device_id ltc2485_id[] = {
+ { "ltc2485", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ltc2485_id);
+
+static struct i2c_driver ltc2485_driver = {
+ .driver = {
+ .name = "ltc2485",
+ },
+ .probe = ltc2485_probe,
+ .id_table = ltc2485_id,
+};
+module_i2c_driver(ltc2485_driver);
+
+MODULE_AUTHOR("Alison Schofield <amsfield22@gmail.com>");
+MODULE_DESCRIPTION("Linear Technology LTC2485 ADC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/men_z188_adc.c b/drivers/iio/adc/men_z188_adc.c
index d095efe1ba14..8f3606de4eaf 100644
--- a/drivers/iio/adc/men_z188_adc.c
+++ b/drivers/iio/adc/men_z188_adc.c
@@ -78,7 +78,7 @@ static int z188_iio_read_raw(struct iio_dev *iio_dev,
return ret;
}
-static struct iio_info z188_adc_info = {
+static const struct iio_info z188_adc_info = {
.read_raw = &z188_iio_read_raw,
.driver_module = THIS_MODULE,
};
diff --git a/drivers/iio/adc/mt6577_auxadc.c b/drivers/iio/adc/mt6577_auxadc.c
new file mode 100644
index 000000000000..2d104c828041
--- /dev/null
+++ b/drivers/iio/adc/mt6577_auxadc.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Zhiyong Tao <zhiyong.tao@mediatek.com>
+ *
+ * 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/iopoll.h>
+#include <linux/io.h>
+#include <linux/iio/iio.h>
+
+/* Register definitions */
+#define MT6577_AUXADC_CON0 0x00
+#define MT6577_AUXADC_CON1 0x04
+#define MT6577_AUXADC_CON2 0x10
+#define MT6577_AUXADC_STA BIT(0)
+
+#define MT6577_AUXADC_DAT0 0x14
+#define MT6577_AUXADC_RDY0 BIT(12)
+
+#define MT6577_AUXADC_MISC 0x94
+#define MT6577_AUXADC_PDN_EN BIT(14)
+
+#define MT6577_AUXADC_DAT_MASK 0xfff
+#define MT6577_AUXADC_SLEEP_US 1000
+#define MT6577_AUXADC_TIMEOUT_US 10000
+#define MT6577_AUXADC_POWER_READY_MS 1
+#define MT6577_AUXADC_SAMPLE_READY_US 25
+
+struct mt6577_auxadc_device {
+ void __iomem *reg_base;
+ struct clk *adc_clk;
+ struct mutex lock;
+};
+
+#define MT6577_AUXADC_CHANNEL(idx) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = (idx), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
+}
+
+static const struct iio_chan_spec mt6577_auxadc_iio_channels[] = {
+ MT6577_AUXADC_CHANNEL(0),
+ MT6577_AUXADC_CHANNEL(1),
+ MT6577_AUXADC_CHANNEL(2),
+ MT6577_AUXADC_CHANNEL(3),
+ MT6577_AUXADC_CHANNEL(4),
+ MT6577_AUXADC_CHANNEL(5),
+ MT6577_AUXADC_CHANNEL(6),
+ MT6577_AUXADC_CHANNEL(7),
+ MT6577_AUXADC_CHANNEL(8),
+ MT6577_AUXADC_CHANNEL(9),
+ MT6577_AUXADC_CHANNEL(10),
+ MT6577_AUXADC_CHANNEL(11),
+ MT6577_AUXADC_CHANNEL(12),
+ MT6577_AUXADC_CHANNEL(13),
+ MT6577_AUXADC_CHANNEL(14),
+ MT6577_AUXADC_CHANNEL(15),
+};
+
+static inline void mt6577_auxadc_mod_reg(void __iomem *reg,
+ u32 or_mask, u32 and_mask)
+{
+ u32 val;
+
+ val = readl(reg);
+ val |= or_mask;
+ val &= ~and_mask;
+ writel(val, reg);
+}
+
+static int mt6577_auxadc_read(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan)
+{
+ u32 val;
+ void __iomem *reg_channel;
+ int ret;
+ struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
+
+ reg_channel = adc_dev->reg_base + MT6577_AUXADC_DAT0 +
+ chan->channel * 0x04;
+
+ mutex_lock(&adc_dev->lock);
+
+ mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_CON1,
+ 0, 1 << chan->channel);
+
+ /* read channel and make sure old ready bit == 0 */
+ ret = readl_poll_timeout(reg_channel, val,
+ ((val & MT6577_AUXADC_RDY0) == 0),
+ MT6577_AUXADC_SLEEP_US,
+ MT6577_AUXADC_TIMEOUT_US);
+ if (ret < 0) {
+ dev_err(indio_dev->dev.parent,
+ "wait for channel[%d] ready bit clear time out\n",
+ chan->channel);
+ goto err_timeout;
+ }
+
+ /* set bit to trigger sample */
+ mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_CON1,
+ 1 << chan->channel, 0);
+
+ /* we must delay here for hardware sample channel data */
+ udelay(MT6577_AUXADC_SAMPLE_READY_US);
+
+ /* check MTK_AUXADC_CON2 if auxadc is idle */
+ ret = readl_poll_timeout(adc_dev->reg_base + MT6577_AUXADC_CON2, val,
+ ((val & MT6577_AUXADC_STA) == 0),
+ MT6577_AUXADC_SLEEP_US,
+ MT6577_AUXADC_TIMEOUT_US);
+ if (ret < 0) {
+ dev_err(indio_dev->dev.parent,
+ "wait for auxadc idle time out\n");
+ goto err_timeout;
+ }
+
+ /* read channel and make sure ready bit == 1 */
+ ret = readl_poll_timeout(reg_channel, val,
+ ((val & MT6577_AUXADC_RDY0) != 0),
+ MT6577_AUXADC_SLEEP_US,
+ MT6577_AUXADC_TIMEOUT_US);
+ if (ret < 0) {
+ dev_err(indio_dev->dev.parent,
+ "wait for channel[%d] data ready time out\n",
+ chan->channel);
+ goto err_timeout;
+ }
+
+ /* read data */
+ val = readl(reg_channel) & MT6577_AUXADC_DAT_MASK;
+
+ mutex_unlock(&adc_dev->lock);
+
+ return val;
+
+err_timeout:
+
+ mutex_unlock(&adc_dev->lock);
+
+ return -ETIMEDOUT;
+}
+
+static int mt6577_auxadc_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long info)
+{
+ switch (info) {
+ case IIO_CHAN_INFO_PROCESSED:
+ *val = mt6577_auxadc_read(indio_dev, chan);
+ if (*val < 0) {
+ dev_err(indio_dev->dev.parent,
+ "failed to sample data on channel[%d]\n",
+ chan->channel);
+ return *val;
+ }
+ return IIO_VAL_INT;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info mt6577_auxadc_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = &mt6577_auxadc_read_raw,
+};
+
+static int mt6577_auxadc_probe(struct platform_device *pdev)
+{
+ struct mt6577_auxadc_device *adc_dev;
+ unsigned long adc_clk_rate;
+ struct resource *res;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ adc_dev = iio_priv(indio_dev);
+ indio_dev->dev.parent = &pdev->dev;
+ indio_dev->name = dev_name(&pdev->dev);
+ indio_dev->info = &mt6577_auxadc_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = mt6577_auxadc_iio_channels;
+ indio_dev->num_channels = ARRAY_SIZE(mt6577_auxadc_iio_channels);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ adc_dev->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(adc_dev->reg_base)) {
+ dev_err(&pdev->dev, "failed to get auxadc base address\n");
+ return PTR_ERR(adc_dev->reg_base);
+ }
+
+ adc_dev->adc_clk = devm_clk_get(&pdev->dev, "main");
+ if (IS_ERR(adc_dev->adc_clk)) {
+ dev_err(&pdev->dev, "failed to get auxadc clock\n");
+ return PTR_ERR(adc_dev->adc_clk);
+ }
+
+ ret = clk_prepare_enable(adc_dev->adc_clk);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable auxadc clock\n");
+ return ret;
+ }
+
+ adc_clk_rate = clk_get_rate(adc_dev->adc_clk);
+ if (!adc_clk_rate) {
+ ret = -EINVAL;
+ dev_err(&pdev->dev, "null clock rate\n");
+ goto err_disable_clk;
+ }
+
+ mutex_init(&adc_dev->lock);
+
+ mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
+ MT6577_AUXADC_PDN_EN, 0);
+ mdelay(MT6577_AUXADC_POWER_READY_MS);
+
+ platform_set_drvdata(pdev, indio_dev);
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to register iio device\n");
+ goto err_power_off;
+ }
+
+ return 0;
+
+err_power_off:
+ mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
+ 0, MT6577_AUXADC_PDN_EN);
+err_disable_clk:
+ clk_disable_unprepare(adc_dev->adc_clk);
+ return ret;
+}
+
+static int mt6577_auxadc_remove(struct platform_device *pdev)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+
+ mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
+ 0, MT6577_AUXADC_PDN_EN);
+
+ clk_disable_unprepare(adc_dev->adc_clk);
+
+ return 0;
+}
+
+static const struct of_device_id mt6577_auxadc_of_match[] = {
+ { .compatible = "mediatek,mt2701-auxadc", },
+ { .compatible = "mediatek,mt8173-auxadc", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, mt6577_auxadc_of_match);
+
+static struct platform_driver mt6577_auxadc_driver = {
+ .driver = {
+ .name = "mt6577-auxadc",
+ .of_match_table = mt6577_auxadc_of_match,
+ },
+ .probe = mt6577_auxadc_probe,
+ .remove = mt6577_auxadc_remove,
+};
+module_platform_driver(mt6577_auxadc_driver);
+
+MODULE_AUTHOR("Zhiyong Tao <zhiyong.tao@mediatek.com>");
+MODULE_DESCRIPTION("MTK AUXADC Device Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/nau7802.c b/drivers/iio/adc/nau7802.c
index db9b829ccf0d..08f446695f97 100644
--- a/drivers/iio/adc/nau7802.c
+++ b/drivers/iio/adc/nau7802.c
@@ -197,7 +197,7 @@ static irqreturn_t nau7802_eoc_trigger(int irq, void *private)
if (st->conversion_count < NAU7802_MIN_CONVERSIONS)
st->conversion_count++;
if (st->conversion_count >= NAU7802_MIN_CONVERSIONS)
- complete_all(&st->value_ok);
+ complete(&st->value_ok);
return IRQ_HANDLED;
}
diff --git a/drivers/iio/dac/stx104.c b/drivers/iio/adc/stx104.c
index bebbd00304ce..7e3645749eaf 100644
--- a/drivers/iio/dac/stx104.c
+++ b/drivers/iio/adc/stx104.c
@@ -1,5 +1,5 @@
/*
- * DAC driver for the Apex Embedded Systems STX104
+ * IIO driver for the Apex Embedded Systems STX104
* Copyright (C) 2016 William Breathitt Gray
*
* This program is free software; you can redistribute it and/or modify
@@ -20,19 +20,30 @@
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/isa.h>
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
-#define STX104_NUM_CHAN 2
-
-#define STX104_CHAN(chan) { \
+#define STX104_OUT_CHAN(chan) { \
.type = IIO_VOLTAGE, \
.channel = chan, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.indexed = 1, \
.output = 1 \
}
+#define STX104_IN_CHAN(chan, diff) { \
+ .type = IIO_VOLTAGE, \
+ .channel = chan, \
+ .channel2 = chan, \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \
+ BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .indexed = 1, \
+ .differential = diff \
+}
+
+#define STX104_NUM_OUT_CHAN 2
#define STX104_EXTENT 16
@@ -47,8 +58,8 @@ MODULE_PARM_DESC(base, "Apex Embedded Systems STX104 base addresses");
* @base: base port address of the IIO device
*/
struct stx104_iio {
- unsigned chan_out_states[STX104_NUM_CHAN];
- unsigned base;
+ unsigned int chan_out_states[STX104_NUM_OUT_CHAN];
+ unsigned int base;
};
/**
@@ -79,28 +90,95 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2, long mask)
{
struct stx104_iio *const priv = iio_priv(indio_dev);
+ unsigned int adc_config;
+ int adbu;
+ int gain;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_HARDWAREGAIN:
+ /* get gain configuration */
+ adc_config = inb(priv->base + 11);
+ gain = adc_config & 0x3;
+
+ *val = 1 << gain;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_RAW:
+ if (chan->output) {
+ *val = priv->chan_out_states[chan->channel];
+ return IIO_VAL_INT;
+ }
+
+ /* select ADC channel */
+ outb(chan->channel | (chan->channel << 4), priv->base + 2);
+
+ /* trigger ADC sample capture and wait for completion */
+ outb(0, priv->base);
+ while (inb(priv->base + 8) & BIT(7));
+
+ *val = inw(priv->base);
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_OFFSET:
+ /* get ADC bipolar/unipolar configuration */
+ adc_config = inb(priv->base + 11);
+ adbu = !(adc_config & BIT(2));
+
+ *val = -32768 * adbu;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ /* get ADC bipolar/unipolar and gain configuration */
+ adc_config = inb(priv->base + 11);
+ adbu = !(adc_config & BIT(2));
+ gain = adc_config & 0x3;
+
+ *val = 5;
+ *val2 = 15 - adbu + gain;
+ return IIO_VAL_FRACTIONAL_LOG2;
+ }
- if (mask != IIO_CHAN_INFO_RAW)
- return -EINVAL;
-
- *val = priv->chan_out_states[chan->channel];
-
- return IIO_VAL_INT;
+ return -EINVAL;
}
static int stx104_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int val, int val2, long mask)
{
struct stx104_iio *const priv = iio_priv(indio_dev);
- const unsigned chan_addr_offset = 2 * chan->channel;
- if (mask != IIO_CHAN_INFO_RAW)
+ switch (mask) {
+ case IIO_CHAN_INFO_HARDWAREGAIN:
+ /* Only four gain states (x1, x2, x4, x8) */
+ switch (val) {
+ case 1:
+ outb(0, priv->base + 11);
+ break;
+ case 2:
+ outb(1, priv->base + 11);
+ break;
+ case 4:
+ outb(2, priv->base + 11);
+ break;
+ case 8:
+ outb(3, priv->base + 11);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+ case IIO_CHAN_INFO_RAW:
+ if (chan->output) {
+ /* DAC can only accept up to a 16-bit value */
+ if ((unsigned int)val > 65535)
+ return -EINVAL;
+
+ priv->chan_out_states[chan->channel] = val;
+ outw(val, priv->base + 4 + 2 * chan->channel);
+
+ return 0;
+ }
return -EINVAL;
+ }
- priv->chan_out_states[chan->channel] = val;
- outw(val, priv->base + 4 + chan_addr_offset);
-
- return 0;
+ return -EINVAL;
}
static const struct iio_info stx104_info = {
@@ -109,9 +187,22 @@ static const struct iio_info stx104_info = {
.write_raw = stx104_write_raw
};
-static const struct iio_chan_spec stx104_channels[STX104_NUM_CHAN] = {
- STX104_CHAN(0),
- STX104_CHAN(1)
+/* single-ended input channels configuration */
+static const struct iio_chan_spec stx104_channels_sing[] = {
+ STX104_OUT_CHAN(0), STX104_OUT_CHAN(1),
+ STX104_IN_CHAN(0, 0), STX104_IN_CHAN(1, 0), STX104_IN_CHAN(2, 0),
+ STX104_IN_CHAN(3, 0), STX104_IN_CHAN(4, 0), STX104_IN_CHAN(5, 0),
+ STX104_IN_CHAN(6, 0), STX104_IN_CHAN(7, 0), STX104_IN_CHAN(8, 0),
+ STX104_IN_CHAN(9, 0), STX104_IN_CHAN(10, 0), STX104_IN_CHAN(11, 0),
+ STX104_IN_CHAN(12, 0), STX104_IN_CHAN(13, 0), STX104_IN_CHAN(14, 0),
+ STX104_IN_CHAN(15, 0)
+};
+/* differential input channels configuration */
+static const struct iio_chan_spec stx104_channels_diff[] = {
+ STX104_OUT_CHAN(0), STX104_OUT_CHAN(1),
+ STX104_IN_CHAN(0, 1), STX104_IN_CHAN(1, 1), STX104_IN_CHAN(2, 1),
+ STX104_IN_CHAN(3, 1), STX104_IN_CHAN(4, 1), STX104_IN_CHAN(5, 1),
+ STX104_IN_CHAN(6, 1), STX104_IN_CHAN(7, 1)
};
static int stx104_gpio_get_direction(struct gpio_chip *chip,
@@ -204,13 +295,27 @@ static int stx104_probe(struct device *dev, unsigned int id)
indio_dev->info = &stx104_info;
indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->channels = stx104_channels;
- indio_dev->num_channels = STX104_NUM_CHAN;
+
+ /* determine if differential inputs */
+ if (inb(base[id] + 8) & BIT(5)) {
+ indio_dev->num_channels = ARRAY_SIZE(stx104_channels_diff);
+ indio_dev->channels = stx104_channels_diff;
+ } else {
+ indio_dev->num_channels = ARRAY_SIZE(stx104_channels_sing);
+ indio_dev->channels = stx104_channels_sing;
+ }
+
indio_dev->name = dev_name(dev);
priv = iio_priv(indio_dev);
priv->base = base[id];
+ /* configure device for software trigger operation */
+ outb(0, base[id] + 9);
+
+ /* initialize gain setting to x1 */
+ outb(0, base[id] + 11);
+
/* initialize DAC output to 0V */
outw(0, base[id] + 4);
outw(0, base[id] + 6);
@@ -271,5 +376,5 @@ static struct isa_driver stx104_driver = {
module_isa_driver(stx104_driver, num_stx104);
MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
-MODULE_DESCRIPTION("Apex Embedded Systems STX104 DAC driver");
+MODULE_DESCRIPTION("Apex Embedded Systems STX104 IIO driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/ti-adc12138.c b/drivers/iio/adc/ti-adc12138.c
new file mode 100644
index 000000000000..072f03bfe6a0
--- /dev/null
+++ b/drivers/iio/adc/ti-adc12138.c
@@ -0,0 +1,552 @@
+/*
+ * ADC12130/ADC12132/ADC12138 12-bit plus sign ADC driver
+ *
+ * Copyright (c) 2016 Akinobu Mita <akinobu.mita@gmail.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * Datasheet: http://www.ti.com/lit/ds/symlink/adc12138.pdf
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/regulator/consumer.h>
+
+#define ADC12138_MODE_AUTO_CAL 0x08
+#define ADC12138_MODE_READ_STATUS 0x0c
+#define ADC12138_MODE_ACQUISITION_TIME_6 0x0e
+#define ADC12138_MODE_ACQUISITION_TIME_10 0x4e
+#define ADC12138_MODE_ACQUISITION_TIME_18 0x8e
+#define ADC12138_MODE_ACQUISITION_TIME_34 0xce
+
+#define ADC12138_STATUS_CAL BIT(6)
+
+enum {
+ adc12130,
+ adc12132,
+ adc12138,
+};
+
+struct adc12138 {
+ struct spi_device *spi;
+ unsigned int id;
+ /* conversion clock */
+ struct clk *cclk;
+ /* positive analog voltage reference */
+ struct regulator *vref_p;
+ /* negative analog voltage reference */
+ struct regulator *vref_n;
+ struct mutex lock;
+ struct completion complete;
+ /* The number of cclk periods for the S/H's acquisition time */
+ unsigned int acquisition_time;
+
+ u8 tx_buf[2] ____cacheline_aligned;
+ u8 rx_buf[2];
+};
+
+#define ADC12138_VOLTAGE_CHANNEL(chan) \
+ { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = chan, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
+ | BIT(IIO_CHAN_INFO_OFFSET), \
+ .scan_index = chan, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 13, \
+ .storagebits = 16, \
+ .shift = 3, \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+#define ADC12138_VOLTAGE_CHANNEL_DIFF(chan1, chan2, si) \
+ { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = (chan1), \
+ .channel2 = (chan2), \
+ .differential = 1, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
+ | BIT(IIO_CHAN_INFO_OFFSET), \
+ .scan_index = si, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 13, \
+ .storagebits = 16, \
+ .shift = 3, \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+static const struct iio_chan_spec adc12132_channels[] = {
+ ADC12138_VOLTAGE_CHANNEL(0),
+ ADC12138_VOLTAGE_CHANNEL(1),
+ ADC12138_VOLTAGE_CHANNEL_DIFF(0, 1, 2),
+ ADC12138_VOLTAGE_CHANNEL_DIFF(1, 0, 3),
+ IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
+static const struct iio_chan_spec adc12138_channels[] = {
+ ADC12138_VOLTAGE_CHANNEL(0),
+ ADC12138_VOLTAGE_CHANNEL(1),
+ ADC12138_VOLTAGE_CHANNEL(2),
+ ADC12138_VOLTAGE_CHANNEL(3),
+ ADC12138_VOLTAGE_CHANNEL(4),
+ ADC12138_VOLTAGE_CHANNEL(5),
+ ADC12138_VOLTAGE_CHANNEL(6),
+ ADC12138_VOLTAGE_CHANNEL(7),
+ ADC12138_VOLTAGE_CHANNEL_DIFF(0, 1, 8),
+ ADC12138_VOLTAGE_CHANNEL_DIFF(1, 0, 9),
+ ADC12138_VOLTAGE_CHANNEL_DIFF(2, 3, 10),
+ ADC12138_VOLTAGE_CHANNEL_DIFF(3, 2, 11),
+ ADC12138_VOLTAGE_CHANNEL_DIFF(4, 5, 12),
+ ADC12138_VOLTAGE_CHANNEL_DIFF(5, 4, 13),
+ ADC12138_VOLTAGE_CHANNEL_DIFF(6, 7, 14),
+ ADC12138_VOLTAGE_CHANNEL_DIFF(7, 6, 15),
+ IIO_CHAN_SOFT_TIMESTAMP(16),
+};
+
+static int adc12138_mode_programming(struct adc12138 *adc, u8 mode,
+ void *rx_buf, int len)
+{
+ struct spi_transfer xfer = {
+ .tx_buf = adc->tx_buf,
+ .rx_buf = adc->rx_buf,
+ .len = len,
+ };
+ int ret;
+
+ /* Skip unused bits for ADC12130 and ADC12132 */
+ if (adc->id != adc12138)
+ mode = (mode & 0xc0) | ((mode & 0x0f) << 2);
+
+ adc->tx_buf[0] = mode;
+
+ ret = spi_sync_transfer(adc->spi, &xfer, 1);
+ if (ret)
+ return ret;
+
+ memcpy(rx_buf, adc->rx_buf, len);
+
+ return 0;
+}
+
+static int adc12138_read_status(struct adc12138 *adc)
+{
+ u8 rx_buf[2];
+ int ret;
+
+ ret = adc12138_mode_programming(adc, ADC12138_MODE_READ_STATUS,
+ rx_buf, 2);
+ if (ret)
+ return ret;
+
+ return (rx_buf[0] << 1) | (rx_buf[1] >> 7);
+}
+
+static int __adc12138_start_conv(struct adc12138 *adc,
+ struct iio_chan_spec const *channel,
+ void *data, int len)
+
+{
+ const u8 ch_to_mux[] = { 0, 4, 1, 5, 2, 6, 3, 7 };
+ u8 mode = (ch_to_mux[channel->channel] << 4) |
+ (channel->differential ? 0 : 0x80);
+
+ return adc12138_mode_programming(adc, mode, data, len);
+}
+
+static int adc12138_start_conv(struct adc12138 *adc,
+ struct iio_chan_spec const *channel)
+{
+ u8 trash;
+
+ return __adc12138_start_conv(adc, channel, &trash, 1);
+}
+
+static int adc12138_start_and_read_conv(struct adc12138 *adc,
+ struct iio_chan_spec const *channel,
+ __be16 *data)
+{
+ return __adc12138_start_conv(adc, channel, data, 2);
+}
+
+static int adc12138_read_conv_data(struct adc12138 *adc, __be16 *value)
+{
+ /* Issue a read status instruction and read previous conversion data */
+ return adc12138_mode_programming(adc, ADC12138_MODE_READ_STATUS,
+ value, sizeof(*value));
+}
+
+static int adc12138_wait_eoc(struct adc12138 *adc, unsigned long timeout)
+{
+ if (!wait_for_completion_timeout(&adc->complete, timeout))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int adc12138_adc_conversion(struct adc12138 *adc,
+ struct iio_chan_spec const *channel,
+ __be16 *value)
+{
+ int ret;
+
+ reinit_completion(&adc->complete);
+
+ ret = adc12138_start_conv(adc, channel);
+ if (ret)
+ return ret;
+
+ ret = adc12138_wait_eoc(adc, msecs_to_jiffies(100));
+ if (ret)
+ return ret;
+
+ return adc12138_read_conv_data(adc, value);
+}
+
+static int adc12138_read_raw(struct iio_dev *iio,
+ struct iio_chan_spec const *channel, int *value,
+ int *shift, long mask)
+{
+ struct adc12138 *adc = iio_priv(iio);
+ int ret;
+ __be16 data;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ mutex_lock(&adc->lock);
+ ret = adc12138_adc_conversion(adc, channel, &data);
+ mutex_unlock(&adc->lock);
+ if (ret)
+ return ret;
+
+ *value = sign_extend32(be16_to_cpu(data) >> 3, 12);
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ ret = regulator_get_voltage(adc->vref_p);
+ if (ret < 0)
+ return ret;
+ *value = ret;
+
+ if (!IS_ERR(adc->vref_n)) {
+ ret = regulator_get_voltage(adc->vref_n);
+ if (ret < 0)
+ return ret;
+ *value -= ret;
+ }
+
+ /* convert regulator output voltage to mV */
+ *value /= 1000;
+ *shift = channel->scan_type.realbits - 1;
+
+ return IIO_VAL_FRACTIONAL_LOG2;
+ case IIO_CHAN_INFO_OFFSET:
+ if (!IS_ERR(adc->vref_n)) {
+ *value = regulator_get_voltage(adc->vref_n);
+ if (*value < 0)
+ return *value;
+ } else {
+ *value = 0;
+ }
+
+ /* convert regulator output voltage to mV */
+ *value /= 1000;
+
+ return IIO_VAL_INT;
+ }
+
+ return -EINVAL;
+}
+
+static const struct iio_info adc12138_info = {
+ .read_raw = adc12138_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static int adc12138_init(struct adc12138 *adc)
+{
+ int ret;
+ int status;
+ u8 mode;
+ u8 trash;
+
+ reinit_completion(&adc->complete);
+
+ ret = adc12138_mode_programming(adc, ADC12138_MODE_AUTO_CAL, &trash, 1);
+ if (ret)
+ return ret;
+
+ /* data output at this time has no significance */
+ status = adc12138_read_status(adc);
+ if (status < 0)
+ return status;
+
+ adc12138_wait_eoc(adc, msecs_to_jiffies(100));
+
+ status = adc12138_read_status(adc);
+ if (status & ADC12138_STATUS_CAL) {
+ dev_warn(&adc->spi->dev,
+ "Auto Cal sequence is still in progress: %#x\n",
+ status);
+ return -EIO;
+ }
+
+ switch (adc->acquisition_time) {
+ case 6:
+ mode = ADC12138_MODE_ACQUISITION_TIME_6;
+ break;
+ case 10:
+ mode = ADC12138_MODE_ACQUISITION_TIME_10;
+ break;
+ case 18:
+ mode = ADC12138_MODE_ACQUISITION_TIME_18;
+ break;
+ case 34:
+ mode = ADC12138_MODE_ACQUISITION_TIME_34;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return adc12138_mode_programming(adc, mode, &trash, 1);
+}
+
+static irqreturn_t adc12138_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct adc12138 *adc = iio_priv(indio_dev);
+ __be16 data[20] = { }; /* 16x 2 bytes ADC data + 8 bytes timestamp */
+ __be16 trash;
+ int ret;
+ int scan_index;
+ int i = 0;
+
+ mutex_lock(&adc->lock);
+
+ for_each_set_bit(scan_index, indio_dev->active_scan_mask,
+ indio_dev->masklength) {
+ const struct iio_chan_spec *scan_chan =
+ &indio_dev->channels[scan_index];
+
+ reinit_completion(&adc->complete);
+
+ ret = adc12138_start_and_read_conv(adc, scan_chan,
+ i ? &data[i - 1] : &trash);
+ if (ret) {
+ dev_warn(&adc->spi->dev,
+ "failed to start conversion\n");
+ goto out;
+ }
+
+ ret = adc12138_wait_eoc(adc, msecs_to_jiffies(100));
+ if (ret) {
+ dev_warn(&adc->spi->dev, "wait eoc timeout\n");
+ goto out;
+ }
+
+ i++;
+ }
+
+ if (i) {
+ ret = adc12138_read_conv_data(adc, &data[i - 1]);
+ if (ret) {
+ dev_warn(&adc->spi->dev,
+ "failed to get conversion data\n");
+ goto out;
+ }
+ }
+
+ iio_push_to_buffers_with_timestamp(indio_dev, data,
+ iio_get_time_ns(indio_dev));
+out:
+ mutex_unlock(&adc->lock);
+
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t adc12138_eoc_handler(int irq, void *p)
+{
+ struct iio_dev *indio_dev = p;
+ struct adc12138 *adc = iio_priv(indio_dev);
+
+ complete(&adc->complete);
+
+ return IRQ_HANDLED;
+}
+
+static int adc12138_probe(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev;
+ struct adc12138 *adc;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ adc = iio_priv(indio_dev);
+ adc->spi = spi;
+ adc->id = spi_get_device_id(spi)->driver_data;
+ mutex_init(&adc->lock);
+ init_completion(&adc->complete);
+
+ indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->info = &adc12138_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ switch (adc->id) {
+ case adc12130:
+ case adc12132:
+ indio_dev->channels = adc12132_channels;
+ indio_dev->num_channels = ARRAY_SIZE(adc12132_channels);
+ break;
+ case adc12138:
+ indio_dev->channels = adc12138_channels;
+ indio_dev->num_channels = ARRAY_SIZE(adc12138_channels);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32(spi->dev.of_node, "ti,acquisition-time",
+ &adc->acquisition_time);
+ if (ret)
+ adc->acquisition_time = 10;
+
+ adc->cclk = devm_clk_get(&spi->dev, NULL);
+ if (IS_ERR(adc->cclk))
+ return PTR_ERR(adc->cclk);
+
+ adc->vref_p = devm_regulator_get(&spi->dev, "vref-p");
+ if (IS_ERR(adc->vref_p))
+ return PTR_ERR(adc->vref_p);
+
+ adc->vref_n = devm_regulator_get_optional(&spi->dev, "vref-n");
+ if (IS_ERR(adc->vref_n)) {
+ /*
+ * Assume vref_n is 0V if an optional regulator is not
+ * specified, otherwise return the error code.
+ */
+ ret = PTR_ERR(adc->vref_n);
+ if (ret != -ENODEV)
+ return ret;
+ }
+
+ ret = devm_request_irq(&spi->dev, spi->irq, adc12138_eoc_handler,
+ IRQF_TRIGGER_RISING, indio_dev->name, indio_dev);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(adc->cclk);
+ if (ret)
+ return ret;
+
+ ret = regulator_enable(adc->vref_p);
+ if (ret)
+ goto err_clk_disable;
+
+ if (!IS_ERR(adc->vref_n)) {
+ ret = regulator_enable(adc->vref_n);
+ if (ret)
+ goto err_vref_p_disable;
+ }
+
+ ret = adc12138_init(adc);
+ if (ret)
+ goto err_vref_n_disable;
+
+ spi_set_drvdata(spi, indio_dev);
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ adc12138_trigger_handler, NULL);
+ if (ret)
+ goto err_vref_n_disable;
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto err_buffer_cleanup;
+
+ return 0;
+err_buffer_cleanup:
+ iio_triggered_buffer_cleanup(indio_dev);
+err_vref_n_disable:
+ if (!IS_ERR(adc->vref_n))
+ regulator_disable(adc->vref_n);
+err_vref_p_disable:
+ regulator_disable(adc->vref_p);
+err_clk_disable:
+ clk_disable_unprepare(adc->cclk);
+
+ return ret;
+}
+
+static int adc12138_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct adc12138 *adc = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+ if (!IS_ERR(adc->vref_n))
+ regulator_disable(adc->vref_n);
+ regulator_disable(adc->vref_p);
+ clk_disable_unprepare(adc->cclk);
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+
+static const struct of_device_id adc12138_dt_ids[] = {
+ { .compatible = "ti,adc12130", },
+ { .compatible = "ti,adc12132", },
+ { .compatible = "ti,adc12138", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, adc12138_dt_ids);
+
+#endif
+
+static const struct spi_device_id adc12138_id[] = {
+ { "adc12130", adc12130 },
+ { "adc12132", adc12132 },
+ { "adc12138", adc12138 },
+ {}
+};
+MODULE_DEVICE_TABLE(spi, adc12138_id);
+
+static struct spi_driver adc12138_driver = {
+ .driver = {
+ .name = "adc12138",
+ .of_match_table = of_match_ptr(adc12138_dt_ids),
+ },
+ .probe = adc12138_probe,
+ .remove = adc12138_remove,
+ .id_table = adc12138_id,
+};
+module_spi_driver(adc12138_driver);
+
+MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
+MODULE_DESCRIPTION("ADC12130/ADC12132/ADC12138 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/ti-adc161s626.c b/drivers/iio/adc/ti-adc161s626.c
new file mode 100644
index 000000000000..f94b69f9c288
--- /dev/null
+++ b/drivers/iio/adc/ti-adc161s626.c
@@ -0,0 +1,248 @@
+/*
+ * ti-adc161s626.c - Texas Instruments ADC161S626 1-channel differential ADC
+ *
+ * ADC Devices Supported:
+ * adc141s626 - 14-bit ADC
+ * adc161s626 - 16-bit ADC
+ *
+ * Copyright (C) 2016 Matt Ranostay <mranostay@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/spi/spi.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define TI_ADC_DRV_NAME "ti-adc161s626"
+
+enum {
+ TI_ADC141S626,
+ TI_ADC161S626,
+};
+
+static const struct iio_chan_spec ti_adc141s626_channels[] = {
+ {
+ .type = IIO_VOLTAGE,
+ .channel = 0,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 's',
+ .realbits = 14,
+ .storagebits = 16,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(1),
+};
+
+static const struct iio_chan_spec ti_adc161s626_channels[] = {
+ {
+ .type = IIO_VOLTAGE,
+ .channel = 0,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 's',
+ .realbits = 16,
+ .storagebits = 16,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(1),
+};
+
+struct ti_adc_data {
+ struct iio_dev *indio_dev;
+ struct spi_device *spi;
+ u8 read_size;
+ u8 shift;
+
+ u8 buffer[16] ____cacheline_aligned;
+};
+
+static int ti_adc_read_measurement(struct ti_adc_data *data,
+ struct iio_chan_spec const *chan, int *val)
+{
+ int ret;
+
+ switch (data->read_size) {
+ case 2: {
+ __be16 buf;
+
+ ret = spi_read(data->spi, (void *) &buf, 2);
+ if (ret)
+ return ret;
+
+ *val = be16_to_cpu(buf);
+ break;
+ }
+ case 3: {
+ __be32 buf;
+
+ ret = spi_read(data->spi, (void *) &buf, 3);
+ if (ret)
+ return ret;
+
+ *val = be32_to_cpu(buf) >> 8;
+ break;
+ }
+ default:
+ return -EINVAL;
+ }
+
+ *val = sign_extend32(*val >> data->shift, chan->scan_type.realbits - 1);
+
+ return 0;
+}
+
+static irqreturn_t ti_adc_trigger_handler(int irq, void *private)
+{
+ struct iio_poll_func *pf = private;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct ti_adc_data *data = iio_priv(indio_dev);
+ int ret;
+
+ ret = ti_adc_read_measurement(data, &indio_dev->channels[0],
+ (int *) &data->buffer);
+ if (!ret)
+ iio_push_to_buffers_with_timestamp(indio_dev,
+ data->buffer,
+ iio_get_time_ns(indio_dev));
+
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int ti_adc_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct ti_adc_data *data = iio_priv(indio_dev);
+ int ret;
+
+ if (mask != IIO_CHAN_INFO_RAW)
+ return -EINVAL;
+
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
+ ret = ti_adc_read_measurement(data, chan, val);
+ iio_device_release_direct_mode(indio_dev);
+
+ if (!ret)
+ return IIO_VAL_INT;
+
+ return 0;
+}
+
+static const struct iio_info ti_adc_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = ti_adc_read_raw,
+};
+
+static int ti_adc_probe(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev;
+ struct ti_adc_data *data;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ indio_dev->info = &ti_adc_info;
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->dev.of_node = spi->dev.of_node;
+ indio_dev->name = TI_ADC_DRV_NAME;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ spi_set_drvdata(spi, indio_dev);
+
+ data = iio_priv(indio_dev);
+ data->spi = spi;
+
+ switch (spi_get_device_id(spi)->driver_data) {
+ case TI_ADC141S626:
+ indio_dev->channels = ti_adc141s626_channels;
+ indio_dev->num_channels = ARRAY_SIZE(ti_adc141s626_channels);
+ data->shift = 0;
+ data->read_size = 2;
+ break;
+ case TI_ADC161S626:
+ indio_dev->channels = ti_adc161s626_channels;
+ indio_dev->num_channels = ARRAY_SIZE(ti_adc161s626_channels);
+ data->shift = 6;
+ data->read_size = 3;
+ break;
+ }
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ ti_adc_trigger_handler, NULL);
+ if (ret)
+ return ret;
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto error_unreg_buffer;
+
+ return 0;
+
+error_unreg_buffer:
+ iio_triggered_buffer_cleanup(indio_dev);
+
+ return ret;
+}
+
+static int ti_adc_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+
+ return 0;
+}
+
+static const struct of_device_id ti_adc_dt_ids[] = {
+ { .compatible = "ti,adc141s626", },
+ { .compatible = "ti,adc161s626", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, ti_adc_dt_ids);
+
+static const struct spi_device_id ti_adc_id[] = {
+ {"adc141s626", TI_ADC141S626},
+ {"adc161s626", TI_ADC161S626},
+ {},
+};
+MODULE_DEVICE_TABLE(spi, ti_adc_id);
+
+static struct spi_driver ti_adc_driver = {
+ .driver = {
+ .name = TI_ADC_DRV_NAME,
+ .of_match_table = of_match_ptr(ti_adc_dt_ids),
+ },
+ .probe = ti_adc_probe,
+ .remove = ti_adc_remove,
+ .id_table = ti_adc_id,
+};
+module_spi_driver(ti_adc_driver);
+
+MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>");
+MODULE_DESCRIPTION("Texas Instruments ADC1x1S 1-channel differential ADC");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c
index 066abaf80201..cde6f130a99a 100644
--- a/drivers/iio/adc/ti-ads1015.c
+++ b/drivers/iio/adc/ti-ads1015.c
@@ -522,6 +522,7 @@ static int ads1015_get_channels_config_of(struct i2c_client *client)
if (pga > 6) {
dev_err(&client->dev, "invalid gain on %s\n",
node->full_name);
+ of_node_put(node);
return -EINVAL;
}
}
@@ -532,6 +533,7 @@ static int ads1015_get_channels_config_of(struct i2c_client *client)
dev_err(&client->dev,
"invalid data_rate on %s\n",
node->full_name);
+ of_node_put(node);
return -EINVAL;
}
}
diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c
index c400439900af..4a163496d9e4 100644
--- a/drivers/iio/adc/ti-ads8688.c
+++ b/drivers/iio/adc/ti-ads8688.c
@@ -438,7 +438,7 @@ static int ads8688_probe(struct spi_device *spi)
return 0;
error_out:
- if (!IS_ERR_OR_NULL(st->reg))
+ if (!IS_ERR(st->reg))
regulator_disable(st->reg);
return ret;
@@ -451,7 +451,7 @@ static int ads8688_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
- if (!IS_ERR_OR_NULL(st->reg))
+ if (!IS_ERR(st->reg))
regulator_disable(st->reg);
return 0;
diff --git a/drivers/iio/buffer/industrialio-buffer-cb.c b/drivers/iio/buffer/industrialio-buffer-cb.c
index 323079c3ccce..b8f550e47d3d 100644
--- a/drivers/iio/buffer/industrialio-buffer-cb.c
+++ b/drivers/iio/buffer/industrialio-buffer-cb.c
@@ -18,6 +18,7 @@ struct iio_cb_buffer {
int (*cb)(const void *data, void *private);
void *private;
struct iio_channel *channels;
+ struct iio_dev *indio_dev;
};
static struct iio_cb_buffer *buffer_to_cb_buffer(struct iio_buffer *buffer)
@@ -52,7 +53,6 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
{
int ret;
struct iio_cb_buffer *cb_buff;
- struct iio_dev *indio_dev;
struct iio_channel *chan;
cb_buff = kzalloc(sizeof(*cb_buff), GFP_KERNEL);
@@ -72,17 +72,17 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
goto error_free_cb_buff;
}
- indio_dev = cb_buff->channels[0].indio_dev;
+ cb_buff->indio_dev = cb_buff->channels[0].indio_dev;
cb_buff->buffer.scan_mask
- = kcalloc(BITS_TO_LONGS(indio_dev->masklength), sizeof(long),
- GFP_KERNEL);
+ = kcalloc(BITS_TO_LONGS(cb_buff->indio_dev->masklength),
+ sizeof(long), GFP_KERNEL);
if (cb_buff->buffer.scan_mask == NULL) {
ret = -ENOMEM;
goto error_release_channels;
}
chan = &cb_buff->channels[0];
while (chan->indio_dev) {
- if (chan->indio_dev != indio_dev) {
+ if (chan->indio_dev != cb_buff->indio_dev) {
ret = -EINVAL;
goto error_free_scan_mask;
}
@@ -105,17 +105,14 @@ EXPORT_SYMBOL_GPL(iio_channel_get_all_cb);
int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff)
{
- return iio_update_buffers(cb_buff->channels[0].indio_dev,
- &cb_buff->buffer,
+ return iio_update_buffers(cb_buff->indio_dev, &cb_buff->buffer,
NULL);
}
EXPORT_SYMBOL_GPL(iio_channel_start_all_cb);
void iio_channel_stop_all_cb(struct iio_cb_buffer *cb_buff)
{
- iio_update_buffers(cb_buff->channels[0].indio_dev,
- NULL,
- &cb_buff->buffer);
+ iio_update_buffers(cb_buff->indio_dev, NULL, &cb_buff->buffer);
}
EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb);
@@ -133,6 +130,13 @@ struct iio_channel
}
EXPORT_SYMBOL_GPL(iio_channel_cb_get_channels);
+struct iio_dev
+*iio_channel_cb_get_iio_dev(const struct iio_cb_buffer *cb_buffer)
+{
+ return cb_buffer->indio_dev;
+}
+EXPORT_SYMBOL_GPL(iio_channel_cb_get_iio_dev);
+
MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("Industrial I/O callback buffer");
MODULE_LICENSE("GPL");
diff --git a/drivers/iio/buffer/industrialio-triggered-buffer.c b/drivers/iio/buffer/industrialio-triggered-buffer.c
index 4b2858ba1fd6..d3db1fce54d2 100644
--- a/drivers/iio/buffer/industrialio-triggered-buffer.c
+++ b/drivers/iio/buffer/industrialio-triggered-buffer.c
@@ -98,6 +98,48 @@ void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev)
}
EXPORT_SYMBOL(iio_triggered_buffer_cleanup);
+static void devm_iio_triggered_buffer_clean(struct device *dev, void *res)
+{
+ iio_triggered_buffer_cleanup(*(struct iio_dev **)res);
+}
+
+int devm_iio_triggered_buffer_setup(struct device *dev,
+ struct iio_dev *indio_dev,
+ irqreturn_t (*h)(int irq, void *p),
+ irqreturn_t (*thread)(int irq, void *p),
+ const struct iio_buffer_setup_ops *ops)
+{
+ struct iio_dev **ptr;
+ int ret;
+
+ ptr = devres_alloc(devm_iio_triggered_buffer_clean, sizeof(*ptr),
+ GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ *ptr = indio_dev;
+
+ ret = iio_triggered_buffer_setup(indio_dev, h, thread, ops);
+ if (!ret)
+ devres_add(dev, ptr);
+ else
+ devres_free(ptr);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(devm_iio_triggered_buffer_setup);
+
+void devm_iio_triggered_buffer_cleanup(struct device *dev,
+ struct iio_dev *indio_dev)
+{
+ int rc;
+
+ rc = devres_release(dev, devm_iio_triggered_buffer_clean,
+ devm_iio_device_match, indio_dev);
+ WARN_ON(rc);
+}
+EXPORT_SYMBOL_GPL(devm_iio_triggered_buffer_cleanup);
+
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("IIO helper functions for setting up triggered buffers");
MODULE_LICENSE("GPL");
diff --git a/drivers/iio/chemical/Kconfig b/drivers/iio/chemical/Kconfig
index 4bcc025e8c8a..cea7f9857a1f 100644
--- a/drivers/iio/chemical/Kconfig
+++ b/drivers/iio/chemical/Kconfig
@@ -16,6 +16,7 @@ config ATLAS_PH_SENSOR
Atlas Scientific OEM SM sensors:
* pH SM sensor
* EC SM sensor
+ * ORP SM sensor
To compile this driver as module, choose M here: the
module will be called atlas-ph-sensor.
diff --git a/drivers/iio/chemical/atlas-ph-sensor.c b/drivers/iio/chemical/atlas-ph-sensor.c
index 407f141a1eee..bd321b305a0a 100644
--- a/drivers/iio/chemical/atlas-ph-sensor.c
+++ b/drivers/iio/chemical/atlas-ph-sensor.c
@@ -66,12 +66,17 @@
#define ATLAS_REG_TDS_DATA 0x1c
#define ATLAS_REG_PSS_DATA 0x20
+#define ATLAS_REG_ORP_CALIB_STATUS 0x0d
+#define ATLAS_REG_ORP_DATA 0x0e
+
#define ATLAS_PH_INT_TIME_IN_US 450000
#define ATLAS_EC_INT_TIME_IN_US 650000
+#define ATLAS_ORP_INT_TIME_IN_US 450000
enum {
ATLAS_PH_SM,
ATLAS_EC_SM,
+ ATLAS_ORP_SM,
};
struct atlas_data {
@@ -84,26 +89,10 @@ struct atlas_data {
__be32 buffer[6]; /* 96-bit data + 32-bit pad + 64-bit timestamp */
};
-static const struct regmap_range atlas_volatile_ranges[] = {
- regmap_reg_range(ATLAS_REG_INT_CONTROL, ATLAS_REG_INT_CONTROL),
- regmap_reg_range(ATLAS_REG_PH_DATA, ATLAS_REG_PH_DATA + 4),
- regmap_reg_range(ATLAS_REG_EC_DATA, ATLAS_REG_PSS_DATA + 4),
-};
-
-static const struct regmap_access_table atlas_volatile_table = {
- .yes_ranges = atlas_volatile_ranges,
- .n_yes_ranges = ARRAY_SIZE(atlas_volatile_ranges),
-};
-
static const struct regmap_config atlas_regmap_config = {
.name = ATLAS_REGMAP_NAME,
-
.reg_bits = 8,
.val_bits = 8,
-
- .volatile_table = &atlas_volatile_table,
- .max_register = ATLAS_REG_PSS_DATA + 4,
- .cache_type = REGCACHE_RBTREE,
};
static const struct iio_chan_spec atlas_ph_channels[] = {
@@ -175,6 +164,23 @@ static const struct iio_chan_spec atlas_ec_channels[] = {
},
};
+static const struct iio_chan_spec atlas_orp_channels[] = {
+ {
+ .type = IIO_VOLTAGE,
+ .address = ATLAS_REG_ORP_DATA,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 's',
+ .realbits = 32,
+ .storagebits = 32,
+ .endianness = IIO_BE,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(1),
+};
+
static int atlas_check_ph_calibration(struct atlas_data *data)
{
struct device *dev = &data->client->dev;
@@ -240,6 +246,22 @@ static int atlas_check_ec_calibration(struct atlas_data *data)
return 0;
}
+static int atlas_check_orp_calibration(struct atlas_data *data)
+{
+ struct device *dev = &data->client->dev;
+ int ret;
+ unsigned int val;
+
+ ret = regmap_read(data->regmap, ATLAS_REG_ORP_CALIB_STATUS, &val);
+ if (ret)
+ return ret;
+
+ if (!val)
+ dev_warn(dev, "device has not been calibrated\n");
+
+ return 0;
+};
+
struct atlas_device {
const struct iio_chan_spec *channels;
int num_channels;
@@ -264,7 +286,13 @@ static struct atlas_device atlas_devices[] = {
.calibration = &atlas_check_ec_calibration,
.delay = ATLAS_EC_INT_TIME_IN_US,
},
-
+ [ATLAS_ORP_SM] = {
+ .channels = atlas_orp_channels,
+ .num_channels = 2,
+ .data_reg = ATLAS_REG_ORP_DATA,
+ .calibration = &atlas_check_orp_calibration,
+ .delay = ATLAS_ORP_INT_TIME_IN_US,
+ },
};
static int atlas_set_powermode(struct atlas_data *data, int on)
@@ -402,15 +430,14 @@ static int atlas_read_raw(struct iio_dev *indio_dev,
case IIO_PH:
case IIO_CONCENTRATION:
case IIO_ELECTRICALCONDUCTIVITY:
- mutex_lock(&indio_dev->mlock);
+ case IIO_VOLTAGE:
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
- if (iio_buffer_enabled(indio_dev))
- ret = -EBUSY;
- else
- ret = atlas_read_measurement(data,
- chan->address, &reg);
+ ret = atlas_read_measurement(data, chan->address, &reg);
- mutex_unlock(&indio_dev->mlock);
+ iio_device_release_direct_mode(indio_dev);
break;
default:
ret = -EINVAL;
@@ -440,6 +467,10 @@ static int atlas_read_raw(struct iio_dev *indio_dev,
*val = 0; /* 0.000000001 */
*val2 = 1000;
return IIO_VAL_INT_PLUS_NANO;
+ case IIO_VOLTAGE:
+ *val = 1; /* 0.1 */
+ *val2 = 10;
+ break;
default:
return -EINVAL;
}
@@ -475,6 +506,7 @@ static const struct iio_info atlas_info = {
static const struct i2c_device_id atlas_id[] = {
{ "atlas-ph-sm", ATLAS_PH_SM},
{ "atlas-ec-sm", ATLAS_EC_SM},
+ { "atlas-orp-sm", ATLAS_ORP_SM},
{}
};
MODULE_DEVICE_TABLE(i2c, atlas_id);
@@ -482,6 +514,7 @@ MODULE_DEVICE_TABLE(i2c, atlas_id);
static const struct of_device_id atlas_dt_ids[] = {
{ .compatible = "atlas,ph-sm", .data = (void *)ATLAS_PH_SM, },
{ .compatible = "atlas,ec-sm", .data = (void *)ATLAS_EC_SM, },
+ { .compatible = "atlas,orp-sm", .data = (void *)ATLAS_ORP_SM, },
{ }
};
MODULE_DEVICE_TABLE(of, atlas_dt_ids);
diff --git a/drivers/iio/chemical/vz89x.c b/drivers/iio/chemical/vz89x.c
index 652649da500f..8e0e4415c161 100644
--- a/drivers/iio/chemical/vz89x.c
+++ b/drivers/iio/chemical/vz89x.c
@@ -19,25 +19,55 @@
#include <linux/mutex.h>
#include <linux/init.h>
#include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#define VZ89X_REG_MEASUREMENT 0x09
-#define VZ89X_REG_MEASUREMENT_SIZE 6
+#define VZ89X_REG_MEASUREMENT_RD_SIZE 6
+#define VZ89X_REG_MEASUREMENT_WR_SIZE 3
#define VZ89X_VOC_CO2_IDX 0
#define VZ89X_VOC_SHORT_IDX 1
#define VZ89X_VOC_TVOC_IDX 2
#define VZ89X_VOC_RESISTANCE_IDX 3
+#define VZ89TE_REG_MEASUREMENT 0x0c
+#define VZ89TE_REG_MEASUREMENT_RD_SIZE 7
+#define VZ89TE_REG_MEASUREMENT_WR_SIZE 6
+
+#define VZ89TE_VOC_TVOC_IDX 0
+#define VZ89TE_VOC_CO2_IDX 1
+#define VZ89TE_VOC_RESISTANCE_IDX 2
+
+enum {
+ VZ89X,
+ VZ89TE,
+};
+
+struct vz89x_chip_data;
+
struct vz89x_data {
struct i2c_client *client;
+ const struct vz89x_chip_data *chip;
struct mutex lock;
int (*xfer)(struct vz89x_data *data, u8 cmd);
+ bool is_valid;
unsigned long last_update;
- u8 buffer[VZ89X_REG_MEASUREMENT_SIZE];
+ u8 buffer[VZ89TE_REG_MEASUREMENT_RD_SIZE];
+};
+
+struct vz89x_chip_data {
+ bool (*valid)(struct vz89x_data *data);
+ const struct iio_chan_spec *channels;
+ u8 num_channels;
+
+ u8 cmd;
+ u8 read_size;
+ u8 write_size;
};
static const struct iio_chan_spec vz89x_channels[] = {
@@ -70,6 +100,40 @@ static const struct iio_chan_spec vz89x_channels[] = {
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
.address = VZ89X_VOC_RESISTANCE_IDX,
+ .scan_index = -1,
+ .scan_type = {
+ .endianness = IIO_LE,
+ },
+ },
+};
+
+static const struct iio_chan_spec vz89te_channels[] = {
+ {
+ .type = IIO_CONCENTRATION,
+ .channel2 = IIO_MOD_VOC,
+ .modified = 1,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_RAW),
+ .address = VZ89TE_VOC_TVOC_IDX,
+ },
+
+ {
+ .type = IIO_CONCENTRATION,
+ .channel2 = IIO_MOD_CO2,
+ .modified = 1,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_RAW),
+ .address = VZ89TE_VOC_CO2_IDX,
+ },
+ {
+ .type = IIO_RESISTANCE,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ .address = VZ89TE_VOC_RESISTANCE_IDX,
+ .scan_index = -1,
+ .scan_type = {
+ .endianness = IIO_BE,
+ },
},
};
@@ -93,29 +157,45 @@ static const struct attribute_group vz89x_attrs_group = {
* always zero, and by also confirming the VOC_short isn't zero.
*/
-static int vz89x_measurement_is_valid(struct vz89x_data *data)
+static bool vz89x_measurement_is_valid(struct vz89x_data *data)
{
if (data->buffer[VZ89X_VOC_SHORT_IDX] == 0)
- return 1;
+ return true;
- return !!(data->buffer[VZ89X_REG_MEASUREMENT_SIZE - 1] > 0);
+ return !!(data->buffer[data->chip->read_size - 1] > 0);
+}
+
+/* VZ89TE device has a modified CRC-8 two complement check */
+static bool vz89te_measurement_is_valid(struct vz89x_data *data)
+{
+ u8 crc = 0;
+ int i, sum = 0;
+
+ for (i = 0; i < (data->chip->read_size - 1); i++) {
+ sum = crc + data->buffer[i];
+ crc = sum;
+ crc += sum / 256;
+ }
+
+ return !((0xff - crc) == data->buffer[data->chip->read_size - 1]);
}
static int vz89x_i2c_xfer(struct vz89x_data *data, u8 cmd)
{
+ const struct vz89x_chip_data *chip = data->chip;
struct i2c_client *client = data->client;
struct i2c_msg msg[2];
int ret;
- u8 buf[3] = { cmd, 0, 0};
+ u8 buf[6] = { cmd, 0, 0, 0, 0, 0xf3 };
msg[0].addr = client->addr;
msg[0].flags = client->flags;
- msg[0].len = 3;
+ msg[0].len = chip->write_size;
msg[0].buf = (char *) &buf;
msg[1].addr = client->addr;
msg[1].flags = client->flags | I2C_M_RD;
- msg[1].len = VZ89X_REG_MEASUREMENT_SIZE;
+ msg[1].len = chip->read_size;
msg[1].buf = (char *) &data->buffer;
ret = i2c_transfer(client->adapter, msg, 2);
@@ -133,7 +213,7 @@ static int vz89x_smbus_xfer(struct vz89x_data *data, u8 cmd)
if (ret < 0)
return ret;
- for (i = 0; i < VZ89X_REG_MEASUREMENT_SIZE; i++) {
+ for (i = 0; i < data->chip->read_size; i++) {
ret = i2c_smbus_read_byte(client);
if (ret < 0)
return ret;
@@ -145,30 +225,47 @@ static int vz89x_smbus_xfer(struct vz89x_data *data, u8 cmd)
static int vz89x_get_measurement(struct vz89x_data *data)
{
+ const struct vz89x_chip_data *chip = data->chip;
int ret;
/* sensor can only be polled once a second max per datasheet */
if (!time_after(jiffies, data->last_update + HZ))
- return 0;
+ return data->is_valid ? 0 : -EAGAIN;
+
+ data->is_valid = false;
+ data->last_update = jiffies;
- ret = data->xfer(data, VZ89X_REG_MEASUREMENT);
+ ret = data->xfer(data, chip->cmd);
if (ret < 0)
return ret;
- ret = vz89x_measurement_is_valid(data);
+ ret = chip->valid(data);
if (ret)
return -EAGAIN;
- data->last_update = jiffies;
+ data->is_valid = true;
return 0;
}
-static int vz89x_get_resistance_reading(struct vz89x_data *data)
+static int vz89x_get_resistance_reading(struct vz89x_data *data,
+ struct iio_chan_spec const *chan,
+ int *val)
{
- u8 *buf = &data->buffer[VZ89X_VOC_RESISTANCE_IDX];
+ u8 *tmp = (u8 *) &data->buffer[chan->address];
- return buf[0] | (buf[1] << 8);
+ switch (chan->scan_type.endianness) {
+ case IIO_LE:
+ *val = le32_to_cpup((__le32 *) tmp) & GENMASK(23, 0);
+ break;
+ case IIO_BE:
+ *val = be32_to_cpup((__be32 *) tmp) >> 8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
}
static int vz89x_read_raw(struct iio_dev *indio_dev,
@@ -187,15 +284,15 @@ static int vz89x_read_raw(struct iio_dev *indio_dev,
if (ret)
return ret;
- switch (chan->address) {
- case VZ89X_VOC_CO2_IDX:
- case VZ89X_VOC_SHORT_IDX:
- case VZ89X_VOC_TVOC_IDX:
+ switch (chan->type) {
+ case IIO_CONCENTRATION:
*val = data->buffer[chan->address];
return IIO_VAL_INT;
- case VZ89X_VOC_RESISTANCE_IDX:
- *val = vz89x_get_resistance_reading(data);
- return IIO_VAL_INT;
+ case IIO_RESISTANCE:
+ ret = vz89x_get_resistance_reading(data, chan, val);
+ if (!ret)
+ return IIO_VAL_INT;
+ break;
default:
return -EINVAL;
}
@@ -210,12 +307,12 @@ static int vz89x_read_raw(struct iio_dev *indio_dev,
}
break;
case IIO_CHAN_INFO_OFFSET:
- switch (chan->address) {
- case VZ89X_VOC_CO2_IDX:
+ switch (chan->channel2) {
+ case IIO_MOD_CO2:
*val = 44;
*val2 = 250000;
return IIO_VAL_INT_PLUS_MICRO;
- case VZ89X_VOC_TVOC_IDX:
+ case IIO_MOD_VOC:
*val = -13;
return IIO_VAL_INT;
default:
@@ -232,11 +329,43 @@ static const struct iio_info vz89x_info = {
.driver_module = THIS_MODULE,
};
+static const struct vz89x_chip_data vz89x_chips[] = {
+ {
+ .valid = vz89x_measurement_is_valid,
+
+ .cmd = VZ89X_REG_MEASUREMENT,
+ .read_size = VZ89X_REG_MEASUREMENT_RD_SIZE,
+ .write_size = VZ89X_REG_MEASUREMENT_WR_SIZE,
+
+ .channels = vz89x_channels,
+ .num_channels = ARRAY_SIZE(vz89x_channels),
+ },
+ {
+ .valid = vz89te_measurement_is_valid,
+
+ .cmd = VZ89TE_REG_MEASUREMENT,
+ .read_size = VZ89TE_REG_MEASUREMENT_RD_SIZE,
+ .write_size = VZ89TE_REG_MEASUREMENT_WR_SIZE,
+
+ .channels = vz89te_channels,
+ .num_channels = ARRAY_SIZE(vz89te_channels),
+ },
+};
+
+static const struct of_device_id vz89x_dt_ids[] = {
+ { .compatible = "sgx,vz89x", .data = (void *) VZ89X },
+ { .compatible = "sgx,vz89te", .data = (void *) VZ89TE },
+ { }
+};
+MODULE_DEVICE_TABLE(of, vz89x_dt_ids);
+
static int vz89x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct iio_dev *indio_dev;
struct vz89x_data *data;
+ const struct of_device_id *of_id;
+ int chip_id;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
@@ -251,8 +380,15 @@ static int vz89x_probe(struct i2c_client *client,
else
return -EOPNOTSUPP;
+ of_id = of_match_device(vz89x_dt_ids, &client->dev);
+ if (!of_id)
+ chip_id = id->driver_data;
+ else
+ chip_id = (unsigned long)of_id->data;
+
i2c_set_clientdata(client, indio_dev);
data->client = client;
+ data->chip = &vz89x_chips[chip_id];
data->last_update = jiffies - HZ;
mutex_init(&data->lock);
@@ -261,24 +397,19 @@ static int vz89x_probe(struct i2c_client *client,
indio_dev->name = dev_name(&client->dev);
indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->channels = vz89x_channels;
- indio_dev->num_channels = ARRAY_SIZE(vz89x_channels);
+ indio_dev->channels = data->chip->channels;
+ indio_dev->num_channels = data->chip->num_channels;
return devm_iio_device_register(&client->dev, indio_dev);
}
static const struct i2c_device_id vz89x_id[] = {
- { "vz89x", 0 },
+ { "vz89x", VZ89X },
+ { "vz89te", VZ89TE },
{ }
};
MODULE_DEVICE_TABLE(i2c, vz89x_id);
-static const struct of_device_id vz89x_dt_ids[] = {
- { .compatible = "sgx,vz89x" },
- { }
-};
-MODULE_DEVICE_TABLE(of, vz89x_dt_ids);
-
static struct i2c_driver vz89x_driver = {
.driver = {
.name = "vz89x",
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 5b41f9d0d4f3..a3cce3a38300 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -122,6 +122,14 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
#endif
}
+static void hid_sensor_set_power_work(struct work_struct *work)
+{
+ struct hid_sensor_common *attrb = container_of(work,
+ struct hid_sensor_common,
+ work);
+ _hid_sensor_power_state(attrb, true);
+}
+
static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
bool state)
{
@@ -130,6 +138,7 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
void hid_sensor_remove_trigger(struct hid_sensor_common *attrb)
{
+ cancel_work_sync(&attrb->work);
iio_trigger_unregister(attrb->trigger);
iio_trigger_free(attrb->trigger);
}
@@ -170,6 +179,9 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
goto error_unreg_trigger;
iio_device_set_drvdata(indio_dev, attrb);
+
+ INIT_WORK(&attrb->work, hid_sensor_set_power_work);
+
pm_suspend_ignore_children(&attrb->pdev->dev, true);
pm_runtime_enable(&attrb->pdev->dev);
/* Default to 3 seconds, but can be changed from sysfs */
@@ -187,8 +199,7 @@ error_ret:
}
EXPORT_SYMBOL(hid_sensor_setup_trigger);
-#ifdef CONFIG_PM
-static int hid_sensor_suspend(struct device *dev)
+static int __maybe_unused hid_sensor_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
@@ -197,21 +208,27 @@ static int hid_sensor_suspend(struct device *dev)
return _hid_sensor_power_state(attrb, false);
}
-static int hid_sensor_resume(struct device *dev)
+static int __maybe_unused hid_sensor_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
+ schedule_work(&attrb->work);
+ return 0;
+}
+static int __maybe_unused hid_sensor_runtime_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
return _hid_sensor_power_state(attrb, true);
}
-#endif
-
const struct dev_pm_ops hid_sensor_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(hid_sensor_suspend, hid_sensor_resume)
SET_RUNTIME_PM_OPS(hid_sensor_suspend,
- hid_sensor_resume, NULL)
+ hid_sensor_runtime_resume, NULL)
};
EXPORT_SYMBOL(hid_sensor_pm_ops);
diff --git a/drivers/iio/common/st_sensors/st_sensors_buffer.c b/drivers/iio/common/st_sensors/st_sensors_buffer.c
index d06e728cea37..fe7775bb3740 100644
--- a/drivers/iio/common/st_sensors/st_sensors_buffer.c
+++ b/drivers/iio/common/st_sensors/st_sensors_buffer.c
@@ -63,7 +63,7 @@ irqreturn_t st_sensors_trigger_handler(int irq, void *p)
* the hardware trigger) and the hw_timestamp may get updated.
* By storing it in a local variable first, we are safe.
*/
- if (sdata->hw_irq_trigger)
+ if (iio_trigger_using_own(indio_dev))
timestamp = sdata->hw_timestamp;
else
timestamp = iio_get_time_ns(indio_dev);
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index 2d5282e05482..285a64a589d7 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -234,39 +234,35 @@ int st_sensors_power_enable(struct iio_dev *indio_dev)
int err;
/* Regulators not mandatory, but if requested we should enable them. */
- pdata->vdd = devm_regulator_get_optional(indio_dev->dev.parent, "vdd");
- if (!IS_ERR(pdata->vdd)) {
- err = regulator_enable(pdata->vdd);
- if (err != 0) {
- dev_warn(&indio_dev->dev,
- "Failed to enable specified Vdd supply\n");
- return err;
- }
- } else {
- err = PTR_ERR(pdata->vdd);
- if (err != -ENODEV)
- return err;
+ pdata->vdd = devm_regulator_get(indio_dev->dev.parent, "vdd");
+ if (IS_ERR(pdata->vdd)) {
+ dev_err(&indio_dev->dev, "unable to get Vdd supply\n");
+ return PTR_ERR(pdata->vdd);
+ }
+ err = regulator_enable(pdata->vdd);
+ if (err != 0) {
+ dev_warn(&indio_dev->dev,
+ "Failed to enable specified Vdd supply\n");
+ return err;
}
- pdata->vdd_io = devm_regulator_get_optional(indio_dev->dev.parent, "vddio");
- if (!IS_ERR(pdata->vdd_io)) {
- err = regulator_enable(pdata->vdd_io);
- if (err != 0) {
- dev_warn(&indio_dev->dev,
- "Failed to enable specified Vdd_IO supply\n");
- goto st_sensors_disable_vdd;
- }
- } else {
+ pdata->vdd_io = devm_regulator_get(indio_dev->dev.parent, "vddio");
+ if (IS_ERR(pdata->vdd_io)) {
+ dev_err(&indio_dev->dev, "unable to get Vdd_IO supply\n");
err = PTR_ERR(pdata->vdd_io);
- if (err != -ENODEV)
- goto st_sensors_disable_vdd;
+ goto st_sensors_disable_vdd;
+ }
+ err = regulator_enable(pdata->vdd_io);
+ if (err != 0) {
+ dev_warn(&indio_dev->dev,
+ "Failed to enable specified Vdd_IO supply\n");
+ goto st_sensors_disable_vdd;
}
return 0;
st_sensors_disable_vdd:
- if (!IS_ERR_OR_NULL(pdata->vdd))
- regulator_disable(pdata->vdd);
+ regulator_disable(pdata->vdd);
return err;
}
EXPORT_SYMBOL(st_sensors_power_enable);
@@ -275,11 +271,8 @@ void st_sensors_power_disable(struct iio_dev *indio_dev)
{
struct st_sensor_data *pdata = iio_priv(indio_dev);
- if (!IS_ERR_OR_NULL(pdata->vdd))
- regulator_disable(pdata->vdd);
-
- if (!IS_ERR_OR_NULL(pdata->vdd_io))
- regulator_disable(pdata->vdd_io);
+ regulator_disable(pdata->vdd);
+ regulator_disable(pdata->vdd_io);
}
EXPORT_SYMBOL(st_sensors_power_disable);
diff --git a/drivers/iio/common/st_sensors/st_sensors_trigger.c b/drivers/iio/common/st_sensors/st_sensors_trigger.c
index e66f12ee8a55..fa73e6795359 100644
--- a/drivers/iio/common/st_sensors/st_sensors_trigger.c
+++ b/drivers/iio/common/st_sensors/st_sensors_trigger.c
@@ -66,7 +66,7 @@ static int st_sensors_new_samples_available(struct iio_dev *indio_dev,
* @irq: irq number
* @p: private handler data
*/
-irqreturn_t st_sensors_irq_handler(int irq, void *p)
+static irqreturn_t st_sensors_irq_handler(int irq, void *p)
{
struct iio_trigger *trig = p;
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
@@ -82,7 +82,7 @@ irqreturn_t st_sensors_irq_handler(int irq, void *p)
* @irq: irq number
* @p: private handler data
*/
-irqreturn_t st_sensors_irq_thread(int irq, void *p)
+static irqreturn_t st_sensors_irq_thread(int irq, void *p)
{
struct iio_trigger *trig = p;
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index ca814479fadf..120b24478469 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -181,6 +181,25 @@ config AD7303
To compile this driver as module choose M here: the module will be called
ad7303.
+config CIO_DAC
+ tristate "Measurement Computing CIO-DAC IIO driver"
+ depends on X86 && ISA_BUS_API
+ help
+ Say yes here to build support for the Measurement Computing CIO-DAC
+ analog output device family (CIO-DAC16, CIO-DAC08, PC104-DAC06). The
+ base port addresses for the devices may be configured via the base
+ array module parameter.
+
+config AD8801
+ tristate "Analog Devices AD8801/AD8803 DAC driver"
+ depends on SPI_MASTER
+ help
+ Say yes here to build support for Analog Devices AD8801, AD8803 Digital to
+ Analog Converters (DAC).
+
+ To compile this driver as a module choose M here: the module will be called
+ ad8801.
+
config LPC18XX_DAC
tristate "NXP LPC18xx DAC driver"
depends on ARCH_LPC18XX || COMPILE_TEST
@@ -245,16 +264,6 @@ config MCP4922
To compile this driver as a module, choose M here: the module
will be called mcp4922.
-config STX104
- tristate "Apex Embedded Systems STX104 DAC driver"
- depends on X86 && ISA_BUS_API
- select GPIOLIB
- help
- Say yes here to build support for the 2-channel DAC and GPIO on the
- Apex Embedded Systems STX104 integrated analog PC/104 card. The base
- port addresses for the devices may be configured via the base array
- module parameter.
-
config VF610_DAC
tristate "Vybrid vf610 DAC driver"
depends on OF
diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile
index 8b78d5ca9b11..27642bbf75f2 100644
--- a/drivers/iio/dac/Makefile
+++ b/drivers/iio/dac/Makefile
@@ -20,11 +20,12 @@ obj-$(CONFIG_AD5764) += ad5764.o
obj-$(CONFIG_AD5791) += ad5791.o
obj-$(CONFIG_AD5686) += ad5686.o
obj-$(CONFIG_AD7303) += ad7303.o
+obj-$(CONFIG_AD8801) += ad8801.o
+obj-$(CONFIG_CIO_DAC) += cio-dac.o
obj-$(CONFIG_LPC18XX_DAC) += lpc18xx_dac.o
obj-$(CONFIG_M62332) += m62332.o
obj-$(CONFIG_MAX517) += max517.o
obj-$(CONFIG_MAX5821) += max5821.o
obj-$(CONFIG_MCP4725) += mcp4725.o
obj-$(CONFIG_MCP4922) += mcp4922.o
-obj-$(CONFIG_STX104) += stx104.o
obj-$(CONFIG_VF610_DAC) += vf610_dac.o
diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c
index 0fde593ec0d9..5f7968232564 100644
--- a/drivers/iio/dac/ad5755.c
+++ b/drivers/iio/dac/ad5755.c
@@ -655,7 +655,7 @@ static struct ad5755_platform_data *ad5755_parse_dt(struct device *dev)
devnr = 0;
for_each_child_of_node(np, pp) {
- if (devnr > AD5755_NUM_CHANNELS) {
+ if (devnr >= AD5755_NUM_CHANNELS) {
dev_err(dev,
"There is to many channels defined in DT\n");
goto error_out;
diff --git a/drivers/iio/dac/ad8801.c b/drivers/iio/dac/ad8801.c
new file mode 100644
index 000000000000..f06faa1aec09
--- /dev/null
+++ b/drivers/iio/dac/ad8801.c
@@ -0,0 +1,239 @@
+/*
+ * IIO DAC driver for Analog Devices AD8801 DAC
+ *
+ * Copyright (C) 2016 Gwenhael Goavec-Merou
+ * 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.
+ *
+ */
+
+#include <linux/iio/iio.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+#include <linux/sysfs.h>
+
+#define AD8801_CFG_ADDR_OFFSET 8
+
+enum ad8801_device_ids {
+ ID_AD8801,
+ ID_AD8803,
+};
+
+struct ad8801_state {
+ struct spi_device *spi;
+ unsigned char dac_cache[8]; /* Value write on each channel */
+ unsigned int vrefh_mv;
+ unsigned int vrefl_mv;
+ struct regulator *vrefh_reg;
+ struct regulator *vrefl_reg;
+
+ __be16 data ____cacheline_aligned;
+};
+
+static int ad8801_spi_write(struct ad8801_state *state,
+ u8 channel, unsigned char value)
+{
+ state->data = cpu_to_be16((channel << AD8801_CFG_ADDR_OFFSET) | value);
+ return spi_write(state->spi, &state->data, sizeof(state->data));
+}
+
+static int ad8801_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int val, int val2, long mask)
+{
+ struct ad8801_state *state = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (val >= 256 || val < 0)
+ return -EINVAL;
+
+ ret = ad8801_spi_write(state, chan->channel, val);
+ if (ret == 0)
+ state->dac_cache[chan->channel] = val;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int ad8801_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val, int *val2, long info)
+{
+ struct ad8801_state *state = iio_priv(indio_dev);
+
+ switch (info) {
+ case IIO_CHAN_INFO_RAW:
+ *val = state->dac_cache[chan->channel];
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = state->vrefh_mv - state->vrefl_mv;
+ *val2 = 8;
+ return IIO_VAL_FRACTIONAL_LOG2;
+ case IIO_CHAN_INFO_OFFSET:
+ *val = state->vrefl_mv;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+
+ return -EINVAL;
+}
+
+static const struct iio_info ad8801_info = {
+ .read_raw = ad8801_read_raw,
+ .write_raw = ad8801_write_raw,
+ .driver_module = THIS_MODULE,
+};
+
+#define AD8801_CHANNEL(chan) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .output = 1, \
+ .channel = chan, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_OFFSET), \
+}
+
+static const struct iio_chan_spec ad8801_channels[] = {
+ AD8801_CHANNEL(0),
+ AD8801_CHANNEL(1),
+ AD8801_CHANNEL(2),
+ AD8801_CHANNEL(3),
+ AD8801_CHANNEL(4),
+ AD8801_CHANNEL(5),
+ AD8801_CHANNEL(6),
+ AD8801_CHANNEL(7),
+};
+
+static int ad8801_probe(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev;
+ struct ad8801_state *state;
+ const struct spi_device_id *id;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ state = iio_priv(indio_dev);
+ state->spi = spi;
+ id = spi_get_device_id(spi);
+
+ state->vrefh_reg = devm_regulator_get(&spi->dev, "vrefh");
+ if (IS_ERR(state->vrefh_reg)) {
+ dev_err(&spi->dev, "Vrefh regulator not specified\n");
+ return PTR_ERR(state->vrefh_reg);
+ }
+
+ ret = regulator_enable(state->vrefh_reg);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to enable vrefh regulator: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = regulator_get_voltage(state->vrefh_reg);
+ if (ret < 0) {
+ dev_err(&spi->dev, "Failed to read vrefh regulator: %d\n",
+ ret);
+ goto error_disable_vrefh_reg;
+ }
+ state->vrefh_mv = ret / 1000;
+
+ if (id->driver_data == ID_AD8803) {
+ state->vrefl_reg = devm_regulator_get(&spi->dev, "vrefl");
+ if (IS_ERR(state->vrefl_reg)) {
+ dev_err(&spi->dev, "Vrefl regulator not specified\n");
+ ret = PTR_ERR(state->vrefl_reg);
+ goto error_disable_vrefh_reg;
+ }
+
+ ret = regulator_enable(state->vrefl_reg);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to enable vrefl regulator: %d\n",
+ ret);
+ goto error_disable_vrefh_reg;
+ }
+
+ ret = regulator_get_voltage(state->vrefl_reg);
+ if (ret < 0) {
+ dev_err(&spi->dev, "Failed to read vrefl regulator: %d\n",
+ ret);
+ goto error_disable_vrefl_reg;
+ }
+ state->vrefl_mv = ret / 1000;
+ } else {
+ state->vrefl_mv = 0;
+ state->vrefl_reg = NULL;
+ }
+
+ spi_set_drvdata(spi, indio_dev);
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->info = &ad8801_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = ad8801_channels;
+ indio_dev->num_channels = ARRAY_SIZE(ad8801_channels);
+ indio_dev->name = id->name;
+
+ ret = iio_device_register(indio_dev);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to register iio device: %d\n",
+ ret);
+ goto error_disable_vrefl_reg;
+ }
+
+ return 0;
+
+error_disable_vrefl_reg:
+ if (state->vrefl_reg)
+ regulator_disable(state->vrefl_reg);
+error_disable_vrefh_reg:
+ regulator_disable(state->vrefh_reg);
+ return ret;
+}
+
+static int ad8801_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct ad8801_state *state = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ if (state->vrefl_reg)
+ regulator_disable(state->vrefl_reg);
+ regulator_disable(state->vrefh_reg);
+
+ return 0;
+}
+
+static const struct spi_device_id ad8801_ids[] = {
+ {"ad8801", ID_AD8801},
+ {"ad8803", ID_AD8803},
+ {}
+};
+MODULE_DEVICE_TABLE(spi, ad8801_ids);
+
+static struct spi_driver ad8801_driver = {
+ .driver = {
+ .name = "ad8801",
+ },
+ .probe = ad8801_probe,
+ .remove = ad8801_remove,
+ .id_table = ad8801_ids,
+};
+module_spi_driver(ad8801_driver);
+
+MODULE_AUTHOR("Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>");
+MODULE_DESCRIPTION("Analog Devices AD8801/AD8803 DAC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dac/cio-dac.c b/drivers/iio/dac/cio-dac.c
new file mode 100644
index 000000000000..5a743e2a779d
--- /dev/null
+++ b/drivers/iio/dac/cio-dac.c
@@ -0,0 +1,144 @@
+/*
+ * IIO driver for the Measurement Computing CIO-DAC
+ * Copyright (C) 2016 William Breathitt Gray
+ *
+ * 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.
+ *
+ * This driver supports the following Measurement Computing devices: CIO-DAC16,
+ * CIO-DAC06, and PC104-DAC06.
+ */
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/types.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/isa.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#define CIO_DAC_NUM_CHAN 16
+
+#define CIO_DAC_CHAN(chan) { \
+ .type = IIO_VOLTAGE, \
+ .channel = chan, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .indexed = 1, \
+ .output = 1 \
+}
+
+#define CIO_DAC_EXTENT 32
+
+static unsigned int base[max_num_isa_dev(CIO_DAC_EXTENT)];
+static unsigned int num_cio_dac;
+module_param_array(base, uint, &num_cio_dac, 0);
+MODULE_PARM_DESC(base, "Measurement Computing CIO-DAC base addresses");
+
+/**
+ * struct cio_dac_iio - IIO device private data structure
+ * @chan_out_states: channels' output states
+ * @base: base port address of the IIO device
+ */
+struct cio_dac_iio {
+ int chan_out_states[CIO_DAC_NUM_CHAN];
+ unsigned int base;
+};
+
+static int cio_dac_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val, int *val2, long mask)
+{
+ struct cio_dac_iio *const priv = iio_priv(indio_dev);
+
+ if (mask != IIO_CHAN_INFO_RAW)
+ return -EINVAL;
+
+ *val = priv->chan_out_states[chan->channel];
+
+ return IIO_VAL_INT;
+}
+
+static int cio_dac_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int val, int val2, long mask)
+{
+ struct cio_dac_iio *const priv = iio_priv(indio_dev);
+ const unsigned int chan_addr_offset = 2 * chan->channel;
+
+ if (mask != IIO_CHAN_INFO_RAW)
+ return -EINVAL;
+
+ /* DAC can only accept up to a 16-bit value */
+ if ((unsigned int)val > 65535)
+ return -EINVAL;
+
+ priv->chan_out_states[chan->channel] = val;
+ outw(val, priv->base + chan_addr_offset);
+
+ return 0;
+}
+
+static const struct iio_info cio_dac_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = cio_dac_read_raw,
+ .write_raw = cio_dac_write_raw
+};
+
+static const struct iio_chan_spec cio_dac_channels[CIO_DAC_NUM_CHAN] = {
+ CIO_DAC_CHAN(0), CIO_DAC_CHAN(1), CIO_DAC_CHAN(2), CIO_DAC_CHAN(3),
+ CIO_DAC_CHAN(4), CIO_DAC_CHAN(5), CIO_DAC_CHAN(6), CIO_DAC_CHAN(7),
+ CIO_DAC_CHAN(8), CIO_DAC_CHAN(9), CIO_DAC_CHAN(10), CIO_DAC_CHAN(11),
+ CIO_DAC_CHAN(12), CIO_DAC_CHAN(13), CIO_DAC_CHAN(14), CIO_DAC_CHAN(15)
+};
+
+static int cio_dac_probe(struct device *dev, unsigned int id)
+{
+ struct iio_dev *indio_dev;
+ struct cio_dac_iio *priv;
+ unsigned int i;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*priv));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ if (!devm_request_region(dev, base[id], CIO_DAC_EXTENT,
+ dev_name(dev))) {
+ dev_err(dev, "Unable to request port addresses (0x%X-0x%X)\n",
+ base[id], base[id] + CIO_DAC_EXTENT);
+ return -EBUSY;
+ }
+
+ indio_dev->info = &cio_dac_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = cio_dac_channels;
+ indio_dev->num_channels = CIO_DAC_NUM_CHAN;
+ indio_dev->name = dev_name(dev);
+
+ priv = iio_priv(indio_dev);
+ priv->base = base[id];
+
+ /* initialize DAC outputs to 0V */
+ for (i = 0; i < 32; i += 2)
+ outw(0, base[id] + i);
+
+ return devm_iio_device_register(dev, indio_dev);
+}
+
+static struct isa_driver cio_dac_driver = {
+ .probe = cio_dac_probe,
+ .driver = {
+ .name = "cio-dac"
+ }
+};
+
+module_isa_driver(cio_dac_driver, num_cio_dac);
+
+MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
+MODULE_DESCRIPTION("Measurement Computing CIO-DAC IIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/gyro/ssp_gyro_sensor.c b/drivers/iio/gyro/ssp_gyro_sensor.c
index 0a8afdd21728..1f25f406c545 100644
--- a/drivers/iio/gyro/ssp_gyro_sensor.c
+++ b/drivers/iio/gyro/ssp_gyro_sensor.c
@@ -74,7 +74,7 @@ static int ssp_gyro_write_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
-static struct iio_info ssp_gyro_iio_info = {
+static const struct iio_info ssp_gyro_iio_info = {
.read_raw = &ssp_gyro_read_raw,
.write_raw = &ssp_gyro_write_raw,
};
diff --git a/drivers/iio/humidity/Kconfig b/drivers/iio/humidity/Kconfig
index d04124345992..b17e2e2bd4f5 100644
--- a/drivers/iio/humidity/Kconfig
+++ b/drivers/iio/humidity/Kconfig
@@ -28,11 +28,11 @@ config HDC100X
tristate "TI HDC100x relative humidity and temperature sensor"
depends on I2C
help
- Say yes here to build support for the TI HDC100x series of
- relative humidity and temperature sensors.
+ Say yes here to build support for the Texas Instruments
+ HDC1000 and HDC1008 relative humidity and temperature sensors.
- To compile this driver as a module, choose M here: the module
- will be called hdc100x.
+ To compile this driver as a module, choose M here: the module
+ will be called hdc100x.
config HTU21
tristate "Measurement Specialties HTU21 humidity & temperature sensor"
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index d2b889918c3e..fc340ed3dca1 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -1308,7 +1308,7 @@ static void devm_iio_device_release(struct device *dev, void *res)
iio_device_free(*(struct iio_dev **)res);
}
-static int devm_iio_device_match(struct device *dev, void *res, void *data)
+int devm_iio_device_match(struct device *dev, void *res, void *data)
{
struct iio_dev **r = res;
if (!r || !*r) {
@@ -1317,6 +1317,7 @@ static int devm_iio_device_match(struct device *dev, void *res, void *data)
}
return *r == data;
}
+EXPORT_SYMBOL_GPL(devm_iio_device_match);
/**
* devm_iio_device_alloc - Resource-managed iio_device_alloc()
diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
index 0ebfc923a997..90fac8ec63c9 100644
--- a/drivers/iio/industrialio-event.c
+++ b/drivers/iio/industrialio-event.c
@@ -57,6 +57,11 @@ bool iio_event_enabled(const struct iio_event_interface *ev_int)
*
* Note: The caller must make sure that this function is not running
* concurrently for the same indio_dev more than once.
+ *
+ * This function may be safely used as soon as a valid reference to iio_dev has
+ * been obtained via iio_device_alloc(), but any events that are submitted
+ * before iio_device_register() has successfully completed will be silently
+ * discarded.
**/
int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp)
{
@@ -64,6 +69,9 @@ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp)
struct iio_event_data ev;
int copied;
+ if (!ev_int)
+ return 0;
+
/* Does anyone care? */
if (iio_event_enabled(ev_int)) {
diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c
index 7ad82fdd3e5b..e1e104845e38 100644
--- a/drivers/iio/industrialio-trigger.c
+++ b/drivers/iio/industrialio-trigger.c
@@ -119,6 +119,22 @@ void iio_trigger_unregister(struct iio_trigger *trig_info)
}
EXPORT_SYMBOL(iio_trigger_unregister);
+int iio_trigger_set_immutable(struct iio_dev *indio_dev, struct iio_trigger *trig)
+{
+ if (!indio_dev || !trig)
+ return -EINVAL;
+
+ mutex_lock(&indio_dev->mlock);
+ WARN_ON(indio_dev->trig_readonly);
+
+ indio_dev->trig = iio_trigger_get(trig);
+ indio_dev->trig_readonly = true;
+ mutex_unlock(&indio_dev->mlock);
+
+ return 0;
+}
+EXPORT_SYMBOL(iio_trigger_set_immutable);
+
/* Search for trigger by name, assuming iio_trigger_list_lock held */
static struct iio_trigger *__iio_trigger_find_by_name(const char *name)
{
@@ -255,6 +271,14 @@ static int iio_trigger_attach_poll_func(struct iio_trigger *trig,
goto out_free_irq;
}
+ /*
+ * Check if we just registered to our own trigger: we determine that
+ * this is the case if the IIO device and the trigger device share the
+ * same parent device.
+ */
+ if (pf->indio_dev->dev.parent == trig->dev.parent)
+ trig->attached_own_device = true;
+
return ret;
out_free_irq:
@@ -279,6 +303,8 @@ static int iio_trigger_detach_poll_func(struct iio_trigger *trig,
if (ret)
return ret;
}
+ if (pf->indio_dev->dev.parent == trig->dev.parent)
+ trig->attached_own_device = false;
iio_trigger_put_irq(trig, pf->irq);
free_irq(pf->irq, pf);
module_put(pf->indio_dev->info->driver_module);
@@ -384,6 +410,10 @@ static ssize_t iio_trigger_write_current(struct device *dev,
mutex_unlock(&indio_dev->mlock);
return -EBUSY;
}
+ if (indio_dev->trig_readonly) {
+ mutex_unlock(&indio_dev->mlock);
+ return -EPERM;
+ }
mutex_unlock(&indio_dev->mlock);
trig = iio_trigger_find_by_name(buf, len);
@@ -622,6 +652,71 @@ void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig)
}
EXPORT_SYMBOL_GPL(devm_iio_trigger_free);
+static void devm_iio_trigger_unreg(struct device *dev, void *res)
+{
+ iio_trigger_unregister(*(struct iio_trigger **)res);
+}
+
+/**
+ * devm_iio_trigger_register - Resource-managed iio_trigger_register()
+ * @dev: device this trigger was allocated for
+ * @trig_info: trigger to register
+ *
+ * Managed iio_trigger_register(). The IIO trigger registered with this
+ * function is automatically unregistered on driver detach. This function
+ * calls iio_trigger_register() internally. Refer to that function for more
+ * information.
+ *
+ * If an iio_trigger registered with this function needs to be unregistered
+ * separately, devm_iio_trigger_unregister() must be used.
+ *
+ * RETURNS:
+ * 0 on success, negative error number on failure.
+ */
+int devm_iio_trigger_register(struct device *dev, struct iio_trigger *trig_info)
+{
+ struct iio_trigger **ptr;
+ int ret;
+
+ ptr = devres_alloc(devm_iio_trigger_unreg, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ *ptr = trig_info;
+ ret = iio_trigger_register(trig_info);
+ if (!ret)
+ devres_add(dev, ptr);
+ else
+ devres_free(ptr);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(devm_iio_trigger_register);
+
+/**
+ * devm_iio_trigger_unregister - Resource-managed iio_trigger_unregister()
+ * @dev: device this iio_trigger belongs to
+ * @trig_info: the trigger associated with the device
+ *
+ * Unregister trigger registered with devm_iio_trigger_register().
+ */
+void devm_iio_trigger_unregister(struct device *dev,
+ struct iio_trigger *trig_info)
+{
+ int rc;
+
+ rc = devres_release(dev, devm_iio_trigger_unreg, devm_iio_trigger_match,
+ trig_info);
+ WARN_ON(rc);
+}
+EXPORT_SYMBOL_GPL(devm_iio_trigger_unregister);
+
+bool iio_trigger_using_own(struct iio_dev *indio_dev)
+{
+ return indio_dev->trig->attached_own_device;
+}
+EXPORT_SYMBOL(iio_trigger_using_own);
+
void iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
{
indio_dev->groups[indio_dev->groupcounter++] =
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index 3574945183fe..ba2e64d7ee58 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -267,6 +267,19 @@ config PA12203001
This driver can also be built as a module. If so, the module
will be called pa12203001.
+config SI1145
+ tristate "SI1132 and SI1141/2/3/5/6/7 combined ALS, UV index and proximity sensor"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say Y here if you want to build a driver for the Silicon Labs SI1132 or
+ SI1141/2/3/5/6/7 combined ambient light, UV index and proximity sensor
+ chips.
+
+ To compile this driver as a module, choose M here: the module will be
+ called si1145.
+
config STK3310
tristate "STK3310 ALS and proximity sensor"
depends on I2C
@@ -334,11 +347,11 @@ config US5182D
will be called us5182d.
config VCNL4000
- tristate "VCNL4000 combined ALS and proximity sensor"
+ tristate "VCNL4000/4010/4020 combined ALS and proximity sensor"
depends on I2C
help
- Say Y here if you want to build a driver for the Vishay VCNL4000
- combined ambient light and proximity sensor.
+ Say Y here if you want to build a driver for the Vishay VCNL4000,
+ VCNL4010, VCNL4020 combined ambient light and proximity sensor.
To compile this driver as a module, choose M here: the
module will be called vcnl4000.
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index 6f2a3c62de27..c5768df87a17 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_OPT3001) += opt3001.o
obj-$(CONFIG_PA12203001) += pa12203001.o
obj-$(CONFIG_RPR0521) += rpr0521.o
obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
+obj-$(CONFIG_SI1145) += si1145.o
obj-$(CONFIG_STK3310) += stk3310.o
obj-$(CONFIG_TCS3414) += tcs3414.o
obj-$(CONFIG_TCS3472) += tcs3472.o
diff --git a/drivers/iio/light/si1145.c b/drivers/iio/light/si1145.c
new file mode 100644
index 000000000000..096034c126a4
--- /dev/null
+++ b/drivers/iio/light/si1145.c
@@ -0,0 +1,1404 @@
+/*
+ * si1145.c - Support for Silabs SI1132 and SI1141/2/3/5/6/7 combined ambient
+ * light, UV index and proximity sensors
+ *
+ * Copyright 2014-16 Peter Meerwald-Stadler <pmeerw@pmeerw.net>
+ * Copyright 2016 Crestez Dan Leonard <leonard.crestez@intel.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * SI1132 (7-bit I2C slave address 0x60)
+ * SI1141/2/3 (7-bit I2C slave address 0x5a)
+ * SI1145/6/6 (7-bit I2C slave address 0x60)
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/buffer.h>
+#include <linux/util_macros.h>
+
+#define SI1145_REG_PART_ID 0x00
+#define SI1145_REG_REV_ID 0x01
+#define SI1145_REG_SEQ_ID 0x02
+#define SI1145_REG_INT_CFG 0x03
+#define SI1145_REG_IRQ_ENABLE 0x04
+#define SI1145_REG_IRQ_MODE 0x05
+#define SI1145_REG_HW_KEY 0x07
+#define SI1145_REG_MEAS_RATE 0x08
+#define SI1145_REG_PS_LED21 0x0f
+#define SI1145_REG_PS_LED3 0x10
+#define SI1145_REG_UCOEF1 0x13
+#define SI1145_REG_UCOEF2 0x14
+#define SI1145_REG_UCOEF3 0x15
+#define SI1145_REG_UCOEF4 0x16
+#define SI1145_REG_PARAM_WR 0x17
+#define SI1145_REG_COMMAND 0x18
+#define SI1145_REG_RESPONSE 0x20
+#define SI1145_REG_IRQ_STATUS 0x21
+#define SI1145_REG_ALSVIS_DATA 0x22
+#define SI1145_REG_ALSIR_DATA 0x24
+#define SI1145_REG_PS1_DATA 0x26
+#define SI1145_REG_PS2_DATA 0x28
+#define SI1145_REG_PS3_DATA 0x2a
+#define SI1145_REG_AUX_DATA 0x2c
+#define SI1145_REG_PARAM_RD 0x2e
+#define SI1145_REG_CHIP_STAT 0x30
+
+#define SI1145_UCOEF1_DEFAULT 0x7b
+#define SI1145_UCOEF2_DEFAULT 0x6b
+#define SI1145_UCOEF3_DEFAULT 0x01
+#define SI1145_UCOEF4_DEFAULT 0x00
+
+/* Helper to figure out PS_LED register / shift per channel */
+#define SI1145_PS_LED_REG(ch) \
+ (((ch) == 2) ? SI1145_REG_PS_LED3 : SI1145_REG_PS_LED21)
+#define SI1145_PS_LED_SHIFT(ch) \
+ (((ch) == 1) ? 4 : 0)
+
+/* Parameter offsets */
+#define SI1145_PARAM_CHLIST 0x01
+#define SI1145_PARAM_PSLED12_SELECT 0x02
+#define SI1145_PARAM_PSLED3_SELECT 0x03
+#define SI1145_PARAM_PS_ENCODING 0x05
+#define SI1145_PARAM_ALS_ENCODING 0x06
+#define SI1145_PARAM_PS1_ADC_MUX 0x07
+#define SI1145_PARAM_PS2_ADC_MUX 0x08
+#define SI1145_PARAM_PS3_ADC_MUX 0x09
+#define SI1145_PARAM_PS_ADC_COUNTER 0x0a
+#define SI1145_PARAM_PS_ADC_GAIN 0x0b
+#define SI1145_PARAM_PS_ADC_MISC 0x0c
+#define SI1145_PARAM_ALS_ADC_MUX 0x0d
+#define SI1145_PARAM_ALSIR_ADC_MUX 0x0e
+#define SI1145_PARAM_AUX_ADC_MUX 0x0f
+#define SI1145_PARAM_ALSVIS_ADC_COUNTER 0x10
+#define SI1145_PARAM_ALSVIS_ADC_GAIN 0x11
+#define SI1145_PARAM_ALSVIS_ADC_MISC 0x12
+#define SI1145_PARAM_LED_RECOVERY 0x1c
+#define SI1145_PARAM_ALSIR_ADC_COUNTER 0x1d
+#define SI1145_PARAM_ALSIR_ADC_GAIN 0x1e
+#define SI1145_PARAM_ALSIR_ADC_MISC 0x1f
+#define SI1145_PARAM_ADC_OFFSET 0x1a
+
+/* Channel enable masks for CHLIST parameter */
+#define SI1145_CHLIST_EN_PS1 BIT(0)
+#define SI1145_CHLIST_EN_PS2 BIT(1)
+#define SI1145_CHLIST_EN_PS3 BIT(2)
+#define SI1145_CHLIST_EN_ALSVIS BIT(4)
+#define SI1145_CHLIST_EN_ALSIR BIT(5)
+#define SI1145_CHLIST_EN_AUX BIT(6)
+#define SI1145_CHLIST_EN_UV BIT(7)
+
+/* Proximity measurement mode for ADC_MISC parameter */
+#define SI1145_PS_ADC_MODE_NORMAL BIT(2)
+/* Signal range mask for ADC_MISC parameter */
+#define SI1145_ADC_MISC_RANGE BIT(5)
+
+/* Commands for REG_COMMAND */
+#define SI1145_CMD_NOP 0x00
+#define SI1145_CMD_RESET 0x01
+#define SI1145_CMD_PS_FORCE 0x05
+#define SI1145_CMD_ALS_FORCE 0x06
+#define SI1145_CMD_PSALS_FORCE 0x07
+#define SI1145_CMD_PS_PAUSE 0x09
+#define SI1145_CMD_ALS_PAUSE 0x0a
+#define SI1145_CMD_PSALS_PAUSE 0x0b
+#define SI1145_CMD_PS_AUTO 0x0d
+#define SI1145_CMD_ALS_AUTO 0x0e
+#define SI1145_CMD_PSALS_AUTO 0x0f
+#define SI1145_CMD_PARAM_QUERY 0x80
+#define SI1145_CMD_PARAM_SET 0xa0
+
+#define SI1145_RSP_INVALID_SETTING 0x80
+#define SI1145_RSP_COUNTER_MASK 0x0F
+
+/* Minimum sleep after each command to ensure it's received */
+#define SI1145_COMMAND_MINSLEEP_MS 5
+/* Return -ETIMEDOUT after this long */
+#define SI1145_COMMAND_TIMEOUT_MS 25
+
+/* Interrupt configuration masks for INT_CFG register */
+#define SI1145_INT_CFG_OE BIT(0) /* enable interrupt */
+#define SI1145_INT_CFG_MODE BIT(1) /* auto reset interrupt pin */
+
+/* Interrupt enable masks for IRQ_ENABLE register */
+#define SI1145_MASK_ALL_IE (BIT(4) | BIT(3) | BIT(2) | BIT(0))
+
+#define SI1145_MUX_TEMP 0x65
+#define SI1145_MUX_VDD 0x75
+
+/* Proximity LED current; see Table 2 in datasheet */
+#define SI1145_LED_CURRENT_45mA 0x04
+
+enum {
+ SI1132,
+ SI1141,
+ SI1142,
+ SI1143,
+ SI1145,
+ SI1146,
+ SI1147,
+};
+
+struct si1145_part_info {
+ u8 part;
+ const struct iio_info *iio_info;
+ const struct iio_chan_spec *channels;
+ unsigned int num_channels;
+ unsigned int num_leds;
+ bool uncompressed_meas_rate;
+};
+
+/**
+ * struct si1145_data - si1145 chip state data
+ * @client: I2C client
+ * @lock: mutex to protect shared state.
+ * @cmdlock: Low-level mutex to protect command execution only
+ * @rsp_seq: Next expected response number or -1 if counter reset required
+ * @scan_mask: Saved scan mask to avoid duplicate set_chlist
+ * @autonomous: If automatic measurements are active (for buffer support)
+ * @part_info: Part information
+ * @trig: Pointer to iio trigger
+ * @meas_rate: Value of MEAS_RATE register. Only set in HW in auto mode
+ */
+struct si1145_data {
+ struct i2c_client *client;
+ struct mutex lock;
+ struct mutex cmdlock;
+ int rsp_seq;
+ const struct si1145_part_info *part_info;
+ unsigned long scan_mask;
+ bool autonomous;
+ struct iio_trigger *trig;
+ int meas_rate;
+};
+
+/**
+ * __si1145_command_reset() - Send CMD_NOP and wait for response 0
+ *
+ * Does not modify data->rsp_seq
+ *
+ * Return: 0 on success and -errno on error.
+ */
+static int __si1145_command_reset(struct si1145_data *data)
+{
+ struct device *dev = &data->client->dev;
+ unsigned long stop_jiffies;
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(data->client, SI1145_REG_COMMAND,
+ SI1145_CMD_NOP);
+ if (ret < 0)
+ return ret;
+ msleep(SI1145_COMMAND_MINSLEEP_MS);
+
+ stop_jiffies = jiffies + SI1145_COMMAND_TIMEOUT_MS * HZ / 1000;
+ while (true) {
+ ret = i2c_smbus_read_byte_data(data->client,
+ SI1145_REG_RESPONSE);
+ if (ret <= 0)
+ return ret;
+ if (time_after(jiffies, stop_jiffies)) {
+ dev_warn(dev, "timeout on reset\n");
+ return -ETIMEDOUT;
+ }
+ msleep(SI1145_COMMAND_MINSLEEP_MS);
+ continue;
+ }
+}
+
+/**
+ * si1145_command() - Execute a command and poll the response register
+ *
+ * All conversion overflows are reported as -EOVERFLOW
+ * INVALID_SETTING is reported as -EINVAL
+ * Timeouts are reported as -ETIMEDOUT
+ *
+ * Return: 0 on success or -errno on failure
+ */
+static int si1145_command(struct si1145_data *data, u8 cmd)
+{
+ struct device *dev = &data->client->dev;
+ unsigned long stop_jiffies;
+ int ret;
+
+ mutex_lock(&data->cmdlock);
+
+ if (data->rsp_seq < 0) {
+ ret = __si1145_command_reset(data);
+ if (ret < 0) {
+ dev_err(dev, "failed to reset command counter, ret=%d\n",
+ ret);
+ goto out;
+ }
+ data->rsp_seq = 0;
+ }
+
+ ret = i2c_smbus_write_byte_data(data->client, SI1145_REG_COMMAND, cmd);
+ if (ret) {
+ dev_warn(dev, "failed to write command, ret=%d\n", ret);
+ goto out;
+ }
+ /* Sleep a little to ensure the command is received */
+ msleep(SI1145_COMMAND_MINSLEEP_MS);
+
+ stop_jiffies = jiffies + SI1145_COMMAND_TIMEOUT_MS * HZ / 1000;
+ while (true) {
+ ret = i2c_smbus_read_byte_data(data->client,
+ SI1145_REG_RESPONSE);
+ if (ret < 0) {
+ dev_warn(dev, "failed to read response, ret=%d\n", ret);
+ break;
+ }
+
+ if ((ret & ~SI1145_RSP_COUNTER_MASK) == 0) {
+ if (ret == data->rsp_seq) {
+ if (time_after(jiffies, stop_jiffies)) {
+ dev_warn(dev, "timeout on command %#02hhx\n",
+ cmd);
+ ret = -ETIMEDOUT;
+ break;
+ }
+ msleep(SI1145_COMMAND_MINSLEEP_MS);
+ continue;
+ }
+ if (ret == ((data->rsp_seq + 1) &
+ SI1145_RSP_COUNTER_MASK)) {
+ data->rsp_seq = ret;
+ ret = 0;
+ break;
+ }
+ dev_warn(dev, "unexpected response counter %d instead of %d\n",
+ ret, (data->rsp_seq + 1) &
+ SI1145_RSP_COUNTER_MASK);
+ ret = -EIO;
+ } else {
+ if (ret == SI1145_RSP_INVALID_SETTING) {
+ dev_warn(dev, "INVALID_SETTING error on command %#02hhx\n",
+ cmd);
+ ret = -EINVAL;
+ } else {
+ /* All overflows are treated identically */
+ dev_dbg(dev, "overflow, ret=%d, cmd=%#02hhx\n",
+ ret, cmd);
+ ret = -EOVERFLOW;
+ }
+ }
+
+ /* Force a counter reset next time */
+ data->rsp_seq = -1;
+ break;
+ }
+
+out:
+ mutex_unlock(&data->cmdlock);
+
+ return ret;
+}
+
+static int si1145_param_update(struct si1145_data *data, u8 op, u8 param,
+ u8 value)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ SI1145_REG_PARAM_WR, value);
+ if (ret < 0)
+ return ret;
+
+ return si1145_command(data, op | (param & 0x1F));
+}
+
+static int si1145_param_set(struct si1145_data *data, u8 param, u8 value)
+{
+ return si1145_param_update(data, SI1145_CMD_PARAM_SET, param, value);
+}
+
+/* Set param. Returns negative errno or current value */
+static int si1145_param_query(struct si1145_data *data, u8 param)
+{
+ int ret;
+
+ ret = si1145_command(data, SI1145_CMD_PARAM_QUERY | (param & 0x1F));
+ if (ret < 0)
+ return ret;
+
+ return i2c_smbus_read_byte_data(data->client, SI1145_REG_PARAM_RD);
+}
+
+/* Expand 8 bit compressed value to 16 bit, see Silabs AN498 */
+static u16 si1145_uncompress(u8 x)
+{
+ u16 result = 0;
+ u8 exponent = 0;
+
+ if (x < 8)
+ return 0;
+
+ exponent = (x & 0xf0) >> 4;
+ result = 0x10 | (x & 0x0f);
+
+ if (exponent >= 4)
+ return result << (exponent - 4);
+ return result >> (4 - exponent);
+}
+
+/* Compress 16 bit value to 8 bit, see Silabs AN498 */
+static u8 si1145_compress(u16 x)
+{
+ u32 exponent = 0;
+ u32 significand = 0;
+ u32 tmp = x;
+
+ if (x == 0x0000)
+ return 0x00;
+ if (x == 0x0001)
+ return 0x08;
+
+ while (1) {
+ tmp >>= 1;
+ exponent += 1;
+ if (tmp == 1)
+ break;
+ }
+
+ if (exponent < 5) {
+ significand = x << (4 - exponent);
+ return (exponent << 4) | (significand & 0xF);
+ }
+
+ significand = x >> (exponent - 5);
+ if (significand & 1) {
+ significand += 2;
+ if (significand & 0x0040) {
+ exponent += 1;
+ significand >>= 1;
+ }
+ }
+
+ return (exponent << 4) | ((significand >> 1) & 0xF);
+}
+
+/* Write meas_rate in hardware */
+static int si1145_set_meas_rate(struct si1145_data *data, int interval)
+{
+ if (data->part_info->uncompressed_meas_rate)
+ return i2c_smbus_write_word_data(data->client,
+ SI1145_REG_MEAS_RATE, interval);
+ else
+ return i2c_smbus_write_byte_data(data->client,
+ SI1145_REG_MEAS_RATE, interval);
+}
+
+static int si1145_read_samp_freq(struct si1145_data *data, int *val, int *val2)
+{
+ *val = 32000;
+ if (data->part_info->uncompressed_meas_rate)
+ *val2 = data->meas_rate;
+ else
+ *val2 = si1145_uncompress(data->meas_rate);
+ return IIO_VAL_FRACTIONAL;
+}
+
+/* Set the samp freq in driver private data */
+static int si1145_store_samp_freq(struct si1145_data *data, int val)
+{
+ int ret = 0;
+ int meas_rate;
+
+ if (val <= 0 || val > 32000)
+ return -ERANGE;
+ meas_rate = 32000 / val;
+
+ mutex_lock(&data->lock);
+ if (data->autonomous) {
+ ret = si1145_set_meas_rate(data, meas_rate);
+ if (ret)
+ goto out;
+ }
+ if (data->part_info->uncompressed_meas_rate)
+ data->meas_rate = meas_rate;
+ else
+ data->meas_rate = si1145_compress(meas_rate);
+
+out:
+ mutex_unlock(&data->lock);
+
+ return ret;
+}
+
+static irqreturn_t si1145_trigger_handler(int irq, void *private)
+{
+ struct iio_poll_func *pf = private;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct si1145_data *data = iio_priv(indio_dev);
+ /*
+ * Maximum buffer size:
+ * 6*2 bytes channels data + 4 bytes alignment +
+ * 8 bytes timestamp
+ */
+ u8 buffer[24];
+ int i, j = 0;
+ int ret;
+ u8 irq_status = 0;
+
+ if (!data->autonomous) {
+ ret = si1145_command(data, SI1145_CMD_PSALS_FORCE);
+ if (ret < 0 && ret != -EOVERFLOW)
+ goto done;
+ } else {
+ irq_status = ret = i2c_smbus_read_byte_data(data->client,
+ SI1145_REG_IRQ_STATUS);
+ if (ret < 0)
+ goto done;
+ if (!(irq_status & SI1145_MASK_ALL_IE))
+ goto done;
+ }
+
+ for_each_set_bit(i, indio_dev->active_scan_mask,
+ indio_dev->masklength) {
+ int run = 1;
+
+ while (i + run < indio_dev->masklength) {
+ if (!test_bit(i + run, indio_dev->active_scan_mask))
+ break;
+ if (indio_dev->channels[i + run].address !=
+ indio_dev->channels[i].address + 2 * run)
+ break;
+ run++;
+ }
+
+ ret = i2c_smbus_read_i2c_block_data_or_emulated(
+ data->client, indio_dev->channels[i].address,
+ sizeof(u16) * run, &buffer[j]);
+ if (ret < 0)
+ goto done;
+ j += run * sizeof(u16);
+ i += run - 1;
+ }
+
+ if (data->autonomous) {
+ ret = i2c_smbus_write_byte_data(data->client,
+ SI1145_REG_IRQ_STATUS,
+ irq_status & SI1145_MASK_ALL_IE);
+ if (ret < 0)
+ goto done;
+ }
+
+ iio_push_to_buffers_with_timestamp(indio_dev, buffer,
+ iio_get_time_ns(indio_dev));
+
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+ return IRQ_HANDLED;
+}
+
+static int si1145_set_chlist(struct iio_dev *indio_dev, unsigned long scan_mask)
+{
+ struct si1145_data *data = iio_priv(indio_dev);
+ u8 reg = 0, mux;
+ int ret;
+ int i;
+
+ /* channel list already set, no need to reprogram */
+ if (data->scan_mask == scan_mask)
+ return 0;
+
+ for_each_set_bit(i, &scan_mask, indio_dev->masklength) {
+ switch (indio_dev->channels[i].address) {
+ case SI1145_REG_ALSVIS_DATA:
+ reg |= SI1145_CHLIST_EN_ALSVIS;
+ break;
+ case SI1145_REG_ALSIR_DATA:
+ reg |= SI1145_CHLIST_EN_ALSIR;
+ break;
+ case SI1145_REG_PS1_DATA:
+ reg |= SI1145_CHLIST_EN_PS1;
+ break;
+ case SI1145_REG_PS2_DATA:
+ reg |= SI1145_CHLIST_EN_PS2;
+ break;
+ case SI1145_REG_PS3_DATA:
+ reg |= SI1145_CHLIST_EN_PS3;
+ break;
+ case SI1145_REG_AUX_DATA:
+ switch (indio_dev->channels[i].type) {
+ case IIO_UVINDEX:
+ reg |= SI1145_CHLIST_EN_UV;
+ break;
+ default:
+ reg |= SI1145_CHLIST_EN_AUX;
+ if (indio_dev->channels[i].type == IIO_TEMP)
+ mux = SI1145_MUX_TEMP;
+ else
+ mux = SI1145_MUX_VDD;
+ ret = si1145_param_set(data,
+ SI1145_PARAM_AUX_ADC_MUX, mux);
+ if (ret < 0)
+ return ret;
+
+ break;
+ }
+ }
+ }
+
+ data->scan_mask = scan_mask;
+ ret = si1145_param_set(data, SI1145_PARAM_CHLIST, reg);
+
+ return ret < 0 ? ret : 0;
+}
+
+static int si1145_measure(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan)
+{
+ struct si1145_data *data = iio_priv(indio_dev);
+ u8 cmd;
+ int ret;
+
+ ret = si1145_set_chlist(indio_dev, BIT(chan->scan_index));
+ if (ret < 0)
+ return ret;
+
+ cmd = (chan->type == IIO_PROXIMITY) ? SI1145_CMD_PS_FORCE :
+ SI1145_CMD_ALS_FORCE;
+ ret = si1145_command(data, cmd);
+ if (ret < 0 && ret != -EOVERFLOW)
+ return ret;
+
+ return i2c_smbus_read_word_data(data->client, chan->address);
+}
+
+/*
+ * Conversion between iio scale and ADC_GAIN values
+ * These could be further adjusted but proximity/intensity are dimensionless
+ */
+static const int si1145_proximity_scale_available[] = {
+ 128, 64, 32, 16, 8, 4};
+static const int si1145_intensity_scale_available[] = {
+ 128, 64, 32, 16, 8, 4, 2, 1};
+static IIO_CONST_ATTR(in_proximity_scale_available,
+ "128 64 32 16 8 4");
+static IIO_CONST_ATTR(in_intensity_scale_available,
+ "128 64 32 16 8 4 2 1");
+static IIO_CONST_ATTR(in_intensity_ir_scale_available,
+ "128 64 32 16 8 4 2 1");
+
+static int si1145_scale_from_adcgain(int regval)
+{
+ return 128 >> regval;
+}
+
+static int si1145_proximity_adcgain_from_scale(int val, int val2)
+{
+ val = find_closest_descending(val, si1145_proximity_scale_available,
+ ARRAY_SIZE(si1145_proximity_scale_available));
+ if (val < 0 || val > 5 || val2 != 0)
+ return -EINVAL;
+
+ return val;
+}
+
+static int si1145_intensity_adcgain_from_scale(int val, int val2)
+{
+ val = find_closest_descending(val, si1145_intensity_scale_available,
+ ARRAY_SIZE(si1145_intensity_scale_available));
+ if (val < 0 || val > 7 || val2 != 0)
+ return -EINVAL;
+
+ return val;
+}
+
+static int si1145_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct si1145_data *data = iio_priv(indio_dev);
+ int ret;
+ u8 reg;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ switch (chan->type) {
+ case IIO_INTENSITY:
+ case IIO_PROXIMITY:
+ case IIO_VOLTAGE:
+ case IIO_TEMP:
+ case IIO_UVINDEX:
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+ ret = si1145_measure(indio_dev, chan);
+ iio_device_release_direct_mode(indio_dev);
+
+ if (ret < 0)
+ return ret;
+
+ *val = ret;
+
+ return IIO_VAL_INT;
+ case IIO_CURRENT:
+ ret = i2c_smbus_read_byte_data(data->client,
+ SI1145_PS_LED_REG(chan->channel));
+ if (ret < 0)
+ return ret;
+
+ *val = (ret >> SI1145_PS_LED_SHIFT(chan->channel))
+ & 0x0f;
+
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->type) {
+ case IIO_PROXIMITY:
+ reg = SI1145_PARAM_PS_ADC_GAIN;
+ break;
+ case IIO_INTENSITY:
+ if (chan->channel2 == IIO_MOD_LIGHT_IR)
+ reg = SI1145_PARAM_ALSIR_ADC_GAIN;
+ else
+ reg = SI1145_PARAM_ALSVIS_ADC_GAIN;
+ break;
+ case IIO_TEMP:
+ *val = 28;
+ *val2 = 571429;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_UVINDEX:
+ *val = 0;
+ *val2 = 10000;
+ return IIO_VAL_INT_PLUS_MICRO;
+ default:
+ return -EINVAL;
+ }
+
+ ret = si1145_param_query(data, reg);
+ if (ret < 0)
+ return ret;
+
+ *val = si1145_scale_from_adcgain(ret & 0x07);
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_OFFSET:
+ switch (chan->type) {
+ case IIO_TEMP:
+ /*
+ * -ADC offset - ADC counts @ 25°C -
+ * 35 * ADC counts / °C
+ */
+ *val = -256 - 11136 + 25 * 35;
+ return IIO_VAL_INT;
+ default:
+ /*
+ * All ADC measurements have are by default offset
+ * by -256
+ * See AN498 5.6.3
+ */
+ ret = si1145_param_query(data, SI1145_PARAM_ADC_OFFSET);
+ if (ret < 0)
+ return ret;
+ *val = -si1145_uncompress(ret);
+ return IIO_VAL_INT;
+ }
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ return si1145_read_samp_freq(data, val, val2);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int si1145_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct si1145_data *data = iio_priv(indio_dev);
+ u8 reg1, reg2, shift;
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->type) {
+ case IIO_PROXIMITY:
+ val = si1145_proximity_adcgain_from_scale(val, val2);
+ if (val < 0)
+ return val;
+ reg1 = SI1145_PARAM_PS_ADC_GAIN;
+ reg2 = SI1145_PARAM_PS_ADC_COUNTER;
+ break;
+ case IIO_INTENSITY:
+ val = si1145_intensity_adcgain_from_scale(val, val2);
+ if (val < 0)
+ return val;
+ if (chan->channel2 == IIO_MOD_LIGHT_IR) {
+ reg1 = SI1145_PARAM_ALSIR_ADC_GAIN;
+ reg2 = SI1145_PARAM_ALSIR_ADC_COUNTER;
+ } else {
+ reg1 = SI1145_PARAM_ALSVIS_ADC_GAIN;
+ reg2 = SI1145_PARAM_ALSVIS_ADC_COUNTER;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
+ ret = si1145_param_set(data, reg1, val);
+ if (ret < 0) {
+ iio_device_release_direct_mode(indio_dev);
+ return ret;
+ }
+ /* Set recovery period to one's complement of gain */
+ ret = si1145_param_set(data, reg2, (~val & 0x07) << 4);
+ iio_device_release_direct_mode(indio_dev);
+ return ret;
+ case IIO_CHAN_INFO_RAW:
+ if (chan->type != IIO_CURRENT)
+ return -EINVAL;
+
+ if (val < 0 || val > 15 || val2 != 0)
+ return -EINVAL;
+
+ reg1 = SI1145_PS_LED_REG(chan->channel);
+ shift = SI1145_PS_LED_SHIFT(chan->channel);
+
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, reg1);
+ if (ret < 0) {
+ iio_device_release_direct_mode(indio_dev);
+ return ret;
+ }
+ ret = i2c_smbus_write_byte_data(data->client, reg1,
+ (ret & ~(0x0f << shift)) |
+ ((val & 0x0f) << shift));
+ iio_device_release_direct_mode(indio_dev);
+ return ret;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ return si1145_store_samp_freq(data, val);
+ default:
+ return -EINVAL;
+ }
+}
+
+#define SI1145_ST { \
+ .sign = 'u', \
+ .realbits = 16, \
+ .storagebits = 16, \
+ .endianness = IIO_LE, \
+}
+
+#define SI1145_INTENSITY_CHANNEL(_si) { \
+ .type = IIO_INTENSITY, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_OFFSET) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .scan_type = SI1145_ST, \
+ .scan_index = _si, \
+ .address = SI1145_REG_ALSVIS_DATA, \
+}
+
+#define SI1145_INTENSITY_IR_CHANNEL(_si) { \
+ .type = IIO_INTENSITY, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_OFFSET) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .modified = 1, \
+ .channel2 = IIO_MOD_LIGHT_IR, \
+ .scan_type = SI1145_ST, \
+ .scan_index = _si, \
+ .address = SI1145_REG_ALSIR_DATA, \
+}
+
+#define SI1145_TEMP_CHANNEL(_si) { \
+ .type = IIO_TEMP, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_OFFSET) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .scan_type = SI1145_ST, \
+ .scan_index = _si, \
+ .address = SI1145_REG_AUX_DATA, \
+}
+
+#define SI1145_UV_CHANNEL(_si) { \
+ .type = IIO_UVINDEX, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .scan_type = SI1145_ST, \
+ .scan_index = _si, \
+ .address = SI1145_REG_AUX_DATA, \
+}
+
+#define SI1145_PROXIMITY_CHANNEL(_si, _ch) { \
+ .type = IIO_PROXIMITY, \
+ .indexed = 1, \
+ .channel = _ch, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_OFFSET), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .scan_type = SI1145_ST, \
+ .scan_index = _si, \
+ .address = SI1145_REG_PS1_DATA + _ch * 2, \
+}
+
+#define SI1145_VOLTAGE_CHANNEL(_si) { \
+ .type = IIO_VOLTAGE, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .scan_type = SI1145_ST, \
+ .scan_index = _si, \
+ .address = SI1145_REG_AUX_DATA, \
+}
+
+#define SI1145_CURRENT_CHANNEL(_ch) { \
+ .type = IIO_CURRENT, \
+ .indexed = 1, \
+ .channel = _ch, \
+ .output = 1, \
+ .scan_index = -1, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+}
+
+static const struct iio_chan_spec si1132_channels[] = {
+ SI1145_INTENSITY_CHANNEL(0),
+ SI1145_INTENSITY_IR_CHANNEL(1),
+ SI1145_TEMP_CHANNEL(2),
+ SI1145_VOLTAGE_CHANNEL(3),
+ SI1145_UV_CHANNEL(4),
+ IIO_CHAN_SOFT_TIMESTAMP(6),
+};
+
+static const struct iio_chan_spec si1141_channels[] = {
+ SI1145_INTENSITY_CHANNEL(0),
+ SI1145_INTENSITY_IR_CHANNEL(1),
+ SI1145_PROXIMITY_CHANNEL(2, 0),
+ SI1145_TEMP_CHANNEL(3),
+ SI1145_VOLTAGE_CHANNEL(4),
+ IIO_CHAN_SOFT_TIMESTAMP(5),
+ SI1145_CURRENT_CHANNEL(0),
+};
+
+static const struct iio_chan_spec si1142_channels[] = {
+ SI1145_INTENSITY_CHANNEL(0),
+ SI1145_INTENSITY_IR_CHANNEL(1),
+ SI1145_PROXIMITY_CHANNEL(2, 0),
+ SI1145_PROXIMITY_CHANNEL(3, 1),
+ SI1145_TEMP_CHANNEL(4),
+ SI1145_VOLTAGE_CHANNEL(5),
+ IIO_CHAN_SOFT_TIMESTAMP(6),
+ SI1145_CURRENT_CHANNEL(0),
+ SI1145_CURRENT_CHANNEL(1),
+};
+
+static const struct iio_chan_spec si1143_channels[] = {
+ SI1145_INTENSITY_CHANNEL(0),
+ SI1145_INTENSITY_IR_CHANNEL(1),
+ SI1145_PROXIMITY_CHANNEL(2, 0),
+ SI1145_PROXIMITY_CHANNEL(3, 1),
+ SI1145_PROXIMITY_CHANNEL(4, 2),
+ SI1145_TEMP_CHANNEL(5),
+ SI1145_VOLTAGE_CHANNEL(6),
+ IIO_CHAN_SOFT_TIMESTAMP(7),
+ SI1145_CURRENT_CHANNEL(0),
+ SI1145_CURRENT_CHANNEL(1),
+ SI1145_CURRENT_CHANNEL(2),
+};
+
+static const struct iio_chan_spec si1145_channels[] = {
+ SI1145_INTENSITY_CHANNEL(0),
+ SI1145_INTENSITY_IR_CHANNEL(1),
+ SI1145_PROXIMITY_CHANNEL(2, 0),
+ SI1145_TEMP_CHANNEL(3),
+ SI1145_VOLTAGE_CHANNEL(4),
+ SI1145_UV_CHANNEL(5),
+ IIO_CHAN_SOFT_TIMESTAMP(6),
+ SI1145_CURRENT_CHANNEL(0),
+};
+
+static const struct iio_chan_spec si1146_channels[] = {
+ SI1145_INTENSITY_CHANNEL(0),
+ SI1145_INTENSITY_IR_CHANNEL(1),
+ SI1145_TEMP_CHANNEL(2),
+ SI1145_VOLTAGE_CHANNEL(3),
+ SI1145_UV_CHANNEL(4),
+ SI1145_PROXIMITY_CHANNEL(5, 0),
+ SI1145_PROXIMITY_CHANNEL(6, 1),
+ IIO_CHAN_SOFT_TIMESTAMP(7),
+ SI1145_CURRENT_CHANNEL(0),
+ SI1145_CURRENT_CHANNEL(1),
+};
+
+static const struct iio_chan_spec si1147_channels[] = {
+ SI1145_INTENSITY_CHANNEL(0),
+ SI1145_INTENSITY_IR_CHANNEL(1),
+ SI1145_PROXIMITY_CHANNEL(2, 0),
+ SI1145_PROXIMITY_CHANNEL(3, 1),
+ SI1145_PROXIMITY_CHANNEL(4, 2),
+ SI1145_TEMP_CHANNEL(5),
+ SI1145_VOLTAGE_CHANNEL(6),
+ SI1145_UV_CHANNEL(7),
+ IIO_CHAN_SOFT_TIMESTAMP(8),
+ SI1145_CURRENT_CHANNEL(0),
+ SI1145_CURRENT_CHANNEL(1),
+ SI1145_CURRENT_CHANNEL(2),
+};
+
+static struct attribute *si1132_attributes[] = {
+ &iio_const_attr_in_intensity_scale_available.dev_attr.attr,
+ &iio_const_attr_in_intensity_ir_scale_available.dev_attr.attr,
+ NULL,
+};
+
+static struct attribute *si114x_attributes[] = {
+ &iio_const_attr_in_intensity_scale_available.dev_attr.attr,
+ &iio_const_attr_in_intensity_ir_scale_available.dev_attr.attr,
+ &iio_const_attr_in_proximity_scale_available.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group si1132_attribute_group = {
+ .attrs = si1132_attributes,
+};
+
+static const struct attribute_group si114x_attribute_group = {
+ .attrs = si114x_attributes,
+};
+
+
+static const struct iio_info si1132_info = {
+ .read_raw = si1145_read_raw,
+ .write_raw = si1145_write_raw,
+ .driver_module = THIS_MODULE,
+ .attrs = &si1132_attribute_group,
+};
+
+static const struct iio_info si114x_info = {
+ .read_raw = si1145_read_raw,
+ .write_raw = si1145_write_raw,
+ .driver_module = THIS_MODULE,
+ .attrs = &si114x_attribute_group,
+};
+
+#define SI1145_PART(id, iio_info, chans, leds, uncompressed_meas_rate) \
+ {id, iio_info, chans, ARRAY_SIZE(chans), leds, uncompressed_meas_rate}
+
+static const struct si1145_part_info si1145_part_info[] = {
+ [SI1132] = SI1145_PART(0x32, &si1132_info, si1132_channels, 0, true),
+ [SI1141] = SI1145_PART(0x41, &si114x_info, si1141_channels, 1, false),
+ [SI1142] = SI1145_PART(0x42, &si114x_info, si1142_channels, 2, false),
+ [SI1143] = SI1145_PART(0x43, &si114x_info, si1143_channels, 3, false),
+ [SI1145] = SI1145_PART(0x45, &si114x_info, si1145_channels, 1, true),
+ [SI1146] = SI1145_PART(0x46, &si114x_info, si1146_channels, 2, true),
+ [SI1147] = SI1145_PART(0x47, &si114x_info, si1147_channels, 3, true),
+};
+
+static int si1145_initialize(struct si1145_data *data)
+{
+ struct i2c_client *client = data->client;
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, SI1145_REG_COMMAND,
+ SI1145_CMD_RESET);
+ if (ret < 0)
+ return ret;
+ msleep(SI1145_COMMAND_TIMEOUT_MS);
+
+ /* Hardware key, magic value */
+ ret = i2c_smbus_write_byte_data(client, SI1145_REG_HW_KEY, 0x17);
+ if (ret < 0)
+ return ret;
+ msleep(SI1145_COMMAND_TIMEOUT_MS);
+
+ /* Turn off autonomous mode */
+ ret = si1145_set_meas_rate(data, 0);
+ if (ret < 0)
+ return ret;
+
+ /* Initialize sampling freq to 10 Hz */
+ ret = si1145_store_samp_freq(data, 10);
+ if (ret < 0)
+ return ret;
+
+ /* Set LED currents to 45 mA; have 4 bits, see Table 2 in datasheet */
+ switch (data->part_info->num_leds) {
+ case 3:
+ ret = i2c_smbus_write_byte_data(client,
+ SI1145_REG_PS_LED3,
+ SI1145_LED_CURRENT_45mA);
+ if (ret < 0)
+ return ret;
+ /* fallthrough */
+ case 2:
+ ret = i2c_smbus_write_byte_data(client,
+ SI1145_REG_PS_LED21,
+ (SI1145_LED_CURRENT_45mA << 4) |
+ SI1145_LED_CURRENT_45mA);
+ break;
+ case 1:
+ ret = i2c_smbus_write_byte_data(client,
+ SI1145_REG_PS_LED21,
+ SI1145_LED_CURRENT_45mA);
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ if (ret < 0)
+ return ret;
+
+ /* Set normal proximity measurement mode */
+ ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_MISC,
+ SI1145_PS_ADC_MODE_NORMAL);
+ if (ret < 0)
+ return ret;
+
+ ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_GAIN, 0x01);
+ if (ret < 0)
+ return ret;
+
+ /* ADC_COUNTER should be one complement of ADC_GAIN */
+ ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_COUNTER, 0x06 << 4);
+ if (ret < 0)
+ return ret;
+
+ /* Set ALS visible measurement mode */
+ ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_MISC,
+ SI1145_ADC_MISC_RANGE);
+ if (ret < 0)
+ return ret;
+
+ ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_GAIN, 0x03);
+ if (ret < 0)
+ return ret;
+
+ ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_COUNTER,
+ 0x04 << 4);
+ if (ret < 0)
+ return ret;
+
+ /* Set ALS IR measurement mode */
+ ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_MISC,
+ SI1145_ADC_MISC_RANGE);
+ if (ret < 0)
+ return ret;
+
+ ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_GAIN, 0x01);
+ if (ret < 0)
+ return ret;
+
+ ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_COUNTER,
+ 0x06 << 4);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Initialize UCOEF to default values in datasheet
+ * These registers are normally zero on reset
+ */
+ if (data->part_info == &si1145_part_info[SI1132] ||
+ data->part_info == &si1145_part_info[SI1145] ||
+ data->part_info == &si1145_part_info[SI1146] ||
+ data->part_info == &si1145_part_info[SI1147]) {
+ ret = i2c_smbus_write_byte_data(data->client,
+ SI1145_REG_UCOEF1,
+ SI1145_UCOEF1_DEFAULT);
+ if (ret < 0)
+ return ret;
+ ret = i2c_smbus_write_byte_data(data->client,
+ SI1145_REG_UCOEF2, SI1145_UCOEF2_DEFAULT);
+ if (ret < 0)
+ return ret;
+ ret = i2c_smbus_write_byte_data(data->client,
+ SI1145_REG_UCOEF3, SI1145_UCOEF3_DEFAULT);
+ if (ret < 0)
+ return ret;
+ ret = i2c_smbus_write_byte_data(data->client,
+ SI1145_REG_UCOEF4, SI1145_UCOEF4_DEFAULT);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Program the channels we want to measure with CMD_PSALS_AUTO. No need for
+ * _postdisable as we stop with CMD_PSALS_PAUSE; single measurement (direct)
+ * mode reprograms the channels list anyway...
+ */
+static int si1145_buffer_preenable(struct iio_dev *indio_dev)
+{
+ struct si1145_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->lock);
+ ret = si1145_set_chlist(indio_dev, *indio_dev->active_scan_mask);
+ mutex_unlock(&data->lock);
+
+ return ret;
+}
+
+static bool si1145_validate_scan_mask(struct iio_dev *indio_dev,
+ const unsigned long *scan_mask)
+{
+ struct si1145_data *data = iio_priv(indio_dev);
+ unsigned int count = 0;
+ int i;
+
+ /* Check that at most one AUX channel is enabled */
+ for_each_set_bit(i, scan_mask, data->part_info->num_channels) {
+ if (indio_dev->channels[i].address == SI1145_REG_AUX_DATA)
+ count++;
+ }
+
+ return count <= 1;
+}
+
+static const struct iio_buffer_setup_ops si1145_buffer_setup_ops = {
+ .preenable = si1145_buffer_preenable,
+ .postenable = iio_triggered_buffer_postenable,
+ .predisable = iio_triggered_buffer_predisable,
+ .validate_scan_mask = si1145_validate_scan_mask,
+};
+
+/**
+ * si1145_trigger_set_state() - Set trigger state
+ *
+ * When not using triggers interrupts are disabled and measurement rate is
+ * set to zero in order to minimize power consumption.
+ */
+static int si1145_trigger_set_state(struct iio_trigger *trig, bool state)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct si1145_data *data = iio_priv(indio_dev);
+ int err = 0, ret;
+
+ mutex_lock(&data->lock);
+
+ if (state) {
+ data->autonomous = true;
+ err = i2c_smbus_write_byte_data(data->client,
+ SI1145_REG_INT_CFG, SI1145_INT_CFG_OE);
+ if (err < 0)
+ goto disable;
+ err = i2c_smbus_write_byte_data(data->client,
+ SI1145_REG_IRQ_ENABLE, SI1145_MASK_ALL_IE);
+ if (err < 0)
+ goto disable;
+ err = si1145_set_meas_rate(data, data->meas_rate);
+ if (err < 0)
+ goto disable;
+ err = si1145_command(data, SI1145_CMD_PSALS_AUTO);
+ if (err < 0)
+ goto disable;
+ } else {
+disable:
+ /* Disable as much as possible skipping errors */
+ ret = si1145_command(data, SI1145_CMD_PSALS_PAUSE);
+ if (ret < 0 && !err)
+ err = ret;
+ ret = si1145_set_meas_rate(data, 0);
+ if (ret < 0 && !err)
+ err = ret;
+ ret = i2c_smbus_write_byte_data(data->client,
+ SI1145_REG_IRQ_ENABLE, 0);
+ if (ret < 0 && !err)
+ err = ret;
+ ret = i2c_smbus_write_byte_data(data->client,
+ SI1145_REG_INT_CFG, 0);
+ if (ret < 0 && !err)
+ err = ret;
+ data->autonomous = false;
+ }
+
+ mutex_unlock(&data->lock);
+ return err;
+}
+
+static const struct iio_trigger_ops si1145_trigger_ops = {
+ .owner = THIS_MODULE,
+ .set_trigger_state = si1145_trigger_set_state,
+};
+
+static int si1145_probe_trigger(struct iio_dev *indio_dev)
+{
+ struct si1145_data *data = iio_priv(indio_dev);
+ struct i2c_client *client = data->client;
+ struct iio_trigger *trig;
+ int ret;
+
+ trig = devm_iio_trigger_alloc(&client->dev,
+ "%s-dev%d", indio_dev->name, indio_dev->id);
+ if (!trig)
+ return -ENOMEM;
+
+ trig->dev.parent = &client->dev;
+ trig->ops = &si1145_trigger_ops;
+ iio_trigger_set_drvdata(trig, indio_dev);
+
+ ret = devm_request_irq(&client->dev, client->irq,
+ iio_trigger_generic_data_rdy_poll,
+ IRQF_TRIGGER_FALLING,
+ "si1145_irq",
+ trig);
+ if (ret < 0) {
+ dev_err(&client->dev, "irq request failed\n");
+ return ret;
+ }
+
+ ret = iio_trigger_register(trig);
+ if (ret)
+ return ret;
+
+ data->trig = trig;
+ indio_dev->trig = iio_trigger_get(data->trig);
+
+ return 0;
+}
+
+static void si1145_remove_trigger(struct iio_dev *indio_dev)
+{
+ struct si1145_data *data = iio_priv(indio_dev);
+
+ if (data->trig) {
+ iio_trigger_unregister(data->trig);
+ data->trig = NULL;
+ }
+}
+
+static int si1145_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct si1145_data *data;
+ struct iio_dev *indio_dev;
+ u8 part_id, rev_id, seq_id;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ data->client = client;
+ data->part_info = &si1145_part_info[id->driver_data];
+
+ part_id = ret = i2c_smbus_read_byte_data(data->client,
+ SI1145_REG_PART_ID);
+ if (ret < 0)
+ return ret;
+ rev_id = ret = i2c_smbus_read_byte_data(data->client,
+ SI1145_REG_REV_ID);
+ if (ret < 0)
+ return ret;
+ seq_id = ret = i2c_smbus_read_byte_data(data->client,
+ SI1145_REG_SEQ_ID);
+ if (ret < 0)
+ return ret;
+ dev_info(&client->dev, "device ID part %#02hhx rev %#02hhx seq %#02hhx\n",
+ part_id, rev_id, seq_id);
+ if (part_id != data->part_info->part) {
+ dev_err(&client->dev, "part ID mismatch got %#02hhx, expected %#02x\n",
+ part_id, data->part_info->part);
+ return -ENODEV;
+ }
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->name = id->name;
+ indio_dev->channels = data->part_info->channels;
+ indio_dev->num_channels = data->part_info->num_channels;
+ indio_dev->info = data->part_info->iio_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ mutex_init(&data->lock);
+ mutex_init(&data->cmdlock);
+
+ ret = si1145_initialize(data);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ si1145_trigger_handler, &si1145_buffer_setup_ops);
+ if (ret < 0)
+ return ret;
+
+ if (client->irq) {
+ ret = si1145_probe_trigger(indio_dev);
+ if (ret < 0)
+ goto error_free_buffer;
+ } else {
+ dev_info(&client->dev, "no irq, using polling\n");
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0)
+ goto error_free_trigger;
+
+ return 0;
+
+error_free_trigger:
+ si1145_remove_trigger(indio_dev);
+error_free_buffer:
+ iio_triggered_buffer_cleanup(indio_dev);
+
+ return ret;
+}
+
+static const struct i2c_device_id si1145_ids[] = {
+ { "si1132", SI1132 },
+ { "si1141", SI1141 },
+ { "si1142", SI1142 },
+ { "si1143", SI1143 },
+ { "si1145", SI1145 },
+ { "si1146", SI1146 },
+ { "si1147", SI1147 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, si1145_ids);
+
+static int si1145_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+ iio_device_unregister(indio_dev);
+ si1145_remove_trigger(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+
+ return 0;
+}
+
+static struct i2c_driver si1145_driver = {
+ .driver = {
+ .name = "si1145",
+ },
+ .probe = si1145_probe,
+ .remove = si1145_remove,
+ .id_table = si1145_ids,
+};
+
+module_i2c_driver(si1145_driver);
+
+MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("Silabs SI1132 and SI1141/2/3/5/6/7 proximity, ambient light and UV index sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c
index 20c40f780964..18cf2e29e4d5 100644
--- a/drivers/iio/light/us5182d.c
+++ b/drivers/iio/light/us5182d.c
@@ -894,7 +894,7 @@ static int us5182d_probe(struct i2c_client *client,
goto out_err;
if (data->default_continuous) {
- pm_runtime_set_active(&client->dev);
+ ret = pm_runtime_set_active(&client->dev);
if (ret < 0)
goto out_err;
}
diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c
index c9d85bbc9230..360b6e98137a 100644
--- a/drivers/iio/light/vcnl4000.c
+++ b/drivers/iio/light/vcnl4000.c
@@ -1,6 +1,6 @@
/*
- * vcnl4000.c - Support for Vishay VCNL4000 combined ambient light and
- * proximity sensor
+ * vcnl4000.c - Support for Vishay VCNL4000/4010/4020 combined ambient
+ * light and proximity sensor
*
* Copyright 2012 Peter Meerwald <pmeerw@pmeerw.net>
*
@@ -13,6 +13,8 @@
* TODO:
* allow to adjust IR current
* proximity threshold and event handling
+ * periodic ALS/proximity measurement (VCNL4010/20)
+ * interrupts (VCNL4010/20)
*/
#include <linux/module.h>
@@ -24,6 +26,8 @@
#include <linux/iio/sysfs.h>
#define VCNL4000_DRV_NAME "vcnl4000"
+#define VCNL4000_ID 0x01
+#define VCNL4010_ID 0x02 /* for VCNL4020, VCNL4010 */
#define VCNL4000_COMMAND 0x80 /* Command register */
#define VCNL4000_PROD_REV 0x81 /* Product ID and Revision ID */
@@ -37,13 +41,14 @@
#define VCNL4000_PS_MOD_ADJ 0x8a /* Proximity modulator timing adjustment */
/* Bit masks for COMMAND register */
-#define VCNL4000_AL_RDY 0x40 /* ALS data ready? */
-#define VCNL4000_PS_RDY 0x20 /* proximity data ready? */
-#define VCNL4000_AL_OD 0x10 /* start on-demand ALS measurement */
-#define VCNL4000_PS_OD 0x08 /* start on-demand proximity measurement */
+#define VCNL4000_AL_RDY BIT(6) /* ALS data ready? */
+#define VCNL4000_PS_RDY BIT(5) /* proximity data ready? */
+#define VCNL4000_AL_OD BIT(4) /* start on-demand ALS measurement */
+#define VCNL4000_PS_OD BIT(3) /* start on-demand proximity measurement */
struct vcnl4000_data {
struct i2c_client *client;
+ struct mutex lock;
};
static const struct i2c_device_id vcnl4000_id[] = {
@@ -59,16 +64,18 @@ static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask,
__be16 buf;
int ret;
+ mutex_lock(&data->lock);
+
ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
req_mask);
if (ret < 0)
- return ret;
+ goto fail;
/* wait for data to become ready */
while (tries--) {
ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND);
if (ret < 0)
- return ret;
+ goto fail;
if (ret & rdy_mask)
break;
msleep(20); /* measurement takes up to 100 ms */
@@ -77,17 +84,23 @@ static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask,
if (tries < 0) {
dev_err(&data->client->dev,
"vcnl4000_measure() failed, data not ready\n");
- return -EIO;
+ ret = -EIO;
+ goto fail;
}
ret = i2c_smbus_read_i2c_block_data(data->client,
data_reg, sizeof(buf), (u8 *) &buf);
if (ret < 0)
- return ret;
+ goto fail;
+ mutex_unlock(&data->lock);
*val = be16_to_cpu(buf);
return 0;
+
+fail:
+ mutex_unlock(&data->lock);
+ return ret;
}
static const struct iio_chan_spec vcnl4000_channels[] = {
@@ -105,7 +118,7 @@ static int vcnl4000_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
- int ret = -EINVAL;
+ int ret;
struct vcnl4000_data *data = iio_priv(indio_dev);
switch (mask) {
@@ -117,32 +130,27 @@ static int vcnl4000_read_raw(struct iio_dev *indio_dev,
VCNL4000_AL_RESULT_HI, val);
if (ret < 0)
return ret;
- ret = IIO_VAL_INT;
- break;
+ return IIO_VAL_INT;
case IIO_PROXIMITY:
ret = vcnl4000_measure(data,
VCNL4000_PS_OD, VCNL4000_PS_RDY,
VCNL4000_PS_RESULT_HI, val);
if (ret < 0)
return ret;
- ret = IIO_VAL_INT;
- break;
+ return IIO_VAL_INT;
default:
- break;
+ return -EINVAL;
}
- break;
case IIO_CHAN_INFO_SCALE:
- if (chan->type == IIO_LIGHT) {
- *val = 0;
- *val2 = 250000;
- ret = IIO_VAL_INT_PLUS_MICRO;
- }
- break;
+ if (chan->type != IIO_LIGHT)
+ return -EINVAL;
+
+ *val = 0;
+ *val2 = 250000;
+ return IIO_VAL_INT_PLUS_MICRO;
default:
- break;
+ return -EINVAL;
}
-
- return ret;
}
static const struct iio_info vcnl4000_info = {
@@ -155,7 +163,7 @@ static int vcnl4000_probe(struct i2c_client *client,
{
struct vcnl4000_data *data;
struct iio_dev *indio_dev;
- int ret;
+ int ret, prod_id;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
@@ -164,13 +172,19 @@ static int vcnl4000_probe(struct i2c_client *client,
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
+ mutex_init(&data->lock);
ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV);
if (ret < 0)
return ret;
- dev_info(&client->dev, "VCNL4000 Ambient light/proximity sensor, Prod %02x, Rev: %02x\n",
- ret >> 4, ret & 0xf);
+ prod_id = ret >> 4;
+ if (prod_id != VCNL4010_ID && prod_id != VCNL4000_ID)
+ return -ENODEV;
+
+ dev_dbg(&client->dev, "%s Ambient light/proximity sensor, Rev: %02x\n",
+ (prod_id == VCNL4010_ID) ? "VCNL4010/4020" : "VCNL4000",
+ ret & 0xf);
indio_dev->dev.parent = &client->dev;
indio_dev->info = &vcnl4000_info;
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
index 1f842abcb4a4..421ad90a5fbe 100644
--- a/drivers/iio/magnetometer/Kconfig
+++ b/drivers/iio/magnetometer/Kconfig
@@ -5,8 +5,22 @@
menu "Magnetometer sensors"
+config AK8974
+ tristate "Asahi Kasei AK8974 3-Axis Magnetometer"
+ depends on I2C
+ depends on OF
+ select REGMAP_I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for Asahi Kasei AK8974 or
+ AMI305 I2C-based 3-axis magnetometer chips.
+
+ To compile this driver as a module, choose M here: the module
+ will be called ak8974.
+
config AK8975
- tristate "Asahi Kasei AK 3-Axis Magnetometer"
+ tristate "Asahi Kasei AK8975 3-Axis Magnetometer"
depends on I2C
depends on GPIOLIB || COMPILE_TEST
select IIO_BUFFER
diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile
index 92a745c9a6e8..b86d6cb7f285 100644
--- a/drivers/iio/magnetometer/Makefile
+++ b/drivers/iio/magnetometer/Makefile
@@ -3,6 +3,7 @@
#
# When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_AK8974) += ak8974.o
obj-$(CONFIG_AK8975) += ak8975.o
obj-$(CONFIG_BMC150_MAGN) += bmc150_magn.o
obj-$(CONFIG_BMC150_MAGN_I2C) += bmc150_magn_i2c.o
diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c
new file mode 100644
index 000000000000..217353145676
--- /dev/null
+++ b/drivers/iio/magnetometer/ak8974.c
@@ -0,0 +1,860 @@
+/*
+ * Driver for the Asahi Kasei EMD Corporation AK8974
+ * and Aichi Steel AMI305 magnetometer chips.
+ * Based on a patch from Samu Onkalo and the AK8975 IIO driver.
+ *
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * Copyright (C) 2016 Linaro Ltd.
+ *
+ * Author: Samu Onkalo <samu.p.onkalo@nokia.com>
+ * Author: Linus Walleij <linus.walleij@linaro.org>
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h> /* For irq_get_irq_data() */
+#include <linux/completion.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+/*
+ * 16-bit registers are little-endian. LSB is at the address defined below
+ * and MSB is at the next higher address.
+ */
+
+/* These registers are common for AK8974 and AMI305 */
+#define AK8974_SELFTEST 0x0C
+#define AK8974_SELFTEST_IDLE 0x55
+#define AK8974_SELFTEST_OK 0xAA
+
+#define AK8974_INFO 0x0D
+
+#define AK8974_WHOAMI 0x0F
+#define AK8974_WHOAMI_VALUE_AMI305 0x47
+#define AK8974_WHOAMI_VALUE_AK8974 0x48
+
+#define AK8974_DATA_X 0x10
+#define AK8974_DATA_Y 0x12
+#define AK8974_DATA_Z 0x14
+#define AK8974_INT_SRC 0x16
+#define AK8974_STATUS 0x18
+#define AK8974_INT_CLEAR 0x1A
+#define AK8974_CTRL1 0x1B
+#define AK8974_CTRL2 0x1C
+#define AK8974_CTRL3 0x1D
+#define AK8974_INT_CTRL 0x1E
+#define AK8974_INT_THRES 0x26 /* Absolute any axis value threshold */
+#define AK8974_PRESET 0x30
+
+/* AK8974-specific offsets */
+#define AK8974_OFFSET_X 0x20
+#define AK8974_OFFSET_Y 0x22
+#define AK8974_OFFSET_Z 0x24
+/* AMI305-specific offsets */
+#define AMI305_OFFSET_X 0x6C
+#define AMI305_OFFSET_Y 0x72
+#define AMI305_OFFSET_Z 0x78
+
+/* Different temperature registers */
+#define AK8974_TEMP 0x31
+#define AMI305_TEMP 0x60
+
+#define AK8974_INT_X_HIGH BIT(7) /* Axis over +threshold */
+#define AK8974_INT_Y_HIGH BIT(6)
+#define AK8974_INT_Z_HIGH BIT(5)
+#define AK8974_INT_X_LOW BIT(4) /* Axis below -threshold */
+#define AK8974_INT_Y_LOW BIT(3)
+#define AK8974_INT_Z_LOW BIT(2)
+#define AK8974_INT_RANGE BIT(1) /* Range overflow (any axis) */
+
+#define AK8974_STATUS_DRDY BIT(6) /* Data ready */
+#define AK8974_STATUS_OVERRUN BIT(5) /* Data overrun */
+#define AK8974_STATUS_INT BIT(4) /* Interrupt occurred */
+
+#define AK8974_CTRL1_POWER BIT(7) /* 0 = standby; 1 = active */
+#define AK8974_CTRL1_RATE BIT(4) /* 0 = 10 Hz; 1 = 20 Hz */
+#define AK8974_CTRL1_FORCE_EN BIT(1) /* 0 = normal; 1 = force */
+#define AK8974_CTRL1_MODE2 BIT(0) /* 0 */
+
+#define AK8974_CTRL2_INT_EN BIT(4) /* 1 = enable interrupts */
+#define AK8974_CTRL2_DRDY_EN BIT(3) /* 1 = enable data ready signal */
+#define AK8974_CTRL2_DRDY_POL BIT(2) /* 1 = data ready active high */
+#define AK8974_CTRL2_RESDEF (AK8974_CTRL2_DRDY_POL)
+
+#define AK8974_CTRL3_RESET BIT(7) /* Software reset */
+#define AK8974_CTRL3_FORCE BIT(6) /* Start forced measurement */
+#define AK8974_CTRL3_SELFTEST BIT(4) /* Set selftest register */
+#define AK8974_CTRL3_RESDEF 0x00
+
+#define AK8974_INT_CTRL_XEN BIT(7) /* Enable interrupt for this axis */
+#define AK8974_INT_CTRL_YEN BIT(6)
+#define AK8974_INT_CTRL_ZEN BIT(5)
+#define AK8974_INT_CTRL_XYZEN (BIT(7)|BIT(6)|BIT(5))
+#define AK8974_INT_CTRL_POL BIT(3) /* 0 = active low; 1 = active high */
+#define AK8974_INT_CTRL_PULSE BIT(1) /* 0 = latched; 1 = pulse (50 usec) */
+#define AK8974_INT_CTRL_RESDEF (AK8974_INT_CTRL_XYZEN | AK8974_INT_CTRL_POL)
+
+/* The AMI305 has elaborate FW version and serial number registers */
+#define AMI305_VER 0xE8
+#define AMI305_SN 0xEA
+
+#define AK8974_MAX_RANGE 2048
+
+#define AK8974_POWERON_DELAY 50
+#define AK8974_ACTIVATE_DELAY 1
+#define AK8974_SELFTEST_DELAY 1
+/*
+ * Set the autosuspend to two orders of magnitude larger than the poweron
+ * delay to make sane reasonable power tradeoff savings (5 seconds in
+ * this case).
+ */
+#define AK8974_AUTOSUSPEND_DELAY 5000
+
+#define AK8974_MEASTIME 3
+
+#define AK8974_PWR_ON 1
+#define AK8974_PWR_OFF 0
+
+/**
+ * struct ak8974 - state container for the AK8974 driver
+ * @i2c: parent I2C client
+ * @orientation: mounting matrix, flipped axis etc
+ * @map: regmap to access the AK8974 registers over I2C
+ * @regs: the avdd and dvdd power regulators
+ * @name: the name of the part
+ * @variant: the whoami ID value (for selecting code paths)
+ * @lock: locks the magnetometer for exclusive use during a measurement
+ * @drdy_irq: uses the DRDY IRQ line
+ * @drdy_complete: completion for DRDY
+ * @drdy_active_low: the DRDY IRQ is active low
+ */
+struct ak8974 {
+ struct i2c_client *i2c;
+ struct iio_mount_matrix orientation;
+ struct regmap *map;
+ struct regulator_bulk_data regs[2];
+ const char *name;
+ u8 variant;
+ struct mutex lock;
+ bool drdy_irq;
+ struct completion drdy_complete;
+ bool drdy_active_low;
+};
+
+static const char ak8974_reg_avdd[] = "avdd";
+static const char ak8974_reg_dvdd[] = "dvdd";
+
+static int ak8974_set_power(struct ak8974 *ak8974, bool mode)
+{
+ int ret;
+ u8 val;
+
+ val = mode ? AK8974_CTRL1_POWER : 0;
+ val |= AK8974_CTRL1_FORCE_EN;
+ ret = regmap_write(ak8974->map, AK8974_CTRL1, val);
+ if (ret < 0)
+ return ret;
+
+ if (mode)
+ msleep(AK8974_ACTIVATE_DELAY);
+
+ return 0;
+}
+
+static int ak8974_reset(struct ak8974 *ak8974)
+{
+ int ret;
+
+ /* Power on to get register access. Sets CTRL1 reg to reset state */
+ ret = ak8974_set_power(ak8974, AK8974_PWR_ON);
+ if (ret)
+ return ret;
+ ret = regmap_write(ak8974->map, AK8974_CTRL2, AK8974_CTRL2_RESDEF);
+ if (ret)
+ return ret;
+ ret = regmap_write(ak8974->map, AK8974_CTRL3, AK8974_CTRL3_RESDEF);
+ if (ret)
+ return ret;
+ ret = regmap_write(ak8974->map, AK8974_INT_CTRL,
+ AK8974_INT_CTRL_RESDEF);
+ if (ret)
+ return ret;
+
+ /* After reset, power off is default state */
+ return ak8974_set_power(ak8974, AK8974_PWR_OFF);
+}
+
+static int ak8974_configure(struct ak8974 *ak8974)
+{
+ int ret;
+
+ ret = regmap_write(ak8974->map, AK8974_CTRL2, AK8974_CTRL2_DRDY_EN |
+ AK8974_CTRL2_INT_EN);
+ if (ret)
+ return ret;
+ ret = regmap_write(ak8974->map, AK8974_CTRL3, 0);
+ if (ret)
+ return ret;
+ ret = regmap_write(ak8974->map, AK8974_INT_CTRL, AK8974_INT_CTRL_POL);
+ if (ret)
+ return ret;
+
+ return regmap_write(ak8974->map, AK8974_PRESET, 0);
+}
+
+static int ak8974_trigmeas(struct ak8974 *ak8974)
+{
+ unsigned int clear;
+ u8 mask;
+ u8 val;
+ int ret;
+
+ /* Clear any previous measurement overflow status */
+ ret = regmap_read(ak8974->map, AK8974_INT_CLEAR, &clear);
+ if (ret)
+ return ret;
+
+ /* If we have a DRDY IRQ line, use it */
+ if (ak8974->drdy_irq) {
+ mask = AK8974_CTRL2_INT_EN |
+ AK8974_CTRL2_DRDY_EN |
+ AK8974_CTRL2_DRDY_POL;
+ val = AK8974_CTRL2_DRDY_EN;
+
+ if (!ak8974->drdy_active_low)
+ val |= AK8974_CTRL2_DRDY_POL;
+
+ init_completion(&ak8974->drdy_complete);
+ ret = regmap_update_bits(ak8974->map, AK8974_CTRL2,
+ mask, val);
+ if (ret)
+ return ret;
+ }
+
+ /* Force a measurement */
+ return regmap_update_bits(ak8974->map,
+ AK8974_CTRL3,
+ AK8974_CTRL3_FORCE,
+ AK8974_CTRL3_FORCE);
+}
+
+static int ak8974_await_drdy(struct ak8974 *ak8974)
+{
+ int timeout = 2;
+ unsigned int val;
+ int ret;
+
+ if (ak8974->drdy_irq) {
+ ret = wait_for_completion_timeout(&ak8974->drdy_complete,
+ 1 + msecs_to_jiffies(1000));
+ if (!ret) {
+ dev_err(&ak8974->i2c->dev,
+ "timeout waiting for DRDY IRQ\n");
+ return -ETIMEDOUT;
+ }
+ return 0;
+ }
+
+ /* Default delay-based poll loop */
+ do {
+ msleep(AK8974_MEASTIME);
+ ret = regmap_read(ak8974->map, AK8974_STATUS, &val);
+ if (ret < 0)
+ return ret;
+ if (val & AK8974_STATUS_DRDY)
+ return 0;
+ } while (--timeout);
+ if (!timeout) {
+ dev_err(&ak8974->i2c->dev,
+ "timeout waiting for DRDY\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int ak8974_getresult(struct ak8974 *ak8974, s16 *result)
+{
+ unsigned int src;
+ int ret;
+
+ ret = ak8974_await_drdy(ak8974);
+ if (ret)
+ return ret;
+ ret = regmap_read(ak8974->map, AK8974_INT_SRC, &src);
+ if (ret < 0)
+ return ret;
+
+ /* Out of range overflow! Strong magnet close? */
+ if (src & AK8974_INT_RANGE) {
+ dev_err(&ak8974->i2c->dev,
+ "range overflow in sensor\n");
+ return -ERANGE;
+ }
+
+ ret = regmap_bulk_read(ak8974->map, AK8974_DATA_X, result, 6);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static irqreturn_t ak8974_drdy_irq(int irq, void *d)
+{
+ struct ak8974 *ak8974 = d;
+
+ if (!ak8974->drdy_irq)
+ return IRQ_NONE;
+
+ /* TODO: timestamp here to get good measurement stamps */
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t ak8974_drdy_irq_thread(int irq, void *d)
+{
+ struct ak8974 *ak8974 = d;
+ unsigned int val;
+ int ret;
+
+ /* Check if this was a DRDY from us */
+ ret = regmap_read(ak8974->map, AK8974_STATUS, &val);
+ if (ret < 0) {
+ dev_err(&ak8974->i2c->dev, "error reading DRDY status\n");
+ return IRQ_HANDLED;
+ }
+ if (val & AK8974_STATUS_DRDY) {
+ /* Yes this was our IRQ */
+ complete(&ak8974->drdy_complete);
+ return IRQ_HANDLED;
+ }
+
+ /* We may be on a shared IRQ, let the next client check */
+ return IRQ_NONE;
+}
+
+static int ak8974_selftest(struct ak8974 *ak8974)
+{
+ struct device *dev = &ak8974->i2c->dev;
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(ak8974->map, AK8974_SELFTEST, &val);
+ if (ret)
+ return ret;
+ if (val != AK8974_SELFTEST_IDLE) {
+ dev_err(dev, "selftest not idle before test\n");
+ return -EIO;
+ }
+
+ /* Trigger self-test */
+ ret = regmap_update_bits(ak8974->map,
+ AK8974_CTRL3,
+ AK8974_CTRL3_SELFTEST,
+ AK8974_CTRL3_SELFTEST);
+ if (ret) {
+ dev_err(dev, "could not write CTRL3\n");
+ return ret;
+ }
+
+ msleep(AK8974_SELFTEST_DELAY);
+
+ ret = regmap_read(ak8974->map, AK8974_SELFTEST, &val);
+ if (ret)
+ return ret;
+ if (val != AK8974_SELFTEST_OK) {
+ dev_err(dev, "selftest result NOT OK (%02x)\n", val);
+ return -EIO;
+ }
+
+ ret = regmap_read(ak8974->map, AK8974_SELFTEST, &val);
+ if (ret)
+ return ret;
+ if (val != AK8974_SELFTEST_IDLE) {
+ dev_err(dev, "selftest not idle after test (%02x)\n", val);
+ return -EIO;
+ }
+ dev_dbg(dev, "passed self-test\n");
+
+ return 0;
+}
+
+static int ak8974_get_u16_val(struct ak8974 *ak8974, u8 reg, u16 *val)
+{
+ int ret;
+ u16 bulk;
+
+ ret = regmap_bulk_read(ak8974->map, reg, &bulk, 2);
+ if (ret)
+ return ret;
+ *val = le16_to_cpu(bulk);
+
+ return 0;
+}
+
+static int ak8974_detect(struct ak8974 *ak8974)
+{
+ unsigned int whoami;
+ const char *name;
+ int ret;
+ unsigned int fw;
+ u16 sn;
+
+ ret = regmap_read(ak8974->map, AK8974_WHOAMI, &whoami);
+ if (ret)
+ return ret;
+
+ switch (whoami) {
+ case AK8974_WHOAMI_VALUE_AMI305:
+ name = "ami305";
+ ret = regmap_read(ak8974->map, AMI305_VER, &fw);
+ if (ret)
+ return ret;
+ fw &= 0x7f; /* only bits 0 thru 6 valid */
+ ret = ak8974_get_u16_val(ak8974, AMI305_SN, &sn);
+ if (ret)
+ return ret;
+ dev_info(&ak8974->i2c->dev,
+ "detected %s, FW ver %02x, S/N: %04x\n",
+ name, fw, sn);
+ break;
+ case AK8974_WHOAMI_VALUE_AK8974:
+ name = "ak8974";
+ dev_info(&ak8974->i2c->dev, "detected AK8974\n");
+ break;
+ default:
+ dev_err(&ak8974->i2c->dev, "unsupported device (%02x) ",
+ whoami);
+ return -ENODEV;
+ }
+
+ ak8974->name = name;
+ ak8974->variant = whoami;
+
+ return 0;
+}
+
+static int ak8974_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2,
+ long mask)
+{
+ struct ak8974 *ak8974 = iio_priv(indio_dev);
+ s16 hw_values[3];
+ int ret = -EINVAL;
+
+ pm_runtime_get_sync(&ak8974->i2c->dev);
+ mutex_lock(&ak8974->lock);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (chan->address > 2) {
+ dev_err(&ak8974->i2c->dev, "faulty channel address\n");
+ ret = -EIO;
+ goto out_unlock;
+ }
+ ret = ak8974_trigmeas(ak8974);
+ if (ret)
+ goto out_unlock;
+ ret = ak8974_getresult(ak8974, hw_values);
+ if (ret)
+ goto out_unlock;
+
+ /*
+ * We read all axes and discard all but one, for optimized
+ * reading, use the triggered buffer.
+ */
+ *val = le16_to_cpu(hw_values[chan->address]);
+
+ ret = IIO_VAL_INT;
+ }
+
+ out_unlock:
+ mutex_unlock(&ak8974->lock);
+ pm_runtime_mark_last_busy(&ak8974->i2c->dev);
+ pm_runtime_put_autosuspend(&ak8974->i2c->dev);
+
+ return ret;
+}
+
+static void ak8974_fill_buffer(struct iio_dev *indio_dev)
+{
+ struct ak8974 *ak8974 = iio_priv(indio_dev);
+ int ret;
+ s16 hw_values[8]; /* Three axes + 64bit padding */
+
+ pm_runtime_get_sync(&ak8974->i2c->dev);
+ mutex_lock(&ak8974->lock);
+
+ ret = ak8974_trigmeas(ak8974);
+ if (ret) {
+ dev_err(&ak8974->i2c->dev, "error triggering measure\n");
+ goto out_unlock;
+ }
+ ret = ak8974_getresult(ak8974, hw_values);
+ if (ret) {
+ dev_err(&ak8974->i2c->dev, "error getting measures\n");
+ goto out_unlock;
+ }
+
+ iio_push_to_buffers_with_timestamp(indio_dev, hw_values,
+ iio_get_time_ns(indio_dev));
+
+ out_unlock:
+ mutex_unlock(&ak8974->lock);
+ pm_runtime_mark_last_busy(&ak8974->i2c->dev);
+ pm_runtime_put_autosuspend(&ak8974->i2c->dev);
+}
+
+static irqreturn_t ak8974_handle_trigger(int irq, void *p)
+{
+ const struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+
+ ak8974_fill_buffer(indio_dev);
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static const struct iio_mount_matrix *
+ak8974_get_mount_matrix(const struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan)
+{
+ struct ak8974 *ak8974 = iio_priv(indio_dev);
+
+ return &ak8974->orientation;
+}
+
+static const struct iio_chan_spec_ext_info ak8974_ext_info[] = {
+ IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, ak8974_get_mount_matrix),
+ { },
+};
+
+#define AK8974_AXIS_CHANNEL(axis, index) \
+ { \
+ .type = IIO_MAGN, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .ext_info = ak8974_ext_info, \
+ .address = index, \
+ .scan_index = index, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 16, \
+ .storagebits = 16, \
+ .endianness = IIO_LE \
+ }, \
+ }
+
+static const struct iio_chan_spec ak8974_channels[] = {
+ AK8974_AXIS_CHANNEL(X, 0),
+ AK8974_AXIS_CHANNEL(Y, 1),
+ AK8974_AXIS_CHANNEL(Z, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+static const unsigned long ak8974_scan_masks[] = { 0x7, 0 };
+
+static const struct iio_info ak8974_info = {
+ .read_raw = &ak8974_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static bool ak8974_writeable_reg(struct device *dev, unsigned int reg)
+{
+ struct i2c_client *i2c = to_i2c_client(dev);
+ struct iio_dev *indio_dev = i2c_get_clientdata(i2c);
+ struct ak8974 *ak8974 = iio_priv(indio_dev);
+
+ switch (reg) {
+ case AK8974_CTRL1:
+ case AK8974_CTRL2:
+ case AK8974_CTRL3:
+ case AK8974_INT_CTRL:
+ case AK8974_INT_THRES:
+ case AK8974_INT_THRES + 1:
+ case AK8974_PRESET:
+ case AK8974_PRESET + 1:
+ return true;
+ case AK8974_OFFSET_X:
+ case AK8974_OFFSET_X + 1:
+ case AK8974_OFFSET_Y:
+ case AK8974_OFFSET_Y + 1:
+ case AK8974_OFFSET_Z:
+ case AK8974_OFFSET_Z + 1:
+ if (ak8974->variant == AK8974_WHOAMI_VALUE_AK8974)
+ return true;
+ return false;
+ case AMI305_OFFSET_X:
+ case AMI305_OFFSET_X + 1:
+ case AMI305_OFFSET_Y:
+ case AMI305_OFFSET_Y + 1:
+ case AMI305_OFFSET_Z:
+ case AMI305_OFFSET_Z + 1:
+ if (ak8974->variant == AK8974_WHOAMI_VALUE_AMI305)
+ return true;
+ return false;
+ default:
+ return false;
+ }
+}
+
+static const struct regmap_config ak8974_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0xff,
+ .writeable_reg = ak8974_writeable_reg,
+};
+
+static int ak8974_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct iio_dev *indio_dev;
+ struct ak8974 *ak8974;
+ unsigned long irq_trig;
+ int irq = i2c->irq;
+ int ret;
+
+ /* Register with IIO */
+ indio_dev = devm_iio_device_alloc(&i2c->dev, sizeof(*ak8974));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ ak8974 = iio_priv(indio_dev);
+ i2c_set_clientdata(i2c, indio_dev);
+ ak8974->i2c = i2c;
+ mutex_init(&ak8974->lock);
+
+ ret = of_iio_read_mount_matrix(&i2c->dev,
+ "mount-matrix",
+ &ak8974->orientation);
+ if (ret)
+ return ret;
+
+ ak8974->regs[0].supply = ak8974_reg_avdd;
+ ak8974->regs[1].supply = ak8974_reg_dvdd;
+
+ ret = devm_regulator_bulk_get(&i2c->dev,
+ ARRAY_SIZE(ak8974->regs),
+ ak8974->regs);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "cannot get regulators\n");
+ return ret;
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(ak8974->regs), ak8974->regs);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "cannot enable regulators\n");
+ return ret;
+ }
+
+ /* Take runtime PM online */
+ pm_runtime_get_noresume(&i2c->dev);
+ pm_runtime_set_active(&i2c->dev);
+ pm_runtime_enable(&i2c->dev);
+
+ ak8974->map = devm_regmap_init_i2c(i2c, &ak8974_regmap_config);
+ if (IS_ERR(ak8974->map)) {
+ dev_err(&i2c->dev, "failed to allocate register map\n");
+ return PTR_ERR(ak8974->map);
+ }
+
+ ret = ak8974_set_power(ak8974, AK8974_PWR_ON);
+ if (ret) {
+ dev_err(&i2c->dev, "could not power on\n");
+ goto power_off;
+ }
+
+ ret = ak8974_detect(ak8974);
+ if (ret) {
+ dev_err(&i2c->dev, "neither AK8974 nor AMI305 found\n");
+ goto power_off;
+ }
+
+ ret = ak8974_selftest(ak8974);
+ if (ret)
+ dev_err(&i2c->dev, "selftest failed (continuing anyway)\n");
+
+ ret = ak8974_reset(ak8974);
+ if (ret) {
+ dev_err(&i2c->dev, "AK8974 reset failed\n");
+ goto power_off;
+ }
+
+ pm_runtime_set_autosuspend_delay(&i2c->dev,
+ AK8974_AUTOSUSPEND_DELAY);
+ pm_runtime_use_autosuspend(&i2c->dev);
+ pm_runtime_put(&i2c->dev);
+
+ indio_dev->dev.parent = &i2c->dev;
+ indio_dev->channels = ak8974_channels;
+ indio_dev->num_channels = ARRAY_SIZE(ak8974_channels);
+ indio_dev->info = &ak8974_info;
+ indio_dev->available_scan_masks = ak8974_scan_masks;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->name = ak8974->name;
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ ak8974_handle_trigger,
+ NULL);
+ if (ret) {
+ dev_err(&i2c->dev, "triggered buffer setup failed\n");
+ goto disable_pm;
+ }
+
+ /* If we have a valid DRDY IRQ, make use of it */
+ if (irq > 0) {
+ irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq));
+ if (irq_trig == IRQF_TRIGGER_RISING) {
+ dev_info(&i2c->dev, "enable rising edge DRDY IRQ\n");
+ } else if (irq_trig == IRQF_TRIGGER_FALLING) {
+ ak8974->drdy_active_low = true;
+ dev_info(&i2c->dev, "enable falling edge DRDY IRQ\n");
+ } else {
+ irq_trig = IRQF_TRIGGER_RISING;
+ }
+ irq_trig |= IRQF_ONESHOT;
+ irq_trig |= IRQF_SHARED;
+
+ ret = devm_request_threaded_irq(&i2c->dev,
+ irq,
+ ak8974_drdy_irq,
+ ak8974_drdy_irq_thread,
+ irq_trig,
+ ak8974->name,
+ ak8974);
+ if (ret) {
+ dev_err(&i2c->dev, "unable to request DRDY IRQ "
+ "- proceeding without IRQ\n");
+ goto no_irq;
+ }
+ ak8974->drdy_irq = true;
+ }
+
+no_irq:
+ ret = iio_device_register(indio_dev);
+ if (ret) {
+ dev_err(&i2c->dev, "device register failed\n");
+ goto cleanup_buffer;
+ }
+
+ return 0;
+
+cleanup_buffer:
+ iio_triggered_buffer_cleanup(indio_dev);
+disable_pm:
+ pm_runtime_put_noidle(&i2c->dev);
+ pm_runtime_disable(&i2c->dev);
+ ak8974_set_power(ak8974, AK8974_PWR_OFF);
+power_off:
+ regulator_bulk_disable(ARRAY_SIZE(ak8974->regs), ak8974->regs);
+
+ return ret;
+}
+
+static int __exit ak8974_remove(struct i2c_client *i2c)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(i2c);
+ struct ak8974 *ak8974 = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+ pm_runtime_get_sync(&i2c->dev);
+ pm_runtime_put_noidle(&i2c->dev);
+ pm_runtime_disable(&i2c->dev);
+ ak8974_set_power(ak8974, AK8974_PWR_OFF);
+ regulator_bulk_disable(ARRAY_SIZE(ak8974->regs), ak8974->regs);
+
+ return 0;
+}
+
+static int __maybe_unused ak8974_runtime_suspend(struct device *dev)
+{
+ struct ak8974 *ak8974 =
+ iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+
+ ak8974_set_power(ak8974, AK8974_PWR_OFF);
+ regulator_bulk_disable(ARRAY_SIZE(ak8974->regs), ak8974->regs);
+
+ return 0;
+}
+
+static int __maybe_unused ak8974_runtime_resume(struct device *dev)
+{
+ struct ak8974 *ak8974 =
+ iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(ak8974->regs), ak8974->regs);
+ if (ret)
+ return ret;
+ msleep(AK8974_POWERON_DELAY);
+ ret = ak8974_set_power(ak8974, AK8974_PWR_ON);
+ if (ret)
+ goto out_regulator_disable;
+
+ ret = ak8974_configure(ak8974);
+ if (ret)
+ goto out_disable_power;
+
+ return 0;
+
+out_disable_power:
+ ak8974_set_power(ak8974, AK8974_PWR_OFF);
+out_regulator_disable:
+ regulator_bulk_disable(ARRAY_SIZE(ak8974->regs), ak8974->regs);
+
+ return ret;
+}
+
+static const struct dev_pm_ops ak8974_dev_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(ak8974_runtime_suspend,
+ ak8974_runtime_resume, NULL)
+};
+
+static const struct i2c_device_id ak8974_id[] = {
+ {"ami305", 0 },
+ {"ak8974", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, ak8974_id);
+
+static const struct of_device_id ak8974_of_match[] = {
+ { .compatible = "asahi-kasei,ak8974", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, ak8974_of_match);
+
+static struct i2c_driver ak8974_driver = {
+ .driver = {
+ .name = "ak8974",
+ .pm = &ak8974_dev_pm_ops,
+ .of_match_table = of_match_ptr(ak8974_of_match),
+ },
+ .probe = ak8974_probe,
+ .remove = __exit_p(ak8974_remove),
+ .id_table = ak8974_id,
+};
+module_i2c_driver(ak8974_driver);
+
+MODULE_DESCRIPTION("AK8974 and AMI305 3-axis magnetometer driver");
+MODULE_AUTHOR("Samu Onkalo");
+MODULE_AUTHOR("Linus Walleij");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c
index f2be4a049056..f2b3bd7bf862 100644
--- a/drivers/iio/magnetometer/mag3110.c
+++ b/drivers/iio/magnetometer/mag3110.c
@@ -154,34 +154,41 @@ static int mag3110_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
- if (iio_buffer_enabled(indio_dev))
- return -EBUSY;
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
switch (chan->type) {
case IIO_MAGN: /* in 0.1 uT / LSB */
ret = mag3110_read(data, buffer);
if (ret < 0)
- return ret;
+ goto release;
*val = sign_extend32(
be16_to_cpu(buffer[chan->scan_index]), 15);
- return IIO_VAL_INT;
+ ret = IIO_VAL_INT;
+ break;
case IIO_TEMP: /* in 1 C / LSB */
mutex_lock(&data->lock);
ret = mag3110_request(data);
if (ret < 0) {
mutex_unlock(&data->lock);
- return ret;
+ goto release;
}
ret = i2c_smbus_read_byte_data(data->client,
MAG3110_DIE_TEMP);
mutex_unlock(&data->lock);
if (ret < 0)
- return ret;
+ goto release;
*val = sign_extend32(ret, 7);
- return IIO_VAL_INT;
+ ret = IIO_VAL_INT;
+ break;
default:
- return -EINVAL;
+ ret = -EINVAL;
}
+release:
+ iio_device_release_direct_mode(indio_dev);
+ return ret;
+
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_MAGN:
diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
index 7fa65ab664fb..15cd416365c1 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -185,4 +185,26 @@ config HP206C
This driver can also be built as a module. If so, the module will
be called hp206c.
+config ZPA2326
+ tristate "Murata ZPA2326 pressure sensor driver"
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ select REGMAP
+ select ZPA2326_I2C if I2C
+ select ZPA2326_SPI if SPI_MASTER
+ help
+ Say Y here to build support for the Murata ZPA2326 pressure and
+ temperature sensor.
+
+ To compile this driver as a module, choose M here: the module will
+ be called zpa2326.
+
+config ZPA2326_I2C
+ tristate
+ select REGMAP_I2C
+
+config ZPA2326_SPI
+ tristate
+ select REGMAP_SPI
+
endmenu
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
index 7f395bed5e88..fff77185a5cc 100644
--- a/drivers/iio/pressure/Makefile
+++ b/drivers/iio/pressure/Makefile
@@ -22,6 +22,9 @@ st_pressure-y := st_pressure_core.o
st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o
obj-$(CONFIG_T5403) += t5403.o
obj-$(CONFIG_HP206C) += hp206c.o
+obj-$(CONFIG_ZPA2326) += zpa2326.o
+obj-$(CONFIG_ZPA2326_I2C) += zpa2326_i2c.o
+obj-$(CONFIG_ZPA2326_SPI) += zpa2326_spi.o
obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o
obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o
diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c
index feb41f82c64a..a74ed1f0c880 100644
--- a/drivers/iio/pressure/ms5611_core.c
+++ b/drivers/iio/pressure/ms5611_core.c
@@ -416,8 +416,7 @@ static int ms5611_init(struct iio_dev *indio_dev)
return 0;
err_regulator_disable:
- if (!IS_ERR_OR_NULL(st->vdd))
- regulator_disable(st->vdd);
+ regulator_disable(st->vdd);
return ret;
}
@@ -425,8 +424,7 @@ static void ms5611_fini(const struct iio_dev *indio_dev)
{
const struct ms5611_state *st = iio_priv(indio_dev);
- if (!IS_ERR_OR_NULL(st->vdd))
- regulator_disable(st->vdd);
+ regulator_disable(st->vdd);
}
int ms5611_probe(struct iio_dev *indio_dev, struct device *dev,
diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c
new file mode 100644
index 000000000000..19d2eb46fda6
--- /dev/null
+++ b/drivers/iio/pressure/zpa2326.c
@@ -0,0 +1,1735 @@
+/*
+ * Murata ZPA2326 pressure and temperature sensor IIO driver
+ *
+ * Copyright (c) 2016 Parrot S.A.
+ *
+ * Author: Gregor Boirie <gregor.boirie@parrot.com>
+ *
+ * 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.
+ */
+
+/**
+ * DOC: ZPA2326 theory of operations
+ *
+ * This driver supports %INDIO_DIRECT_MODE and %INDIO_BUFFER_TRIGGERED IIO
+ * modes.
+ * A internal hardware trigger is also implemented to dispatch registered IIO
+ * trigger consumers upon "sample ready" interrupts.
+ *
+ * ZPA2326 hardware supports 2 sampling mode: one shot and continuous.
+ *
+ * A complete one shot sampling cycle gets device out of low power mode,
+ * performs pressure and temperature measurements, then automatically switches
+ * back to low power mode. It is meant for on demand sampling with optimal power
+ * saving at the cost of lower sampling rate and higher software overhead.
+ * This is a natural candidate for IIO read_raw hook implementation
+ * (%INDIO_DIRECT_MODE). It is also used for triggered buffering support to
+ * ensure explicit synchronization with external trigger events
+ * (%INDIO_BUFFER_TRIGGERED).
+ *
+ * The continuous mode works according to a periodic hardware measurement
+ * process continuously pushing samples into an internal hardware FIFO (for
+ * pressure samples only). Measurement cycle completion may be signaled by a
+ * "sample ready" interrupt.
+ * Typical software sequence of operations :
+ * - get device out of low power mode,
+ * - setup hardware sampling period,
+ * - at end of period, upon data ready interrupt: pop pressure samples out of
+ * hardware FIFO and fetch temperature sample
+ * - when no longer needed, stop sampling process by putting device into
+ * low power mode.
+ * This mode is used to implement %INDIO_BUFFER_TRIGGERED mode if device tree
+ * declares a valid interrupt line. In this case, the internal hardware trigger
+ * drives acquisition.
+ *
+ * Note that hardware sampling frequency is taken into account only when
+ * internal hardware trigger is attached as the highest sampling rate seems to
+ * be the most energy efficient.
+ *
+ * TODO:
+ * preset pressure threshold crossing / IIO events ;
+ * differential pressure sampling ;
+ * hardware samples averaging.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include "zpa2326.h"
+
+/* 200 ms should be enough for the longest conversion time in one-shot mode. */
+#define ZPA2326_CONVERSION_JIFFIES (HZ / 5)
+
+/* There should be a 1 ms delay (Tpup) after getting out of reset. */
+#define ZPA2326_TPUP_USEC_MIN (1000)
+#define ZPA2326_TPUP_USEC_MAX (2000)
+
+/**
+ * struct zpa2326_frequency - Hardware sampling frequency descriptor
+ * @hz : Frequency in Hertz.
+ * @odr: Output Data Rate word as expected by %ZPA2326_CTRL_REG3_REG.
+ */
+struct zpa2326_frequency {
+ int hz;
+ u16 odr;
+};
+
+/*
+ * Keep these in strict ascending order: last array entry is expected to
+ * correspond to the highest sampling frequency.
+ */
+static const struct zpa2326_frequency zpa2326_sampling_frequencies[] = {
+ { .hz = 1, .odr = 1 << ZPA2326_CTRL_REG3_ODR_SHIFT },
+ { .hz = 5, .odr = 5 << ZPA2326_CTRL_REG3_ODR_SHIFT },
+ { .hz = 11, .odr = 6 << ZPA2326_CTRL_REG3_ODR_SHIFT },
+ { .hz = 23, .odr = 7 << ZPA2326_CTRL_REG3_ODR_SHIFT },
+};
+
+/* Return the highest hardware sampling frequency available. */
+static const struct zpa2326_frequency *zpa2326_highest_frequency(void)
+{
+ return &zpa2326_sampling_frequencies[
+ ARRAY_SIZE(zpa2326_sampling_frequencies) - 1];
+}
+
+/**
+ * struct zpa_private - Per-device internal private state
+ * @timestamp: Buffered samples ready datum.
+ * @regmap: Underlying I2C / SPI bus adapter used to abstract slave register
+ * accesses.
+ * @result: Allows sampling logic to get completion status of operations
+ * that interrupt handlers perform asynchronously.
+ * @data_ready: Interrupt handler uses this to wake user context up at sampling
+ * operation completion.
+ * @trigger: Optional hardware / interrupt driven trigger used to notify
+ * external devices a new sample is ready.
+ * @waken: Flag indicating whether or not device has just been powered on.
+ * @irq: Optional interrupt line: negative or zero if not declared into
+ * DT, in which case sampling logic keeps polling status register
+ * to detect completion.
+ * @frequency: Current hardware sampling frequency.
+ * @vref: Power / voltage reference.
+ * @vdd: Power supply.
+ */
+struct zpa2326_private {
+ s64 timestamp;
+ struct regmap *regmap;
+ int result;
+ struct completion data_ready;
+ struct iio_trigger *trigger;
+ bool waken;
+ int irq;
+ const struct zpa2326_frequency *frequency;
+ struct regulator *vref;
+ struct regulator *vdd;
+};
+
+#define zpa2326_err(_idev, _format, _arg...) \
+ dev_err(_idev->dev.parent, _format, ##_arg)
+
+#define zpa2326_warn(_idev, _format, _arg...) \
+ dev_warn(_idev->dev.parent, _format, ##_arg)
+
+#ifdef DEBUG
+#define zpa2326_dbg(_idev, _format, _arg...) \
+ dev_dbg(_idev->dev.parent, _format, ##_arg)
+#else
+#define zpa2326_dbg(_idev, _format, _arg...)
+#endif
+
+bool zpa2326_isreg_writeable(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case ZPA2326_REF_P_XL_REG:
+ case ZPA2326_REF_P_L_REG:
+ case ZPA2326_REF_P_H_REG:
+ case ZPA2326_RES_CONF_REG:
+ case ZPA2326_CTRL_REG0_REG:
+ case ZPA2326_CTRL_REG1_REG:
+ case ZPA2326_CTRL_REG2_REG:
+ case ZPA2326_CTRL_REG3_REG:
+ case ZPA2326_THS_P_LOW_REG:
+ case ZPA2326_THS_P_HIGH_REG:
+ return true;
+
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL_GPL(zpa2326_isreg_writeable);
+
+bool zpa2326_isreg_readable(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case ZPA2326_REF_P_XL_REG:
+ case ZPA2326_REF_P_L_REG:
+ case ZPA2326_REF_P_H_REG:
+ case ZPA2326_DEVICE_ID_REG:
+ case ZPA2326_RES_CONF_REG:
+ case ZPA2326_CTRL_REG0_REG:
+ case ZPA2326_CTRL_REG1_REG:
+ case ZPA2326_CTRL_REG2_REG:
+ case ZPA2326_CTRL_REG3_REG:
+ case ZPA2326_INT_SOURCE_REG:
+ case ZPA2326_THS_P_LOW_REG:
+ case ZPA2326_THS_P_HIGH_REG:
+ case ZPA2326_STATUS_REG:
+ case ZPA2326_PRESS_OUT_XL_REG:
+ case ZPA2326_PRESS_OUT_L_REG:
+ case ZPA2326_PRESS_OUT_H_REG:
+ case ZPA2326_TEMP_OUT_L_REG:
+ case ZPA2326_TEMP_OUT_H_REG:
+ return true;
+
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL_GPL(zpa2326_isreg_readable);
+
+bool zpa2326_isreg_precious(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case ZPA2326_INT_SOURCE_REG:
+ case ZPA2326_PRESS_OUT_H_REG:
+ return true;
+
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL_GPL(zpa2326_isreg_precious);
+
+/**
+ * zpa2326_enable_device() - Enable device, i.e. get out of low power mode.
+ * @indio_dev: The IIO device associated with the hardware to enable.
+ *
+ * Required to access complete register space and to perform any sampling
+ * or control operations.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_enable_device(const struct iio_dev *indio_dev)
+{
+ int err;
+
+ err = regmap_write(((struct zpa2326_private *)
+ iio_priv(indio_dev))->regmap,
+ ZPA2326_CTRL_REG0_REG, ZPA2326_CTRL_REG0_ENABLE);
+ if (err) {
+ zpa2326_err(indio_dev, "failed to enable device (%d)", err);
+ return err;
+ }
+
+ zpa2326_dbg(indio_dev, "enabled");
+
+ return 0;
+}
+
+/**
+ * zpa2326_sleep() - Disable device, i.e. switch to low power mode.
+ * @indio_dev: The IIO device associated with the hardware to disable.
+ *
+ * Only %ZPA2326_DEVICE_ID_REG and %ZPA2326_CTRL_REG0_REG registers may be
+ * accessed once device is in the disabled state.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_sleep(const struct iio_dev *indio_dev)
+{
+ int err;
+
+ err = regmap_write(((struct zpa2326_private *)
+ iio_priv(indio_dev))->regmap,
+ ZPA2326_CTRL_REG0_REG, 0);
+ if (err) {
+ zpa2326_err(indio_dev, "failed to sleep (%d)", err);
+ return err;
+ }
+
+ zpa2326_dbg(indio_dev, "sleeping");
+
+ return 0;
+}
+
+/**
+ * zpa2326_reset_device() - Reset device to default hardware state.
+ * @indio_dev: The IIO device associated with the hardware to reset.
+ *
+ * Disable sampling and empty hardware FIFO.
+ * Device must be enabled before reset, i.e. not in low power mode.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_reset_device(const struct iio_dev *indio_dev)
+{
+ int err;
+
+ err = regmap_write(((struct zpa2326_private *)
+ iio_priv(indio_dev))->regmap,
+ ZPA2326_CTRL_REG2_REG, ZPA2326_CTRL_REG2_SWRESET);
+ if (err) {
+ zpa2326_err(indio_dev, "failed to reset device (%d)", err);
+ return err;
+ }
+
+ usleep_range(ZPA2326_TPUP_USEC_MIN, ZPA2326_TPUP_USEC_MAX);
+
+ zpa2326_dbg(indio_dev, "reset");
+
+ return 0;
+}
+
+/**
+ * zpa2326_start_oneshot() - Start a single sampling cycle, i.e. in one shot
+ * mode.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ *
+ * Device must have been previously enabled and configured for one shot mode.
+ * Device will be switched back to low power mode at end of cycle.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_start_oneshot(const struct iio_dev *indio_dev)
+{
+ int err;
+
+ err = regmap_write(((struct zpa2326_private *)
+ iio_priv(indio_dev))->regmap,
+ ZPA2326_CTRL_REG0_REG,
+ ZPA2326_CTRL_REG0_ENABLE |
+ ZPA2326_CTRL_REG0_ONE_SHOT);
+ if (err) {
+ zpa2326_err(indio_dev, "failed to start one shot cycle (%d)",
+ err);
+ return err;
+ }
+
+ zpa2326_dbg(indio_dev, "one shot cycle started");
+
+ return 0;
+}
+
+/**
+ * zpa2326_power_on() - Power on device to allow subsequent configuration.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ * @private: Internal private state related to @indio_dev.
+ *
+ * Sampling will be disabled, preventing strange things from happening in our
+ * back. Hardware FIFO content will be cleared.
+ * When successful, device will be left in the enabled state to allow further
+ * configuration.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_power_on(const struct iio_dev *indio_dev,
+ const struct zpa2326_private *private)
+{
+ int err;
+
+ err = regulator_enable(private->vref);
+ if (err)
+ return err;
+
+ err = regulator_enable(private->vdd);
+ if (err)
+ goto vref;
+
+ zpa2326_dbg(indio_dev, "powered on");
+
+ err = zpa2326_enable_device(indio_dev);
+ if (err)
+ goto vdd;
+
+ err = zpa2326_reset_device(indio_dev);
+ if (err)
+ goto sleep;
+
+ return 0;
+
+sleep:
+ zpa2326_sleep(indio_dev);
+vdd:
+ regulator_disable(private->vdd);
+vref:
+ regulator_disable(private->vref);
+
+ zpa2326_dbg(indio_dev, "powered off");
+
+ return err;
+}
+
+/**
+ * zpa2326_power_off() - Power off device, i.e. disable attached power
+ * regulators.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ * @private: Internal private state related to @indio_dev.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static void zpa2326_power_off(const struct iio_dev *indio_dev,
+ const struct zpa2326_private *private)
+{
+ regulator_disable(private->vdd);
+ regulator_disable(private->vref);
+
+ zpa2326_dbg(indio_dev, "powered off");
+}
+
+/**
+ * zpa2326_config_oneshot() - Setup device for one shot / on demand mode.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ * @irq: Optional interrupt line the hardware uses to notify new data
+ * samples are ready. Negative or zero values indicate no interrupts
+ * are available, meaning polling is required.
+ *
+ * Output Data Rate is configured for the highest possible rate so that
+ * conversion time and power consumption are reduced to a minimum.
+ * Note that hardware internal averaging machinery (not implemented in this
+ * driver) is not applicable in this mode.
+ *
+ * Device must have been previously enabled before calling
+ * zpa2326_config_oneshot().
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_config_oneshot(const struct iio_dev *indio_dev,
+ int irq)
+{
+ struct regmap *regs = ((struct zpa2326_private *)
+ iio_priv(indio_dev))->regmap;
+ const struct zpa2326_frequency *freq = zpa2326_highest_frequency();
+ int err;
+
+ /* Setup highest available Output Data Rate for one shot mode. */
+ err = regmap_write(regs, ZPA2326_CTRL_REG3_REG, freq->odr);
+ if (err)
+ return err;
+
+ if (irq > 0) {
+ /* Request interrupt when new sample is available. */
+ err = regmap_write(regs, ZPA2326_CTRL_REG1_REG,
+ (u8)~ZPA2326_CTRL_REG1_MASK_DATA_READY);
+
+ if (err) {
+ dev_err(indio_dev->dev.parent,
+ "failed to setup one shot mode (%d)", err);
+ return err;
+ }
+ }
+
+ zpa2326_dbg(indio_dev, "one shot mode setup @%dHz", freq->hz);
+
+ return 0;
+}
+
+/**
+ * zpa2326_clear_fifo() - Clear remaining entries in hardware FIFO.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ * @min_count: Number of samples present within hardware FIFO.
+ *
+ * @min_count argument is a hint corresponding to the known minimum number of
+ * samples currently living in the FIFO. This allows to reduce the number of bus
+ * accesses by skipping status register read operation as long as we know for
+ * sure there are still entries left.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_clear_fifo(const struct iio_dev *indio_dev,
+ unsigned int min_count)
+{
+ struct regmap *regs = ((struct zpa2326_private *)
+ iio_priv(indio_dev))->regmap;
+ int err;
+ unsigned int val;
+
+ if (!min_count) {
+ /*
+ * No hint: read status register to determine whether FIFO is
+ * empty or not.
+ */
+ err = regmap_read(regs, ZPA2326_STATUS_REG, &val);
+
+ if (err < 0)
+ goto err;
+
+ if (val & ZPA2326_STATUS_FIFO_E)
+ /* Fifo is empty: nothing to trash. */
+ return 0;
+ }
+
+ /* Clear FIFO. */
+ do {
+ /*
+ * A single fetch from pressure MSB register is enough to pop
+ * values out of FIFO.
+ */
+ err = regmap_read(regs, ZPA2326_PRESS_OUT_H_REG, &val);
+ if (err < 0)
+ goto err;
+
+ if (min_count) {
+ /*
+ * We know for sure there are at least min_count entries
+ * left in FIFO. Skip status register read.
+ */
+ min_count--;
+ continue;
+ }
+
+ err = regmap_read(regs, ZPA2326_STATUS_REG, &val);
+ if (err < 0)
+ goto err;
+
+ } while (!(val & ZPA2326_STATUS_FIFO_E));
+
+ zpa2326_dbg(indio_dev, "FIFO cleared");
+
+ return 0;
+
+err:
+ zpa2326_err(indio_dev, "failed to clear FIFO (%d)", err);
+
+ return err;
+}
+
+/**
+ * zpa2326_dequeue_pressure() - Retrieve the most recent pressure sample from
+ * hardware FIFO.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ * @pressure: Sampled pressure output.
+ *
+ * Note that ZPA2326 hardware FIFO stores pressure samples only.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_dequeue_pressure(const struct iio_dev *indio_dev,
+ u32 *pressure)
+{
+ struct regmap *regs = ((struct zpa2326_private *)
+ iio_priv(indio_dev))->regmap;
+ unsigned int val;
+ int err;
+ int cleared = -1;
+
+ err = regmap_read(regs, ZPA2326_STATUS_REG, &val);
+ if (err < 0)
+ return err;
+
+ *pressure = 0;
+
+ if (val & ZPA2326_STATUS_P_OR) {
+ /*
+ * Fifo overrun : first sample dequeued from FIFO is the
+ * newest.
+ */
+ zpa2326_warn(indio_dev, "FIFO overflow");
+
+ err = regmap_bulk_read(regs, ZPA2326_PRESS_OUT_XL_REG, pressure,
+ 3);
+ if (err)
+ return err;
+
+#define ZPA2326_FIFO_DEPTH (16U)
+ /* Hardware FIFO may hold no more than 16 pressure samples. */
+ return zpa2326_clear_fifo(indio_dev, ZPA2326_FIFO_DEPTH - 1);
+ }
+
+ /*
+ * Fifo has not overflown : retrieve newest sample. We need to pop
+ * values out until FIFO is empty : last fetched pressure is the newest.
+ * In nominal cases, we should find a single queued sample only.
+ */
+ do {
+ err = regmap_bulk_read(regs, ZPA2326_PRESS_OUT_XL_REG, pressure,
+ 3);
+ if (err)
+ return err;
+
+ err = regmap_read(regs, ZPA2326_STATUS_REG, &val);
+ if (err < 0)
+ return err;
+
+ cleared++;
+ } while (!(val & ZPA2326_STATUS_FIFO_E));
+
+ if (cleared)
+ /*
+ * Samples were pushed by hardware during previous rounds but we
+ * didn't consume them fast enough: inform user.
+ */
+ zpa2326_dbg(indio_dev, "cleared %d FIFO entries", cleared);
+
+ return 0;
+}
+
+/**
+ * zpa2326_fill_sample_buffer() - Enqueue new channel samples to IIO buffer.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ * @private: Internal private state related to @indio_dev.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_fill_sample_buffer(struct iio_dev *indio_dev,
+ const struct zpa2326_private *private)
+{
+ struct {
+ u32 pressure;
+ u16 temperature;
+ u64 timestamp;
+ } sample;
+ int err;
+
+ if (test_bit(0, indio_dev->active_scan_mask)) {
+ /* Get current pressure from hardware FIFO. */
+ err = zpa2326_dequeue_pressure(indio_dev, &sample.pressure);
+ if (err) {
+ zpa2326_warn(indio_dev, "failed to fetch pressure (%d)",
+ err);
+ return err;
+ }
+ }
+
+ if (test_bit(1, indio_dev->active_scan_mask)) {
+ /* Get current temperature. */
+ err = regmap_bulk_read(private->regmap, ZPA2326_TEMP_OUT_L_REG,
+ &sample.temperature, 2);
+ if (err) {
+ zpa2326_warn(indio_dev,
+ "failed to fetch temperature (%d)", err);
+ return err;
+ }
+ }
+
+ /*
+ * Now push samples using timestamp stored either :
+ * - by hardware interrupt handler if interrupt is available: see
+ * zpa2326_handle_irq(),
+ * - or oneshot completion polling machinery : see
+ * zpa2326_trigger_handler().
+ */
+ zpa2326_dbg(indio_dev, "filling raw samples buffer");
+
+ iio_push_to_buffers_with_timestamp(indio_dev, &sample,
+ private->timestamp);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int zpa2326_runtime_suspend(struct device *parent)
+{
+ const struct iio_dev *indio_dev = dev_get_drvdata(parent);
+
+ if (pm_runtime_autosuspend_expiration(parent))
+ /* Userspace changed autosuspend delay. */
+ return -EAGAIN;
+
+ zpa2326_power_off(indio_dev, iio_priv(indio_dev));
+
+ return 0;
+}
+
+static int zpa2326_runtime_resume(struct device *parent)
+{
+ const struct iio_dev *indio_dev = dev_get_drvdata(parent);
+
+ return zpa2326_power_on(indio_dev, iio_priv(indio_dev));
+}
+
+const struct dev_pm_ops zpa2326_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+ SET_RUNTIME_PM_OPS(zpa2326_runtime_suspend, zpa2326_runtime_resume,
+ NULL)
+};
+EXPORT_SYMBOL_GPL(zpa2326_pm_ops);
+
+/**
+ * zpa2326_resume() - Request the PM layer to power supply the device.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ *
+ * Return:
+ * < 0 - a negative error code meaning failure ;
+ * 0 - success, device has just been powered up ;
+ * 1 - success, device was already powered.
+ */
+static int zpa2326_resume(const struct iio_dev *indio_dev)
+{
+ int err;
+
+ err = pm_runtime_get_sync(indio_dev->dev.parent);
+ if (err < 0)
+ return err;
+
+ if (err > 0) {
+ /*
+ * Device was already power supplied: get it out of low power
+ * mode and inform caller.
+ */
+ zpa2326_enable_device(indio_dev);
+ return 1;
+ }
+
+ /* Inform caller device has just been brought back to life. */
+ return 0;
+}
+
+/**
+ * zpa2326_suspend() - Schedule a power down using autosuspend feature of PM
+ * layer.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ *
+ * Device is switched to low power mode at first to save power even when
+ * attached regulator is a "dummy" one.
+ */
+static void zpa2326_suspend(struct iio_dev *indio_dev)
+{
+ struct device *parent = indio_dev->dev.parent;
+
+ zpa2326_sleep(indio_dev);
+
+ pm_runtime_mark_last_busy(parent);
+ pm_runtime_put_autosuspend(parent);
+}
+
+static void zpa2326_init_runtime(struct device *parent)
+{
+ pm_runtime_get_noresume(parent);
+ pm_runtime_set_active(parent);
+ pm_runtime_enable(parent);
+ pm_runtime_set_autosuspend_delay(parent, 1000);
+ pm_runtime_use_autosuspend(parent);
+ pm_runtime_mark_last_busy(parent);
+ pm_runtime_put_autosuspend(parent);
+}
+
+static void zpa2326_fini_runtime(struct device *parent)
+{
+ pm_runtime_disable(parent);
+ pm_runtime_set_suspended(parent);
+}
+#else /* !CONFIG_PM */
+static int zpa2326_resume(const struct iio_dev *indio_dev)
+{
+ zpa2326_enable_device(indio_dev);
+
+ return 0;
+}
+
+static void zpa2326_suspend(struct iio_dev *indio_dev)
+{
+ zpa2326_sleep(indio_dev);
+}
+
+#define zpa2326_init_runtime(_parent)
+#define zpa2326_fini_runtime(_parent)
+#endif /* !CONFIG_PM */
+
+/**
+ * zpa2326_handle_irq() - Process hardware interrupts.
+ * @irq: Interrupt line the hardware uses to notify new data has arrived.
+ * @data: The IIO device associated with the sampling hardware.
+ *
+ * Timestamp buffered samples as soon as possible then schedule threaded bottom
+ * half.
+ *
+ * Return: Always successful.
+ */
+static irqreturn_t zpa2326_handle_irq(int irq, void *data)
+{
+ struct iio_dev *indio_dev = (struct iio_dev *)data;
+
+ if (iio_buffer_enabled(indio_dev)) {
+ /* Timestamping needed for buffered sampling only. */
+ ((struct zpa2326_private *)
+ iio_priv(indio_dev))->timestamp = iio_get_time_ns(indio_dev);
+ }
+
+ return IRQ_WAKE_THREAD;
+}
+
+/**
+ * zpa2326_handle_threaded_irq() - Interrupt bottom-half handler.
+ * @irq: Interrupt line the hardware uses to notify new data has arrived.
+ * @data: The IIO device associated with the sampling hardware.
+ *
+ * Mainly ensures interrupt is caused by a real "new sample available"
+ * condition. This relies upon the ability to perform blocking / sleeping bus
+ * accesses to slave's registers. This is why zpa2326_handle_threaded_irq() is
+ * called from within a thread, i.e. not called from hard interrupt context.
+ *
+ * When device is using its own internal hardware trigger in continuous sampling
+ * mode, data are available into hardware FIFO once interrupt has occurred. All
+ * we have to do is to dispatch the trigger, which in turn will fetch data and
+ * fill IIO buffer.
+ *
+ * When not using its own internal hardware trigger, the device has been
+ * configured in one-shot mode either by an external trigger or the IIO read_raw
+ * hook. This means one of the latter is currently waiting for sampling
+ * completion, in which case we must simply wake it up.
+ *
+ * See zpa2326_trigger_handler().
+ *
+ * Return:
+ * %IRQ_NONE - no consistent interrupt happened ;
+ * %IRQ_HANDLED - there was new samples available.
+ */
+static irqreturn_t zpa2326_handle_threaded_irq(int irq, void *data)
+{
+ struct iio_dev *indio_dev = (struct iio_dev *)data;
+ struct zpa2326_private *priv = iio_priv(indio_dev);
+ unsigned int val;
+ bool cont;
+ irqreturn_t ret = IRQ_NONE;
+
+ /*
+ * Are we using our own internal trigger in triggered buffer mode, i.e.,
+ * currently working in continuous sampling mode ?
+ */
+ cont = (iio_buffer_enabled(indio_dev) &&
+ iio_trigger_using_own(indio_dev));
+
+ /*
+ * Device works according to a level interrupt scheme: reading interrupt
+ * status de-asserts interrupt line.
+ */
+ priv->result = regmap_read(priv->regmap, ZPA2326_INT_SOURCE_REG, &val);
+ if (priv->result < 0) {
+ if (cont)
+ return IRQ_NONE;
+
+ goto complete;
+ }
+
+ /* Data ready is the only interrupt source we requested. */
+ if (!(val & ZPA2326_INT_SOURCE_DATA_READY)) {
+ /*
+ * Interrupt happened but no new sample available: likely caused
+ * by spurious interrupts, in which case, returning IRQ_NONE
+ * allows to benefit from the generic spurious interrupts
+ * handling.
+ */
+ zpa2326_warn(indio_dev, "unexpected interrupt status %02x",
+ val);
+
+ if (cont)
+ return IRQ_NONE;
+
+ priv->result = -ENODATA;
+ goto complete;
+ }
+
+ /* New sample available: dispatch internal trigger consumers. */
+ iio_trigger_poll_chained(priv->trigger);
+
+ if (cont)
+ /*
+ * Internal hardware trigger has been scheduled above : it will
+ * fetch data on its own.
+ */
+ return IRQ_HANDLED;
+
+ ret = IRQ_HANDLED;
+
+complete:
+ /*
+ * Wake up direct or externaly triggered buffer mode waiters: see
+ * zpa2326_sample_oneshot() and zpa2326_trigger_handler().
+ */
+ complete(&priv->data_ready);
+
+ return ret;
+}
+
+/**
+ * zpa2326_wait_oneshot_completion() - Wait for oneshot data ready interrupt.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ * @private: Internal private state related to @indio_dev.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev,
+ struct zpa2326_private *private)
+{
+ int ret;
+ unsigned int val;
+
+ zpa2326_dbg(indio_dev, "waiting for one shot completion interrupt");
+
+ ret = wait_for_completion_interruptible_timeout(
+ &private->data_ready, ZPA2326_CONVERSION_JIFFIES);
+ if (ret > 0)
+ /*
+ * Interrupt handler completed before timeout: return operation
+ * status.
+ */
+ return private->result;
+
+ /* Clear all interrupts just to be sure. */
+ regmap_read(private->regmap, ZPA2326_INT_SOURCE_REG, &val);
+
+ if (!ret)
+ /* Timed out. */
+ ret = -ETIME;
+
+ if (ret != -ERESTARTSYS)
+ zpa2326_warn(indio_dev, "no one shot interrupt occurred (%d)",
+ ret);
+
+ return ret;
+}
+
+static int zpa2326_init_managed_irq(struct device *parent,
+ struct iio_dev *indio_dev,
+ struct zpa2326_private *private,
+ int irq)
+{
+ int err;
+
+ private->irq = irq;
+
+ if (irq <= 0) {
+ /*
+ * Platform declared no interrupt line: device will be polled
+ * for data availability.
+ */
+ dev_info(parent, "no interrupt found, running in polling mode");
+ return 0;
+ }
+
+ init_completion(&private->data_ready);
+
+ /* Request handler to be scheduled into threaded interrupt context. */
+ err = devm_request_threaded_irq(parent, irq, zpa2326_handle_irq,
+ zpa2326_handle_threaded_irq,
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+ dev_name(parent), indio_dev);
+ if (err) {
+ dev_err(parent, "failed to request interrupt %d (%d)", irq,
+ err);
+ return err;
+ }
+
+ dev_info(parent, "using interrupt %d", irq);
+
+ return 0;
+}
+
+/**
+ * zpa2326_poll_oneshot_completion() - Actively poll for one shot data ready.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ *
+ * Loop over registers content to detect end of sampling cycle. Used when DT
+ * declared no valid interrupt lines.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_poll_oneshot_completion(const struct iio_dev *indio_dev)
+{
+ unsigned long tmout = jiffies + ZPA2326_CONVERSION_JIFFIES;
+ struct regmap *regs = ((struct zpa2326_private *)
+ iio_priv(indio_dev))->regmap;
+ unsigned int val;
+ int err;
+
+ zpa2326_dbg(indio_dev, "polling for one shot completion");
+
+ /*
+ * At least, 100 ms is needed for the device to complete its one-shot
+ * cycle.
+ */
+ if (msleep_interruptible(100))
+ return -ERESTARTSYS;
+
+ /* Poll for conversion completion in hardware. */
+ while (true) {
+ err = regmap_read(regs, ZPA2326_CTRL_REG0_REG, &val);
+ if (err < 0)
+ goto err;
+
+ if (!(val & ZPA2326_CTRL_REG0_ONE_SHOT))
+ /* One-shot bit self clears at conversion end. */
+ break;
+
+ if (time_after(jiffies, tmout)) {
+ /* Prevent from waiting forever : let's time out. */
+ err = -ETIME;
+ goto err;
+ }
+
+ usleep_range(10000, 20000);
+ }
+
+ /*
+ * In oneshot mode, pressure sample availability guarantees that
+ * temperature conversion has also completed : just check pressure
+ * status bit to keep things simple.
+ */
+ err = regmap_read(regs, ZPA2326_STATUS_REG, &val);
+ if (err < 0)
+ goto err;
+
+ if (!(val & ZPA2326_STATUS_P_DA)) {
+ /* No sample available. */
+ err = -ENODATA;
+ goto err;
+ }
+
+ return 0;
+
+err:
+ zpa2326_warn(indio_dev, "failed to poll one shot completion (%d)", err);
+
+ return err;
+}
+
+/**
+ * zpa2326_fetch_raw_sample() - Retrieve a raw sample and convert it to CPU
+ * endianness.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ * @type: Type of measurement / channel to fetch from.
+ * @value: Sample output.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_fetch_raw_sample(const struct iio_dev *indio_dev,
+ enum iio_chan_type type,
+ int *value)
+{
+ struct regmap *regs = ((struct zpa2326_private *)
+ iio_priv(indio_dev))->regmap;
+ int err;
+
+ switch (type) {
+ case IIO_PRESSURE:
+ zpa2326_dbg(indio_dev, "fetching raw pressure sample");
+
+ err = regmap_bulk_read(regs, ZPA2326_PRESS_OUT_XL_REG, value,
+ 3);
+ if (err) {
+ zpa2326_warn(indio_dev, "failed to fetch pressure (%d)",
+ err);
+ return err;
+ }
+
+ /* Pressure is a 24 bits wide little-endian unsigned int. */
+ *value = (((u8 *)value)[2] << 16) | (((u8 *)value)[1] << 8) |
+ ((u8 *)value)[0];
+
+ return IIO_VAL_INT;
+
+ case IIO_TEMP:
+ zpa2326_dbg(indio_dev, "fetching raw temperature sample");
+
+ err = regmap_bulk_read(regs, ZPA2326_TEMP_OUT_L_REG, value, 2);
+ if (err) {
+ zpa2326_warn(indio_dev,
+ "failed to fetch temperature (%d)", err);
+ return err;
+ }
+
+ /* Temperature is a 16 bits wide little-endian signed int. */
+ *value = (int)le16_to_cpup((__le16 *)value);
+
+ return IIO_VAL_INT;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+/**
+ * zpa2326_sample_oneshot() - Perform a complete one shot sampling cycle.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ * @type: Type of measurement / channel to fetch from.
+ * @value: Sample output.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_sample_oneshot(struct iio_dev *indio_dev,
+ enum iio_chan_type type,
+ int *value)
+{
+ int ret;
+ struct zpa2326_private *priv;
+
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
+ ret = zpa2326_resume(indio_dev);
+ if (ret < 0)
+ goto release;
+
+ priv = iio_priv(indio_dev);
+
+ if (ret > 0) {
+ /*
+ * We were already power supplied. Just clear hardware FIFO to
+ * get rid of samples acquired during previous rounds (if any).
+ * Sampling operation always generates both temperature and
+ * pressure samples. The latter are always enqueued into
+ * hardware FIFO. This may lead to situations were pressure
+ * samples still sit into FIFO when previous cycle(s) fetched
+ * temperature data only.
+ * Hence, we need to clear hardware FIFO content to prevent from
+ * getting outdated values at the end of current cycle.
+ */
+ if (type == IIO_PRESSURE) {
+ ret = zpa2326_clear_fifo(indio_dev, 0);
+ if (ret)
+ goto suspend;
+ }
+ } else {
+ /*
+ * We have just been power supplied, i.e. device is in default
+ * "out of reset" state, meaning we need to reconfigure it
+ * entirely.
+ */
+ ret = zpa2326_config_oneshot(indio_dev, priv->irq);
+ if (ret)
+ goto suspend;
+ }
+
+ /* Start a sampling cycle in oneshot mode. */
+ ret = zpa2326_start_oneshot(indio_dev);
+ if (ret)
+ goto suspend;
+
+ /* Wait for sampling cycle to complete. */
+ if (priv->irq > 0)
+ ret = zpa2326_wait_oneshot_completion(indio_dev, priv);
+ else
+ ret = zpa2326_poll_oneshot_completion(indio_dev);
+
+ if (ret)
+ goto suspend;
+
+ /* Retrieve raw sample value and convert it to CPU endianness. */
+ ret = zpa2326_fetch_raw_sample(indio_dev, type, value);
+
+suspend:
+ zpa2326_suspend(indio_dev);
+release:
+ iio_device_release_direct_mode(indio_dev);
+
+ return ret;
+}
+
+/**
+ * zpa2326_trigger_handler() - Perform an IIO buffered sampling round in one
+ * shot mode.
+ * @irq: The software interrupt assigned to @data
+ * @data: The IIO poll function dispatched by external trigger our device is
+ * attached to.
+ *
+ * Bottom-half handler called by the IIO trigger to which our device is
+ * currently attached. Allows us to synchronize this device buffered sampling
+ * either with external events (such as timer expiration, external device sample
+ * ready, etc...) or with its own interrupt (internal hardware trigger).
+ *
+ * When using an external trigger, basically run the same sequence of operations
+ * as for zpa2326_sample_oneshot() with the following hereafter. Hardware FIFO
+ * is not cleared since already done at buffering enable time and samples
+ * dequeueing always retrieves the most recent value.
+ *
+ * Otherwise, when internal hardware trigger has dispatched us, just fetch data
+ * from hardware FIFO.
+ *
+ * Fetched data will pushed unprocessed to IIO buffer since samples conversion
+ * is delegated to userspace in buffered mode (endianness, etc...).
+ *
+ * Return:
+ * %IRQ_NONE - no consistent interrupt happened ;
+ * %IRQ_HANDLED - there was new samples available.
+ */
+static irqreturn_t zpa2326_trigger_handler(int irq, void *data)
+{
+ struct iio_dev *indio_dev = ((struct iio_poll_func *)
+ data)->indio_dev;
+ struct zpa2326_private *priv = iio_priv(indio_dev);
+ bool cont;
+
+ /*
+ * We have been dispatched, meaning we are in triggered buffer mode.
+ * Using our own internal trigger implies we are currently in continuous
+ * hardware sampling mode.
+ */
+ cont = iio_trigger_using_own(indio_dev);
+
+ if (!cont) {
+ /* On demand sampling : start a one shot cycle. */
+ if (zpa2326_start_oneshot(indio_dev))
+ goto out;
+
+ /* Wait for sampling cycle to complete. */
+ if (priv->irq <= 0) {
+ /* No interrupt available: poll for completion. */
+ if (zpa2326_poll_oneshot_completion(indio_dev))
+ goto out;
+
+ /* Only timestamp sample once it is ready. */
+ priv->timestamp = iio_get_time_ns(indio_dev);
+ } else {
+ /* Interrupt handlers will timestamp for us. */
+ if (zpa2326_wait_oneshot_completion(indio_dev, priv))
+ goto out;
+ }
+ }
+
+ /* Enqueue to IIO buffer / userspace. */
+ zpa2326_fill_sample_buffer(indio_dev, priv);
+
+out:
+ if (!cont)
+ /* Don't switch to low power if sampling continuously. */
+ zpa2326_sleep(indio_dev);
+
+ /* Inform attached trigger we are done. */
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * zpa2326_preenable_buffer() - Prepare device for configuring triggered
+ * sampling
+ * modes.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ *
+ * Basically power up device.
+ * Called with IIO device's lock held.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_preenable_buffer(struct iio_dev *indio_dev)
+{
+ int ret = zpa2326_resume(indio_dev);
+
+ if (ret < 0)
+ return ret;
+
+ /* Tell zpa2326_postenable_buffer() if we have just been powered on. */
+ ((struct zpa2326_private *)
+ iio_priv(indio_dev))->waken = iio_priv(indio_dev);
+
+ return 0;
+}
+
+/**
+ * zpa2326_postenable_buffer() - Configure device for triggered sampling.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ *
+ * Basically setup one-shot mode if plugging external trigger.
+ * Otherwise, let internal trigger configure continuous sampling :
+ * see zpa2326_set_trigger_state().
+ *
+ * If an error is returned, IIO layer will call our postdisable hook for us,
+ * i.e. no need to explicitly power device off here.
+ * Called with IIO device's lock held.
+ *
+ * Called with IIO device's lock held.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_postenable_buffer(struct iio_dev *indio_dev)
+{
+ const struct zpa2326_private *priv = iio_priv(indio_dev);
+ int err;
+
+ if (!priv->waken) {
+ /*
+ * We were already power supplied. Just clear hardware FIFO to
+ * get rid of samples acquired during previous rounds (if any).
+ */
+ err = zpa2326_clear_fifo(indio_dev, 0);
+ if (err)
+ goto err;
+ }
+
+ if (!iio_trigger_using_own(indio_dev) && priv->waken) {
+ /*
+ * We are using an external trigger and we have just been
+ * powered up: reconfigure one-shot mode.
+ */
+ err = zpa2326_config_oneshot(indio_dev, priv->irq);
+ if (err)
+ goto err;
+ }
+
+ /* Plug our own trigger event handler. */
+ err = iio_triggered_buffer_postenable(indio_dev);
+ if (err)
+ goto err;
+
+ return 0;
+
+err:
+ zpa2326_err(indio_dev, "failed to enable buffering (%d)", err);
+
+ return err;
+}
+
+static int zpa2326_postdisable_buffer(struct iio_dev *indio_dev)
+{
+ zpa2326_suspend(indio_dev);
+
+ return 0;
+}
+
+static const struct iio_buffer_setup_ops zpa2326_buffer_setup_ops = {
+ .preenable = zpa2326_preenable_buffer,
+ .postenable = zpa2326_postenable_buffer,
+ .predisable = iio_triggered_buffer_predisable,
+ .postdisable = zpa2326_postdisable_buffer
+};
+
+/**
+ * zpa2326_set_trigger_state() - Start / stop continuous sampling.
+ * @trig: The trigger being attached to IIO device associated with the sampling
+ * hardware.
+ * @state: Tell whether to start (true) or stop (false)
+ *
+ * Basically enable / disable hardware continuous sampling mode.
+ *
+ * Called with IIO device's lock held at postenable() or predisable() time.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_set_trigger_state(struct iio_trigger *trig, bool state)
+{
+ const struct iio_dev *indio_dev = dev_get_drvdata(
+ trig->dev.parent);
+ const struct zpa2326_private *priv = iio_priv(indio_dev);
+ int err;
+
+ if (!state) {
+ /*
+ * Switch trigger off : in case of failure, interrupt is left
+ * disabled in order to prevent handler from accessing released
+ * resources.
+ */
+ unsigned int val;
+
+ /*
+ * As device is working in continuous mode, handlers may be
+ * accessing resources we are currently freeing...
+ * Prevent this by disabling interrupt handlers and ensure
+ * the device will generate no more interrupts unless explicitly
+ * required to, i.e. by restoring back to default one shot mode.
+ */
+ disable_irq(priv->irq);
+
+ /*
+ * Disable continuous sampling mode to restore settings for
+ * one shot / direct sampling operations.
+ */
+ err = regmap_write(priv->regmap, ZPA2326_CTRL_REG3_REG,
+ zpa2326_highest_frequency()->odr);
+ if (err)
+ return err;
+
+ /*
+ * Now that device won't generate interrupts on its own,
+ * acknowledge any currently active interrupts (may happen on
+ * rare occasions while stopping continuous mode).
+ */
+ err = regmap_read(priv->regmap, ZPA2326_INT_SOURCE_REG, &val);
+ if (err < 0)
+ return err;
+
+ /*
+ * Re-enable interrupts only if we can guarantee the device will
+ * generate no more interrupts to prevent handlers from
+ * accessing released resources.
+ */
+ enable_irq(priv->irq);
+
+ zpa2326_dbg(indio_dev, "continuous mode stopped");
+ } else {
+ /*
+ * Switch trigger on : start continuous sampling at required
+ * frequency.
+ */
+
+ if (priv->waken) {
+ /* Enable interrupt if getting out of reset. */
+ err = regmap_write(priv->regmap, ZPA2326_CTRL_REG1_REG,
+ (u8)
+ ~ZPA2326_CTRL_REG1_MASK_DATA_READY);
+ if (err)
+ return err;
+ }
+
+ /* Enable continuous sampling at specified frequency. */
+ err = regmap_write(priv->regmap, ZPA2326_CTRL_REG3_REG,
+ ZPA2326_CTRL_REG3_ENABLE_MEAS |
+ priv->frequency->odr);
+ if (err)
+ return err;
+
+ zpa2326_dbg(indio_dev, "continuous mode setup @%dHz",
+ priv->frequency->hz);
+ }
+
+ return 0;
+}
+
+static const struct iio_trigger_ops zpa2326_trigger_ops = {
+ .owner = THIS_MODULE,
+ .set_trigger_state = zpa2326_set_trigger_state,
+};
+
+/**
+ * zpa2326_init_trigger() - Create an interrupt driven / hardware trigger
+ * allowing to notify external devices a new sample is
+ * ready.
+ * @parent: Hardware sampling device @indio_dev is a child of.
+ * @indio_dev: The IIO device associated with the sampling hardware.
+ * @private: Internal private state related to @indio_dev.
+ * @irq: Optional interrupt line the hardware uses to notify new data
+ * samples are ready. Negative or zero values indicate no interrupts
+ * are available, meaning polling is required.
+ *
+ * Only relevant when DT declares a valid interrupt line.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+static int zpa2326_init_managed_trigger(struct device *parent,
+ struct iio_dev *indio_dev,
+ struct zpa2326_private *private,
+ int irq)
+{
+ struct iio_trigger *trigger;
+ int ret;
+
+ if (irq <= 0)
+ return 0;
+
+ trigger = devm_iio_trigger_alloc(parent, "%s-dev%d",
+ indio_dev->name, indio_dev->id);
+ if (!trigger)
+ return -ENOMEM;
+
+ /* Basic setup. */
+ trigger->dev.parent = parent;
+ trigger->ops = &zpa2326_trigger_ops;
+
+ private->trigger = trigger;
+
+ /* Register to triggers space. */
+ ret = devm_iio_trigger_register(parent, trigger);
+ if (ret)
+ dev_err(parent, "failed to register hardware trigger (%d)",
+ ret);
+
+ return ret;
+}
+
+static int zpa2326_get_frequency(const struct iio_dev *indio_dev)
+{
+ return ((struct zpa2326_private *)iio_priv(indio_dev))->frequency->hz;
+}
+
+static int zpa2326_set_frequency(struct iio_dev *indio_dev, int hz)
+{
+ struct zpa2326_private *priv = iio_priv(indio_dev);
+ int freq;
+ int err;
+
+ /* Check if requested frequency is supported. */
+ for (freq = 0; freq < ARRAY_SIZE(zpa2326_sampling_frequencies); freq++)
+ if (zpa2326_sampling_frequencies[freq].hz == hz)
+ break;
+ if (freq == ARRAY_SIZE(zpa2326_sampling_frequencies))
+ return -EINVAL;
+
+ /* Don't allow changing frequency if buffered sampling is ongoing. */
+ err = iio_device_claim_direct_mode(indio_dev);
+ if (err)
+ return err;
+
+ priv->frequency = &zpa2326_sampling_frequencies[freq];
+
+ iio_device_release_direct_mode(indio_dev);
+
+ return 0;
+}
+
+/* Expose supported hardware sampling frequencies (Hz) through sysfs. */
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1 5 11 23");
+
+static struct attribute *zpa2326_attributes[] = {
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group zpa2326_attribute_group = {
+ .attrs = zpa2326_attributes,
+};
+
+static int zpa2326_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long mask)
+{
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ return zpa2326_sample_oneshot(indio_dev, chan->type, val);
+
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->type) {
+ case IIO_PRESSURE:
+ /*
+ * Pressure resolution is 1/64 Pascal. Scale to kPascal
+ * as required by IIO ABI.
+ */
+ *val = 1;
+ *val2 = 64000;
+ return IIO_VAL_FRACTIONAL;
+
+ case IIO_TEMP:
+ /*
+ * Temperature follows the equation:
+ * Temp[degC] = Tempcode * 0.00649 - 176.83
+ * where:
+ * Tempcode is composed the raw sampled 16 bits.
+ *
+ * Hence, to produce a temperature in milli-degrees
+ * Celsius according to IIO ABI, we need to apply the
+ * following equation to raw samples:
+ * Temp[milli degC] = (Tempcode + Offset) * Scale
+ * where:
+ * Offset = -176.83 / 0.00649
+ * Scale = 0.00649 * 1000
+ */
+ *val = 6;
+ *val2 = 490000;
+ return IIO_VAL_INT_PLUS_MICRO;
+
+ default:
+ return -EINVAL;
+ }
+
+ case IIO_CHAN_INFO_OFFSET:
+ switch (chan->type) {
+ case IIO_TEMP:
+ *val = -17683000;
+ *val2 = 649;
+ return IIO_VAL_FRACTIONAL;
+
+ default:
+ return -EINVAL;
+ }
+
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = zpa2326_get_frequency(indio_dev);
+ return IIO_VAL_INT;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int zpa2326_write_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int val,
+ int val2,
+ long mask)
+{
+ if ((mask != IIO_CHAN_INFO_SAMP_FREQ) || val2)
+ return -EINVAL;
+
+ return zpa2326_set_frequency(indio_dev, val);
+}
+
+static const struct iio_chan_spec zpa2326_channels[] = {
+ [0] = {
+ .type = IIO_PRESSURE,
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 24,
+ .storagebits = 32,
+ .endianness = IIO_LE,
+ },
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ },
+ [1] = {
+ .type = IIO_TEMP,
+ .scan_index = 1,
+ .scan_type = {
+ .sign = 's',
+ .realbits = 16,
+ .storagebits = 16,
+ .endianness = IIO_LE,
+ },
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_OFFSET),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ },
+ [2] = IIO_CHAN_SOFT_TIMESTAMP(2),
+};
+
+static const struct iio_info zpa2326_info = {
+ .driver_module = THIS_MODULE,
+ .attrs = &zpa2326_attribute_group,
+ .read_raw = zpa2326_read_raw,
+ .write_raw = zpa2326_write_raw,
+};
+
+static struct iio_dev *zpa2326_create_managed_iiodev(struct device *device,
+ const char *name,
+ struct regmap *regmap)
+{
+ struct iio_dev *indio_dev;
+
+ /* Allocate space to hold IIO device internal state. */
+ indio_dev = devm_iio_device_alloc(device,
+ sizeof(struct zpa2326_private));
+ if (!indio_dev)
+ return NULL;
+
+ /* Setup for userspace synchronous on demand sampling. */
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->dev.parent = device;
+ indio_dev->channels = zpa2326_channels;
+ indio_dev->num_channels = ARRAY_SIZE(zpa2326_channels);
+ indio_dev->name = name;
+ indio_dev->info = &zpa2326_info;
+
+ return indio_dev;
+}
+
+int zpa2326_probe(struct device *parent,
+ const char *name,
+ int irq,
+ unsigned int hwid,
+ struct regmap *regmap)
+{
+ struct iio_dev *indio_dev;
+ struct zpa2326_private *priv;
+ int err;
+ unsigned int id;
+
+ indio_dev = zpa2326_create_managed_iiodev(parent, name, regmap);
+ if (!indio_dev)
+ return -ENOMEM;
+
+ priv = iio_priv(indio_dev);
+
+ priv->vref = devm_regulator_get(parent, "vref");
+ if (IS_ERR(priv->vref))
+ return PTR_ERR(priv->vref);
+
+ priv->vdd = devm_regulator_get(parent, "vdd");
+ if (IS_ERR(priv->vdd))
+ return PTR_ERR(priv->vdd);
+
+ /* Set default hardware sampling frequency to highest rate supported. */
+ priv->frequency = zpa2326_highest_frequency();
+
+ /*
+ * Plug device's underlying bus abstraction : this MUST be set before
+ * registering interrupt handlers since an interrupt might happen if
+ * power up sequence is not properly applied.
+ */
+ priv->regmap = regmap;
+
+ err = devm_iio_triggered_buffer_setup(parent, indio_dev, NULL,
+ zpa2326_trigger_handler,
+ &zpa2326_buffer_setup_ops);
+ if (err)
+ return err;
+
+ err = zpa2326_init_managed_trigger(parent, indio_dev, priv, irq);
+ if (err)
+ return err;
+
+ err = zpa2326_init_managed_irq(parent, indio_dev, priv, irq);
+ if (err)
+ return err;
+
+ /* Power up to check device ID and perform initial hardware setup. */
+ err = zpa2326_power_on(indio_dev, priv);
+ if (err)
+ return err;
+
+ /* Read id register to check we are talking to the right slave. */
+ err = regmap_read(regmap, ZPA2326_DEVICE_ID_REG, &id);
+ if (err)
+ goto sleep;
+
+ if (id != hwid) {
+ dev_err(parent, "found device with unexpected id %02x", id);
+ err = -ENODEV;
+ goto sleep;
+ }
+
+ err = zpa2326_config_oneshot(indio_dev, irq);
+ if (err)
+ goto sleep;
+
+ /* Setup done : go sleeping. Device will be awaken upon user request. */
+ err = zpa2326_sleep(indio_dev);
+ if (err)
+ goto poweroff;
+
+ dev_set_drvdata(parent, indio_dev);
+
+ zpa2326_init_runtime(parent);
+
+ err = iio_device_register(indio_dev);
+ if (err) {
+ zpa2326_fini_runtime(parent);
+ goto poweroff;
+ }
+
+ return 0;
+
+sleep:
+ /* Put to sleep just in case power regulators are "dummy" ones. */
+ zpa2326_sleep(indio_dev);
+poweroff:
+ zpa2326_power_off(indio_dev, priv);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(zpa2326_probe);
+
+void zpa2326_remove(const struct device *parent)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(parent);
+
+ iio_device_unregister(indio_dev);
+ zpa2326_fini_runtime(indio_dev->dev.parent);
+ zpa2326_sleep(indio_dev);
+ zpa2326_power_off(indio_dev, iio_priv(indio_dev));
+}
+EXPORT_SYMBOL_GPL(zpa2326_remove);
+
+MODULE_AUTHOR("Gregor Boirie <gregor.boirie@parrot.com>");
+MODULE_DESCRIPTION("Core driver for Murata ZPA2326 pressure sensor");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/pressure/zpa2326.h b/drivers/iio/pressure/zpa2326.h
new file mode 100644
index 000000000000..05d3e1e3a449
--- /dev/null
+++ b/drivers/iio/pressure/zpa2326.h
@@ -0,0 +1,89 @@
+/*
+ * Murata ZPA2326 pressure and temperature sensor IIO driver
+ *
+ * Copyright (c) 2016 Parrot S.A.
+ *
+ * Author: Gregor Boirie <gregor.boirie@parrot.com>
+ *
+ * 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.
+ */
+
+#ifndef _ZPA2326_H
+#define _ZPA2326_H
+
+/* Register map. */
+#define ZPA2326_REF_P_XL_REG (0x8)
+#define ZPA2326_REF_P_L_REG (0x9)
+#define ZPA2326_REF_P_H_REG (0xa)
+#define ZPA2326_DEVICE_ID_REG (0xf)
+#define ZPA2326_DEVICE_ID (0xb9)
+#define ZPA2326_RES_CONF_REG (0x10)
+#define ZPA2326_CTRL_REG0_REG (0x20)
+#define ZPA2326_CTRL_REG0_ONE_SHOT BIT(0)
+#define ZPA2326_CTRL_REG0_ENABLE BIT(1)
+#define ZPA2326_CTRL_REG1_REG (0x21)
+#define ZPA2326_CTRL_REG1_MASK_DATA_READY BIT(2)
+#define ZPA2326_CTRL_REG2_REG (0x22)
+#define ZPA2326_CTRL_REG2_SWRESET BIT(2)
+#define ZPA2326_CTRL_REG3_REG (0x23)
+#define ZPA2326_CTRL_REG3_ODR_SHIFT (4)
+#define ZPA2326_CTRL_REG3_ENABLE_MEAS BIT(7)
+#define ZPA2326_INT_SOURCE_REG (0x24)
+#define ZPA2326_INT_SOURCE_DATA_READY BIT(2)
+#define ZPA2326_THS_P_LOW_REG (0x25)
+#define ZPA2326_THS_P_HIGH_REG (0x26)
+#define ZPA2326_STATUS_REG (0x27)
+#define ZPA2326_STATUS_P_DA BIT(1)
+#define ZPA2326_STATUS_FIFO_E BIT(2)
+#define ZPA2326_STATUS_P_OR BIT(5)
+#define ZPA2326_PRESS_OUT_XL_REG (0x28)
+#define ZPA2326_PRESS_OUT_L_REG (0x29)
+#define ZPA2326_PRESS_OUT_H_REG (0x2a)
+#define ZPA2326_TEMP_OUT_L_REG (0x2b)
+#define ZPA2326_TEMP_OUT_H_REG (0x2c)
+
+struct device;
+struct regmap;
+
+bool zpa2326_isreg_writeable(struct device *dev, unsigned int reg);
+bool zpa2326_isreg_readable(struct device *dev, unsigned int reg);
+bool zpa2326_isreg_precious(struct device *dev, unsigned int reg);
+
+/**
+ * zpa2326_probe() - Instantiate and register core ZPA2326 IIO device
+ * @parent: Hardware sampling device the created IIO device will be a child of.
+ * @name: Arbitrary name to identify the device.
+ * @irq: Interrupt line, negative if none.
+ * @hwid: Expected device hardware id.
+ * @regmap: Registers map used to abstract underlying bus accesses.
+ *
+ * Return: Zero when successful, a negative error code otherwise.
+ */
+int zpa2326_probe(struct device *parent,
+ const char *name,
+ int irq,
+ unsigned int hwid,
+ struct regmap *regmap);
+
+/**
+ * zpa2326_remove() - Unregister and destroy core ZPA2326 IIO device.
+ * @parent: Hardware sampling device the IIO device to remove is a child of.
+ */
+void zpa2326_remove(const struct device *parent);
+
+#ifdef CONFIG_PM
+#include <linux/pm.h>
+extern const struct dev_pm_ops zpa2326_pm_ops;
+#define ZPA2326_PM_OPS (&zpa2326_pm_ops)
+#else
+#define ZPA2326_PM_OPS (NULL)
+#endif
+
+#endif
diff --git a/drivers/iio/pressure/zpa2326_i2c.c b/drivers/iio/pressure/zpa2326_i2c.c
new file mode 100644
index 000000000000..e4d27dd4493a
--- /dev/null
+++ b/drivers/iio/pressure/zpa2326_i2c.c
@@ -0,0 +1,99 @@
+/*
+ * Murata ZPA2326 I2C pressure and temperature sensor driver
+ *
+ * Copyright (c) 2016 Parrot S.A.
+ *
+ * Author: Gregor Boirie <gregor.boirie@parrot.com>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/i2c.h>
+#include <linux/of_device.h>
+#include "zpa2326.h"
+
+/*
+ * read_flag_mask:
+ * - address bit 7 must be set to request a register read operation
+ */
+static const struct regmap_config zpa2326_regmap_i2c_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .writeable_reg = zpa2326_isreg_writeable,
+ .readable_reg = zpa2326_isreg_readable,
+ .precious_reg = zpa2326_isreg_precious,
+ .max_register = ZPA2326_TEMP_OUT_H_REG,
+ .read_flag_mask = BIT(7),
+ .cache_type = REGCACHE_NONE,
+};
+
+static unsigned int zpa2326_i2c_hwid(const struct i2c_client *client)
+{
+#define ZPA2326_SA0(_addr) (_addr & BIT(0))
+#define ZPA2326_DEVICE_ID_SA0_SHIFT (1)
+
+ /* Identification register bit 1 mirrors device address bit 0. */
+ return (ZPA2326_DEVICE_ID |
+ (ZPA2326_SA0(client->addr) << ZPA2326_DEVICE_ID_SA0_SHIFT));
+}
+
+static int zpa2326_probe_i2c(struct i2c_client *client,
+ const struct i2c_device_id *i2c_id)
+{
+ struct regmap *regmap;
+
+ regmap = devm_regmap_init_i2c(client, &zpa2326_regmap_i2c_config);
+ if (IS_ERR(regmap)) {
+ dev_err(&client->dev, "failed to init registers map");
+ return PTR_ERR(regmap);
+ }
+
+ return zpa2326_probe(&client->dev, i2c_id->name, client->irq,
+ zpa2326_i2c_hwid(client), regmap);
+}
+
+static int zpa2326_remove_i2c(struct i2c_client *client)
+{
+ zpa2326_remove(&client->dev);
+
+ return 0;
+}
+
+static const struct i2c_device_id zpa2326_i2c_ids[] = {
+ { "zpa2326", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, zpa2326_i2c_ids);
+
+#if defined(CONFIG_OF)
+static const struct of_device_id zpa2326_i2c_matches[] = {
+ { .compatible = "murata,zpa2326" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, zpa2326_i2c_matches);
+#endif
+
+static struct i2c_driver zpa2326_i2c_driver = {
+ .driver = {
+ .name = "zpa2326-i2c",
+ .of_match_table = of_match_ptr(zpa2326_i2c_matches),
+ .pm = ZPA2326_PM_OPS,
+ },
+ .probe = zpa2326_probe_i2c,
+ .remove = zpa2326_remove_i2c,
+ .id_table = zpa2326_i2c_ids,
+};
+module_i2c_driver(zpa2326_i2c_driver);
+
+MODULE_AUTHOR("Gregor Boirie <gregor.boirie@parrot.com>");
+MODULE_DESCRIPTION("I2C driver for Murata ZPA2326 pressure sensor");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/pressure/zpa2326_spi.c b/drivers/iio/pressure/zpa2326_spi.c
new file mode 100644
index 000000000000..bd2c1c319fca
--- /dev/null
+++ b/drivers/iio/pressure/zpa2326_spi.c
@@ -0,0 +1,103 @@
+/*
+ * Murata ZPA2326 SPI pressure and temperature sensor driver
+ *
+ * Copyright (c) 2016 Parrot S.A.
+ *
+ * Author: Gregor Boirie <gregor.boirie@parrot.com>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+#include <linux/of_device.h>
+#include "zpa2326.h"
+
+/*
+ * read_flag_mask:
+ * - address bit 7 must be set to request a register read operation
+ * - address bit 6 must be set to request register address auto increment
+ */
+static const struct regmap_config zpa2326_regmap_spi_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .writeable_reg = zpa2326_isreg_writeable,
+ .readable_reg = zpa2326_isreg_readable,
+ .precious_reg = zpa2326_isreg_precious,
+ .max_register = ZPA2326_TEMP_OUT_H_REG,
+ .read_flag_mask = BIT(7) | BIT(6),
+ .cache_type = REGCACHE_NONE,
+};
+
+static int zpa2326_probe_spi(struct spi_device *spi)
+{
+ struct regmap *regmap;
+ int err;
+
+ regmap = devm_regmap_init_spi(spi, &zpa2326_regmap_spi_config);
+ if (IS_ERR(regmap)) {
+ dev_err(&spi->dev, "failed to init registers map");
+ return PTR_ERR(regmap);
+ }
+
+ /*
+ * Enforce SPI slave settings to prevent from DT misconfiguration.
+ *
+ * Clock is idle high. Sampling happens on trailing edge, i.e., rising
+ * edge. Maximum bus frequency is 1 MHz. Registers are 8 bits wide.
+ */
+ spi->mode = SPI_MODE_3;
+ spi->max_speed_hz = min(spi->max_speed_hz, 1000000U);
+ spi->bits_per_word = 8;
+ err = spi_setup(spi);
+ if (err < 0)
+ return err;
+
+ return zpa2326_probe(&spi->dev, spi_get_device_id(spi)->name,
+ spi->irq, ZPA2326_DEVICE_ID, regmap);
+}
+
+static int zpa2326_remove_spi(struct spi_device *spi)
+{
+ zpa2326_remove(&spi->dev);
+
+ return 0;
+}
+
+static const struct spi_device_id zpa2326_spi_ids[] = {
+ { "zpa2326", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(spi, zpa2326_spi_ids);
+
+#if defined(CONFIG_OF)
+static const struct of_device_id zpa2326_spi_matches[] = {
+ { .compatible = "murata,zpa2326" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, zpa2326_spi_matches);
+#endif
+
+static struct spi_driver zpa2326_spi_driver = {
+ .driver = {
+ .name = "zpa2326-spi",
+ .of_match_table = of_match_ptr(zpa2326_spi_matches),
+ .pm = ZPA2326_PM_OPS,
+ },
+ .probe = zpa2326_probe_spi,
+ .remove = zpa2326_remove_spi,
+ .id_table = zpa2326_spi_ids,
+};
+module_spi_driver(zpa2326_spi_driver);
+
+MODULE_AUTHOR("Gregor Boirie <gregor.boirie@parrot.com>");
+MODULE_DESCRIPTION("SPI driver for Murata ZPA2326 pressure sensor");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c
index 1d74b3aafeed..1f06282ec793 100644
--- a/drivers/iio/proximity/sx9500.c
+++ b/drivers/iio/proximity/sx9500.c
@@ -516,7 +516,7 @@ static irqreturn_t sx9500_irq_thread_handler(int irq, void *private)
sx9500_push_events(indio_dev);
if (val & SX9500_CONVDONE_IRQ)
- complete_all(&data->completion);
+ complete(&data->completion);
out:
mutex_unlock(&data->mutex);
@@ -1025,6 +1025,12 @@ static const struct acpi_device_id sx9500_acpi_match[] = {
};
MODULE_DEVICE_TABLE(acpi, sx9500_acpi_match);
+static const struct of_device_id sx9500_of_match[] = {
+ { .compatible = "semtech,sx9500", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sx9500_of_match);
+
static const struct i2c_device_id sx9500_id[] = {
{"sx9500", 0},
{ },
@@ -1035,6 +1041,7 @@ static struct i2c_driver sx9500_driver = {
.driver = {
.name = SX9500_DRIVER_NAME,
.acpi_match_table = ACPI_PTR(sx9500_acpi_match),
+ .of_match_table = of_match_ptr(sx9500_of_match),
.pm = &sx9500_pm_ops,
},
.probe = sx9500_probe,
diff --git a/drivers/iio/temperature/Kconfig b/drivers/iio/temperature/Kconfig
index c4664e5de791..5ea77a7e261d 100644
--- a/drivers/iio/temperature/Kconfig
+++ b/drivers/iio/temperature/Kconfig
@@ -3,6 +3,22 @@
#
menu "Temperature sensors"
+config MAXIM_THERMOCOUPLE
+ tristate "Maxim thermocouple sensors"
+ depends on SPI
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ If you say yes here you get support for the Maxim series of
+ thermocouple sensors connected via SPI.
+
+ Supported sensors:
+ * MAX6675
+ * MAX31855
+
+ This driver can also be built as a module. If so, the module will
+ be called maxim_thermocouple.
+
config MLX90614
tristate "MLX90614 contact-less infrared sensor"
depends on I2C
diff --git a/drivers/iio/temperature/Makefile b/drivers/iio/temperature/Makefile
index 02bc79d49b24..78c3de0dc3f0 100644
--- a/drivers/iio/temperature/Makefile
+++ b/drivers/iio/temperature/Makefile
@@ -2,6 +2,7 @@
# Makefile for industrial I/O temperature drivers
#
+obj-$(CONFIG_MAXIM_THERMOCOUPLE) += maxim_thermocouple.o
obj-$(CONFIG_MLX90614) += mlx90614.o
obj-$(CONFIG_TMP006) += tmp006.o
obj-$(CONFIG_TSYS01) += tsys01.o
diff --git a/drivers/iio/temperature/maxim_thermocouple.c b/drivers/iio/temperature/maxim_thermocouple.c
new file mode 100644
index 000000000000..39dd2026ccc9
--- /dev/null
+++ b/drivers/iio/temperature/maxim_thermocouple.c
@@ -0,0 +1,281 @@
+/*
+ * maxim_thermocouple.c - Support for Maxim thermocouple chips
+ *
+ * Copyright (C) 2016 Matt Ranostay <mranostay@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/spi/spi.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+
+#define MAXIM_THERMOCOUPLE_DRV_NAME "maxim_thermocouple"
+
+enum {
+ MAX6675,
+ MAX31855,
+};
+
+static const struct iio_chan_spec max6675_channels[] = {
+ { /* thermocouple temperature */
+ .type = IIO_TEMP,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 's',
+ .realbits = 13,
+ .storagebits = 16,
+ .shift = 3,
+ .endianness = IIO_BE,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(1),
+};
+
+static const struct iio_chan_spec max31855_channels[] = {
+ { /* thermocouple temperature */
+ .type = IIO_TEMP,
+ .address = 2,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 's',
+ .realbits = 14,
+ .storagebits = 16,
+ .shift = 2,
+ .endianness = IIO_BE,
+ },
+ },
+ { /* cold junction temperature */
+ .type = IIO_TEMP,
+ .address = 0,
+ .channel2 = IIO_MOD_TEMP_AMBIENT,
+ .modified = 1,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 1,
+ .scan_type = {
+ .sign = 's',
+ .realbits = 12,
+ .storagebits = 16,
+ .shift = 4,
+ .endianness = IIO_BE,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(2),
+};
+
+static const unsigned long max31855_scan_masks[] = {0x3, 0};
+
+struct maxim_thermocouple_chip {
+ const struct iio_chan_spec *channels;
+ const unsigned long *scan_masks;
+ u8 num_channels;
+ u8 read_size;
+
+ /* bit-check for valid input */
+ u32 status_bit;
+};
+
+static const struct maxim_thermocouple_chip maxim_thermocouple_chips[] = {
+ [MAX6675] = {
+ .channels = max6675_channels,
+ .num_channels = ARRAY_SIZE(max6675_channels),
+ .read_size = 2,
+ .status_bit = BIT(2),
+ },
+ [MAX31855] = {
+ .channels = max31855_channels,
+ .num_channels = ARRAY_SIZE(max31855_channels),
+ .read_size = 4,
+ .scan_masks = max31855_scan_masks,
+ .status_bit = BIT(16),
+ },
+};
+
+struct maxim_thermocouple_data {
+ struct spi_device *spi;
+ const struct maxim_thermocouple_chip *chip;
+
+ u8 buffer[16] ____cacheline_aligned;
+};
+
+static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,
+ struct iio_chan_spec const *chan, int *val)
+{
+ unsigned int storage_bytes = data->chip->read_size;
+ unsigned int shift = chan->scan_type.shift + (chan->address * 8);
+ unsigned int buf;
+ int ret;
+
+ ret = spi_read(data->spi, (void *) &buf, storage_bytes);
+ if (ret)
+ return ret;
+
+ switch (storage_bytes) {
+ case 2:
+ *val = be16_to_cpu(buf);
+ break;
+ case 4:
+ *val = be32_to_cpu(buf);
+ break;
+ }
+
+ /* check to be sure this is a valid reading */
+ if (*val & data->chip->status_bit)
+ return -EINVAL;
+
+ *val = sign_extend32(*val >> shift, chan->scan_type.realbits - 1);
+
+ return 0;
+}
+
+static irqreturn_t maxim_thermocouple_trigger_handler(int irq, void *private)
+{
+ struct iio_poll_func *pf = private;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct maxim_thermocouple_data *data = iio_priv(indio_dev);
+ int ret;
+
+ ret = spi_read(data->spi, data->buffer, data->chip->read_size);
+ if (!ret) {
+ iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+ iio_get_time_ns(indio_dev));
+ }
+
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int maxim_thermocouple_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct maxim_thermocouple_data *data = iio_priv(indio_dev);
+ int ret = -EINVAL;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
+ ret = maxim_thermocouple_read(data, chan, val);
+ iio_device_release_direct_mode(indio_dev);
+
+ if (!ret)
+ return IIO_VAL_INT;
+
+ break;
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->channel2) {
+ case IIO_MOD_TEMP_AMBIENT:
+ *val = 62;
+ *val2 = 500000; /* 1000 * 0.0625 */
+ ret = IIO_VAL_INT_PLUS_MICRO;
+ break;
+ default:
+ *val = 250; /* 1000 * 0.25 */
+ ret = IIO_VAL_INT;
+ };
+ break;
+ }
+
+ return ret;
+}
+
+static const struct iio_info maxim_thermocouple_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = maxim_thermocouple_read_raw,
+};
+
+static int maxim_thermocouple_probe(struct spi_device *spi)
+{
+ const struct spi_device_id *id = spi_get_device_id(spi);
+ struct iio_dev *indio_dev;
+ struct maxim_thermocouple_data *data;
+ const struct maxim_thermocouple_chip *chip =
+ &maxim_thermocouple_chips[id->driver_data];
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ indio_dev->info = &maxim_thermocouple_info;
+ indio_dev->name = MAXIM_THERMOCOUPLE_DRV_NAME;
+ indio_dev->channels = chip->channels;
+ indio_dev->available_scan_masks = chip->scan_masks;
+ indio_dev->num_channels = chip->num_channels;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ data = iio_priv(indio_dev);
+ data->spi = spi;
+ data->chip = chip;
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ maxim_thermocouple_trigger_handler, NULL);
+ if (ret)
+ return ret;
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto error_unreg_buffer;
+
+ return 0;
+
+error_unreg_buffer:
+ iio_triggered_buffer_cleanup(indio_dev);
+
+ return ret;
+}
+
+static int maxim_thermocouple_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+
+ return 0;
+}
+
+static const struct spi_device_id maxim_thermocouple_id[] = {
+ {"max6675", MAX6675},
+ {"max31855", MAX31855},
+ {},
+};
+MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);
+
+static struct spi_driver maxim_thermocouple_driver = {
+ .driver = {
+ .name = MAXIM_THERMOCOUPLE_DRV_NAME,
+ },
+ .probe = maxim_thermocouple_probe,
+ .remove = maxim_thermocouple_remove,
+ .id_table = maxim_thermocouple_id,
+};
+module_spi_driver(maxim_thermocouple_driver);
+
+MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>");
+MODULE_DESCRIPTION("Maxim thermocouple sensors");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index af9476460023..58a7b3504b82 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -40,8 +40,6 @@ source "drivers/staging/rtl8712/Kconfig"
source "drivers/staging/rtl8188eu/Kconfig"
-source "drivers/staging/rtl8723au/Kconfig"
-
source "drivers/staging/rts5208/Kconfig"
source "drivers/staging/octeon/Kconfig"
@@ -104,4 +102,8 @@ source "drivers/staging/i4l/Kconfig"
source "drivers/staging/ks7010/Kconfig"
+source "drivers/staging/greybus/Kconfig"
+
+source "drivers/staging/vc04_services/Kconfig"
+
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 9f6009dcafa8..2fa9745db614 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -9,7 +9,6 @@ obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_R8188EU) += rtl8188eu/
-obj-$(CONFIG_R8723AU) += rtl8723au/
obj-$(CONFIG_RTS5208) += rts5208/
obj-$(CONFIG_NETLOGIC_XLR_NET) += netlogic/
obj-$(CONFIG_OCTEON_ETHERNET) += octeon/
@@ -41,3 +40,5 @@ obj-$(CONFIG_WILC1000) += wilc1000/
obj-$(CONFIG_MOST) += most/
obj-$(CONFIG_ISDN_I4L) += i4l/
obj-$(CONFIG_KS7010) += ks7010/
+obj-$(CONFIG_GREYBUS) += greybus/
+obj-$(CONFIG_BCM2708_VCHIQ) += vc04_services/
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 06e41d24ec62..6c00d6f765c6 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -24,19 +24,6 @@ config ANDROID_LOW_MEMORY_KILLER
scripts (/init.rc), and it defines priority values with minimum free memory size
for each priority.
-config SW_SYNC
- bool "Software synchronization framework"
- default n
- depends on SYNC_FILE
- depends on DEBUG_FS
- ---help---
- A sync object driver that uses a 32bit counter to coordinate
- synchronization. Useful when there is no hardware primitive backing
- the synchronization.
-
- WARNING: improper use of this can result in deadlocking kernel
- drivers from userspace. Intended for test and debug only.
-
source "drivers/staging/android/ion/Kconfig"
endif # if ANDROID
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index 7ca61b77a8d4..7ed1be798909 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -4,4 +4,3 @@ obj-y += ion/
obj-$(CONFIG_ASHMEM) += ashmem.o
obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o
-obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o
diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig
index 19c1572f1525..c8fb4134c55d 100644
--- a/drivers/staging/android/ion/Kconfig
+++ b/drivers/staging/android/ion/Kconfig
@@ -36,7 +36,19 @@ config ION_TEGRA
config ION_HISI
tristate "Ion for Hisilicon"
depends on ARCH_HISI && ION
+ select ION_OF
help
Choose this option if you wish to use ion on Hisilicon Platform.
source "drivers/staging/android/ion/hisilicon/Kconfig"
+
+config ION_OF
+ bool "Devicetree support for Ion"
+ depends on ION && OF_ADDRESS
+ help
+ Provides base support for defining Ion heaps in devicetree
+ and setting them up. Also includes functions for platforms
+ to parse the devicetree and expand for their own custom
+ extensions
+
+ If using Ion and devicetree, you should say Y here
diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile
index 18cc2aa593c2..5d630a088381 100644
--- a/drivers/staging/android/ion/Makefile
+++ b/drivers/staging/android/ion/Makefile
@@ -1,4 +1,5 @@
-obj-$(CONFIG_ION) += ion.o ion_heap.o ion_page_pool.o ion_system_heap.o \
+obj-$(CONFIG_ION) += ion.o ion-ioctl.o ion_heap.o \
+ ion_page_pool.o ion_system_heap.o \
ion_carveout_heap.o ion_chunk_heap.o ion_cma_heap.o
obj-$(CONFIG_ION_TEST) += ion_test.o
ifdef CONFIG_COMPAT
@@ -8,4 +9,5 @@ endif
obj-$(CONFIG_ION_DUMMY) += ion_dummy_driver.o
obj-$(CONFIG_ION_TEGRA) += tegra/
obj-$(CONFIG_ION_HISI) += hisilicon/
+obj-$(CONFIG_ION_OF) += ion_of.o
diff --git a/drivers/staging/android/ion/devicetree.txt b/drivers/staging/android/ion/devicetree.txt
new file mode 100644
index 000000000000..168715271f06
--- /dev/null
+++ b/drivers/staging/android/ion/devicetree.txt
@@ -0,0 +1,51 @@
+Ion Memory Manager
+
+Ion is a memory manager that allows for sharing of buffers via dma-buf.
+Ion allows for different types of allocation via an abstraction called
+a 'heap'. A heap represents a specific type of memory. Each heap has
+a different type. There can be multiple instances of the same heap
+type.
+
+Specific heap instances are tied to heap IDs. Heap IDs are not to be specified
+in the devicetree.
+
+Required properties for Ion
+
+- compatible: "linux,ion" PLUS a compatible property for the device
+
+All child nodes of a linux,ion node are interpreted as heaps
+
+required properties for heaps
+
+- compatible: compatible string for a heap type PLUS a compatible property
+for the specific instance of the heap. Current heap types
+-- linux,ion-heap-system
+-- linux,ion-heap-system-contig
+-- linux,ion-heap-carveout
+-- linux,ion-heap-chunk
+-- linux,ion-heap-dma
+-- linux,ion-heap-custom
+
+Optional properties
+- memory-region: A phandle to a memory region. Required for DMA heap type
+(see reserved-memory.txt for details on the reservation)
+
+Example:
+
+ ion {
+ compatbile = "hisilicon,ion", "linux,ion";
+
+ ion-system-heap {
+ compatbile = "hisilicon,system-heap", "linux,ion-heap-system"
+ };
+
+ ion-camera-region {
+ compatible = "hisilicon,camera-heap", "linux,ion-heap-dma"
+ memory-region = <&camera_region>;
+ };
+
+ ion-fb-region {
+ compatbile = "hisilicon,fb-heap", "linux,ion-heap-dma"
+ memory-region = <&fb_region>;
+ };
+ }
diff --git a/drivers/staging/android/ion/hisilicon/hi6220_ion.c b/drivers/staging/android/ion/hisilicon/hi6220_ion.c
index fe9f0fd210cd..0de7897fd4bf 100644
--- a/drivers/staging/android/ion/hisilicon/hi6220_ion.c
+++ b/drivers/staging/android/ion/hisilicon/hi6220_ion.c
@@ -19,181 +19,74 @@
#include <linux/mm.h>
#include "../ion_priv.h"
#include "../ion.h"
+#include "../ion_of.h"
-struct hi6220_ion_type_table {
- const char *name;
- enum ion_heap_type type;
+struct hisi_ion_dev {
+ struct ion_heap **heaps;
+ struct ion_device *idev;
+ struct ion_platform_data *data;
};
-static struct hi6220_ion_type_table ion_type_table[] = {
- {"ion_system", ION_HEAP_TYPE_SYSTEM},
- {"ion_system_contig", ION_HEAP_TYPE_SYSTEM_CONTIG},
- {"ion_carveout", ION_HEAP_TYPE_CARVEOUT},
- {"ion_chunk", ION_HEAP_TYPE_CHUNK},
- {"ion_dma", ION_HEAP_TYPE_DMA},
- {"ion_custom", ION_HEAP_TYPE_CUSTOM},
+static struct ion_of_heap hisi_heaps[] = {
+ PLATFORM_HEAP("hisilicon,sys_user", 0,
+ ION_HEAP_TYPE_SYSTEM, "sys_user"),
+ PLATFORM_HEAP("hisilicon,sys_contig", 1,
+ ION_HEAP_TYPE_SYSTEM_CONTIG, "sys_contig"),
+ PLATFORM_HEAP("hisilicon,cma", ION_HEAP_TYPE_DMA, ION_HEAP_TYPE_DMA,
+ "cma"),
+ {}
};
-static struct ion_device *idev;
-static int num_heaps;
-static struct ion_heap **heaps;
-static struct ion_platform_heap **heaps_data;
-
-static int get_type_by_name(const char *name, enum ion_heap_type *type)
+static int hi6220_ion_probe(struct platform_device *pdev)
{
+ struct hisi_ion_dev *ipdev;
int i;
- for (i = 0; i < ARRAY_SIZE(ion_type_table); i++) {
- if (strncmp(name, ion_type_table[i].name, strlen(name)))
- continue;
-
- *type = ion_type_table[i].type;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int hi6220_set_platform_data(struct platform_device *pdev)
-{
- unsigned int base;
- unsigned int size;
- unsigned int id;
- const char *heap_name;
- const char *type_name;
- enum ion_heap_type type;
- int ret;
- struct device_node *np;
- struct ion_platform_heap *p_data;
- const struct device_node *dt_node = pdev->dev.of_node;
- int index = 0;
-
- for_each_child_of_node(dt_node, np)
- num_heaps++;
-
- heaps_data = devm_kzalloc(&pdev->dev,
- sizeof(struct ion_platform_heap *) *
- num_heaps,
- GFP_KERNEL);
- if (!heaps_data)
+ ipdev = devm_kzalloc(&pdev->dev, sizeof(*ipdev), GFP_KERNEL);
+ if (!ipdev)
return -ENOMEM;
- for_each_child_of_node(dt_node, np) {
- ret = of_property_read_string(np, "heap-name", &heap_name);
- if (ret < 0) {
- pr_err("check the name of node %s\n", np->name);
- continue;
- }
+ platform_set_drvdata(pdev, ipdev);
- ret = of_property_read_u32(np, "heap-id", &id);
- if (ret < 0) {
- pr_err("check the id %s\n", np->name);
- continue;
- }
+ ipdev->idev = ion_device_create(NULL);
+ if (IS_ERR(ipdev->idev))
+ return PTR_ERR(ipdev->idev);
- ret = of_property_read_u32(np, "heap-base", &base);
- if (ret < 0) {
- pr_err("check the base of node %s\n", np->name);
- continue;
- }
-
- ret = of_property_read_u32(np, "heap-size", &size);
- if (ret < 0) {
- pr_err("check the size of node %s\n", np->name);
- continue;
- }
-
- ret = of_property_read_string(np, "heap-type", &type_name);
- if (ret < 0) {
- pr_err("check the type of node %s\n", np->name);
- continue;
- }
+ ipdev->data = ion_parse_dt(pdev, hisi_heaps);
+ if (IS_ERR(ipdev->data))
+ return PTR_ERR(ipdev->data);
- ret = get_type_by_name(type_name, &type);
- if (ret < 0) {
- pr_err("type name error %s!\n", type_name);
- continue;
- }
- pr_info("heap index %d : name %s base 0x%x size 0x%x id %d type %d\n",
- index, heap_name, base, size, id, type);
+ ipdev->heaps = devm_kzalloc(&pdev->dev,
+ sizeof(struct ion_heap) * ipdev->data->nr,
+ GFP_KERNEL);
+ if (!ipdev->heaps) {
+ ion_destroy_platform_data(ipdev->data);
+ return -ENOMEM;
+ }
- p_data = devm_kzalloc(&pdev->dev,
- sizeof(struct ion_platform_heap),
- GFP_KERNEL);
- if (!p_data)
+ for (i = 0; i < ipdev->data->nr; i++) {
+ ipdev->heaps[i] = ion_heap_create(&ipdev->data->heaps[i]);
+ if (!ipdev->heaps) {
+ ion_destroy_platform_data(ipdev->data);
return -ENOMEM;
-
- p_data->name = heap_name;
- p_data->base = base;
- p_data->size = size;
- p_data->id = id;
- p_data->type = type;
-
- heaps_data[index] = p_data;
- index++;
+ }
+ ion_device_add_heap(ipdev->idev, ipdev->heaps[i]);
}
return 0;
}
-static int hi6220_ion_probe(struct platform_device *pdev)
+static int hi6220_ion_remove(struct platform_device *pdev)
{
+ struct hisi_ion_dev *ipdev;
int i;
- int err;
- static struct ion_platform_heap *p_heap;
-
- idev = ion_device_create(NULL);
- err = hi6220_set_platform_data(pdev);
- if (err) {
- pr_err("ion set platform data error!\n");
- goto err_free_idev;
- }
- heaps = devm_kzalloc(&pdev->dev,
- sizeof(struct ion_heap *) * num_heaps,
- GFP_KERNEL);
- if (!heaps) {
- err = -ENOMEM;
- goto err_free_idev;
- }
-
- /*
- * create the heaps as specified in the dts file
- */
- for (i = 0; i < num_heaps; i++) {
- p_heap = heaps_data[i];
- heaps[i] = ion_heap_create(p_heap);
- if (IS_ERR_OR_NULL(heaps[i])) {
- err = PTR_ERR(heaps[i]);
- goto err_free_heaps;
- }
-
- ion_device_add_heap(idev, heaps[i]);
- pr_info("%s: adding heap %s of type %d with %lx@%lx\n",
- __func__, p_heap->name, p_heap->type,
- p_heap->base, (unsigned long)p_heap->size);
- }
- return err;
+ ipdev = platform_get_drvdata(pdev);
-err_free_heaps:
- for (i = 0; i < num_heaps; ++i) {
- ion_heap_destroy(heaps[i]);
- heaps[i] = NULL;
- }
-err_free_idev:
- ion_device_destroy(idev);
+ for (i = 0; i < ipdev->data->nr; i++)
+ ion_heap_destroy(ipdev->heaps[i]);
- return err;
-}
-
-static int hi6220_ion_remove(struct platform_device *pdev)
-{
- int i;
-
- for (i = 0; i < num_heaps; i++) {
- ion_heap_destroy(heaps[i]);
- heaps[i] = NULL;
- }
- ion_device_destroy(idev);
+ ion_destroy_platform_data(ipdev->data);
+ ion_device_destroy(ipdev->idev);
return 0;
}
diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c
new file mode 100644
index 000000000000..7e7431d8d49f
--- /dev/null
+++ b/drivers/staging/android/ion/ion-ioctl.c
@@ -0,0 +1,177 @@
+/*
+ *
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+
+#include "ion.h"
+#include "ion_priv.h"
+#include "compat_ion.h"
+
+union ion_ioctl_arg {
+ struct ion_fd_data fd;
+ struct ion_allocation_data allocation;
+ struct ion_handle_data handle;
+ struct ion_custom_data custom;
+ struct ion_heap_query query;
+};
+
+static int validate_ioctl_arg(unsigned int cmd, union ion_ioctl_arg *arg)
+{
+ int ret = 0;
+
+ switch (cmd) {
+ case ION_IOC_HEAP_QUERY:
+ ret = arg->query.reserved0 != 0;
+ ret |= arg->query.reserved1 != 0;
+ ret |= arg->query.reserved2 != 0;
+ break;
+ default:
+ break;
+ }
+
+ return ret ? -EINVAL : 0;
+}
+
+/* fix up the cases where the ioctl direction bits are incorrect */
+static unsigned int ion_ioctl_dir(unsigned int cmd)
+{
+ switch (cmd) {
+ case ION_IOC_SYNC:
+ case ION_IOC_FREE:
+ case ION_IOC_CUSTOM:
+ return _IOC_WRITE;
+ default:
+ return _IOC_DIR(cmd);
+ }
+}
+
+long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ struct ion_client *client = filp->private_data;
+ struct ion_device *dev = client->dev;
+ struct ion_handle *cleanup_handle = NULL;
+ int ret = 0;
+ unsigned int dir;
+ union ion_ioctl_arg data;
+
+ dir = ion_ioctl_dir(cmd);
+
+ if (_IOC_SIZE(cmd) > sizeof(data))
+ return -EINVAL;
+
+ /*
+ * The copy_from_user is unconditional here for both read and write
+ * to do the validate. If there is no write for the ioctl, the
+ * buffer is cleared
+ */
+ if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd)))
+ return -EFAULT;
+
+ ret = validate_ioctl_arg(cmd, &data);
+ if (WARN_ON_ONCE(ret))
+ return ret;
+
+ if (!(dir & _IOC_WRITE))
+ memset(&data, 0, sizeof(data));
+
+ switch (cmd) {
+ case ION_IOC_ALLOC:
+ {
+ struct ion_handle *handle;
+
+ handle = ion_alloc(client, data.allocation.len,
+ data.allocation.align,
+ data.allocation.heap_id_mask,
+ data.allocation.flags);
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+
+ data.allocation.handle = handle->id;
+
+ cleanup_handle = handle;
+ break;
+ }
+ case ION_IOC_FREE:
+ {
+ struct ion_handle *handle;
+
+ mutex_lock(&client->lock);
+ handle = ion_handle_get_by_id_nolock(client, data.handle.handle);
+ if (IS_ERR(handle)) {
+ mutex_unlock(&client->lock);
+ return PTR_ERR(handle);
+ }
+ ion_free_nolock(client, handle);
+ ion_handle_put_nolock(handle);
+ mutex_unlock(&client->lock);
+ break;
+ }
+ case ION_IOC_SHARE:
+ case ION_IOC_MAP:
+ {
+ struct ion_handle *handle;
+
+ handle = ion_handle_get_by_id(client, data.handle.handle);
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ data.fd.fd = ion_share_dma_buf_fd(client, handle);
+ ion_handle_put(handle);
+ if (data.fd.fd < 0)
+ ret = data.fd.fd;
+ break;
+ }
+ case ION_IOC_IMPORT:
+ {
+ struct ion_handle *handle;
+
+ handle = ion_import_dma_buf_fd(client, data.fd.fd);
+ if (IS_ERR(handle))
+ ret = PTR_ERR(handle);
+ else
+ data.handle.handle = handle->id;
+ break;
+ }
+ case ION_IOC_SYNC:
+ {
+ ret = ion_sync_for_device(client, data.fd.fd);
+ break;
+ }
+ case ION_IOC_CUSTOM:
+ {
+ if (!dev->custom_ioctl)
+ return -ENOTTY;
+ ret = dev->custom_ioctl(client, data.custom.cmd,
+ data.custom.arg);
+ break;
+ }
+ case ION_IOC_HEAP_QUERY:
+ ret = ion_query_heaps(client, &data.query);
+ break;
+ default:
+ return -ENOTTY;
+ }
+
+ if (dir & _IOC_READ) {
+ if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) {
+ if (cleanup_handle)
+ ion_free(client, cleanup_handle);
+ return -EFAULT;
+ }
+ }
+ return ret;
+}
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index a2cf93b59016..396ded52ab70 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -41,80 +41,6 @@
#include "ion_priv.h"
#include "compat_ion.h"
-/**
- * struct ion_device - the metadata of the ion device node
- * @dev: the actual misc device
- * @buffers: an rb tree of all the existing buffers
- * @buffer_lock: lock protecting the tree of buffers
- * @lock: rwsem protecting the tree of heaps and clients
- * @heaps: list of all the heaps in the system
- * @user_clients: list of all the clients created from userspace
- */
-struct ion_device {
- struct miscdevice dev;
- struct rb_root buffers;
- struct mutex buffer_lock;
- struct rw_semaphore lock;
- struct plist_head heaps;
- long (*custom_ioctl)(struct ion_client *client, unsigned int cmd,
- unsigned long arg);
- struct rb_root clients;
- struct dentry *debug_root;
- struct dentry *heaps_debug_root;
- struct dentry *clients_debug_root;
-};
-
-/**
- * struct ion_client - a process/hw block local address space
- * @node: node in the tree of all clients
- * @dev: backpointer to ion device
- * @handles: an rb tree of all the handles in this client
- * @idr: an idr space for allocating handle ids
- * @lock: lock protecting the tree of handles
- * @name: used for debugging
- * @display_name: used for debugging (unique version of @name)
- * @display_serial: used for debugging (to make display_name unique)
- * @task: used for debugging
- *
- * A client represents a list of buffers this client may access.
- * The mutex stored here is used to protect both handles tree
- * as well as the handles themselves, and should be held while modifying either.
- */
-struct ion_client {
- struct rb_node node;
- struct ion_device *dev;
- struct rb_root handles;
- struct idr idr;
- struct mutex lock;
- const char *name;
- char *display_name;
- int display_serial;
- struct task_struct *task;
- pid_t pid;
- struct dentry *debug_root;
-};
-
-/**
- * ion_handle - a client local reference to a buffer
- * @ref: reference count
- * @client: back pointer to the client the buffer resides in
- * @buffer: pointer to the buffer
- * @node: node in the client's handle rbtree
- * @kmap_cnt: count of times this client has mapped to kernel
- * @id: client-unique id allocated by client->idr
- *
- * Modifications to node, map_cnt or mapping should be protected by the
- * lock in the client. Other fields are never changed after initialization.
- */
-struct ion_handle {
- struct kref ref;
- struct ion_client *client;
- struct ion_buffer *buffer;
- struct rb_node node;
- unsigned int kmap_cnt;
- int id;
-};
-
bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer)
{
return (buffer->flags & ION_FLAG_CACHED) &&
@@ -174,10 +100,10 @@ static void ion_buffer_add(struct ion_device *dev,
/* this function should only be called while dev->lock is held */
static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
- struct ion_device *dev,
- unsigned long len,
- unsigned long align,
- unsigned long flags)
+ struct ion_device *dev,
+ unsigned long len,
+ unsigned long align,
+ unsigned long flags)
{
struct ion_buffer *buffer;
struct sg_table *table;
@@ -205,19 +131,16 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
goto err2;
}
- buffer->dev = dev;
- buffer->size = len;
-
- table = heap->ops->map_dma(heap, buffer);
- if (WARN_ONCE(table == NULL,
- "heap->ops->map_dma should return ERR_PTR on error"))
- table = ERR_PTR(-EINVAL);
- if (IS_ERR(table)) {
+ if (buffer->sg_table == NULL) {
+ WARN_ONCE(1, "This heap needs to set the sgtable");
ret = -EINVAL;
goto err1;
}
- buffer->sg_table = table;
+ table = buffer->sg_table;
+ buffer->dev = dev;
+ buffer->size = len;
+
if (ion_buffer_fault_user_mappings(buffer)) {
int num_pages = PAGE_ALIGN(buffer->size) / PAGE_SIZE;
struct scatterlist *sg;
@@ -226,7 +149,7 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
buffer->pages = vmalloc(sizeof(struct page *) * num_pages);
if (!buffer->pages) {
ret = -ENOMEM;
- goto err;
+ goto err1;
}
for_each_sg(table->sgl, sg, table->nents, i) {
@@ -260,8 +183,6 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
mutex_unlock(&dev->buffer_lock);
return buffer;
-err:
- heap->ops->unmap_dma(heap, buffer);
err1:
heap->ops->free(buffer);
err2:
@@ -273,7 +194,6 @@ void ion_buffer_destroy(struct ion_buffer *buffer)
{
if (WARN_ON(buffer->kmap_cnt > 0))
buffer->heap->ops->unmap_kernel(buffer->heap, buffer);
- buffer->heap->ops->unmap_dma(buffer->heap, buffer);
buffer->heap->ops->free(buffer);
vfree(buffer->pages);
kfree(buffer);
@@ -337,7 +257,7 @@ static void ion_buffer_remove_from_handle(struct ion_buffer *buffer)
}
static struct ion_handle *ion_handle_create(struct ion_client *client,
- struct ion_buffer *buffer)
+ struct ion_buffer *buffer)
{
struct ion_handle *handle;
@@ -377,26 +297,17 @@ static void ion_handle_destroy(struct kref *kref)
kfree(handle);
}
-struct ion_buffer *ion_handle_buffer(struct ion_handle *handle)
-{
- return handle->buffer;
-}
-
static void ion_handle_get(struct ion_handle *handle)
{
kref_get(&handle->ref);
}
-static int ion_handle_put_nolock(struct ion_handle *handle)
+int ion_handle_put_nolock(struct ion_handle *handle)
{
- int ret;
-
- ret = kref_put(&handle->ref, ion_handle_destroy);
-
- return ret;
+ return kref_put(&handle->ref, ion_handle_destroy);
}
-static int ion_handle_put(struct ion_handle *handle)
+int ion_handle_put(struct ion_handle *handle)
{
struct ion_client *client = handle->client;
int ret;
@@ -426,8 +337,8 @@ static struct ion_handle *ion_handle_lookup(struct ion_client *client,
return ERR_PTR(-EINVAL);
}
-static struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client,
- int id)
+struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client,
+ int id)
{
struct ion_handle *handle;
@@ -438,7 +349,7 @@ static struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client,
return handle ? handle : ERR_PTR(-EINVAL);
}
-static struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
+struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
int id)
{
struct ion_handle *handle;
@@ -551,15 +462,10 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
}
EXPORT_SYMBOL(ion_alloc);
-static void ion_free_nolock(struct ion_client *client, struct ion_handle *handle)
+void ion_free_nolock(struct ion_client *client,
+ struct ion_handle *handle)
{
- bool valid_handle;
-
- BUG_ON(client != handle->client);
-
- valid_handle = ion_handle_validate(client, handle);
-
- if (!valid_handle) {
+ if (!ion_handle_validate(client, handle)) {
WARN(1, "%s: invalid handle passed to free.\n", __func__);
return;
}
@@ -576,32 +482,6 @@ void ion_free(struct ion_client *client, struct ion_handle *handle)
}
EXPORT_SYMBOL(ion_free);
-int ion_phys(struct ion_client *client, struct ion_handle *handle,
- ion_phys_addr_t *addr, size_t *len)
-{
- struct ion_buffer *buffer;
- int ret;
-
- mutex_lock(&client->lock);
- if (!ion_handle_validate(client, handle)) {
- mutex_unlock(&client->lock);
- return -EINVAL;
- }
-
- buffer = handle->buffer;
-
- if (!buffer->heap->ops->phys) {
- pr_err("%s: ion_phys is not implemented by this heap (name=%s, type=%d).\n",
- __func__, buffer->heap->name, buffer->heap->type);
- mutex_unlock(&client->lock);
- return -ENODEV;
- }
- mutex_unlock(&client->lock);
- ret = buffer->heap->ops->phys(buffer->heap, buffer, addr, len);
- return ret;
-}
-EXPORT_SYMBOL(ion_phys);
-
static void *ion_buffer_kmap_get(struct ion_buffer *buffer)
{
void *vaddr;
@@ -612,7 +492,7 @@ static void *ion_buffer_kmap_get(struct ion_buffer *buffer)
}
vaddr = buffer->heap->ops->map_kernel(buffer->heap, buffer);
if (WARN_ONCE(vaddr == NULL,
- "heap->ops->map_kernel should return ERR_PTR on error"))
+ "heap->ops->map_kernel should return ERR_PTR on error"))
return ERR_PTR(-EINVAL);
if (IS_ERR(vaddr))
return vaddr;
@@ -781,14 +661,14 @@ static const struct file_operations debug_client_fops = {
};
static int ion_get_client_serial(const struct rb_root *root,
- const unsigned char *name)
+ const unsigned char *name)
{
int serial = -1;
struct rb_node *node;
for (node = rb_first(root); node; node = rb_next(node)) {
struct ion_client *client = rb_entry(node, struct ion_client,
- node);
+ node);
if (strcmp(client->name, name))
continue;
@@ -863,14 +743,14 @@ struct ion_client *ion_client_create(struct ion_device *dev,
rb_insert_color(&client->node, &dev->clients);
client->debug_root = debugfs_create_file(client->display_name, 0664,
- dev->clients_debug_root,
- client, &debug_client_fops);
+ dev->clients_debug_root,
+ client, &debug_client_fops);
if (!client->debug_root) {
char buf[256], *path;
path = dentry_path(dev->clients_debug_root, buf, 256);
pr_err("Failed to create client debugfs at %s/%s\n",
- path, client->display_name);
+ path, client->display_name);
}
up_write(&dev->lock);
@@ -917,26 +797,6 @@ void ion_client_destroy(struct ion_client *client)
}
EXPORT_SYMBOL(ion_client_destroy);
-struct sg_table *ion_sg_table(struct ion_client *client,
- struct ion_handle *handle)
-{
- struct ion_buffer *buffer;
- struct sg_table *table;
-
- mutex_lock(&client->lock);
- if (!ion_handle_validate(client, handle)) {
- pr_err("%s: invalid handle passed to map_dma.\n",
- __func__);
- mutex_unlock(&client->lock);
- return ERR_PTR(-EINVAL);
- }
- buffer = handle->buffer;
- table = buffer->sg_table;
- mutex_unlock(&client->lock);
- return table;
-}
-EXPORT_SYMBOL(ion_sg_table);
-
static void ion_buffer_sync_for_device(struct ion_buffer *buffer,
struct device *dev,
enum dma_data_direction direction);
@@ -958,7 +818,7 @@ static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment,
}
void ion_pages_sync_for_device(struct device *dev, struct page *page,
- size_t size, enum dma_data_direction dir)
+ size_t size, enum dma_data_direction dir)
{
struct scatterlist sg;
@@ -998,7 +858,7 @@ static void ion_buffer_sync_for_device(struct ion_buffer *buffer,
if (ion_buffer_page_is_dirty(page))
ion_pages_sync_for_device(dev, ion_buffer_page(page),
- PAGE_SIZE, dir);
+ PAGE_SIZE, dir);
ion_buffer_page_clean(buffer->pages + i);
}
@@ -1076,7 +936,7 @@ static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
if (!buffer->heap->ops->map_user) {
pr_err("%s: this heap does not define a method for mapping to userspace\n",
- __func__);
+ __func__);
return -EINVAL;
}
@@ -1167,7 +1027,7 @@ static struct dma_buf_ops dma_buf_ops = {
};
struct dma_buf *ion_share_dma_buf(struct ion_client *client,
- struct ion_handle *handle)
+ struct ion_handle *handle)
{
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
struct ion_buffer *buffer;
@@ -1275,7 +1135,7 @@ struct ion_handle *ion_import_dma_buf_fd(struct ion_client *client, int fd)
}
EXPORT_SYMBOL(ion_import_dma_buf_fd);
-static int ion_sync_for_device(struct ion_client *client, int fd)
+int ion_sync_for_device(struct ion_client *client, int fd)
{
struct dma_buf *dmabuf;
struct ion_buffer *buffer;
@@ -1299,124 +1159,45 @@ static int ion_sync_for_device(struct ion_client *client, int fd)
return 0;
}
-/* fix up the cases where the ioctl direction bits are incorrect */
-static unsigned int ion_ioctl_dir(unsigned int cmd)
-{
- switch (cmd) {
- case ION_IOC_SYNC:
- case ION_IOC_FREE:
- case ION_IOC_CUSTOM:
- return _IOC_WRITE;
- default:
- return _IOC_DIR(cmd);
- }
-}
-
-static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+int ion_query_heaps(struct ion_client *client, struct ion_heap_query *query)
{
- struct ion_client *client = filp->private_data;
struct ion_device *dev = client->dev;
- struct ion_handle *cleanup_handle = NULL;
- int ret = 0;
- unsigned int dir;
-
- union {
- struct ion_fd_data fd;
- struct ion_allocation_data allocation;
- struct ion_handle_data handle;
- struct ion_custom_data custom;
- } data;
+ struct ion_heap_data __user *buffer = u64_to_user_ptr(query->heaps);
+ int ret = -EINVAL, cnt = 0, max_cnt;
+ struct ion_heap *heap;
+ struct ion_heap_data hdata;
- dir = ion_ioctl_dir(cmd);
+ memset(&hdata, 0, sizeof(hdata));
- if (_IOC_SIZE(cmd) > sizeof(data))
- return -EINVAL;
+ down_read(&dev->lock);
+ if (!buffer) {
+ query->cnt = dev->heap_cnt;
+ ret = 0;
+ goto out;
+ }
- if (dir & _IOC_WRITE)
- if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd)))
- return -EFAULT;
+ if (query->cnt <= 0)
+ goto out;
- switch (cmd) {
- case ION_IOC_ALLOC:
- {
- struct ion_handle *handle;
+ max_cnt = query->cnt;
- handle = ion_alloc(client, data.allocation.len,
- data.allocation.align,
- data.allocation.heap_id_mask,
- data.allocation.flags);
- if (IS_ERR(handle))
- return PTR_ERR(handle);
+ plist_for_each_entry(heap, &dev->heaps, node) {
+ strncpy(hdata.name, heap->name, MAX_HEAP_NAME);
+ hdata.name[sizeof(hdata.name) - 1] = '\0';
+ hdata.type = heap->type;
+ hdata.heap_id = heap->id;
- data.allocation.handle = handle->id;
+ ret = copy_to_user(&buffer[cnt],
+ &hdata, sizeof(hdata));
- cleanup_handle = handle;
- break;
- }
- case ION_IOC_FREE:
- {
- struct ion_handle *handle;
-
- mutex_lock(&client->lock);
- handle = ion_handle_get_by_id_nolock(client, data.handle.handle);
- if (IS_ERR(handle)) {
- mutex_unlock(&client->lock);
- return PTR_ERR(handle);
- }
- ion_free_nolock(client, handle);
- ion_handle_put_nolock(handle);
- mutex_unlock(&client->lock);
- break;
- }
- case ION_IOC_SHARE:
- case ION_IOC_MAP:
- {
- struct ion_handle *handle;
-
- handle = ion_handle_get_by_id(client, data.handle.handle);
- if (IS_ERR(handle))
- return PTR_ERR(handle);
- data.fd.fd = ion_share_dma_buf_fd(client, handle);
- ion_handle_put(handle);
- if (data.fd.fd < 0)
- ret = data.fd.fd;
- break;
- }
- case ION_IOC_IMPORT:
- {
- struct ion_handle *handle;
-
- handle = ion_import_dma_buf_fd(client, data.fd.fd);
- if (IS_ERR(handle))
- ret = PTR_ERR(handle);
- else
- data.handle.handle = handle->id;
- break;
- }
- case ION_IOC_SYNC:
- {
- ret = ion_sync_for_device(client, data.fd.fd);
- break;
- }
- case ION_IOC_CUSTOM:
- {
- if (!dev->custom_ioctl)
- return -ENOTTY;
- ret = dev->custom_ioctl(client, data.custom.cmd,
- data.custom.arg);
- break;
- }
- default:
- return -ENOTTY;
+ cnt++;
+ if (cnt >= max_cnt)
+ break;
}
- if (dir & _IOC_READ) {
- if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) {
- if (cleanup_handle)
- ion_free(client, cleanup_handle);
- return -EFAULT;
- }
- }
+ query->cnt = cnt;
+out:
+ up_read(&dev->lock);
return ret;
}
@@ -1528,7 +1309,7 @@ static int ion_debug_heap_show(struct seq_file *s, void *unused)
seq_printf(s, "%16s %16zu\n", "total ", total_size);
if (heap->flags & ION_HEAP_FLAG_DEFER_FREE)
seq_printf(s, "%16s %16zu\n", "deferred free",
- heap->free_list_size);
+ heap->free_list_size);
seq_puts(s, "----------------------------------------------------\n");
if (heap->debug_show)
@@ -1588,8 +1369,7 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
{
struct dentry *debug_file;
- if (!heap->ops->allocate || !heap->ops->free || !heap->ops->map_dma ||
- !heap->ops->unmap_dma)
+ if (!heap->ops->allocate || !heap->ops->free)
pr_err("%s: can not add heap with invalid ops struct.\n",
__func__);
@@ -1611,15 +1391,15 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
plist_node_init(&heap->node, -heap->id);
plist_add(&heap->node, &dev->heaps);
debug_file = debugfs_create_file(heap->name, 0664,
- dev->heaps_debug_root, heap,
- &debug_heap_fops);
+ dev->heaps_debug_root, heap,
+ &debug_heap_fops);
if (!debug_file) {
char buf[256], *path;
path = dentry_path(dev->heaps_debug_root, buf, 256);
pr_err("Failed to create heap debugfs at %s/%s\n",
- path, heap->name);
+ path, heap->name);
}
if (heap->shrinker.count_objects && heap->shrinker.scan_objects) {
@@ -1634,10 +1414,11 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
path = dentry_path(dev->heaps_debug_root, buf, 256);
pr_err("Failed to create heap shrinker debugfs at %s/%s\n",
- path, debug_name);
+ path, debug_name);
}
}
+ dev->heap_cnt++;
up_write(&dev->lock);
}
EXPORT_SYMBOL(ion_device_add_heap);
@@ -1702,38 +1483,3 @@ void ion_device_destroy(struct ion_device *dev)
kfree(dev);
}
EXPORT_SYMBOL(ion_device_destroy);
-
-void __init ion_reserve(struct ion_platform_data *data)
-{
- int i;
-
- for (i = 0; i < data->nr; i++) {
- if (data->heaps[i].size == 0)
- continue;
-
- if (data->heaps[i].base == 0) {
- phys_addr_t paddr;
-
- paddr = memblock_alloc_base(data->heaps[i].size,
- data->heaps[i].align,
- MEMBLOCK_ALLOC_ANYWHERE);
- if (!paddr) {
- pr_err("%s: error allocating memblock for heap %d\n",
- __func__, i);
- continue;
- }
- data->heaps[i].base = paddr;
- } else {
- int ret = memblock_reserve(data->heaps[i].base,
- data->heaps[i].size);
- if (ret)
- pr_err("memblock reserve of %zx@%lx failed\n",
- data->heaps[i].size,
- data->heaps[i].base);
- }
- pr_info("%s: %s reserved base %lx size %zu\n", __func__,
- data->heaps[i].name,
- data->heaps[i].base,
- data->heaps[i].size);
- }
-}
diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h
index a1331fc169a1..93dafb4586e4 100644
--- a/drivers/staging/android/ion/ion.h
+++ b/drivers/staging/android/ion/ion.h
@@ -73,17 +73,6 @@ struct ion_platform_data {
};
/**
- * ion_reserve() - reserve memory for ion heaps if applicable
- * @data: platform data specifying starting physical address and
- * size
- *
- * Calls memblock reserve to set aside memory for heaps that are
- * located at specific memory addresses or of specific sizes not
- * managed by the kernel
- */
-void ion_reserve(struct ion_platform_data *data);
-
-/**
* ion_client_create() - allocate a client and returns it
* @dev: the global ion device
* @name: used for debugging
@@ -130,36 +119,6 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
void ion_free(struct ion_client *client, struct ion_handle *handle);
/**
- * ion_phys - returns the physical address and len of a handle
- * @client: the client
- * @handle: the handle
- * @addr: a pointer to put the address in
- * @len: a pointer to put the length in
- *
- * This function queries the heap for a particular handle to get the
- * handle's physical address. It't output is only correct if
- * a heap returns physically contiguous memory -- in other cases
- * this api should not be implemented -- ion_sg_table should be used
- * instead. Returns -EINVAL if the handle is invalid. This has
- * no implications on the reference counting of the handle --
- * the returned value may not be valid if the caller is not
- * holding a reference.
- */
-int ion_phys(struct ion_client *client, struct ion_handle *handle,
- ion_phys_addr_t *addr, size_t *len);
-
-/**
- * ion_map_dma - return an sg_table describing a handle
- * @client: the client
- * @handle: the handle
- *
- * This function returns the sg_table describing
- * a particular ion handle.
- */
-struct sg_table *ion_sg_table(struct ion_client *client,
- struct ion_handle *handle);
-
-/**
* ion_map_kernel - create mapping for the given handle
* @client: the client
* @handle: handle to map
diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c
index 1fb0d81556da..a8ea97391c40 100644
--- a/drivers/staging/android/ion/ion_carveout_heap.c
+++ b/drivers/staging/android/ion/ion_carveout_heap.c
@@ -25,15 +25,17 @@
#include "ion.h"
#include "ion_priv.h"
+#define ION_CARVEOUT_ALLOCATE_FAIL -1
+
struct ion_carveout_heap {
struct ion_heap heap;
struct gen_pool *pool;
ion_phys_addr_t base;
};
-ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap,
- unsigned long size,
- unsigned long align)
+static ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap,
+ unsigned long size,
+ unsigned long align)
{
struct ion_carveout_heap *carveout_heap =
container_of(heap, struct ion_carveout_heap, heap);
@@ -45,8 +47,8 @@ ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap,
return offset;
}
-void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr,
- unsigned long size)
+static void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr,
+ unsigned long size)
{
struct ion_carveout_heap *carveout_heap =
container_of(heap, struct ion_carveout_heap, heap);
@@ -56,19 +58,6 @@ void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr,
gen_pool_free(carveout_heap->pool, addr, size);
}
-static int ion_carveout_heap_phys(struct ion_heap *heap,
- struct ion_buffer *buffer,
- ion_phys_addr_t *addr, size_t *len)
-{
- struct sg_table *table = buffer->priv_virt;
- struct page *page = sg_page(table->sgl);
- ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page));
-
- *addr = paddr;
- *len = buffer->size;
- return 0;
-}
-
static int ion_carveout_heap_allocate(struct ion_heap *heap,
struct ion_buffer *buffer,
unsigned long size, unsigned long align,
@@ -95,7 +84,7 @@ static int ion_carveout_heap_allocate(struct ion_heap *heap,
}
sg_set_page(table->sgl, pfn_to_page(PFN_DOWN(paddr)), size, 0);
- buffer->priv_virt = table;
+ buffer->sg_table = table;
return 0;
@@ -109,7 +98,7 @@ err_free:
static void ion_carveout_heap_free(struct ion_buffer *buffer)
{
struct ion_heap *heap = buffer->heap;
- struct sg_table *table = buffer->priv_virt;
+ struct sg_table *table = buffer->sg_table;
struct page *page = sg_page(table->sgl);
ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page));
@@ -124,23 +113,9 @@ static void ion_carveout_heap_free(struct ion_buffer *buffer)
kfree(table);
}
-static struct sg_table *ion_carveout_heap_map_dma(struct ion_heap *heap,
- struct ion_buffer *buffer)
-{
- return buffer->priv_virt;
-}
-
-static void ion_carveout_heap_unmap_dma(struct ion_heap *heap,
- struct ion_buffer *buffer)
-{
-}
-
static struct ion_heap_ops carveout_heap_ops = {
.allocate = ion_carveout_heap_allocate,
.free = ion_carveout_heap_free,
- .phys = ion_carveout_heap_phys,
- .map_dma = ion_carveout_heap_map_dma,
- .unmap_dma = ion_carveout_heap_unmap_dma,
.map_user = ion_heap_map_user,
.map_kernel = ion_heap_map_kernel,
.unmap_kernel = ion_heap_unmap_kernel,
diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c
index e0553fee9b8a..70495dc645ea 100644
--- a/drivers/staging/android/ion/ion_chunk_heap.c
+++ b/drivers/staging/android/ion/ion_chunk_heap.c
@@ -34,9 +34,9 @@ struct ion_chunk_heap {
};
static int ion_chunk_heap_allocate(struct ion_heap *heap,
- struct ion_buffer *buffer,
- unsigned long size, unsigned long align,
- unsigned long flags)
+ struct ion_buffer *buffer,
+ unsigned long size, unsigned long align,
+ unsigned long flags)
{
struct ion_chunk_heap *chunk_heap =
container_of(heap, struct ion_chunk_heap, heap);
@@ -71,11 +71,11 @@ static int ion_chunk_heap_allocate(struct ion_heap *heap,
if (!paddr)
goto err;
sg_set_page(sg, pfn_to_page(PFN_DOWN(paddr)),
- chunk_heap->chunk_size, 0);
+ chunk_heap->chunk_size, 0);
sg = sg_next(sg);
}
- buffer->priv_virt = table;
+ buffer->sg_table = table;
chunk_heap->allocated += allocated_size;
return 0;
err:
@@ -95,7 +95,7 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer)
struct ion_heap *heap = buffer->heap;
struct ion_chunk_heap *chunk_heap =
container_of(heap, struct ion_chunk_heap, heap);
- struct sg_table *table = buffer->priv_virt;
+ struct sg_table *table = buffer->sg_table;
struct scatterlist *sg;
int i;
unsigned long allocated_size;
@@ -106,7 +106,7 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer)
if (ion_buffer_cached(buffer))
dma_sync_sg_for_device(NULL, table->sgl, table->nents,
- DMA_BIDIRECTIONAL);
+ DMA_BIDIRECTIONAL);
for_each_sg(table->sgl, sg, table->nents, i) {
gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)),
@@ -117,22 +117,9 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer)
kfree(table);
}
-static struct sg_table *ion_chunk_heap_map_dma(struct ion_heap *heap,
- struct ion_buffer *buffer)
-{
- return buffer->priv_virt;
-}
-
-static void ion_chunk_heap_unmap_dma(struct ion_heap *heap,
- struct ion_buffer *buffer)
-{
-}
-
static struct ion_heap_ops chunk_heap_ops = {
.allocate = ion_chunk_heap_allocate,
.free = ion_chunk_heap_free,
- .map_dma = ion_chunk_heap_map_dma,
- .unmap_dma = ion_chunk_heap_unmap_dma,
.map_user = ion_heap_map_user,
.map_kernel = ion_heap_map_kernel,
.unmap_kernel = ion_heap_unmap_kernel,
@@ -174,7 +161,7 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data)
chunk_heap->heap.type = ION_HEAP_TYPE_CHUNK;
chunk_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE;
pr_debug("%s: base %lu size %zu align %ld\n", __func__,
- chunk_heap->base, heap_data->size, heap_data->align);
+ chunk_heap->base, heap_data->size, heap_data->align);
return &chunk_heap->heap;
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c
index a3446da4fdc2..6c7de74bc7ab 100644
--- a/drivers/staging/android/ion/ion_cma_heap.c
+++ b/drivers/staging/android/ion/ion_cma_heap.c
@@ -78,6 +78,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
goto free_table;
/* keep this for memory release */
buffer->priv_virt = info;
+ buffer->sg_table = info->table;
dev_dbg(dev, "Allocate buffer %p\n", buffer);
return 0;
@@ -105,36 +106,6 @@ static void ion_cma_free(struct ion_buffer *buffer)
kfree(info);
}
-/* return physical address in addr */
-static int ion_cma_phys(struct ion_heap *heap, struct ion_buffer *buffer,
- ion_phys_addr_t *addr, size_t *len)
-{
- struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap);
- struct device *dev = cma_heap->dev;
- struct ion_cma_buffer_info *info = buffer->priv_virt;
-
- dev_dbg(dev, "Return buffer %p physical address %pa\n", buffer,
- &info->handle);
-
- *addr = info->handle;
- *len = buffer->size;
-
- return 0;
-}
-
-static struct sg_table *ion_cma_heap_map_dma(struct ion_heap *heap,
- struct ion_buffer *buffer)
-{
- struct ion_cma_buffer_info *info = buffer->priv_virt;
-
- return info->table;
-}
-
-static void ion_cma_heap_unmap_dma(struct ion_heap *heap,
- struct ion_buffer *buffer)
-{
-}
-
static int ion_cma_mmap(struct ion_heap *mapper, struct ion_buffer *buffer,
struct vm_area_struct *vma)
{
@@ -155,16 +126,13 @@ static void *ion_cma_map_kernel(struct ion_heap *heap,
}
static void ion_cma_unmap_kernel(struct ion_heap *heap,
- struct ion_buffer *buffer)
+ struct ion_buffer *buffer)
{
}
static struct ion_heap_ops ion_cma_ops = {
.allocate = ion_cma_allocate,
.free = ion_cma_free,
- .map_dma = ion_cma_heap_map_dma,
- .unmap_dma = ion_cma_heap_unmap_dma,
- .phys = ion_cma_phys,
.map_user = ion_cma_mmap,
.map_kernel = ion_cma_map_kernel,
.unmap_kernel = ion_cma_unmap_kernel,
diff --git a/drivers/staging/android/ion/ion_dummy_driver.c b/drivers/staging/android/ion/ion_dummy_driver.c
index 814a3c92a56e..b23f2c76c753 100644
--- a/drivers/staging/android/ion/ion_dummy_driver.c
+++ b/drivers/staging/android/ion/ion_dummy_driver.c
@@ -99,7 +99,7 @@ static int __init ion_dummy_init(void)
struct ion_platform_heap *heap_data = &dummy_ion_pdata.heaps[i];
if (heap_data->type == ION_HEAP_TYPE_CARVEOUT &&
- !heap_data->base)
+ !heap_data->base)
continue;
if (heap_data->type == ION_HEAP_TYPE_CHUNK && !heap_data->base)
@@ -120,12 +120,12 @@ err:
if (carveout_ptr) {
free_pages_exact(carveout_ptr,
- dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size);
+ dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size);
carveout_ptr = NULL;
}
if (chunk_ptr) {
free_pages_exact(chunk_ptr,
- dummy_heaps[ION_HEAP_TYPE_CHUNK].size);
+ dummy_heaps[ION_HEAP_TYPE_CHUNK].size);
chunk_ptr = NULL;
}
return err;
@@ -144,12 +144,12 @@ static void __exit ion_dummy_exit(void)
if (carveout_ptr) {
free_pages_exact(carveout_ptr,
- dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size);
+ dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size);
carveout_ptr = NULL;
}
if (chunk_ptr) {
free_pages_exact(chunk_ptr,
- dummy_heaps[ION_HEAP_TYPE_CHUNK].size);
+ dummy_heaps[ION_HEAP_TYPE_CHUNK].size);
chunk_ptr = NULL;
}
}
diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c
index ca15a87f6fd3..4e5c0f17f579 100644
--- a/drivers/staging/android/ion/ion_heap.c
+++ b/drivers/staging/android/ion/ion_heap.c
@@ -93,7 +93,7 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
}
len = min(len, remainder);
ret = remap_pfn_range(vma, addr, page_to_pfn(page), len,
- vma->vm_page_prot);
+ vma->vm_page_prot);
if (ret)
return ret;
addr += len;
@@ -116,7 +116,7 @@ static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot)
}
static int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents,
- pgprot_t pgprot)
+ pgprot_t pgprot)
{
int p = 0;
int ret = 0;
@@ -181,7 +181,7 @@ size_t ion_heap_freelist_size(struct ion_heap *heap)
}
static size_t _ion_heap_freelist_drain(struct ion_heap *heap, size_t size,
- bool skip_pools)
+ bool skip_pools)
{
struct ion_buffer *buffer;
size_t total_drained = 0;
@@ -266,7 +266,7 @@ int ion_heap_init_deferred_free(struct ion_heap *heap)
}
static unsigned long ion_heap_shrink_count(struct shrinker *shrinker,
- struct shrink_control *sc)
+ struct shrink_control *sc)
{
struct ion_heap *heap = container_of(shrinker, struct ion_heap,
shrinker);
@@ -279,7 +279,7 @@ static unsigned long ion_heap_shrink_count(struct shrinker *shrinker,
}
static unsigned long ion_heap_shrink_scan(struct shrinker *shrinker,
- struct shrink_control *sc)
+ struct shrink_control *sc)
{
struct ion_heap *heap = container_of(shrinker, struct ion_heap,
shrinker);
diff --git a/drivers/staging/android/ion/ion_of.c b/drivers/staging/android/ion/ion_of.c
new file mode 100644
index 000000000000..15bac92b7f04
--- /dev/null
+++ b/drivers/staging/android/ion/ion_of.c
@@ -0,0 +1,185 @@
+/*
+ * Based on work from:
+ * Andrew Andrianov <andrew@ncrmnt.org>
+ * Google
+ * The Linux Foundation
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/cma.h>
+#include <linux/dma-contiguous.h>
+#include <linux/io.h>
+#include <linux/of_reserved_mem.h>
+#include "ion.h"
+#include "ion_priv.h"
+#include "ion_of.h"
+
+static int ion_parse_dt_heap_common(struct device_node *heap_node,
+ struct ion_platform_heap *heap,
+ struct ion_of_heap *compatible)
+{
+ int i;
+
+ for (i = 0; compatible[i].name; i++) {
+ if (of_device_is_compatible(heap_node, compatible[i].compat))
+ break;
+ }
+
+ if (!compatible[i].name)
+ return -ENODEV;
+
+ heap->id = compatible[i].heap_id;
+ heap->type = compatible[i].type;
+ heap->name = compatible[i].name;
+ heap->align = compatible[i].align;
+
+ /* Some kind of callback function pointer? */
+
+ pr_info("%s: id %d type %d name %s align %lx\n", __func__,
+ heap->id, heap->type, heap->name, heap->align);
+ return 0;
+}
+
+static int ion_setup_heap_common(struct platform_device *parent,
+ struct device_node *heap_node,
+ struct ion_platform_heap *heap)
+{
+ int ret = 0;
+
+ switch (heap->type) {
+ case ION_HEAP_TYPE_CARVEOUT:
+ case ION_HEAP_TYPE_CHUNK:
+ if (heap->base && heap->size)
+ return 0;
+
+ ret = of_reserved_mem_device_init(heap->priv);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+struct ion_platform_data *ion_parse_dt(struct platform_device *pdev,
+ struct ion_of_heap *compatible)
+{
+ int num_heaps, ret;
+ const struct device_node *dt_node = pdev->dev.of_node;
+ struct device_node *node;
+ struct ion_platform_heap *heaps;
+ struct ion_platform_data *data;
+ int i = 0;
+
+ num_heaps = of_get_available_child_count(dt_node);
+
+ if (!num_heaps)
+ return ERR_PTR(-EINVAL);
+
+ heaps = devm_kzalloc(&pdev->dev,
+ sizeof(struct ion_platform_heap) * num_heaps,
+ GFP_KERNEL);
+ if (!heaps)
+ return ERR_PTR(-ENOMEM);
+
+ data = devm_kzalloc(&pdev->dev, sizeof(struct ion_platform_data),
+ GFP_KERNEL);
+ if (!data)
+ return ERR_PTR(-ENOMEM);
+
+ for_each_available_child_of_node(dt_node, node) {
+ struct platform_device *heap_pdev;
+
+ ret = ion_parse_dt_heap_common(node, &heaps[i], compatible);
+ if (ret)
+ return ERR_PTR(ret);
+
+ heap_pdev = of_platform_device_create(node, heaps[i].name,
+ &pdev->dev);
+ if (!pdev)
+ return ERR_PTR(-ENOMEM);
+ heap_pdev->dev.platform_data = &heaps[i];
+
+ heaps[i].priv = &heap_pdev->dev;
+
+ ret = ion_setup_heap_common(pdev, node, &heaps[i]);
+ if (ret)
+ goto out_err;
+ i++;
+ }
+
+ data->heaps = heaps;
+ data->nr = num_heaps;
+ return data;
+
+out_err:
+ for ( ; i >= 0; i--)
+ if (heaps[i].priv)
+ of_device_unregister(to_platform_device(heaps[i].priv));
+
+ return ERR_PTR(ret);
+}
+
+void ion_destroy_platform_data(struct ion_platform_data *data)
+{
+ int i;
+
+ for (i = 0; i < data->nr; i++)
+ if (data->heaps[i].priv)
+ of_device_unregister(to_platform_device(
+ data->heaps[i].priv));
+}
+
+#ifdef CONFIG_OF_RESERVED_MEM
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_reserved_mem.h>
+
+static int rmem_ion_device_init(struct reserved_mem *rmem, struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct ion_platform_heap *heap = pdev->dev.platform_data;
+
+ heap->base = rmem->base;
+ heap->base = rmem->size;
+ pr_debug("%s: heap %s base %pa size %pa dev %p\n", __func__,
+ heap->name, &rmem->base, &rmem->size, dev);
+ return 0;
+}
+
+static void rmem_ion_device_release(struct reserved_mem *rmem,
+ struct device *dev)
+{
+ return;
+}
+
+static const struct reserved_mem_ops rmem_dma_ops = {
+ .device_init = rmem_ion_device_init,
+ .device_release = rmem_ion_device_release,
+};
+
+static int __init rmem_ion_setup(struct reserved_mem *rmem)
+{
+ phys_addr_t size = rmem->size;
+
+ size = size / 1024;
+
+ pr_info("Ion memory setup at %pa size %pa MiB\n",
+ &rmem->base, &size);
+ rmem->ops = &rmem_dma_ops;
+ return 0;
+}
+
+RESERVEDMEM_OF_DECLARE(ion, "ion-region", rmem_ion_setup);
+#endif
diff --git a/drivers/staging/android/ion/ion_of.h b/drivers/staging/android/ion/ion_of.h
new file mode 100644
index 000000000000..8241a1770f0a
--- /dev/null
+++ b/drivers/staging/android/ion/ion_of.h
@@ -0,0 +1,37 @@
+/*
+ * Based on work from:
+ * Andrew Andrianov <andrew@ncrmnt.org>
+ * Google
+ * The Linux Foundation
+ *
+ * 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.
+ */
+
+#ifndef _ION_OF_H
+#define _ION_OF_H
+
+struct ion_of_heap {
+ const char *compat;
+ int heap_id;
+ int type;
+ const char *name;
+ int align;
+};
+
+#define PLATFORM_HEAP(_compat, _id, _type, _name) \
+{ \
+ .compat = _compat, \
+ .heap_id = _id, \
+ .type = _type, \
+ .name = _name, \
+ .align = PAGE_SIZE, \
+}
+
+struct ion_platform_data *ion_parse_dt(struct platform_device *pdev,
+ struct ion_of_heap *compatible);
+
+void ion_destroy_platform_data(struct ion_platform_data *data);
+
+#endif
diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c
index 1fe80165a462..aea89c1ec345 100644
--- a/drivers/staging/android/ion/ion_page_pool.c
+++ b/drivers/staging/android/ion/ion_page_pool.c
@@ -30,8 +30,9 @@ static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool)
if (!page)
return NULL;
- ion_pages_sync_for_device(NULL, page, PAGE_SIZE << pool->order,
- DMA_BIDIRECTIONAL);
+ if (!pool->cached)
+ ion_pages_sync_for_device(NULL, page, PAGE_SIZE << pool->order,
+ DMA_BIDIRECTIONAL);
return page;
}
@@ -114,7 +115,7 @@ static int ion_page_pool_total(struct ion_page_pool *pool, bool high)
}
int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
- int nr_to_scan)
+ int nr_to_scan)
{
int freed = 0;
bool high;
@@ -147,7 +148,8 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
return freed;
}
-struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order)
+struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order,
+ bool cached)
{
struct ion_page_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL);
@@ -161,6 +163,8 @@ struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order)
pool->order = order;
mutex_init(&pool->mutex);
plist_node_init(&pool->list, order);
+ if (cached)
+ pool->cached = true;
return pool;
}
diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h
index 0239883bffb7..3c3b3245275d 100644
--- a/drivers/staging/android/ion/ion_priv.h
+++ b/drivers/staging/android/ion/ion_priv.h
@@ -26,11 +26,10 @@
#include <linux/sched.h>
#include <linux/shrinker.h>
#include <linux/types.h>
+#include <linux/miscdevice.h>
#include "ion.h"
-struct ion_buffer *ion_handle_buffer(struct ion_handle *handle);
-
/**
* struct ion_buffer - metadata for a particular buffer
* @ref: reference count
@@ -42,8 +41,6 @@ struct ion_buffer *ion_handle_buffer(struct ion_handle *handle);
* @size: size of the buffer
* @priv_virt: private data to the buffer representable as
* a void *
- * @priv_phys: private data to the buffer representable as
- * an ion_phys_addr_t (and someday a phys_addr_t)
* @lock: protects the buffers cnt fields
* @kmap_cnt: number of times the buffer is mapped to the kernel
* @vaddr: the kernel mapping if kmap_cnt is not zero
@@ -69,10 +66,7 @@ struct ion_buffer {
unsigned long flags;
unsigned long private_flags;
size_t size;
- union {
- void *priv_virt;
- ion_phys_addr_t priv_phys;
- };
+ void *priv_virt;
struct mutex lock;
int kmap_cnt;
void *vaddr;
@@ -88,13 +82,84 @@ struct ion_buffer {
void ion_buffer_destroy(struct ion_buffer *buffer);
/**
+ * struct ion_device - the metadata of the ion device node
+ * @dev: the actual misc device
+ * @buffers: an rb tree of all the existing buffers
+ * @buffer_lock: lock protecting the tree of buffers
+ * @lock: rwsem protecting the tree of heaps and clients
+ * @heaps: list of all the heaps in the system
+ * @user_clients: list of all the clients created from userspace
+ */
+struct ion_device {
+ struct miscdevice dev;
+ struct rb_root buffers;
+ struct mutex buffer_lock;
+ struct rw_semaphore lock;
+ struct plist_head heaps;
+ long (*custom_ioctl)(struct ion_client *client, unsigned int cmd,
+ unsigned long arg);
+ struct rb_root clients;
+ struct dentry *debug_root;
+ struct dentry *heaps_debug_root;
+ struct dentry *clients_debug_root;
+ int heap_cnt;
+};
+
+/**
+ * struct ion_client - a process/hw block local address space
+ * @node: node in the tree of all clients
+ * @dev: backpointer to ion device
+ * @handles: an rb tree of all the handles in this client
+ * @idr: an idr space for allocating handle ids
+ * @lock: lock protecting the tree of handles
+ * @name: used for debugging
+ * @display_name: used for debugging (unique version of @name)
+ * @display_serial: used for debugging (to make display_name unique)
+ * @task: used for debugging
+ *
+ * A client represents a list of buffers this client may access.
+ * The mutex stored here is used to protect both handles tree
+ * as well as the handles themselves, and should be held while modifying either.
+ */
+struct ion_client {
+ struct rb_node node;
+ struct ion_device *dev;
+ struct rb_root handles;
+ struct idr idr;
+ struct mutex lock;
+ const char *name;
+ char *display_name;
+ int display_serial;
+ struct task_struct *task;
+ pid_t pid;
+ struct dentry *debug_root;
+};
+
+/**
+ * ion_handle - a client local reference to a buffer
+ * @ref: reference count
+ * @client: back pointer to the client the buffer resides in
+ * @buffer: pointer to the buffer
+ * @node: node in the client's handle rbtree
+ * @kmap_cnt: count of times this client has mapped to kernel
+ * @id: client-unique id allocated by client->idr
+ *
+ * Modifications to node, map_cnt or mapping should be protected by the
+ * lock in the client. Other fields are never changed after initialization.
+ */
+struct ion_handle {
+ struct kref ref;
+ struct ion_client *client;
+ struct ion_buffer *buffer;
+ struct rb_node node;
+ unsigned int kmap_cnt;
+ int id;
+};
+
+/**
* struct ion_heap_ops - ops to operate on a given heap
* @allocate: allocate memory
* @free: free memory
- * @phys get physical address of a buffer (only define on
- * physically contiguous heaps)
- * @map_dma map the memory for dma to a scatterlist
- * @unmap_dma unmap the memory for dma
* @map_kernel map memory to the kernel
* @unmap_kernel unmap memory to the kernel
* @map_user map memory to userspace
@@ -111,11 +176,6 @@ struct ion_heap_ops {
struct ion_buffer *buffer, unsigned long len,
unsigned long align, unsigned long flags);
void (*free)(struct ion_buffer *buffer);
- int (*phys)(struct ion_heap *heap, struct ion_buffer *buffer,
- ion_phys_addr_t *addr, size_t *len);
- struct sg_table * (*map_dma)(struct ion_heap *heap,
- struct ion_buffer *buffer);
- void (*unmap_dma)(struct ion_heap *heap, struct ion_buffer *buffer);
void * (*map_kernel)(struct ion_heap *heap, struct ion_buffer *buffer);
void (*unmap_kernel)(struct ion_heap *heap, struct ion_buffer *buffer);
int (*map_user)(struct ion_heap *mapper, struct ion_buffer *buffer,
@@ -328,20 +388,6 @@ struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *);
void ion_cma_heap_destroy(struct ion_heap *);
/**
- * kernel api to allocate/free from carveout -- used when carveout is
- * used to back an architecture specific custom heap
- */
-ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap, unsigned long size,
- unsigned long align);
-void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr,
- unsigned long size);
-/**
- * The carveout heap returns physical addresses, since 0 may be a valid
- * physical address, this is used to indicate allocation failed
- */
-#define ION_CARVEOUT_ALLOCATE_FAIL -1
-
-/**
* functions for creating and destroying a heap pool -- allows you
* to keep a pool of pre allocated memory to use from your heap. Keeping
* a pool of memory that is ready for dma, ie any cached mapping have been
@@ -360,6 +406,7 @@ void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr,
* @gfp_mask: gfp_mask to use from alloc
* @order: order of pages in the pool
* @list: plist node for list of pools
+ * @cached: it's cached pool or not
*
* Allows you to keep a pool of pre allocated pages to use from your heap.
* Keeping a pool of pages that is ready for dma, ie any cached mapping have
@@ -369,6 +416,7 @@ void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr,
struct ion_page_pool {
int high_count;
int low_count;
+ bool cached;
struct list_head high_items;
struct list_head low_items;
struct mutex mutex;
@@ -377,7 +425,8 @@ struct ion_page_pool {
struct plist_node list;
};
-struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order);
+struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order,
+ bool cached);
void ion_page_pool_destroy(struct ion_page_pool *);
struct page *ion_page_pool_alloc(struct ion_page_pool *);
void ion_page_pool_free(struct ion_page_pool *, struct page *);
@@ -403,4 +452,22 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
void ion_pages_sync_for_device(struct device *dev, struct page *page,
size_t size, enum dma_data_direction dir);
+long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+
+int ion_sync_for_device(struct ion_client *client, int fd);
+
+struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client,
+ int id);
+
+void ion_free_nolock(struct ion_client *client, struct ion_handle *handle);
+
+int ion_handle_put_nolock(struct ion_handle *handle);
+
+struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
+ int id);
+
+int ion_handle_put(struct ion_handle *handle);
+
+int ion_query_heaps(struct ion_client *client, struct ion_heap_query *query);
+
#endif /* _ION_PRIV_H */
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
index b69dfc706440..7e023d505af8 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/ion/ion_system_heap.c
@@ -26,16 +26,18 @@
#include "ion.h"
#include "ion_priv.h"
+#define NUM_ORDERS ARRAY_SIZE(orders)
+
static gfp_t high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN |
__GFP_NORETRY) & ~__GFP_RECLAIM;
-static gfp_t low_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN);
+static gfp_t low_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO);
static const unsigned int orders[] = {8, 4, 0};
-static const int num_orders = ARRAY_SIZE(orders);
+
static int order_to_index(unsigned int order)
{
int i;
- for (i = 0; i < num_orders; i++)
+ for (i = 0; i < NUM_ORDERS; i++)
if (order == orders[i])
return i;
BUG();
@@ -49,47 +51,55 @@ static inline unsigned int order_to_size(int order)
struct ion_system_heap {
struct ion_heap heap;
- struct ion_page_pool *pools[0];
+ struct ion_page_pool *uncached_pools[NUM_ORDERS];
+ struct ion_page_pool *cached_pools[NUM_ORDERS];
};
+/**
+ * The page from page-pool are all zeroed before. We need do cache
+ * clean for cached buffer. The uncached buffer are always non-cached
+ * since it's allocated. So no need for non-cached pages.
+ */
static struct page *alloc_buffer_page(struct ion_system_heap *heap,
struct ion_buffer *buffer,
unsigned long order)
{
bool cached = ion_buffer_cached(buffer);
- struct ion_page_pool *pool = heap->pools[order_to_index(order)];
+ struct ion_page_pool *pool;
struct page *page;
- if (!cached) {
- page = ion_page_pool_alloc(pool);
- } else {
- gfp_t gfp_flags = low_order_gfp_flags;
+ if (!cached)
+ pool = heap->uncached_pools[order_to_index(order)];
+ else
+ pool = heap->cached_pools[order_to_index(order)];
- if (order > 4)
- gfp_flags = high_order_gfp_flags;
- page = alloc_pages(gfp_flags | __GFP_COMP, order);
- if (!page)
- return NULL;
- ion_pages_sync_for_device(NULL, page, PAGE_SIZE << order,
- DMA_BIDIRECTIONAL);
- }
+ page = ion_page_pool_alloc(pool);
+ if (cached)
+ ion_pages_sync_for_device(NULL, page, PAGE_SIZE << order,
+ DMA_BIDIRECTIONAL);
return page;
}
static void free_buffer_page(struct ion_system_heap *heap,
struct ion_buffer *buffer, struct page *page)
{
+ struct ion_page_pool *pool;
unsigned int order = compound_order(page);
bool cached = ion_buffer_cached(buffer);
- if (!cached && !(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE)) {
- struct ion_page_pool *pool = heap->pools[order_to_index(order)];
-
- ion_page_pool_free(pool, page);
- } else {
+ /* go to system */
+ if (buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE) {
__free_pages(page, order);
+ return;
}
+
+ if (!cached)
+ pool = heap->uncached_pools[order_to_index(order)];
+ else
+ pool = heap->cached_pools[order_to_index(order)];
+
+ ion_page_pool_free(pool, page);
}
@@ -101,7 +111,7 @@ static struct page *alloc_largest_available(struct ion_system_heap *heap,
struct page *page;
int i;
- for (i = 0; i < num_orders; i++) {
+ for (i = 0; i < NUM_ORDERS; i++) {
if (size < order_to_size(orders[i]))
continue;
if (max_order < orders[i])
@@ -118,9 +128,9 @@ static struct page *alloc_largest_available(struct ion_system_heap *heap,
}
static int ion_system_heap_allocate(struct ion_heap *heap,
- struct ion_buffer *buffer,
- unsigned long size, unsigned long align,
- unsigned long flags)
+ struct ion_buffer *buffer,
+ unsigned long size, unsigned long align,
+ unsigned long flags)
{
struct ion_system_heap *sys_heap = container_of(heap,
struct ion_system_heap,
@@ -142,7 +152,7 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
INIT_LIST_HEAD(&pages);
while (size_remaining > 0) {
page = alloc_largest_available(sys_heap, buffer, size_remaining,
- max_order);
+ max_order);
if (!page)
goto free_pages;
list_add_tail(&page->lru, &pages);
@@ -164,7 +174,7 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
list_del(&page->lru);
}
- buffer->priv_virt = table;
+ buffer->sg_table = table;
return 0;
free_table:
@@ -181,16 +191,11 @@ static void ion_system_heap_free(struct ion_buffer *buffer)
struct ion_system_heap,
heap);
struct sg_table *table = buffer->sg_table;
- bool cached = ion_buffer_cached(buffer);
struct scatterlist *sg;
int i;
- /*
- * uncached pages come from the page pools, zero them before returning
- * for security purposes (other allocations are zerod at
- * alloc time
- */
- if (!cached && !(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE))
+ /* zero the buffer before goto page pool */
+ if (!(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE))
ion_heap_buffer_zero(buffer);
for_each_sg(table->sgl, sg, table->nents, i)
@@ -199,20 +204,11 @@ static void ion_system_heap_free(struct ion_buffer *buffer)
kfree(table);
}
-static struct sg_table *ion_system_heap_map_dma(struct ion_heap *heap,
- struct ion_buffer *buffer)
-{
- return buffer->priv_virt;
-}
-
-static void ion_system_heap_unmap_dma(struct ion_heap *heap,
- struct ion_buffer *buffer)
-{
-}
-
static int ion_system_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask,
- int nr_to_scan)
+ int nr_to_scan)
{
+ struct ion_page_pool *uncached_pool;
+ struct ion_page_pool *cached_pool;
struct ion_system_heap *sys_heap;
int nr_total = 0;
int i, nr_freed;
@@ -223,28 +219,41 @@ static int ion_system_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask,
if (!nr_to_scan)
only_scan = 1;
- for (i = 0; i < num_orders; i++) {
- struct ion_page_pool *pool = sys_heap->pools[i];
-
- nr_freed = ion_page_pool_shrink(pool, gfp_mask, nr_to_scan);
- nr_total += nr_freed;
-
- if (!only_scan) {
+ for (i = 0; i < NUM_ORDERS; i++) {
+ uncached_pool = sys_heap->uncached_pools[i];
+ cached_pool = sys_heap->cached_pools[i];
+
+ if (only_scan) {
+ nr_total += ion_page_pool_shrink(uncached_pool,
+ gfp_mask,
+ nr_to_scan);
+
+ nr_total += ion_page_pool_shrink(cached_pool,
+ gfp_mask,
+ nr_to_scan);
+ } else {
+ nr_freed = ion_page_pool_shrink(uncached_pool,
+ gfp_mask,
+ nr_to_scan);
+ nr_to_scan -= nr_freed;
+ nr_total += nr_freed;
+ if (nr_to_scan <= 0)
+ break;
+ nr_freed = ion_page_pool_shrink(cached_pool,
+ gfp_mask,
+ nr_to_scan);
nr_to_scan -= nr_freed;
- /* shrink completed */
+ nr_total += nr_freed;
if (nr_to_scan <= 0)
break;
}
}
-
return nr_total;
}
static struct ion_heap_ops system_heap_ops = {
.allocate = ion_system_heap_allocate,
.free = ion_system_heap_free,
- .map_dma = ion_system_heap_map_dma,
- .unmap_dma = ion_system_heap_unmap_dma,
.map_kernel = ion_heap_map_kernel,
.unmap_kernel = ion_heap_unmap_kernel,
.map_user = ion_heap_map_user,
@@ -259,52 +268,89 @@ static int ion_system_heap_debug_show(struct ion_heap *heap, struct seq_file *s,
struct ion_system_heap,
heap);
int i;
+ struct ion_page_pool *pool;
+
+ for (i = 0; i < NUM_ORDERS; i++) {
+ pool = sys_heap->uncached_pools[i];
+
+ seq_printf(s, "%d order %u highmem pages uncached %lu total\n",
+ pool->high_count, pool->order,
+ (PAGE_SIZE << pool->order) * pool->high_count);
+ seq_printf(s, "%d order %u lowmem pages uncached %lu total\n",
+ pool->low_count, pool->order,
+ (PAGE_SIZE << pool->order) * pool->low_count);
+ }
- for (i = 0; i < num_orders; i++) {
- struct ion_page_pool *pool = sys_heap->pools[i];
+ for (i = 0; i < NUM_ORDERS; i++) {
+ pool = sys_heap->cached_pools[i];
- seq_printf(s, "%d order %u highmem pages in pool = %lu total\n",
+ seq_printf(s, "%d order %u highmem pages cached %lu total\n",
pool->high_count, pool->order,
(PAGE_SIZE << pool->order) * pool->high_count);
- seq_printf(s, "%d order %u lowmem pages in pool = %lu total\n",
+ seq_printf(s, "%d order %u lowmem pages cached %lu total\n",
pool->low_count, pool->order,
(PAGE_SIZE << pool->order) * pool->low_count);
}
return 0;
}
+static void ion_system_heap_destroy_pools(struct ion_page_pool **pools)
+{
+ int i;
+
+ for (i = 0; i < NUM_ORDERS; i++)
+ if (pools[i])
+ ion_page_pool_destroy(pools[i]);
+}
+
+static int ion_system_heap_create_pools(struct ion_page_pool **pools,
+ bool cached)
+{
+ int i;
+ gfp_t gfp_flags = low_order_gfp_flags;
+
+ for (i = 0; i < NUM_ORDERS; i++) {
+ struct ion_page_pool *pool;
+
+ if (orders[i] > 4)
+ gfp_flags = high_order_gfp_flags;
+
+ pool = ion_page_pool_create(gfp_flags, orders[i], cached);
+ if (!pool)
+ goto err_create_pool;
+ pools[i] = pool;
+ }
+ return 0;
+
+err_create_pool:
+ ion_system_heap_destroy_pools(pools);
+ return -ENOMEM;
+}
+
struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
{
struct ion_system_heap *heap;
- int i;
- heap = kzalloc(sizeof(struct ion_system_heap) +
- sizeof(struct ion_page_pool *) * num_orders,
- GFP_KERNEL);
+ heap = kzalloc(sizeof(*heap), GFP_KERNEL);
if (!heap)
return ERR_PTR(-ENOMEM);
heap->heap.ops = &system_heap_ops;
heap->heap.type = ION_HEAP_TYPE_SYSTEM;
heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE;
- for (i = 0; i < num_orders; i++) {
- struct ion_page_pool *pool;
- gfp_t gfp_flags = low_order_gfp_flags;
+ if (ion_system_heap_create_pools(heap->uncached_pools, false))
+ goto free_heap;
- if (orders[i] > 4)
- gfp_flags = high_order_gfp_flags;
- pool = ion_page_pool_create(gfp_flags, orders[i]);
- if (!pool)
- goto destroy_pools;
- heap->pools[i] = pool;
- }
+ if (ion_system_heap_create_pools(heap->cached_pools, true))
+ goto destroy_uncached_pools;
heap->heap.debug_show = ion_system_heap_debug_show;
return &heap->heap;
-destroy_pools:
- while (i--)
- ion_page_pool_destroy(heap->pools[i]);
+destroy_uncached_pools:
+ ion_system_heap_destroy_pools(heap->uncached_pools);
+
+free_heap:
kfree(heap);
return ERR_PTR(-ENOMEM);
}
@@ -316,8 +362,10 @@ void ion_system_heap_destroy(struct ion_heap *heap)
heap);
int i;
- for (i = 0; i < num_orders; i++)
- ion_page_pool_destroy(sys_heap->pools[i]);
+ for (i = 0; i < NUM_ORDERS; i++) {
+ ion_page_pool_destroy(sys_heap->uncached_pools[i]);
+ ion_page_pool_destroy(sys_heap->cached_pools[i]);
+ }
kfree(sys_heap);
}
@@ -358,7 +406,7 @@ static int ion_system_contig_heap_allocate(struct ion_heap *heap,
sg_set_page(table->sgl, page, len, 0);
- buffer->priv_virt = table;
+ buffer->sg_table = table;
ion_pages_sync_for_device(NULL, page, len, DMA_BIDIRECTIONAL);
@@ -375,7 +423,7 @@ free_pages:
static void ion_system_contig_heap_free(struct ion_buffer *buffer)
{
- struct sg_table *table = buffer->priv_virt;
+ struct sg_table *table = buffer->sg_table;
struct page *page = sg_page(table->sgl);
unsigned long pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT;
unsigned long i;
@@ -386,34 +434,9 @@ static void ion_system_contig_heap_free(struct ion_buffer *buffer)
kfree(table);
}
-static int ion_system_contig_heap_phys(struct ion_heap *heap,
- struct ion_buffer *buffer,
- ion_phys_addr_t *addr, size_t *len)
-{
- struct sg_table *table = buffer->priv_virt;
- struct page *page = sg_page(table->sgl);
- *addr = page_to_phys(page);
- *len = buffer->size;
- return 0;
-}
-
-static struct sg_table *ion_system_contig_heap_map_dma(struct ion_heap *heap,
- struct ion_buffer *buffer)
-{
- return buffer->priv_virt;
-}
-
-static void ion_system_contig_heap_unmap_dma(struct ion_heap *heap,
- struct ion_buffer *buffer)
-{
-}
-
static struct ion_heap_ops kmalloc_ops = {
.allocate = ion_system_contig_heap_allocate,
.free = ion_system_contig_heap_free,
- .phys = ion_system_contig_heap_phys,
- .map_dma = ion_system_contig_heap_map_dma,
- .unmap_dma = ion_system_contig_heap_unmap_dma,
.map_kernel = ion_heap_map_kernel,
.unmap_kernel = ion_heap_unmap_kernel,
.map_user = ion_heap_map_user,
diff --git a/drivers/staging/android/ion/ion_test.c b/drivers/staging/android/ion/ion_test.c
index 5a396a1a8238..5abf8320a96a 100644
--- a/drivers/staging/android/ion/ion_test.c
+++ b/drivers/staging/android/ion/ion_test.c
@@ -42,7 +42,8 @@ struct ion_test_data {
};
static int ion_handle_test_dma(struct device *dev, struct dma_buf *dma_buf,
- void __user *ptr, size_t offset, size_t size, bool write)
+ void __user *ptr, size_t offset, size_t size,
+ bool write)
{
int ret = 0;
struct dma_buf_attachment *attach;
@@ -98,7 +99,7 @@ err:
}
static int ion_handle_test_kernel(struct dma_buf *dma_buf, void __user *ptr,
- size_t offset, size_t size, bool write)
+ size_t offset, size_t size, bool write)
{
int ret;
unsigned long page_offset = offset >> PAGE_SHIFT;
@@ -144,7 +145,7 @@ err:
}
static long ion_test_ioctl(struct file *filp, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
struct ion_test_data *test_data = filp->private_data;
int ret = 0;
@@ -179,17 +180,19 @@ static long ion_test_ioctl(struct file *filp, unsigned int cmd,
case ION_IOC_TEST_DMA_MAPPING:
{
ret = ion_handle_test_dma(test_data->dev, test_data->dma_buf,
- u64_to_uptr(data.test_rw.ptr),
- data.test_rw.offset, data.test_rw.size,
- data.test_rw.write);
+ u64_to_uptr(data.test_rw.ptr),
+ data.test_rw.offset,
+ data.test_rw.size,
+ data.test_rw.write);
break;
}
case ION_IOC_TEST_KERNEL_MAPPING:
{
ret = ion_handle_test_kernel(test_data->dma_buf,
- u64_to_uptr(data.test_rw.ptr),
- data.test_rw.offset, data.test_rw.size,
- data.test_rw.write);
+ u64_to_uptr(data.test_rw.ptr),
+ data.test_rw.offset,
+ data.test_rw.size,
+ data.test_rw.write);
break;
}
default:
@@ -242,7 +245,7 @@ static int __init ion_test_probe(struct platform_device *pdev)
struct ion_test_device *testdev;
testdev = devm_kzalloc(&pdev->dev, sizeof(struct ion_test_device),
- GFP_KERNEL);
+ GFP_KERNEL);
if (!testdev)
return -ENOMEM;
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 45a1b4ec4ca3..ec3b66561412 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -92,8 +92,8 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
int array_size = ARRAY_SIZE(lowmem_adj);
int other_free = global_page_state(NR_FREE_PAGES) - totalreserve_pages;
int other_file = global_node_page_state(NR_FILE_PAGES) -
- global_node_page_state(NR_SHMEM) -
- total_swapcache_pages();
+ global_node_page_state(NR_SHMEM) -
+ total_swapcache_pages();
if (lowmem_adj_size < array_size)
array_size = lowmem_adj_size;
@@ -204,10 +204,9 @@ device_initcall(lowmem_init);
* not really modular, but the easiest way to keep compat with existing
* bootargs behaviour is to continue using module_param here.
*/
-module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
-module_param_array_named(adj, lowmem_adj, short, &lowmem_adj_size,
- S_IRUGO | S_IWUSR);
+module_param_named(cost, lowmem_shrinker.seeks, int, 0644);
+module_param_array_named(adj, lowmem_adj, short, &lowmem_adj_size, 0644);
module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
- S_IRUGO | S_IWUSR);
-module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR);
+ 0644);
+module_param_named(debug_level, lowmem_debug_level, uint, 0644);
diff --git a/drivers/staging/android/uapi/ion.h b/drivers/staging/android/uapi/ion.h
index 0a8e40f92cd7..14cd8738ecfc 100644
--- a/drivers/staging/android/uapi/ion.h
+++ b/drivers/staging/android/uapi/ion.h
@@ -44,32 +44,26 @@ enum ion_heap_type {
* must be last so device specific heaps always
* are at the end of this enum
*/
- ION_NUM_HEAPS = 16,
};
-#define ION_HEAP_SYSTEM_MASK (1 << ION_HEAP_TYPE_SYSTEM)
-#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG)
-#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT)
-#define ION_HEAP_TYPE_DMA_MASK (1 << ION_HEAP_TYPE_DMA)
-
#define ION_NUM_HEAP_IDS (sizeof(unsigned int) * 8)
/**
* allocation flags - the lower 16 bits are used by core ion, the upper 16
* bits are reserved for use by the heaps themselves.
*/
-#define ION_FLAG_CACHED 1 /*
- * mappings of this buffer should be
- * cached, ion will do cache
- * maintenance when the buffer is
- * mapped for dma
- */
-#define ION_FLAG_CACHED_NEEDS_SYNC 2 /*
- * mappings of this buffer will created
- * at mmap time, if this is set
- * caches must be managed
- * manually
- */
+
+/*
+ * mappings of this buffer should be cached, ion will do cache maintenance
+ * when the buffer is mapped for dma
+ */
+#define ION_FLAG_CACHED 1
+
+/*
+ * mappings of this buffer will created at mmap time, if this is set
+ * caches must be managed manually
+ */
+#define ION_FLAG_CACHED_NEEDS_SYNC 2
/**
* DOC: Ion Userspace API
@@ -134,6 +128,36 @@ struct ion_custom_data {
unsigned long arg;
};
+#define MAX_HEAP_NAME 32
+
+/**
+ * struct ion_heap_data - data about a heap
+ * @name - first 32 characters of the heap name
+ * @type - heap type
+ * @heap_id - heap id for the heap
+ */
+struct ion_heap_data {
+ char name[MAX_HEAP_NAME];
+ __u32 type;
+ __u32 heap_id;
+ __u32 reserved0;
+ __u32 reserved1;
+ __u32 reserved2;
+};
+
+/**
+ * struct ion_heap_query - collection of data about all heaps
+ * @cnt - total number of heaps to be copied
+ * @heaps - buffer to copy heap data
+ */
+struct ion_heap_query {
+ __u32 cnt; /* Total number of heaps to be copied */
+ __u32 reserved0; /* align to 64bits */
+ __u64 heaps; /* buffer to be populated */
+ __u32 reserved1;
+ __u32 reserved2;
+};
+
#define ION_IOC_MAGIC 'I'
/**
@@ -200,4 +224,13 @@ struct ion_custom_data {
*/
#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data)
+/**
+ * DOC: ION_IOC_HEAP_QUERY - information about available heaps
+ *
+ * Takes an ion_heap_query structure and populates information about
+ * available Ion heaps.
+ */
+#define ION_IOC_HEAP_QUERY _IOWR(ION_IOC_MAGIC, 8, \
+ struct ion_heap_query)
+
#endif /* _UAPI_LINUX_ION_H */
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 1999eed4f4c5..64b3966c5f1f 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -81,20 +81,20 @@ struct comedi_file {
(COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS)
static int comedi_num_legacy_minors;
-module_param(comedi_num_legacy_minors, int, S_IRUGO);
+module_param(comedi_num_legacy_minors, int, 0444);
MODULE_PARM_DESC(comedi_num_legacy_minors,
"number of comedi minor devices to reserve for non-auto-configured devices (default 0)"
);
unsigned int comedi_default_buf_size_kb = CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB;
-module_param(comedi_default_buf_size_kb, uint, S_IRUGO | S_IWUSR);
+module_param(comedi_default_buf_size_kb, uint, 0644);
MODULE_PARM_DESC(comedi_default_buf_size_kb,
"default asynchronous buffer size in KiB (default "
__MODULE_STRING(CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB) ")");
unsigned int comedi_default_buf_maxsize_kb
= CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB;
-module_param(comedi_default_buf_maxsize_kb, uint, S_IRUGO | S_IWUSR);
+module_param(comedi_default_buf_maxsize_kb, uint, 0644);
MODULE_PARM_DESC(comedi_default_buf_maxsize_kb,
"default maximum size of asynchronous buffer in KiB (default "
__MODULE_STRING(CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB) ")");
@@ -2233,7 +2233,7 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
goto done;
}
- n_pages = size >> PAGE_SHIFT;
+ n_pages = vma_pages(vma);
/* get reference to current buf map (if any) */
bm = comedi_buf_map_from_subdev_get(s);
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 44511d729450..a5bf2cc165c0 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -15,7 +15,7 @@
* 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.
-*/
+ */
#include <linux/device.h>
#include <linux/module.h>
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
deleted file mode 100644
index 375707497896..000000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* Watchdog Related Defines */
-
-#define ADDIDATA_TIMER 0
-#define ADDIDATA_WATCHDOG 2
-
-/*
- * (*insn_config) for the timer subdevice
- *
- * Configures The Timer, Counter or Watchdog
- * Data Pointer contains configuration parameters as below
- * data[0] : 0 Configure As Timer
- * 1 Configure As Counter
- * 2 Configure As Watchdog
- * data[1] : 1 Enable Interrupt
- * 0 Disable Interrupt
- * data[2] : Time Unit
- * data[3] : Reload Value
- */
-static int apci3501_config_insn_timer(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci3501_private *devpriv = dev->private;
- unsigned int ctrl;
-
- if (data[0] != ADDIDATA_WATCHDOG &&
- data[0] != ADDIDATA_TIMER)
- return -EINVAL;
-
- devpriv->tsk_Current = current;
-
- devpriv->timer_mode = data[0];
-
- /* first, disable the watchdog or stop the timer */
- if (devpriv->timer_mode == ADDIDATA_WATCHDOG) {
- ctrl = 0;
- } else {
- ctrl = inl(devpriv->tcw + ADDI_TCW_CTRL_REG);
- ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG |
- ADDI_TCW_CTRL_ENA);
- }
- outl(ctrl, devpriv->tcw + ADDI_TCW_CTRL_REG);
-
- /* enable/disable the timer interrupt */
- ctrl = (data[1] == 1) ? ADDI_TCW_CTRL_IRQ_ENA : 0;
- outl(ctrl, devpriv->tcw + ADDI_TCW_CTRL_REG);
-
- outl(data[2], devpriv->tcw + ADDI_TCW_TIMEBASE_REG);
- outl(data[3], devpriv->tcw + ADDI_TCW_RELOAD_REG);
-
- ctrl = inl(devpriv->tcw + ADDI_TCW_CTRL_REG);
- if (devpriv->timer_mode == ADDIDATA_WATCHDOG) {
- /* Set the mode (e2->e0) NOTE: this doesn't look correct */
- ctrl |= ~(ADDI_TCW_CTRL_CNT_UP | ADDI_TCW_CTRL_EXT_CLK_MASK |
- ADDI_TCW_CTRL_MODE_MASK | ADDI_TCW_CTRL_GATE |
- ADDI_TCW_CTRL_TRIG | ADDI_TCW_CTRL_TIMER_ENA |
- ADDI_TCW_CTRL_RESET_ENA | ADDI_TCW_CTRL_WARN_ENA |
- ADDI_TCW_CTRL_IRQ_ENA | ADDI_TCW_CTRL_ENA);
- } else {
- /* mode 2 */
- ctrl &= ~(ADDI_TCW_CTRL_CNTR_ENA | ADDI_TCW_CTRL_MODE_MASK |
- ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG |
- ADDI_TCW_CTRL_TIMER_ENA | ADDI_TCW_CTRL_RESET_ENA |
- ADDI_TCW_CTRL_WARN_ENA | ADDI_TCW_CTRL_ENA);
- ctrl |= ADDI_TCW_CTRL_MODE(2) | ADDI_TCW_CTRL_TIMER_ENA;
- }
- outl(ctrl, devpriv->tcw + ADDI_TCW_CTRL_REG);
-
- return insn->n;
-}
-
-/*
- * (*insn_write) for the timer subdevice
- *
- * Start / Stop The Selected Timer , Counter or Watchdog
- * Data Pointer contains configuration parameters as below
- * data[0] : 0 Timer
- * 1 Counter
- * 2 Watchdog
- * data[1] : 1 Start
- * 0 Stop
- * 2 Trigger
- */
-static int apci3501_write_insn_timer(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci3501_private *devpriv = dev->private;
- unsigned int ctrl;
-
- if (devpriv->timer_mode == ADDIDATA_WATCHDOG ||
- devpriv->timer_mode == ADDIDATA_TIMER) {
- ctrl = inl(devpriv->tcw + ADDI_TCW_CTRL_REG);
- ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG);
-
- if (data[1] == 1) { /* enable */
- ctrl |= ADDI_TCW_CTRL_ENA;
- } else if (data[1] == 0) { /* stop */
- if (devpriv->timer_mode == ADDIDATA_WATCHDOG)
- ctrl = 0;
- else
- ctrl &= ~ADDI_TCW_CTRL_ENA;
- } else if (data[1] == 2) { /* trigger */
- ctrl |= ADDI_TCW_CTRL_TRIG;
- }
- outl(ctrl, devpriv->tcw + ADDI_TCW_CTRL_REG);
- }
-
- inl(devpriv->tcw + ADDI_TCW_STATUS_REG);
- return insn->n;
-}
-
-/*
- * (*insn_read) for the timer subdevice
- *
- * Read The Selected Timer, Counter or Watchdog
- * Data Pointer contains configuration parameters as below
- * data[0] : 0 Timer
- * 1 Counter
- * 2 Watchdog
- * data[1] : Timer Counter Watchdog Number
- */
-static int apci3501_read_insn_timer(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci3501_private *devpriv = dev->private;
-
- if (devpriv->timer_mode != ADDIDATA_TIMER &&
- devpriv->timer_mode != ADDIDATA_WATCHDOG)
- return -EINVAL;
-
- data[0] = inl(devpriv->tcw + ADDI_TCW_STATUS_REG) &
- ADDI_TCW_STATUS_OVERFLOW;
- data[1] = inl(devpriv->tcw + ADDI_TCW_VAL_REG);
-
- return insn->n;
-}
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c
index 40ff91411139..57f0f46de0be 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3501.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3501.c
@@ -22,12 +22,36 @@
* more details.
*/
+/*
+ * Driver: addi_apci_3501
+ * Description: ADDI-DATA APCI-3501 Analog output board
+ * Devices: [ADDI-DATA] APCI-3501 (addi_apci_3501)
+ * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
+ * Updated: Mon, 20 Jun 2016 10:57:01 -0700
+ * Status: untested
+ *
+ * Configuration Options: not applicable, uses comedi PCI auto config
+ *
+ * This board has the following features:
+ * - 4 or 8 analog output channels
+ * - 2 optically isolated digital inputs
+ * - 2 optically isolated digital outputs
+ * - 1 12-bit watchdog/timer
+ *
+ * There are 2 versions of the APCI-3501:
+ * - APCI-3501-4 4 analog output channels
+ * - APCI-3501-8 8 analog output channels
+ *
+ * These boards use the same PCI Vendor/Device IDs. The number of output
+ * channels used by this driver is determined by reading the EEPROM on
+ * the board.
+ *
+ * The watchdog/timer subdevice is not currently supported.
+ */
+
#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
#include "../comedi_pci.h"
-#include "addi_tcw.h"
#include "amcc_s5933.h"
/*
@@ -67,8 +91,6 @@
struct apci3501_private {
unsigned long amcc;
- unsigned long tcw;
- struct task_struct *tsk_Current;
unsigned char timer_mode;
};
@@ -139,8 +161,6 @@ static int apci3501_ao_insn_write(struct comedi_device *dev,
return insn->n;
}
-#include "addi-data/hwdrv_apci3501.c"
-
static int apci3501_di_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
@@ -253,37 +273,6 @@ static int apci3501_eeprom_insn_read(struct comedi_device *dev,
return insn->n;
}
-static irqreturn_t apci3501_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct apci3501_private *devpriv = dev->private;
- unsigned int status;
- unsigned int ctrl;
-
- /* Disable Interrupt */
- ctrl = inl(devpriv->tcw + ADDI_TCW_CTRL_REG);
- ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG |
- ADDI_TCW_CTRL_IRQ_ENA);
- outl(ctrl, devpriv->tcw + ADDI_TCW_CTRL_REG);
-
- status = inl(devpriv->tcw + ADDI_TCW_IRQ_REG);
- if (!(status & ADDI_TCW_IRQ)) {
- dev_err(dev->class_dev, "IRQ from unknown source\n");
- return IRQ_NONE;
- }
-
- /* Enable Interrupt Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
- ctrl = inl(devpriv->tcw + ADDI_TCW_CTRL_REG);
- ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG |
- ADDI_TCW_CTRL_IRQ_ENA);
- ctrl |= ADDI_TCW_CTRL_IRQ_ENA;
- outl(ctrl, devpriv->tcw + ADDI_TCW_CTRL_REG);
- inl(devpriv->tcw + ADDI_TCW_STATUS_REG);
-
- return IRQ_HANDLED;
-}
-
static int apci3501_reset(struct comedi_device *dev)
{
unsigned int val;
@@ -333,17 +322,9 @@ static int apci3501_auto_attach(struct comedi_device *dev,
devpriv->amcc = pci_resource_start(pcidev, 0);
dev->iobase = pci_resource_start(pcidev, 1);
- devpriv->tcw = dev->iobase + APCI3501_TIMER_BASE;
ao_n_chan = apci3501_eeprom_get_ao_n_chan(dev);
- if (pcidev->irq > 0) {
- ret = request_irq(pcidev->irq, apci3501_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = pcidev->irq;
- }
-
ret = comedi_alloc_subdevices(dev, 5);
if (ret)
return ret;
@@ -383,17 +364,9 @@ static int apci3501_auto_attach(struct comedi_device *dev,
s->range_table = &range_digital;
s->insn_bits = apci3501_do_insn_bits;
- /* Initialize the timer/watchdog subdevice */
+ /* Timer/Watchdog subdevice */
s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_TIMER;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 1;
- s->maxdata = 0;
- s->len_chanlist = 1;
- s->range_table = &range_digital;
- s->insn_write = apci3501_write_insn_timer;
- s->insn_read = apci3501_read_insn_timer;
- s->insn_config = apci3501_config_insn_timer;
+ s->type = COMEDI_SUBD_UNUSED;
/* Initialize the eeprom subdevice */
s = &dev->subdevices[4];
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index be70bd333807..86450c08f291 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -1693,8 +1693,7 @@ static void pci9118_detach(struct comedi_device *dev)
pci9118_reset(dev);
comedi_pci_detach(dev);
pci9118_free_dma(dev);
- if (pcidev)
- pci_dev_put(pcidev);
+ pci_dev_put(pcidev);
}
static struct comedi_driver adl_pci9118_driver = {
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
index 1f9c08a845b6..cb9c2699277e 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -1,34 +1,34 @@
/*
- comedi/drivers/cb_pcidas64.c
- This is a driver for the ComputerBoards/MeasurementComputing PCI-DAS
- 64xx, 60xx, and 4020 cards.
-
- Author: Frank Mori Hess <fmhess@users.sourceforge.net>
- Copyright (C) 2001, 2002 Frank Mori Hess
-
- Thanks also go to the following people:
-
- Steve Rosenbluth, for providing the source code for
- his pci-das6402 driver, and source code for working QNX pci-6402
- drivers by Greg Laird and Mariusz Bogacz. None of the code was
- used directly here, but it was useful as an additional source of
- documentation on how to program the boards.
-
- John Sims, for much testing and feedback on pcidas-4020 support.
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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.
-*/
+ * comedi/drivers/cb_pcidas64.c
+ * This is a driver for the ComputerBoards/MeasurementComputing PCI-DAS
+ * 64xx, 60xx, and 4020 cards.
+ *
+ * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+ * Copyright (C) 2001, 2002 Frank Mori Hess
+ *
+ * Thanks also go to the following people:
+ *
+ * Steve Rosenbluth, for providing the source code for
+ * his pci-das6402 driver, and source code for working QNX pci-6402
+ * drivers by Greg Laird and Mariusz Bogacz. None of the code was
+ * used directly here, but it was useful as an additional source of
+ * documentation on how to program the boards.
+ *
+ * John Sims, for much testing and feedback on pcidas-4020 support.
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
/*
* Driver: cb_pcidas64
@@ -66,19 +66,18 @@
*/
/*
-
-TODO:
- make it return error if user attempts an ai command that uses the
- external queue, and an ao command simultaneously user counter subdevice
- there are a number of boards this driver will support when they are
- fully released, but does not yet since the pci device id numbers
- are not yet available.
-
- support prescaled 100khz clock for slow pacing (not available on 6000
- series?)
-
- make ao fifo size adjustable like ai fifo
-*/
+ * TODO:
+ * make it return error if user attempts an ai command that uses the
+ * external queue, and an ao command simultaneously user counter subdevice
+ * there are a number of boards this driver will support when they are
+ * fully released, but does not yet since the pci device id numbers
+ * are not yet available.
+ *
+ * support prescaled 100khz clock for slow pacing (not available on 6000
+ * series?)
+ *
+ * make ao fifo size adjustable like ai fifo
+ */
#include <linux/module.h>
#include <linux/delay.h>
@@ -90,53 +89,56 @@ TODO:
#include "plx9080.h"
#define TIMER_BASE 25 /* 40MHz master clock */
-/* 100kHz 'prescaled' clock for slow acquisition,
- * maybe I'll support this someday */
+/*
+ * 100kHz 'prescaled' clock for slow acquisition,
+ * maybe I'll support this someday
+ */
#define PRESCALED_TIMER_BASE 10000
-#define DMA_BUFFER_SIZE 0x1000
+#define DMA_BUFFER_SIZE 0x1000
+#define DAC_FIFO_SIZE 0x2000
-/* maximum value that can be loaded into board's 24-bit counters*/
+/* maximum value that can be loaded into board's 24-bit counters */
static const int max_counter_value = 0xffffff;
/* PCI-DAS64xxx base addresses */
/* devpriv->main_iobase registers */
enum write_only_registers {
- INTR_ENABLE_REG = 0x0, /* interrupt enable register */
- HW_CONFIG_REG = 0x2, /* hardware config register */
+ INTR_ENABLE_REG = 0x0, /* interrupt enable register */
+ HW_CONFIG_REG = 0x2, /* hardware config register */
DAQ_SYNC_REG = 0xc,
DAQ_ATRIG_LOW_4020_REG = 0xc,
- ADC_CONTROL0_REG = 0x10, /* adc control register 0 */
- ADC_CONTROL1_REG = 0x12, /* adc control register 1 */
+ ADC_CONTROL0_REG = 0x10, /* adc control register 0 */
+ ADC_CONTROL1_REG = 0x12, /* adc control register 1 */
CALIBRATION_REG = 0x14,
- /* lower 16 bits of adc sample interval counter */
+ /* lower 16 bits of adc sample interval counter */
ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16,
- /* upper 8 bits of adc sample interval counter */
+ /* upper 8 bits of adc sample interval counter */
ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18,
- /* lower 16 bits of delay interval counter */
+ /* lower 16 bits of delay interval counter */
ADC_DELAY_INTERVAL_LOWER_REG = 0x1a,
- /* upper 8 bits of delay interval counter */
+ /* upper 8 bits of delay interval counter */
ADC_DELAY_INTERVAL_UPPER_REG = 0x1c,
- /* lower 16 bits of hardware conversion/scan counter */
+ /* lower 16 bits of hardware conversion/scan counter */
ADC_COUNT_LOWER_REG = 0x1e,
- /* upper 8 bits of hardware conversion/scan counter */
+ /* upper 8 bits of hardware conversion/scan counter */
ADC_COUNT_UPPER_REG = 0x20,
- ADC_START_REG = 0x22, /* software trigger to start acquisition */
- ADC_CONVERT_REG = 0x24, /* initiates single conversion */
- ADC_QUEUE_CLEAR_REG = 0x26, /* clears adc queue */
- ADC_QUEUE_LOAD_REG = 0x28, /* loads adc queue */
+ ADC_START_REG = 0x22, /* software trigger to start acquisition */
+ ADC_CONVERT_REG = 0x24, /* initiates single conversion */
+ ADC_QUEUE_CLEAR_REG = 0x26, /* clears adc queue */
+ ADC_QUEUE_LOAD_REG = 0x28, /* loads adc queue */
ADC_BUFFER_CLEAR_REG = 0x2a,
- /* high channel for internal queue, use adc_chan_bits() inline above */
+ /* high channel for internal queue, use adc_chan_bits() inline above */
ADC_QUEUE_HIGH_REG = 0x2c,
- DAC_CONTROL0_REG = 0x50, /* dac control register 0 */
- DAC_CONTROL1_REG = 0x52, /* dac control register 0 */
- /* lower 16 bits of dac sample interval counter */
+ DAC_CONTROL0_REG = 0x50, /* dac control register 0 */
+ DAC_CONTROL1_REG = 0x52, /* dac control register 0 */
+ /* lower 16 bits of dac sample interval counter */
DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54,
- /* upper 8 bits of dac sample interval counter */
+ /* upper 8 bits of dac sample interval counter */
DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56,
DAC_SELECT_REG = 0x60,
DAC_START_REG = 0x64,
- DAC_BUFFER_CLEAR_REG = 0x66, /* clear dac buffer */
+ DAC_BUFFER_CLEAR_REG = 0x66, /* clear dac buffer */
};
static inline unsigned int dac_convert_reg(unsigned int channel)
@@ -168,8 +170,8 @@ enum read_only_registers {
};
enum read_write_registers {
- I8255_4020_REG = 0x48, /* 8255 offset, for 4020 only */
- /* external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG */
+ I8255_4020_REG = 0x48, /* 8255 offset, for 4020 only */
+ /* external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG */
ADC_QUEUE_FIFO_REG = 0x100,
ADC_FIFO_REG = 0x200, /* adc data fifo */
/* dac data fifo, has weird interactions with external channel queue */
@@ -188,50 +190,51 @@ enum dio_counter_registers {
/* bit definitions for write-only registers */
enum intr_enable_contents {
- ADC_INTR_SRC_MASK = 0x3, /* adc interrupt source mask */
- ADC_INTR_QFULL_BITS = 0x0, /* interrupt fifo quarter full */
- ADC_INTR_EOC_BITS = 0x1, /* interrupt end of conversion */
- ADC_INTR_EOSCAN_BITS = 0x2, /* interrupt end of scan */
- ADC_INTR_EOSEQ_BITS = 0x3, /* interrupt end of sequence mask */
- EN_ADC_INTR_SRC_BIT = 0x4, /* enable adc interrupt source */
- EN_ADC_DONE_INTR_BIT = 0x8, /* enable adc acquisition done intr */
+ ADC_INTR_SRC_MASK = 0x3, /* adc interrupt source mask */
+ ADC_INTR_QFULL_BITS = 0x0, /* interrupt fifo quarter full */
+ ADC_INTR_EOC_BITS = 0x1, /* interrupt end of conversion */
+ ADC_INTR_EOSCAN_BITS = 0x2, /* interrupt end of scan */
+ ADC_INTR_EOSEQ_BITS = 0x3, /* interrupt end of sequence mask */
+ EN_ADC_INTR_SRC_BIT = 0x4, /* enable adc interrupt source */
+ EN_ADC_DONE_INTR_BIT = 0x8, /* enable adc acquisition done intr */
DAC_INTR_SRC_MASK = 0x30,
DAC_INTR_QEMPTY_BITS = 0x0,
DAC_INTR_HIGH_CHAN_BITS = 0x10,
- EN_DAC_INTR_SRC_BIT = 0x40, /* enable dac interrupt source */
+ EN_DAC_INTR_SRC_BIT = 0x40, /* enable dac interrupt source */
EN_DAC_DONE_INTR_BIT = 0x80,
- EN_ADC_ACTIVE_INTR_BIT = 0x200, /* enable adc active interrupt */
- EN_ADC_STOP_INTR_BIT = 0x400, /* enable adc stop trigger interrupt */
- EN_DAC_ACTIVE_INTR_BIT = 0x800, /* enable dac active interrupt */
- EN_DAC_UNDERRUN_BIT = 0x4000, /* enable dac underrun status bit */
- EN_ADC_OVERRUN_BIT = 0x8000, /* enable adc overrun status bit */
+ EN_ADC_ACTIVE_INTR_BIT = 0x200, /* enable adc active interrupt */
+ EN_ADC_STOP_INTR_BIT = 0x400, /* enable adc stop trigger interrupt */
+ EN_DAC_ACTIVE_INTR_BIT = 0x800, /* enable dac active interrupt */
+ EN_DAC_UNDERRUN_BIT = 0x4000, /* enable dac underrun status bit */
+ EN_ADC_OVERRUN_BIT = 0x8000, /* enable adc overrun status bit */
};
enum hw_config_contents {
- MASTER_CLOCK_4020_MASK = 0x3, /* master clock source mask for 4020 */
- INTERNAL_CLOCK_4020_BITS = 0x1, /* use 40 MHz internal master clock */
- BNC_CLOCK_4020_BITS = 0x2, /* use BNC input for master clock */
- EXT_CLOCK_4020_BITS = 0x3, /* use dio input for master clock */
- EXT_QUEUE_BIT = 0x200, /* use external channel/gain queue */
- /* use 225 nanosec strobe when loading dac instead of 50 nanosec */
+ MASTER_CLOCK_4020_MASK = 0x3, /* master clock source mask for 4020 */
+ INTERNAL_CLOCK_4020_BITS = 0x1, /* use 40 MHz internal master clock */
+ BNC_CLOCK_4020_BITS = 0x2, /* use BNC input for master clock */
+ EXT_CLOCK_4020_BITS = 0x3, /* use dio input for master clock */
+ EXT_QUEUE_BIT = 0x200, /* use external channel/gain queue */
+ /* use 225 nanosec strobe when loading dac instead of 50 nanosec */
SLOW_DAC_BIT = 0x400,
- /* bit with unknown function yet given as default value in pci-das64
- * manual */
+ /*
+ * bit with unknown function yet given as default value in pci-das64
+ * manual
+ */
HW_CONFIG_DUMMY_BITS = 0x2000,
- /* bit selects channels 1/0 for analog input/output, otherwise 0/1 */
+ /* bit selects channels 1/0 for analog input/output, otherwise 0/1 */
DMA_CH_SELECT_BIT = 0x8000,
- FIFO_SIZE_REG = 0x4, /* allows adjustment of fifo sizes */
- DAC_FIFO_SIZE_MASK = 0xff00, /* bits that set dac fifo size */
- DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */
+ FIFO_SIZE_REG = 0x4, /* allows adjustment of fifo sizes */
+ DAC_FIFO_SIZE_MASK = 0xff00, /* bits that set dac fifo size */
+ DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */
};
-#define DAC_FIFO_SIZE 0x2000
enum daq_atrig_low_4020_contents {
- /* use trig/ext clk bnc input for analog gate signal */
+ /* use trig/ext clk bnc input for analog gate signal */
EXT_AGATE_BNC_BIT = 0x8000,
- /* use trig/ext clk bnc input for external stop trigger signal */
+ /* use trig/ext clk bnc input for external stop trigger signal */
EXT_STOP_TRIG_BNC_BIT = 0x4000,
- /* use trig/ext clk bnc input for external start trigger signal */
+ /* use trig/ext clk bnc input for external start trigger signal */
EXT_START_TRIG_BNC_BIT = 0x2000,
};
@@ -241,38 +244,38 @@ static inline uint16_t analog_trig_low_threshold_bits(uint16_t threshold)
}
enum adc_control0_contents {
- ADC_GATE_SRC_MASK = 0x3, /* bits that select gate */
- ADC_SOFT_GATE_BITS = 0x1, /* software gate */
- ADC_EXT_GATE_BITS = 0x2, /* external digital gate */
- ADC_ANALOG_GATE_BITS = 0x3, /* analog level gate */
- /* level-sensitive gate (for digital) */
+ ADC_GATE_SRC_MASK = 0x3, /* bits that select gate */
+ ADC_SOFT_GATE_BITS = 0x1, /* software gate */
+ ADC_EXT_GATE_BITS = 0x2, /* external digital gate */
+ ADC_ANALOG_GATE_BITS = 0x3, /* analog level gate */
+ /* level-sensitive gate (for digital) */
ADC_GATE_LEVEL_BIT = 0x4,
- ADC_GATE_POLARITY_BIT = 0x8, /* gate active low */
+ ADC_GATE_POLARITY_BIT = 0x8, /* gate active low */
ADC_START_TRIG_SOFT_BITS = 0x10,
ADC_START_TRIG_EXT_BITS = 0x20,
ADC_START_TRIG_ANALOG_BITS = 0x30,
ADC_START_TRIG_MASK = 0x30,
- ADC_START_TRIG_FALLING_BIT = 0x40, /* trig 1 uses falling edge */
- /* external pacing uses falling edge */
+ ADC_START_TRIG_FALLING_BIT = 0x40, /* trig 1 uses falling edge */
+ /* external pacing uses falling edge */
ADC_EXT_CONV_FALLING_BIT = 0x800,
- /* enable hardware scan counter */
+ /* enable hardware scan counter */
ADC_SAMPLE_COUNTER_EN_BIT = 0x1000,
- ADC_DMA_DISABLE_BIT = 0x4000, /* disables dma */
- ADC_ENABLE_BIT = 0x8000, /* master adc enable */
+ ADC_DMA_DISABLE_BIT = 0x4000, /* disables dma */
+ ADC_ENABLE_BIT = 0x8000, /* master adc enable */
};
enum adc_control1_contents {
- /* should be set for boards with > 16 channels */
+ /* should be set for boards with > 16 channels */
ADC_QUEUE_CONFIG_BIT = 0x1,
CONVERT_POLARITY_BIT = 0x10,
EOC_POLARITY_BIT = 0x20,
- ADC_SW_GATE_BIT = 0x40, /* software gate of adc */
- ADC_DITHER_BIT = 0x200, /* turn on extra noise for dithering */
+ ADC_SW_GATE_BIT = 0x40, /* software gate of adc */
+ ADC_DITHER_BIT = 0x200, /* turn on extra noise for dithering */
RETRIGGER_BIT = 0x800,
ADC_LO_CHANNEL_4020_MASK = 0x300,
ADC_HI_CHANNEL_4020_MASK = 0xc00,
- TWO_CHANNEL_4020_BITS = 0x1000, /* two channel mode for 4020 */
- FOUR_CHANNEL_4020_BITS = 0x2000, /* four channel mode for 4020 */
+ TWO_CHANNEL_4020_BITS = 0x1000, /* two channel mode for 4020 */
+ FOUR_CHANNEL_4020_BITS = 0x2000, /* four channel mode for 4020 */
CHANNEL_MODE_4020_MASK = 0x3000,
ADC_MODE_MASK = 0xf000,
};
@@ -296,10 +299,10 @@ enum calibration_contents {
SELECT_8800_BIT = 0x1,
SELECT_8402_64XX_BIT = 0x2,
SELECT_1590_60XX_BIT = 0x2,
- CAL_EN_64XX_BIT = 0x40, /* calibration enable for 64xx series */
+ CAL_EN_64XX_BIT = 0x40, /* calibration enable for 64xx series */
SERIAL_DATA_IN_BIT = 0x80,
SERIAL_CLOCK_BIT = 0x100,
- CAL_EN_60XX_BIT = 0x200, /* calibration enable for 60xx series */
+ CAL_EN_60XX_BIT = 0x200, /* calibration enable for 60xx series */
CAL_GAIN_BIT = 0x800,
};
@@ -326,12 +329,12 @@ static inline uint16_t adc_convert_chan_4020_bits(unsigned int channel)
};
enum adc_queue_load_contents {
- UNIP_BIT = 0x800, /* unipolar/bipolar bit */
- ADC_SE_DIFF_BIT = 0x1000, /* single-ended/ differential bit */
- /* non-referenced single-ended (common-mode input) */
+ UNIP_BIT = 0x800, /* unipolar/bipolar bit */
+ ADC_SE_DIFF_BIT = 0x1000, /* single-ended/ differential bit */
+ /* non-referenced single-ended (common-mode input) */
ADC_COMMON_BIT = 0x2000,
- QUEUE_EOSEQ_BIT = 0x4000, /* queue end of sequence */
- QUEUE_EOSCAN_BIT = 0x8000, /* queue end of scan */
+ QUEUE_EOSEQ_BIT = 0x4000, /* queue end of sequence */
+ QUEUE_EOSCAN_BIT = 0x8000, /* queue end of scan */
};
static inline uint16_t adc_chan_bits(unsigned int channel)
@@ -340,7 +343,7 @@ static inline uint16_t adc_chan_bits(unsigned int channel)
};
enum dac_control0_contents {
- DAC_ENABLE_BIT = 0x8000, /* dac controller enable bit */
+ DAC_ENABLE_BIT = 0x8000, /* dac controller enable bit */
DAC_CYCLIC_STOP_BIT = 0x4000,
DAC_WAVEFORM_MODE_BIT = 0x100,
DAC_EXT_UPDATE_FALLING_BIT = 0x80,
@@ -360,7 +363,7 @@ enum dac_control1_contents {
DAC_WRITE_POLARITY_BIT = 0x800, /* board-dependent setting */
DAC1_EXT_REF_BIT = 0x200,
DAC0_EXT_REF_BIT = 0x100,
- DAC_OUTPUT_ENABLE_BIT = 0x80, /* dac output enable bit */
+ DAC_OUTPUT_ENABLE_BIT = 0x80, /* dac output enable bit */
DAC_UPDATE_POLARITY_BIT = 0x40, /* board-dependent setting */
DAC_SW_GATE_BIT = 0x20,
DAC1_UNIPOLAR_BIT = 0x8,
@@ -409,9 +412,9 @@ enum i2c_addresses {
};
enum range_cal_i2c_contents {
- /* bits that set what source the adc converter measures */
+ /* bits that set what source the adc converter measures */
ADC_SRC_4020_MASK = 0x70,
- /* make bnc trig/ext clock threshold 0V instead of 2.5V */
+ /* make bnc trig/ext clock threshold 0V instead of 2.5V */
BNC_TRIG_THRESHOLD_0V_BIT = 0x80,
};
@@ -422,7 +425,7 @@ static inline uint8_t adc_src_4020_bits(unsigned int source)
static inline uint8_t attenuate_bit(unsigned int channel)
{
- /* attenuate channel (+-5V input range) */
+ /* attenuate channel (+-5V input range) */
return 1 << (channel & 0x3);
};
@@ -627,18 +630,18 @@ enum pcidas64_boardid {
struct pcidas64_board {
const char *name;
- int ai_se_chans; /* number of ai inputs in single-ended mode */
- int ai_bits; /* analog input resolution */
- int ai_speed; /* fastest conversion period in ns */
+ int ai_se_chans; /* number of ai inputs in single-ended mode */
+ int ai_bits; /* analog input resolution */
+ int ai_speed; /* fastest conversion period in ns */
const struct comedi_lrange *ai_range_table;
const uint8_t *ai_range_code;
- int ao_nchan; /* number of analog out channels */
- int ao_bits; /* analog output resolution */
- int ao_scan_speed; /* analog output scan speed */
+ int ao_nchan; /* number of analog out channels */
+ int ao_bits; /* analog output resolution */
+ int ao_scan_speed; /* analog output scan speed */
const struct comedi_lrange *ao_range_table;
const int *ao_range_code;
const struct hw_fifo_info *const ai_fifo;
- /* different board families have slightly different registers */
+ /* different board families have slightly different registers */
enum register_layout layout;
unsigned has_8255:1;
};
@@ -699,7 +702,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
.has_8255 = 1,
},
[BOARD_PCIDAS6402_12] = {
- .name = "pci-das6402/12", /* XXX check */
+ .name = "pci-das6402/12", /* XXX check */
.ai_se_chans = 64,
.ai_bits = 12,
.ai_speed = 5000,
@@ -996,7 +999,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
.ai_speed = 50,
.ao_bits = 12,
.ao_nchan = 2,
- .ao_scan_speed = 0, /* no hardware pacing on ao */
+ .ao_scan_speed = 0, /* no hardware pacing on ao */
.layout = LAYOUT_4020,
.ai_range_table = &ai_ranges_4020,
.ao_range_table = &ao_ranges_4020,
@@ -1005,9 +1008,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
.has_8255 = 1,
},
#if 0
- /*
- * The device id for these boards is unknown
- */
+ /* The device id for these boards is unknown */
[BOARD_PCIDAS6402_16_JR] = {
.name = "pci-das6402/16/jr",
@@ -1116,62 +1117,66 @@ static inline unsigned short se_diff_bit_6xxx(struct comedi_device *dev,
}
struct ext_clock_info {
- /* master clock divisor to use for scans with external master clock */
+ /* master clock divisor to use for scans with external master clock */
unsigned int divisor;
- /* chanspec for master clock input when used as scan begin src */
+ /* chanspec for master clock input when used as scan begin src */
unsigned int chanspec;
};
/* this structure is for data unique to this hardware driver. */
struct pcidas64_private {
- /* base addresses (physical) */
+ /* base addresses (physical) */
resource_size_t main_phys_iobase;
resource_size_t dio_counter_phys_iobase;
- /* base addresses (ioremapped) */
+ /* base addresses (ioremapped) */
void __iomem *plx9080_iobase;
void __iomem *main_iobase;
- /* local address (used by dma controller) */
+ /* local address (used by dma controller) */
uint32_t local0_iobase;
uint32_t local1_iobase;
- /* dma buffers for analog input */
+ /* dma buffers for analog input */
uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT];
- /* physical addresses of ai dma buffers */
+ /* physical addresses of ai dma buffers */
dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT];
- /* array of ai dma descriptors read by plx9080,
- * allocated to get proper alignment */
+ /*
+ * array of ai dma descriptors read by plx9080,
+ * allocated to get proper alignment
+ */
struct plx_dma_desc *ai_dma_desc;
- /* physical address of ai dma descriptor array */
+ /* physical address of ai dma descriptor array */
dma_addr_t ai_dma_desc_bus_addr;
- /* index of the ai dma descriptor/buffer
- * that is currently being used */
+ /*
+ * index of the ai dma descriptor/buffer
+ * that is currently being used
+ */
unsigned int ai_dma_index;
- /* dma buffers for analog output */
+ /* dma buffers for analog output */
uint16_t *ao_buffer[AO_DMA_RING_COUNT];
- /* physical addresses of ao dma buffers */
+ /* physical addresses of ao dma buffers */
dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT];
struct plx_dma_desc *ao_dma_desc;
dma_addr_t ao_dma_desc_bus_addr;
- /* keeps track of buffer where the next ao sample should go */
+ /* keeps track of buffer where the next ao sample should go */
unsigned int ao_dma_index;
- unsigned int hw_revision; /* stc chip hardware revision number */
- /* last bits sent to INTR_ENABLE_REG register */
+ unsigned int hw_revision; /* stc chip hardware revision number */
+ /* last bits sent to INTR_ENABLE_REG register */
unsigned int intr_enable_bits;
- /* last bits sent to ADC_CONTROL1_REG register */
+ /* last bits sent to ADC_CONTROL1_REG register */
uint16_t adc_control1_bits;
- /* last bits sent to FIFO_SIZE_REG register */
+ /* last bits sent to FIFO_SIZE_REG register */
uint16_t fifo_size_bits;
- /* last bits sent to HW_CONFIG_REG register */
+ /* last bits sent to HW_CONFIG_REG register */
uint16_t hw_config_bits;
uint16_t dac_control1_bits;
- /* last bits written to plx9080 control register */
+ /* last bits written to plx9080 control register */
uint32_t plx_control_bits;
- /* last bits written to plx interrupt control and status register */
+ /* last bits written to plx interrupt control and status register */
uint32_t plx_intcsr_bits;
- /* index of calibration source readable through ai ch0 */
+ /* index of calibration source readable through ai ch0 */
int calibration_source;
- /* bits written to i2c calibration/range register */
+ /* bits written to i2c calibration/range register */
uint8_t i2c_cal_range_bits;
- /* configure digital triggers to trigger on falling edge */
+ /* configure digital triggers to trigger on falling edge */
unsigned int ext_trig_falling;
short ai_cmd_running;
unsigned int ai_fifo_segment_length;
@@ -1224,7 +1229,7 @@ static void abort_dma(struct comedi_device *dev, unsigned int channel)
struct pcidas64_private *devpriv = dev->private;
unsigned long flags;
- /* spinlock for plx dma control/status reg */
+ /* spinlock for plx dma control/status reg */
spin_lock_irqsave(&dev->spinlock, flags);
plx9080_abort_dma(devpriv->plx9080_iobase, channel);
@@ -1271,7 +1276,7 @@ static void enable_ai_interrupts(struct comedi_device *dev,
* if CMDF_WAKE_EOS flag is set.
*/
if (cmd->flags & CMDF_WAKE_EOS) {
- /* 4020 doesn't support pio transfers except for fifo dregs */
+ /* 4020 doesn't support pio transfers except for fifo dregs */
if (board->layout != LAYOUT_4020)
bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT;
}
@@ -1305,36 +1310,40 @@ static void init_plx9080(struct comedi_device *dev)
abort_dma(dev, 0);
abort_dma(dev, 1);
- /* configure dma0 mode */
+ /* configure dma0 mode */
bits = 0;
- /* enable ready input, not sure if this is necessary */
+ /* enable ready input, not sure if this is necessary */
bits |= PLX_DMAMODE_READYIEN;
- /* enable bterm, not sure if this is necessary */
+ /* enable bterm, not sure if this is necessary */
bits |= PLX_DMAMODE_BTERMIEN;
- /* enable dma chaining */
+ /* enable dma chaining */
bits |= PLX_DMAMODE_CHAINEN;
- /* enable interrupt on dma done
- * (probably don't need this, since chain never finishes) */
+ /*
+ * enable interrupt on dma done
+ * (probably don't need this, since chain never finishes)
+ */
bits |= PLX_DMAMODE_DONEIEN;
- /* don't increment local address during transfers
- * (we are transferring from a fixed fifo register) */
+ /*
+ * don't increment local address during transfers
+ * (we are transferring from a fixed fifo register)
+ */
bits |= PLX_DMAMODE_LACONST;
- /* route dma interrupt to pci bus */
+ /* route dma interrupt to pci bus */
bits |= PLX_DMAMODE_INTRPCI;
- /* enable demand mode */
+ /* enable demand mode */
bits |= PLX_DMAMODE_DEMAND;
- /* enable local burst mode */
+ /* enable local burst mode */
bits |= PLX_DMAMODE_BURSTEN;
- /* 4020 uses 32 bit dma */
+ /* 4020 uses 32 bit dma */
if (board->layout == LAYOUT_4020)
- bits |= PLX_DMAMODE_WIDTH32;
- else /* localspace0 bus is 16 bits wide */
- bits |= PLX_DMAMODE_WIDTH16;
+ bits |= PLX_DMAMODE_WIDTH_32;
+ else /* localspace0 bus is 16 bits wide */
+ bits |= PLX_DMAMODE_WIDTH_16;
writel(bits, plx_iobase + PLX_REG_DMAMODE1);
if (ao_cmd_is_supported(board))
writel(bits, plx_iobase + PLX_REG_DMAMODE0);
- /* enable interrupts on plx 9080 */
+ /* enable interrupts on plx 9080 */
devpriv->plx_intcsr_bits |=
PLX_INTCSR_LSEABORTEN | PLX_INTCSR_LSEPARITYEN | PLX_INTCSR_PIEN |
PLX_INTCSR_PLIEN | PLX_INTCSR_PABORTIEN | PLX_INTCSR_LIOEN |
@@ -1376,7 +1385,7 @@ static int set_ai_fifo_segment_length(struct comedi_device *dev,
if (num_entries > fifo->max_segment_length)
num_entries = fifo->max_segment_length;
- /* 1 == 256 entries, 2 == 512 entries, etc */
+ /* 1 == 256 entries, 2 == 512 entries, etc */
num_increments = DIV_ROUND_CLOSEST(num_entries, increment_size);
bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask;
@@ -1442,7 +1451,7 @@ static void init_stc_registers(struct comedi_device *dev)
writew(devpriv->adc_control1_bits,
devpriv->main_iobase + ADC_CONTROL1_REG);
- /* 6402/16 manual says this register must be initialized to 0xff? */
+ /* 6402/16 manual says this register must be initialized to 0xff? */
writew(0xff, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
bits = SLOW_DAC_BIT | DMA_CH_SELECT_BIT;
@@ -1457,7 +1466,7 @@ static void init_stc_registers(struct comedi_device *dev)
spin_unlock_irqrestore(&dev->spinlock, flags);
- /* set fifos to maximum size */
+ /* set fifos to maximum size */
devpriv->fifo_size_bits |= DAC_FIFO_BITS;
set_ai_fifo_segment_length(dev, board->ai_fifo->max_segment_length);
@@ -1478,7 +1487,7 @@ static int alloc_and_init_dma_members(struct comedi_device *dev)
struct pcidas64_private *devpriv = dev->private;
int i;
- /* allocate pci dma buffers */
+ /* allocate pci dma buffers */
for (i = 0; i < ai_dma_ring_count(board); i++) {
devpriv->ai_buffer[i] =
dma_alloc_coherent(&pcidev->dev, DMA_BUFFER_SIZE,
@@ -1499,7 +1508,7 @@ static int alloc_and_init_dma_members(struct comedi_device *dev)
return -ENOMEM;
}
}
- /* allocate dma descriptors */
+ /* allocate dma descriptors */
devpriv->ai_dma_desc =
dma_alloc_coherent(&pcidev->dev, sizeof(struct plx_dma_desc) *
ai_dma_ring_count(board),
@@ -1517,7 +1526,7 @@ static int alloc_and_init_dma_members(struct comedi_device *dev)
if (!devpriv->ao_dma_desc)
return -ENOMEM;
}
- /* initialize dma descriptors */
+ /* initialize dma descriptors */
for (i = 0; i < ai_dma_ring_count(board); i++) {
devpriv->ai_dma_desc[i].pci_start_addr =
cpu_to_le32(devpriv->ai_buffer_bus_addr[i]);
@@ -1618,13 +1627,11 @@ static void i2c_set_sda(struct comedi_device *dev, int state)
void __iomem *plx_control_addr = devpriv->plx9080_iobase +
PLX_REG_CNTRL;
- if (state) {
- /* set data line high */
+ if (state) { /* set data line high */
devpriv->plx_control_bits &= ~data_bit;
writel(devpriv->plx_control_bits, plx_control_addr);
udelay(i2c_high_udelay);
- } else { /* set data line low */
-
+ } else { /* set data line low */
devpriv->plx_control_bits |= data_bit;
writel(devpriv->plx_control_bits, plx_control_addr);
udelay(i2c_low_udelay);
@@ -1639,13 +1646,11 @@ static void i2c_set_scl(struct comedi_device *dev, int state)
void __iomem *plx_control_addr = devpriv->plx9080_iobase +
PLX_REG_CNTRL;
- if (state) {
- /* set clock line high */
+ if (state) { /* set clock line high */
devpriv->plx_control_bits &= ~clock_bit;
writel(devpriv->plx_control_bits, plx_control_addr);
udelay(i2c_high_udelay);
- } else { /* set clock line low */
-
+ } else { /* set clock line low */
devpriv->plx_control_bits |= clock_bit;
writel(devpriv->plx_control_bits, plx_control_addr);
udelay(i2c_low_udelay);
@@ -1674,7 +1679,7 @@ static int i2c_read_ack(struct comedi_device *dev)
i2c_set_sda(dev, 1);
i2c_set_scl(dev, 1);
- return 0; /* return fake acknowledge bit */
+ return 0; /* return fake acknowledge bit */
}
/* send start bit */
@@ -1707,23 +1712,23 @@ static void i2c_write(struct comedi_device *dev, unsigned int address,
* eeprom and i2c bus
*/
- /* make sure we dont send anything to eeprom */
+ /* make sure we dont send anything to eeprom */
devpriv->plx_control_bits &= ~PLX_CNTRL_EECS;
i2c_stop(dev);
i2c_start(dev);
- /* send address and write bit */
+ /* send address and write bit */
bitstream = (address << 1) & ~read_bit;
i2c_write_byte(dev, bitstream);
- /* get acknowledge */
+ /* get acknowledge */
if (i2c_read_ack(dev) != 0) {
dev_err(dev->class_dev, "failed: no acknowledge\n");
i2c_stop(dev);
return;
}
- /* write data bytes */
+ /* write data bytes */
for (i = 0; i < length; i++) {
i2c_write_byte(dev, data[i]);
if (i2c_read_ack(dev) != 0) {
@@ -1770,8 +1775,8 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
range = CR_RANGE(insn->chanspec);
aref = CR_AREF(insn->chanspec);
- /* disable card's analog input interrupt sources and pacing */
- /* 4020 generates dac done interrupts even though they are disabled */
+ /* disable card's analog input interrupt sources and pacing */
+ /* 4020 generates dac done interrupts even though they are disabled */
disable_ai_pacing(dev);
spin_lock_irqsave(&dev->spinlock, flags);
@@ -1784,12 +1789,12 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
spin_unlock_irqrestore(&dev->spinlock, flags);
if (board->layout != LAYOUT_4020) {
- /* use internal queue */
+ /* use internal queue */
devpriv->hw_config_bits &= ~EXT_QUEUE_BIT;
writew(devpriv->hw_config_bits,
devpriv->main_iobase + HW_CONFIG_REG);
- /* ALT_SOURCE is internal calibration reference */
+ /* ALT_SOURCE is internal calibration reference */
if (insn->chanspec & CR_ALT_SOURCE) {
unsigned int cal_en_bit;
@@ -1811,19 +1816,19 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
*/
writew(0, devpriv->main_iobase + CALIBRATION_REG);
}
- /* load internal queue */
+ /* load internal queue */
bits = 0;
- /* set gain */
+ /* set gain */
bits |= ai_range_bits_6xxx(dev, CR_RANGE(insn->chanspec));
- /* set single-ended / differential */
+ /* set single-ended / differential */
bits |= se_diff_bit_6xxx(dev, aref == AREF_DIFF);
if (aref == AREF_COMMON)
bits |= ADC_COMMON_BIT;
bits |= adc_chan_bits(channel);
- /* set stop channel */
+ /* set stop channel */
writew(adc_chan_bits(channel),
devpriv->main_iobase + ADC_QUEUE_HIGH_REG);
- /* set start channel, and rest of settings */
+ /* set start channel, and rest of settings */
writew(bits, devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
} else {
uint8_t old_cal_range_bits = devpriv->i2c_cal_range_bits;
@@ -1835,7 +1840,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
} else { /* select BNC inputs */
devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4);
}
- /* select range */
+ /* select range */
if (range == 0)
devpriv->i2c_cal_range_bits |= attenuate_bit(channel);
else
@@ -1862,14 +1867,14 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
}
for (n = 0; n < insn->n; n++) {
- /* clear adc buffer (inside loop for 4020 sake) */
+ /* clear adc buffer (inside loop for 4020 sake) */
writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG);
/* trigger conversion, bits sent only matter for 4020 */
writew(adc_convert_chan_4020_bits(CR_CHAN(insn->chanspec)),
devpriv->main_iobase + ADC_CONVERT_REG);
- /* wait for data */
+ /* wait for data */
ret = comedi_timeout(dev, s, insn, cb_pcidas64_ai_eoc, 0);
if (ret)
return ret;
@@ -2249,7 +2254,7 @@ static void setup_sample_counters(struct comedi_device *dev,
{
struct pcidas64_private *devpriv = dev->private;
- /* load hardware conversion counter */
+ /* load hardware conversion counter */
if (use_hw_sample_counter(cmd)) {
writew(cmd->stop_arg & 0xffff,
devpriv->main_iobase + ADC_COUNT_LOWER_REG);
@@ -2277,7 +2282,7 @@ static inline unsigned int dma_transfer_size(struct comedi_device *dev)
static uint32_t ai_convert_counter_6xxx(const struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
- /* supposed to load counter with desired divisor minus 3 */
+ /* supposed to load counter with desired divisor minus 3 */
return cmd->convert_arg / TIMER_BASE - 3;
}
@@ -2286,7 +2291,7 @@ static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev,
{
uint32_t count;
- /* figure out how long we need to delay at end of scan */
+ /* figure out how long we need to delay at end of scan */
switch (cmd->scan_begin_src) {
case TRIG_TIMER:
count = (cmd->scan_begin_arg -
@@ -2315,13 +2320,13 @@ static uint32_t ai_convert_counter_4020(struct comedi_device *dev,
case TRIG_OTHER:
divisor = devpriv->ext_clock.divisor;
break;
- default: /* should never happen */
+ default: /* should never happen */
dev_err(dev->class_dev, "bug! failed to set ai pacing!\n");
divisor = 1000;
break;
}
- /* supposed to load counter with desired divisor minus 2 for 4020 */
+ /* supposed to load counter with desired divisor minus 2 for 4020 */
return divisor - 2;
}
@@ -2330,7 +2335,7 @@ static void select_master_clock_4020(struct comedi_device *dev,
{
struct pcidas64_private *devpriv = dev->private;
- /* select internal/external master clock */
+ /* select internal/external master clock */
devpriv->hw_config_bits &= ~MASTER_CLOCK_4020_MASK;
if (cmd->scan_begin_src == TRIG_OTHER) {
int chanspec = devpriv->ext_clock.chanspec;
@@ -2366,7 +2371,7 @@ static inline void dma_start_sync(struct comedi_device *dev,
struct pcidas64_private *devpriv = dev->private;
unsigned long flags;
- /* spinlock for plx dma control/status reg */
+ /* spinlock for plx dma control/status reg */
spin_lock_irqsave(&dev->spinlock, flags);
writeb(PLX_DMACSR_ENABLE | PLX_DMACSR_START | PLX_DMACSR_CLEARINTR,
devpriv->plx9080_iobase + PLX_REG_DMACSR(channel));
@@ -2390,16 +2395,16 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd)
scan_counter = ai_scan_counter_6xxx(dev, cmd);
}
- /* load lower 16 bits of convert interval */
+ /* load lower 16 bits of convert interval */
writew(convert_counter & 0xffff,
devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
- /* load upper 8 bits of convert interval */
+ /* load upper 8 bits of convert interval */
writew((convert_counter >> 16) & 0xff,
devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
- /* load lower 16 bits of scan delay */
+ /* load lower 16 bits of scan delay */
writew(scan_counter & 0xffff,
devpriv->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG);
- /* load upper 8 bits of scan delay */
+ /* load upper 8 bits of scan delay */
writew((scan_counter >> 16) & 0xff,
devpriv->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG);
}
@@ -2435,26 +2440,26 @@ static int setup_channel_queue(struct comedi_device *dev,
writew(devpriv->hw_config_bits,
devpriv->main_iobase + HW_CONFIG_REG);
bits = 0;
- /* set channel */
+ /* set channel */
bits |= adc_chan_bits(CR_CHAN(cmd->chanlist[0]));
- /* set gain */
+ /* set gain */
bits |= ai_range_bits_6xxx(dev,
CR_RANGE(cmd->chanlist[0]));
- /* set single-ended / differential */
+ /* set single-ended / differential */
bits |= se_diff_bit_6xxx(dev,
CR_AREF(cmd->chanlist[0]) ==
AREF_DIFF);
if (CR_AREF(cmd->chanlist[0]) == AREF_COMMON)
bits |= ADC_COMMON_BIT;
- /* set stop channel */
+ /* set stop channel */
writew(adc_chan_bits
(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])),
devpriv->main_iobase + ADC_QUEUE_HIGH_REG);
- /* set start channel, and rest of settings */
+ /* set start channel, and rest of settings */
writew(bits,
devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
} else {
- /* use external queue */
+ /* use external queue */
if (dev->write_subdev && dev->write_subdev->busy) {
warn_external_queue(dev);
return -EBUSY;
@@ -2462,30 +2467,30 @@ static int setup_channel_queue(struct comedi_device *dev,
devpriv->hw_config_bits |= EXT_QUEUE_BIT;
writew(devpriv->hw_config_bits,
devpriv->main_iobase + HW_CONFIG_REG);
- /* clear DAC buffer to prevent weird interactions */
+ /* clear DAC buffer to prevent weird interactions */
writew(0,
devpriv->main_iobase + DAC_BUFFER_CLEAR_REG);
- /* clear queue pointer */
+ /* clear queue pointer */
writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
- /* load external queue */
+ /* load external queue */
for (i = 0; i < cmd->chanlist_len; i++) {
bits = 0;
- /* set channel */
+ /* set channel */
bits |= adc_chan_bits(CR_CHAN(cmd->
chanlist[i]));
- /* set gain */
+ /* set gain */
bits |= ai_range_bits_6xxx(dev,
CR_RANGE(cmd->
chanlist
[i]));
- /* set single-ended / differential */
+ /* set single-ended / differential */
bits |= se_diff_bit_6xxx(dev,
CR_AREF(cmd->
chanlist[i]) ==
AREF_DIFF);
if (CR_AREF(cmd->chanlist[i]) == AREF_COMMON)
bits |= ADC_COMMON_BIT;
- /* mark end of queue */
+ /* mark end of queue */
if (i == cmd->chanlist_len - 1)
bits |= QUEUE_EOSCAN_BIT |
QUEUE_EOSEQ_BIT;
@@ -2498,7 +2503,7 @@ static int setup_channel_queue(struct comedi_device *dev,
* but required for reliable operation
*/
writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
- /* prime queue holding register */
+ /* prime queue holding register */
writew(0, devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
}
} else {
@@ -2507,7 +2512,7 @@ static int setup_channel_queue(struct comedi_device *dev,
devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
/* select BNC inputs */
devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4);
- /* select ranges */
+ /* select ranges */
for (i = 0; i < cmd->chanlist_len; i++) {
unsigned int channel = CR_CHAN(cmd->chanlist[i]);
unsigned int range = CR_RANGE(cmd->chanlist[i]);
@@ -2579,7 +2584,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
if (retval < 0)
return retval;
- /* make sure internal calibration source is turned off */
+ /* make sure internal calibration source is turned off */
writew(0, devpriv->main_iobase + CALIBRATION_REG);
set_ai_pacing(dev, cmd);
@@ -2595,10 +2600,10 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
if (board->layout != LAYOUT_4020) {
devpriv->adc_control1_bits &= ~ADC_MODE_MASK;
if (cmd->convert_src == TRIG_EXT)
- /* good old mode 13 */
+ /* good old mode 13 */
devpriv->adc_control1_bits |= adc_mode_bits(13);
else
- /* mode 8. What else could you need? */
+ /* mode 8. What else could you need? */
devpriv->adc_control1_bits |= adc_mode_bits(8);
} else {
devpriv->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK;
@@ -2618,20 +2623,20 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->main_iobase + ADC_CONTROL1_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
- /* clear adc buffer */
+ /* clear adc buffer */
writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG);
if ((cmd->flags & CMDF_WAKE_EOS) == 0 ||
board->layout == LAYOUT_4020) {
devpriv->ai_dma_index = 0;
- /* set dma transfer size */
+ /* set dma transfer size */
for (i = 0; i < ai_dma_ring_count(board); i++)
devpriv->ai_dma_desc[i].transfer_size =
cpu_to_le32(dma_transfer_size(dev) *
sizeof(uint16_t));
- /* give location of first dma descriptor */
+ /* give location of first dma descriptor */
load_first_dma_descriptor(dev, 1,
devpriv->ai_dma_desc_bus_addr |
PLX_DMADPR_DESCPCI |
@@ -2657,7 +2662,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
bits = ADC_ENABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT;
if (cmd->flags & CMDF_WAKE_EOS)
bits |= ADC_DMA_DISABLE_BIT;
- /* set start trigger */
+ /* set start trigger */
if (cmd->start_src == TRIG_EXT) {
bits |= ADC_START_TRIG_EXT_BITS;
if (cmd->start_arg & CR_INVERT)
@@ -2673,7 +2678,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
spin_unlock_irqrestore(&dev->spinlock, flags);
- /* start acquisition */
+ /* start acquisition */
if (cmd->start_src == TRIG_NOW)
writew(0, devpriv->main_iobase + ADC_START_REG);
@@ -2691,7 +2696,7 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev)
int num_samples;
do {
- /* get least significant 15 bits */
+ /* get least significant 15 bits */
read_index = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) &
0x7fff;
write_index = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) &
@@ -2796,14 +2801,14 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
pci_addr_reg = devpriv->plx9080_iobase + PLX_REG_DMAPADR(channel);
- /* loop until we have read all the full buffers */
+ /* loop until we have read all the full buffers */
for (j = 0, next_transfer_addr = readl(pci_addr_reg);
(next_transfer_addr <
devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] ||
next_transfer_addr >=
devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] +
DMA_BUFFER_SIZE) && j < ai_dma_ring_count(board); j++) {
- /* transfer data from dma buffer to comedi buffer */
+ /* transfer data from dma buffer to comedi buffer */
num_samples = comedi_nsamples_left(s, dma_transfer_size(dev));
comedi_buf_write_samples(s,
devpriv->ai_buffer[devpriv->ai_dma_index],
@@ -2829,15 +2834,15 @@ static void handle_ai_interrupt(struct comedi_device *dev,
uint8_t dma1_status;
unsigned long flags;
- /* check for fifo overrun */
+ /* check for fifo overrun */
if (status & ADC_OVERRUN_BIT) {
dev_err(dev->class_dev, "fifo overrun\n");
async->events |= COMEDI_CB_ERROR;
}
- /* spin lock makes sure no one else changes plx dma control reg */
+ /* spin lock makes sure no one else changes plx dma control reg */
spin_lock_irqsave(&dev->spinlock, flags);
dma1_status = readb(devpriv->plx9080_iobase + PLX_REG_DMACSR1);
- if (plx_status & PLX_INTCSR_DMA1IA) { /* dma chan 1 interrupt */
+ if (plx_status & PLX_INTCSR_DMA1IA) { /* dma chan 1 interrupt */
writeb((dma1_status & PLX_DMACSR_ENABLE) | PLX_DMACSR_CLEARINTR,
devpriv->plx9080_iobase + PLX_REG_DMACSR1);
@@ -2846,7 +2851,7 @@ static void handle_ai_interrupt(struct comedi_device *dev,
}
spin_unlock_irqrestore(&dev->spinlock, flags);
- /* drain fifo with pio */
+ /* drain fifo with pio */
if ((status & ADC_DONE_BIT) ||
((cmd->flags & CMDF_WAKE_EOS) &&
(status & ADC_INTR_PENDING_BIT) &&
@@ -2859,7 +2864,7 @@ static void handle_ai_interrupt(struct comedi_device *dev,
spin_unlock_irqrestore(&dev->spinlock, flags);
}
}
- /* if we are have all the data, then quit */
+ /* if we are have all the data, then quit */
if ((cmd->stop_src == TRIG_COUNT &&
async->scans_done >= cmd->stop_arg) ||
(cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT)))
@@ -3012,7 +3017,7 @@ static void handle_ao_interrupt(struct comedi_device *dev,
async = s->async;
cmd = &async->cmd;
- /* spin lock makes sure no one else changes plx dma control reg */
+ /* spin lock makes sure no one else changes plx dma control reg */
spin_lock_irqsave(&dev->spinlock, flags);
dma0_status = readb(devpriv->plx9080_iobase + PLX_REG_DMACSR0);
if (plx_status & PLX_INTCSR_DMA0IA) { /* dma chan 0 interrupt */
@@ -3106,15 +3111,15 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
int chan = CR_CHAN(insn->chanspec);
int range = CR_RANGE(insn->chanspec);
- /* do some initializing */
+ /* do some initializing */
writew(0, devpriv->main_iobase + DAC_CONTROL0_REG);
- /* set range */
+ /* set range */
set_dac_range_bits(dev, &devpriv->dac_control1_bits, chan, range);
writew(devpriv->dac_control1_bits,
devpriv->main_iobase + DAC_CONTROL1_REG);
- /* write to channel */
+ /* write to channel */
if (board->layout == LAYOUT_4020) {
writew(data[0] & 0xff,
devpriv->main_iobase + dac_lsb_4020_reg(chan));
@@ -3124,7 +3129,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
writew(data[0], devpriv->main_iobase + dac_convert_reg(chan));
}
- /* remember output value */
+ /* remember output value */
s->readback[chan] = data[0];
return 1;
@@ -3556,7 +3561,7 @@ static int caldac_i2c_write(struct comedi_device *dev,
uint8_t serial_bytes[3];
uint8_t i2c_addr;
enum pointer_bits {
- /* manual has gain and offset bits switched */
+ /* manual has gain and offset bits switched */
OFFSET_0_2 = 0x1,
GAIN_0_2 = 0x2,
OFFSET_1_3 = 0x4,
@@ -3567,35 +3572,35 @@ static int caldac_i2c_write(struct comedi_device *dev,
};
switch (caldac_channel) {
- case 0: /* chan 0 offset */
+ case 0: /* chan 0 offset */
i2c_addr = CALDAC0_I2C_ADDR;
serial_bytes[0] = OFFSET_0_2;
break;
- case 1: /* chan 1 offset */
+ case 1: /* chan 1 offset */
i2c_addr = CALDAC0_I2C_ADDR;
serial_bytes[0] = OFFSET_1_3;
break;
- case 2: /* chan 2 offset */
+ case 2: /* chan 2 offset */
i2c_addr = CALDAC1_I2C_ADDR;
serial_bytes[0] = OFFSET_0_2;
break;
- case 3: /* chan 3 offset */
+ case 3: /* chan 3 offset */
i2c_addr = CALDAC1_I2C_ADDR;
serial_bytes[0] = OFFSET_1_3;
break;
- case 4: /* chan 0 gain */
+ case 4: /* chan 0 gain */
i2c_addr = CALDAC0_I2C_ADDR;
serial_bytes[0] = GAIN_0_2;
break;
- case 5: /* chan 1 gain */
+ case 5: /* chan 1 gain */
i2c_addr = CALDAC0_I2C_ADDR;
serial_bytes[0] = GAIN_1_3;
break;
- case 6: /* chan 2 gain */
+ case 6: /* chan 2 gain */
i2c_addr = CALDAC1_I2C_ADDR;
serial_bytes[0] = GAIN_0_2;
break;
- case 7: /* chan 3 gain */
+ case 7: /* chan 3 gain */
i2c_addr = CALDAC1_I2C_ADDR;
serial_bytes[0] = GAIN_1_3;
break;
@@ -3718,24 +3723,24 @@ static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address)
udelay(eeprom_udelay);
devpriv->plx_control_bits &= ~PLX_CNTRL_EESK & ~PLX_CNTRL_EECS;
- /* make sure we don't send anything to the i2c bus on 4020 */
+ /* make sure we don't send anything to the i2c bus on 4020 */
devpriv->plx_control_bits |= PLX_CNTRL_USERO;
writel(devpriv->plx_control_bits, plx_control_addr);
- /* activate serial eeprom */
+ /* activate serial eeprom */
udelay(eeprom_udelay);
devpriv->plx_control_bits |= PLX_CNTRL_EECS;
writel(devpriv->plx_control_bits, plx_control_addr);
- /* write read command and desired memory address */
+ /* write read command and desired memory address */
for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
- /* set bit to be written */
+ /* set bit to be written */
udelay(eeprom_udelay);
if (bitstream & bit)
devpriv->plx_control_bits |= PLX_CNTRL_EEWB;
else
devpriv->plx_control_bits &= ~PLX_CNTRL_EEWB;
writel(devpriv->plx_control_bits, plx_control_addr);
- /* clock in bit */
+ /* clock in bit */
udelay(eeprom_udelay);
devpriv->plx_control_bits |= PLX_CNTRL_EESK;
writel(devpriv->plx_control_bits, plx_control_addr);
@@ -3743,10 +3748,10 @@ static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address)
devpriv->plx_control_bits &= ~PLX_CNTRL_EESK;
writel(devpriv->plx_control_bits, plx_control_addr);
}
- /* read back value from eeprom memory location */
+ /* read back value from eeprom memory location */
value = 0;
for (bit = 1 << (value_length - 1); bit; bit >>= 1) {
- /* clock out bit */
+ /* clock out bit */
udelay(eeprom_udelay);
devpriv->plx_control_bits |= PLX_CNTRL_EESK;
writel(devpriv->plx_control_bits, plx_control_addr);
@@ -3758,7 +3763,7 @@ static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address)
value |= bit;
}
- /* deactivate eeprom serial input */
+ /* deactivate eeprom serial input */
udelay(eeprom_udelay);
devpriv->plx_control_bits &= ~PLX_CNTRL_EECS;
writel(devpriv->plx_control_bits, plx_control_addr);
@@ -3775,9 +3780,7 @@ static int eeprom_read_insn(struct comedi_device *dev,
return 1;
}
-/*
- * Allocate and initialize the subdevice structures.
- */
+/* Allocate and initialize the subdevice structures. */
static int setup_subdevices(struct comedi_device *dev)
{
const struct pcidas64_board *board = dev->board_ptr;
@@ -3816,7 +3819,7 @@ static int setup_subdevices(struct comedi_device *dev)
* (not internal calibration sources)
*/
devpriv->i2c_cal_range_bits = adc_src_4020_bits(4);
- /* set channels to +-5 volt input ranges */
+ /* set channels to +-5 volt input ranges */
for (i = 0; i < s->n_chan; i++)
devpriv->i2c_cal_range_bits |= attenuate_bit(i);
data = devpriv->i2c_cal_range_bits;
@@ -3849,7 +3852,7 @@ static int setup_subdevices(struct comedi_device *dev)
s->type = COMEDI_SUBD_UNUSED;
}
- /* digital input */
+ /* digital input */
s = &dev->subdevices[2];
if (board->layout == LAYOUT_64XX) {
s->type = COMEDI_SUBD_DI;
@@ -3862,7 +3865,7 @@ static int setup_subdevices(struct comedi_device *dev)
s->type = COMEDI_SUBD_UNUSED;
}
- /* digital output */
+ /* digital output */
if (board->layout == LAYOUT_64XX) {
s = &dev->subdevices[3];
s->type = COMEDI_SUBD_DO;
@@ -3891,7 +3894,7 @@ static int setup_subdevices(struct comedi_device *dev)
s->type = COMEDI_SUBD_UNUSED;
}
- /* 8 channel dio for 60xx */
+ /* 8 channel dio for 60xx */
s = &dev->subdevices[5];
if (board->layout == LAYOUT_60XX) {
s->type = COMEDI_SUBD_DIO;
@@ -3905,7 +3908,7 @@ static int setup_subdevices(struct comedi_device *dev)
s->type = COMEDI_SUBD_UNUSED;
}
- /* caldac */
+ /* caldac */
s = &dev->subdevices[6];
s->type = COMEDI_SUBD_CALIB;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
@@ -3925,7 +3928,7 @@ static int setup_subdevices(struct comedi_device *dev)
s->readback[i] = s->maxdata / 2;
}
- /* 2 channel ad8402 potentiometer */
+ /* 2 channel ad8402 potentiometer */
s = &dev->subdevices[7];
if (board->layout == LAYOUT_64XX) {
s->type = COMEDI_SUBD_CALIB;
@@ -3959,7 +3962,7 @@ static int setup_subdevices(struct comedi_device *dev)
s->type = COMEDI_SUBD_UNUSED;
}
- /* user counter subd XXX */
+ /* user counter subd XXX */
s = &dev->subdevices[9];
s->type = COMEDI_SUBD_UNUSED;
@@ -4005,7 +4008,7 @@ static int auto_attach(struct comedi_device *dev,
return -ENOMEM;
}
- /* figure out what local addresses are */
+ /* figure out what local addresses are */
local_range = readl(devpriv->plx9080_iobase + PLX_REG_LAS0RR) &
PLX_LASRR_MEM_MASK;
local_decode = readl(devpriv->plx9080_iobase + PLX_REG_LAS0BA) &
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
index 9c02b17a2834..317a9b5e4a3b 100644
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -1,43 +1,42 @@
/*
- comedi/drivers/das08_cs.c
- DAS08 driver
+ * Comedi driver for DAS008 PCMCIA boards
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ * Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * PCMCIA support code for this driver is adapted from the dummy_cs.c
+ * driver of the Linux PCMCIA Card Services package.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+ */
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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.
-
- PCMCIA support code for this driver is adapted from the dummy_cs.c
- driver of the Linux PCMCIA Card Services package.
-
- The initial developer of the original code is David A. Hinds
- <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
- are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-*/
/*
-Driver: das08_cs
-Description: DAS-08 PCMCIA boards
-Author: Warren Jasper, ds, Frank Hess
-Devices: [ComputerBoards] PCM-DAS08 (pcm-das08)
-Status: works
-
-This is the PCMCIA-specific support split off from the
-das08 driver.
-
-Options (for pcm-das08):
- NONE
-
-Command support does not exist, but could be added for this board.
-*/
+ * Driver: das08_cs
+ * Description: DAS-08 PCMCIA boards
+ * Author: Warren Jasper, ds, Frank Hess
+ * Devices: [ComputerBoards] PCM-DAS08 (pcm-das08)
+ * Status: works
+ *
+ * This is the PCMCIA-specific support split off from the
+ * das08 driver.
+ *
+ * Configuration Options: none, uses PCMCIA auto config
+ *
+ * Command support does not exist, but could be added for this board.
+ */
#include <linux/module.h>
diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c
index 8bbd93814340..fcd85475e429 100644
--- a/drivers/staging/comedi/drivers/dt2811.c
+++ b/drivers/staging/comedi/drivers/dt2811.c
@@ -96,11 +96,11 @@
* 6 6 100 kHz 6 1000000
* 7 12 50 kHz 7 10000000
*/
-const unsigned int dt2811_clk_dividers[] = {
+static const unsigned int dt2811_clk_dividers[] = {
1, 10, 2, 3, 4, 5, 6, 12
};
-const unsigned int dt2811_clk_multipliers[] = {
+static const unsigned int dt2811_clk_multipliers[] = {
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
};
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index 3295bb4ac8c4..7ebca862ecaa 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -660,12 +660,12 @@ static int dt9812_find_endpoints(struct comedi_device *dev)
case 1:
dir = USB_DIR_OUT;
devpriv->cmd_wr.addr = ep->bEndpointAddress;
- devpriv->cmd_wr.size = le16_to_cpu(ep->wMaxPacketSize);
+ devpriv->cmd_wr.size = usb_endpoint_maxp(ep);
break;
case 2:
dir = USB_DIR_IN;
devpriv->cmd_rd.addr = ep->bEndpointAddress;
- devpriv->cmd_rd.size = le16_to_cpu(ep->wMaxPacketSize);
+ devpriv->cmd_rd.size = usb_endpoint_maxp(ep);
break;
case 3:
/* unused write stream */
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
index af4b4175af4d..e5b948405fd9 100644
--- a/drivers/staging/comedi/drivers/gsc_hpdi.c
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -582,7 +582,7 @@ static void gsc_hpdi_init_plx9080(struct comedi_device *dev)
bits |= PLX_DMAMODE_DEMAND;
/* enable local burst mode */
bits |= PLX_DMAMODE_BURSTEN;
- bits |= PLX_DMAMODE_WIDTH32;
+ bits |= PLX_DMAMODE_WIDTH_32;
writel(bits, plx_iobase + PLX_REG_DMAMODE0);
}
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
index 6c4ff023717f..70390de66e0e 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.c
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -141,7 +141,7 @@ static void set_transforms(struct jr3_channel __iomem *channel,
{
int i;
- num &= 0x000f; /* Make sure that 0 <= num <= 15 */
+ num &= 0x000f; /* Make sure that 0 <= num <= 15 */
for (i = 0; i < 8; i++) {
set_u16(&channel->transforms[num].link[i].link_type,
transf.link[i].link_type);
@@ -323,10 +323,10 @@ static int read_idm_word(const u8 *data, size_t size, int *pos,
int value;
if (pos && val) {
- /* Skip over non hex */
+ /* Skip over non hex */
for (; *pos < size && !isxdigit(data[*pos]); (*pos)++)
;
- /* Collect value */
+ /* Collect value */
*val = 0;
for (; *pos < size; (*pos)++) {
value = hex_to_bin(data[*pos]);
@@ -448,7 +448,8 @@ static int jr3_download_firmware(struct comedi_device *dev,
return 0;
}
-static struct jr3_pci_poll_delay jr3_pci_poll_subdevice(struct comedi_subdevice *s)
+static struct jr3_pci_poll_delay
+jr3_pci_poll_subdevice(struct comedi_subdevice *s)
{
struct jr3_pci_subdev_private *spriv = s->private;
struct jr3_pci_poll_delay result = poll_delay_min_max(1000, 2000);
@@ -733,13 +734,13 @@ static int jr3_pci_auto_attach(struct comedi_device *dev,
}
}
- /* Reset DSP card */
+ /* Reset DSP card */
writel(0, &devpriv->iobase->channel[0].reset);
ret = comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
"comedi/jr3pci.idm",
jr3_download_firmware, 0);
- dev_dbg(dev->class_dev, "Firmare load %d\n", ret);
+ dev_dbg(dev->class_dev, "Firmware load %d\n", ret);
if (ret < 0)
return ret;
/*
@@ -763,7 +764,7 @@ static int jr3_pci_auto_attach(struct comedi_device *dev,
data.copyright[i]) >> 8);
}
- /* Start card timer */
+ /* Start card timer */
for (i = 0; i < dev->n_subdevices; i++) {
s = &dev->subdevices[i];
spriv = s->private;
diff --git a/drivers/staging/comedi/drivers/jr3_pci.h b/drivers/staging/comedi/drivers/jr3_pci.h
index 356811defaf4..f10a84fb6c14 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.h
+++ b/drivers/staging/comedi/drivers/jr3_pci.h
@@ -1,4 +1,5 @@
-/* Helper types to take care of the fact that the DSP card memory
+/*
+ * Helper types to take care of the fact that the DSP card memory
* is 16 bits, but aligned on a 32 bit PCI boundary
*/
@@ -22,7 +23,8 @@ static inline void set_s16(s32 __iomem *p, s16 val)
writel(val, p);
}
-/* The raw data is stored in a format which facilitates rapid
+/*
+ * The raw data is stored in a format which facilitates rapid
* processing by the JR3 DSP chip. The raw_channel structure shows the
* format for a single channel of data. Each channel takes four,
* two-byte words.
@@ -47,7 +49,8 @@ struct raw_channel {
s32 reserved[2];
};
-/* The force_array structure shows the layout for the decoupled and
+/*
+ * The force_array structure shows the layout for the decoupled and
* filtered force data.
*/
struct force_array {
@@ -61,7 +64,8 @@ struct force_array {
s32 v2;
};
-/* The six_axis_array structure shows the layout for the offsets and
+/*
+ * The six_axis_array structure shows the layout for the offsets and
* the full scales.
*/
struct six_axis_array {
@@ -74,7 +78,8 @@ struct six_axis_array {
};
/* VECT_BITS */
-/* The vect_bits structure shows the layout for indicating
+/*
+ * The vect_bits structure shows the layout for indicating
* which axes to use in computing the vectors. Each bit signifies
* selection of a single axis. The V1x axis bit corresponds to a hex
* value of 0x0001 and the V2z bit corresponds to a hex value of
@@ -100,12 +105,14 @@ enum {
};
/* WARNING_BITS */
-/* The warning_bits structure shows the bit pattern for the warning
+/*
+ * The warning_bits structure shows the bit pattern for the warning
* word. The bit fields are shown from bit 0 (lsb) to bit 15 (msb).
*/
-/* XX_NEAR_SET */
-/* The xx_near_sat bits signify that the indicated axis has reached or
+/* XX_NEAR_SET */
+/*
+ * The xx_near_sat bits signify that the indicated axis has reached or
* exceeded the near saturation value.
*/
@@ -118,12 +125,13 @@ enum {
mz_near_sat = 0x0020
};
-/* ERROR_BITS */
-/* XX_SAT */
-/* MEMORY_ERROR */
-/* SENSOR_CHANGE */
+/* ERROR_BITS */
+/* XX_SAT */
+/* MEMORY_ERROR */
+/* SENSOR_CHANGE */
-/* The error_bits structure shows the bit pattern for the error word.
+/*
+ * The error_bits structure shows the bit pattern for the error word.
* The bit fields are shown from bit 0 (lsb) to bit 15 (msb). The
* xx_sat bits signify that the indicated axis has reached or exceeded
* the saturation value. The memory_error bit indicates that a problem
@@ -134,9 +142,10 @@ enum {
*
*/
-/* SYSTEM_BUSY */
+/* SYSTEM_BUSY */
-/* The system_busy bit indicates that the JR3 DSP is currently busy
+/*
+ * The system_busy bit indicates that the JR3 DSP is currently busy
* and is not calculating force data. This occurs when a new
* coordinate transformation, or new sensor full scale is set by the
* user. A very fast system using the force data for feedback might
@@ -146,9 +155,10 @@ enum {
* calibration CRC.
*/
-/* CAL_CRC_BAD */
+/* CAL_CRC_BAD */
-/* The cal_crc_bad bit indicates that the calibration CRC has not
+/*
+ * The cal_crc_bad bit indicates that the calibration CRC has not
* calculated to zero. CRC is short for cyclic redundancy code. It is
* a method for determining the integrity of messages in data
* communication. The calibration data stored inside the sensor is
@@ -168,7 +178,8 @@ enum {
/* WATCH_DOG */
/* WATCH_DOG2 */
-/* The watch_dog and watch_dog2 bits are sensor, not processor, watch
+/*
+ * The watch_dog and watch_dog2 bits are sensor, not processor, watch
* dog bits. Watch_dog indicates that the sensor data line seems to be
* acting correctly, while watch_dog2 indicates that sensor data and
* clock are being received. It is possible for watch_dog2 to go off
@@ -192,9 +203,10 @@ enum error_bits_t {
watch_dog = 0x8000
};
-/* THRESH_STRUCT */
+/* THRESH_STRUCT */
-/* This structure shows the layout for a single threshold packet inside of a
+/*
+ * This structure shows the layout for a single threshold packet inside of a
* load envelope. Each load envelope can contain several threshold structures.
* 1. data_address contains the address of the data for that threshold. This
* includes filtered, unfiltered, raw, rate, counters, error and warning data
@@ -210,9 +222,10 @@ struct thresh_struct {
s32 bit_pattern;
};
-/* LE_STRUCT */
+/* LE_STRUCT */
-/* Layout of a load enveloped packet. Four thresholds are showed ... for more
+/*
+ * Layout of a load enveloped packet. Four thresholds are showed ... for more
* see manual (pag.25)
* 1. latch_bits is a bit pattern that show which bits the user wants to latch.
* The latched bits will not be reset once the threshold which set them is
@@ -228,8 +241,9 @@ struct le_struct {
s32 reserved;
};
-/* LINK_TYPES */
-/* Link types is an enumerated value showing the different possible transform
+/* LINK_TYPES */
+/*
+ * Link types is an enumerated value showing the different possible transform
* link types.
* 0 - end transform packet
* 1 - translate along X axis (TX)
@@ -252,8 +266,8 @@ enum link_types {
neg
};
-/* TRANSFORM */
-/* Structure used to describe a transform. */
+/* TRANSFORM */
+/* Structure used to describe a transform. */
struct intern_transform {
struct {
u32 link_type;
@@ -261,23 +275,29 @@ struct intern_transform {
} link[8];
};
-/* JR3 force/torque sensor data definition. For more information see sensor
- * and hardware manuals.
+/*
+ * JR3 force/torque sensor data definition. For more information see sensor
+ * and hardware manuals.
*/
struct jr3_channel {
- /* Raw_channels is the area used to store the raw data coming from */
- /* the sensor. */
+ /*
+ * Raw_channels is the area used to store the raw data coming from
+ * the sensor.
+ */
struct raw_channel raw_channels[16]; /* offset 0x0000 */
- /* Copyright is a null terminated ASCII string containing the JR3 */
- /* copyright notice. */
+ /*
+ * Copyright is a null terminated ASCII string containing the JR3
+ * copyright notice.
+ */
u32 copyright[0x0018]; /* offset 0x0040 */
s32 reserved1[0x0008]; /* offset 0x0058 */
- /* Shunts contains the sensor shunt readings. Some JR3 sensors have
+ /*
+ * Shunts contains the sensor shunt readings. Some JR3 sensors have
* the ability to have their gains adjusted. This allows the
* hardware full scales to be adjusted to potentially allow
* better resolution or dynamic range. For sensors that have
@@ -298,25 +318,29 @@ struct jr3_channel {
* command (10) set new full scales (pg. 38).
*/
- struct six_axis_array shunts; /* offset 0x0060 */
- s32 reserved2[2]; /* offset 0x0066 */
+ struct six_axis_array shunts; /* offset 0x0060 */
+ s32 reserved2[2]; /* offset 0x0066 */
- /* Default_FS contains the full scale that is used if the user does */
- /* not set a full scale. */
+ /*
+ * Default_FS contains the full scale that is used if the user does
+ * not set a full scale.
+ */
struct six_axis_array default_FS; /* offset 0x0068 */
- s32 reserved3; /* offset 0x006e */
+ s32 reserved3; /* offset 0x006e */
- /* Load_envelope_num is the load envelope number that is currently
+ /*
+ * Load_envelope_num is the load envelope number that is currently
* in use. This value is set by the user after one of the load
* envelopes has been initialized.
*/
- s32 load_envelope_num; /* offset 0x006f */
+ s32 load_envelope_num; /* offset 0x006f */
/* Min_full_scale is the recommend minimum full scale. */
- /* These values in conjunction with max_full_scale (pg. 9) helps
+ /*
+ * These values in conjunction with max_full_scale (pg. 9) helps
* determine the appropriate value for setting the full scales. The
* software allows the user to set the sensor full scale to an
* arbitrary value. But setting the full scales has some hazards. If
@@ -342,30 +366,35 @@ struct jr3_channel {
*/
struct six_axis_array min_full_scale; /* offset 0x0070 */
- s32 reserved4; /* offset 0x0076 */
+ s32 reserved4; /* offset 0x0076 */
- /* Transform_num is the transform number that is currently in use.
+ /*
+ * Transform_num is the transform number that is currently in use.
* This value is set by the JR3 DSP after the user has used command
* (5) use transform # (pg. 33).
*/
- s32 transform_num; /* offset 0x0077 */
+ s32 transform_num; /* offset 0x0077 */
- /* Max_full_scale is the recommended maximum full scale. See */
- /* min_full_scale (pg. 9) for more details. */
+ /*
+ * Max_full_scale is the recommended maximum full scale.
+ * See min_full_scale (pg. 9) for more details.
+ */
struct six_axis_array max_full_scale; /* offset 0x0078 */
- s32 reserved5; /* offset 0x007e */
+ s32 reserved5; /* offset 0x007e */
- /* Peak_address is the address of the data which will be monitored
+ /*
+ * Peak_address is the address of the data which will be monitored
* by the peak routine. This value is set by the user. The peak
* routine will monitor any 8 contiguous addresses for peak values.
* (ex. to watch filter3 data for peaks, set this value to 0x00a8).
*/
- s32 peak_address; /* offset 0x007f */
+ s32 peak_address; /* offset 0x007f */
- /* Full_scale is the sensor full scales which are currently in use.
+ /*
+ * Full_scale is the sensor full scales which are currently in use.
* Decoupled and filtered data is scaled so that +/- 16384 is equal
* to the full scales. The engineering units used are indicated by
* the units value discussed on page 16. The full scales for Fx, Fy,
@@ -377,9 +406,10 @@ struct jr3_channel {
* axes used for each vector respectively.
*/
- struct force_array full_scale; /* offset 0x0080 */
+ struct force_array full_scale; /* offset 0x0080 */
- /* Offsets contains the sensor offsets. These values are subtracted from
+ /*
+ * Offsets contains the sensor offsets. These values are subtracted from
* the sensor data to obtain the decoupled data. The offsets are set a
* few seconds (< 10) after the calibration data has been received.
* They are set so that the output data will be zero. These values
@@ -392,23 +422,26 @@ struct jr3_channel {
* about Z by 90 degrees, FY would be 5 and all others would be zero.
*/
- struct six_axis_array offsets; /* offset 0x0088 */
+ struct six_axis_array offsets; /* offset 0x0088 */
- /* Offset_num is the number of the offset currently in use. This
+ /*
+ * Offset_num is the number of the offset currently in use. This
* value is set by the JR3 DSP after the user has executed the use
* offset # command (pg. 34). It can vary between 0 and 15.
*/
- s32 offset_num; /* offset 0x008e */
+ s32 offset_num; /* offset 0x008e */
- /* Vect_axes is a bit map showing which of the axes are being used
+ /*
+ * Vect_axes is a bit map showing which of the axes are being used
* in the vector calculations. This value is set by the JR3 DSP
* after the user has executed the set vector axes command (pg. 37).
*/
- u32 vect_axes; /* offset 0x008f */
+ u32 vect_axes; /* offset 0x008f */
- /* Filter0 is the decoupled, unfiltered data from the JR3 sensor.
+ /*
+ * Filter0 is the decoupled, unfiltered data from the JR3 sensor.
* This data has had the offsets removed.
*
* These force_arrays hold the filtered data. The decoupled data is
@@ -420,23 +453,27 @@ struct jr3_channel {
* cutoff at 125 Hz, 31.25 Hz, 7.813 Hz, 1.953 Hz and 0.4883 Hz.
*/
- struct force_array filter[7]; /* offset 0x0090,
- offset 0x0098,
- offset 0x00a0,
- offset 0x00a8,
- offset 0x00b0,
- offset 0x00b8 ,
- offset 0x00c0 */
-
- /* Rate_data is the calculated rate data. It is a first derivative
+ struct force_array filter[7]; /*
+ * offset 0x0090,
+ * offset 0x0098,
+ * offset 0x00a0,
+ * offset 0x00a8,
+ * offset 0x00b0,
+ * offset 0x00b8,
+ * offset 0x00c0
+ */
+
+ /*
+ * Rate_data is the calculated rate data. It is a first derivative
* calculation. It is calculated at a frequency specified by the
* variable rate_divisor (pg. 12). The data on which the rate is
* calculated is specified by the variable rate_address (pg. 12).
*/
- struct force_array rate_data; /* offset 0x00c8 */
+ struct force_array rate_data; /* offset 0x00c8 */
- /* Minimum_data & maximum_data are the minimum and maximum (peak)
+ /*
+ * Minimum_data & maximum_data are the minimum and maximum (peak)
* data values. The JR3 DSP can monitor any 8 contiguous data items
* for minimums and maximums at full sensor bandwidth. This area is
* only updated at user request. This is done so that the user does
@@ -451,7 +488,8 @@ struct jr3_channel {
struct force_array minimum_data; /* offset 0x00d0 */
struct force_array maximum_data; /* offset 0x00d8 */
- /* Near_sat_value & sat_value contain the value used to determine if
+ /*
+ * Near_sat_value & sat_value contain the value used to determine if
* the raw sensor is saturated. Because of decoupling and offset
* removal, it is difficult to tell from the processed data if the
* sensor is saturated. These values, in conjunction with the error
@@ -465,10 +503,11 @@ struct jr3_channel {
* sat_value = 32768 - 2^(16 - ADC bits)
*/
- s32 near_sat_value; /* offset 0x00e0 */
- s32 sat_value; /* offset 0x00e1 */
+ s32 near_sat_value; /* offset 0x00e0 */
+ s32 sat_value; /* offset 0x00e1 */
- /* Rate_address, rate_divisor & rate_count contain the data used to
+ /*
+ * Rate_address, rate_divisor & rate_count contain the data used to
* control the calculations of the rates. Rate_address is the
* address of the data used for the rate calculation. The JR3 DSP
* will calculate rates for any 8 contiguous values (ex. to
@@ -485,11 +524,12 @@ struct jr3_channel {
* will minimize the time necessary to start the rate calculations.
*/
- s32 rate_address; /* offset 0x00e2 */
- u32 rate_divisor; /* offset 0x00e3 */
- u32 rate_count; /* offset 0x00e4 */
+ s32 rate_address; /* offset 0x00e2 */
+ u32 rate_divisor; /* offset 0x00e3 */
+ u32 rate_count; /* offset 0x00e4 */
- /* Command_word2 through command_word0 are the locations used to
+ /*
+ * Command_word2 through command_word0 are the locations used to
* send commands to the JR3 DSP. Their usage varies with the command
* and is detailed later in the Command Definitions section (pg.
* 29). In general the user places values into various memory
@@ -502,11 +542,12 @@ struct jr3_channel {
* command_word1).
*/
- s32 command_word2; /* offset 0x00e5 */
- s32 command_word1; /* offset 0x00e6 */
- s32 command_word0; /* offset 0x00e7 */
+ s32 command_word2; /* offset 0x00e5 */
+ s32 command_word1; /* offset 0x00e6 */
+ s32 command_word0; /* offset 0x00e7 */
- /* Count1 through count6 are unsigned counters which are incremented
+ /*
+ * Count1 through count6 are unsigned counters which are incremented
* every time the matching filters are calculated. Filter1 is
* calculated at the sensor data bandwidth. So this counter would
* increment at 8 kHz for a typical sensor. The rest of the counters
@@ -518,14 +559,15 @@ struct jr3_channel {
* once.
*/
- u32 count1; /* offset 0x00e8 */
- u32 count2; /* offset 0x00e9 */
- u32 count3; /* offset 0x00ea */
- u32 count4; /* offset 0x00eb */
- u32 count5; /* offset 0x00ec */
- u32 count6; /* offset 0x00ed */
+ u32 count1; /* offset 0x00e8 */
+ u32 count2; /* offset 0x00e9 */
+ u32 count3; /* offset 0x00ea */
+ u32 count4; /* offset 0x00eb */
+ u32 count5; /* offset 0x00ec */
+ u32 count6; /* offset 0x00ed */
- /* Error_count is a running count of data reception errors. If this
+ /*
+ * Error_count is a running count of data reception errors. If this
* counter is changing rapidly, it probably indicates a bad sensor
* cable connection or other hardware problem. In most installations
* error_count should not change at all. But it is possible in an
@@ -535,75 +577,84 @@ struct jr3_channel {
* where this counter counts a bad sample, that sample is ignored.
*/
- u32 error_count; /* offset 0x00ee */
+ u32 error_count; /* offset 0x00ee */
- /* Count_x is a counter which is incremented every time the JR3 DSP
+ /*
+ * Count_x is a counter which is incremented every time the JR3 DSP
* searches its job queues and finds nothing to do. It indicates the
* amount of idle time the JR3 DSP has available. It can also be
* used to determine if the JR3 DSP is alive. See the Performance
* Issues section on pg. 49 for more details.
*/
- u32 count_x; /* offset 0x00ef */
+ u32 count_x; /* offset 0x00ef */
- /* Warnings & errors contain the warning and error bits
+ /*
+ * Warnings & errors contain the warning and error bits
* respectively. The format of these two words is discussed on page
* 21 under the headings warnings_bits and error_bits.
*/
- u32 warnings; /* offset 0x00f0 */
- u32 errors; /* offset 0x00f1 */
+ u32 warnings; /* offset 0x00f0 */
+ u32 errors; /* offset 0x00f1 */
- /* Threshold_bits is a word containing the bits that are set by the
+ /*
+ * Threshold_bits is a word containing the bits that are set by the
* load envelopes. See load_envelopes (pg. 17) and thresh_struct
* (pg. 23) for more details.
*/
- s32 threshold_bits; /* offset 0x00f2 */
+ s32 threshold_bits; /* offset 0x00f2 */
- /* Last_crc is the value that shows the actual calculated CRC. CRC
+ /*
+ * Last_crc is the value that shows the actual calculated CRC. CRC
* is short for cyclic redundancy code. It should be zero. See the
* description for cal_crc_bad (pg. 21) for more information.
*/
- s32 last_CRC; /* offset 0x00f3 */
+ s32 last_CRC; /* offset 0x00f3 */
- /* EEProm_ver_no contains the version number of the sensor EEProm.
+ /*
+ * EEProm_ver_no contains the version number of the sensor EEProm.
* EEProm version numbers can vary between 0 and 255.
* Software_ver_no contains the software version number. Version
* 3.02 would be stored as 302.
*/
- s32 eeprom_ver_no; /* offset 0x00f4 */
- s32 software_ver_no; /* offset 0x00f5 */
+ s32 eeprom_ver_no; /* offset 0x00f4 */
+ s32 software_ver_no; /* offset 0x00f5 */
- /* Software_day & software_year are the release date of the software
+ /*
+ * Software_day & software_year are the release date of the software
* the JR3 DSP is currently running. Day is the day of the year,
* with January 1 being 1, and December 31, being 365 for non leap
* years.
*/
- s32 software_day; /* offset 0x00f6 */
- s32 software_year; /* offset 0x00f7 */
+ s32 software_day; /* offset 0x00f6 */
+ s32 software_year; /* offset 0x00f7 */
- /* Serial_no & model_no are the two values which uniquely identify a
+ /*
+ * Serial_no & model_no are the two values which uniquely identify a
* sensor. This model number does not directly correspond to the JR3
* model number, but it will provide a unique identifier for
* different sensor configurations.
*/
- u32 serial_no; /* offset 0x00f8 */
- u32 model_no; /* offset 0x00f9 */
+ u32 serial_no; /* offset 0x00f8 */
+ u32 model_no; /* offset 0x00f9 */
- /* Cal_day & cal_year are the sensor calibration date. Day is the
+ /*
+ * Cal_day & cal_year are the sensor calibration date. Day is the
* day of the year, with January 1 being 1, and December 31, being
* 366 for leap years.
*/
- s32 cal_day; /* offset 0x00fa */
- s32 cal_year; /* offset 0x00fb */
+ s32 cal_day; /* offset 0x00fa */
+ s32 cal_year; /* offset 0x00fb */
- /* Units is an enumerated read only value defining the engineering
+ /*
+ * Units is an enumerated read only value defining the engineering
* units used in the sensor full scale. The meanings of particular
* values are discussed in the section detailing the force_units
* structure on page 22. The engineering units are setto customer
@@ -626,20 +677,22 @@ struct jr3_channel {
* received.
*/
- u32 units; /* offset 0x00fc */
- s32 bits; /* offset 0x00fd */
- s32 channels; /* offset 0x00fe */
+ u32 units; /* offset 0x00fc */
+ s32 bits; /* offset 0x00fd */
+ s32 channels; /* offset 0x00fe */
- /* Thickness specifies the overall thickness of the sensor from
+ /*
+ * Thickness specifies the overall thickness of the sensor from
* flange to flange. The engineering units for this value are
* contained in units (pg. 16). The sensor calibration is relative
* to the center of the sensor. This value allows easy coordinate
* transformation from the center of the sensor to either flange.
*/
- s32 thickness; /* offset 0x00ff */
+ s32 thickness; /* offset 0x00ff */
- /* Load_envelopes is a table containing the load envelope
+ /*
+ * Load_envelopes is a table containing the load envelope
* descriptions. There are 16 possible load envelope slots in the
* table. The slots are on 16 word boundaries and are numbered 0-15.
* Each load envelope needs to start at the beginning of a slot but
@@ -655,7 +708,8 @@ struct jr3_channel {
struct le_struct load_envelopes[0x10]; /* offset 0x0100 */
- /* Transforms is a table containing the transform descriptions.
+ /*
+ * Transforms is a table containing the transform descriptions.
* There are 16 possible transform slots in the table. The slots are
* on 16 word boundaries and are numbered 0-15. Each transform needs
* to start at the beginning of a slot but need not be fully
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c
index 3e72718801a9..74911dbb2561 100644
--- a/drivers/staging/comedi/drivers/ni_670x.c
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -1,40 +1,34 @@
/*
- comedi/drivers/ni_670x.c
- Hardware driver for NI 670x devices
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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.
-*/
-/*
-Driver: ni_670x
-Description: National Instruments 670x
-Author: Bart Joris <bjoris@advalvas.be>
-Updated: Wed, 11 Dec 2002 18:25:35 -0800
-Devices: [National Instruments] PCI-6703 (ni_670x), PCI-6704
-Status: unknown
-
-Commands are not supported.
-*/
+ * Comedi driver for NI 670x devices
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
/*
- Bart Joris <bjoris@advalvas.be> Last updated on 20/08/2001
-
- Manuals:
-
- 322110a.pdf PCI/PXI-6704 User Manual
- 322110b.pdf PCI/PXI-6703/6704 User Manual
-
-*/
+ * Driver: ni_670x
+ * Description: National Instruments 670x
+ * Author: Bart Joris <bjoris@advalvas.be>
+ * Updated: Wed, 11 Dec 2002 18:25:35 -0800
+ * Devices: [National Instruments] PCI-6703 (ni_670x), PCI-6704
+ * Status: unknown
+ *
+ * Commands are not supported.
+ *
+ * Manuals:
+ * 322110a.pdf PCI/PXI-6704 User Manual
+ * 322110b.pdf PCI/PXI-6703/6704 User Manual
+ */
#include <linux/module.h>
#include <linux/interrupt.h>
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
index 9b444f8c4e33..5a4dcc6e61d8 100644
--- a/drivers/staging/comedi/drivers/ni_at_a2150.c
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -1,62 +1,47 @@
/*
- comedi/drivers/ni_at_a2150.c
- Driver for National Instruments AT-A2150 boards
- Copyright (C) 2001, 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 2000 David A. Schleef <ds@schleef.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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.
-*/
-/*
-Driver: ni_at_a2150
-Description: National Instruments AT-A2150
-Author: Frank Mori Hess
-Status: works
-Devices: [National Instruments] AT-A2150C (at_a2150c), AT-2150S (at_a2150s)
-
-If you want to ac couple the board's inputs, use AREF_OTHER.
-
-Configuration options:
- [0] - I/O port base address
- [1] - IRQ (optional, required for timed conversions)
- [2] - DMA (optional, required for timed conversions)
+ * Comedi driver for National Instruments AT-A2150 boards
+ * Copyright (C) 2001, 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
-*/
/*
-Yet another driver for obsolete hardware brought to you by Frank Hess.
-Testing and debugging help provided by Dave Andruczyk.
-
-This driver supports the boards:
-
-AT-A2150C
-AT-A2150S
-
-The only difference is their master clock frequencies.
-
-Options:
- [0] - base io address
- [1] - irq
- [2] - dma channel
-
-References (from ftp://ftp.natinst.com/support/manuals):
-
- 320360.pdf AT-A2150 User Manual
-
-TODO:
-
-analog level triggering
-TRIG_WAKE_EOS
-
-*/
+ * Driver: ni_at_a2150
+ * Description: National Instruments AT-A2150
+ * Author: Frank Mori Hess
+ * Status: works
+ * Devices: [National Instruments] AT-A2150C (at_a2150c), AT-2150S (at_a2150s)
+ *
+ * Configuration options:
+ * [0] - I/O port base address
+ * [1] - IRQ (optional, required for timed conversions)
+ * [2] - DMA (optional, required for timed conversions)
+ *
+ * Yet another driver for obsolete hardware brought to you by Frank Hess.
+ * Testing and debugging help provided by Dave Andruczyk.
+ *
+ * If you want to ac couple the board's inputs, use AREF_OTHER.
+ *
+ * The only difference in the boards is their master clock frequencies.
+ *
+ * References (from ftp://ftp.natinst.com/support/manuals):
+ * 320360.pdf AT-A2150 User Manual
+ *
+ * TODO:
+ * - analog level triggering
+ * - TRIG_WAKE_EOS
+ */
#include <linux/module.h>
#include <linux/delay.h>
@@ -73,48 +58,52 @@ TRIG_WAKE_EOS
/* Registers and bits */
#define CONFIG_REG 0x0
-#define CHANNEL_BITS(x) ((x) & 0x7)
+#define CHANNEL_BITS(x) ((x) & 0x7)
#define CHANNEL_MASK 0x7
-#define CLOCK_SELECT_BITS(x) (((x) & 0x3) << 3)
-#define CLOCK_DIVISOR_BITS(x) (((x) & 0x3) << 5)
+#define CLOCK_SELECT_BITS(x) (((x) & 0x3) << 3)
+#define CLOCK_DIVISOR_BITS(x) (((x) & 0x3) << 5)
#define CLOCK_MASK (0xf << 3)
-#define ENABLE0_BIT 0x80 /* enable (don't internally ground) channels 0 and 1 */
-#define ENABLE1_BIT 0x100 /* enable (don't internally ground) channels 2 and 3 */
-#define AC0_BIT 0x200 /* ac couple channels 0,1 */
-#define AC1_BIT 0x400 /* ac couple channels 2,3 */
-#define APD_BIT 0x800 /* analog power down */
-#define DPD_BIT 0x1000 /* digital power down */
-#define TRIGGER_REG 0x2 /* trigger config register */
-#define POST_TRIGGER_BITS 0x2
-#define DELAY_TRIGGER_BITS 0x3
-#define HW_TRIG_EN 0x10 /* enable hardware trigger */
-#define FIFO_START_REG 0x6 /* software start aquistion trigger */
-#define FIFO_RESET_REG 0x8 /* clears fifo + fifo flags */
-#define FIFO_DATA_REG 0xa /* read data */
-#define DMA_TC_CLEAR_REG 0xe /* clear dma terminal count interrupt */
-#define STATUS_REG 0x12 /* read only */
-#define FNE_BIT 0x1 /* fifo not empty */
-#define OVFL_BIT 0x8 /* fifo overflow */
-#define EDAQ_BIT 0x10 /* end of acquisition interrupt */
-#define DCAL_BIT 0x20 /* offset calibration in progress */
-#define INTR_BIT 0x40 /* interrupt has occurred */
-#define DMA_TC_BIT 0x80 /* dma terminal count interrupt has occurred */
-#define ID_BITS(x) (((x) >> 8) & 0x3)
-#define IRQ_DMA_CNTRL_REG 0x12 /* write only */
-#define DMA_CHAN_BITS(x) ((x) & 0x7) /* sets dma channel */
-#define DMA_EN_BIT 0x8 /* enables dma */
-#define IRQ_LVL_BITS(x) (((x) & 0xf) << 4) /* sets irq level */
-#define FIFO_INTR_EN_BIT 0x100 /* enable fifo interrupts */
-#define FIFO_INTR_FHF_BIT 0x200 /* interrupt fifo half full */
-#define DMA_INTR_EN_BIT 0x800 /* enable interrupt on dma terminal count */
-#define DMA_DEM_EN_BIT 0x1000 /* enables demand mode dma */
+/* enable (don't internally ground) channels 0 and 1 */
+#define ENABLE0_BIT 0x80
+/* enable (don't internally ground) channels 2 and 3 */
+#define ENABLE1_BIT 0x100
+#define AC0_BIT 0x200 /* ac couple channels 0,1 */
+#define AC1_BIT 0x400 /* ac couple channels 2,3 */
+#define APD_BIT 0x800 /* analog power down */
+#define DPD_BIT 0x1000 /* digital power down */
+#define TRIGGER_REG 0x2 /* trigger config register */
+#define POST_TRIGGER_BITS 0x2
+#define DELAY_TRIGGER_BITS 0x3
+#define HW_TRIG_EN 0x10 /* enable hardware trigger */
+#define FIFO_START_REG 0x6 /* software start aquistion trigger */
+#define FIFO_RESET_REG 0x8 /* clears fifo + fifo flags */
+#define FIFO_DATA_REG 0xa /* read data */
+#define DMA_TC_CLEAR_REG 0xe /* clear dma terminal count interrupt */
+#define STATUS_REG 0x12 /* read only */
+#define FNE_BIT 0x1 /* fifo not empty */
+#define OVFL_BIT 0x8 /* fifo overflow */
+#define EDAQ_BIT 0x10 /* end of acquisition interrupt */
+#define DCAL_BIT 0x20 /* offset calibration in progress */
+#define INTR_BIT 0x40 /* interrupt has occurred */
+/* dma terminal count interrupt has occurred */
+#define DMA_TC_BIT 0x80
+#define ID_BITS(x) (((x) >> 8) & 0x3)
+#define IRQ_DMA_CNTRL_REG 0x12 /* write only */
+#define DMA_CHAN_BITS(x) ((x) & 0x7) /* sets dma channel */
+#define DMA_EN_BIT 0x8 /* enables dma */
+#define IRQ_LVL_BITS(x) (((x) & 0xf) << 4) /* sets irq level */
+#define FIFO_INTR_EN_BIT 0x100 /* enable fifo interrupts */
+#define FIFO_INTR_FHF_BIT 0x200 /* interrupt fifo half full */
+/* enable interrupt on dma terminal count */
+#define DMA_INTR_EN_BIT 0x800
+#define DMA_DEM_EN_BIT 0x1000 /* enables demand mode dma */
#define I8253_BASE_REG 0x14
struct a2150_board {
const char *name;
- int clock[4]; /* master clock periods, in nanoseconds */
- int num_clocks; /* number of available master clock speeds */
- int ai_speed; /* maximum conversion rate in nanoseconds */
+ int clock[4]; /* master clock periods, in nanoseconds */
+ int num_clocks; /* number of available master clock speeds */
+ int ai_speed; /* maximum conversion rate in nanoseconds */
};
/* analog input range */
@@ -144,8 +133,8 @@ static const struct a2150_board a2150_boards[] = {
struct a2150_private {
struct comedi_isadma *dma;
unsigned int count; /* number of data points left to be taken */
- int irq_dma_bits; /* irq/dma register bits */
- int config_bits; /* config register bits */
+ int irq_dma_bits; /* irq/dma register bits */
+ int config_bits; /* config register bits */
};
/* interrupt service routine */
@@ -189,13 +178,13 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
*/
residue = comedi_isadma_disable(desc->chan);
- /* figure out how many points to read */
+ /* figure out how many points to read */
max_points = comedi_bytes_to_samples(s, desc->size);
num_points = max_points - comedi_bytes_to_samples(s, residue);
if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
num_points = devpriv->count;
- /* figure out how many points will be stored next time */
+ /* figure out how many points will be stored next time */
leftover = 0;
if (cmd->stop_src == TRIG_NONE) {
leftover = comedi_bytes_to_samples(s, desc->size);
@@ -204,7 +193,8 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
if (leftover > max_points)
leftover = max_points;
}
- /* there should only be a residue if collection was stopped by having
+ /*
+ * There should only be a residue if collection was stopped by having
* the stop_src set to an external trigger, in which case there
* will be no more data
*/
@@ -214,7 +204,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
for (i = 0; i < num_points; i++) {
/* write data point to comedi buffer */
dpnt = buf[i];
- /* convert from 2's complement to unsigned coding */
+ /* convert from 2's complement to unsigned coding */
dpnt ^= 0x8000;
comedi_buf_write_samples(s, &dpnt, 1);
if (cmd->stop_src == TRIG_COUNT) {
@@ -244,14 +234,14 @@ static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
struct comedi_isadma *dma = devpriv->dma;
struct comedi_isadma_desc *desc = &dma->desc[0];
- /* disable dma on card */
+ /* disable dma on card */
devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
- /* disable computer's dma */
+ /* disable computer's dma */
comedi_isadma_disable(desc->chan);
- /* clear fifo and reset triggering circuitry */
+ /* clear fifo and reset triggering circuitry */
outw(0, dev->iobase + FIFO_RESET_REG);
return 0;
@@ -270,7 +260,7 @@ static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
int i, j;
- /* initialize greatest lower and least upper bounds */
+ /* initialize greatest lower and least upper bounds */
lub_divisor_shift = 3;
lub_index = 0;
lub = board->clock[lub_index] * (1 << lub_divisor_shift);
@@ -278,19 +268,19 @@ static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
glb_index = board->num_clocks - 1;
glb = board->clock[glb_index] * (1 << glb_divisor_shift);
- /* make sure period is in available range */
+ /* make sure period is in available range */
if (*period < glb)
*period = glb;
if (*period > lub)
*period = lub;
- /* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
+ /* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
for (i = 0; i < 4; i++) {
- /* there are a maximum of 4 master clocks */
+ /* there are a maximum of 4 master clocks */
for (j = 0; j < board->num_clocks; j++) {
- /* temp is the period in nanosec we are evaluating */
+ /* temp is the period in nanosec we are evaluating */
temp = board->clock[j] * (1 << i);
- /* if it is the best match yet */
+ /* if it is the best match yet */
if (temp < lub && temp >= *period) {
lub_divisor_shift = i;
lub_index = j;
@@ -306,7 +296,7 @@ static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
switch (flags & CMDF_ROUND_MASK) {
case CMDF_ROUND_NEAREST:
default:
- /* if least upper bound is better approximation */
+ /* if least upper bound is better approximation */
if (lub - *period < *period - glb)
*period = lub;
else
@@ -320,7 +310,7 @@ static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
break;
}
- /* set clock bits for config register appropriately */
+ /* set clock bits for config register appropriately */
devpriv->config_bits &= ~CLOCK_MASK;
if (*period == lub) {
devpriv->config_bits |=
@@ -495,7 +485,7 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
"dma incompatible with hard real-time interrupt (CMDF_PRIORITY), aborting\n");
return -1;
}
- /* clear fifo and reset triggering circuitry */
+ /* clear fifo and reset triggering circuitry */
outw(0, dev->iobase + FIFO_RESET_REG);
/* setup chanlist */
@@ -503,7 +493,7 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
cmd->chanlist_len) < 0)
return -1;
- /* setup ac/dc coupling */
+ /* setup ac/dc coupling */
if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
devpriv->config_bits |= AC0_BIT;
else
@@ -513,18 +503,18 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
else
devpriv->config_bits &= ~AC1_BIT;
- /* setup timing */
+ /* setup timing */
a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
- /* send timing, channel, config bits */
+ /* send timing, channel, config bits */
outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
- /* initialize number of samples remaining */
+ /* initialize number of samples remaining */
devpriv->count = cmd->stop_arg * cmd->chanlist_len;
comedi_isadma_disable(desc->chan);
- /* set size of transfer to fill in 1/3 second */
+ /* set size of transfer to fill in 1/3 second */
#define ONE_THIRD_SECOND 333333333
desc->size = comedi_bytes_per_sample(s) * cmd->chanlist_len *
ONE_THIRD_SECOND / cmd->scan_begin_arg;
@@ -536,40 +526,45 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
comedi_isadma_program(desc);
- /* clear dma interrupt before enabling it, to try and get rid of that
- * one spurious interrupt that has been happening */
+ /*
+ * Clear dma interrupt before enabling it, to try and get rid of
+ * that one spurious interrupt that has been happening.
+ */
outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
- /* enable dma on card */
+ /* enable dma on card */
devpriv->irq_dma_bits |= DMA_INTR_EN_BIT | DMA_EN_BIT;
outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
- /* may need to wait 72 sampling periods if timing was changed */
+ /* may need to wait 72 sampling periods if timing was changed */
comedi_8254_load(dev->pacer, 2, 72, I8254_MODE0 | I8254_BINARY);
- /* setup start triggering */
+ /* setup start triggering */
trigger_bits = 0;
- /* decide if we need to wait 72 periods for valid data */
+ /* decide if we need to wait 72 periods for valid data */
if (cmd->start_src == TRIG_NOW &&
(old_config_bits & CLOCK_MASK) !=
(devpriv->config_bits & CLOCK_MASK)) {
- /* set trigger source to delay trigger */
+ /* set trigger source to delay trigger */
trigger_bits |= DELAY_TRIGGER_BITS;
} else {
- /* otherwise no delay */
+ /* otherwise no delay */
trigger_bits |= POST_TRIGGER_BITS;
}
- /* enable external hardware trigger */
+ /* enable external hardware trigger */
if (cmd->start_src == TRIG_EXT) {
trigger_bits |= HW_TRIG_EN;
} else if (cmd->start_src == TRIG_OTHER) {
- /* XXX add support for level/slope start trigger using TRIG_OTHER */
+ /*
+ * XXX add support for level/slope start trigger
+ * using TRIG_OTHER
+ */
dev_err(dev->class_dev, "you shouldn't see this?\n");
}
- /* send trigger config bits */
+ /* send trigger config bits */
outw(trigger_bits, dev->iobase + TRIGGER_REG);
- /* start acquisition for soft trigger */
+ /* start acquisition for soft trigger */
if (cmd->start_src == TRIG_NOW)
outw(0, dev->iobase + FIFO_START_REG);
@@ -596,28 +591,28 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int n;
int ret;
- /* clear fifo and reset triggering circuitry */
+ /* clear fifo and reset triggering circuitry */
outw(0, dev->iobase + FIFO_RESET_REG);
/* setup chanlist */
if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0)
return -1;
- /* set dc coupling */
+ /* set dc coupling */
devpriv->config_bits &= ~AC0_BIT;
devpriv->config_bits &= ~AC1_BIT;
- /* send timing, channel, config bits */
+ /* send timing, channel, config bits */
outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
- /* disable dma on card */
+ /* disable dma on card */
devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
- /* setup start triggering */
+ /* setup start triggering */
outw(0, dev->iobase + TRIGGER_REG);
- /* start acquisition for soft trigger */
+ /* start acquisition for soft trigger */
outw(0, dev->iobase + FIFO_START_REG);
/*
@@ -632,7 +627,7 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
inw(dev->iobase + FIFO_DATA_REG);
}
- /* read data */
+ /* read data */
for (n = 0; n < insn->n; n++) {
ret = comedi_timeout(dev, s, insn, a2150_ai_eoc, 0);
if (ret)
@@ -642,7 +637,7 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
data[n] ^= 0x8000;
}
- /* clear fifo and reset triggering circuitry */
+ /* clear fifo and reset triggering circuitry */
outw(0, dev->iobase + FIFO_RESET_REG);
return n;
@@ -749,16 +744,16 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->cancel = a2150_cancel;
}
- /* set card's irq and dma levels */
+ /* set card's irq and dma levels */
outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
- /* reset and sync adc clock circuitry */
+ /* reset and sync adc clock circuitry */
outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG);
outw_p(DPD_BIT, dev->iobase + CONFIG_REG);
- /* initialize configuration register */
+ /* initialize configuration register */
devpriv->config_bits = 0;
outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
- /* wait until offset calibration is done, then enable analog inputs */
+ /* wait until offset calibration is done, then enable analog inputs */
for (i = 0; i < timeout; i++) {
if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0)
break;
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c
index 95435b81aa55..ffcf7afce684 100644
--- a/drivers/staging/comedi/drivers/ni_atmio.c
+++ b/drivers/staging/comedi/drivers/ni_atmio.c
@@ -1,93 +1,84 @@
/*
- comedi/drivers/ni_atmio.c
- Hardware driver for NI AT-MIO E series cards
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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.
-*/
-/*
-Driver: ni_atmio
-Description: National Instruments AT-MIO-E series
-Author: ds
-Devices: [National Instruments] AT-MIO-16E-1 (ni_atmio),
- AT-MIO-16E-2, AT-MIO-16E-10, AT-MIO-16DE-10, AT-MIO-64E-3,
- AT-MIO-16XE-50, AT-MIO-16XE-10, AT-AI-16XE-10
-Status: works
-Updated: Thu May 1 20:03:02 CDT 2003
-
-The driver has 2.6 kernel isapnp support, and
-will automatically probe for a supported board if the
-I/O base is left unspecified with comedi_config.
-However, many of
-the isapnp id numbers are unknown. If your board is not
-recognized, please send the output of 'cat /proc/isapnp'
-(you may need to modprobe the isa-pnp module for
-/proc/isapnp to exist) so the
-id numbers for your board can be added to the driver.
-
-Otherwise, you can use the isapnptools package to configure
-your board. Use isapnp to
-configure the I/O base and IRQ for the board, and then pass
-the same values as
-parameters in comedi_config. A sample isapnp.conf file is included
-in the etc/ directory of Comedilib.
-
-Comedilib includes a utility to autocalibrate these boards. The
-boards seem to boot into a state where the all calibration DACs
-are at one extreme of their range, thus the default calibration
-is terrible. Calibration at boot is strongly encouraged.
-
-To use the extended digital I/O on some of the boards, enable the
-8255 driver when configuring the Comedi source tree.
-
-External triggering is supported for some events. The channel index
-(scan_begin_arg, etc.) maps to PFI0 - PFI9.
-
-Some of the more esoteric triggering possibilities of these boards
-are not supported.
-*/
-/*
- The real guts of the driver is in ni_mio_common.c, which is included
- both here and in ni_pcimio.c
-
- Interrupt support added by Truxton Fulton <trux@truxton.com>
-
- References for specifications:
-
- 340747b.pdf Register Level Programmer Manual (obsolete)
- 340747c.pdf Register Level Programmer Manual (new)
- DAQ-STC reference manual
-
- Other possibly relevant info:
-
- 320517c.pdf User manual (obsolete)
- 320517f.pdf User manual (new)
- 320889a.pdf delete
- 320906c.pdf maximum signal ratings
- 321066a.pdf about 16x
- 321791a.pdf discontinuation of at-mio-16e-10 rev. c
- 321808a.pdf about at-mio-16e-10 rev P
- 321837a.pdf discontinuation of at-mio-16de-10 rev d
- 321838a.pdf about at-mio-16de-10 rev N
-
- ISSUES:
-
- need to deal with external reference for DAC, and other DAC
- properties in board properties
+ * Comedi driver for NI AT-MIO E series cards
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
- deal with at-mio-16de-10 revision D to N changes, etc.
+/*
+ * Driver: ni_atmio
+ * Description: National Instruments AT-MIO-E series
+ * Author: ds
+ * Devices: [National Instruments] AT-MIO-16E-1 (ni_atmio),
+ * AT-MIO-16E-2, AT-MIO-16E-10, AT-MIO-16DE-10, AT-MIO-64E-3,
+ * AT-MIO-16XE-50, AT-MIO-16XE-10, AT-AI-16XE-10
+ * Status: works
+ * Updated: Thu May 1 20:03:02 CDT 2003
+ *
+ * The driver has 2.6 kernel isapnp support, and will automatically probe for
+ * a supported board if the I/O base is left unspecified with comedi_config.
+ * However, many of the isapnp id numbers are unknown. If your board is not
+ * recognized, please send the output of 'cat /proc/isapnp' (you may need to
+ * modprobe the isa-pnp module for /proc/isapnp to exist) so the id numbers
+ * for your board can be added to the driver.
+ *
+ * Otherwise, you can use the isapnptools package to configure your board.
+ * Use isapnp to configure the I/O base and IRQ for the board, and then pass
+ * the same values as parameters in comedi_config. A sample isapnp.conf file
+ * is included in the etc/ directory of Comedilib.
+ *
+ * Comedilib includes a utility to autocalibrate these boards. The boards
+ * seem to boot into a state where the all calibration DACs are at one
+ * extreme of their range, thus the default calibration is terrible.
+ * Calibration at boot is strongly encouraged.
+ *
+ * To use the extended digital I/O on some of the boards, enable the
+ * 8255 driver when configuring the Comedi source tree.
+ *
+ * External triggering is supported for some events. The channel index
+ * (scan_begin_arg, etc.) maps to PFI0 - PFI9.
+ *
+ * Some of the more esoteric triggering possibilities of these boards are
+ * not supported.
+ */
-*/
+/*
+ * The real guts of the driver is in ni_mio_common.c, which is included
+ * both here and in ni_pcimio.c
+ *
+ * Interrupt support added by Truxton Fulton <trux@truxton.com>
+ *
+ * References for specifications:
+ * 340747b.pdf Register Level Programmer Manual (obsolete)
+ * 340747c.pdf Register Level Programmer Manual (new)
+ * DAQ-STC reference manual
+ *
+ * Other possibly relevant info:
+ * 320517c.pdf User manual (obsolete)
+ * 320517f.pdf User manual (new)
+ * 320889a.pdf delete
+ * 320906c.pdf maximum signal ratings
+ * 321066a.pdf about 16x
+ * 321791a.pdf discontinuation of at-mio-16e-10 rev. c
+ * 321808a.pdf about at-mio-16e-10 rev P
+ * 321837a.pdf discontinuation of at-mio-16de-10 rev d
+ * 321838a.pdf about at-mio-16de-10 rev N
+ *
+ * ISSUES:
+ * - need to deal with external reference for DAC, and other DAC
+ * properties in board properties
+ * - deal with at-mio-16de-10 revision D to N changes, etc.
+ */
#include <linux/module.h>
#include <linux/interrupt.h>
@@ -98,10 +89,7 @@ are not supported.
#include "ni_stc.h"
#include "8255.h"
-/*
- * AT specific setup
- */
-
+/* AT specific setup */
static const struct ni_board_struct ni_boards[] = {
{
.name = "at-mio-16e-1",
@@ -215,7 +203,7 @@ static const struct ni_board_struct ni_boards[] = {
.n_adchan = 16,
.ai_maxdata = 0xffff,
.ai_fifo_depth = 512,
- .alwaysdither = 1, /* unknown */
+ .alwaysdither = 1, /* unknown */
.gainlkup = ai_gain_14,
.ai_speed = 10000,
.caldac = { dac8800, dac8043, ad8522 },
@@ -287,10 +275,10 @@ static const struct ni_board_struct *ni_atmio_probe(struct comedi_device *dev)
}
if (device_id == 255)
dev_err(dev->class_dev, "can't find board\n");
- else if (device_id == 0)
+ else if (device_id == 0)
dev_err(dev->class_dev,
"EEPROM read error (?) or device not found\n");
- else
+ else
dev_err(dev->class_dev,
"unknown device ID %d -- contact author\n", device_id);
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c
index c3eb54622bc3..fb59b0ffbba6 100644
--- a/drivers/staging/comedi/drivers/ni_atmio16d.c
+++ b/drivers/staging/comedi/drivers/ni_atmio16d.c
@@ -1,25 +1,41 @@
/*
- comedi/drivers/ni_atmio16d.c
- Hardware driver for National Instruments AT-MIO16D board
- Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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.
+ * Comedi driver for National Instruments AT-MIO16D board
+ * Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
*/
+
/*
-Driver: ni_atmio16d
-Description: National Instruments AT-MIO-16D
-Author: Chris R. Baugher <baugher@enteract.com>
-Status: unknown
-Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d)
-*/
+ * Driver: ni_atmio16d
+ * Description: National Instruments AT-MIO-16D
+ * Author: Chris R. Baugher <baugher@enteract.com>
+ * Status: unknown
+ * Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d)
+ *
+ * Configuration options:
+ * [0] - I/O port
+ * [1] - MIO irq (0 == no irq; or 3,4,5,6,7,9,10,11,12,14,15)
+ * [2] - DIO irq (0 == no irq; or 3,4,5,6,7,9)
+ * [3] - DMA1 channel (0 == no DMA; or 5,6,7)
+ * [4] - DMA2 channel (0 == no DMA; or 5,6,7)
+ * [5] - a/d mux (0=differential; 1=single)
+ * [6] - a/d range (0=bipolar10; 1=bipolar5; 2=unipolar10)
+ * [7] - dac0 range (0=bipolar; 1=unipolar)
+ * [8] - dac0 reference (0=internal; 1=external)
+ * [9] - dac0 coding (0=2's comp; 1=straight binary)
+ * [10] - dac1 range (same as dac0 options)
+ * [11] - dac1 reference (same as dac0 options)
+ * [12] - dac1 coding (same as dac0 options)
+ */
+
/*
* I must give credit here to Michal Dobes <dobes@tesnet.cz> who
* wrote the driver for Advantec's pcl812 boards. I used the interrupt
@@ -295,8 +311,10 @@ static int atmio16d_ai_cmd(struct comedi_device *dev,
unsigned int sample_count, tmp, chan, gain;
int i;
- /* This is slowly becoming a working command interface. *
- * It is still uber-experimental */
+ /*
+ * This is slowly becoming a working command interface.
+ * It is still uber-experimental
+ */
reset_counters(dev);
@@ -322,9 +340,10 @@ static int atmio16d_ai_cmd(struct comedi_device *dev,
outw(tmp, dev->iobase + MUX_GAIN_REG);
}
- /* Now program the sample interval timer */
- /* Figure out which clock to use then get an
- * appropriate timer value */
+ /*
+ * Now program the sample interval timer.
+ * Figure out which clock to use then get an appropriate timer value.
+ */
if (cmd->convert_arg < 65536000) {
base_clock = CLOCK_1_MHZ;
timer = cmd->convert_arg / 1000;
@@ -386,9 +405,10 @@ static int atmio16d_ai_cmd(struct comedi_device *dev,
outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
}
- /* Program the scan interval timer ONLY IF SCANNING IS ENABLED */
- /* Figure out which clock to use then get an
- * appropriate timer value */
+ /*
+ * Program the scan interval timer ONLY IF SCANNING IS ENABLED.
+ * Figure out which clock to use then get an appropriate timer value.
+ */
if (cmd->chanlist_len > 1) {
if (cmd->scan_begin_arg < 65536000) {
base_clock = CLOCK_1_MHZ;
@@ -566,38 +586,6 @@ static int atmio16d_dio_insn_config(struct comedi_device *dev,
return insn->n;
}
-/*
- options[0] - I/O port
- options[1] - MIO irq
- 0 == no irq
- N == irq N {3,4,5,6,7,9,10,11,12,14,15}
- options[2] - DIO irq
- 0 == no irq
- N == irq N {3,4,5,6,7,9}
- options[3] - DMA1 channel
- 0 == no DMA
- N == DMA N {5,6,7}
- options[4] - DMA2 channel
- 0 == no DMA
- N == DMA N {5,6,7}
-
- options[5] - a/d mux
- 0=differential, 1=single
- options[6] - a/d range
- 0=bipolar10, 1=bipolar5, 2=unipolar10
-
- options[7] - dac0 range
- 0=bipolar, 1=unipolar
- options[8] - dac0 reference
- 0=internal, 1=external
- options[9] - dac0 coding
- 0=2's comp, 1=straight binary
-
- options[10] - dac1 range
- options[11] - dac1 reference
- options[12] - dac1 coding
- */
-
static int atmio16d_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
index d9de83ab0267..733d3fbafa4d 100644
--- a/drivers/staging/comedi/drivers/ni_daq_dio24.c
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -1,35 +1,35 @@
/*
- comedi/drivers/ni_daq_dio24.c
- Driver for National Instruments PCMCIA DAQ-Card DIO-24
- Copyright (C) 2002 Daniel Vecino Castel <dvecino@able.es>
+ * Comedi driver for National Instruments PCMCIA DAQ-Card DIO-24
+ * Copyright (C) 2002 Daniel Vecino Castel <dvecino@able.es>
+ *
+ * PCMCIA crap at end of file is adapted from dummy_cs.c 1.31
+ * 2001/08/24 12:13:13 from the pcmcia package.
+ * The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
- PCMCIA crap at end of file is adapted from dummy_cs.c 1.31
- 2001/08/24 12:13:13 from the pcmcia package.
- The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
- <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
- are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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.
-*/
/*
-Driver: ni_daq_dio24
-Description: National Instruments PCMCIA DAQ-Card DIO-24
-Author: Daniel Vecino Castel <dvecino@able.es>
-Devices: [National Instruments] PCMCIA DAQ-Card DIO-24 (ni_daq_dio24)
-Status: ?
-Updated: Thu, 07 Nov 2002 21:53:06 -0800
-
-This is just a wrapper around the 8255.o driver to properly handle
-the PCMCIA interface.
-*/
+ * Driver: ni_daq_dio24
+ * Description: National Instruments PCMCIA DAQ-Card DIO-24
+ * Author: Daniel Vecino Castel <dvecino@able.es>
+ * Devices: [National Instruments] PCMCIA DAQ-Card DIO-24 (ni_daq_dio24)
+ * Status: ?
+ * Updated: Thu, 07 Nov 2002 21:53:06 -0800
+ *
+ * This is just a wrapper around the 8255.o driver to properly handle
+ * the PCMCIA interface.
+ */
#include <linux/module.h>
#include "../comedi_pcmcia.h"
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
index e3d821bf2d6a..21f823179356 100644
--- a/drivers/staging/comedi/drivers/ni_mio_cs.c
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -1,40 +1,39 @@
/*
- comedi/drivers/ni_mio_cs.c
- Hardware driver for NI PCMCIA MIO E series cards
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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.
-*/
-/*
-Driver: ni_mio_cs
-Description: National Instruments DAQCard E series
-Author: ds
-Status: works
-Devices: [National Instruments] DAQCard-AI-16XE-50 (ni_mio_cs),
- DAQCard-AI-16E-4, DAQCard-6062E, DAQCard-6024E, DAQCard-6036E
-Updated: Thu Oct 23 19:43:17 CDT 2003
-
-See the notes in the ni_atmio.o driver.
-*/
-/*
- The real guts of the driver is in ni_mio_common.c, which is
- included by all the E series drivers.
-
- References for specifications:
+ * Comedi driver for NI PCMCIA MIO E series cards
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
- 341080a.pdf DAQCard E Series Register Level Programmer Manual
+/*
+ * Driver: ni_mio_cs
+ * Description: National Instruments DAQCard E series
+ * Author: ds
+ * Status: works
+ * Devices: [National Instruments] DAQCard-AI-16XE-50 (ni_mio_cs),
+ * DAQCard-AI-16E-4, DAQCard-6062E, DAQCard-6024E, DAQCard-6036E
+ * Updated: Thu Oct 23 19:43:17 CDT 2003
+ *
+ * See the notes in the ni_atmio.o driver.
+ */
-*/
+/*
+ * The real guts of the driver is in ni_mio_common.c, which is
+ * included by all the E series drivers.
+ *
+ * References for specifications:
+ * 341080a.pdf DAQCard E Series Register Level Programmer Manual
+ */
#include <linux/module.h>
#include <linux/delay.h>
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index 35ef1925703f..daeb4ad7a75f 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -1,50 +1,49 @@
/*
- comedi/drivers/ni_pcidio.c
- driver for National Instruments PCI-DIO-32HS
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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.
-*/
+ * Comedi driver for National Instruments PCI-DIO-32HS
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
/*
-Driver: ni_pcidio
-Description: National Instruments PCI-DIO32HS, PCI-6533
-Author: ds
-Status: works
-Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio)
- [National Instruments] PXI-6533, PCI-6533 (pxi-6533)
- [National Instruments] PCI-6534 (pci-6534)
-Updated: Mon, 09 Jan 2012 14:27:23 +0000
-
-The DIO32HS board appears as one subdevice, with 32 channels.
-Each channel is individually I/O configurable. The channel order
-is 0=A0, 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0. The driver only
-supports simple digital I/O; no handshaking is supported.
-
-DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
-
-The PCI-DIO-32HS/PCI-6533 has a configurable external trigger. Setting
-scan_begin_arg to 0 or CR_EDGE triggers on the leading edge. Setting
-scan_begin_arg to CR_INVERT or (CR_EDGE | CR_INVERT) triggers on the
-trailing edge.
-
-This driver could be easily modified to support AT-MIO32HS and
-AT-MIO96.
-
-The PCI-6534 requires a firmware upload after power-up to work, the
-firmware data and instructions for loading it with comedi_config
-it are contained in the
-comedi_nonfree_firmware tarball available from http://www.comedi.org
-*/
+ * Driver: ni_pcidio
+ * Description: National Instruments PCI-DIO32HS, PCI-6533
+ * Author: ds
+ * Status: works
+ * Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio)
+ * [National Instruments] PXI-6533, PCI-6533 (pxi-6533)
+ * [National Instruments] PCI-6534 (pci-6534)
+ * Updated: Mon, 09 Jan 2012 14:27:23 +0000
+ *
+ * The DIO32HS board appears as one subdevice, with 32 channels. Each
+ * channel is individually I/O configurable. The channel order is 0=A0,
+ * 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0. The driver only supports simple
+ * digital I/O; no handshaking is supported.
+ *
+ * DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
+ *
+ * The PCI-DIO-32HS/PCI-6533 has a configurable external trigger. Setting
+ * scan_begin_arg to 0 or CR_EDGE triggers on the leading edge. Setting
+ * scan_begin_arg to CR_INVERT or (CR_EDGE | CR_INVERT) triggers on the
+ * trailing edge.
+ *
+ * This driver could be easily modified to support AT-MIO32HS and AT-MIO96.
+ *
+ * The PCI-6534 requires a firmware upload after power-up to work, the
+ * firmware data and instructions for loading it with comedi_config
+ * it are contained in the comedi_nonfree_firmware tarball available from
+ * http://www.comedi.org
+ */
#define USE_DMA
@@ -61,36 +60,36 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org
#define Window_Address 4 /* W */
#define Interrupt_And_Window_Status 4 /* R */
-#define IntStatus1 (1<<0)
-#define IntStatus2 (1<<1)
+#define IntStatus1 BIT(0)
+#define IntStatus2 BIT(1)
#define WindowAddressStatus_mask 0x7c
#define Master_DMA_And_Interrupt_Control 5 /* W */
#define InterruptLine(x) ((x)&3)
-#define OpenInt (1<<2)
+#define OpenInt BIT(2)
#define Group_Status 5 /* R */
-#define DataLeft (1<<0)
-#define Req (1<<2)
-#define StopTrig (1<<3)
+#define DataLeft BIT(0)
+#define Req BIT(2)
+#define StopTrig BIT(3)
#define Group_1_Flags 6 /* R */
#define Group_2_Flags 7 /* R */
-#define TransferReady (1<<0)
-#define CountExpired (1<<1)
-#define Waited (1<<5)
-#define PrimaryTC (1<<6)
-#define SecondaryTC (1<<7)
+#define TransferReady BIT(0)
+#define CountExpired BIT(1)
+#define Waited BIT(5)
+#define PrimaryTC BIT(6)
+#define SecondaryTC BIT(7)
/* #define SerialRose */
/* #define ReqRose */
/* #define Paused */
#define Group_1_First_Clear 6 /* W */
#define Group_2_First_Clear 7 /* W */
-#define ClearWaited (1<<3)
-#define ClearPrimaryTC (1<<4)
-#define ClearSecondaryTC (1<<5)
-#define DMAReset (1<<6)
-#define FIFOReset (1<<7)
+#define ClearWaited BIT(3)
+#define ClearPrimaryTC BIT(4)
+#define ClearSecondaryTC BIT(5)
+#define DMAReset BIT(6)
+#define FIFOReset BIT(7)
#define ClearAll 0xf8
#define Group_1_FIFO 8 /* W */
@@ -111,27 +110,27 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org
#define Group_1_Second_Clear 46 /* W */
#define Group_2_Second_Clear 47 /* W */
-#define ClearExpired (1<<0)
+#define ClearExpired BIT(0)
#define Port_Pattern(x) (48+(x))
#define Data_Path 64
-#define FIFOEnableA (1<<0)
-#define FIFOEnableB (1<<1)
-#define FIFOEnableC (1<<2)
-#define FIFOEnableD (1<<3)
+#define FIFOEnableA BIT(0)
+#define FIFOEnableB BIT(1)
+#define FIFOEnableC BIT(2)
+#define FIFOEnableD BIT(3)
#define Funneling(x) (((x)&3)<<4)
-#define GroupDirection (1<<7)
+#define GroupDirection BIT(7)
#define Protocol_Register_1 65
#define OpMode Protocol_Register_1
#define RunMode(x) ((x)&7)
-#define Numbered (1<<3)
+#define Numbered BIT(3)
#define Protocol_Register_2 66
#define ClockReg Protocol_Register_2
#define ClockLine(x) (((x)&3)<<5)
-#define InvertStopTrig (1<<7)
+#define InvertStopTrig BIT(7)
#define DataLatching(x) (((x)&3)<<5)
#define Protocol_Register_3 67
@@ -152,17 +151,17 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org
#define Protocol_Register_6 73
#define LinePolarities Protocol_Register_6
-#define InvertAck (1<<0)
-#define InvertReq (1<<1)
-#define InvertClock (1<<2)
-#define InvertSerial (1<<3)
-#define OpenAck (1<<4)
-#define OpenClock (1<<5)
+#define InvertAck BIT(0)
+#define InvertReq BIT(1)
+#define InvertClock BIT(2)
+#define InvertSerial BIT(3)
+#define OpenAck BIT(4)
+#define OpenClock BIT(5)
#define Protocol_Register_7 74
#define AckSer Protocol_Register_7
#define AckLine(x) (((x)&3)<<2)
-#define ExchangePins (1<<7)
+#define ExchangePins BIT(7)
#define Interrupt_Control 75
/* bits same as flags */
@@ -183,20 +182,20 @@ static inline unsigned int secondary_DMAChannel_bits(unsigned int channel)
#define Transfer_Size_Control 77
#define TransferWidth(x) ((x)&3)
#define TransferLength(x) (((x)&3)<<3)
-#define RequireRLevel (1<<5)
+#define RequireRLevel BIT(5)
#define Protocol_Register_15 79
#define DAQOptions Protocol_Register_15
#define StartSource(x) ((x)&0x3)
-#define InvertStart (1<<2)
+#define InvertStart BIT(2)
#define StopSource(x) (((x)&0x3)<<3)
-#define ReqStart (1<<6)
-#define PreStart (1<<7)
+#define ReqStart BIT(6)
+#define PreStart BIT(7)
#define Pattern_Detection 81
-#define DetectionMethod (1<<0)
-#define InvertMatch (1<<1)
-#define IE_Pattern_Detection (1<<2)
+#define DetectionMethod BIT(0)
+#define InvertMatch BIT(1)
+#define IE_Pattern_Detection BIT(2)
#define Protocol_Register_9 82
#define ReqDelay Protocol_Register_9
@@ -649,8 +648,10 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
writeb(1, dev->mmio + AckDelay);
writeb(0x0b, dev->mmio + AckNotDelay);
writeb(0x01, dev->mmio + Data1Delay);
- /* manual, page 4-5: ClockSpeed comment is incorrectly listed
- * on DAQOptions */
+ /*
+ * manual, page 4-5:
+ * ClockSpeed comment is incorrectly listed on DAQOptions
+ */
writew(0, dev->mmio + ClockSpeed);
writeb(0, dev->mmio + DAQOptions);
} else {
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
index d8917392b9f9..f13a2f7360b3 100644
--- a/drivers/staging/comedi/drivers/ni_pcimio.c
+++ b/drivers/staging/comedi/drivers/ni_pcimio.c
@@ -1,111 +1,106 @@
/*
- comedi/drivers/ni_pcimio.c
- Hardware driver for NI PCI-MIO E series cards
+ * Comedi driver for NI PCI-MIO E series cards
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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.
-*/
/*
-Driver: ni_pcimio
-Description: National Instruments PCI-MIO-E series and M series (all boards)
-Author: ds, John Hallen, Frank Mori Hess, Rolf Mueller, Herbert Peremans,
- Herman Bruyninckx, Terry Barnaby
-Status: works
-Devices: [National Instruments] PCI-MIO-16XE-50 (ni_pcimio),
- PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014, PCI-6040E,
- PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E,
- PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E,
- PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224,
- PCI-6225, PXI-6225, PCI-6229, PCI-6250,
- PCI-6251, PXI-6251, PCIe-6251, PXIe-6251,
- PCI-6254, PCI-6259, PCIe-6259,
- PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289,
- PCI-6711, PXI-6711, PCI-6713, PXI-6713,
- PXI-6071E, PCI-6070E, PXI-6070E,
- PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733,
- PCI-6143, PXI-6143
-Updated: Mon, 09 Jan 2012 14:52:48 +0000
-
-These boards are almost identical to the AT-MIO E series, except that
-they use the PCI bus instead of ISA (i.e., AT). See the notes for
-the ni_atmio.o driver for additional information about these boards.
-
-Autocalibration is supported on many of the devices, using the
-comedi_calibrate (or comedi_soft_calibrate for m-series) utility.
-M-Series boards do analog input and analog output calibration entirely
-in software. The software calibration corrects
-the analog input for offset, gain and
-nonlinearity. The analog outputs are corrected for offset and gain.
-See the comedilib documentation on comedi_get_softcal_converter() for
-more information.
-
-By default, the driver uses DMA to transfer analog input data to
-memory. When DMA is enabled, not all triggering features are
-supported.
-
-Digital I/O may not work on 673x.
-
-Note that the PCI-6143 is a simultaineous sampling device with 8 convertors.
-With this board all of the convertors perform one simultaineous sample during
-a scan interval. The period for a scan is used for the convert time in a
-Comedi cmd. The convert trigger source is normally set to TRIG_NOW by default.
-
-The RTSI trigger bus is supported on these cards on
-subdevice 10. See the comedilib documentation for details.
-
-Information (number of channels, bits, etc.) for some devices may be
-incorrect. Please check this and submit a bug if there are problems
-for your device.
-
-SCXI is probably broken for m-series boards.
-
-Bugs:
- - When DMA is enabled, COMEDI_EV_CONVERT does
- not work correctly.
+ * Driver: ni_pcimio
+ * Description: National Instruments PCI-MIO-E series and M series (all boards)
+ * Author: ds, John Hallen, Frank Mori Hess, Rolf Mueller, Herbert Peremans,
+ * Herman Bruyninckx, Terry Barnaby
+ * Status: works
+ * Devices: [National Instruments] PCI-MIO-16XE-50 (ni_pcimio),
+ * PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014,
+ * PCI-6040E, PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E,
+ * PCI-6071E, PCI-6023E, PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E,
+ * PCI-6035E, PCI-6052E,
+ * PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224,
+ * PCI-6225, PXI-6225, PCI-6229, PCI-6250,
+ * PCI-6251, PXI-6251, PCIe-6251, PXIe-6251,
+ * PCI-6254, PCI-6259, PCIe-6259,
+ * PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289,
+ * PCI-6711, PXI-6711, PCI-6713, PXI-6713,
+ * PXI-6071E, PCI-6070E, PXI-6070E,
+ * PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733,
+ * PCI-6143, PXI-6143
+ * Updated: Mon, 09 Jan 2012 14:52:48 +0000
+ *
+ * These boards are almost identical to the AT-MIO E series, except that
+ * they use the PCI bus instead of ISA (i.e., AT). See the notes for the
+ * ni_atmio.o driver for additional information about these boards.
+ *
+ * Autocalibration is supported on many of the devices, using the
+ * comedi_calibrate (or comedi_soft_calibrate for m-series) utility.
+ * M-Series boards do analog input and analog output calibration entirely
+ * in software. The software calibration corrects the analog input for
+ * offset, gain and nonlinearity. The analog outputs are corrected for
+ * offset and gain. See the comedilib documentation on
+ * comedi_get_softcal_converter() for more information.
+ *
+ * By default, the driver uses DMA to transfer analog input data to
+ * memory. When DMA is enabled, not all triggering features are
+ * supported.
+ *
+ * Digital I/O may not work on 673x.
+ *
+ * Note that the PCI-6143 is a simultaineous sampling device with 8
+ * convertors. With this board all of the convertors perform one
+ * simultaineous sample during a scan interval. The period for a scan
+ * is used for the convert time in a Comedi cmd. The convert trigger
+ * source is normally set to TRIG_NOW by default.
+ *
+ * The RTSI trigger bus is supported on these cards on subdevice 10.
+ * See the comedilib documentation for details.
+ *
+ * Information (number of channels, bits, etc.) for some devices may be
+ * incorrect. Please check this and submit a bug if there are problems
+ * for your device.
+ *
+ * SCXI is probably broken for m-series boards.
+ *
+ * Bugs:
+ * - When DMA is enabled, COMEDI_EV_CONVERT does not work correctly.
+ */
-*/
/*
- The PCI-MIO E series driver was originally written by
- Tomasz Motylewski <...>, and ported to comedi by ds.
-
- References:
-
- 341079b.pdf PCI E Series Register-Level Programmer Manual
- 340934b.pdf DAQ-STC reference manual
-
- 322080b.pdf 6711/6713/6715 User Manual
-
- 320945c.pdf PCI E Series User Manual
- 322138a.pdf PCI-6052E and DAQPad-6052E User Manual
-
- ISSUES:
-
- need to deal with external reference for DAC, and other DAC
- properties in board properties
-
- deal with at-mio-16de-10 revision D to N changes, etc.
-
- need to add other CALDAC type
-
- need to slow down DAC loading. I don't trust NI's claim that
- two writes to the PCI bus slows IO enough. I would prefer to
- use udelay(). Timing specs: (clock)
- AD8522 30ns
- DAC8043 120ns
- DAC8800 60ns
- MB88341 ?
-
-*/
+ * The PCI-MIO E series driver was originally written by
+ * Tomasz Motylewski <...>, and ported to comedi by ds.
+ *
+ * References:
+ * 341079b.pdf PCI E Series Register-Level Programmer Manual
+ * 340934b.pdf DAQ-STC reference manual
+ *
+ * 322080b.pdf 6711/6713/6715 User Manual
+ *
+ * 320945c.pdf PCI E Series User Manual
+ * 322138a.pdf PCI-6052E and DAQPad-6052E User Manual
+ *
+ * ISSUES:
+ * - need to deal with external reference for DAC, and other DAC
+ * properties in board properties
+ * - deal with at-mio-16de-10 revision D to N changes, etc.
+ * - need to add other CALDAC type
+ * - need to slow down DAC loading. I don't trust NI's claim that
+ * two writes to the PCI bus slows IO enough. I would prefer to
+ * use udelay().
+ * Timing specs: (clock)
+ * AD8522 30ns
+ * DAC8043 120ns
+ * DAC8800 60ns
+ * MB88341 ?
+ */
#include <linux/module.h>
#include <linux/delay.h>
@@ -119,13 +114,14 @@ Bugs:
#define PCIDMA
-/* These are not all the possible ao ranges for 628x boards.
- They can do OFFSET +- REFERENCE where OFFSET can be
- 0V, 5V, APFI<0,1>, or AO<0...3> and RANGE can
- be 10V, 5V, 2V, 1V, APFI<0,1>, AO<0...3>. That's
- 63 different possibilities. An AO channel
- can not act as it's own OFFSET or REFERENCE.
-*/
+/*
+ * These are not all the possible ao ranges for 628x boards.
+ * They can do OFFSET +- REFERENCE where OFFSET can be
+ * 0V, 5V, APFI<0,1>, or AO<0...3> and RANGE can
+ * be 10V, 5V, 2V, 1V, APFI<0,1>, AO<0...3>. That's
+ * 63 different possibilities. An AO channel
+ * can not act as it's own OFFSET or REFERENCE.
+ */
static const struct comedi_lrange range_ni_M_628x_ao = {
8, {
BIP_RANGE(10),
diff --git a/drivers/staging/comedi/drivers/ni_usb6501.c b/drivers/staging/comedi/drivers/ni_usb6501.c
index 95b537a8ecdb..5036eebb9162 100644
--- a/drivers/staging/comedi/drivers/ni_usb6501.c
+++ b/drivers/staging/comedi/drivers/ni_usb6501.c
@@ -465,12 +465,12 @@ static int ni6501_alloc_usb_buffers(struct comedi_device *dev)
struct ni6501_private *devpriv = dev->private;
size_t size;
- size = le16_to_cpu(devpriv->ep_rx->wMaxPacketSize);
+ size = usb_endpoint_maxp(devpriv->ep_rx);
devpriv->usb_rx_buf = kzalloc(size, GFP_KERNEL);
if (!devpriv->usb_rx_buf)
return -ENOMEM;
- size = le16_to_cpu(devpriv->ep_tx->wMaxPacketSize);
+ size = usb_endpoint_maxp(devpriv->ep_tx);
devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL);
if (!devpriv->usb_tx_buf) {
kfree(devpriv->usb_rx_buf);
diff --git a/drivers/staging/comedi/drivers/plx9080.h b/drivers/staging/comedi/drivers/plx9080.h
index 0e20cc5c9a69..e23e63a097b5 100644
--- a/drivers/staging/comedi/drivers/plx9080.h
+++ b/drivers/staging/comedi/drivers/plx9080.h
@@ -60,9 +60,9 @@ struct plx_dma_desc {
#define PLX_REG_LAS1RR 0x00f0
#define PLX_LASRR_IO BIT(0) /* Map to: 1=I/O, 0=Mem */
-#define PLX_LASRR_ANY32 (BIT(1) * 0) /* Locate anywhere in 32 bit */
-#define PLX_LASRR_LT1MB (BIT(1) * 1) /* Locate in 1st meg */
-#define PLX_LASRR_ANY64 (BIT(1) * 2) /* Locate anywhere in 64 bit */
+#define PLX_LASRR_MLOC_ANY32 (BIT(1) * 0) /* Locate anywhere in 32 bit */
+#define PLX_LASRR_MLOC_LT1MB (BIT(1) * 1) /* Locate in 1st meg */
+#define PLX_LASRR_MLOC_ANY64 (BIT(1) * 2) /* Locate anywhere in 64 bit */
#define PLX_LASRR_MLOC_MASK GENMASK(2, 1) /* Memory location bits */
#define PLX_LASRR_PREFETCH BIT(3) /* Memory is prefetchable */
/* bits that specify range for memory space decode bits */
@@ -89,11 +89,11 @@ struct plx_dma_desc {
/* Local Bus Latency Timer */
#define PLX_MARBR_LT(x) (BIT(0) * ((x) & 0xff))
#define PLX_MARBR_LT_MASK GENMASK(7, 0)
-#define PLX_MARBR_LT_SHIFT 0
+#define PLX_MARBR_TO_LT(r) ((r) & PLX_MARBR_LT_MASK)
/* Local Bus Pause Timer */
#define PLX_MARBR_PT(x) (BIT(8) * ((x) & 0xff))
#define PLX_MARBR_PT_MASK GENMASK(15, 8)
-#define PLX_MARBR_PT_SHIFT 8
+#define PLX_MARBR_TO_PT(r) (((r) & PLX_MARBR_PT_MASK) >> 8)
/* Local Bus Latency Timer Enable */
#define PLX_MARBR_LTEN BIT(16)
/* Local Bus Pause Timer Enable */
@@ -166,16 +166,15 @@ struct plx_dma_desc {
#define PLX_REG_LBRD1 0x00f8
/* Memory Space Local Bus Width */
-#define PLX_LBRD_MSWIDTH8 (BIT(0) * 0) /* 8 bits wide */
-#define PLX_LBRD_MSWIDTH16 (BIT(0) * 1) /* 16 bits wide */
-#define PLX_LBRD_MSWIDTH32 (BIT(0) * 2) /* 32 bits wide */
-#define PLX_LBRD_MSWIDTH32A (BIT(0) * 3) /* 32 bits wide */
+#define PLX_LBRD_MSWIDTH_8 (BIT(0) * 0) /* 8 bits wide */
+#define PLX_LBRD_MSWIDTH_16 (BIT(0) * 1) /* 16 bits wide */
+#define PLX_LBRD_MSWIDTH_32 (BIT(0) * 2) /* 32 bits wide */
+#define PLX_LBRD_MSWIDTH_32A (BIT(0) * 3) /* 32 bits wide */
#define PLX_LBRD_MSWIDTH_MASK GENMASK(1, 0)
-#define PLX_LBRD_MSWIDTH_SHIFT 0
/* Memory Space Internal Wait States */
#define PLX_LBRD_MSIWS(x) (BIT(2) * ((x) & 0xf))
#define PLX_LBRD_MSIWS_MASK GENMASK(5, 2)
-#define PLX_LBRD_MSIWS_SHIFT 2
+#define PLX_LBRD_TO_MSIWS(r) (((r) & PLS_LBRD_MSIWS_MASK) >> 2)
/* Memory Space Ready Input Enable */
#define PLX_LBRD_MSREADYIEN BIT(6)
/* Memory Space BTERM# Input Enable */
@@ -193,18 +192,17 @@ struct plx_dma_desc {
/* Prefetch Counter */
#define PLX_LBRD_PFCOUNT(x) (BIT(11) * ((x) & 0xf))
#define PLX_LBRD_PFCOUNT_MASK GENMASK(14, 11)
-#define PLX_LBRD_PFCOUNT_SHIFT 11
+#define PLX_LBRD_TO_PFCOUNT(r) (((r) & PLX_LBRD_PFCOUNT_MASK) >> 11)
/* Expansion ROM Space Local Bus Width (LBRD0 only) */
-#define PLX_LBRD0_EROMWIDTH8 (BIT(16) * 0) /* 8 bits wide */
-#define PLX_LBRD0_EROMWIDTH16 (BIT(16) * 1) /* 16 bits wide */
-#define PLX_LBRD0_EROMWIDTH32 (BIT(16) * 2) /* 32 bits wide */
-#define PLX_LBRD0_EROMWIDTH32A (BIT(16) * 3) /* 32 bits wide */
+#define PLX_LBRD0_EROMWIDTH_8 (BIT(16) * 0) /* 8 bits wide */
+#define PLX_LBRD0_EROMWIDTH_16 (BIT(16) * 1) /* 16 bits wide */
+#define PLX_LBRD0_EROMWIDTH_32 (BIT(16) * 2) /* 32 bits wide */
+#define PLX_LBRD0_EROMWIDTH_32A (BIT(16) * 3) /* 32 bits wide */
#define PLX_LBRD0_EROMWIDTH_MASK GENMASK(17, 16)
-#define PLX_LBRD0_EROMWIDTH_SHIFT 16
/* Expansion ROM Space Internal Wait States (LBRD0 only) */
#define PLX_LBRD0_EROMIWS(x) (BIT(18) * ((x) & 0xf))
#define PLX_LBRD0_EROMIWS_MASK GENMASK(21, 18)
-#define PLX_LBRD0_EROMIWS_SHIFT 18
+#define PLX_LBRD0_TO_EROMIWS(r) (((r) & PLX_LBRD0_EROMIWS_MASK) >> 18)
/* Expansion ROM Space Ready Input Enable (LBDR0 only) */
#define PLX_LBRD0_EROMREADYIEN BIT(22)
/* Expansion ROM Space BTERM# Input Enable (LBRD0 only) */
@@ -220,7 +218,7 @@ struct plx_dma_desc {
/* PCI Target Retry Delay Clocks / 8 (LBRD0 only) */
#define PLX_LBRD0_TRDELAY(x) (BIT(28) * ((x) & 0xF))
#define PLX_LBRD0_TRDELAY_MASK GENMASK(31, 28)
-#define PLX_LBRD0_TRDELAY_SHIFT 28
+#define PLX_LBRD0_TO_TRDELAY(r) (((r) & PLX_LBRD0_TRDELAY_MASK) >> 28)
/* Local Range Register for Direct Master to PCI */
#define PLX_REG_DMRR 0x001c
@@ -241,10 +239,10 @@ struct plx_dma_desc {
/* LLOCK# Input Enable */
#define PLX_DMPBAM_LLOCKIEN BIT(2)
/* Direct Master Read Prefetch Size Control (bits 12, 3) */
-#define PLX_DMPBAM_RPSIZECONT ((BIT(12) * 0) | (BIT(3) * 0))
-#define PLX_DMPBAM_RPSIZE4 ((BIT(12) * 0) | (BIT(3) * 1))
-#define PLX_DMPBAM_RPSIZE8 ((BIT(12) * 1) | (BIT(3) * 0))
-#define PLX_DMPBAM_RPSIZE16 ((BIT(12) * 1) | (BIT(3) * 1))
+#define PLX_DMPBAM_RPSIZE_CONT ((BIT(12) * 0) | (BIT(3) * 0))
+#define PLX_DMPBAM_RPSIZE_4 ((BIT(12) * 0) | (BIT(3) * 1))
+#define PLX_DMPBAM_RPSIZE_8 ((BIT(12) * 1) | (BIT(3) * 0))
+#define PLX_DMPBAM_RPSIZE_16 ((BIT(12) * 1) | (BIT(3) * 1))
#define PLX_DMPBAM_RPSIZE_MASK (BIT(12) | BIT(3))
/* Direct Master PCI Read Mode - deassert IRDY when FIFO full */
#define PLX_DMPBAM_RMIRDY BIT(4)
@@ -261,10 +259,10 @@ struct plx_dma_desc {
/* I/O Remap Select */
#define PLX_DMPBAM_IOREMAPSEL BIT(13)
/* Direct Master Write Delay */
-#define PLX_DMPBAM_WDELAYNONE (BIT(14) * 0)
-#define PLX_DMPBAM_WDELAY4 (BIT(14) * 1)
-#define PLX_DMPBAM_WDELAY8 (BIT(14) * 2)
-#define PLX_DMPBAM_WDELAY16 (BIT(14) * 3)
+#define PLX_DMPBAM_WDELAY_NONE (BIT(14) * 0)
+#define PLX_DMPBAM_WDELAY_4 (BIT(14) * 1)
+#define PLX_DMPBAM_WDELAY_8 (BIT(14) * 2)
+#define PLX_DMPBAM_WDELAY_16 (BIT(14) * 3)
#define PLX_DMPBAM_WDELAY_MASK GENMASK(15, 14)
/* Remap of Local-to-PCI Space Into PCI Address Space */
#define PLX_DMPBAM_REMAP_MASK GENMASK(31, 16)
@@ -279,19 +277,19 @@ struct plx_dma_desc {
/* Register Number */
#define PLX_DMCFGA_REGNUM(x) (BIT(2) * ((x) & 0x3f))
#define PLX_DMCFGA_REGNUM_MASK GENMASK(7, 2)
-#define PLX_DMCFGA_REGNUM_SHIFT 2
+#define PLX_DMCFGA_TO_REGNUM(r) (((r) & PLX_DMCFGA_REGNUM_MASK) >> 2)
/* Function Number */
#define PLX_DMCFGA_FUNCNUM(x) (BIT(8) * ((x) & 0x7))
#define PLX_DMCFGA_FUNCNUM_MASK GENMASK(10, 8)
-#define PLX_DMCFGA_FUNCNUM_SHIFT 8
+#define PLX_DMCFGA_TO_FUNCNUM(r) (((r) & PLX_DMCFGA_FUNCNUM_MASK) >> 8)
/* Device Number */
#define PLX_DMCFGA_DEVNUM(x) (BIT(11) * ((x) & 0x1f))
#define PLX_DMCFGA_DEVNUM_MASK GENMASK(15, 11)
-#define PLX_DMCFGA_DEVNUM_SHIFT 11
+#define PLX_DMCFGA_TO_DEVNUM(r) (((r) & PLX_DMCFGA_DEVNUM_MASK) >> 11)
/* Bus Number */
#define PLX_DMCFGA_BUSNUM(x) (BIT(16) * ((x) & 0xff))
#define PLX_DMCFGA_BUSNUM_MASK GENMASK(23, 16)
-#define PLX_DMCFGA_BUSNUM_SHIFT 16
+#define PLX_DMCFGA_TO_BUSNUM(r) (((r) & PLX_DMCFGA_BUSNUM_MASK) >> 16)
/* Configuration Enable */
#define PLX_DMCFGA_CONFIGEN BIT(31)
@@ -402,22 +400,22 @@ struct plx_dma_desc {
/* PCI Read Command Code For DMA */
#define PLX_CNTRL_CCRDMA(x) (BIT(0) * ((x) & 0xf))
#define PLX_CNTRL_CCRDMA_MASK GENMASK(3, 0)
-#define PLX_CNTRL_CCRDMA_SHIFT 0
+#define PLX_CNTRL_TO_CCRDMA(r) ((r) & PLX_CNTRL_CCRDMA_MASK)
#define PLX_CNTRL_CCRDMA_NORMAL PLX_CNTRL_CCRDMA(14) /* value after reset */
/* PCI Write Command Code For DMA 0 */
#define PLX_CNTRL_CCWDMA(x) (BIT(4) * ((x) & 0xf))
#define PLX_CNTRL_CCWDMA_MASK GENMASK(7, 4)
-#define PLX_CNTRL_CCWDMA_SHIFT 4
+#define PLX_CNTRL_TO_CCWDMA(r) (((r) & PLX_CNTRL_CCWDMA_MASK) >> 4)
#define PLX_CNTRL_CCWDMA_NORMAL PLX_CNTRL_CCWDMA(7) /* value after reset */
/* PCI Memory Read Command Code For Direct Master */
#define PLX_CNTRL_CCRDM(x) (BIT(8) * ((x) & 0xf))
#define PLX_CNTRL_CCRDM_MASK GENMASK(11, 8)
-#define PLX_CNTRL_CCRDM_SHIFT 8
+#define PLX_CNTRL_TO_CCRDM(r) (((r) & PLX_CNTRL_CCRDM_MASK) >> 8)
#define PLX_CNTRL_CCRDM_NORMAL PLX_CNTRL_CCRDM(6) /* value after reset */
/* PCI Memory Write Command Code For Direct Master */
#define PLX_CNTRL_CCWDM(x) (BIT(12) * ((x) & 0xf))
#define PLX_CNTRL_CCWDM_MASK GENMASK(15, 12)
-#define PLX_CNTRL_CCWDM_SHIFT 12
+#define PLX_CNTRL_TO_CCWDM(r) (((r) & PLX_CNTRL_CCWDM_MASK) >> 12)
#define PLX_CNTRL_CCWDM_NORMAL PLX_CNTRL_CCWDM(7) /* value after reset */
/* General Purpose Output (USERO) */
#define PLX_CNTRL_USERO BIT(16)
@@ -464,16 +462,15 @@ struct plx_dma_desc {
#define PLX_REG_DMAMODE1 0x0094
/* Local Bus Width */
-#define PLX_DMAMODE_WIDTH8 (BIT(0) * 0) /* 8 bits wide */
-#define PLX_DMAMODE_WIDTH16 (BIT(0) * 1) /* 16 bits wide */
-#define PLX_DMAMODE_WIDTH32 (BIT(0) * 2) /* 32 bits wide */
-#define PLX_DMAMODE_WIDTH32A (BIT(0) * 3) /* 32 bits wide */
+#define PLX_DMAMODE_WIDTH_8 (BIT(0) * 0) /* 8 bits wide */
+#define PLX_DMAMODE_WIDTH_16 (BIT(0) * 1) /* 16 bits wide */
+#define PLX_DMAMODE_WIDTH_32 (BIT(0) * 2) /* 32 bits wide */
+#define PLX_DMAMODE_WIDTH_32A (BIT(0) * 3) /* 32 bits wide */
#define PLX_DMAMODE_WIDTH_MASK GENMASK(1, 0)
-#define PLX_DMAMODE_WIDTH_SHIFT 0
/* Internal Wait States */
#define PLX_DMAMODE_IWS(x) (BIT(2) * ((x) & 0xf))
#define PLX_DMAMODE_IWS_MASK GENMASK(5, 2)
-#define PLX_DMAMODE_SHIFT 2
+#define PLX_DMAMODE_TO_IWS(r) (((r) & PLX_DMAMODE_IWS_MASK) >> 2)
/* Ready Input Enable */
#define PLX_DMAMODE_READYIEN BIT(6)
/* BTERM# Input Enable */
@@ -560,35 +557,35 @@ struct plx_dma_desc {
/* DMA Channel 0 PCI-to-Local Almost Full (divided by 2, minus 1) */
#define PLX_DMATHR_C0PLAF(x) (BIT(0) * ((x) & 0xf))
#define PLX_DMATHR_C0PLAF_MASK GENMASK(3, 0)
-#define PLX_DMATHR_C0PLAF_SHIFT 0
+#define PLX_DMATHR_TO_C0PLAF(r) ((r) & PLX_DMATHR_C0PLAF_MASK)
/* DMA Channel 0 Local-to-PCI Almost Empty (divided by 2, minus 1) */
#define PLX_DMATHR_C0LPAE(x) (BIT(4) * ((x) & 0xf))
#define PLX_DMATHR_C0LPAE_MASK GENMASK(7, 4)
-#define PLX_DMATHR_C0LPAE_SHIFT 4
+#define PLX_DMATHR_TO_C0LPAE(r) (((r) & PLX_DMATHR_C0LPAE_MASK) >> 4)
/* DMA Channel 0 Local-to-PCI Almost Full (divided by 2, minus 1) */
#define PLX_DMATHR_C0LPAF(x) (BIT(8) * ((x) & 0xf))
#define PLX_DMATHR_C0LPAF_MASK GENMASK(11, 8)
-#define PLX_DMATHR_C0LPAF_SHIFT 8
+#define PLX_DMATHR_TO_C0LPAF(r) (((r) & PLX_DMATHR_C0LPAF_MASK) >> 8)
/* DMA Channel 0 PCI-to-Local Almost Empty (divided by 2, minus 1) */
#define PLX_DMATHR_C0PLAE(x) (BIT(12) * ((x) & 0xf))
#define PLX_DMATHR_C0PLAE_MASK GENMASK(15, 12)
-#define PLX_DMATHR_C0PLAE_SHIFT 12
+#define PLX_DMATHR_TO_C0PLAE(r) (((r) & PLX_DMATHR_C0PLAE_MASK) >> 12)
/* DMA Channel 1 PCI-to-Local Almost Full (divided by 2, minus 1) */
#define PLX_DMATHR_C1PLAF(x) (BIT(16) * ((x) & 0xf))
#define PLX_DMATHR_C1PLAF_MASK GENMASK(19, 16)
-#define PLX_DMATHR_C1PLAF_SHIFT 16
+#define PLX_DMATHR_TO_C1PLAF(r) (((r) & PLX_DMATHR_C1PLAF_MASK) >> 16)
/* DMA Channel 1 Local-to-PCI Almost Empty (divided by 2, minus 1) */
#define PLX_DMATHR_C1LPAE(x) (BIT(20) * ((x) & 0xf))
#define PLX_DMATHR_C1LPAE_MASK GENMASK(23, 20)
-#define PLX_DMATHR_C1LPAE_SHIFT 20
+#define PLX_DMATHR_TO_C1LPAE(r) (((r) & PLX_DMATHR_C1LPAE_MASK) >> 20)
/* DMA Channel 1 Local-to-PCI Almost Full (divided by 2, minus 1) */
#define PLX_DMATHR_C1LPAF(x) (BIT(24) * ((x) & 0xf))
#define PLX_DMATHR_C1LPAF_MASK GENMASK(27, 24)
-#define PLX_DMATHR_C1LPAF_SHIFT 24
+#define PLX_DMATHR_TO_C1LPAF(r) (((r) & PLX_DMATHR_C1LPAF_MASK) >> 24)
/* DMA Channel 1 PCI-to-Local Almost Empty (divided by 2, minus 1) */
#define PLX_DMATHR_C1PLAE(x) (BIT(28) * ((x) & 0xf))
#define PLX_DMATHR_C1PLAE_MASK GENMASK(31, 28)
-#define PLX_DMATHR_C1PLAE_SHIFT 28
+#define PLX_DMATHR_TO_C1PLAE(r) (((r) & PLX_DMATHR_C1PLAE_MASK) >> 28)
/*
* Messaging Queue Registers OPLFIS, OPLFIM, IQP, OQP, MQCR, QBAR, IFHPR,
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index 4a87b4b52400..c14a02564432 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -697,134 +697,6 @@ static void s626_reset_cap_flags(struct comedi_device *dev,
s626_debi_replace(dev, S626_LP_CRB(chan), ~S626_CRBMSK_INTCTRL, set);
}
-#ifdef unused
-/*
- * Return counter setup in a format (COUNTER_SETUP) that is consistent
- * for both A and B counters.
- */
-static uint16_t s626_get_mode_a(struct comedi_device *dev,
- unsigned int chan)
-{
- uint16_t cra;
- uint16_t crb;
- uint16_t setup;
- unsigned int cntsrc, clkmult, clkpol, encmode;
-
- /* Fetch CRA and CRB register images. */
- cra = s626_debi_read(dev, S626_LP_CRA(chan));
- crb = s626_debi_read(dev, S626_LP_CRB(chan));
-
- /*
- * Populate the standardized counter setup bit fields.
- */
- setup =
- /* LoadSrc = LoadSrcA. */
- S626_SET_STD_LOADSRC(S626_GET_CRA_LOADSRC_A(cra)) |
- /* LatchSrc = LatchSrcA. */
- S626_SET_STD_LATCHSRC(S626_GET_CRB_LATCHSRC(crb)) |
- /* IntSrc = IntSrcA. */
- S626_SET_STD_INTSRC(S626_GET_CRA_INTSRC_A(cra)) |
- /* IndxSrc = IndxSrcA. */
- S626_SET_STD_INDXSRC(S626_GET_CRA_INDXSRC_A(cra)) |
- /* IndxPol = IndxPolA. */
- S626_SET_STD_INDXPOL(S626_GET_CRA_INDXPOL_A(cra)) |
- /* ClkEnab = ClkEnabA. */
- S626_SET_STD_CLKENAB(S626_GET_CRB_CLKENAB_A(crb));
-
- /* Adjust mode-dependent parameters. */
- cntsrc = S626_GET_CRA_CNTSRC_A(cra);
- if (cntsrc & S626_CNTSRC_SYSCLK) {
- /* Timer mode (CntSrcA<1> == 1): */
- encmode = S626_ENCMODE_TIMER;
- /* Set ClkPol to indicate count direction (CntSrcA<0>). */
- clkpol = cntsrc & 1;
- /* ClkMult must be 1x in Timer mode. */
- clkmult = S626_CLKMULT_1X;
- } else {
- /* Counter mode (CntSrcA<1> == 0): */
- encmode = S626_ENCMODE_COUNTER;
- /* Pass through ClkPol. */
- clkpol = S626_GET_CRA_CLKPOL_A(cra);
- /* Force ClkMult to 1x if not legal, else pass through. */
- clkmult = S626_GET_CRA_CLKMULT_A(cra);
- if (clkmult == S626_CLKMULT_SPECIAL)
- clkmult = S626_CLKMULT_1X;
- }
- setup |= S626_SET_STD_ENCMODE(encmode) | S626_SET_STD_CLKMULT(clkmult) |
- S626_SET_STD_CLKPOL(clkpol);
-
- /* Return adjusted counter setup. */
- return setup;
-}
-
-static uint16_t s626_get_mode_b(struct comedi_device *dev,
- unsigned int chan)
-{
- uint16_t cra;
- uint16_t crb;
- uint16_t setup;
- unsigned int cntsrc, clkmult, clkpol, encmode;
-
- /* Fetch CRA and CRB register images. */
- cra = s626_debi_read(dev, S626_LP_CRA(chan));
- crb = s626_debi_read(dev, S626_LP_CRB(chan));
-
- /*
- * Populate the standardized counter setup bit fields.
- */
- setup =
- /* IntSrc = IntSrcB. */
- S626_SET_STD_INTSRC(S626_GET_CRB_INTSRC_B(crb)) |
- /* LatchSrc = LatchSrcB. */
- S626_SET_STD_LATCHSRC(S626_GET_CRB_LATCHSRC(crb)) |
- /* LoadSrc = LoadSrcB. */
- S626_SET_STD_LOADSRC(S626_GET_CRB_LOADSRC_B(crb)) |
- /* IndxPol = IndxPolB. */
- S626_SET_STD_INDXPOL(S626_GET_CRB_INDXPOL_B(crb)) |
- /* ClkEnab = ClkEnabB. */
- S626_SET_STD_CLKENAB(S626_GET_CRB_CLKENAB_B(crb)) |
- /* IndxSrc = IndxSrcB. */
- S626_SET_STD_INDXSRC(S626_GET_CRA_INDXSRC_B(cra));
-
- /* Adjust mode-dependent parameters. */
- cntsrc = S626_GET_CRA_CNTSRC_B(cra);
- clkmult = S626_GET_CRB_CLKMULT_B(crb);
- if (clkmult == S626_CLKMULT_SPECIAL) {
- /* Extender mode (ClkMultB == S626_CLKMULT_SPECIAL): */
- encmode = S626_ENCMODE_EXTENDER;
- /* Indicate multiplier is 1x. */
- clkmult = S626_CLKMULT_1X;
- /* Set ClkPol equal to Timer count direction (CntSrcB<0>). */
- clkpol = cntsrc & 1;
- } else if (cntsrc & S626_CNTSRC_SYSCLK) {
- /* Timer mode (CntSrcB<1> == 1): */
- encmode = S626_ENCMODE_TIMER;
- /* Indicate multiplier is 1x. */
- clkmult = S626_CLKMULT_1X;
- /* Set ClkPol equal to Timer count direction (CntSrcB<0>). */
- clkpol = cntsrc & 1;
- } else {
- /* If Counter mode (CntSrcB<1> == 0): */
- encmode = S626_ENCMODE_COUNTER;
- /* Clock multiplier is passed through. */
- /* Clock polarity is passed through. */
- clkpol = S626_GET_CRB_CLKPOL_B(crb);
- }
- setup |= S626_SET_STD_ENCMODE(encmode) | S626_SET_STD_CLKMULT(clkmult) |
- S626_SET_STD_CLKPOL(clkpol);
-
- /* Return adjusted counter setup. */
- return setup;
-}
-
-static uint16_t s626_get_mode(struct comedi_device *dev,
- unsigned int chan)
-{
- return (chan < 3) ? s626_get_mode_a(dev, chan)
- : s626_get_mode_b(dev, chan);
-}
-#endif
-
/*
* Set the operating mode for the specified counter. The setup
* parameter is treated as a COUNTER_SETUP data type. The following
@@ -1023,25 +895,6 @@ static void s626_set_enable(struct comedi_device *dev,
s626_debi_replace(dev, S626_LP_CRB(chan), ~mask, set);
}
-#ifdef unused
-static uint16_t s626_get_enable(struct comedi_device *dev,
- unsigned int chan)
-{
- uint16_t crb = s626_debi_read(dev, S626_LP_CRB(chan));
-
- return (chan < 3) ? S626_GET_CRB_CLKENAB_A(crb)
- : S626_GET_CRB_CLKENAB_B(crb);
-}
-#endif
-
-#ifdef unused
-static uint16_t s626_get_latch_source(struct comedi_device *dev,
- unsigned int chan)
-{
- return S626_GET_CRB_LATCHSRC(s626_debi_read(dev, S626_LP_CRB(chan)));
-}
-#endif
-
/*
* Return/set the event that will trigger transfer of the preload
* register into the counter. 0=ThisCntr_Index, 1=ThisCntr_Overflow,
@@ -1066,19 +919,6 @@ static void s626_set_load_trig(struct comedi_device *dev,
s626_debi_replace(dev, reg, ~mask, set);
}
-#ifdef unused
-static uint16_t s626_get_load_trig(struct comedi_device *dev,
- unsigned int chan)
-{
- if (chan < 3)
- return S626_GET_CRA_LOADSRC_A(s626_debi_read(dev,
- S626_LP_CRA(chan)));
- else
- return S626_GET_CRB_LOADSRC_B(s626_debi_read(dev,
- S626_LP_CRB(chan)));
-}
-#endif
-
/*
* Return/set counter interrupt source and clear any captured
* index/overflow events. int_source: 0=Disabled, 1=OverflowOnly,
@@ -1138,93 +978,6 @@ static void s626_set_int_src(struct comedi_device *dev,
}
}
-#ifdef unused
-static uint16_t s626_get_int_src(struct comedi_device *dev,
- unsigned int chan)
-{
- if (chan < 3)
- return S626_GET_CRA_INTSRC_A(s626_debi_read(dev,
- S626_LP_CRA(chan)));
- else
- return S626_GET_CRB_INTSRC_B(s626_debi_read(dev,
- S626_LP_CRB(chan)));
-}
-#endif
-
-#ifdef unused
-/*
- * Return/set the clock multiplier.
- */
-static void s626_set_clk_mult(struct comedi_device *dev,
- unsigned int chan, uint16_t value)
-{
- uint16_t mode;
-
- mode = s626_get_mode(dev, chan);
- mode &= ~S626_STDMSK_CLKMULT;
- mode |= S626_SET_STD_CLKMULT(value);
-
- s626_set_mode(dev, chan, mode, false);
-}
-
-/*
- * Return/set the clock polarity.
- */
-static void s626_set_clk_pol(struct comedi_device *dev,
- unsigned int chan, uint16_t value)
-{
- uint16_t mode;
-
- mode = s626_get_mode(dev, chan);
- mode &= ~S626_STDMSK_CLKPOL;
- mode |= S626_SET_STD_CLKPOL(value);
-
- s626_set_mode(dev, chan, mode, false);
-}
-
-/*
- * Return/set the encoder mode.
- */
-static void s626_set_enc_mode(struct comedi_device *dev,
- unsigned int chan, uint16_t value)
-{
- uint16_t mode;
-
- mode = s626_get_mode(dev, chan);
- mode &= ~S626_STDMSK_ENCMODE;
- mode |= S626_SET_STD_ENCMODE(value);
-
- s626_set_mode(dev, chan, mode, false);
-}
-
-static uint16_t s626_get_index_pol(struct comedi_device *dev,
- unsigned int chan)
-{
- return S626_GET_STD_INDXPOL(s626_get_mode(dev, chan));
-}
-
-/*
- * Return/set the index source.
- */
-static void s626_set_index_src(struct comedi_device *dev,
- unsigned int chan, uint16_t value)
-{
- uint16_t mode;
-
- mode = s626_get_mode(dev, chan);
- mode &= ~S626_STDMSK_INDXSRC;
- mode |= S626_SET_STD_INDXSRC(value != 0);
-
- s626_set_mode(dev, chan, mode, false);
-}
-
-static uint16_t s626_get_index_src(struct comedi_device *dev,
- unsigned int chan)
-{
- return S626_GET_STD_INDXSRC(s626_get_mode(dev, chan));
-}
-#endif
-
/*
* Generate an index pulse.
*/
@@ -1717,43 +1470,6 @@ static void s626_reset_adc(struct comedi_device *dev, uint8_t *ppl)
/* End of RPS program build */
}
-#ifdef unused_code
-static int s626_ai_rinsn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct s626_private *devpriv = dev->private;
- uint8_t i;
- int32_t *readaddr;
-
- /* Trigger ADC scan loop start */
- s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2);
-
- /* Wait until ADC scan loop is finished (RPS Signal 0 reset) */
- while (s626_mc_test(dev, S626_MC2_ADC_RPS, S626_P_MC2))
- ;
-
- /*
- * Init ptr to DMA buffer that holds new ADC data. We skip the
- * first uint16_t in the buffer because it contains junk data from
- * the final ADC of the previous poll list scan.
- */
- readaddr = (uint32_t *)devpriv->ana_buf.logical_base + 1;
-
- /*
- * Convert ADC data to 16-bit integer values and
- * copy to application buffer.
- */
- for (i = 0; i < devpriv->adc_items; i++) {
- *data = s626_ai_reg_to_uint(*readaddr++);
- data++;
- }
-
- return i;
-}
-#endif
-
static int s626_ai_eoc(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
@@ -2500,7 +2216,8 @@ static int s626_initialize(struct comedi_device *dev)
for (i = 0; i < 2; i++) {
writel(S626_I2C_CLKSEL, dev->mmio + S626_P_I2CSTAT);
s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
- ret = comedi_timeout(dev, NULL, NULL, s626_i2c_handshake_eoc, 0);
+ ret = comedi_timeout(dev, NULL,
+ NULL, s626_i2c_handshake_eoc, 0);
if (ret)
return ret;
}
diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h
index 6a00a64c6f3a..4cef45263267 100644
--- a/drivers/staging/comedi/drivers/s626.h
+++ b/drivers/staging/comedi/drivers/s626.h
@@ -79,7 +79,7 @@
/* Address offsets, in DWORDS, from base of DMA buffer. */
#define S626_DAC_WDMABUF_OS S626_ADC_DMABUF_DWORDS
-/* Interrupt enable bit in ISR and IER. */
+/* Interrupt enable bit in ISR and IER. */
#define S626_IRQ_GPIO3 0x00000040 /* IRQ enable for GPIO3. */
#define S626_IRQ_RPS1 0x10000000
#define S626_ISR_AFOU 0x00000800
@@ -329,7 +329,7 @@
* WS1-WS4 = CS* outputs.
*/
-#if S626_PLATFORM == S626_INTEL /*
+#if (S626_PLATFORM == S626_INTEL) /*
* Base ACON1 config: always run
* A1 based on TSL1.
*/
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index 10f94ec34536..608403c7586b 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -946,10 +946,8 @@ static int usbduxfast_auto_attach(struct comedi_device *dev,
}
devpriv->urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!devpriv->urb) {
- dev_err(dev->class_dev, "Could not alloc. urb\n");
+ if (!devpriv->urb)
return -ENOMEM;
- }
devpriv->inbuf = kmalloc(SIZEINBUF, GFP_KERNEL);
if (!devpriv->inbuf)
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index 8c7393ef762d..a004aed0147a 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -177,7 +177,7 @@ static void vmk80xx_do_bulk_msg(struct comedi_device *dev)
* The max packet size attributes of the K8061
* input/output endpoints are identical
*/
- size = le16_to_cpu(devpriv->ep_tx->wMaxPacketSize);
+ size = usb_endpoint_maxp(devpriv->ep_tx);
usb_bulk_msg(usb, tx_pipe, devpriv->usb_tx_buf,
size, NULL, devpriv->ep_tx->bInterval);
@@ -199,7 +199,7 @@ static int vmk80xx_read_packet(struct comedi_device *dev)
ep = devpriv->ep_rx;
pipe = usb_rcvintpipe(usb, ep->bEndpointAddress);
return usb_interrupt_msg(usb, pipe, devpriv->usb_rx_buf,
- le16_to_cpu(ep->wMaxPacketSize), NULL,
+ usb_endpoint_maxp(ep), NULL,
HZ * 10);
}
@@ -220,7 +220,7 @@ static int vmk80xx_write_packet(struct comedi_device *dev, int cmd)
ep = devpriv->ep_tx;
pipe = usb_sndintpipe(usb, ep->bEndpointAddress);
return usb_interrupt_msg(usb, pipe, devpriv->usb_tx_buf,
- le16_to_cpu(ep->wMaxPacketSize), NULL,
+ usb_endpoint_maxp(ep), NULL,
HZ * 10);
}
@@ -230,7 +230,7 @@ static int vmk80xx_reset_device(struct comedi_device *dev)
size_t size;
int retval;
- size = le16_to_cpu(devpriv->ep_tx->wMaxPacketSize);
+ size = usb_endpoint_maxp(devpriv->ep_tx);
memset(devpriv->usb_tx_buf, 0, size);
retval = vmk80xx_write_packet(dev, VMK8055_CMD_RST);
if (retval)
@@ -684,12 +684,12 @@ static int vmk80xx_alloc_usb_buffers(struct comedi_device *dev)
struct vmk80xx_private *devpriv = dev->private;
size_t size;
- size = le16_to_cpu(devpriv->ep_rx->wMaxPacketSize);
+ size = usb_endpoint_maxp(devpriv->ep_rx);
devpriv->usb_rx_buf = kzalloc(size, GFP_KERNEL);
if (!devpriv->usb_rx_buf)
return -ENOMEM;
- size = le16_to_cpu(devpriv->ep_tx->wMaxPacketSize);
+ size = usb_endpoint_maxp(devpriv->ep_tx);
devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL);
if (!devpriv->usb_tx_buf) {
kfree(devpriv->usb_rx_buf);
diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c
index 46c050cc7dbe..aedca66cbe41 100644
--- a/drivers/staging/dgnc/dgnc_cls.c
+++ b/drivers/staging/dgnc/dgnc_cls.c
@@ -26,56 +26,6 @@
#include "dgnc_cls.h"
#include "dgnc_tty.h"
-static inline void cls_parse_isr(struct dgnc_board *brd, uint port);
-static inline void cls_clear_break(struct channel_t *ch, int force);
-static inline void cls_set_cts_flow_control(struct channel_t *ch);
-static inline void cls_set_rts_flow_control(struct channel_t *ch);
-static inline void cls_set_ixon_flow_control(struct channel_t *ch);
-static inline void cls_set_ixoff_flow_control(struct channel_t *ch);
-static inline void cls_set_no_output_flow_control(struct channel_t *ch);
-static inline void cls_set_no_input_flow_control(struct channel_t *ch);
-static void cls_parse_modem(struct channel_t *ch, unsigned char signals);
-static void cls_tasklet(unsigned long data);
-static void cls_vpd(struct dgnc_board *brd);
-static void cls_uart_init(struct channel_t *ch);
-static void cls_uart_off(struct channel_t *ch);
-static int cls_drain(struct tty_struct *tty, uint seconds);
-static void cls_param(struct tty_struct *tty);
-static void cls_assert_modem_signals(struct channel_t *ch);
-static void cls_flush_uart_write(struct channel_t *ch);
-static void cls_flush_uart_read(struct channel_t *ch);
-static void cls_disable_receiver(struct channel_t *ch);
-static void cls_enable_receiver(struct channel_t *ch);
-static void cls_send_break(struct channel_t *ch, int msecs);
-static void cls_send_start_character(struct channel_t *ch);
-static void cls_send_stop_character(struct channel_t *ch);
-static void cls_copy_data_from_uart_to_queue(struct channel_t *ch);
-static void cls_copy_data_from_queue_to_uart(struct channel_t *ch);
-static uint cls_get_uart_bytes_left(struct channel_t *ch);
-static void cls_send_immediate_char(struct channel_t *ch, unsigned char);
-static irqreturn_t cls_intr(int irq, void *voidbrd);
-
-struct board_ops dgnc_cls_ops = {
- .tasklet = cls_tasklet,
- .intr = cls_intr,
- .uart_init = cls_uart_init,
- .uart_off = cls_uart_off,
- .drain = cls_drain,
- .param = cls_param,
- .vpd = cls_vpd,
- .assert_modem_signals = cls_assert_modem_signals,
- .flush_uart_write = cls_flush_uart_write,
- .flush_uart_read = cls_flush_uart_read,
- .disable_receiver = cls_disable_receiver,
- .enable_receiver = cls_enable_receiver,
- .send_break = cls_send_break,
- .send_start_character = cls_send_start_character,
- .send_stop_character = cls_send_stop_character,
- .copy_data_from_queue_to_uart = cls_copy_data_from_queue_to_uart,
- .get_uart_bytes_left = cls_get_uart_bytes_left,
- .send_immediate_char = cls_send_immediate_char
-};
-
static inline void cls_set_cts_flow_control(struct channel_t *ch)
{
unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
@@ -357,6 +307,253 @@ static inline void cls_clear_break(struct channel_t *ch, int force)
spin_unlock_irqrestore(&ch->ch_lock, flags);
}
+static void cls_copy_data_from_uart_to_queue(struct channel_t *ch)
+{
+ int qleft = 0;
+ unsigned char linestatus = 0;
+ unsigned char error_mask = 0;
+ ushort head;
+ ushort tail;
+ unsigned long flags;
+
+ if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
+ return;
+
+ spin_lock_irqsave(&ch->ch_lock, flags);
+
+ /* cache head and tail of queue */
+ head = ch->ch_r_head;
+ tail = ch->ch_r_tail;
+
+ /* Store how much space we have left in the queue */
+ qleft = tail - head - 1;
+ if (qleft < 0)
+ qleft += RQUEUEMASK + 1;
+
+ /*
+ * Create a mask to determine whether we should
+ * insert the character (if any) into our queue.
+ */
+ if (ch->ch_c_iflag & IGNBRK)
+ error_mask |= UART_LSR_BI;
+
+ while (1) {
+ linestatus = readb(&ch->ch_cls_uart->lsr);
+
+ if (!(linestatus & (UART_LSR_DR)))
+ break;
+
+ /*
+ * Discard character if we are ignoring the error mask.
+ */
+ if (linestatus & error_mask) {
+ linestatus = 0;
+ readb(&ch->ch_cls_uart->txrx);
+ continue;
+ }
+
+ /*
+ * If our queue is full, we have no choice but to drop some
+ * data. The assumption is that HWFLOW or SWFLOW should have
+ * stopped things way way before we got to this point.
+ *
+ * I decided that I wanted to ditch the oldest data first,
+ * I hope thats okay with everyone? Yes? Good.
+ */
+ while (qleft < 1) {
+ tail = (tail + 1) & RQUEUEMASK;
+ ch->ch_r_tail = tail;
+ ch->ch_err_overrun++;
+ qleft++;
+ }
+
+ ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE
+ | UART_LSR_FE);
+ ch->ch_rqueue[head] = readb(&ch->ch_cls_uart->txrx);
+
+ qleft--;
+
+ if (ch->ch_equeue[head] & UART_LSR_PE)
+ ch->ch_err_parity++;
+ if (ch->ch_equeue[head] & UART_LSR_BI)
+ ch->ch_err_break++;
+ if (ch->ch_equeue[head] & UART_LSR_FE)
+ ch->ch_err_frame++;
+
+ /* Add to, and flip head if needed */
+ head = (head + 1) & RQUEUEMASK;
+ ch->ch_rxcount++;
+ }
+
+ /*
+ * Write new final heads to channel structure.
+ */
+ ch->ch_r_head = head & RQUEUEMASK;
+ ch->ch_e_head = head & EQUEUEMASK;
+
+ spin_unlock_irqrestore(&ch->ch_lock, flags);
+}
+
+/* Make the UART raise any of the output signals we want up */
+static void cls_assert_modem_signals(struct channel_t *ch)
+{
+ unsigned char out;
+
+ if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
+ return;
+
+ out = ch->ch_mostat;
+
+ if (ch->ch_flags & CH_LOOPBACK)
+ out |= UART_MCR_LOOP;
+
+ writeb(out, &ch->ch_cls_uart->mcr);
+
+ /* Give time for the UART to actually drop the signals */
+ udelay(10);
+}
+
+static void cls_copy_data_from_queue_to_uart(struct channel_t *ch)
+{
+ ushort head;
+ ushort tail;
+ int n;
+ int qlen;
+ uint len_written = 0;
+ unsigned long flags;
+
+ if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
+ return;
+
+ spin_lock_irqsave(&ch->ch_lock, flags);
+
+ /* No data to write to the UART */
+ if (ch->ch_w_tail == ch->ch_w_head)
+ goto exit_unlock;
+
+ /* If port is "stopped", don't send any data to the UART */
+ if ((ch->ch_flags & CH_FORCED_STOP) ||
+ (ch->ch_flags & CH_BREAK_SENDING))
+ goto exit_unlock;
+
+ if (!(ch->ch_flags & (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM)))
+ goto exit_unlock;
+
+ n = 32;
+
+ /* cache head and tail of queue */
+ head = ch->ch_w_head & WQUEUEMASK;
+ tail = ch->ch_w_tail & WQUEUEMASK;
+ qlen = (head - tail) & WQUEUEMASK;
+
+ /* Find minimum of the FIFO space, versus queue length */
+ n = min(n, qlen);
+
+ while (n > 0) {
+ /*
+ * If RTS Toggle mode is on, turn on RTS now if not already set,
+ * and make sure we get an event when the data transfer has
+ * completed.
+ */
+ if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) {
+ if (!(ch->ch_mostat & UART_MCR_RTS)) {
+ ch->ch_mostat |= (UART_MCR_RTS);
+ cls_assert_modem_signals(ch);
+ }
+ ch->ch_tun.un_flags |= (UN_EMPTY);
+ }
+
+ /*
+ * If DTR Toggle mode is on, turn on DTR now if not already set,
+ * and make sure we get an event when the data transfer has
+ * completed.
+ */
+ if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) {
+ if (!(ch->ch_mostat & UART_MCR_DTR)) {
+ ch->ch_mostat |= (UART_MCR_DTR);
+ cls_assert_modem_signals(ch);
+ }
+ ch->ch_tun.un_flags |= (UN_EMPTY);
+ }
+ writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_cls_uart->txrx);
+ ch->ch_w_tail++;
+ ch->ch_w_tail &= WQUEUEMASK;
+ ch->ch_txcount++;
+ len_written++;
+ n--;
+ }
+
+ if (len_written > 0)
+ ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
+
+exit_unlock:
+ spin_unlock_irqrestore(&ch->ch_lock, flags);
+}
+
+static void cls_parse_modem(struct channel_t *ch, unsigned char signals)
+{
+ unsigned char msignals = signals;
+ unsigned long flags;
+
+ if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
+ return;
+
+ /*
+ * Do altpin switching. Altpin switches DCD and DSR.
+ * This prolly breaks DSRPACE, so we should be more clever here.
+ */
+ spin_lock_irqsave(&ch->ch_lock, flags);
+ if (ch->ch_digi.digi_flags & DIGI_ALTPIN) {
+ unsigned char mswap = signals;
+
+ if (mswap & UART_MSR_DDCD) {
+ msignals &= ~UART_MSR_DDCD;
+ msignals |= UART_MSR_DDSR;
+ }
+ if (mswap & UART_MSR_DDSR) {
+ msignals &= ~UART_MSR_DDSR;
+ msignals |= UART_MSR_DDCD;
+ }
+ if (mswap & UART_MSR_DCD) {
+ msignals &= ~UART_MSR_DCD;
+ msignals |= UART_MSR_DSR;
+ }
+ if (mswap & UART_MSR_DSR) {
+ msignals &= ~UART_MSR_DSR;
+ msignals |= UART_MSR_DCD;
+ }
+ }
+ spin_unlock_irqrestore(&ch->ch_lock, flags);
+
+ /*
+ * Scrub off lower bits. They signify delta's, which I don't
+ * care about
+ */
+ signals &= 0xf0;
+
+ spin_lock_irqsave(&ch->ch_lock, flags);
+ if (msignals & UART_MSR_DCD)
+ ch->ch_mistat |= UART_MSR_DCD;
+ else
+ ch->ch_mistat &= ~UART_MSR_DCD;
+
+ if (msignals & UART_MSR_DSR)
+ ch->ch_mistat |= UART_MSR_DSR;
+ else
+ ch->ch_mistat &= ~UART_MSR_DSR;
+
+ if (msignals & UART_MSR_RI)
+ ch->ch_mistat |= UART_MSR_RI;
+ else
+ ch->ch_mistat &= ~UART_MSR_RI;
+
+ if (msignals & UART_MSR_CTS)
+ ch->ch_mistat |= UART_MSR_CTS;
+ else
+ ch->ch_mistat &= ~UART_MSR_CTS;
+ spin_unlock_irqrestore(&ch->ch_lock, flags);
+}
+
/* Parse the ISR register for the specific port */
static inline void cls_parse_isr(struct dgnc_board *brd, uint port)
{
@@ -387,8 +584,6 @@ static inline void cls_parse_isr(struct dgnc_board *brd, uint port)
/* Receive Interrupt pending */
if (isr & (UART_IIR_RDI | UART_IIR_RDI_TIMEOUT)) {
/* Read data from uart -> queue */
- brd->intr_rx++;
- ch->ch_intr_rx++;
cls_copy_data_from_uart_to_queue(ch);
dgnc_check_queue_flow_control(ch);
}
@@ -398,27 +593,48 @@ static inline void cls_parse_isr(struct dgnc_board *brd, uint port)
/* Transfer data (if any) from Write Queue -> UART. */
spin_lock_irqsave(&ch->ch_lock, flags);
ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
- brd->intr_tx++;
- ch->ch_intr_tx++;
spin_unlock_irqrestore(&ch->ch_lock, flags);
cls_copy_data_from_queue_to_uart(ch);
}
- /* CTS/RTS change of state */
- if (isr & UART_IIR_CTSRTS) {
- brd->intr_modem++;
- ch->ch_intr_modem++;
- /*
- * Don't need to do anything, the cls_parse_modem
- * below will grab the updated modem signals.
- */
- }
-
/* Parse any modem signal changes */
cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr));
}
}
+/* Channel lock MUST be held before calling this function! */
+static void cls_flush_uart_write(struct channel_t *ch)
+{
+ if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
+ return;
+
+ writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT),
+ &ch->ch_cls_uart->isr_fcr);
+ usleep_range(10, 20);
+
+ ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
+}
+
+/* Channel lock MUST be held before calling this function! */
+static void cls_flush_uart_read(struct channel_t *ch)
+{
+ if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
+ return;
+
+ /*
+ * For complete POSIX compatibility, we should be purging the
+ * read FIFO in the UART here.
+ *
+ * However, clearing the read FIFO (UART_FCR_CLEAR_RCVR) also
+ * incorrectly flushes write data as well as just basically trashing the
+ * FIFO.
+ *
+ * Presumably, this is a bug in this UART.
+ */
+
+ udelay(10);
+}
+
/*
* cls_param()
* Send any/all changes to the line to the UART.
@@ -760,8 +976,6 @@ static irqreturn_t cls_intr(int irq, void *voidbrd)
spin_lock_irqsave(&brd->bd_intr_lock, flags);
- brd->intr_count++;
-
/*
* Check the board's global interrupt offset to see if we
* we actually do have an interrupt pending for us.
@@ -804,93 +1018,6 @@ static void cls_enable_receiver(struct channel_t *ch)
writeb(tmp, &ch->ch_cls_uart->ier);
}
-static void cls_copy_data_from_uart_to_queue(struct channel_t *ch)
-{
- int qleft = 0;
- unsigned char linestatus = 0;
- unsigned char error_mask = 0;
- ushort head;
- ushort tail;
- unsigned long flags;
-
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return;
-
- spin_lock_irqsave(&ch->ch_lock, flags);
-
- /* cache head and tail of queue */
- head = ch->ch_r_head;
- tail = ch->ch_r_tail;
-
- /* Store how much space we have left in the queue */
- qleft = tail - head - 1;
- if (qleft < 0)
- qleft += RQUEUEMASK + 1;
-
- /*
- * Create a mask to determine whether we should
- * insert the character (if any) into our queue.
- */
- if (ch->ch_c_iflag & IGNBRK)
- error_mask |= UART_LSR_BI;
-
- while (1) {
- linestatus = readb(&ch->ch_cls_uart->lsr);
-
- if (!(linestatus & (UART_LSR_DR)))
- break;
-
- /*
- * Discard character if we are ignoring the error mask.
- */
- if (linestatus & error_mask) {
- linestatus = 0;
- readb(&ch->ch_cls_uart->txrx);
- continue;
- }
-
- /*
- * If our queue is full, we have no choice but to drop some
- * data. The assumption is that HWFLOW or SWFLOW should have
- * stopped things way way before we got to this point.
- *
- * I decided that I wanted to ditch the oldest data first,
- * I hope thats okay with everyone? Yes? Good.
- */
- while (qleft < 1) {
- tail = (tail + 1) & RQUEUEMASK;
- ch->ch_r_tail = tail;
- ch->ch_err_overrun++;
- qleft++;
- }
-
- ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE
- | UART_LSR_FE);
- ch->ch_rqueue[head] = readb(&ch->ch_cls_uart->txrx);
-
- qleft--;
-
- if (ch->ch_equeue[head] & UART_LSR_PE)
- ch->ch_err_parity++;
- if (ch->ch_equeue[head] & UART_LSR_BI)
- ch->ch_err_break++;
- if (ch->ch_equeue[head] & UART_LSR_FE)
- ch->ch_err_frame++;
-
- /* Add to, and flip head if needed */
- head = (head + 1) & RQUEUEMASK;
- ch->ch_rxcount++;
- }
-
- /*
- * Write new final heads to channel structure.
- */
- ch->ch_r_head = head & RQUEUEMASK;
- ch->ch_e_head = head & EQUEUEMASK;
-
- spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
/*
* This function basically goes to sleep for secs, or until
* it gets signalled that the port has fully drained.
@@ -926,199 +1053,6 @@ static int cls_drain(struct tty_struct *tty, uint seconds)
((un->un_flags & UN_EMPTY) == 0));
}
-/* Channel lock MUST be held before calling this function! */
-static void cls_flush_uart_write(struct channel_t *ch)
-{
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return;
-
- writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT),
- &ch->ch_cls_uart->isr_fcr);
- usleep_range(10, 20);
-
- ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
-}
-
-/* Channel lock MUST be held before calling this function! */
-static void cls_flush_uart_read(struct channel_t *ch)
-{
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return;
-
- /*
- * For complete POSIX compatibility, we should be purging the
- * read FIFO in the UART here.
- *
- * However, clearing the read FIFO (UART_FCR_CLEAR_RCVR) also
- * incorrectly flushes write data as well as just basically trashing the
- * FIFO.
- *
- * Presumably, this is a bug in this UART.
- */
-
- udelay(10);
-}
-
-static void cls_copy_data_from_queue_to_uart(struct channel_t *ch)
-{
- ushort head;
- ushort tail;
- int n;
- int qlen;
- uint len_written = 0;
- unsigned long flags;
-
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return;
-
- spin_lock_irqsave(&ch->ch_lock, flags);
-
- /* No data to write to the UART */
- if (ch->ch_w_tail == ch->ch_w_head)
- goto exit_unlock;
-
- /* If port is "stopped", don't send any data to the UART */
- if ((ch->ch_flags & CH_FORCED_STOP) ||
- (ch->ch_flags & CH_BREAK_SENDING))
- goto exit_unlock;
-
- if (!(ch->ch_flags & (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM)))
- goto exit_unlock;
-
- n = 32;
-
- /* cache head and tail of queue */
- head = ch->ch_w_head & WQUEUEMASK;
- tail = ch->ch_w_tail & WQUEUEMASK;
- qlen = (head - tail) & WQUEUEMASK;
-
- /* Find minimum of the FIFO space, versus queue length */
- n = min(n, qlen);
-
- while (n > 0) {
- /*
- * If RTS Toggle mode is on, turn on RTS now if not already set,
- * and make sure we get an event when the data transfer has
- * completed.
- */
- if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) {
- if (!(ch->ch_mostat & UART_MCR_RTS)) {
- ch->ch_mostat |= (UART_MCR_RTS);
- cls_assert_modem_signals(ch);
- }
- ch->ch_tun.un_flags |= (UN_EMPTY);
- }
-
- /*
- * If DTR Toggle mode is on, turn on DTR now if not already set,
- * and make sure we get an event when the data transfer has
- * completed.
- */
- if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) {
- if (!(ch->ch_mostat & UART_MCR_DTR)) {
- ch->ch_mostat |= (UART_MCR_DTR);
- cls_assert_modem_signals(ch);
- }
- ch->ch_tun.un_flags |= (UN_EMPTY);
- }
- writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_cls_uart->txrx);
- ch->ch_w_tail++;
- ch->ch_w_tail &= WQUEUEMASK;
- ch->ch_txcount++;
- len_written++;
- n--;
- }
-
- if (len_written > 0)
- ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
-
-exit_unlock:
- spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-static void cls_parse_modem(struct channel_t *ch, unsigned char signals)
-{
- unsigned char msignals = signals;
- unsigned long flags;
-
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return;
-
- /*
- * Do altpin switching. Altpin switches DCD and DSR.
- * This prolly breaks DSRPACE, so we should be more clever here.
- */
- spin_lock_irqsave(&ch->ch_lock, flags);
- if (ch->ch_digi.digi_flags & DIGI_ALTPIN) {
- unsigned char mswap = signals;
-
- if (mswap & UART_MSR_DDCD) {
- msignals &= ~UART_MSR_DDCD;
- msignals |= UART_MSR_DDSR;
- }
- if (mswap & UART_MSR_DDSR) {
- msignals &= ~UART_MSR_DDSR;
- msignals |= UART_MSR_DDCD;
- }
- if (mswap & UART_MSR_DCD) {
- msignals &= ~UART_MSR_DCD;
- msignals |= UART_MSR_DSR;
- }
- if (mswap & UART_MSR_DSR) {
- msignals &= ~UART_MSR_DSR;
- msignals |= UART_MSR_DCD;
- }
- }
- spin_unlock_irqrestore(&ch->ch_lock, flags);
-
- /*
- * Scrub off lower bits. They signify delta's, which I don't
- * care about
- */
- signals &= 0xf0;
-
- spin_lock_irqsave(&ch->ch_lock, flags);
- if (msignals & UART_MSR_DCD)
- ch->ch_mistat |= UART_MSR_DCD;
- else
- ch->ch_mistat &= ~UART_MSR_DCD;
-
- if (msignals & UART_MSR_DSR)
- ch->ch_mistat |= UART_MSR_DSR;
- else
- ch->ch_mistat &= ~UART_MSR_DSR;
-
- if (msignals & UART_MSR_RI)
- ch->ch_mistat |= UART_MSR_RI;
- else
- ch->ch_mistat &= ~UART_MSR_RI;
-
- if (msignals & UART_MSR_CTS)
- ch->ch_mistat |= UART_MSR_CTS;
- else
- ch->ch_mistat &= ~UART_MSR_CTS;
- spin_unlock_irqrestore(&ch->ch_lock, flags);
-}
-
-/* Make the UART raise any of the output signals we want up */
-static void cls_assert_modem_signals(struct channel_t *ch)
-{
- unsigned char out;
-
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return;
-
- out = ch->ch_mostat;
-
- if (ch->ch_flags & CH_LOOPBACK)
- out |= UART_MCR_LOOP;
-
- writeb(out, &ch->ch_cls_uart->mcr);
-
- /* Give time for the UART to actually drop the signals */
- udelay(10);
-}
-
static void cls_send_start_character(struct channel_t *ch)
{
if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
@@ -1298,3 +1232,24 @@ static void cls_vpd(struct dgnc_board *brd)
iounmap(re_map_vpdbase);
}
+
+struct board_ops dgnc_cls_ops = {
+ .tasklet = cls_tasklet,
+ .intr = cls_intr,
+ .uart_init = cls_uart_init,
+ .uart_off = cls_uart_off,
+ .drain = cls_drain,
+ .param = cls_param,
+ .vpd = cls_vpd,
+ .assert_modem_signals = cls_assert_modem_signals,
+ .flush_uart_write = cls_flush_uart_write,
+ .flush_uart_read = cls_flush_uart_read,
+ .disable_receiver = cls_disable_receiver,
+ .enable_receiver = cls_enable_receiver,
+ .send_break = cls_send_break,
+ .send_start_character = cls_send_start_character,
+ .send_stop_character = cls_send_stop_character,
+ .copy_data_from_queue_to_uart = cls_copy_data_from_queue_to_uart,
+ .get_uart_bytes_left = cls_get_uart_bytes_left,
+ .send_immediate_char = cls_send_immediate_char
+};
diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c
index af2e835efa1b..fd372d3afa46 100644
--- a/drivers/staging/dgnc/dgnc_driver.c
+++ b/drivers/staging/dgnc/dgnc_driver.c
@@ -37,13 +37,14 @@ MODULE_SUPPORTED_DEVICE("dgnc");
*
*/
static int dgnc_start(void);
-static int dgnc_finalize_board_init(struct dgnc_board *brd);
-static int dgnc_found_board(struct pci_dev *pdev, int id);
+static int dgnc_request_irq(struct dgnc_board *brd);
+static void dgnc_free_irq(struct dgnc_board *brd);
+static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id);
static void dgnc_cleanup_board(struct dgnc_board *brd);
static void dgnc_poll_handler(ulong dummy);
static int dgnc_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent);
-static void dgnc_do_remap(struct dgnc_board *brd);
+static int dgnc_do_remap(struct dgnc_board *brd);
/*
* File operations permitted on Control/Management major.
@@ -146,7 +147,7 @@ static void cleanup(bool sysfiles)
for (i = 0; i < dgnc_num_boards; ++i) {
dgnc_remove_ports_sysfiles(dgnc_board[i]);
- dgnc_tty_uninit(dgnc_board[i]);
+ dgnc_cleanup_tty(dgnc_board[i]);
dgnc_cleanup_board(dgnc_board[i]);
}
@@ -158,7 +159,7 @@ static void cleanup(bool sysfiles)
*
* Module unload. This is where it all ends.
*/
-static void dgnc_cleanup_module(void)
+static void __exit dgnc_cleanup_module(void)
{
cleanup(true);
pci_unregister_driver(&dgnc_driver);
@@ -274,6 +275,7 @@ failed_class:
static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int rc;
+ struct dgnc_board *brd;
/* wake up and enable device */
rc = pci_enable_device(pdev);
@@ -281,9 +283,48 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return -EIO;
- rc = dgnc_found_board(pdev, ent->driver_data);
- if (rc == 0)
- dgnc_num_boards++;
+ brd = dgnc_found_board(pdev, ent->driver_data);
+ if (IS_ERR(brd))
+ return PTR_ERR(brd);
+
+ /*
+ * Do tty device initialization.
+ */
+
+ rc = dgnc_tty_register(brd);
+ if (rc < 0) {
+ pr_err(DRVSTR ": Can't register tty devices (%d)\n", rc);
+ goto failed;
+ }
+
+ rc = dgnc_request_irq(brd);
+ if (rc < 0) {
+ pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc);
+ goto unregister_tty;
+ }
+
+ rc = dgnc_tty_init(brd);
+ if (rc < 0) {
+ pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc);
+ goto free_irq;
+ }
+
+ brd->state = BOARD_READY;
+ brd->dpastatus = BD_RUNNING;
+
+ dgnc_create_ports_sysfiles(brd);
+
+ dgnc_board[dgnc_num_boards++] = brd;
+
+ return 0;
+
+free_irq:
+ dgnc_free_irq(brd);
+unregister_tty:
+ dgnc_tty_unregister(brd);
+
+failed:
+ kfree(brd);
return rc;
}
@@ -324,17 +365,6 @@ static void dgnc_cleanup_board(struct dgnc_board *brd)
brd->re_map_membase = NULL;
}
- if (brd->msgbuf_head) {
- unsigned long flags;
-
- spin_lock_irqsave(&dgnc_global_lock, flags);
- brd->msgbuf = NULL;
- dev_dbg(&brd->pdev->dev, "%s\n", brd->msgbuf_head);
- kfree(brd->msgbuf_head);
- brd->msgbuf_head = NULL;
- spin_unlock_irqrestore(&dgnc_global_lock, flags);
- }
-
/* Free all allocated channels structs */
for (i = 0; i < MAXPORTS ; i++) {
if (brd->channels[i]) {
@@ -356,29 +386,17 @@ static void dgnc_cleanup_board(struct dgnc_board *brd)
*
* A board has been found, init it.
*/
-static int dgnc_found_board(struct pci_dev *pdev, int id)
+static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id)
{
struct dgnc_board *brd;
unsigned int pci_irq;
int i = 0;
int rc = 0;
- unsigned long flags;
/* get the board structure and prep it */
- dgnc_board[dgnc_num_boards] = kzalloc(sizeof(*brd), GFP_KERNEL);
- brd = dgnc_board[dgnc_num_boards];
-
+ brd = kzalloc(sizeof(*brd), GFP_KERNEL);
if (!brd)
- return -ENOMEM;
-
- /* make a temporary message buffer for the boot messages */
- brd->msgbuf_head = kcalloc(8192, sizeof(u8), GFP_KERNEL);
- brd->msgbuf = brd->msgbuf_head;
-
- if (!brd->msgbuf) {
- kfree(brd);
- return -ENOMEM;
- }
+ return ERR_PTR(-ENOMEM);
/* store the info for the board we've found */
brd->magic = DGNC_BOARD_MAGIC;
@@ -400,9 +418,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
brd->state = BOARD_FOUND;
- for (i = 0; i < MAXPORTS; i++)
- brd->channels[i] = NULL;
-
/* store which card & revision we have */
pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &brd->subvendor);
pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &brd->subdevice);
@@ -435,7 +450,8 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
if (!brd->membase) {
dev_err(&brd->pdev->dev,
"Card has no PCI IO resources, failing.\n");
- return -ENODEV;
+ rc = -ENODEV;
+ goto failed;
}
brd->membase_end = pci_resource_end(pdev, 4);
@@ -455,7 +471,10 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
brd->bd_uart_offset = 0x8;
brd->bd_dividend = 921600;
- dgnc_do_remap(brd);
+ rc = dgnc_do_remap(brd);
+
+ if (rc < 0)
+ goto failed;
/* Get and store the board VPD, if it exists */
brd->bd_ops->vpd(brd);
@@ -507,81 +526,45 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
brd->bd_uart_offset = 0x200;
brd->bd_dividend = 921600;
- dgnc_do_remap(brd);
+ rc = dgnc_do_remap(brd);
- if (brd->re_map_membase) {
- /* Read and store the dvid after remapping */
- brd->dvid = readb(brd->re_map_membase + 0x8D);
+ if (rc < 0)
+ goto failed;
+
+ /* Read and store the dvid after remapping */
+ brd->dvid = readb(brd->re_map_membase + 0x8D);
+
+ /* Get and store the board VPD, if it exists */
+ brd->bd_ops->vpd(brd);
- /* Get and store the board VPD, if it exists */
- brd->bd_ops->vpd(brd);
- }
break;
default:
dev_err(&brd->pdev->dev,
"Didn't find any compatible Neo/Classic PCI boards.\n");
- return -ENXIO;
- }
-
- /*
- * Do tty device initialization.
- */
-
- rc = dgnc_tty_register(brd);
- if (rc < 0) {
- pr_err(DRVSTR ": Can't register tty devices (%d)\n", rc);
- goto failed;
- }
-
- rc = dgnc_finalize_board_init(brd);
- if (rc < 0) {
- pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc);
- goto failed;
- }
-
- rc = dgnc_tty_init(brd);
- if (rc < 0) {
- pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc);
+ rc = -ENXIO;
goto failed;
}
- brd->state = BOARD_READY;
- brd->dpastatus = BD_RUNNING;
-
- dgnc_create_ports_sysfiles(brd);
-
/* init our poll helper tasklet */
tasklet_init(&brd->helper_tasklet,
brd->bd_ops->tasklet,
(unsigned long)brd);
- spin_lock_irqsave(&dgnc_global_lock, flags);
- brd->msgbuf = NULL;
- dev_dbg(&brd->pdev->dev, "%s\n", brd->msgbuf_head);
- kfree(brd->msgbuf_head);
- brd->msgbuf_head = NULL;
- spin_unlock_irqrestore(&dgnc_global_lock, flags);
-
wake_up_interruptible(&brd->state_wait);
- return 0;
+ return brd;
failed:
- dgnc_tty_uninit(brd);
- brd->state = BOARD_FAILED;
- brd->dpastatus = BD_NOFEP;
+ kfree(brd);
- return -ENXIO;
+ return ERR_PTR(rc);
}
-static int dgnc_finalize_board_init(struct dgnc_board *brd)
+static int dgnc_request_irq(struct dgnc_board *brd)
{
int rc = 0;
- if (!brd || brd->magic != DGNC_BOARD_MAGIC)
- return -ENODEV;
-
if (brd->irq) {
rc = request_irq(brd->irq, brd->bd_ops->intr,
IRQF_SHARED, "DGNC", brd);
@@ -597,42 +580,51 @@ static int dgnc_finalize_board_init(struct dgnc_board *brd)
return rc;
}
+static void dgnc_free_irq(struct dgnc_board *brd)
+{
+ if (brd->irq)
+ free_irq(brd->irq, brd);
+}
+
/*
* Remap PCI memory.
*/
-static void dgnc_do_remap(struct dgnc_board *brd)
+static int dgnc_do_remap(struct dgnc_board *brd)
{
- if (!brd || brd->magic != DGNC_BOARD_MAGIC)
- return;
+ int rc = 0;
brd->re_map_membase = ioremap(brd->membase, 0x1000);
+ if (!brd->re_map_membase)
+ rc = -ENOMEM;
+
+ return rc;
}
-/*****************************************************************************
-*
-* Function:
-*
-* dgnc_poll_handler
-*
-* Author:
-*
-* Scott H Kilau
-*
-* Parameters:
-*
-* dummy -- ignored
-*
-* Return Values:
-*
-* none
-*
-* Description:
-*
-* As each timer expires, it determines (a) whether the "transmit"
-* waiter needs to be woken up, and (b) whether the poller needs to
-* be rescheduled.
-*
-******************************************************************************/
+/*
+ *
+ * Function:
+ *
+ * dgnc_poll_handler
+ *
+ * Author:
+ *
+ * Scott H Kilau
+ *
+ * Parameters:
+ *
+ * dummy -- ignored
+ *
+ * Return Values:
+ *
+ * none
+ *
+ * Description:
+ *
+ * As each timer expires, it determines (a) whether the "transmit"
+ * waiter needs to be woken up, and (b) whether the poller needs to
+ * be rescheduled.
+ *
+ */
static void dgnc_poll_handler(ulong dummy)
{
diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h
index 95ec729fae38..879202663a98 100644
--- a/drivers/staging/dgnc/dgnc_driver.h
+++ b/drivers/staging/dgnc/dgnc_driver.h
@@ -183,10 +183,6 @@ struct dgnc_board {
uint nasync; /* Number of ports on card */
uint irq; /* Interrupt request number */
- ulong intr_count; /* Count of interrupts */
- ulong intr_modem; /* Count of interrupts */
- ulong intr_tx; /* Count of interrupts */
- ulong intr_rx; /* Count of interrupts */
ulong membase; /* Start of base memory of the card */
ulong membase_end; /* End of base memory of the card */
@@ -207,9 +203,6 @@ struct dgnc_board {
struct tty_driver *print_driver;
char print_name[200];
- bool dgnc_major_serial_registered;
- bool dgnc_major_transparent_print_registered;
-
u16 dpatype; /* The board "type",
* as defined by DPA
*/
@@ -217,12 +210,6 @@ struct dgnc_board {
* as defined by DPA
*/
- /*
- * Mgmt data.
- */
- char *msgbuf_head;
- char *msgbuf;
-
uint bd_dividend; /* Board/UARTs specific dividend */
struct board_ops *bd_ops;
@@ -381,10 +368,6 @@ struct channel_t {
ulong ch_xon_sends; /* Count of xons transmitted */
ulong ch_xoff_sends; /* Count of xoffs transmitted */
- ulong ch_intr_modem; /* Count of interrupts */
- ulong ch_intr_tx; /* Count of interrupts */
- ulong ch_intr_rx; /* Count of interrupts */
-
/* /proc/<board>/<channel> entries */
struct proc_dir_entry *proc_entry_pointer;
struct dgnc_proc_entry *dgnc_channel_table;
@@ -398,7 +381,7 @@ extern uint dgnc_major; /* Our driver/mgmt major */
extern int dgnc_poll_tick; /* Poll interval - 20 ms */
extern spinlock_t dgnc_global_lock; /* Driver global spinlock */
extern spinlock_t dgnc_poll_lock; /* Poll scheduling lock */
-extern uint dgnc_num_boards; /* Total number of boards */
+extern uint dgnc_num_boards; /* Total number of boards */
extern struct dgnc_board *dgnc_board[MAXBOARDS]; /* Array of board
* structs
*/
diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c
index ba57e9546f72..5becb3741b67 100644
--- a/drivers/staging/dgnc/dgnc_neo.c
+++ b/drivers/staging/dgnc/dgnc_neo.c
@@ -107,7 +107,9 @@ static inline void neo_set_cts_flow_control(struct channel_t *ch)
/* Turn off auto Xon flow control */
efr &= ~UART_17158_EFR_IXON;
- /* Why? Becuz Exar's spec says we have to zero it out before setting it */
+ /* Why? Because Exar's spec says we have to zero it
+ * out before setting it
+ */
writeb(0, &ch->ch_neo_uart->efr);
/* Turn on UART enhanced bits */
@@ -143,7 +145,9 @@ static inline void neo_set_rts_flow_control(struct channel_t *ch)
ier &= ~UART_17158_IER_XOFF;
efr &= ~UART_17158_EFR_IXOFF;
- /* Why? Becuz Exar's spec says we have to zero it out before setting it */
+ /* Why? Because Exar's spec says we have to zero it
+ * out before setting it
+ */
writeb(0, &ch->ch_neo_uart->efr);
/* Turn on UART enhanced bits */
@@ -181,7 +185,9 @@ static inline void neo_set_ixon_flow_control(struct channel_t *ch)
/* Turn on auto Xon flow control */
efr |= (UART_17158_EFR_ECB | UART_17158_EFR_IXON);
- /* Why? Becuz Exar's spec says we have to zero it out before setting it */
+ /* Why? Because Exar's spec says we have to zero it
+ * out before setting it
+ */
writeb(0, &ch->ch_neo_uart->efr);
/* Turn on UART enhanced bits */
@@ -219,7 +225,9 @@ static inline void neo_set_ixoff_flow_control(struct channel_t *ch)
ier |= UART_17158_IER_XOFF;
efr |= (UART_17158_EFR_ECB | UART_17158_EFR_IXOFF);
- /* Why? Becuz Exar's spec says we have to zero it out before setting it */
+ /* Why? Because Exar's spec says we have to zero it
+ * out before setting it
+ */
writeb(0, &ch->ch_neo_uart->efr);
/* Turn on UART enhanced bits */
@@ -260,7 +268,9 @@ static inline void neo_set_no_input_flow_control(struct channel_t *ch)
else
efr &= ~(UART_17158_EFR_ECB | UART_17158_EFR_IXOFF);
- /* Why? Becuz Exar's spec says we have to zero it out before setting it */
+ /* Why? Because Exar's spec says we have to zero
+ * it out before setting it
+ */
writeb(0, &ch->ch_neo_uart->efr);
/* Turn on UART enhanced bits */
@@ -298,7 +308,9 @@ static inline void neo_set_no_output_flow_control(struct channel_t *ch)
else
efr &= ~(UART_17158_EFR_ECB | UART_17158_EFR_IXON);
- /* Why? Becuz Exar's spec says we have to zero it out before setting it */
+ /* Why? Because Exar's spec says we have to zero it
+ * out before setting it
+ */
writeb(0, &ch->ch_neo_uart->efr);
/* Turn on UART enhanced bits */
@@ -399,19 +411,17 @@ static inline void neo_parse_isr(struct dgnc_board *brd, uint port)
if (isr & (UART_17158_IIR_RDI_TIMEOUT | UART_IIR_RDI)) {
/* Read data from uart -> queue */
- brd->intr_rx++;
- ch->ch_intr_rx++;
neo_copy_data_from_uart_to_queue(ch);
- /* Call our tty layer to enforce queue flow control if needed. */
+ /* Call our tty layer to enforce queue
+ * flow control if needed.
+ */
spin_lock_irqsave(&ch->ch_lock, flags);
dgnc_check_queue_flow_control(ch);
spin_unlock_irqrestore(&ch->ch_lock, flags);
}
if (isr & UART_IIR_THRI) {
- brd->intr_tx++;
- ch->ch_intr_tx++;
/* Transfer data (if any) from Write Queue -> UART. */
spin_lock_irqsave(&ch->ch_lock, flags);
ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
@@ -428,7 +438,9 @@ static inline void neo_parse_isr(struct dgnc_board *brd, uint port)
* one it was, so we can suspend or resume data flow.
*/
if (cause == UART_17158_XON_DETECT) {
- /* Is output stopped right now, if so, resume it */
+ /* Is output stopped right now, if so,
+ * resume it
+ */
if (brd->channels[port]->ch_flags & CH_STOP) {
spin_lock_irqsave(&ch->ch_lock,
flags);
@@ -437,7 +449,8 @@ static inline void neo_parse_isr(struct dgnc_board *brd, uint port)
flags);
}
} else if (cause == UART_17158_XOFF_DETECT) {
- if (!(brd->channels[port]->ch_flags & CH_STOP)) {
+ if (!(brd->channels[port]->ch_flags &
+ CH_STOP)) {
spin_lock_irqsave(&ch->ch_lock,
flags);
ch->ch_flags |= CH_STOP;
@@ -449,11 +462,10 @@ static inline void neo_parse_isr(struct dgnc_board *brd, uint port)
if (isr & UART_17158_IIR_HWFLOW_STATE_CHANGE) {
/*
- * If we get here, this means the hardware is doing auto flow control.
- * Check to see whether RTS/DTR or CTS/DSR caused this interrupt.
+ * If we get here, this means the hardware is
+ * doing auto flow control. Check to see whether
+ * RTS/DTR or CTS/DSR caused this interrupt.
*/
- brd->intr_modem++;
- ch->ch_intr_modem++;
cause = readb(&ch->ch_neo_uart->mcr);
/* Which pin is doing auto flow? RTS or DTR? */
if ((cause & 0x4) == 0) {
@@ -517,8 +529,6 @@ static inline void neo_parse_lsr(struct dgnc_board *brd, uint port)
ch->ch_cached_lsr |= linestatus;
if (ch->ch_cached_lsr & UART_LSR_DR) {
- brd->intr_rx++;
- ch->ch_intr_rx++;
/* Read data from uart -> queue */
neo_copy_data_from_uart_to_queue(ch);
spin_lock_irqsave(&ch->ch_lock, flags);
@@ -545,14 +555,13 @@ static inline void neo_parse_lsr(struct dgnc_board *brd, uint port)
* Rx Oruns. Exar says that an orun will NOT corrupt
* the FIFO. It will just replace the holding register
* with this new data byte. So basically just ignore this.
- * Probably we should eventually have an orun stat in our driver...
+ * Probably we should eventually have an orun stat in our
+ * driver...
*/
ch->ch_err_overrun++;
}
if (linestatus & UART_LSR_THRE) {
- brd->intr_tx++;
- ch->ch_intr_tx++;
spin_lock_irqsave(&ch->ch_lock, flags);
ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
spin_unlock_irqrestore(&ch->ch_lock, flags);
@@ -560,8 +569,6 @@ static inline void neo_parse_lsr(struct dgnc_board *brd, uint port)
/* Transfer data (if any) from Write Queue -> UART. */
neo_copy_data_from_queue_to_uart(ch);
} else if (linestatus & UART_17158_TX_AND_FIFO_CLR) {
- brd->intr_tx++;
- ch->ch_intr_tx++;
spin_lock_irqsave(&ch->ch_lock, flags);
ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
spin_unlock_irqrestore(&ch->ch_lock, flags);
@@ -665,7 +672,9 @@ static void neo_param(struct tty_struct *tty)
4800, 9600, 19200, 38400 }
};
- /* Only use the TXPrint baud rate if the terminal unit is NOT open */
+ /* Only use the TXPrint baud rate if the terminal unit
+ * is NOT open
+ */
if (!(ch->ch_tun.un_flags & UN_ISOPEN) &&
(un->un_type == DGNC_PRINT))
baud = C_BAUD(ch->ch_pun.un_tty) & 0xff;
@@ -788,7 +797,9 @@ static void neo_param(struct tty_struct *tty)
if (ch->ch_digi.digi_flags & CTSPACE || ch->ch_c_cflag & CRTSCTS) {
neo_set_cts_flow_control(ch);
} else if (ch->ch_c_iflag & IXON) {
- /* If start/stop is set to disable, then we should disable flow control */
+ /* If start/stop is set to disable, then we should
+ * disable flow control
+ */
if ((ch->ch_startc == _POSIX_VDISABLE) ||
(ch->ch_stopc == _POSIX_VDISABLE))
neo_set_no_output_flow_control(ch);
@@ -801,7 +812,9 @@ static void neo_param(struct tty_struct *tty)
if (ch->ch_digi.digi_flags & RTSPACE || ch->ch_c_cflag & CRTSCTS) {
neo_set_rts_flow_control(ch);
} else if (ch->ch_c_iflag & IXOFF) {
- /* If start/stop is set to disable, then we should disable flow control */
+ /* If start/stop is set to disable, then we should
+ * disable flow control
+ */
if ((ch->ch_startc == _POSIX_VDISABLE) ||
(ch->ch_stopc == _POSIX_VDISABLE))
neo_set_no_input_flow_control(ch);
@@ -926,8 +939,6 @@ static irqreturn_t neo_intr(int irq, void *voidbrd)
if (!brd || brd->magic != DGNC_BOARD_MAGIC)
return IRQ_NONE;
- brd->intr_count++;
-
/* Lock out the slow poller from running on this board. */
spin_lock_irqsave(&brd->bd_intr_lock, flags);
@@ -940,14 +951,18 @@ static irqreturn_t neo_intr(int irq, void *voidbrd)
/*
* If 0, no interrupts pending.
- * This can happen if the IRQ is shared among a couple Neo/Classic boards.
+ * This can happen if the IRQ is shared among a couple Neo/Classic
+ * boards.
*/
if (!uart_poll) {
spin_unlock_irqrestore(&brd->bd_intr_lock, flags);
return IRQ_NONE;
}
- /* At this point, we have at least SOMETHING to service, dig further... */
+ /*
+ * At this point, we have at least SOMETHING to service, dig
+ * further...
+ */
/* Loop on each port */
while ((uart_poll & 0xff) != 0) {
@@ -971,7 +986,10 @@ static irqreturn_t neo_intr(int irq, void *voidbrd)
ch = brd->channels[port];
neo_copy_data_from_uart_to_queue(ch);
- /* Call our tty layer to enforce queue flow control if needed. */
+ /*
+ * Call our tty layer to enforce queue flow control if
+ * needed.
+ */
spin_lock_irqsave(&ch->ch_lock, flags2);
dgnc_check_queue_flow_control(ch);
spin_unlock_irqrestore(&ch->ch_lock, flags2);
@@ -987,16 +1005,18 @@ static irqreturn_t neo_intr(int irq, void *voidbrd)
case UART_17158_TXRDY:
/*
- * TXRDY interrupt clears after reading ISR register for the UART channel.
+ * TXRDY interrupt clears after reading ISR register
+ * for the UART channel.
*/
/*
* Yes, this is odd...
* Why would I check EVERY possibility of type of
* interrupt, when we know its TXRDY???
- * Becuz for some reason, even tho we got triggered for TXRDY,
- * it seems to be occasionally wrong. Instead of TX, which
- * it should be, I was getting things like RXDY too. Weird.
+ * Becuz for some reason, even tho we got triggered for
+ * TXRDY, it seems to be occasionally wrong. Instead of
+ * TX, which it should be, I was getting things like
+ * RXDY too. Weird.
*/
neo_parse_isr(brd, port);
break;
@@ -1011,8 +1031,8 @@ static irqreturn_t neo_intr(int irq, void *voidbrd)
default:
/*
* The UART triggered us with a bogus interrupt type.
- * It appears the Exar chip, when REALLY bogged down, will throw
- * these once and awhile.
+ * It appears the Exar chip, when REALLY bogged down,
+ * will throw these once and awhile.
* Its harmless, just ignore it and move on.
*/
break;
@@ -1230,7 +1250,8 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch)
}
/*
- * If our queue is full, we have no choice but to drop some data.
+ * If our queue is full, we have no choice but to drop some
+ * data.
* The assumption is that HWFLOW or SWFLOW should have stopped
* things way way before we got to this point.
*
@@ -1323,7 +1344,10 @@ static void neo_flush_uart_write(struct channel_t *ch)
neo_pci_posting_flush(ch->ch_bd);
for (i = 0; i < 10; i++) {
- /* Check to see if the UART feels it completely flushed the FIFO. */
+ /*
+ * Check to see if the UART feels it completely flushed the
+ * FIFO.
+ */
tmp = readb(&ch->ch_neo_uart->isr_fcr);
if (tmp & 4)
udelay(10);
@@ -1352,7 +1376,10 @@ static void neo_flush_uart_read(struct channel_t *ch)
neo_pci_posting_flush(ch->ch_bd);
for (i = 0; i < 10; i++) {
- /* Check to see if the UART feels it completely flushed the FIFO. */
+ /*
+ * Check to see if the UART feels it completely flushed the
+ * FIFO.
+ */
tmp = readb(&ch->ch_neo_uart->isr_fcr);
if (tmp & 2)
udelay(10);
@@ -1397,8 +1424,9 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch)
ch->ch_cached_lsr &= ~(UART_LSR_THRE);
/*
- * If RTS Toggle mode is on, turn on RTS now if not already set,
- * and make sure we get an event when the data transfer has completed.
+ * If RTS Toggle mode is on, turn on RTS now if not
+ * already set, and make sure we get an event when the
+ * data transfer has completed.
*/
if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) {
if (!(ch->ch_mostat & UART_MCR_RTS)) {
@@ -1408,8 +1436,9 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch)
ch->ch_tun.un_flags |= (UN_EMPTY);
}
/*
- * If DTR Toggle mode is on, turn on DTR now if not already set,
- * and make sure we get an event when the data transfer has completed.
+ * If DTR Toggle mode is on, turn on DTR now if not
+ * already set, and make sure we get an event when the
+ * data transfer has completed.
*/
if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) {
if (!(ch->ch_mostat & UART_MCR_DTR)) {
@@ -1465,7 +1494,8 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch)
/*
* If RTS Toggle mode is on, turn on RTS now if not already set,
- * and make sure we get an event when the data transfer has completed.
+ * and make sure we get an event when the data transfer has
+ * completed.
*/
if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) {
if (!(ch->ch_mostat & UART_MCR_RTS)) {
@@ -1477,7 +1507,8 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch)
/*
* If DTR Toggle mode is on, turn on DTR now if not already set,
- * and make sure we get an event when the data transfer has completed.
+ * and make sure we get an event when the data transfer has
+ * completed.
*/
if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) {
if (!(ch->ch_mostat & UART_MCR_DTR)) {
@@ -1541,7 +1572,10 @@ static void neo_parse_modem(struct channel_t *ch, unsigned char signals)
}
}
- /* Scrub off lower bits. They signify delta's, which I don't care about */
+ /*
+ * Scrub off lower bits. They signify delta's, which I don't care
+ * about
+ */
msignals &= 0xf0;
if (msignals & UART_MSR_DCD)
diff --git a/drivers/staging/dgnc/dgnc_sysfs.c b/drivers/staging/dgnc/dgnc_sysfs.c
index b8d41c5617e2..290bf6e226ac 100644
--- a/drivers/staging/dgnc/dgnc_sysfs.c
+++ b/drivers/staging/dgnc/dgnc_sysfs.c
@@ -25,31 +25,31 @@
#include "dgnc_driver.h"
#include "dgnc_mgmt.h"
-static ssize_t dgnc_driver_version_show(struct device_driver *ddp, char *buf)
+static ssize_t version_show(struct device_driver *ddp, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART);
}
-static DRIVER_ATTR(version, S_IRUSR, dgnc_driver_version_show, NULL);
+static DRIVER_ATTR_RO(version);
-static ssize_t dgnc_driver_boards_show(struct device_driver *ddp, char *buf)
+static ssize_t boards_show(struct device_driver *ddp, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", dgnc_num_boards);
}
-static DRIVER_ATTR(boards, S_IRUSR, dgnc_driver_boards_show, NULL);
+static DRIVER_ATTR_RO(boards);
-static ssize_t dgnc_driver_maxboards_show(struct device_driver *ddp, char *buf)
+static ssize_t maxboards_show(struct device_driver *ddp, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS);
}
-static DRIVER_ATTR(maxboards, S_IRUSR, dgnc_driver_maxboards_show, NULL);
+static DRIVER_ATTR_RO(maxboards);
-static ssize_t dgnc_driver_pollrate_show(struct device_driver *ddp, char *buf)
+static ssize_t pollrate_show(struct device_driver *ddp, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%dms\n", dgnc_poll_tick);
}
-static ssize_t dgnc_driver_pollrate_store(struct device_driver *ddp,
- const char *buf, size_t count)
+static ssize_t pollrate_store(struct device_driver *ddp,
+ const char *buf, size_t count)
{
unsigned long flags;
int tick;
@@ -65,8 +65,7 @@ static ssize_t dgnc_driver_pollrate_store(struct device_driver *ddp,
return count;
}
-static DRIVER_ATTR(pollrate, (S_IRUSR | S_IWUSR), dgnc_driver_pollrate_show,
- dgnc_driver_pollrate_store);
+static DRIVER_ATTR_RW(pollrate);
void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver)
{
@@ -103,8 +102,8 @@ void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver)
return 0; \
} while (0)
-static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr,
- char *buf)
+static ssize_t vpd_show(struct device *p, struct device_attribute *attr,
+ char *buf)
{
struct dgnc_board *bd;
int count = 0;
@@ -123,10 +122,10 @@ static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr,
return count;
}
-static DEVICE_ATTR(vpd, S_IRUSR, dgnc_vpd_show, NULL);
+static DEVICE_ATTR_RO(vpd);
-static ssize_t dgnc_serial_number_show(struct device *p,
- struct device_attribute *attr, char *buf)
+static ssize_t serial_number_show(struct device *p,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
int count = 0;
@@ -140,10 +139,10 @@ static ssize_t dgnc_serial_number_show(struct device *p,
return count;
}
-static DEVICE_ATTR(serial_number, S_IRUSR, dgnc_serial_number_show, NULL);
+static DEVICE_ATTR_RO(serial_number);
-static ssize_t dgnc_ports_state_show(struct device *p,
- struct device_attribute *attr, char *buf)
+static ssize_t ports_state_show(struct device *p,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
int count = 0;
@@ -158,10 +157,10 @@ static ssize_t dgnc_ports_state_show(struct device *p,
}
return count;
}
-static DEVICE_ATTR(ports_state, S_IRUSR, dgnc_ports_state_show, NULL);
+static DEVICE_ATTR_RO(ports_state);
-static ssize_t dgnc_ports_baud_show(struct device *p,
- struct device_attribute *attr, char *buf)
+static ssize_t ports_baud_show(struct device *p,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
int count = 0;
@@ -176,11 +175,10 @@ static ssize_t dgnc_ports_baud_show(struct device *p,
}
return count;
}
-static DEVICE_ATTR(ports_baud, S_IRUSR, dgnc_ports_baud_show, NULL);
+static DEVICE_ATTR_RO(ports_baud);
-static ssize_t dgnc_ports_msignals_show(struct device *p,
- struct device_attribute *attr,
- char *buf)
+static ssize_t ports_msignals_show(struct device *p,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
int count = 0;
@@ -208,10 +206,10 @@ static ssize_t dgnc_ports_msignals_show(struct device *p,
}
return count;
}
-static DEVICE_ATTR(ports_msignals, S_IRUSR, dgnc_ports_msignals_show, NULL);
+static DEVICE_ATTR_RO(ports_msignals);
-static ssize_t dgnc_ports_iflag_show(struct device *p,
- struct device_attribute *attr, char *buf)
+static ssize_t ports_iflag_show(struct device *p,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
int count = 0;
@@ -226,10 +224,10 @@ static ssize_t dgnc_ports_iflag_show(struct device *p,
}
return count;
}
-static DEVICE_ATTR(ports_iflag, S_IRUSR, dgnc_ports_iflag_show, NULL);
+static DEVICE_ATTR_RO(ports_iflag);
-static ssize_t dgnc_ports_cflag_show(struct device *p,
- struct device_attribute *attr, char *buf)
+static ssize_t ports_cflag_show(struct device *p,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
int count = 0;
@@ -244,10 +242,10 @@ static ssize_t dgnc_ports_cflag_show(struct device *p,
}
return count;
}
-static DEVICE_ATTR(ports_cflag, S_IRUSR, dgnc_ports_cflag_show, NULL);
+static DEVICE_ATTR_RO(ports_cflag);
-static ssize_t dgnc_ports_oflag_show(struct device *p,
- struct device_attribute *attr, char *buf)
+static ssize_t ports_oflag_show(struct device *p,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
int count = 0;
@@ -262,10 +260,10 @@ static ssize_t dgnc_ports_oflag_show(struct device *p,
}
return count;
}
-static DEVICE_ATTR(ports_oflag, S_IRUSR, dgnc_ports_oflag_show, NULL);
+static DEVICE_ATTR_RO(ports_oflag);
-static ssize_t dgnc_ports_lflag_show(struct device *p,
- struct device_attribute *attr, char *buf)
+static ssize_t ports_lflag_show(struct device *p,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
int count = 0;
@@ -280,11 +278,10 @@ static ssize_t dgnc_ports_lflag_show(struct device *p,
}
return count;
}
-static DEVICE_ATTR(ports_lflag, S_IRUSR, dgnc_ports_lflag_show, NULL);
+static DEVICE_ATTR_RO(ports_lflag);
-static ssize_t dgnc_ports_digi_flag_show(struct device *p,
- struct device_attribute *attr,
- char *buf)
+static ssize_t ports_digi_flag_show(struct device *p,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
int count = 0;
@@ -299,10 +296,10 @@ static ssize_t dgnc_ports_digi_flag_show(struct device *p,
}
return count;
}
-static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgnc_ports_digi_flag_show, NULL);
+static DEVICE_ATTR_RO(ports_digi_flag);
-static ssize_t dgnc_ports_rxcount_show(struct device *p,
- struct device_attribute *attr, char *buf)
+static ssize_t ports_rxcount_show(struct device *p,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
int count = 0;
@@ -317,10 +314,10 @@ static ssize_t dgnc_ports_rxcount_show(struct device *p,
}
return count;
}
-static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgnc_ports_rxcount_show, NULL);
+static DEVICE_ATTR_RO(ports_rxcount);
-static ssize_t dgnc_ports_txcount_show(struct device *p,
- struct device_attribute *attr, char *buf)
+static ssize_t ports_txcount_show(struct device *p,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
int count = 0;
@@ -335,7 +332,7 @@ static ssize_t dgnc_ports_txcount_show(struct device *p,
}
return count;
}
-static DEVICE_ATTR(ports_txcount, S_IRUSR, dgnc_ports_txcount_show, NULL);
+static DEVICE_ATTR_RO(ports_txcount);
/* this function creates the sys files that will export each signal status
* to sysfs each value will be put in a separate filename
@@ -378,8 +375,8 @@ void dgnc_remove_ports_sysfiles(struct dgnc_board *bd)
device_remove_file(&bd->pdev->dev, &dev_attr_serial_number);
}
-static ssize_t dgnc_tty_state_show(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t tty_state_show(struct device *d,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
struct channel_t *ch;
@@ -402,10 +399,10 @@ static ssize_t dgnc_tty_state_show(struct device *d,
return snprintf(buf, PAGE_SIZE, "%s",
un->un_open_count ? "Open" : "Closed");
}
-static DEVICE_ATTR(state, S_IRUSR, dgnc_tty_state_show, NULL);
+static DEVICE_ATTR_RO(tty_state);
-static ssize_t dgnc_tty_baud_show(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t tty_baud_show(struct device *d,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
struct channel_t *ch;
@@ -427,10 +424,10 @@ static ssize_t dgnc_tty_baud_show(struct device *d,
return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
}
-static DEVICE_ATTR(baud, S_IRUSR, dgnc_tty_baud_show, NULL);
+static DEVICE_ATTR_RO(tty_baud);
-static ssize_t dgnc_tty_msignals_show(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t tty_msignals_show(struct device *d,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
struct channel_t *ch;
@@ -461,10 +458,10 @@ static ssize_t dgnc_tty_msignals_show(struct device *d,
}
return 0;
}
-static DEVICE_ATTR(msignals, S_IRUSR, dgnc_tty_msignals_show, NULL);
+static DEVICE_ATTR_RO(tty_msignals);
-static ssize_t dgnc_tty_iflag_show(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t tty_iflag_show(struct device *d,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
struct channel_t *ch;
@@ -486,10 +483,10 @@ static ssize_t dgnc_tty_iflag_show(struct device *d,
return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
}
-static DEVICE_ATTR(iflag, S_IRUSR, dgnc_tty_iflag_show, NULL);
+static DEVICE_ATTR_RO(tty_iflag);
-static ssize_t dgnc_tty_cflag_show(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t tty_cflag_show(struct device *d,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
struct channel_t *ch;
@@ -511,10 +508,10 @@ static ssize_t dgnc_tty_cflag_show(struct device *d,
return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
}
-static DEVICE_ATTR(cflag, S_IRUSR, dgnc_tty_cflag_show, NULL);
+static DEVICE_ATTR_RO(tty_cflag);
-static ssize_t dgnc_tty_oflag_show(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t tty_oflag_show(struct device *d,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
struct channel_t *ch;
@@ -536,10 +533,10 @@ static ssize_t dgnc_tty_oflag_show(struct device *d,
return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
}
-static DEVICE_ATTR(oflag, S_IRUSR, dgnc_tty_oflag_show, NULL);
+static DEVICE_ATTR_RO(tty_oflag);
-static ssize_t dgnc_tty_lflag_show(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t tty_lflag_show(struct device *d,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
struct channel_t *ch;
@@ -561,10 +558,10 @@ static ssize_t dgnc_tty_lflag_show(struct device *d,
return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
}
-static DEVICE_ATTR(lflag, S_IRUSR, dgnc_tty_lflag_show, NULL);
+static DEVICE_ATTR_RO(tty_lflag);
-static ssize_t dgnc_tty_digi_flag_show(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t tty_digi_flag_show(struct device *d,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
struct channel_t *ch;
@@ -586,10 +583,10 @@ static ssize_t dgnc_tty_digi_flag_show(struct device *d,
return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
}
-static DEVICE_ATTR(digi_flag, S_IRUSR, dgnc_tty_digi_flag_show, NULL);
+static DEVICE_ATTR_RO(tty_digi_flag);
-static ssize_t dgnc_tty_rxcount_show(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t tty_rxcount_show(struct device *d,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
struct channel_t *ch;
@@ -611,10 +608,10 @@ static ssize_t dgnc_tty_rxcount_show(struct device *d,
return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
}
-static DEVICE_ATTR(rxcount, S_IRUSR, dgnc_tty_rxcount_show, NULL);
+static DEVICE_ATTR_RO(tty_rxcount);
-static ssize_t dgnc_tty_txcount_show(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t tty_txcount_show(struct device *d,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
struct channel_t *ch;
@@ -636,10 +633,10 @@ static ssize_t dgnc_tty_txcount_show(struct device *d,
return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
}
-static DEVICE_ATTR(txcount, S_IRUSR, dgnc_tty_txcount_show, NULL);
+static DEVICE_ATTR_RO(tty_txcount);
-static ssize_t dgnc_tty_name_show(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t tty_custom_name_show(struct device *d,
+ struct device_attribute *attr, char *buf)
{
struct dgnc_board *bd;
struct channel_t *ch;
@@ -663,24 +660,24 @@ static ssize_t dgnc_tty_name_show(struct device *d,
(un->un_type == DGNC_PRINT) ? "pr" : "tty",
bd->boardnum + 1, 'a' + ch->ch_portnum);
}
-static DEVICE_ATTR(custom_name, S_IRUSR, dgnc_tty_name_show, NULL);
+static DEVICE_ATTR_RO(tty_custom_name);
static struct attribute *dgnc_sysfs_tty_entries[] = {
- &dev_attr_state.attr,
- &dev_attr_baud.attr,
- &dev_attr_msignals.attr,
- &dev_attr_iflag.attr,
- &dev_attr_cflag.attr,
- &dev_attr_oflag.attr,
- &dev_attr_lflag.attr,
- &dev_attr_digi_flag.attr,
- &dev_attr_rxcount.attr,
- &dev_attr_txcount.attr,
- &dev_attr_custom_name.attr,
+ &dev_attr_tty_state.attr,
+ &dev_attr_tty_baud.attr,
+ &dev_attr_tty_msignals.attr,
+ &dev_attr_tty_iflag.attr,
+ &dev_attr_tty_cflag.attr,
+ &dev_attr_tty_oflag.attr,
+ &dev_attr_tty_lflag.attr,
+ &dev_attr_tty_digi_flag.attr,
+ &dev_attr_tty_rxcount.attr,
+ &dev_attr_tty_txcount.attr,
+ &dev_attr_tty_custom_name.attr,
NULL
};
-static struct attribute_group dgnc_tty_attribute_group = {
+static const struct attribute_group dgnc_tty_attribute_group = {
.name = NULL,
.attrs = dgnc_sysfs_tty_entries,
};
diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c
index 4eeecc992a02..953d9310fa74 100644
--- a/drivers/staging/dgnc/dgnc_tty.c
+++ b/drivers/staging/dgnc/dgnc_tty.c
@@ -45,7 +45,6 @@
/*
* internal variables
*/
-static struct dgnc_board *dgnc_BoardsByMajor[256];
static unsigned char *dgnc_TmpWriteBuf;
/*
@@ -100,7 +99,7 @@ static void dgnc_tty_unthrottle(struct tty_struct *tty);
static void dgnc_tty_flush_chars(struct tty_struct *tty);
static void dgnc_tty_flush_buffer(struct tty_struct *tty);
static void dgnc_tty_hangup(struct tty_struct *tty);
-static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command,
+static int dgnc_set_modem_info(struct channel_t *ch, unsigned int command,
unsigned int __user *value);
static int dgnc_get_modem_info(struct channel_t *ch,
unsigned int __user *value);
@@ -186,7 +185,8 @@ int dgnc_tty_register(struct dgnc_board *brd)
if (IS_ERR(brd->serial_driver))
return PTR_ERR(brd->serial_driver);
- snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgnc_%d_", brd->boardnum);
+ snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgnc_%d_",
+ brd->boardnum);
brd->serial_driver->name = brd->serial_name;
brd->serial_driver->name_base = 0;
@@ -203,15 +203,11 @@ int dgnc_tty_register(struct dgnc_board *brd)
*/
tty_set_operations(brd->serial_driver, &dgnc_tty_ops);
- if (!brd->dgnc_major_serial_registered) {
- /* Register tty devices */
- rc = tty_register_driver(brd->serial_driver);
- if (rc < 0) {
- dev_dbg(&brd->pdev->dev,
- "Can't register tty device (%d)\n", rc);
- goto free_serial_driver;
- }
- brd->dgnc_major_serial_registered = true;
+ rc = tty_register_driver(brd->serial_driver);
+ if (rc < 0) {
+ dev_dbg(&brd->pdev->dev,
+ "Can't register tty device (%d)\n", rc);
+ goto free_serial_driver;
}
/*
@@ -246,20 +242,14 @@ int dgnc_tty_register(struct dgnc_board *brd)
*/
tty_set_operations(brd->print_driver, &dgnc_tty_ops);
- if (!brd->dgnc_major_transparent_print_registered) {
- /* Register Transparent Print devices */
- rc = tty_register_driver(brd->print_driver);
- if (rc < 0) {
- dev_dbg(&brd->pdev->dev,
- "Can't register Transparent Print device(%d)\n",
- rc);
- goto free_print_driver;
- }
- brd->dgnc_major_transparent_print_registered = true;
+ rc = tty_register_driver(brd->print_driver);
+ if (rc < 0) {
+ dev_dbg(&brd->pdev->dev,
+ "Can't register Transparent Print device(%d)\n",
+ rc);
+ goto free_print_driver;
}
- dgnc_BoardsByMajor[brd->serial_driver->major] = brd;
-
return 0;
free_print_driver:
@@ -272,6 +262,14 @@ free_serial_driver:
return rc;
}
+void dgnc_tty_unregister(struct dgnc_board *brd)
+{
+ tty_unregister_driver(brd->print_driver);
+ tty_unregister_driver(brd->serial_driver);
+ put_tty_driver(brd->print_driver);
+ put_tty_driver(brd->serial_driver);
+}
+
/*
* dgnc_tty_init()
*
@@ -378,38 +376,30 @@ void dgnc_tty_post_uninit(void)
}
/*
- * dgnc_tty_uninit()
+ * dgnc_cleanup_tty()
*
* Uninitialize the TTY portion of this driver. Free all memory and
* resources.
*/
-void dgnc_tty_uninit(struct dgnc_board *brd)
+void dgnc_cleanup_tty(struct dgnc_board *brd)
{
int i = 0;
- if (brd->dgnc_major_serial_registered) {
- dgnc_BoardsByMajor[brd->serial_driver->major] = NULL;
- for (i = 0; i < brd->nasync; i++) {
- if (brd->channels[i])
- dgnc_remove_tty_sysfs(brd->channels[i]->
- ch_tun.un_sysfs);
- tty_unregister_device(brd->serial_driver, i);
- }
- tty_unregister_driver(brd->serial_driver);
- brd->dgnc_major_serial_registered = false;
+ for (i = 0; i < brd->nasync; i++) {
+ if (brd->channels[i])
+ dgnc_remove_tty_sysfs(brd->channels[i]->
+ ch_tun.un_sysfs);
+ tty_unregister_device(brd->serial_driver, i);
}
+ tty_unregister_driver(brd->serial_driver);
- if (brd->dgnc_major_transparent_print_registered) {
- dgnc_BoardsByMajor[brd->print_driver->major] = NULL;
- for (i = 0; i < brd->nasync; i++) {
- if (brd->channels[i])
- dgnc_remove_tty_sysfs(brd->channels[i]->
- ch_pun.un_sysfs);
- tty_unregister_device(brd->print_driver, i);
- }
- tty_unregister_driver(brd->print_driver);
- brd->dgnc_major_transparent_print_registered = false;
+ for (i = 0; i < brd->nasync; i++) {
+ if (brd->channels[i])
+ dgnc_remove_tty_sysfs(brd->channels[i]->
+ ch_pun.un_sysfs);
+ tty_unregister_device(brd->print_driver, i);
}
+ tty_unregister_driver(brd->print_driver);
put_tty_driver(brd->serial_driver);
put_tty_driver(brd->print_driver);
@@ -640,19 +630,12 @@ exit_unlock:
************************************************************************/
void dgnc_carrier(struct channel_t *ch)
{
- struct dgnc_board *bd;
-
int virt_carrier = 0;
int phys_carrier = 0;
if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
return;
- bd = ch->ch_bd;
-
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return;
-
if (ch->ch_mistat & UART_MSR_DCD)
phys_carrier = 1;
@@ -947,6 +930,24 @@ void dgnc_wakeup_writes(struct channel_t *ch)
spin_unlock_irqrestore(&ch->ch_lock, flags);
}
+struct dgnc_board *find_board_by_major(unsigned int major)
+{
+ int i;
+
+ for (i = 0; i < MAXBOARDS; i++) {
+ struct dgnc_board *brd = dgnc_board[i];
+
+ if (!brd)
+ return NULL;
+
+ if (major == brd->serial_driver->major ||
+ major == brd->print_driver->major)
+ return brd;
+ }
+
+ return NULL;
+}
+
/************************************************************************
*
* TTY Entry points and helper functions
@@ -976,7 +977,7 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
return -ENXIO;
/* Get board pointer from our array of majors we have allocated */
- brd = dgnc_BoardsByMajor[major];
+ brd = find_board_by_major(major);
if (!brd)
return -ENXIO;
@@ -1172,17 +1173,12 @@ static int dgnc_block_til_ready(struct tty_struct *tty,
struct channel_t *ch)
{
int retval = 0;
- struct un_t *un = NULL;
+ struct un_t *un = tty->driver_data;
unsigned long flags;
uint old_flags = 0;
int sleep_on_un_flags = 0;
- if (!tty || tty->magic != TTY_MAGIC || !file || !ch ||
- ch->magic != DGNC_CHANNEL_MAGIC)
- return -ENXIO;
-
- un = tty->driver_data;
- if (!un || un->magic != DGNC_UNIT_MAGIC)
+ if (!file)
return -ENXIO;
spin_lock_irqsave(&ch->ch_lock, flags);
@@ -1301,15 +1297,9 @@ static int dgnc_block_til_ready(struct tty_struct *tty,
*/
static void dgnc_tty_hangup(struct tty_struct *tty)
{
- struct un_t *un;
-
if (!tty || tty->magic != TTY_MAGIC)
return;
- un = tty->driver_data;
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return;
-
/* flush the transmit queues */
dgnc_tty_flush_buffer(tty);
}
@@ -1510,18 +1500,8 @@ static int dgnc_tty_chars_in_buffer(struct tty_struct *tty)
* returns the new bytes_available. This only affects printer
* output.
*/
-static int dgnc_maxcps_room(struct tty_struct *tty, int bytes_available)
+static int dgnc_maxcps_room(struct channel_t *ch, int bytes_available)
{
- struct un_t *un = tty->driver_data;
- struct channel_t *ch = un->un_ch;
-
- /*
- * If its not the Transparent print device, return
- * the full data amount.
- */
- if (un->un_type != DGNC_PRINT)
- return bytes_available;
-
if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0) {
int cps_limit = 0;
unsigned long current_time = jiffies;
@@ -1585,7 +1565,8 @@ static int dgnc_tty_write_room(struct tty_struct *tty)
ret += WQUEUESIZE;
/* Limit printer to maxcps */
- ret = dgnc_maxcps_room(tty, ret);
+ if (un->un_type != DGNC_PRINT)
+ ret = dgnc_maxcps_room(ch, ret);
/*
* If we are printer device, leave space for
@@ -1677,7 +1658,8 @@ static int dgnc_tty_write(struct tty_struct *tty,
* Limit printer output to maxcps overall, with bursts allowed
* up to bufsize characters.
*/
- bufcount = dgnc_maxcps_room(tty, bufcount);
+ if (un->un_type != DGNC_PRINT)
+ bufcount = dgnc_maxcps_room(ch, bufcount);
/*
* Take minimum of what the user wants to send, and the
@@ -1984,7 +1966,7 @@ static void dgnc_tty_send_xchar(struct tty_struct *tty, char c)
static inline int dgnc_get_mstat(struct channel_t *ch)
{
unsigned char mstat;
- int result = -EIO;
+ int result = 0;
unsigned long flags;
if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
@@ -1996,8 +1978,6 @@ static inline int dgnc_get_mstat(struct channel_t *ch)
spin_unlock_irqrestore(&ch->ch_lock, flags);
- result = 0;
-
if (mstat & UART_MCR_DTR)
result |= TIOCM_DTR;
if (mstat & UART_MCR_RTS)
@@ -2028,32 +2008,14 @@ static int dgnc_get_modem_info(struct channel_t *ch,
*
* Set modem signals, called by ld.
*/
-static int dgnc_set_modem_info(struct tty_struct *tty,
+static int dgnc_set_modem_info(struct channel_t *ch,
unsigned int command,
unsigned int __user *value)
{
- struct dgnc_board *bd;
- struct channel_t *ch;
- struct un_t *un;
int ret = -ENXIO;
unsigned int arg = 0;
unsigned long flags;
- if (!tty || tty->magic != TTY_MAGIC)
- return ret;
-
- un = tty->driver_data;
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return ret;
-
- ch = un->un_ch;
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return ret;
-
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return ret;
-
ret = get_user(arg, value);
if (ret)
return ret;
@@ -2593,9 +2555,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
spin_unlock_irqrestore(&ch->ch_lock, flags);
- rc = put_user(C_CLOCAL(tty) ? 1 : 0,
- (unsigned long __user *)arg);
- return rc;
+ return put_user(C_CLOCAL(tty) ? 1 : 0,
+ (unsigned long __user *)arg);
case TIOCSSOFTCAR:
@@ -2620,7 +2581,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
case TIOCMBIC:
case TIOCMSET:
spin_unlock_irqrestore(&ch->ch_lock, flags);
- return dgnc_set_modem_info(tty, cmd, uarg);
+ return dgnc_set_modem_info(ch, cmd, uarg);
/*
* Here are any additional ioctl's that we want to implement
@@ -2766,8 +2727,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
case DIGI_GETCUSTOMBAUD:
spin_unlock_irqrestore(&ch->ch_lock, flags);
- rc = put_user(ch->ch_custom_speed, (unsigned int __user *)arg);
- return rc;
+ return put_user(ch->ch_custom_speed,
+ (unsigned int __user *)arg);
case DIGI_SETCUSTOMBAUD:
{
@@ -2853,8 +2814,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
events |= (EV_IPU | EV_IPS);
spin_unlock_irqrestore(&ch->ch_lock, flags);
- rc = put_user(events, (unsigned int __user *)arg);
- return rc;
+ return put_user(events, (unsigned int __user *)arg);
}
/*
diff --git a/drivers/staging/dgnc/dgnc_tty.h b/drivers/staging/dgnc/dgnc_tty.h
index 21d3369b875c..24c9a412211e 100644
--- a/drivers/staging/dgnc/dgnc_tty.h
+++ b/drivers/staging/dgnc/dgnc_tty.h
@@ -19,12 +19,13 @@
#include "dgnc_driver.h"
int dgnc_tty_register(struct dgnc_board *brd);
+void dgnc_tty_unregister(struct dgnc_board *brd);
int dgnc_tty_preinit(void);
int dgnc_tty_init(struct dgnc_board *);
void dgnc_tty_post_uninit(void);
-void dgnc_tty_uninit(struct dgnc_board *);
+void dgnc_cleanup_tty(struct dgnc_board *);
void dgnc_input(struct channel_t *ch);
void dgnc_carrier(struct channel_t *ch);
diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c
index 3b56b2826263..c3e298843b43 100644
--- a/drivers/staging/emxx_udc/emxx_udc.c
+++ b/drivers/staging/emxx_udc/emxx_udc.c
@@ -131,7 +131,6 @@ static void _nbu2ss_dump_register(struct nbu2ss_udc *udc)
reg_data = _nbu2ss_readl(
(u32 *)IO_ADDRESS(USB_BASE_ADDRESS + i + 12));
dev_dbg(&udc->dev, " %08x\n", (int)reg_data);
-
}
spin_lock(&udc->lock);
@@ -478,9 +477,9 @@ static void _nbu2ss_dma_map_single(
)
{
if (req->req.dma == DMA_ADDR_INVALID) {
- if (req->unaligned)
+ if (req->unaligned) {
req->req.dma = ep->phys_buf;
- else {
+ } else {
req->req.dma = dma_map_single(
udc->gadget.dev.parent,
req->req.buf,
@@ -1236,9 +1235,9 @@ static int _nbu2ss_start_transfer(
req->dma_flag = FALSE;
req->div_len = 0;
- if (req->req.length == 0)
+ if (req->req.length == 0) {
req->zero = false;
- else {
+ } else {
if ((req->req.length % ep->ep.maxpacket) == 0)
req->zero = req->req.zero;
else
@@ -1941,9 +1940,9 @@ static void _nbu2ss_ep_done(
if (likely(req->req.status == -EINPROGRESS))
req->req.status = status;
- if (ep->stalled)
+ if (ep->stalled) {
_nbu2ss_epn_set_stall(udc, ep);
- else {
+ } else {
if (!list_empty(&ep->queue))
_nbu2ss_restert_transfer(ep);
}
@@ -2264,9 +2263,7 @@ static int _nbu2ss_enable_controller(struct nbu2ss_udc *udc)
if (udc->udc_enabled)
return 0;
- /*
- Reset
- */
+ /* Reset */
_nbu2ss_bitset(&udc->p_regs->EPCTR, (DIRPD | EPC_RST));
udelay(EPC_RST_DISABLE_TIME); /* 1us wait */
@@ -2476,8 +2473,9 @@ static irqreturn_t _nbu2ss_udc_irq(int irq, void *_udc)
_nbu2ss_writel(&preg->USB_INT_STA, ~USB_INT_STA_RW);
_nbu2ss_writel(&preg->USB_INT_ENA, 0);
status = 0;
- } else
+ } else {
status = _nbu2ss_readl(&preg->USB_INT_STA);
+ }
if (status == 0)
break;
diff --git a/drivers/staging/emxx_udc/emxx_udc.h b/drivers/staging/emxx_udc/emxx_udc.h
index 39769e3a801c..789bfb97143c 100644
--- a/drivers/staging/emxx_udc/emxx_udc.h
+++ b/drivers/staging/emxx_udc/emxx_udc.h
@@ -586,7 +586,7 @@ struct nbu2ss_udc {
unsigned remote_wakeup:1;
unsigned udc_enabled:1;
- unsigned mA;
+ unsigned int mA;
u32 curr_config; /* Current Configuration Number */
diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c
index 82b46cd27ca7..7561385761e9 100644
--- a/drivers/staging/fbtft/fb_agm1264k-fl.c
+++ b/drivers/staging/fbtft/fb_agm1264k-fl.c
@@ -350,8 +350,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
}
}
- /* 1 string = 2 pages */
- for (y = addr_win.ys_page; y <= addr_win.ye_page; ++y) {
+ /* 1 string = 2 pages */
+ for (y = addr_win.ys_page; y <= addr_win.ye_page; ++y) {
/* left half of display */
if (addr_win.xs < par->info->var.xres / 2) {
construct_line_bitmap(par, buf, convert_buf,
diff --git a/drivers/staging/fbtft/fb_ili9320.c b/drivers/staging/fbtft/fb_ili9320.c
index 6ff222d6d6d6..278e4c7e95e5 100644
--- a/drivers/staging/fbtft/fb_ili9320.c
+++ b/drivers/staging/fbtft/fb_ili9320.c
@@ -29,7 +29,7 @@
#define DEFAULT_GAMMA "07 07 6 0 0 0 5 5 4 0\n" \
"07 08 4 7 5 1 2 0 7 7"
-static unsigned read_devicecode(struct fbtft_par *par)
+static unsigned int read_devicecode(struct fbtft_par *par)
{
int ret;
u8 rxbuf[8] = {0, };
@@ -41,7 +41,7 @@ static unsigned read_devicecode(struct fbtft_par *par)
static int init_display(struct fbtft_par *par)
{
- unsigned devcode;
+ unsigned int devcode;
par->fbtftops.reset(par);
diff --git a/drivers/staging/fbtft/fb_ili9325.c b/drivers/staging/fbtft/fb_ili9325.c
index fdf98d37550e..c31e2e051d4a 100644
--- a/drivers/staging/fbtft/fb_ili9325.c
+++ b/drivers/staging/fbtft/fb_ili9325.c
@@ -32,26 +32,26 @@
#define DEFAULT_GAMMA "0F 00 7 2 0 0 6 5 4 1\n" \
"04 16 2 7 6 3 2 1 7 7"
-static unsigned bt = 6; /* VGL=Vci*4 , VGH=Vci*4 */
+static unsigned int bt = 6; /* VGL=Vci*4 , VGH=Vci*4 */
module_param(bt, uint, 0);
MODULE_PARM_DESC(bt, "Sets the factor used in the step-up circuits");
-static unsigned vc = 0x03; /* Vci1=Vci*0.80 */
+static unsigned int vc = 0x03; /* Vci1=Vci*0.80 */
module_param(vc, uint, 0);
MODULE_PARM_DESC(vc,
"Sets the ratio factor of Vci to generate the reference voltages Vci1");
-static unsigned vrh = 0x0d; /* VREG1OUT=Vci*1.85 */
+static unsigned int vrh = 0x0d; /* VREG1OUT=Vci*1.85 */
module_param(vrh, uint, 0);
MODULE_PARM_DESC(vrh,
"Set the amplifying rate (1.6 ~ 1.9) of Vci applied to output the VREG1OUT");
-static unsigned vdv = 0x12; /* VCOMH amplitude=VREG1OUT*0.98 */
+static unsigned int vdv = 0x12; /* VCOMH amplitude=VREG1OUT*0.98 */
module_param(vdv, uint, 0);
MODULE_PARM_DESC(vdv,
"Select the factor of VREG1OUT to set the amplitude of Vcom");
-static unsigned vcm = 0x0a; /* VCOMH=VREG1OUT*0.735 */
+static unsigned int vcm = 0x0a; /* VCOMH=VREG1OUT*0.735 */
module_param(vcm, uint, 0);
MODULE_PARM_DESC(vcm, "Set the internal VcomH voltage");
diff --git a/drivers/staging/fbtft/fb_pcd8544.c b/drivers/staging/fbtft/fb_pcd8544.c
index a6b43323f29a..a4710dc067ef 100644
--- a/drivers/staging/fbtft/fb_pcd8544.c
+++ b/drivers/staging/fbtft/fb_pcd8544.c
@@ -32,11 +32,11 @@
#define TXBUFLEN (84 * 6)
#define DEFAULT_GAMMA "40" /* gamma controls the contrast in this driver */
-static unsigned tc;
+static unsigned int tc;
module_param(tc, uint, 0);
MODULE_PARM_DESC(tc, "TC[1:0] Temperature coefficient: 0-3 (default: 0)");
-static unsigned bs = 4;
+static unsigned int bs = 4;
module_param(bs, uint, 0);
MODULE_PARM_DESC(bs, "BS[2:0] Bias voltage level: 0-7 (default: 4)");
diff --git a/drivers/staging/fbtft/fb_s6d02a1.c b/drivers/staging/fbtft/fb_s6d02a1.c
index 3113355062fc..774b0ff69e6d 100644
--- a/drivers/staging/fbtft/fb_s6d02a1.c
+++ b/drivers/staging/fbtft/fb_s6d02a1.c
@@ -113,12 +113,14 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
#define MV BIT(5)
static int set_var(struct fbtft_par *par)
{
- /* Memory data access control (0x36h)
- RGB/BGR:
- 1. Mode selection pin SRGB
- RGB H/W pin for color filter setting: 0=RGB, 1=BGR
- 2. MADCTL RGB bit
- RGB-BGR ORDER color filter panel: 0=RGB, 1=BGR */
+ /*
+ * Memory data access control (0x36h)
+ * RGB/BGR:
+ * 1. Mode selection pin SRGB
+ * RGB H/W pin for color filter setting: 0=RGB, 1=BGR
+ * 2. MADCTL RGB bit
+ * RGB-BGR ORDER color filter panel: 0=RGB, 1=BGR
+ */
switch (par->info->var.rotate) {
case 0:
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
diff --git a/drivers/staging/fbtft/fb_s6d1121.c b/drivers/staging/fbtft/fb_s6d1121.c
index d6ae76b318ad..9b1d70b218df 100644
--- a/drivers/staging/fbtft/fb_s6d1121.c
+++ b/drivers/staging/fbtft/fb_s6d1121.c
@@ -125,10 +125,10 @@ static int set_var(struct fbtft_par *par)
}
/*
- Gamma string format:
- PKP0 PKP1 PKP2 PKP3 PKP4 PKP5 PKP6 PKP7 PKP8 PKP9 PKP10 PKP11 VRP0 VRP1
- PKN0 PKN1 PKN2 PKN3 PKN4 PKN5 PKN6 PKN7 PRN8 PRN9 PRN10 PRN11 VRN0 VRN1
-*/
+ * Gamma string format:
+ * PKP0 PKP1 PKP2 PKP3 PKP4 PKP5 PKP6 PKP7 PKP8 PKP9 PKP10 PKP11 VRP0 VRP1
+ * PKN0 PKN1 PKN2 PKN3 PKN4 PKN5 PKN6 PKN7 PRN8 PRN9 PRN10 PRN11 VRN0 VRN1
+ */
#define CURVE(num, idx) curves[num * par->gamma.num_values + idx]
static int set_gamma(struct fbtft_par *par, unsigned long *curves)
{
diff --git a/drivers/staging/fbtft/fb_ssd1289.c b/drivers/staging/fbtft/fb_ssd1289.c
index 1162c08613fa..25f9fbe1e76f 100644
--- a/drivers/staging/fbtft/fb_ssd1289.c
+++ b/drivers/staging/fbtft/fb_ssd1289.c
@@ -29,7 +29,7 @@
#define DEFAULT_GAMMA "02 03 2 5 7 7 4 2 4 2\n" \
"02 03 2 5 7 5 4 2 4 2"
-static unsigned reg11 = 0x6040;
+static unsigned int reg11 = 0x6040;
module_param(reg11, uint, 0);
MODULE_PARM_DESC(reg11, "Register 11h value");
@@ -131,10 +131,10 @@ static int set_var(struct fbtft_par *par)
}
/*
- Gamma string format:
- VRP0 VRP1 PRP0 PRP1 PKP0 PKP1 PKP2 PKP3 PKP4 PKP5
- VRN0 VRN1 PRN0 PRN1 PKN0 PKN1 PKN2 PKN3 PKN4 PKN5
-*/
+ * Gamma string format:
+ * VRP0 VRP1 PRP0 PRP1 PKP0 PKP1 PKP2 PKP3 PKP4 PKP5
+ * VRN0 VRN1 PRN0 PRN1 PKN0 PKN1 PKN2 PKN3 PKN4 PKN5
+ */
#define CURVE(num, idx) curves[num * par->gamma.num_values + idx]
static int set_gamma(struct fbtft_par *par, unsigned long *curves)
{
diff --git a/drivers/staging/fbtft/fb_ssd1306.c b/drivers/staging/fbtft/fb_ssd1306.c
index e0b34a42c9c6..80fc57029fee 100644
--- a/drivers/staging/fbtft/fb_ssd1306.c
+++ b/drivers/staging/fbtft/fb_ssd1306.c
@@ -27,15 +27,15 @@
#define HEIGHT 64
/*
- write_reg() caveat:
-
- This doesn't work because D/C has to be LOW for both values:
- write_reg(par, val1, val2);
-
- Do it like this:
- write_reg(par, val1);
- write_reg(par, val2);
-*/
+ * write_reg() caveat:
+ *
+ * This doesn't work because D/C has to be LOW for both values:
+ * write_reg(par, val1, val2);
+ *
+ * Do it like this:
+ * write_reg(par, val1);
+ * write_reg(par, val2);
+ */
/* Init sequence taken from the Adafruit SSD1306 Arduino library */
static int init_display(struct fbtft_par *par)
@@ -113,8 +113,9 @@ static int init_display(struct fbtft_par *par)
write_reg(par, 0xA4);
/* Set Normal Display
- 0 in RAM: OFF in display panel
- 1 in RAM: ON in display panel */
+ * 0 in RAM: OFF in display panel
+ * 1 in RAM: ON in display panel
+ */
write_reg(par, 0xA6);
/* Set Display ON */
diff --git a/drivers/staging/fbtft/fb_ssd1331.c b/drivers/staging/fbtft/fb_ssd1331.c
index bd294f886c5f..1d74ac1343a8 100644
--- a/drivers/staging/fbtft/fb_ssd1331.c
+++ b/drivers/staging/fbtft/fb_ssd1331.c
@@ -102,26 +102,26 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
}
/*
- Grayscale Lookup Table
- GS1 - GS63
- The driver Gamma curve contains the relative values between the entries
- in the Lookup table.
-
- From datasheet:
- 8.8 Gray Scale Decoder
-
- there are total 180 Gamma Settings (Setting 0 to Setting 180)
- available for the Gray Scale table.
-
- The gray scale is defined in incremental way, with reference
- to the length of previous table entry:
- Setting of GS1 has to be >= 0
- Setting of GS2 has to be > Setting of GS1 +1
- Setting of GS3 has to be > Setting of GS2 +1
- :
- Setting of GS63 has to be > Setting of GS62 +1
-
-*/
+ * Grayscale Lookup Table
+ * GS1 - GS63
+ * The driver Gamma curve contains the relative values between the entries
+ * in the Lookup table.
+ *
+ * From datasheet:
+ * 8.8 Gray Scale Decoder
+ *
+ * there are total 180 Gamma Settings (Setting 0 to Setting 180)
+ * available for the Gray Scale table.
+ *
+ * The gray scale is defined in incremental way, with reference
+ * to the length of previous table entry:
+ * Setting of GS1 has to be >= 0
+ * Setting of GS2 has to be > Setting of GS1 +1
+ * Setting of GS3 has to be > Setting of GS2 +1
+ * :
+ * Setting of GS63 has to be > Setting of GS62 +1
+ *
+ */
static int set_gamma(struct fbtft_par *par, unsigned long *curves)
{
unsigned long tmp[GAMMA_NUM * GAMMA_LEN];
diff --git a/drivers/staging/fbtft/fb_ssd1351.c b/drivers/staging/fbtft/fb_ssd1351.c
index cef33e439f46..200aa9ba98f9 100644
--- a/drivers/staging/fbtft/fb_ssd1351.c
+++ b/drivers/staging/fbtft/fb_ssd1351.c
@@ -25,8 +25,8 @@ static void register_onboard_backlight(struct fbtft_par *par);
static int init_display(struct fbtft_par *par)
{
- if (par->pdata
- && par->pdata->display.backlight == FBTFT_ONBOARD_BACKLIGHT) {
+ if (par->pdata &&
+ par->pdata->display.backlight == FBTFT_ONBOARD_BACKLIGHT) {
/* module uses onboard GPIO for panel power */
par->fbtftops.register_backlight = register_onboard_backlight;
}
@@ -66,7 +66,7 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
static int set_var(struct fbtft_par *par)
{
- unsigned remap;
+ unsigned int remap;
if (par->fbtftops.init_display != init_display) {
/* don't risk messing up register A0h */
@@ -80,10 +80,10 @@ static int set_var(struct fbtft_par *par)
switch (par->info->var.rotate) {
case 0:
- write_reg(par, 0xA0, remap | 0x00 | 1<<4);
+ write_reg(par, 0xA0, remap | 0x00 | 1 << 4);
break;
case 270:
- write_reg(par, 0xA0, remap | 0x03 | 1<<4);
+ write_reg(par, 0xA0, remap | 0x03 | 1 << 4);
break;
case 180:
write_reg(par, 0xA0, remap | 0x02);
@@ -189,8 +189,8 @@ static int update_onboard_backlight(struct backlight_device *bd)
"%s: power=%d, fb_blank=%d\n",
__func__, bd->props.power, bd->props.fb_blank);
- on = (bd->props.power == FB_BLANK_UNBLANK)
- && (bd->props.fb_blank == FB_BLANK_UNBLANK);
+ on = (bd->props.power == FB_BLANK_UNBLANK) &&
+ (bd->props.fb_blank == FB_BLANK_UNBLANK);
/* Onboard backlight connected to GPIO0 on SSD1351, GPIO1 unused */
write_reg(par, 0xB5, on ? 0x03 : 0x02);
diff --git a/drivers/staging/fbtft/fb_st7735r.c b/drivers/staging/fbtft/fb_st7735r.c
index c5e51fe1aad5..6670f2bb62ec 100644
--- a/drivers/staging/fbtft/fb_st7735r.c
+++ b/drivers/staging/fbtft/fb_st7735r.c
@@ -33,35 +33,43 @@ static int default_init_sequence[] = {
-2, 500, /* delay */
/* FRMCTR1 - frame rate control: normal mode
- frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D) */
+ * frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D)
+ */
-1, 0xB1, 0x01, 0x2C, 0x2D,
/* FRMCTR2 - frame rate control: idle mode
- frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D) */
+ * frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D)
+ */
-1, 0xB2, 0x01, 0x2C, 0x2D,
/* FRMCTR3 - frame rate control - partial mode
- dot inversion mode, line inversion mode */
+ * dot inversion mode, line inversion mode
+ */
-1, 0xB3, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D,
/* INVCTR - display inversion control
- no inversion */
+ * no inversion
+ */
-1, 0xB4, 0x07,
/* PWCTR1 - Power Control
- -4.6V, AUTO mode */
+ * -4.6V, AUTO mode
+ */
-1, 0xC0, 0xA2, 0x02, 0x84,
/* PWCTR2 - Power Control
- VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD */
+ * VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD
+ */
-1, 0xC1, 0xC5,
/* PWCTR3 - Power Control
- Opamp current small, Boost frequency */
+ * Opamp current small, Boost frequency
+ */
-1, 0xC2, 0x0A, 0x00,
/* PWCTR4 - Power Control
- BCLK/2, Opamp current small & Medium low */
+ * BCLK/2, Opamp current small & Medium low
+ */
-1, 0xC3, 0x8A, 0x2A,
/* PWCTR5 - Power Control */
@@ -101,11 +109,12 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
static int set_var(struct fbtft_par *par)
{
/* MADCTL - Memory data access control
- RGB/BGR:
- 1. Mode selection pin SRGB
- RGB H/W pin for color filter setting: 0=RGB, 1=BGR
- 2. MADCTL RGB bit
- RGB-BGR ORDER color filter panel: 0=RGB, 1=BGR */
+ * RGB/BGR:
+ * 1. Mode selection pin SRGB
+ * RGB H/W pin for color filter setting: 0=RGB, 1=BGR
+ * 2. MADCTL RGB bit
+ * RGB-BGR ORDER color filter panel: 0=RGB, 1=BGR
+ */
switch (par->info->var.rotate) {
case 0:
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
@@ -129,10 +138,10 @@ static int set_var(struct fbtft_par *par)
}
/*
- Gamma string format:
- VRF0P VOS0P PK0P PK1P PK2P PK3P PK4P PK5P PK6P PK7P PK8P PK9P SELV0P SELV1P SELV62P SELV63P
- VRF0N VOS0N PK0N PK1N PK2N PK3N PK4N PK5N PK6N PK7N PK8N PK9N SELV0N SELV1N SELV62N SELV63N
-*/
+ * Gamma string format:
+ * VRF0P VOS0P PK0P PK1P PK2P PK3P PK4P PK5P PK6P PK7P PK8P PK9P SELV0P SELV1P SELV62P SELV63P
+ * VRF0N VOS0N PK0N PK1N PK2N PK3N PK4N PK5N PK6N PK7N PK8N PK9N SELV0N SELV1N SELV62N SELV63N
+ */
#define CURVE(num, idx) curves[num * par->gamma.num_values + idx]
static int set_gamma(struct fbtft_par *par, unsigned long *curves)
{
diff --git a/drivers/staging/fbtft/fb_tls8204.c b/drivers/staging/fbtft/fb_tls8204.c
index 2183f98c8315..ea2ddacb9468 100644
--- a/drivers/staging/fbtft/fb_tls8204.c
+++ b/drivers/staging/fbtft/fb_tls8204.c
@@ -35,7 +35,7 @@
/* gamma is used to control contrast in this driver */
#define DEFAULT_GAMMA "40"
-static unsigned bs = 4;
+static unsigned int bs = 4;
module_param(bs, uint, 0);
MODULE_PARM_DESC(bs, "BS[2:0] Bias voltage level: 0-7 (default: 4)");
@@ -44,21 +44,21 @@ static int init_display(struct fbtft_par *par)
par->fbtftops.reset(par);
/* Enter extended command mode */
- write_reg(par, 0x21); /* 5:1 1
- 2:0 PD - Powerdown control: chip is active
- 1:0 V - Entry mode: horizontal addressing
- 0:1 H - Extended instruction set control:
- extended
- */
+ write_reg(par, 0x21); /* 5:1 1
+ * 2:0 PD - Powerdown control: chip is active
+ * 1:0 V - Entry mode: horizontal addressing
+ * 0:1 H - Extended instruction set control:
+ * extended
+ */
/* H=1 Bias system */
- write_reg(par, 0x10 | (bs & 0x7)); /*
- 4:1 1
- 3:0 0
- 2:x BS2 - Bias System
- 1:x BS1
- 0:x BS0
- */
+ write_reg(par, 0x10 | (bs & 0x7));
+ /* 4:1 1
+ * 3:0 0
+ * 2:x BS2 - Bias System
+ * 1:x BS1
+ * 0:x BS0
+ */
/* Set the address of the first display line. */
write_reg(par, 0x04 | (64 >> 6));
@@ -68,12 +68,12 @@ static int init_display(struct fbtft_par *par)
write_reg(par, 0x20);
/* H=0 Display control */
- write_reg(par, 0x08 | 4); /*
- 3:1 1
- 2:1 D - DE: 10=normal mode
- 1:0 0
- 0:0 E
- */
+ write_reg(par, 0x08 | 4);
+ /* 3:1 1
+ * 2:1 D - DE: 10=normal mode
+ * 1:0 0
+ * 0:0 E
+ */
return 0;
}
@@ -81,15 +81,15 @@ static int init_display(struct fbtft_par *par)
static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
/* H=0 Set X address of RAM */
- write_reg(par, 0x80); /* 7:1 1
- 6-0: X[6:0] - 0x00
- */
+ write_reg(par, 0x80); /* 7:1 1
+ * 6-0: X[6:0] - 0x00
+ */
/* H=0 Set Y address of RAM */
- write_reg(par, 0x40); /* 7:0 0
- 6:1 1
- 2-0: Y[2:0] - 0x0
- */
+ write_reg(par, 0x40); /* 7:0 0
+ * 6:1 1
+ * 2-0: Y[2:0] - 0x0
+ */
}
static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
@@ -100,8 +100,9 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
for (y = 0; y < HEIGHT / 8; y++) {
u8 *buf = par->txbuf.buf;
- /* The display is 102x68 but the LCD is 84x48. Set
- the write pointer at the start of each row. */
+ /* The display is 102x68 but the LCD is 84x48.
+ * Set the write pointer at the start of each row.
+ */
gpio_set_value(par->gpio.dc, 0);
write_reg(par, 0x80 | 0);
write_reg(par, 0x40 | y);
diff --git a/drivers/staging/fbtft/fb_uc1611.c b/drivers/staging/fbtft/fb_uc1611.c
index e87401aacfb3..b33b73f17da4 100644
--- a/drivers/staging/fbtft/fb_uc1611.c
+++ b/drivers/staging/fbtft/fb_uc1611.c
@@ -41,30 +41,30 @@
*/
/* BR -> actual ratio: 0-3 -> 5, 10, 11, 13 */
-static unsigned ratio = 2;
+static unsigned int ratio = 2;
module_param(ratio, uint, 0);
MODULE_PARM_DESC(ratio, "BR[1:0] Bias voltage ratio: 0-3 (default: 2)");
-static unsigned gain = 3;
+static unsigned int gain = 3;
module_param(gain, uint, 0);
MODULE_PARM_DESC(gain, "GN[1:0] Bias voltage gain: 0-3 (default: 3)");
-static unsigned pot = 16;
+static unsigned int pot = 16;
module_param(pot, uint, 0);
MODULE_PARM_DESC(pot, "PM[6:0] Bias voltage pot.: 0-63 (default: 16)");
/* TC -> % compensation per deg C: 0-3 -> -.05, -.10, -.015, -.20 */
-static unsigned temp;
+static unsigned int temp;
module_param(temp, uint, 0);
MODULE_PARM_DESC(temp, "TC[1:0] Temperature compensation: 0-3 (default: 0)");
/* PC[1:0] -> LCD capacitance: 0-3 -> <20nF, 20-28 nF, 29-40 nF, 40-56 nF */
-static unsigned load = 1;
+static unsigned int load = 1;
module_param(load, uint, 0);
MODULE_PARM_DESC(load, "PC[1:0] Panel Loading: 0-3 (default: 1)");
/* PC[3:2] -> V_LCD: 0, 1, 3 -> ext., int. with ratio = 5, int. standard */
-static unsigned pump = 3;
+static unsigned int pump = 3;
module_param(pump, uint, 0);
MODULE_PARM_DESC(pump, "PC[3:2] Pump control: 0,1,3 (default: 3)");
diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c
index f8cb610a7b69..a52e28a48825 100644
--- a/drivers/staging/fbtft/fb_watterott.c
+++ b/drivers/staging/fbtft/fb_watterott.c
@@ -67,7 +67,7 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
{
- unsigned start_line, end_line;
+ unsigned int start_line, end_line;
u16 *vmem16 = (u16 *)(par->info->screen_buffer + offset);
u16 *pos = par->txbuf.buf + 1;
u16 *buf16 = par->txbuf.buf + 10;
@@ -104,7 +104,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
static int write_vmem_8bit(struct fbtft_par *par, size_t offset, size_t len)
{
- unsigned start_line, end_line;
+ unsigned int start_line, end_line;
u16 *vmem16 = (u16 *)(par->info->screen_buffer + offset);
u16 *pos = par->txbuf.buf + 1;
u8 *buf8 = par->txbuf.buf + 10;
@@ -137,7 +137,7 @@ static int write_vmem_8bit(struct fbtft_par *par, size_t offset, size_t len)
return 0;
}
-static unsigned firmware_version(struct fbtft_par *par)
+static unsigned int firmware_version(struct fbtft_par *par)
{
u8 rxbuf[4] = {0, };
@@ -152,7 +152,7 @@ static unsigned firmware_version(struct fbtft_par *par)
static int init_display(struct fbtft_par *par)
{
int ret;
- unsigned version;
+ unsigned int version;
u8 save_mode;
/* enable SPI interface by having CS and MOSI low during reset */
diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c
index 83505bce628a..ec45043c0830 100644
--- a/drivers/staging/fbtft/fbtft-bus.c
+++ b/drivers/staging/fbtft/fbtft-bus.c
@@ -92,7 +92,8 @@ void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...)
if (par->spi && (par->spi->bits_per_word == 8)) {
/* we're emulating 9-bit, pad start of buffer with no-ops
- (assuming here that zero is a no-op) */
+ * (assuming here that zero is a no-op)
+ */
pad = (len % 4) ? 4 - (len % 4) : 0;
for (i = 0; i < pad; i++)
*buf++ = 0x000;
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
index 0c1a77cafe14..587f68aa466c 100644
--- a/drivers/staging/fbtft/fbtft-core.c
+++ b/drivers/staging/fbtft/fbtft-core.c
@@ -341,8 +341,8 @@ static void fbtft_reset(struct fbtft_par *par)
mdelay(120);
}
-static void fbtft_update_display(struct fbtft_par *par, unsigned start_line,
- unsigned end_line)
+static void fbtft_update_display(struct fbtft_par *par, unsigned int start_line,
+ unsigned int end_line)
{
size_t offset, len;
ktime_t ts_start, ts_end;
@@ -391,11 +391,11 @@ static void fbtft_update_display(struct fbtft_par *par, unsigned start_line,
if (unlikely(timeit)) {
ts_end = ktime_get();
- if (ktime_to_ns(par->update_time))
+ if (!ktime_to_ns(par->update_time))
par->update_time = ts_start;
- par->update_time = ts_start;
fps = ktime_us_delta(ts_start, par->update_time);
+ par->update_time = ts_start;
fps = fps ? 1000000 / fps : 0;
throughput = ktime_us_delta(ts_end, ts_start);
@@ -435,10 +435,10 @@ static void fbtft_mkdirty(struct fb_info *info, int y, int height)
static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagelist)
{
struct fbtft_par *par = info->par;
- unsigned dirty_lines_start, dirty_lines_end;
+ unsigned int dirty_lines_start, dirty_lines_end;
struct page *page;
unsigned long index;
- unsigned y_low = 0, y_high = 0;
+ unsigned int y_low = 0, y_high = 0;
int count = 0;
spin_lock(&par->dirty_lock);
@@ -526,18 +526,18 @@ static ssize_t fbtft_fb_write(struct fb_info *info, const char __user *buf,
}
/* from pxafb.c */
-static unsigned int chan_to_field(unsigned chan, struct fb_bitfield *bf)
+static unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
{
chan &= 0xffff;
chan >>= 16 - bf->length;
return chan << bf->offset;
}
-static int fbtft_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
+static int fbtft_fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
+ unsigned int blue, unsigned int transp,
struct fb_info *info)
{
- unsigned val;
+ unsigned int val;
int ret = 1;
dev_dbg(info->dev,
@@ -654,11 +654,11 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
u8 *vmem = NULL;
void *txbuf = NULL;
void *buf = NULL;
- unsigned width;
- unsigned height;
+ unsigned int width;
+ unsigned int height;
int txbuflen = display->txbuflen;
- unsigned bpp = display->bpp;
- unsigned fps = display->fps;
+ unsigned int bpp = display->bpp;
+ unsigned int fps = display->fps;
int vmem_size, i;
int *init_sequence = display->init_sequence;
char *gamma = display->gamma;
@@ -820,6 +820,8 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
/* Transmit buffer */
if (txbuflen == -1)
txbuflen = vmem_size + 2; /* add in case startbyte is used */
+ if (txbuflen >= vmem_size + 2)
+ txbuflen = 0;
#ifdef __LITTLE_ENDIAN
if ((!txbuflen) && (bpp > 8))
diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h
index d3bc3943a983..89c4b5b76ce6 100644
--- a/drivers/staging/fbtft/fbtft.h
+++ b/drivers/staging/fbtft/fbtft.h
@@ -38,7 +38,7 @@
*/
struct fbtft_gpio {
char name[FBTFT_GPIO_NAME_SIZE];
- unsigned gpio;
+ unsigned int gpio;
};
struct fbtft_par;
@@ -79,7 +79,7 @@ struct fbtft_ops {
void (*reset)(struct fbtft_par *par);
void (*mkdirty)(struct fb_info *info, int from, int to);
void (*update_display)(struct fbtft_par *par,
- unsigned start_line, unsigned end_line);
+ unsigned int start_line, unsigned int end_line);
int (*init_display)(struct fbtft_par *par);
int (*blank)(struct fbtft_par *par, bool on);
@@ -115,14 +115,14 @@ struct fbtft_ops {
* This structure is not stored by FBTFT except for init_sequence.
*/
struct fbtft_display {
- unsigned width;
- unsigned height;
- unsigned regwidth;
- unsigned buswidth;
- unsigned backlight;
+ unsigned int width;
+ unsigned int height;
+ unsigned int regwidth;
+ unsigned int buswidth;
+ unsigned int backlight;
struct fbtft_ops fbtftops;
- unsigned bpp;
- unsigned fps;
+ unsigned int bpp;
+ unsigned int fps;
int txbuflen;
int *init_sequence;
char *gamma;
@@ -146,9 +146,9 @@ struct fbtft_display {
struct fbtft_platform_data {
struct fbtft_display display;
const struct fbtft_gpio *gpios;
- unsigned rotate;
+ unsigned int rotate;
bool bgr;
- unsigned fps;
+ unsigned int fps;
int txbuflen;
u8 startbyte;
char *gamma;
@@ -216,8 +216,8 @@ struct fbtft_par {
u8 startbyte;
struct fbtft_ops fbtftops;
spinlock_t dirty_lock;
- unsigned dirty_lines_start;
- unsigned dirty_lines_end;
+ unsigned int dirty_lines_start;
+ unsigned int dirty_lines_end;
struct {
int reset;
int dc;
diff --git a/drivers/staging/fbtft/fbtft_device.c b/drivers/staging/fbtft/fbtft_device.c
index e4a355aefb25..e9211831b6a1 100644
--- a/drivers/staging/fbtft/fbtft_device.c
+++ b/drivers/staging/fbtft/fbtft_device.c
@@ -32,20 +32,20 @@ static char *name;
module_param(name, charp, 0);
MODULE_PARM_DESC(name, "Devicename (required). name=list => list all supported devices.");
-static unsigned rotate;
+static unsigned int rotate;
module_param(rotate, uint, 0);
MODULE_PARM_DESC(rotate,
"Angle to rotate display counter clockwise: 0, 90, 180, 270");
-static unsigned busnum;
+static unsigned int busnum;
module_param(busnum, uint, 0);
MODULE_PARM_DESC(busnum, "SPI bus number (default=0)");
-static unsigned cs;
+static unsigned int cs;
module_param(cs, uint, 0);
MODULE_PARM_DESC(cs, "SPI chip select (default=0)");
-static unsigned speed;
+static unsigned int speed;
module_param(speed, uint, 0);
MODULE_PARM_DESC(speed, "SPI speed (override device default)");
@@ -58,7 +58,7 @@ module_param(gpios, charp, 0);
MODULE_PARM_DESC(gpios,
"List of gpios. Comma separated with the form: reset:23,dc:24 (when overriding the default, all gpios must be specified)");
-static unsigned fps;
+static unsigned int fps;
module_param(fps, uint, 0);
MODULE_PARM_DESC(fps, "Frames per second (override driver default)");
@@ -76,7 +76,7 @@ module_param(bgr, int, 0);
MODULE_PARM_DESC(bgr,
"BGR bit (supported by some drivers).");
-static unsigned startbyte;
+static unsigned int startbyte;
module_param(startbyte, uint, 0);
MODULE_PARM_DESC(startbyte, "Sets the Start byte used by some SPI displays.");
@@ -84,15 +84,15 @@ static bool custom;
module_param(custom, bool, 0);
MODULE_PARM_DESC(custom, "Add a custom display device. Use speed= argument to make it a SPI device, else platform_device");
-static unsigned width;
+static unsigned int width;
module_param(width, uint, 0);
MODULE_PARM_DESC(width, "Display width, used with the custom argument");
-static unsigned height;
+static unsigned int height;
module_param(height, uint, 0);
MODULE_PARM_DESC(height, "Display height, used with the custom argument");
-static unsigned buswidth = 8;
+static unsigned int buswidth = 8;
module_param(buswidth, uint, 0);
MODULE_PARM_DESC(buswidth, "Display bus width, used with the custom argument");
@@ -106,7 +106,7 @@ module_param(debug, ulong, 0);
MODULE_PARM_DESC(debug,
"level: 0-7 (the remaining 29 bits is for advanced usage)");
-static unsigned verbose = 3;
+static unsigned int verbose = 3;
module_param(verbose, uint, 0);
MODULE_PARM_DESC(verbose,
"0 silent, >0 show gpios, >1 show devices, >2 show devices before (default=3)");
@@ -1215,7 +1215,8 @@ static struct fbtft_device_display displays[] = {
}
}, {
/* This should be the last item.
- Used with the custom argument */
+ * Used with the custom argument
+ */
.name = "",
.spi = &(struct spi_board_info) {
.modalias = "",
@@ -1306,8 +1307,9 @@ static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS + 1] = { };
static void fbtft_device_pdev_release(struct device *dev)
{
/* Needed to silence this message:
-Device 'xxx' does not have a release() function, it is broken and must be fixed
-*/
+ * Device 'xxx' does not have a release() function,
+ * it is broken and must be fixed
+ */
}
static int spi_device_found(struct device *dev, void *data)
@@ -1346,7 +1348,7 @@ static void pr_p_devices(void)
}
#ifdef MODULE
-static void fbtft_device_spi_delete(struct spi_master *master, unsigned cs)
+static void fbtft_device_spi_delete(struct spi_master *master, unsigned int cs)
{
struct device *dev;
char str[32];
@@ -1399,7 +1401,7 @@ static int __init fbtft_device_init(void)
long val;
int ret = 0;
- if (name == NULL) {
+ if (!name) {
#ifdef MODULE
pr_err("missing module parameter: 'name'\n");
return -EINVAL;
@@ -1416,14 +1418,14 @@ static int __init fbtft_device_init(void)
/* parse module parameter: gpios */
while ((p_gpio = strsep(&gpios, ","))) {
- if (strchr(p_gpio, ':') == NULL) {
+ if (!strchr(p_gpio, ':')) {
pr_err("error: missing ':' in gpios parameter: %s\n",
p_gpio);
return -EINVAL;
}
p_num = p_gpio;
p_name = strsep(&p_num, ":");
- if (p_name == NULL || p_num == NULL) {
+ if (!p_name || !p_num) {
pr_err("something bad happened parsing gpios parameter: %s\n",
p_gpio);
return -EINVAL;
diff --git a/drivers/staging/fsl-mc/bus/Makefile b/drivers/staging/fsl-mc/bus/Makefile
index e7315170b7a3..38716fd5cb58 100644
--- a/drivers/staging/fsl-mc/bus/Makefile
+++ b/drivers/staging/fsl-mc/bus/Makefile
@@ -7,13 +7,14 @@
#
obj-$(CONFIG_FSL_MC_BUS) += mc-bus-driver.o
-mc-bus-driver-objs := mc-bus.o \
+mc-bus-driver-objs := fsl-mc-bus.o \
mc-sys.o \
+ mc-io.o \
dprc.o \
dpmng.o \
dprc-driver.o \
- mc-allocator.o \
- mc-msi.o \
+ fsl-mc-allocator.o \
+ fsl-mc-msi.o \
irq-gic-v3-its-fsl-mc-msi.o \
dpmcp.o \
dpbp.o
diff --git a/drivers/staging/fsl-mc/bus/dpbp.c b/drivers/staging/fsl-mc/bus/dpbp.c
index fe271fbd629b..5d4cd812a400 100644
--- a/drivers/staging/fsl-mc/bus/dpbp.c
+++ b/drivers/staging/fsl-mc/bus/dpbp.c
@@ -1,34 +1,34 @@
/* Copyright 2013-2016 Freescale Semiconductor Inc.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-* * Neither the name of the above-listed copyright holders nor the
-* names of any contributors may be used to endorse or promote products
-* derived from this software without specific prior written permission.
-*
-*
-* ALTERNATIVELY, this software may be distributed under the terms of the
-* GNU General Public License ("GPL") as published by the Free Software
-* Foundation, either version 2 of that License or (at your option) any
-* later version.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-* POSSIBILITY OF SUCH DAMAGE.
-*/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
#include "../include/mc-sys.h"
#include "../include/mc-cmd.h"
#include "../include/dpbp.h"
diff --git a/drivers/staging/fsl-mc/bus/dpmcp.c b/drivers/staging/fsl-mc/bus/dpmcp.c
index 06440176243a..55766f78a528 100644
--- a/drivers/staging/fsl-mc/bus/dpmcp.c
+++ b/drivers/staging/fsl-mc/bus/dpmcp.c
@@ -31,6 +31,7 @@
*/
#include "../include/mc-sys.h"
#include "../include/mc-cmd.h"
+
#include "dpmcp.h"
#include "dpmcp-cmd.h"
@@ -368,7 +369,6 @@ int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io,
struct mc_command cmd = { 0 };
struct dpmcp_cmd_set_irq_mask *cmd_params;
-
/* prepare command */
cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_MASK,
cmd_flags, token);
diff --git a/drivers/staging/fsl-mc/bus/dpmng-cmd.h b/drivers/staging/fsl-mc/bus/dpmng-cmd.h
index 779bf9c25bc0..a7b77d58c8cd 100644
--- a/drivers/staging/fsl-mc/bus/dpmng-cmd.h
+++ b/drivers/staging/fsl-mc/bus/dpmng-cmd.h
@@ -1,4 +1,5 @@
-/* Copyright 2013-2016 Freescale Semiconductor Inc.
+/*
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -30,12 +31,12 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-/*************************************************************************//*
- dpmng-cmd.h
-
- defines portal commands
-
- *//**************************************************************************/
+/*
+ * dpmng-cmd.h
+ *
+ * defines portal commands
+ *
+ */
#ifndef __FSL_DPMNG_CMD_H
#define __FSL_DPMNG_CMD_H
diff --git a/drivers/staging/fsl-mc/bus/dpmng.c b/drivers/staging/fsl-mc/bus/dpmng.c
index 660bbe7ea899..96b1d67756fa 100644
--- a/drivers/staging/fsl-mc/bus/dpmng.c
+++ b/drivers/staging/fsl-mc/bus/dpmng.c
@@ -1,37 +1,38 @@
/* Copyright 2013-2016 Freescale Semiconductor Inc.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-* * Neither the name of the above-listed copyright holders nor the
-* names of any contributors may be used to endorse or promote products
-* derived from this software without specific prior written permission.
-*
-*
-* ALTERNATIVELY, this software may be distributed under the terms of the
-* GNU General Public License ("GPL") as published by the Free Software
-* Foundation, either version 2 of that License or (at your option) any
-* later version.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-* POSSIBILITY OF SUCH DAMAGE.
-*/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
#include "../include/mc-sys.h"
#include "../include/mc-cmd.h"
#include "../include/dpmng.h"
+
#include "dpmng-cmd.h"
/**
diff --git a/drivers/staging/fsl-mc/bus/dprc-cmd.h b/drivers/staging/fsl-mc/bus/dprc-cmd.h
index bb127f4a3ae7..009d65673155 100644
--- a/drivers/staging/fsl-mc/bus/dprc-cmd.h
+++ b/drivers/staging/fsl-mc/bus/dprc-cmd.h
@@ -1,4 +1,5 @@
-/* Copyright 2013-2016 Freescale Semiconductor Inc.
+/*
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -30,12 +31,12 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-/*************************************************************************//*
- dprc-cmd.h
-
- defines dprc portal commands
-
- *//**************************************************************************/
+/*
+ * dprc-cmd.h
+ *
+ * defines dprc portal commands
+ *
+ */
#ifndef _FSL_DPRC_CMD_H
#define _FSL_DPRC_CMD_H
diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c b/drivers/staging/fsl-mc/bus/dprc-driver.c
index d2a71f14bf72..c5ee4639682b 100644
--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -9,13 +9,21 @@
* warranty of any kind, whether express or implied.
*/
-#include "../include/mc-private.h"
-#include "../include/mc-sys.h"
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/msi.h>
+#include "../include/mc-bus.h"
+#include "../include/mc-sys.h"
+
#include "dprc-cmd.h"
+#include "fsl-mc-private.h"
+
+#define FSL_MC_DPRC_DRIVER_NAME "fsl_mc_dprc"
+
+#define FSL_MC_DEVICE_MATCH(_mc_dev, _obj_desc) \
+ (strcmp((_mc_dev)->obj_desc.type, (_obj_desc)->type) == 0 && \
+ (_mc_dev)->obj_desc.id == (_obj_desc)->id)
struct dprc_child_objs {
int child_count;
@@ -190,55 +198,6 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
}
}
-static void dprc_init_all_resource_pools(struct fsl_mc_device *mc_bus_dev)
-{
- int pool_type;
- struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
-
- for (pool_type = 0; pool_type < FSL_MC_NUM_POOL_TYPES; pool_type++) {
- struct fsl_mc_resource_pool *res_pool =
- &mc_bus->resource_pools[pool_type];
-
- res_pool->type = pool_type;
- res_pool->max_count = 0;
- res_pool->free_count = 0;
- res_pool->mc_bus = mc_bus;
- INIT_LIST_HEAD(&res_pool->free_list);
- mutex_init(&res_pool->mutex);
- }
-}
-
-static void dprc_cleanup_resource_pool(struct fsl_mc_device *mc_bus_dev,
- enum fsl_mc_pool_type pool_type)
-{
- struct fsl_mc_resource *resource;
- struct fsl_mc_resource *next;
- struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
- struct fsl_mc_resource_pool *res_pool =
- &mc_bus->resource_pools[pool_type];
- int free_count = 0;
-
- WARN_ON(res_pool->type != pool_type);
- WARN_ON(res_pool->free_count != res_pool->max_count);
-
- list_for_each_entry_safe(resource, next, &res_pool->free_list, node) {
- free_count++;
- WARN_ON(resource->type != res_pool->type);
- WARN_ON(resource->parent_pool != res_pool);
- devm_kfree(&mc_bus_dev->dev, resource);
- }
-
- WARN_ON(free_count != res_pool->free_count);
-}
-
-static void dprc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev)
-{
- int pool_type;
-
- for (pool_type = 0; pool_type < FSL_MC_NUM_POOL_TYPES; pool_type++)
- dprc_cleanup_resource_pool(mc_bus_dev, pool_type);
-}
-
/**
* dprc_scan_objects - Discover objects in a DPRC
*
@@ -363,7 +322,7 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
unsigned int irq_count;
struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
- dprc_init_all_resource_pools(mc_bus_dev);
+ fsl_mc_init_all_resource_pools(mc_bus_dev);
/*
* Discover objects in the DPRC:
@@ -390,7 +349,7 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
return 0;
error:
- dprc_cleanup_all_resource_pools(mc_bus_dev);
+ fsl_mc_cleanup_all_resource_pools(mc_bus_dev);
return error;
}
EXPORT_SYMBOL_GPL(dprc_scan_container);
@@ -649,7 +608,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
/*
* This is a child DPRC:
*/
- if (WARN_ON(parent_dev->bus != &fsl_mc_bus_type))
+ if (WARN_ON(!dev_is_fsl_mc(parent_dev)))
return -EINVAL;
if (WARN_ON(mc_dev->obj_desc.region_count == 0))
@@ -681,7 +640,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev)
*/
struct irq_domain *mc_msi_domain;
- if (WARN_ON(parent_dev->bus == &fsl_mc_bus_type))
+ if (WARN_ON(dev_is_fsl_mc(parent_dev)))
return -EINVAL;
error = fsl_mc_find_msi_domain(parent_dev,
@@ -802,7 +761,7 @@ static int dprc_remove(struct fsl_mc_device *mc_dev)
dev_set_msi_domain(&mc_dev->dev, NULL);
}
- dprc_cleanup_all_resource_pools(mc_dev);
+ fsl_mc_cleanup_all_resource_pools(mc_dev);
error = dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
if (error < 0)
diff --git a/drivers/staging/fsl-mc/bus/dprc.c b/drivers/staging/fsl-mc/bus/dprc.c
index c26054981333..9fea3def6041 100644
--- a/drivers/staging/fsl-mc/bus/dprc.c
+++ b/drivers/staging/fsl-mc/bus/dprc.c
@@ -1,37 +1,38 @@
/* Copyright 2013-2016 Freescale Semiconductor Inc.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-* * Neither the name of the above-listed copyright holders nor the
-* names of any contributors may be used to endorse or promote products
-* derived from this software without specific prior written permission.
-*
-*
-* ALTERNATIVELY, this software may be distributed under the terms of the
-* GNU General Public License ("GPL") as published by the Free Software
-* Foundation, either version 2 of that License or (at your option) any
-* later version.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-* POSSIBILITY OF SUCH DAMAGE.
-*/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
#include "../include/mc-sys.h"
#include "../include/mc-cmd.h"
#include "../include/dprc.h"
+
#include "dprc-cmd.h"
/**
@@ -1334,20 +1335,20 @@ int dprc_disconnect(struct fsl_mc_io *mc_io,
}
/**
-* dprc_get_connection() - Get connected endpoint and link status if connection
-* exists.
-* @mc_io: Pointer to MC portal's I/O object
-* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
-* @token: Token of DPRC object
-* @endpoint1: Endpoint 1 configuration parameters
-* @endpoint2: Returned endpoint 2 configuration parameters
-* @state: Returned link state:
-* 1 - link is up;
-* 0 - link is down;
-* -1 - no connection (endpoint2 information is irrelevant)
-*
-* Return: '0' on Success; -ENAVAIL if connection does not exist.
-*/
+ * dprc_get_connection() - Get connected endpoint and link status if connection
+ * exists.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPRC object
+ * @endpoint1: Endpoint 1 configuration parameters
+ * @endpoint2: Returned endpoint 2 configuration parameters
+ * @state: Returned link state:
+ * 1 - link is up;
+ * 0 - link is down;
+ * -1 - no connection (endpoint2 information is irrelevant)
+ *
+ * Return: '0' on Success; -ENAVAIL if connection does not exist.
+ */
int dprc_get_connection(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c b/drivers/staging/fsl-mc/bus/fsl-mc-allocator.c
index e59d85060c7b..e93ab53bae67 100644
--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
+++ b/drivers/staging/fsl-mc/bus/fsl-mc-allocator.c
@@ -8,14 +8,19 @@
* warranty of any kind, whether express or implied.
*/
-#include "../include/mc-private.h"
-#include "../include/mc-sys.h"
#include <linux/module.h>
+#include <linux/msi.h>
+#include "../include/mc-bus.h"
+#include "../include/mc-sys.h"
#include "../include/dpbp-cmd.h"
#include "../include/dpcon-cmd.h"
-#include "dpmcp-cmd.h"
-#include "dpmcp.h"
-#include <linux/msi.h>
+
+#include "fsl-mc-private.h"
+
+#define FSL_MC_IS_ALLOCATABLE(_obj_type) \
+ (strcmp(_obj_type, "dpbp") == 0 || \
+ strcmp(_obj_type, "dpmcp") == 0 || \
+ strcmp(_obj_type, "dpcon") == 0)
/**
* fsl_mc_resource_pool_add_device - add allocatable device to a resource
@@ -137,8 +142,7 @@ static int __must_check fsl_mc_resource_pool_remove_device(struct fsl_mc_device
goto out_unlock;
}
- list_del(&resource->node);
- INIT_LIST_HEAD(&resource->node);
+ list_del_init(&resource->node);
res_pool->free_count--;
res_pool->max_count--;
@@ -215,8 +219,7 @@ int __must_check fsl_mc_resource_allocate(struct fsl_mc_bus *mc_bus,
res_pool->free_count > res_pool->max_count))
goto out_unlock;
- list_del(&resource->node);
- INIT_LIST_HEAD(&resource->node);
+ list_del_init(&resource->node);
res_pool->free_count--;
error = 0;
@@ -252,144 +255,6 @@ out_unlock:
EXPORT_SYMBOL_GPL(fsl_mc_resource_free);
/**
- * fsl_mc_portal_allocate - Allocates an MC portal
- *
- * @mc_dev: MC device for which the MC portal is to be allocated
- * @mc_io_flags: Flags for the fsl_mc_io object that wraps the allocated
- * MC portal.
- * @new_mc_io: Pointer to area where the pointer to the fsl_mc_io object
- * that wraps the allocated MC portal is to be returned
- *
- * This function allocates an MC portal from the device's parent DPRC,
- * from the corresponding MC bus' pool of MC portals and wraps
- * it in a new fsl_mc_io object. If 'mc_dev' is a DPRC itself, the
- * portal is allocated from its own MC bus.
- */
-int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev,
- u16 mc_io_flags,
- struct fsl_mc_io **new_mc_io)
-{
- struct fsl_mc_device *mc_bus_dev;
- struct fsl_mc_bus *mc_bus;
- phys_addr_t mc_portal_phys_addr;
- size_t mc_portal_size;
- struct fsl_mc_device *dpmcp_dev;
- int error = -EINVAL;
- struct fsl_mc_resource *resource = NULL;
- struct fsl_mc_io *mc_io = NULL;
-
- if (mc_dev->flags & FSL_MC_IS_DPRC) {
- mc_bus_dev = mc_dev;
- } else {
- if (WARN_ON(mc_dev->dev.parent->bus != &fsl_mc_bus_type))
- return error;
-
- mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
- }
-
- mc_bus = to_fsl_mc_bus(mc_bus_dev);
- *new_mc_io = NULL;
- error = fsl_mc_resource_allocate(mc_bus, FSL_MC_POOL_DPMCP, &resource);
- if (error < 0)
- return error;
-
- error = -EINVAL;
- dpmcp_dev = resource->data;
- if (WARN_ON(!dpmcp_dev))
- goto error_cleanup_resource;
-
- if (dpmcp_dev->obj_desc.ver_major < DPMCP_MIN_VER_MAJOR ||
- (dpmcp_dev->obj_desc.ver_major == DPMCP_MIN_VER_MAJOR &&
- dpmcp_dev->obj_desc.ver_minor < DPMCP_MIN_VER_MINOR)) {
- dev_err(&dpmcp_dev->dev,
- "ERROR: Version %d.%d of DPMCP not supported.\n",
- dpmcp_dev->obj_desc.ver_major,
- dpmcp_dev->obj_desc.ver_minor);
- error = -ENOTSUPP;
- goto error_cleanup_resource;
- }
-
- if (WARN_ON(dpmcp_dev->obj_desc.region_count == 0))
- goto error_cleanup_resource;
-
- mc_portal_phys_addr = dpmcp_dev->regions[0].start;
- mc_portal_size = dpmcp_dev->regions[0].end -
- dpmcp_dev->regions[0].start + 1;
-
- if (WARN_ON(mc_portal_size != mc_bus_dev->mc_io->portal_size))
- goto error_cleanup_resource;
-
- error = fsl_create_mc_io(&mc_bus_dev->dev,
- mc_portal_phys_addr,
- mc_portal_size, dpmcp_dev,
- mc_io_flags, &mc_io);
- if (error < 0)
- goto error_cleanup_resource;
-
- *new_mc_io = mc_io;
- return 0;
-
-error_cleanup_resource:
- fsl_mc_resource_free(resource);
- return error;
-}
-EXPORT_SYMBOL_GPL(fsl_mc_portal_allocate);
-
-/**
- * fsl_mc_portal_free - Returns an MC portal to the pool of free MC portals
- * of a given MC bus
- *
- * @mc_io: Pointer to the fsl_mc_io object that wraps the MC portal to free
- */
-void fsl_mc_portal_free(struct fsl_mc_io *mc_io)
-{
- struct fsl_mc_device *dpmcp_dev;
- struct fsl_mc_resource *resource;
-
- /*
- * Every mc_io obtained by calling fsl_mc_portal_allocate() is supposed
- * to have a DPMCP object associated with.
- */
- dpmcp_dev = mc_io->dpmcp_dev;
- if (WARN_ON(!dpmcp_dev))
- return;
-
- resource = dpmcp_dev->resource;
- if (WARN_ON(!resource || resource->type != FSL_MC_POOL_DPMCP))
- return;
-
- if (WARN_ON(resource->data != dpmcp_dev))
- return;
-
- fsl_destroy_mc_io(mc_io);
- fsl_mc_resource_free(resource);
-}
-EXPORT_SYMBOL_GPL(fsl_mc_portal_free);
-
-/**
- * fsl_mc_portal_reset - Resets the dpmcp object for a given fsl_mc_io object
- *
- * @mc_io: Pointer to the fsl_mc_io object that wraps the MC portal to free
- */
-int fsl_mc_portal_reset(struct fsl_mc_io *mc_io)
-{
- int error;
- struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
-
- if (WARN_ON(!dpmcp_dev))
- return -EINVAL;
-
- error = dpmcp_reset(mc_io, 0, dpmcp_dev->mc_handle);
- if (error < 0) {
- dev_err(&dpmcp_dev->dev, "dpmcp_reset() failed: %d\n", error);
- return error;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(fsl_mc_portal_reset);
-
-/**
* fsl_mc_object_allocate - Allocates a MC object device of the given
* pool type from a given MC bus
*
@@ -420,7 +285,7 @@ int __must_check fsl_mc_object_allocate(struct fsl_mc_device *mc_dev,
if (WARN_ON(mc_dev->flags & FSL_MC_IS_DPRC))
goto error;
- if (WARN_ON(mc_dev->dev.parent->bus != &fsl_mc_bus_type))
+ if (WARN_ON(!dev_is_fsl_mc(mc_dev->dev.parent)))
goto error;
if (WARN_ON(pool_type == FSL_MC_POOL_DPMCP))
@@ -663,6 +528,55 @@ void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev)
}
EXPORT_SYMBOL_GPL(fsl_mc_free_irqs);
+void fsl_mc_init_all_resource_pools(struct fsl_mc_device *mc_bus_dev)
+{
+ int pool_type;
+ struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
+
+ for (pool_type = 0; pool_type < FSL_MC_NUM_POOL_TYPES; pool_type++) {
+ struct fsl_mc_resource_pool *res_pool =
+ &mc_bus->resource_pools[pool_type];
+
+ res_pool->type = pool_type;
+ res_pool->max_count = 0;
+ res_pool->free_count = 0;
+ res_pool->mc_bus = mc_bus;
+ INIT_LIST_HEAD(&res_pool->free_list);
+ mutex_init(&res_pool->mutex);
+ }
+}
+
+static void fsl_mc_cleanup_resource_pool(struct fsl_mc_device *mc_bus_dev,
+ enum fsl_mc_pool_type pool_type)
+{
+ struct fsl_mc_resource *resource;
+ struct fsl_mc_resource *next;
+ struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
+ struct fsl_mc_resource_pool *res_pool =
+ &mc_bus->resource_pools[pool_type];
+ int free_count = 0;
+
+ WARN_ON(res_pool->type != pool_type);
+ WARN_ON(res_pool->free_count != res_pool->max_count);
+
+ list_for_each_entry_safe(resource, next, &res_pool->free_list, node) {
+ free_count++;
+ WARN_ON(resource->type != res_pool->type);
+ WARN_ON(resource->parent_pool != res_pool);
+ devm_kfree(&mc_bus_dev->dev, resource);
+ }
+
+ WARN_ON(free_count != res_pool->free_count);
+}
+
+void fsl_mc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev)
+{
+ int pool_type;
+
+ for (pool_type = 0; pool_type < FSL_MC_NUM_POOL_TYPES; pool_type++)
+ fsl_mc_cleanup_resource_pool(mc_bus_dev, pool_type);
+}
+
/**
* fsl_mc_allocator_probe - callback invoked when an allocatable device is
* being added to the system
@@ -678,7 +592,7 @@ static int fsl_mc_allocator_probe(struct fsl_mc_device *mc_dev)
return -EINVAL;
mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
- if (WARN_ON(mc_bus_dev->dev.bus != &fsl_mc_bus_type))
+ if (WARN_ON(!dev_is_fsl_mc(&mc_bus_dev->dev)))
return -EINVAL;
mc_bus = to_fsl_mc_bus(mc_bus_dev);
@@ -736,7 +650,6 @@ static const struct fsl_mc_device_id match_id_table[] = {
static struct fsl_mc_driver fsl_mc_allocator_driver = {
.driver = {
.name = "fsl_mc_allocator",
- .owner = THIS_MODULE,
.pm = NULL,
},
.match_id_table = match_id_table,
diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c b/drivers/staging/fsl-mc/bus/fsl-mc-bus.c
index db3afdbdf4ae..44f64b6f0fc9 100644
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/fsl-mc-bus.c
@@ -9,7 +9,6 @@
* warranty of any kind, whether express or implied.
*/
-#include "../include/mc-private.h"
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
@@ -18,13 +17,50 @@
#include <linux/limits.h>
#include <linux/bitops.h>
#include <linux/msi.h>
+#include <linux/dma-mapping.h>
+#include "../include/mc-bus.h"
#include "../include/dpmng.h"
#include "../include/mc-sys.h"
+
+#include "fsl-mc-private.h"
#include "dprc-cmd.h"
static struct kmem_cache *mc_dev_cache;
/**
+ * Default DMA mask for devices on a fsl-mc bus
+ */
+#define FSL_MC_DEFAULT_DMA_MASK (~0ULL)
+
+/**
+ * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device
+ * @root_mc_bus_dev: MC object device representing the root DPRC
+ * @num_translation_ranges: number of entries in addr_translation_ranges
+ * @translation_ranges: array of bus to system address translation ranges
+ */
+struct fsl_mc {
+ struct fsl_mc_device *root_mc_bus_dev;
+ u8 num_translation_ranges;
+ struct fsl_mc_addr_translation_range *translation_ranges;
+};
+
+/**
+ * struct fsl_mc_addr_translation_range - bus to system address translation
+ * range
+ * @mc_region_type: Type of MC region for the range being translated
+ * @start_mc_offset: Start MC offset of the range being translated
+ * @end_mc_offset: MC offset of the first byte after the range (last MC
+ * offset of the range is end_mc_offset - 1)
+ * @start_phys_addr: system physical address corresponding to start_mc_addr
+ */
+struct fsl_mc_addr_translation_range {
+ enum dprc_region_type mc_region_type;
+ u64 start_mc_offset;
+ u64 end_mc_offset;
+ phys_addr_t start_phys_addr;
+};
+
+/**
* fsl_mc_bus_match - device to driver matching callback
* @dev: the MC object device structure to match against
* @drv: the device driver to search for matching MC object device id
@@ -101,14 +137,7 @@ static struct attribute *fsl_mc_dev_attrs[] = {
NULL,
};
-static const struct attribute_group fsl_mc_dev_group = {
- .attrs = fsl_mc_dev_attrs,
-};
-
-static const struct attribute_group *fsl_mc_dev_groups[] = {
- &fsl_mc_dev_group,
- NULL,
-};
+ATTRIBUTE_GROUPS(fsl_mc_dev);
struct bus_type fsl_mc_bus_type = {
.name = "fsl-mc",
@@ -229,21 +258,22 @@ bool fsl_mc_bus_exists(void)
EXPORT_SYMBOL_GPL(fsl_mc_bus_exists);
/**
-* fsl_mc_get_root_dprc - function to traverse to the root dprc
-*/
-static void fsl_mc_get_root_dprc(struct device *dev,
- struct device **root_dprc_dev)
+ * fsl_mc_get_root_dprc - function to traverse to the root dprc
+ */
+void fsl_mc_get_root_dprc(struct device *dev,
+ struct device **root_dprc_dev)
{
if (WARN_ON(!dev)) {
*root_dprc_dev = NULL;
- } else if (WARN_ON(dev->bus != &fsl_mc_bus_type)) {
+ } else if (WARN_ON(!dev_is_fsl_mc(dev))) {
*root_dprc_dev = NULL;
} else {
*root_dprc_dev = dev;
- while ((*root_dprc_dev)->parent->bus == &fsl_mc_bus_type)
+ while (dev_is_fsl_mc((*root_dprc_dev)->parent))
*root_dprc_dev = (*root_dprc_dev)->parent;
}
}
+EXPORT_SYMBOL_GPL(fsl_mc_get_root_dprc);
static int get_dprc_attr(struct fsl_mc_io *mc_io,
int container_id, struct dprc_attributes *attr)
@@ -434,7 +464,7 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
struct fsl_mc_bus *mc_bus = NULL;
struct fsl_mc_device *parent_mc_dev;
- if (parent_dev->bus == &fsl_mc_bus_type)
+ if (dev_is_fsl_mc(parent_dev))
parent_mc_dev = to_fsl_mc_device(parent_dev);
else
parent_mc_dev = NULL;
@@ -887,25 +917,4 @@ error_cleanup_cache:
kmem_cache_destroy(mc_dev_cache);
return error;
}
-
postcore_initcall(fsl_mc_bus_driver_init);
-
-static void __exit fsl_mc_bus_driver_exit(void)
-{
- if (WARN_ON(!mc_dev_cache))
- return;
-
- its_fsl_mc_msi_cleanup();
- fsl_mc_allocator_driver_exit();
- dprc_driver_exit();
- platform_driver_unregister(&fsl_mc_bus_driver);
- bus_unregister(&fsl_mc_bus_type);
- kmem_cache_destroy(mc_dev_cache);
- pr_info("MC bus unregistered\n");
-}
-
-module_exit(fsl_mc_bus_driver_exit);
-
-MODULE_AUTHOR("Freescale Semiconductor Inc.");
-MODULE_DESCRIPTION("Freescale Management Complex (MC) bus driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fsl-mc/bus/mc-msi.c b/drivers/staging/fsl-mc/bus/fsl-mc-msi.c
index 4fd8e41ef468..3d46b1b1fa18 100644
--- a/drivers/staging/fsl-mc/bus/mc-msi.c
+++ b/drivers/staging/fsl-mc/bus/fsl-mc-msi.c
@@ -9,7 +9,6 @@
* warranty of any kind, whether express or implied.
*/
-#include "../include/mc-private.h"
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/irqchip/arm-gic-v3.h>
@@ -17,8 +16,7 @@
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/msi.h>
-#include "../include/mc-sys.h"
-#include "dprc-cmd.h"
+#include "../include/mc-bus.h"
/*
* Generate a unique ID identifying the interrupt (only used within the MSI
@@ -52,7 +50,7 @@ static void fsl_mc_msi_update_dom_ops(struct msi_domain_info *info)
/*
* set_desc should not be set by the caller
*/
- if (ops->set_desc == NULL)
+ if (!ops->set_desc)
ops->set_desc = fsl_mc_msi_set_desc;
}
@@ -142,7 +140,7 @@ static void fsl_mc_msi_update_chip_ops(struct msi_domain_info *info)
/*
* irq_write_msi_msg should not be set by the caller
*/
- if (chip->irq_write_msi_msg == NULL)
+ if (!chip->irq_write_msi_msg)
chip->irq_write_msi_msg = fsl_mc_msi_write_msg;
}
diff --git a/drivers/staging/fsl-mc/bus/fsl-mc-private.h b/drivers/staging/fsl-mc/bus/fsl-mc-private.h
new file mode 100644
index 000000000000..d459c2673f39
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/fsl-mc-private.h
@@ -0,0 +1,52 @@
+/*
+ * Freescale Management Complex (MC) bus private declarations
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#ifndef _FSL_MC_PRIVATE_H_
+#define _FSL_MC_PRIVATE_H_
+
+int __must_check fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
+ struct fsl_mc_io *mc_io,
+ struct device *parent_dev,
+ struct fsl_mc_device **new_mc_dev);
+
+void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);
+
+int __init dprc_driver_init(void);
+
+void dprc_driver_exit(void);
+
+int __init fsl_mc_allocator_driver_init(void);
+
+void fsl_mc_allocator_driver_exit(void);
+
+int __must_check fsl_mc_resource_allocate(struct fsl_mc_bus *mc_bus,
+ enum fsl_mc_pool_type pool_type,
+ struct fsl_mc_resource
+ **new_resource);
+
+void fsl_mc_resource_free(struct fsl_mc_resource *resource);
+
+int fsl_mc_msi_domain_alloc_irqs(struct device *dev,
+ unsigned int irq_count);
+
+void fsl_mc_msi_domain_free_irqs(struct device *dev);
+
+int __init its_fsl_mc_msi_init(void);
+
+void its_fsl_mc_msi_cleanup(void);
+
+int __must_check fsl_create_mc_io(struct device *dev,
+ phys_addr_t mc_portal_phys_addr,
+ u32 mc_portal_size,
+ struct fsl_mc_device *dpmcp_dev,
+ u32 flags, struct fsl_mc_io **new_mc_io);
+
+void fsl_destroy_mc_io(struct fsl_mc_io *mc_io);
+
+#endif /* _FSL_MC_PRIVATE_H_ */
diff --git a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
index 720e2b018d00..7a6ac640752f 100644
--- a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
+++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
@@ -9,7 +9,6 @@
* warranty of any kind, whether express or implied.
*/
-#include "../include/mc-private.h"
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/irqchip/arm-gic-v3.h>
@@ -17,8 +16,7 @@
#include <linux/msi.h>
#include <linux/of.h>
#include <linux/of_irq.h>
-#include "../include/mc-sys.h"
-#include "dprc-cmd.h"
+#include "../include/mc-bus.h"
static struct irq_chip its_msi_irq_chip = {
.name = "fsl-mc-bus-msi",
@@ -35,7 +33,7 @@ static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
struct fsl_mc_device *mc_bus_dev;
struct msi_domain_info *msi_info;
- if (WARN_ON(dev->bus != &fsl_mc_bus_type))
+ if (WARN_ON(!dev_is_fsl_mc(dev)))
return -EINVAL;
mc_bus_dev = to_fsl_mc_device(dev);
diff --git a/drivers/staging/fsl-mc/bus/mc-io.c b/drivers/staging/fsl-mc/bus/mc-io.c
new file mode 100644
index 000000000000..798c965fe203
--- /dev/null
+++ b/drivers/staging/fsl-mc/bus/mc-io.c
@@ -0,0 +1,320 @@
+/* Copyright 2013-2016 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/io.h>
+#include "../include/mc-bus.h"
+#include "../include/mc-sys.h"
+
+#include "fsl-mc-private.h"
+#include "dpmcp.h"
+#include "dpmcp-cmd.h"
+
+static int fsl_mc_io_set_dpmcp(struct fsl_mc_io *mc_io,
+ struct fsl_mc_device *dpmcp_dev)
+{
+ int error;
+
+ if (WARN_ON(!dpmcp_dev))
+ return -EINVAL;
+
+ if (WARN_ON(mc_io->dpmcp_dev))
+ return -EINVAL;
+
+ if (WARN_ON(dpmcp_dev->mc_io))
+ return -EINVAL;
+
+ error = dpmcp_open(mc_io,
+ 0,
+ dpmcp_dev->obj_desc.id,
+ &dpmcp_dev->mc_handle);
+ if (error < 0)
+ return error;
+
+ mc_io->dpmcp_dev = dpmcp_dev;
+ dpmcp_dev->mc_io = mc_io;
+ return 0;
+}
+
+static void fsl_mc_io_unset_dpmcp(struct fsl_mc_io *mc_io)
+{
+ int error;
+ struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
+
+ if (WARN_ON(!dpmcp_dev))
+ return;
+
+ if (WARN_ON(dpmcp_dev->mc_io != mc_io))
+ return;
+
+ error = dpmcp_close(mc_io,
+ 0,
+ dpmcp_dev->mc_handle);
+ if (error < 0) {
+ dev_err(&dpmcp_dev->dev, "dpmcp_close() failed: %d\n",
+ error);
+ }
+
+ mc_io->dpmcp_dev = NULL;
+ dpmcp_dev->mc_io = NULL;
+}
+
+/**
+ * Creates an MC I/O object
+ *
+ * @dev: device to be associated with the MC I/O object
+ * @mc_portal_phys_addr: physical address of the MC portal to use
+ * @mc_portal_size: size in bytes of the MC portal
+ * @dpmcp-dev: Pointer to the DPMCP object associated with this MC I/O
+ * object or NULL if none.
+ * @flags: flags for the new MC I/O object
+ * @new_mc_io: Area to return pointer to newly created MC I/O object
+ *
+ * Returns '0' on Success; Error code otherwise.
+ */
+int __must_check fsl_create_mc_io(struct device *dev,
+ phys_addr_t mc_portal_phys_addr,
+ u32 mc_portal_size,
+ struct fsl_mc_device *dpmcp_dev,
+ u32 flags, struct fsl_mc_io **new_mc_io)
+{
+ int error;
+ struct fsl_mc_io *mc_io;
+ void __iomem *mc_portal_virt_addr;
+ struct resource *res;
+
+ mc_io = devm_kzalloc(dev, sizeof(*mc_io), GFP_KERNEL);
+ if (!mc_io)
+ return -ENOMEM;
+
+ mc_io->dev = dev;
+ mc_io->flags = flags;
+ mc_io->portal_phys_addr = mc_portal_phys_addr;
+ mc_io->portal_size = mc_portal_size;
+ if (flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)
+ spin_lock_init(&mc_io->spinlock);
+ else
+ mutex_init(&mc_io->mutex);
+
+ res = devm_request_mem_region(dev,
+ mc_portal_phys_addr,
+ mc_portal_size,
+ "mc_portal");
+ if (!res) {
+ dev_err(dev,
+ "devm_request_mem_region failed for MC portal %#llx\n",
+ mc_portal_phys_addr);
+ return -EBUSY;
+ }
+
+ mc_portal_virt_addr = devm_ioremap_nocache(dev,
+ mc_portal_phys_addr,
+ mc_portal_size);
+ if (!mc_portal_virt_addr) {
+ dev_err(dev,
+ "devm_ioremap_nocache failed for MC portal %#llx\n",
+ mc_portal_phys_addr);
+ return -ENXIO;
+ }
+
+ mc_io->portal_virt_addr = mc_portal_virt_addr;
+ if (dpmcp_dev) {
+ error = fsl_mc_io_set_dpmcp(mc_io, dpmcp_dev);
+ if (error < 0)
+ goto error_destroy_mc_io;
+ }
+
+ *new_mc_io = mc_io;
+ return 0;
+
+error_destroy_mc_io:
+ fsl_destroy_mc_io(mc_io);
+ return error;
+}
+
+/**
+ * Destroys an MC I/O object
+ *
+ * @mc_io: MC I/O object to destroy
+ */
+void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
+{
+ struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
+
+ if (dpmcp_dev)
+ fsl_mc_io_unset_dpmcp(mc_io);
+
+ devm_iounmap(mc_io->dev, mc_io->portal_virt_addr);
+ devm_release_mem_region(mc_io->dev,
+ mc_io->portal_phys_addr,
+ mc_io->portal_size);
+
+ mc_io->portal_virt_addr = NULL;
+ devm_kfree(mc_io->dev, mc_io);
+}
+
+/**
+ * fsl_mc_portal_allocate - Allocates an MC portal
+ *
+ * @mc_dev: MC device for which the MC portal is to be allocated
+ * @mc_io_flags: Flags for the fsl_mc_io object that wraps the allocated
+ * MC portal.
+ * @new_mc_io: Pointer to area where the pointer to the fsl_mc_io object
+ * that wraps the allocated MC portal is to be returned
+ *
+ * This function allocates an MC portal from the device's parent DPRC,
+ * from the corresponding MC bus' pool of MC portals and wraps
+ * it in a new fsl_mc_io object. If 'mc_dev' is a DPRC itself, the
+ * portal is allocated from its own MC bus.
+ */
+int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev,
+ u16 mc_io_flags,
+ struct fsl_mc_io **new_mc_io)
+{
+ struct fsl_mc_device *mc_bus_dev;
+ struct fsl_mc_bus *mc_bus;
+ phys_addr_t mc_portal_phys_addr;
+ size_t mc_portal_size;
+ struct fsl_mc_device *dpmcp_dev;
+ int error = -EINVAL;
+ struct fsl_mc_resource *resource = NULL;
+ struct fsl_mc_io *mc_io = NULL;
+
+ if (mc_dev->flags & FSL_MC_IS_DPRC) {
+ mc_bus_dev = mc_dev;
+ } else {
+ if (WARN_ON(!dev_is_fsl_mc(mc_dev->dev.parent)))
+ return error;
+
+ mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
+ }
+
+ mc_bus = to_fsl_mc_bus(mc_bus_dev);
+ *new_mc_io = NULL;
+ error = fsl_mc_resource_allocate(mc_bus, FSL_MC_POOL_DPMCP, &resource);
+ if (error < 0)
+ return error;
+
+ error = -EINVAL;
+ dpmcp_dev = resource->data;
+ if (WARN_ON(!dpmcp_dev))
+ goto error_cleanup_resource;
+
+ if (dpmcp_dev->obj_desc.ver_major < DPMCP_MIN_VER_MAJOR ||
+ (dpmcp_dev->obj_desc.ver_major == DPMCP_MIN_VER_MAJOR &&
+ dpmcp_dev->obj_desc.ver_minor < DPMCP_MIN_VER_MINOR)) {
+ dev_err(&dpmcp_dev->dev,
+ "ERROR: Version %d.%d of DPMCP not supported.\n",
+ dpmcp_dev->obj_desc.ver_major,
+ dpmcp_dev->obj_desc.ver_minor);
+ error = -ENOTSUPP;
+ goto error_cleanup_resource;
+ }
+
+ if (WARN_ON(dpmcp_dev->obj_desc.region_count == 0))
+ goto error_cleanup_resource;
+
+ mc_portal_phys_addr = dpmcp_dev->regions[0].start;
+ mc_portal_size = dpmcp_dev->regions[0].end -
+ dpmcp_dev->regions[0].start + 1;
+
+ if (WARN_ON(mc_portal_size != mc_bus_dev->mc_io->portal_size))
+ goto error_cleanup_resource;
+
+ error = fsl_create_mc_io(&mc_bus_dev->dev,
+ mc_portal_phys_addr,
+ mc_portal_size, dpmcp_dev,
+ mc_io_flags, &mc_io);
+ if (error < 0)
+ goto error_cleanup_resource;
+
+ *new_mc_io = mc_io;
+ return 0;
+
+error_cleanup_resource:
+ fsl_mc_resource_free(resource);
+ return error;
+}
+EXPORT_SYMBOL_GPL(fsl_mc_portal_allocate);
+
+/**
+ * fsl_mc_portal_free - Returns an MC portal to the pool of free MC portals
+ * of a given MC bus
+ *
+ * @mc_io: Pointer to the fsl_mc_io object that wraps the MC portal to free
+ */
+void fsl_mc_portal_free(struct fsl_mc_io *mc_io)
+{
+ struct fsl_mc_device *dpmcp_dev;
+ struct fsl_mc_resource *resource;
+
+ /*
+ * Every mc_io obtained by calling fsl_mc_portal_allocate() is supposed
+ * to have a DPMCP object associated with.
+ */
+ dpmcp_dev = mc_io->dpmcp_dev;
+ if (WARN_ON(!dpmcp_dev))
+ return;
+
+ resource = dpmcp_dev->resource;
+ if (WARN_ON(!resource || resource->type != FSL_MC_POOL_DPMCP))
+ return;
+
+ if (WARN_ON(resource->data != dpmcp_dev))
+ return;
+
+ fsl_destroy_mc_io(mc_io);
+ fsl_mc_resource_free(resource);
+}
+EXPORT_SYMBOL_GPL(fsl_mc_portal_free);
+
+/**
+ * fsl_mc_portal_reset - Resets the dpmcp object for a given fsl_mc_io object
+ *
+ * @mc_io: Pointer to the fsl_mc_io object that wraps the MC portal to free
+ */
+int fsl_mc_portal_reset(struct fsl_mc_io *mc_io)
+{
+ int error;
+ struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
+
+ if (WARN_ON(!dpmcp_dev))
+ return -EINVAL;
+
+ error = dpmcp_reset(mc_io, 0, dpmcp_dev->mc_handle);
+ if (error < 0) {
+ dev_err(&dpmcp_dev->dev, "dpmcp_reset() failed: %d\n", error);
+ return error;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fsl_mc_portal_reset);
diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c b/drivers/staging/fsl-mc/bus/mc-sys.c
index 0c185abe665e..285917c7c8e4 100644
--- a/drivers/staging/fsl-mc/bus/mc-sys.c
+++ b/drivers/staging/fsl-mc/bus/mc-sys.c
@@ -32,13 +32,15 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include "../include/mc-sys.h"
-#include "../include/mc-cmd.h"
-#include "../include/mc.h"
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/device.h>
+#include <linux/io.h>
+#include "../include/mc-sys.h"
+#include "../include/mc-cmd.h"
+#include "../include/mc.h"
+
#include "dpmcp.h"
/**
@@ -68,153 +70,6 @@ static u16 mc_cmd_hdr_read_cmdid(struct mc_command *cmd)
return (cmd_id & MC_CMD_HDR_CMDID_MASK) >> MC_CMD_HDR_CMDID_SHIFT;
}
-/**
- * Creates an MC I/O object
- *
- * @dev: device to be associated with the MC I/O object
- * @mc_portal_phys_addr: physical address of the MC portal to use
- * @mc_portal_size: size in bytes of the MC portal
- * @dpmcp-dev: Pointer to the DPMCP object associated with this MC I/O
- * object or NULL if none.
- * @flags: flags for the new MC I/O object
- * @new_mc_io: Area to return pointer to newly created MC I/O object
- *
- * Returns '0' on Success; Error code otherwise.
- */
-int __must_check fsl_create_mc_io(struct device *dev,
- phys_addr_t mc_portal_phys_addr,
- u32 mc_portal_size,
- struct fsl_mc_device *dpmcp_dev,
- u32 flags, struct fsl_mc_io **new_mc_io)
-{
- int error;
- struct fsl_mc_io *mc_io;
- void __iomem *mc_portal_virt_addr;
- struct resource *res;
-
- mc_io = devm_kzalloc(dev, sizeof(*mc_io), GFP_KERNEL);
- if (!mc_io)
- return -ENOMEM;
-
- mc_io->dev = dev;
- mc_io->flags = flags;
- mc_io->portal_phys_addr = mc_portal_phys_addr;
- mc_io->portal_size = mc_portal_size;
- if (flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)
- spin_lock_init(&mc_io->spinlock);
- else
- mutex_init(&mc_io->mutex);
-
- res = devm_request_mem_region(dev,
- mc_portal_phys_addr,
- mc_portal_size,
- "mc_portal");
- if (!res) {
- dev_err(dev,
- "devm_request_mem_region failed for MC portal %#llx\n",
- mc_portal_phys_addr);
- return -EBUSY;
- }
-
- mc_portal_virt_addr = devm_ioremap_nocache(dev,
- mc_portal_phys_addr,
- mc_portal_size);
- if (!mc_portal_virt_addr) {
- dev_err(dev,
- "devm_ioremap_nocache failed for MC portal %#llx\n",
- mc_portal_phys_addr);
- return -ENXIO;
- }
-
- mc_io->portal_virt_addr = mc_portal_virt_addr;
- if (dpmcp_dev) {
- error = fsl_mc_io_set_dpmcp(mc_io, dpmcp_dev);
- if (error < 0)
- goto error_destroy_mc_io;
- }
-
- *new_mc_io = mc_io;
- return 0;
-
-error_destroy_mc_io:
- fsl_destroy_mc_io(mc_io);
- return error;
-}
-EXPORT_SYMBOL_GPL(fsl_create_mc_io);
-
-/**
- * Destroys an MC I/O object
- *
- * @mc_io: MC I/O object to destroy
- */
-void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
-{
- struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
-
- if (dpmcp_dev)
- fsl_mc_io_unset_dpmcp(mc_io);
-
- devm_iounmap(mc_io->dev, mc_io->portal_virt_addr);
- devm_release_mem_region(mc_io->dev,
- mc_io->portal_phys_addr,
- mc_io->portal_size);
-
- mc_io->portal_virt_addr = NULL;
- devm_kfree(mc_io->dev, mc_io);
-}
-EXPORT_SYMBOL_GPL(fsl_destroy_mc_io);
-
-int fsl_mc_io_set_dpmcp(struct fsl_mc_io *mc_io,
- struct fsl_mc_device *dpmcp_dev)
-{
- int error;
-
- if (WARN_ON(!dpmcp_dev))
- return -EINVAL;
-
- if (WARN_ON(mc_io->dpmcp_dev))
- return -EINVAL;
-
- if (WARN_ON(dpmcp_dev->mc_io))
- return -EINVAL;
-
- error = dpmcp_open(mc_io,
- 0,
- dpmcp_dev->obj_desc.id,
- &dpmcp_dev->mc_handle);
- if (error < 0)
- return error;
-
- mc_io->dpmcp_dev = dpmcp_dev;
- dpmcp_dev->mc_io = mc_io;
- return 0;
-}
-EXPORT_SYMBOL_GPL(fsl_mc_io_set_dpmcp);
-
-void fsl_mc_io_unset_dpmcp(struct fsl_mc_io *mc_io)
-{
- int error;
- struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
-
- if (WARN_ON(!dpmcp_dev))
- return;
-
- if (WARN_ON(dpmcp_dev->mc_io != mc_io))
- return;
-
- error = dpmcp_close(mc_io,
- 0,
- dpmcp_dev->mc_handle);
- if (error < 0) {
- dev_err(&dpmcp_dev->dev, "dpmcp_close() failed: %d\n",
- error);
- }
-
- mc_io->dpmcp_dev = NULL;
- dpmcp_dev->mc_io = NULL;
-}
-EXPORT_SYMBOL_GPL(fsl_mc_io_unset_dpmcp);
-
static int mc_status_to_error(enum mc_cmd_status status)
{
static const int mc_status_to_error_map[] = {
diff --git a/drivers/staging/fsl-mc/include/dpbp-cmd.h b/drivers/staging/fsl-mc/include/dpbp-cmd.h
index 4828ccd0cffd..2860411ddb51 100644
--- a/drivers/staging/fsl-mc/include/dpbp-cmd.h
+++ b/drivers/staging/fsl-mc/include/dpbp-cmd.h
@@ -1,34 +1,34 @@
/* Copyright 2013-2016 Freescale Semiconductor Inc.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-* * Neither the name of the above-listed copyright holders nor the
-* names of any contributors may be used to endorse or promote products
-* derived from this software without specific prior written permission.
-*
-*
-* ALTERNATIVELY, this software may be distributed under the terms of the
-* GNU General Public License ("GPL") as published by the Free Software
-* Foundation, either version 2 of that License or (at your option) any
-* later version.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-* POSSIBILITY OF SUCH DAMAGE.
-*/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
#ifndef _FSL_DPBP_CMD_H
#define _FSL_DPBP_CMD_H
diff --git a/drivers/staging/fsl-mc/include/mc-private.h b/drivers/staging/fsl-mc/include/mc-bus.h
index cab1ae90f09e..170684a57ca2 100644
--- a/drivers/staging/fsl-mc/include/mc-private.h
+++ b/drivers/staging/fsl-mc/include/mc-bus.h
@@ -1,5 +1,5 @@
/*
- * Freescale Management Complex (MC) bus private declarations
+ * Freescale Management Complex (MC) bus declarations
*
* Copyright (C) 2014 Freescale Semiconductor, Inc.
* Author: German Rivera <German.Rivera@freescale.com>
@@ -8,23 +8,11 @@
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-#ifndef _FSL_MC_PRIVATE_H_
-#define _FSL_MC_PRIVATE_H_
+#ifndef _FSL_MC_MCBUS_H_
+#define _FSL_MC_MCBUS_H_
#include "../include/mc.h"
#include <linux/mutex.h>
-#include <linux/stringify.h>
-
-#define FSL_MC_DPRC_DRIVER_NAME "fsl_mc_dprc"
-
-#define FSL_MC_DEVICE_MATCH(_mc_dev, _obj_desc) \
- (strcmp((_mc_dev)->obj_desc.type, (_obj_desc)->type) == 0 && \
- (_mc_dev)->obj_desc.id == (_obj_desc)->id)
-
-#define FSL_MC_IS_ALLOCATABLE(_obj_type) \
- (strcmp(_obj_type, "dpbp") == 0 || \
- strcmp(_obj_type, "dpmcp") == 0 || \
- strcmp(_obj_type, "dpcon") == 0)
struct irq_domain;
struct msi_domain_info;
@@ -35,37 +23,12 @@ struct msi_domain_info;
*/
#define FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS 256
-struct device_node;
-struct irq_domain;
-struct msi_domain_info;
-
-/**
- * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device
- * @root_mc_bus_dev: MC object device representing the root DPRC
- * @num_translation_ranges: number of entries in addr_translation_ranges
- * @translation_ranges: array of bus to system address translation ranges
- */
-struct fsl_mc {
- struct fsl_mc_device *root_mc_bus_dev;
- u8 num_translation_ranges;
- struct fsl_mc_addr_translation_range *translation_ranges;
-};
-
-/**
- * struct fsl_mc_addr_translation_range - bus to system address translation
- * range
- * @mc_region_type: Type of MC region for the range being translated
- * @start_mc_offset: Start MC offset of the range being translated
- * @end_mc_offset: MC offset of the first byte after the range (last MC
- * offset of the range is end_mc_offset - 1)
- * @start_phys_addr: system physical address corresponding to start_mc_addr
- */
-struct fsl_mc_addr_translation_range {
- enum dprc_region_type mc_region_type;
- u64 start_mc_offset;
- u64 end_mc_offset;
- phys_addr_t start_phys_addr;
-};
+#ifdef CONFIG_FSL_MC_BUS
+#define dev_is_fsl_mc(_dev) ((_dev)->bus == &fsl_mc_bus_type)
+#else
+/* If fsl-mc bus is not present device cannot belong to fsl-mc bus */
+#define dev_is_fsl_mc(_dev) (0)
+#endif
/**
* struct fsl_mc_resource_pool - Pool of MC resources of a given
@@ -107,13 +70,6 @@ struct fsl_mc_bus {
#define to_fsl_mc_bus(_mc_dev) \
container_of(_mc_dev, struct fsl_mc_bus, mc_dev)
-int __must_check fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
- struct fsl_mc_io *mc_io,
- struct device *parent_dev,
- struct fsl_mc_device **new_mc_dev);
-
-void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);
-
int dprc_scan_container(struct fsl_mc_device *mc_bus_dev);
int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
@@ -127,13 +83,6 @@ int __init fsl_mc_allocator_driver_init(void);
void fsl_mc_allocator_driver_exit(void);
-int __must_check fsl_mc_resource_allocate(struct fsl_mc_bus *mc_bus,
- enum fsl_mc_pool_type pool_type,
- struct fsl_mc_resource
- **new_resource);
-
-void fsl_mc_resource_free(struct fsl_mc_resource *resource);
-
struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode,
struct msi_domain_info *info,
struct irq_domain *parent);
@@ -141,18 +90,22 @@ struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode,
int fsl_mc_find_msi_domain(struct device *mc_platform_dev,
struct irq_domain **mc_msi_domain);
-int fsl_mc_msi_domain_alloc_irqs(struct device *dev,
- unsigned int irq_count);
+int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
+ unsigned int irq_count);
+
+void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus);
-void fsl_mc_msi_domain_free_irqs(struct device *dev);
+void fsl_mc_init_all_resource_pools(struct fsl_mc_device *mc_bus_dev);
-int __init its_fsl_mc_msi_init(void);
+void fsl_mc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev);
-void its_fsl_mc_msi_cleanup(void);
+bool fsl_mc_bus_exists(void);
-int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
- unsigned int irq_count);
+void fsl_mc_get_root_dprc(struct device *dev,
+ struct device **root_dprc_dev);
-void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus);
+bool fsl_mc_is_root_dprc(struct device *dev);
+
+extern struct bus_type fsl_mc_bus_type;
-#endif /* _FSL_MC_PRIVATE_H_ */
+#endif /* _FSL_MC_MCBUS_H_ */
diff --git a/drivers/staging/fsl-mc/include/mc-sys.h b/drivers/staging/fsl-mc/include/mc-sys.h
index c5038cc77240..89ad0cf54702 100644
--- a/drivers/staging/fsl-mc/include/mc-sys.h
+++ b/drivers/staging/fsl-mc/include/mc-sys.h
@@ -37,8 +37,6 @@
#include <linux/types.h>
#include <linux/errno.h>
-#include <linux/io.h>
-#include <linux/dma-mapping.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
@@ -95,19 +93,6 @@ struct fsl_mc_io {
};
};
-int __must_check fsl_create_mc_io(struct device *dev,
- phys_addr_t mc_portal_phys_addr,
- u32 mc_portal_size,
- struct fsl_mc_device *dpmcp_dev,
- u32 flags, struct fsl_mc_io **new_mc_io);
-
-void fsl_destroy_mc_io(struct fsl_mc_io *mc_io);
-
-int fsl_mc_io_set_dpmcp(struct fsl_mc_io *mc_io,
- struct fsl_mc_device *dpmcp_dev);
-
-void fsl_mc_io_unset_dpmcp(struct fsl_mc_io *mc_io);
-
int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd);
#endif /* _FSL_MC_SYS_H */
diff --git a/drivers/staging/fsl-mc/include/mc.h b/drivers/staging/fsl-mc/include/mc.h
index 853cbf38a400..f6e720e84460 100644
--- a/drivers/staging/fsl-mc/include/mc.h
+++ b/drivers/staging/fsl-mc/include/mc.h
@@ -13,7 +13,6 @@
#include <linux/device.h>
#include <linux/mod_devicetable.h>
-#include <linux/list.h>
#include <linux/interrupt.h>
#include "../include/dprc.h"
@@ -21,7 +20,6 @@
struct fsl_mc_device;
struct fsl_mc_io;
-struct fsl_mc_bus;
/**
* struct fsl_mc_driver - MC object device driver object
@@ -112,11 +110,6 @@ struct fsl_mc_device_irq {
#define FSL_MC_IS_DPRC 0x0001
/**
- * Default DMA mask for devices on a fsl-mc bus
- */
-#define FSL_MC_DEFAULT_DMA_MASK (~0ULL)
-
-/**
* struct fsl_mc_device - MC object device object
* @dev: Linux driver model device object
* @dma_mask: Default DMA mask
@@ -187,8 +180,6 @@ int __must_check __fsl_mc_driver_register(struct fsl_mc_driver *fsl_mc_driver,
void fsl_mc_driver_unregister(struct fsl_mc_driver *driver);
-bool fsl_mc_bus_exists(void);
-
int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev,
u16 mc_io_flags,
struct fsl_mc_io **new_mc_io);
@@ -207,8 +198,4 @@ int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev);
void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev);
-bool fsl_mc_is_root_dprc(struct device *dev);
-
-extern struct bus_type fsl_mc_bus_type;
-
#endif /* _FSL_MC_H_ */
diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c
index c241c0ae3f20..49c718b91e55 100644
--- a/drivers/staging/fwserial/fwserial.c
+++ b/drivers/staging/fwserial/fwserial.c
@@ -39,9 +39,9 @@ static int num_ttys = 4; /* # of std ttys to create per fw_card */
static bool auto_connect = true; /* try to VIRT_CABLE to every peer */
static bool create_loop_dev = true; /* create a loopback device for each card */
-module_param_named(ttys, num_ttys, int, S_IRUGO | S_IWUSR);
-module_param_named(auto, auto_connect, bool, S_IRUGO | S_IWUSR);
-module_param_named(loop, create_loop_dev, bool, S_IRUGO | S_IWUSR);
+module_param_named(ttys, num_ttys, int, 0644);
+module_param_named(auto, auto_connect, bool, 0644);
+module_param_named(loop, create_loop_dev, bool, 0644);
/*
* Threshold below which the tty is woken for writing
diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c
index bb552193e4ba..e72dfa9699f3 100644
--- a/drivers/staging/gdm724x/gdm_lte.c
+++ b/drivers/staging/gdm724x/gdm_lte.c
@@ -828,7 +828,7 @@ void start_rx_proc(struct phy_dev *phy_dev)
rx_complete, phy_dev, USB_COMPLETE);
}
-static struct net_device_ops gdm_netdev_ops = {
+static const struct net_device_ops gdm_netdev_ops = {
.ndo_open = gdm_lte_open,
.ndo_stop = gdm_lte_close,
.ndo_set_config = gdm_lte_set_config,
diff --git a/drivers/staging/gdm724x/gdm_mux.h b/drivers/staging/gdm724x/gdm_mux.h
index 3d50383c6ced..0871b8feec55 100644
--- a/drivers/staging/gdm724x/gdm_mux.h
+++ b/drivers/staging/gdm724x/gdm_mux.h
@@ -27,8 +27,8 @@
#define START_FLAG 0xA512485A
#define MUX_HEADER_SIZE 14
-#define MUX_TX_MAX_SIZE (1024*10)
-#define MUX_RX_MAX_SIZE (1024*30)
+#define MUX_TX_MAX_SIZE (1024 * 10)
+#define MUX_RX_MAX_SIZE (1024 * 30)
#define AT_PKT_TYPE 0xF011
#define DM_PKT_TYPE 0xF010
diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c
index eb7e2523c354..ae396638f897 100644
--- a/drivers/staging/gdm724x/gdm_tty.c
+++ b/drivers/staging/gdm724x/gdm_tty.c
@@ -225,7 +225,6 @@ int register_lte_tty_device(struct tty_dev *tty_dev, struct device *device)
int j;
for (i = 0; i < TTY_MAX_COUNT; i++) {
-
gdm = kmalloc(sizeof(*gdm), GFP_KERNEL);
if (!gdm)
return -ENOMEM;
diff --git a/drivers/staging/gdm724x/gdm_usb.c b/drivers/staging/gdm724x/gdm_usb.c
index d650d772095b..15a7e81ec2d2 100644
--- a/drivers/staging/gdm724x/gdm_usb.c
+++ b/drivers/staging/gdm724x/gdm_usb.c
@@ -415,10 +415,10 @@ static void do_rx(struct work_struct *work)
switch (cmd_evt) {
case LTE_GET_INFORMATION_RESULT:
if (set_mac_address(hci->data, r->cb_data) == 0) {
- ret = r->callback(r->cb_data,
- r->buf,
- r->urb->actual_length,
- KERNEL_THREAD);
+ r->callback(r->cb_data,
+ r->buf,
+ r->urb->actual_length,
+ KERNEL_THREAD);
}
break;
diff --git a/drivers/staging/gdm724x/gdm_usb.h b/drivers/staging/gdm724x/gdm_usb.h
index e6486e71a428..ffb3d995097d 100644
--- a/drivers/staging/gdm724x/gdm_usb.h
+++ b/drivers/staging/gdm724x/gdm_usb.h
@@ -26,10 +26,10 @@
#define PM_SUSPEND 1
#define AUTO_SUSPEND_TIMER 5000 /* ms */
-#define RX_BUF_SIZE (1024*32)
-#define TX_BUF_SIZE (1024*32)
+#define RX_BUF_SIZE (1024 * 32)
+#define TX_BUF_SIZE (1024 * 32)
#define SDU_BUF_SIZE 2048
-#define MAX_SDU_SIZE (1024*30)
+#define MAX_SDU_SIZE (1024 * 30)
#define MAX_PACKET_IN_MULTI_SDU 256
#define VID_GCT 0x1076
diff --git a/drivers/staging/gdm724x/hci_packet.h b/drivers/staging/gdm724x/hci_packet.h
index dbc4446cf78d..4644f84038c9 100644
--- a/drivers/staging/gdm724x/hci_packet.h
+++ b/drivers/staging/gdm724x/hci_packet.h
@@ -89,5 +89,4 @@ struct hci_connect_ind {
u32 connect;
} __packed;
-
#endif /* _HCI_PACKET_H_ */
diff --git a/drivers/staging/gdm724x/netlink_k.c b/drivers/staging/gdm724x/netlink_k.c
index a0232e8aec10..abe242505882 100644
--- a/drivers/staging/gdm724x/netlink_k.c
+++ b/drivers/staging/gdm724x/netlink_k.c
@@ -14,6 +14,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/export.h>
+#include <linux/mutex.h>
#include <linux/etherdevice.h>
#include <linux/netlink.h>
#include <asm/byteorder.h>
@@ -21,13 +22,7 @@
#include "netlink_k.h"
-#if defined(DEFINE_MUTEX)
static DEFINE_MUTEX(netlink_mutex);
-#else
-static struct semaphore netlink_mutex;
-#define mutex_lock(x) down(x)
-#define mutex_unlock(x) up(x)
-#endif
#define ND_MAX_GROUP 30
#define ND_IFINDEX_LEN sizeof(int)
@@ -96,10 +91,6 @@ struct sock *netlink_init(int unit,
.input = netlink_rcv,
};
-#if !defined(DEFINE_MUTEX)
- init_MUTEX(&netlink_mutex);
-#endif
-
sock = netlink_kernel_create(&init_net, unit, &cfg);
if (sock)
diff --git a/drivers/staging/greybus/Documentation/firmware/authenticate.c b/drivers/staging/greybus/Documentation/firmware/authenticate.c
new file mode 100644
index 000000000000..ab0688ad1e37
--- /dev/null
+++ b/drivers/staging/greybus/Documentation/firmware/authenticate.c
@@ -0,0 +1,139 @@
+/*
+ * Sample code to test CAP protocol
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2016 Google Inc. All rights reserved.
+ * Copyright(c) 2016 Linaro Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License 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 version 2 for more details.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Google Inc. All rights reserved.
+ * Copyright(c) 2016 Linaro Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. or Linaro Ltd. nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
+ * LINARO LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "../../greybus_authentication.h"
+
+struct cap_ioc_get_endpoint_uid uid;
+struct cap_ioc_get_ims_certificate cert = {
+ .certificate_class = 0,
+ .certificate_id = 0,
+};
+
+struct cap_ioc_authenticate authenticate = {
+ .auth_type = 0,
+ .challenge = {0},
+};
+
+int main(int argc, char *argv[])
+{
+ unsigned int timeout = 10000;
+ char *capdev;
+ int fd, ret;
+
+ /* Make sure arguments are correct */
+ if (argc != 2) {
+ printf("\nUsage: ./firmware <Path of the gb-cap-X dev>\n");
+ return 0;
+ }
+
+ capdev = argv[1];
+
+ printf("Opening %s authentication device\n", capdev);
+
+ fd = open(capdev, O_RDWR);
+ if (fd < 0) {
+ printf("Failed to open: %s\n", capdev);
+ return -1;
+ }
+
+ /* Get UID */
+ printf("Get UID\n");
+
+ ret = ioctl(fd, CAP_IOC_GET_ENDPOINT_UID, &uid);
+ if (ret < 0) {
+ printf("Failed to get UID: %s (%d)\n", capdev, ret);
+ ret = -1;
+ goto close_fd;
+ }
+
+ printf("UID received: 0x%llx\n", *(long long unsigned int *)(uid.uid));
+
+ /* Get certificate */
+ printf("Get IMS certificate\n");
+
+ ret = ioctl(fd, CAP_IOC_GET_IMS_CERTIFICATE, &cert);
+ if (ret < 0) {
+ printf("Failed to get IMS certificate: %s (%d)\n", capdev, ret);
+ ret = -1;
+ goto close_fd;
+ }
+
+ printf("IMS Certificate size: %d\n", cert.cert_size);
+
+ /* Authenticate */
+ printf("Authenticate module\n");
+
+ memcpy(authenticate.uid, uid.uid, 8);
+
+ ret = ioctl(fd, CAP_IOC_AUTHENTICATE, &authenticate);
+ if (ret < 0) {
+ printf("Failed to authenticate module: %s (%d)\n", capdev, ret);
+ ret = -1;
+ goto close_fd;
+ }
+
+ printf("Authenticated, result (%02x), sig-size (%02x)\n",
+ authenticate.result_code, authenticate.signature_size);
+
+close_fd:
+ close(fd);
+
+ return ret;
+}
diff --git a/drivers/staging/greybus/Documentation/firmware/firmware-management b/drivers/staging/greybus/Documentation/firmware/firmware-management
new file mode 100644
index 000000000000..7918257e5b3b
--- /dev/null
+++ b/drivers/staging/greybus/Documentation/firmware/firmware-management
@@ -0,0 +1,333 @@
+
+Firmware Management
+-------------------
+ Copyright 2016 Google Inc.
+ Copyright 2016 Linaro Ltd.
+
+Interface-Manifest
+------------------
+
+All firmware packages on the Modules or Interfaces are managed by a special
+Firmware Management Protocol. To support Firmware Management by the AP, the
+Interface Manifest shall at least contain the Firmware Management Bundle and a
+Firmware Management Protocol CPort within it.
+
+The bundle may contain additional CPorts based on the extra functionality
+required to manage firmware packages.
+
+For example, this is how the Firmware Management part of the Interface Manifest
+may look like:
+
+ ; Firmware Management Bundle (Bundle 1):
+ [bundle-descriptor 1]
+ class = 0x16
+
+ ; (Mandatory) Firmware Management Protocol on CPort 1
+ [cport-descriptor 2]
+ bundle = 1
+ protocol = 0x18
+
+ ; (Optional) Firmware Download Protocol on CPort 2
+ [cport-descriptor 1]
+ bundle = 1
+ protocol = 0x17
+
+ ; (Optional) SPI protocol on CPort 3
+ [cport-descriptor 3]
+ bundle = 1
+ protocol = 0x0b
+
+ ; (Optional) Component Authentication Protocol (CAP) on CPort 4
+ [cport-descriptor 4]
+ bundle = 1
+ protocol = 0x19
+
+
+Sysfs Interfaces - Firmware Management
+--------------------------------------
+
+The Firmware Management Protocol interacts with Userspace using the character
+device interface. The character device will be present in /dev/ directory
+and will be named gb-fw-mgmt-<N>. The number <N> is assigned at runtime.
+
+Identifying the Character Device
+================================
+
+There can be multiple devices present in /dev/ directory with name gb-fw-mgmt-N
+and user first needs to identify the character device used for
+firmware-management for a particular interface.
+
+The Firmware Management core creates a device of class 'gb_fw_mgmt', which shall
+be used by the user to identify the right character device for it. The class
+device is created within the Bundle directory for a particular Interface.
+
+For example this is how the class-device can be present:
+
+/sys/bus/greybus/devices/1-1/1-1.1/1-1.1.1/gb_fw_mgmt/gb-fw-mgmt-0
+
+The last name in this path: gb-fw-mgmt-0 is precisely the name of the char
+device and so the device in this case will be:
+
+/dev/gb-fw-mgmt-0.
+
+Operations on the Char device
+=============================
+
+The Character device (gb-fw-mgmt-0 in example) can be opened by the userspace
+application and it can perform various 'ioctl' operations on the device. The
+device doesn't support any read/write operations.
+
+Following are the IOCTLs and their data structures available to the user:
+
+/* IOCTL support */
+#define GB_FW_LOAD_METHOD_UNIPRO 0x01
+#define GB_FW_LOAD_METHOD_INTERNAL 0x02
+
+#define GB_FW_LOAD_STATUS_FAILED 0x00
+#define GB_FW_LOAD_STATUS_UNVALIDATED 0x01
+#define GB_FW_LOAD_STATUS_VALIDATED 0x02
+#define GB_FW_LOAD_STATUS_VALIDATION_FAILED 0x03
+
+#define GB_FW_BACKEND_FW_STATUS_SUCCESS 0x01
+#define GB_FW_BACKEND_FW_STATUS_FAIL_FIND 0x02
+#define GB_FW_BACKEND_FW_STATUS_FAIL_FETCH 0x03
+#define GB_FW_BACKEND_FW_STATUS_FAIL_WRITE 0x04
+#define GB_FW_BACKEND_FW_STATUS_INT 0x05
+#define GB_FW_BACKEND_FW_STATUS_RETRY 0x06
+#define GB_FW_BACKEND_FW_STATUS_NOT_SUPPORTED 0x07
+
+#define GB_FW_BACKEND_VERSION_STATUS_SUCCESS 0x01
+#define GB_FW_BACKEND_VERSION_STATUS_NOT_AVAILABLE 0x02
+#define GB_FW_BACKEND_VERSION_STATUS_NOT_SUPPORTED 0x03
+#define GB_FW_BACKEND_VERSION_STATUS_RETRY 0x04
+#define GB_FW_BACKEND_VERSION_STATUS_FAIL_INT 0x05
+
+
+struct fw_mgmt_ioc_get_intf_version {
+ __u8 firmware_tag[GB_FIRMWARE_U_TAG_MAX_SIZE];
+ __u16 major;
+ __u16 minor;
+} __attribute__ ((__packed__));
+
+struct fw_mgmt_ioc_get_backend_version {
+ __u8 firmware_tag[GB_FIRMWARE_U_TAG_MAX_SIZE];
+ __u16 major;
+ __u16 minor;
+ __u8 status;
+} __attribute__ ((__packed__));
+
+struct fw_mgmt_ioc_intf_load_and_validate {
+ __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE];
+ __u8 load_method;
+ __u8 status;
+ __u16 major;
+ __u16 minor;
+} __packed;
+
+struct fw_mgmt_ioc_backend_fw_update {
+ __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE];
+ __u8 status;
+} __packed;
+
+#define FW_MGMT_IOCTL_BASE 'S'
+#define FW_MGMT_IOC_GET_INTF_FW _IOR(FW_MGMT_IOCTL_BASE, 0, struct fw_mgmt_ioc_get_intf_version)
+#define FW_MGMT_IOC_GET_BACKEND_FW _IOWR(FW_MGMT_IOCTL_BASE, 1, struct fw_mgmt_ioc_get_backend_version)
+#define FW_MGMT_IOC_INTF_LOAD_AND_VALIDATE _IOWR(FW_MGMT_IOCTL_BASE, 2, struct fw_mgmt_ioc_intf_load_and_validate)
+#define FW_MGMT_IOC_INTF_BACKEND_FW_UPDATE _IOWR(FW_MGMT_IOCTL_BASE, 3, struct fw_mgmt_ioc_backend_fw_update)
+#define FW_MGMT_IOC_SET_TIMEOUT_MS _IOW(FW_MGMT_IOCTL_BASE, 4, unsigned int)
+#define FW_MGMT_IOC_MODE_SWITCH _IO(FW_MGMT_IOCTL_BASE, 5)
+
+1. FW_MGMT_IOC_GET_INTF_FW:
+
+ This ioctl shall be used by the user to get the version and firmware-tag of
+ the currently running Interface Firmware. All the fields of the 'struct
+ fw_mgmt_ioc_get_fw' are filled by the kernel.
+
+2. FW_MGMT_IOC_GET_BACKEND_FW:
+
+ This ioctl shall be used by the user to get the version of a currently
+ running Backend Interface Firmware identified by a firmware-tag. The user is
+ required to fill the 'firmware_tag' field of the 'struct fw_mgmt_ioc_get_fw'
+ in this case. The 'major' and 'minor' fields are set by the kernel in
+ response.
+
+3. FW_MGMT_IOC_INTF_LOAD_AND_VALIDATE:
+
+ This ioctl shall be used by the user to load an Interface Firmware package on
+ an Interface. The user needs to fill the 'firmware_tag' and 'load_method'
+ fields of the 'struct fw_mgmt_ioc_intf_load_and_validate'. The 'status',
+ 'major' and 'minor' fields are set by the kernel in response.
+
+4. FW_MGMT_IOC_INTF_BACKEND_FW_UPDATE:
+
+ This ioctl shall be used by the user to request an Interface to update a
+ Backend Interface Firmware. The user is required to fill the 'firmware_tag'
+ field of the 'struct fw_mgmt_ioc_get_fw' in this case. The 'status' field is
+ set by the kernel in response.
+
+5. FW_MGMT_IOC_SET_TIMEOUT_MS:
+
+ This ioctl shall be used by the user to increase the timeout interval within
+ which the firmware must get loaded by the Module. The default timeout is 1
+ second. The user needs to pass the timeout in milliseconds.
+
+6. FW_MGMT_IOC_MODE_SWITCH:
+
+ This ioctl shall be used by the user to mode-switch the module to the
+ previously loaded interface firmware. If the interface firmware isn't loaded
+ previously, or if another unsuccessful FW_MGMT_IOC_INTF_LOAD_AND_VALIDATE
+ operation is started after loading interface firmware, then the firmware core
+ wouldn't allow mode-switch.
+
+
+Sysfs Interfaces - Authentication
+---------------------------------
+
+The Component Authentication Protocol interacts with Userspace using the
+character device interface. The character device will be present in /dev/
+directory and will be named gb-authenticate-<N>. The number <N> is assigned at
+runtime.
+
+Identifying the Character Device
+================================
+
+There can be multiple devices present in /dev/ directory with name
+gb-authenticate-N and user first needs to identify the character device used for
+authentication a of particular interface.
+
+The Authentication core creates a device of class 'gb_authenticate', which shall
+be used by the user to identify the right character device for it. The class
+device is created within the Bundle directory for a particular Interface.
+
+For example this is how the class-device can be present:
+
+/sys/bus/greybus/devices/1-1/1-1.1/1-1.1.1/gb_authenticate/gb-authenticate-0
+
+The last name in this path: gb-authenticate-0 is precisely the name of the char
+device and so the device in this case will be:
+
+/dev/gb-authenticate-0.
+
+Operations on the Char device
+=============================
+
+The Character device (/dev/gb-authenticate-0 in above example) can be opened by
+the userspace application and it can perform various 'ioctl' operations on the
+device. The device doesn't support any read/write operations.
+
+Following are the IOCTLs and their data structures available to the user:
+
+#define CAP_CERTIFICATE_MAX_SIZE 1600
+#define CAP_SIGNATURE_MAX_SIZE 320
+
+/* Certificate class types */
+#define CAP_CERT_IMS_EAPC 0x00000001
+#define CAP_CERT_IMS_EASC 0x00000002
+#define CAP_CERT_IMS_EARC 0x00000003
+#define CAP_CERT_IMS_IAPC 0x00000004
+#define CAP_CERT_IMS_IASC 0x00000005
+#define CAP_CERT_IMS_IARC 0x00000006
+
+/* IMS Certificate response result codes */
+#define CAP_IMS_RESULT_CERT_FOUND 0x00
+#define CAP_IMS_RESULT_CERT_CLASS_INVAL 0x01
+#define CAP_IMS_RESULT_CERT_CORRUPT 0x02
+#define CAP_IMS_RESULT_CERT_NOT_FOUND 0x03
+
+/* Authentication types */
+#define CAP_AUTH_IMS_PRI 0x00000001
+#define CAP_AUTH_IMS_SEC 0x00000002
+#define CAP_AUTH_IMS_RSA 0x00000003
+
+/* Authenticate response result codes */
+#define CAP_AUTH_RESULT_CR_SUCCESS 0x00
+#define CAP_AUTH_RESULT_CR_BAD_TYPE 0x01
+#define CAP_AUTH_RESULT_CR_WRONG_EP 0x02
+#define CAP_AUTH_RESULT_CR_NO_KEY 0x03
+#define CAP_AUTH_RESULT_CR_SIG_FAIL 0x04
+
+
+/* IOCTL support */
+struct cap_ioc_get_endpoint_uid {
+ __u8 uid[8];
+} __attribute__ ((__packed__));
+
+struct cap_ioc_get_ims_certificate {
+ __u32 certificate_class;
+ __u32 certificate_id;
+
+ __u8 result_code;
+ __u32 cert_size;
+ __u8 certificate[CAP_CERTIFICATE_MAX_SIZE];
+} __attribute__ ((__packed__));
+
+struct cap_ioc_authenticate {
+ __u32 auth_type;
+ __u8 uid[8];
+ __u8 challenge[32];
+
+ __u8 result_code;
+ __u8 response[64];
+ __u32 signature_size;
+ __u8 signature[CAP_SIGNATURE_MAX_SIZE];
+} __attribute__ ((__packed__));
+
+#define CAP_IOCTL_BASE 'C'
+#define CAP_IOC_GET_ENDPOINT_UID _IOR(CAP_IOCTL_BASE, 0, struct cap_ioc_get_endpoint_uid)
+#define CAP_IOC_GET_IMS_CERTIFICATE _IOWR(CAP_IOCTL_BASE, 1, struct cap_ioc_get_ims_certificate)
+#define CAP_IOC_AUTHENTICATE _IOWR(CAP_IOCTL_BASE, 2, struct cap_ioc_authenticate)
+
+
+1. CAP_IOC_GET_ENDPOINT_UID:
+
+ This ioctl shall be used by the user to get the endpoint UID associated with
+ the Interface. All the fields of the 'struct cap_ioc_get_endpoint_uid' are
+ filled by the kernel.
+
+2. CAP_IOC_GET_IMS_CERTIFICATE:
+
+ This ioctl shall be used by the user to retrieve one of the available
+ cryptographic certificates held by the Interface for use in Component
+ Authentication. The user is required to fill the 'certificate_class' and
+ 'certificate_id' field of the 'struct cap_ioc_get_ims_certificate' in this
+ case. The other fields will be set by the kernel in response. The first
+ 'cert_size' bytes of the 'certificate' shall be read by the user and others
+ must be discarded.
+
+3. CAP_IOC_AUTHENTICATE:
+
+ This ioctl shall be used by the user to authenticate the Module attached to
+ an Interface. The user needs to fill the 'auth_type', 'uid', and 'challenge'
+ fields of the 'struct cap_ioc_authenticate'. The other fields will be set by
+ the kernel in response. The first 'signature_size' bytes of the 'signature'
+ shall be read by the user and others must be discarded.
+
+
+Sysfs Interfaces - Firmware Download
+------------------------------------
+
+The Firmware Download Protocol uses the existing Linux Kernel's Firmware class
+and the interface provided to userspace are described in:
+Documentation/firmware_class/.
+
+
+Sysfs Interfaces - SPI Flash
+----------------------------
+
+The SPI flash is exposed in userspace as a MTD device and is created
+within the Bundle directory. For example, this is how the path may look like:
+
+$ ls /sys/bus/greybus/devices/1-1/1-1.1/1-1.1.1/spi_master/spi32766/spi32766.0/mtd
+mtd0 mtd0ro
+
+
+Sample Applications
+-------------------
+
+The current directory also provides a firmware.c test application, which can be
+referenced while developing userspace application to talk to firmware-management
+protocol.
+
+The current directory also provides a authenticate.c test application, which can
+be referenced while developing userspace application to talk to
+component authentication protocol.
diff --git a/drivers/staging/greybus/Documentation/firmware/firmware.c b/drivers/staging/greybus/Documentation/firmware/firmware.c
new file mode 100644
index 000000000000..ff9382401030
--- /dev/null
+++ b/drivers/staging/greybus/Documentation/firmware/firmware.c
@@ -0,0 +1,262 @@
+/*
+ * Sample code to test firmware-management protocol
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2016 Google Inc. All rights reserved.
+ * Copyright(c) 2016 Linaro Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License 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 version 2 for more details.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Google Inc. All rights reserved.
+ * Copyright(c) 2016 Linaro Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. or Linaro Ltd. nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
+ * LINARO LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "../../greybus_firmware.h"
+
+#define FW_DEV_DEFAULT "/dev/gb-fw-mgmt-0"
+#define FW_TAG_INT_DEFAULT "s3f"
+#define FW_TAG_BCND_DEFAULT "bf_01"
+#define FW_UPDATE_TYPE_DEFAULT 0
+#define FW_TIMEOUT_DEFAULT 10000;
+
+static const char *firmware_tag;
+static const char *fwdev = FW_DEV_DEFAULT;
+static int fw_update_type = FW_UPDATE_TYPE_DEFAULT;
+static int fw_timeout = FW_TIMEOUT_DEFAULT;
+
+static struct fw_mgmt_ioc_get_intf_version intf_fw_info;
+static struct fw_mgmt_ioc_get_backend_version backend_fw_info;
+static struct fw_mgmt_ioc_intf_load_and_validate intf_load;
+static struct fw_mgmt_ioc_backend_fw_update backend_update;
+
+static void usage(void)
+{
+ printf("\nUsage: ./firmware <gb-fw-mgmt-X (default: gb-fw-mgmt-0)> <interface: 0, backend: 1 (default: 0)> <firmware-tag> (default: \"s3f\"/\"bf_01\") <timeout (default: 10000 ms)>\n");
+}
+
+static int update_intf_firmware(int fd)
+{
+ int ret;
+
+ /* Get Interface Firmware Version */
+ printf("Get Interface Firmware Version\n");
+
+ ret = ioctl(fd, FW_MGMT_IOC_GET_INTF_FW, &intf_fw_info);
+ if (ret < 0) {
+ printf("Failed to get interface firmware version: %s (%d)\n",
+ fwdev, ret);
+ return -1;
+ }
+
+ printf("Interface Firmware tag (%s), major (%d), minor (%d)\n",
+ intf_fw_info.firmware_tag, intf_fw_info.major,
+ intf_fw_info.minor);
+
+ /* Try Interface Firmware load over Unipro */
+ printf("Loading Interface Firmware\n");
+
+ intf_load.load_method = GB_FW_U_LOAD_METHOD_UNIPRO;
+ intf_load.status = 0;
+ intf_load.major = 0;
+ intf_load.minor = 0;
+
+ strncpy((char *)&intf_load.firmware_tag, firmware_tag,
+ GB_FIRMWARE_U_TAG_MAX_SIZE);
+
+ ret = ioctl(fd, FW_MGMT_IOC_INTF_LOAD_AND_VALIDATE, &intf_load);
+ if (ret < 0) {
+ printf("Failed to load interface firmware: %s (%d)\n", fwdev,
+ ret);
+ return -1;
+ }
+
+ if (intf_load.status != GB_FW_U_LOAD_STATUS_VALIDATED &&
+ intf_load.status != GB_FW_U_LOAD_STATUS_UNVALIDATED) {
+ printf("Load status says loading failed: %d\n",
+ intf_load.status);
+ return -1;
+ }
+
+ printf("Interface Firmware (%s) Load done: major: %d, minor: %d, status: %d\n",
+ firmware_tag, intf_load.major, intf_load.minor,
+ intf_load.status);
+
+ /* Initiate Mode-switch to the newly loaded firmware */
+ printf("Initiate Mode switch\n");
+
+ ret = ioctl(fd, FW_MGMT_IOC_MODE_SWITCH);
+ if (ret < 0)
+ printf("Failed to initiate mode-switch (%d)\n", ret);
+
+ return ret;
+}
+
+static int update_backend_firmware(int fd)
+{
+ int ret;
+
+ /* Get Backend Firmware Version */
+ printf("Getting Backend Firmware Version\n");
+
+ strncpy((char *)&backend_fw_info.firmware_tag, firmware_tag,
+ GB_FIRMWARE_U_TAG_MAX_SIZE);
+
+retry_fw_version:
+ ret = ioctl(fd, FW_MGMT_IOC_GET_BACKEND_FW, &backend_fw_info);
+ if (ret < 0) {
+ printf("Failed to get backend firmware version: %s (%d)\n",
+ fwdev, ret);
+ return -1;
+ }
+
+ printf("Backend Firmware tag (%s), major (%d), minor (%d), status (%d)\n",
+ backend_fw_info.firmware_tag, backend_fw_info.major,
+ backend_fw_info.minor, backend_fw_info.status);
+
+ if (backend_fw_info.status == GB_FW_U_BACKEND_VERSION_STATUS_RETRY)
+ goto retry_fw_version;
+
+ if ((backend_fw_info.status != GB_FW_U_BACKEND_VERSION_STATUS_SUCCESS)
+ && (backend_fw_info.status != GB_FW_U_BACKEND_VERSION_STATUS_NOT_AVAILABLE)) {
+ printf("Failed to get backend firmware version: %s (%d)\n",
+ fwdev, backend_fw_info.status);
+ return -1;
+ }
+
+ /* Try Backend Firmware Update over Unipro */
+ printf("Updating Backend Firmware\n");
+
+ strncpy((char *)&backend_update.firmware_tag, firmware_tag,
+ GB_FIRMWARE_U_TAG_MAX_SIZE);
+
+retry_fw_update:
+ backend_update.status = 0;
+
+ ret = ioctl(fd, FW_MGMT_IOC_INTF_BACKEND_FW_UPDATE, &backend_update);
+ if (ret < 0) {
+ printf("Failed to load backend firmware: %s (%d)\n", fwdev, ret);
+ return -1;
+ }
+
+ if (backend_update.status == GB_FW_U_BACKEND_FW_STATUS_RETRY) {
+ printf("Retrying firmware update: %d\n", backend_update.status);
+ goto retry_fw_update;
+ }
+
+ if (backend_update.status != GB_FW_U_BACKEND_FW_STATUS_SUCCESS) {
+ printf("Load status says loading failed: %d\n",
+ backend_update.status);
+ } else {
+ printf("Backend Firmware (%s) Load done: status: %d\n",
+ firmware_tag, backend_update.status);
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int fd, ret;
+
+ if (argc > 1 &&
+ (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))) {
+ usage();
+ return -1;
+ }
+
+ if (argc > 1)
+ fwdev = argv[1];
+
+ if (argc > 2)
+ sscanf(argv[2], "%u", &fw_update_type);
+
+ if (argc > 3) {
+ firmware_tag = argv[3];
+ } else if (!fw_update_type) {
+ firmware_tag = FW_TAG_INT_DEFAULT;
+ } else {
+ firmware_tag = FW_TAG_BCND_DEFAULT;
+ }
+
+ if (argc > 4)
+ sscanf(argv[4], "%u", &fw_timeout);
+
+ printf("Trying Firmware update: fwdev: %s, type: %s, tag: %s, timeout: %d\n",
+ fwdev, fw_update_type == 0 ? "interface" : "backend",
+ firmware_tag, fw_timeout);
+
+ printf("Opening %s firmware management device\n", fwdev);
+
+ fd = open(fwdev, O_RDWR);
+ if (fd < 0) {
+ printf("Failed to open: %s\n", fwdev);
+ return -1;
+ }
+
+ /* Set Timeout */
+ printf("Setting timeout to %u ms\n", fw_timeout);
+
+ ret = ioctl(fd, FW_MGMT_IOC_SET_TIMEOUT_MS, &fw_timeout);
+ if (ret < 0) {
+ printf("Failed to set timeout: %s (%d)\n", fwdev, ret);
+ ret = -1;
+ goto close_fd;
+ }
+
+ if (!fw_update_type)
+ ret = update_intf_firmware(fd);
+ else
+ ret = update_backend_firmware(fd);
+
+close_fd:
+ close(fd);
+
+ return ret;
+}
diff --git a/drivers/staging/greybus/Documentation/sysfs-bus-greybus b/drivers/staging/greybus/Documentation/sysfs-bus-greybus
new file mode 100644
index 000000000000..2e998966cbe1
--- /dev/null
+++ b/drivers/staging/greybus/Documentation/sysfs-bus-greybus
@@ -0,0 +1,275 @@
+What: /sys/bus/greybus/devices/greybusN
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ The "root" greybus device for the Greybus device tree, or bus,
+ where N is a dynamically assigned 1-based id.
+
+What: /sys/bus/greybus/devices/greybusN/bus_id
+Date: April 2016
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ The ID of the "root" greybus device, or bus.
+
+What: /sys/bus/greybus/devices/N-M
+Date: March 2016
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ A Module M on the bus N, where M is the 1-byte interface
+ ID of the module's primary interface.
+
+What: /sys/bus/greybus/devices/N-M/eject
+Date: March 2016
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ Writing a non-zero argument to this attibute disables the
+ module's interfaces before physically ejecting it.
+
+What: /sys/bus/greybus/devices/N-M/module_id
+Date: March 2016
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ The ID of a Greybus module, corresponding to the ID of its
+ primary interface.
+
+What: /sys/bus/greybus/devices/N-M/num_interfaces
+Date: March 2016
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ The number of interfaces of a module.
+
+What: /sys/bus/greybus/devices/N-M.I
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ An Interface I on the bus N and module N-M, where I is the
+ 1-byte interface ID.
+
+What: /sys/bus/greybus/devices/N-M.I/current_now
+Date: March 2016
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ Current measurement of the interface in microamps (uA)
+
+What: /sys/bus/greybus/devices/N-M.I/ddbl1_manufacturer_id
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ Unipro Device Descriptor Block Level 1 manufacturer ID for the
+ greybus Interface.
+
+What: /sys/bus/greybus/devices/N-M.I/ddbl1_product_id
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ Unipro Device Descriptor Block Level 1 product ID for the
+ greybus Interface.
+
+What: /sys/bus/greybus/devices/N-M.I/interface_id
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ The ID of a Greybus interface.
+
+What: /sys/bus/greybus/devices/N-M.I/interface_type
+Date: June 2016
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ The type of a Greybus interface; "dummy", "unipro", "greybus",
+ or "unknown".
+
+What: /sys/bus/greybus/devices/N-M.I/power_now
+Date: March 2016
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ Power measurement of the interface in microwatts (uW)
+
+What: /sys/bus/greybus/devices/N-M.I/power_state
+Date: March 2016
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ This file reflects the power state of a Greybus interface. If
+ the value read from it is "on", then power is currently
+ supplied to the interface. Otherwise it will read "off" and
+ power is currently not supplied to the interface.
+
+ If the value read is "off", then writing "on" (or '1', 'y',
+ 'Y') to this file will enable power to the interface and an
+ attempt to boot and possibly enumerate it will be made. Note
+ that on errors, the interface will again be powered down.
+
+ If the value read is "on", then writing "off" (or '0', 'n',
+ 'N') to this file will power down the interface.
+
+What: /sys/bus/greybus/devices/N-M.I/product_id
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ Product ID of a Greybus interface.
+
+What: /sys/bus/greybus/devices/N-M.I/serial_number
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ Serial Number of the Greybus interface, represented by a 64 bit
+ hexadecimal number.
+
+What: /sys/bus/greybus/devices/N-M.I/vendor_id
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ Vendor ID of a Greybus interface.
+
+What: /sys/bus/greybus/devices/N-M.I/voltage_now
+Date: March 2016
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ Voltage measurement of the interface in microvolts (uV)
+
+What: /sys/bus/greybus/devices/N-M.I.ctrl
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ Abstract control device for interface I that represents the
+ current mode of an enumerated Greybus interface.
+
+What: /sys/bus/greybus/devices/N-M.I.ctrl/product_string
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ Product ID string of a Greybus interface.
+
+What: /sys/bus/greybus/devices/N-M.I.ctrl/vendor_string
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ Vendor ID string of a Greybus interface.
+
+What: /sys/bus/greybus/devices/N-M.I.B
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ A bundle B on the Interface I, B is replaced by a 1-byte
+ number representing the bundle.
+
+What: /sys/bus/greybus/devices/N-M.I.B/bundle_class
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ The greybus class of the bundle B.
+
+What: /sys/bus/greybus/devices/N-M.I.B/bundle_id
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ The interface-unique id of the bundle B.
+
+What: /sys/bus/greybus/devices/N-M.I.B/gpbX
+Date: April 2016
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ The General Purpose Bridged PHY device of the bundle B,
+ where X is a dynamically assigned 0-based id.
+
+What: /sys/bus/greybus/devices/N-M.I.B/state
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ A bundle has a state that is managed by the userspace
+ Endo process. This file allows that Endo to signal
+ other Android HALs that the state of the bundle has
+ changed to a specific value. When written to, any
+ process watching the file will be woken up, and the new
+ value can be read. It's a "poor-man's IPC", yes, but
+ simplifies the Android userspace code immensely.
+
+What: /sys/bus/greybus/devices/N-svc
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ The singleton SVC device of bus N.
+
+What: /sys/bus/greybus/devices/N-svc/ap_intf_id
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ The AP interface ID, a 1-byte non-zero integer which
+ defines the position of the AP module on the frame.
+ The interface positions are defined in the GMP
+ Module Developer Kit.
+
+What: /sys/bus/greybus/devices/N-svc/endo_id
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ The Endo ID, which is a 2-byte hexadecimal value
+ defined by the Endo layout scheme, documented in
+ the GMP Module Developer Kit.
+
+What: /sys/bus/greybus/devices/N-svc/intf_eject
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ Write the number of the interface that you wish to
+ forcibly eject from the system.
+
+What: /sys/bus/greybus/devices/N-svc/version
+Date: October 2015
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ The version number of the firmware in the SVC device.
+
+What: /sys/bus/greybus/devices/N-svc/watchdog
+Date: October 2016
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ If the SVC watchdog is enabled or not. Writing 0 to this
+ file will disable the watchdog, writing 1 will enable it.
+
+What: /sys/bus/greybus/devices/N-svc/watchdog_action
+Date: July 2016
+KernelVersion: 4.XX
+Contact: Greg Kroah-Hartman <greg@kroah.com>
+Description:
+ This attribute indicates the action to be performed upon SVC
+ watchdog bite.
+
+ The action can be one of the "reset" or "panic". Writing either
+ one of the "reset" or "panic" will change the behavior of SVC
+ watchdog bite. Default value is "reset".
+
+ "reset" means the UniPro subsystem is to be reset.
+
+ "panic" means SVC watchdog bite will cause kernel to panic.
diff --git a/drivers/staging/greybus/Kconfig b/drivers/staging/greybus/Kconfig
new file mode 100644
index 000000000000..50de2d72dde0
--- /dev/null
+++ b/drivers/staging/greybus/Kconfig
@@ -0,0 +1,219 @@
+menuconfig GREYBUS
+ tristate "Greybus support"
+ depends on SYSFS
+ ---help---
+ This option enables the Greybus driver core. Greybus is an
+ hardware protocol that was designed to provide Unipro with a
+ sane application layer. It was originally designed for the
+ ARA project, a module phone system, but has shown up in other
+ phones, and can be tunneled over other busses in order to
+ control hardware devices.
+
+ Say Y here to enable support for these types of drivers.
+
+ To compile this code as a module, chose M here: the module
+ will be called greybus.ko
+
+if GREYBUS
+
+config GREYBUS_ES2
+ tristate "Greybus ES3 USB host controller"
+ depends on USB
+ ---help---
+ Select this option if you have a Toshiba ES3 USB device that
+ acts as a Greybus "host controller". This device is a bridge
+ from a USB device to a Unipro network.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-es2.ko
+
+config GREYBUS_AUDIO
+ tristate "Greybus Audio Class driver"
+ depends on SOUND
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus Audio Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-audio.ko
+
+config GREYBUS_BOOTROM
+ tristate "Greybus Bootrom Class driver"
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus Bootrom Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-bootrom.ko
+
+config GREYBUS_CAMERA
+ tristate "Greybus Camera Class driver"
+ depends on MEDIA_SUPPORT && LEDS_CLASS_FLASH && BROKEN
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus Camera Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-camera.ko
+
+config GREYBUS_FIRMWARE
+ tristate "Greybus Firmware Download Class driver"
+ depends on SPI
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus Firmware Download Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-firmware.ko
+
+config GREYBUS_HID
+ tristate "Greybus HID Class driver"
+ depends on HID && INPUT
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus HID Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-hid.ko
+
+config GREYBUS_LIGHT
+ tristate "Greybus LED Class driver"
+ depends on LEDS_CLASS
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus LED Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-light.ko
+
+config GREYBUS_LOG
+ tristate "Greybus Debug Log Class driver"
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus Debug Log Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-log.ko
+
+config GREYBUS_LOOPBACK
+ tristate "Greybus Loopback Class driver"
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus Debug Log Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-log.ko
+
+config GREYBUS_POWER
+ tristate "Greybus Powersupply Class driver"
+ depends on POWER_SUPPLY
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus Powersupply Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-power-supply.ko
+
+config GREYBUS_RAW
+ tristate "Greybus Raw Class driver"
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus Raw Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-raw.ko
+
+config GREYBUS_VIBRATOR
+ tristate "Greybus Vibrator Motor Class driver"
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus Vibrator Motor Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-vibrator.ko
+
+menuconfig GREYBUS_BRIDGED_PHY
+ tristate "Greybus Bridged PHY Class drivers"
+ ---help---
+ Select this option to pick from a variety of Greybus Bridged
+ PHY class drivers. These drivers emulate a number of
+ different "traditional" busses by tunneling them over Greybus.
+ Examples of this include serial, SPI, USB, and others.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-phy.ko
+
+if GREYBUS_BRIDGED_PHY
+
+config GREYBUS_GPIO
+ tristate "Greybus GPIO Bridged PHY driver"
+ depends on GPIOLIB
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus GPIO Bridged PHY Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-gpio.ko
+
+config GREYBUS_I2C
+ tristate "Greybus I2C Bridged PHY driver"
+ depends on I2C
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus I2C Bridged PHY Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-i2c.ko
+
+config GREYBUS_PWM
+ tristate "Greybus PWM Bridged PHY driver"
+ depends on PWM
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus PWM Bridged PHY Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-pwm.ko
+
+config GREYBUS_SDIO
+ tristate "Greybus SDIO Bridged PHY driver"
+ depends on MMC
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus SDIO Bridged PHY Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-sdio.ko
+
+config GREYBUS_SPI
+ tristate "Greybus SPI Bridged PHY driver"
+ depends on SPI
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus SPI Bridged PHY Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-spi.ko
+
+config GREYBUS_UART
+ tristate "Greybus UART Bridged PHY driver"
+ depends on TTY
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus UART Bridged PHY Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-uart.ko
+
+config GREYBUS_USB
+ tristate "Greybus USB Host Bridged PHY driver"
+ depends on USB
+ ---help---
+ Select this option if you have a device that follows the
+ Greybus USB Host Bridged PHY Class specification.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-usb.ko
+
+endif # GREYBUS_BRIDGED_PHY
+endif # GREYBUS
diff --git a/drivers/staging/greybus/Makefile b/drivers/staging/greybus/Makefile
new file mode 100644
index 000000000000..f337b7b70782
--- /dev/null
+++ b/drivers/staging/greybus/Makefile
@@ -0,0 +1,96 @@
+# Greybus core
+greybus-y := core.o \
+ debugfs.o \
+ hd.o \
+ manifest.o \
+ module.o \
+ interface.o \
+ bundle.o \
+ connection.o \
+ control.o \
+ svc.o \
+ svc_watchdog.o \
+ operation.o \
+ timesync.o \
+ timesync_platform.o
+
+obj-$(CONFIG_GREYBUS) += greybus.o
+
+# needed for trace events
+ccflags-y += -I$(src)
+
+
+# Greybus Host controller drivers
+gb-es2-y := es2.o
+
+obj-$(CONFIG_GREYBUS_ES2) += gb-es2.o
+
+# Greybus class drivers
+gb-bootrom-y := bootrom.o
+gb-camera-y := camera.o
+gb-firmware-y := fw-core.o fw-download.o fw-management.o authentication.o
+gb-spilib-y := spilib.o
+gb-hid-y := hid.o
+gb-light-y := light.o
+gb-log-y := log.o
+gb-loopback-y := loopback.o
+gb-power-supply-y := power_supply.o
+gb-raw-y := raw.o
+gb-vibrator-y := vibrator.o
+
+obj-$(CONFIG_GREYBUS_BOOTROM) += gb-bootrom.o
+obj-$(CONFIG_GREYBUS_CAMERA) += gb-camera.o
+obj-$(CONFIG_GREYBUS_FIRMWARE) += gb-firmware.o gb-spilib.o
+obj-$(CONFIG_GREYBUS_HID) += gb-hid.o
+obj-$(CONFIG_GREYBUS_LIGHT) += gb-light.o
+obj-$(CONFIG_GREYBUS_LOG) += gb-log.o
+obj-$(CONFIG_GREYBUS_LOOPBACK) += gb-loopback.o
+obj-$(CONFIG_GREYBUS_POWER) += gb-power-supply.o
+obj-$(CONFIG_GREYBUS_RAW) += gb-raw.o
+obj-$(CONFIG_GREYBUS_VIBRATOR) += gb-vibrator.o
+
+# Greybus Audio is a bunch of modules
+gb-audio-module-y := audio_module.o audio_topology.o
+gb-audio-codec-y := audio_codec.o
+gb-audio-gb-y := audio_gb.o
+gb-audio-apbridgea-y := audio_apbridgea.o
+gb-audio-manager-y := audio_manager.o audio_manager_module.o
+
+# Greybus Audio sysfs helpers can be useful when debugging
+#GB_AUDIO_MANAGER_SYSFS ?= true
+#ifeq ($(GB_AUDIO_MANAGER_SYSFS),true)
+#gb-audio-manager-y += audio_manager_sysfs.o
+#ccflags-y += -DGB_AUDIO_MANAGER_SYSFS
+#endif
+
+obj-$(CONFIG_GREYBUS_AUDIO_MSM8994) += gb-audio-codec.o
+obj-$(CONFIG_GREYBUS_AUDIO_MSM8994) += gb-audio-module.o
+obj-$(CONFIG_GREYBUS_AUDIO) += gb-audio-gb.o
+obj-$(CONFIG_GREYBUS_AUDIO) += gb-audio-apbridgea.o
+obj-$(CONFIG_GREYBUS_AUDIO) += gb-audio-manager.o
+
+
+# Greybus Bridged PHY drivers
+gb-gbphy-y := gbphy.o
+gb-gpio-y := gpio.o
+gb-i2c-y := i2c.o
+gb-pwm-y := pwm.o
+gb-sdio-y := sdio.o
+gb-spi-y := spi.o
+gb-uart-y := uart.o
+gb-usb-y := usb.o
+
+obj-$(CONFIG_GREYBUS_BRIDGED_PHY) += gb-gbphy.o
+obj-$(CONFIG_GREYBUS_GPIO) += gb-gpio.o
+obj-$(CONFIG_GREYBUS_I2C) += gb-i2c.o
+obj-$(CONFIG_GREYBUS_PWM) += gb-pwm.o
+obj-$(CONFIG_GREYBUS_SDIO) += gb-sdio.o
+obj-$(CONFIG_GREYBUS_SPI) += gb-spi.o gb-spilib.o
+obj-$(CONFIG_GREYBUS_UART) += gb-uart.o
+obj-$(CONFIG_GREYBUS_USB) += gb-usb.o
+
+
+# Greybus Platform driver
+gb-arche-y := arche-platform.o arche-apb-ctrl.o
+
+obj-$(CONFIG_USB_HSIC_USB3613) += gb-arche.o
diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c
new file mode 100644
index 000000000000..70323aa11f24
--- /dev/null
+++ b/drivers/staging/greybus/arche-apb-ctrl.c
@@ -0,0 +1,522 @@
+/*
+ * Arche Platform driver to control APB.
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+#include <linux/module.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spinlock.h>
+#include "arche_platform.h"
+
+
+struct arche_apb_ctrl_drvdata {
+ /* Control GPIO signals to and from AP <=> AP Bridges */
+ int resetn_gpio;
+ int boot_ret_gpio;
+ int pwroff_gpio;
+ int wake_in_gpio;
+ int wake_out_gpio;
+ int pwrdn_gpio;
+
+ enum arche_platform_state state;
+ bool init_disabled;
+
+ struct regulator *vcore;
+ struct regulator *vio;
+
+ int clk_en_gpio;
+ struct clk *clk;
+
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pin_default;
+
+ /* V2: SPI Bus control */
+ int spi_en_gpio;
+ bool spi_en_polarity_high;
+};
+
+/*
+ * Note that these low level api's are active high
+ */
+static inline void deassert_reset(unsigned int gpio)
+{
+ gpio_set_value(gpio, 1);
+}
+
+static inline void assert_reset(unsigned int gpio)
+{
+ gpio_set_value(gpio, 0);
+}
+
+/*
+ * Note: Please do not modify the below sequence, as it is as per the spec
+ */
+static int coldboot_seq(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
+ int ret;
+
+ if (apb->init_disabled ||
+ apb->state == ARCHE_PLATFORM_STATE_ACTIVE)
+ return 0;
+
+ /* Hold APB in reset state */
+ assert_reset(apb->resetn_gpio);
+
+ if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING &&
+ gpio_is_valid(apb->spi_en_gpio))
+ devm_gpio_free(dev, apb->spi_en_gpio);
+
+ /* Enable power to APB */
+ if (!IS_ERR(apb->vcore)) {
+ ret = regulator_enable(apb->vcore);
+ if (ret) {
+ dev_err(dev, "failed to enable core regulator\n");
+ return ret;
+ }
+ }
+
+ if (!IS_ERR(apb->vio)) {
+ ret = regulator_enable(apb->vio);
+ if (ret) {
+ dev_err(dev, "failed to enable IO regulator\n");
+ return ret;
+ }
+ }
+
+ apb_bootret_deassert(dev);
+
+ /* On DB3 clock was not mandatory */
+ if (gpio_is_valid(apb->clk_en_gpio))
+ gpio_set_value(apb->clk_en_gpio, 1);
+
+ usleep_range(100, 200);
+
+ /* deassert reset to APB : Active-low signal */
+ deassert_reset(apb->resetn_gpio);
+
+ apb->state = ARCHE_PLATFORM_STATE_ACTIVE;
+
+ return 0;
+}
+
+static int fw_flashing_seq(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
+ int ret;
+
+ if (apb->init_disabled ||
+ apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
+ return 0;
+
+ ret = regulator_enable(apb->vcore);
+ if (ret) {
+ dev_err(dev, "failed to enable core regulator\n");
+ return ret;
+ }
+
+ ret = regulator_enable(apb->vio);
+ if (ret) {
+ dev_err(dev, "failed to enable IO regulator\n");
+ return ret;
+ }
+
+ if (gpio_is_valid(apb->spi_en_gpio)) {
+ unsigned long flags;
+
+ if (apb->spi_en_polarity_high)
+ flags = GPIOF_OUT_INIT_HIGH;
+ else
+ flags = GPIOF_OUT_INIT_LOW;
+
+ ret = devm_gpio_request_one(dev, apb->spi_en_gpio,
+ flags, "apb_spi_en");
+ if (ret) {
+ dev_err(dev, "Failed requesting SPI bus en gpio %d\n",
+ apb->spi_en_gpio);
+ return ret;
+ }
+ }
+
+ /* for flashing device should be in reset state */
+ assert_reset(apb->resetn_gpio);
+ apb->state = ARCHE_PLATFORM_STATE_FW_FLASHING;
+
+ return 0;
+}
+
+static int standby_boot_seq(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
+
+ if (apb->init_disabled)
+ return 0;
+
+ /* Even if it is in OFF state, then we do not want to change the state */
+ if (apb->state == ARCHE_PLATFORM_STATE_STANDBY ||
+ apb->state == ARCHE_PLATFORM_STATE_OFF)
+ return 0;
+
+ if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING &&
+ gpio_is_valid(apb->spi_en_gpio))
+ devm_gpio_free(dev, apb->spi_en_gpio);
+
+ /*
+ * As per WDM spec, do nothing
+ *
+ * Pasted from WDM spec,
+ * - A falling edge on POWEROFF_L is detected (a)
+ * - WDM enters standby mode, but no output signals are changed
+ * */
+
+ /* TODO: POWEROFF_L is input to WDM module */
+ apb->state = ARCHE_PLATFORM_STATE_STANDBY;
+ return 0;
+}
+
+static void poweroff_seq(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
+
+ if (apb->init_disabled || apb->state == ARCHE_PLATFORM_STATE_OFF)
+ return;
+
+ if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING &&
+ gpio_is_valid(apb->spi_en_gpio))
+ devm_gpio_free(dev, apb->spi_en_gpio);
+
+ /* disable the clock */
+ if (gpio_is_valid(apb->clk_en_gpio))
+ gpio_set_value(apb->clk_en_gpio, 0);
+
+ if (!IS_ERR(apb->vcore) && regulator_is_enabled(apb->vcore) > 0)
+ regulator_disable(apb->vcore);
+
+ if (!IS_ERR(apb->vio) && regulator_is_enabled(apb->vio) > 0)
+ regulator_disable(apb->vio);
+
+ /* As part of exit, put APB back in reset state */
+ assert_reset(apb->resetn_gpio);
+ apb->state = ARCHE_PLATFORM_STATE_OFF;
+
+ /* TODO: May have to send an event to SVC about this exit */
+}
+
+void apb_bootret_assert(struct device *dev)
+{
+ struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev);
+
+ gpio_set_value(apb->boot_ret_gpio, 1);
+}
+
+void apb_bootret_deassert(struct device *dev)
+{
+ struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev);
+
+ gpio_set_value(apb->boot_ret_gpio, 0);
+}
+
+int apb_ctrl_coldboot(struct device *dev)
+{
+ return coldboot_seq(to_platform_device(dev));
+}
+
+int apb_ctrl_fw_flashing(struct device *dev)
+{
+ return fw_flashing_seq(to_platform_device(dev));
+}
+
+int apb_ctrl_standby_boot(struct device *dev)
+{
+ return standby_boot_seq(to_platform_device(dev));
+}
+
+void apb_ctrl_poweroff(struct device *dev)
+{
+ poweroff_seq(to_platform_device(dev));
+}
+
+static ssize_t state_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
+ int ret = 0;
+ bool is_disabled;
+
+ if (sysfs_streq(buf, "off")) {
+ if (apb->state == ARCHE_PLATFORM_STATE_OFF)
+ return count;
+
+ poweroff_seq(pdev);
+ } else if (sysfs_streq(buf, "active")) {
+ if (apb->state == ARCHE_PLATFORM_STATE_ACTIVE)
+ return count;
+
+ poweroff_seq(pdev);
+ is_disabled = apb->init_disabled;
+ apb->init_disabled = false;
+ ret = coldboot_seq(pdev);
+ if (ret)
+ apb->init_disabled = is_disabled;
+ } else if (sysfs_streq(buf, "standby")) {
+ if (apb->state == ARCHE_PLATFORM_STATE_STANDBY)
+ return count;
+
+ ret = standby_boot_seq(pdev);
+ } else if (sysfs_streq(buf, "fw_flashing")) {
+ if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
+ return count;
+
+ /* First we want to make sure we power off everything
+ * and then enter FW flashing state */
+ poweroff_seq(pdev);
+ ret = fw_flashing_seq(pdev);
+ } else {
+ dev_err(dev, "unknown state\n");
+ ret = -EINVAL;
+ }
+
+ return ret ? ret : count;
+}
+
+static ssize_t state_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev);
+
+ switch (apb->state) {
+ case ARCHE_PLATFORM_STATE_OFF:
+ return sprintf(buf, "off%s\n",
+ apb->init_disabled ? ",disabled" : "");
+ case ARCHE_PLATFORM_STATE_ACTIVE:
+ return sprintf(buf, "active\n");
+ case ARCHE_PLATFORM_STATE_STANDBY:
+ return sprintf(buf, "standby\n");
+ case ARCHE_PLATFORM_STATE_FW_FLASHING:
+ return sprintf(buf, "fw_flashing\n");
+ default:
+ return sprintf(buf, "unknown state\n");
+ }
+}
+
+static DEVICE_ATTR_RW(state);
+
+static int apb_ctrl_get_devtree_data(struct platform_device *pdev,
+ struct arche_apb_ctrl_drvdata *apb)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ int ret;
+
+ apb->resetn_gpio = of_get_named_gpio(np, "reset-gpios", 0);
+ if (apb->resetn_gpio < 0) {
+ dev_err(dev, "failed to get reset gpio\n");
+ return apb->resetn_gpio;
+ }
+ ret = devm_gpio_request_one(dev, apb->resetn_gpio,
+ GPIOF_OUT_INIT_LOW, "apb-reset");
+ if (ret) {
+ dev_err(dev, "Failed requesting reset gpio %d\n",
+ apb->resetn_gpio);
+ return ret;
+ }
+
+ apb->boot_ret_gpio = of_get_named_gpio(np, "boot-ret-gpios", 0);
+ if (apb->boot_ret_gpio < 0) {
+ dev_err(dev, "failed to get boot retention gpio\n");
+ return apb->boot_ret_gpio;
+ }
+ ret = devm_gpio_request_one(dev, apb->boot_ret_gpio,
+ GPIOF_OUT_INIT_LOW, "boot retention");
+ if (ret) {
+ dev_err(dev, "Failed requesting bootret gpio %d\n",
+ apb->boot_ret_gpio);
+ return ret;
+ }
+
+ /* It's not mandatory to support power management interface */
+ apb->pwroff_gpio = of_get_named_gpio(np, "pwr-off-gpios", 0);
+ if (apb->pwroff_gpio < 0) {
+ dev_err(dev, "failed to get power off gpio\n");
+ return apb->pwroff_gpio;
+ }
+ ret = devm_gpio_request_one(dev, apb->pwroff_gpio,
+ GPIOF_IN, "pwroff_n");
+ if (ret) {
+ dev_err(dev, "Failed requesting pwroff_n gpio %d\n",
+ apb->pwroff_gpio);
+ return ret;
+ }
+
+ /* Do not make clock mandatory as of now (for DB3) */
+ apb->clk_en_gpio = of_get_named_gpio(np, "clock-en-gpio", 0);
+ if (apb->clk_en_gpio < 0) {
+ dev_warn(dev, "failed to get clock en gpio\n");
+ } else if (gpio_is_valid(apb->clk_en_gpio)) {
+ ret = devm_gpio_request_one(dev, apb->clk_en_gpio,
+ GPIOF_OUT_INIT_LOW, "apb_clk_en");
+ if (ret) {
+ dev_warn(dev, "Failed requesting APB clock en gpio %d\n",
+ apb->clk_en_gpio);
+ return ret;
+ }
+ }
+
+ apb->pwrdn_gpio = of_get_named_gpio(np, "pwr-down-gpios", 0);
+ if (apb->pwrdn_gpio < 0)
+ dev_warn(dev, "failed to get power down gpio\n");
+
+ /* Regulators are optional, as we may have fixed supply coming in */
+ apb->vcore = devm_regulator_get(dev, "vcore");
+ if (IS_ERR(apb->vcore))
+ dev_warn(dev, "no core regulator found\n");
+
+ apb->vio = devm_regulator_get(dev, "vio");
+ if (IS_ERR(apb->vio))
+ dev_warn(dev, "no IO regulator found\n");
+
+ apb->pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (IS_ERR(apb->pinctrl)) {
+ dev_err(&pdev->dev, "could not get pinctrl handle\n");
+ return PTR_ERR(apb->pinctrl);
+ }
+ apb->pin_default = pinctrl_lookup_state(apb->pinctrl, "default");
+ if (IS_ERR(apb->pin_default)) {
+ dev_err(&pdev->dev, "could not get default pin state\n");
+ return PTR_ERR(apb->pin_default);
+ }
+
+ /* Only applicable for platform >= V2 */
+ apb->spi_en_gpio = of_get_named_gpio(np, "spi-en-gpio", 0);
+ if (apb->spi_en_gpio >= 0) {
+ if (of_property_read_bool(pdev->dev.of_node,
+ "spi-en-active-high"))
+ apb->spi_en_polarity_high = true;
+ }
+
+ return 0;
+}
+
+static int arche_apb_ctrl_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct arche_apb_ctrl_drvdata *apb;
+ struct device *dev = &pdev->dev;
+
+ apb = devm_kzalloc(&pdev->dev, sizeof(*apb), GFP_KERNEL);
+ if (!apb)
+ return -ENOMEM;
+
+ ret = apb_ctrl_get_devtree_data(pdev, apb);
+ if (ret) {
+ dev_err(dev, "failed to get apb devicetree data %d\n", ret);
+ return ret;
+ }
+
+ /* Initially set APB to OFF state */
+ apb->state = ARCHE_PLATFORM_STATE_OFF;
+ /* Check whether device needs to be enabled on boot */
+ if (of_property_read_bool(pdev->dev.of_node, "arche,init-disable"))
+ apb->init_disabled = true;
+
+ platform_set_drvdata(pdev, apb);
+
+ /* Create sysfs interface to allow user to change state dynamically */
+ ret = device_create_file(dev, &dev_attr_state);
+ if (ret) {
+ dev_err(dev, "failed to create state file in sysfs\n");
+ return ret;
+ }
+
+ dev_info(&pdev->dev, "Device registered successfully\n");
+ return 0;
+}
+
+static int arche_apb_ctrl_remove(struct platform_device *pdev)
+{
+ device_remove_file(&pdev->dev, &dev_attr_state);
+ poweroff_seq(pdev);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static int arche_apb_ctrl_suspend(struct device *dev)
+{
+ /*
+ * If timing profile permits, we may shutdown bridge
+ * completely
+ *
+ * TODO: sequence ??
+ *
+ * Also, need to make sure we meet precondition for unipro suspend
+ * Precondition: Definition ???
+ */
+ return 0;
+}
+
+static int arche_apb_ctrl_resume(struct device *dev)
+{
+ /*
+ * Atleast for ES2 we have to meet the delay requirement between
+ * unipro switch and AP bridge init, depending on whether bridge is in
+ * OFF state or standby state.
+ *
+ * Based on whether bridge is in standby or OFF state we may have to
+ * assert multiple signals. Please refer to WDM spec, for more info.
+ *
+ */
+ return 0;
+}
+
+static void arche_apb_ctrl_shutdown(struct platform_device *pdev)
+{
+ apb_ctrl_poweroff(&pdev->dev);
+}
+
+static SIMPLE_DEV_PM_OPS(arche_apb_ctrl_pm_ops, arche_apb_ctrl_suspend,
+ arche_apb_ctrl_resume);
+
+static const struct of_device_id arche_apb_ctrl_of_match[] = {
+ { .compatible = "usbffff,2", },
+ { },
+};
+
+static struct platform_driver arche_apb_ctrl_device_driver = {
+ .probe = arche_apb_ctrl_probe,
+ .remove = arche_apb_ctrl_remove,
+ .shutdown = arche_apb_ctrl_shutdown,
+ .driver = {
+ .name = "arche-apb-ctrl",
+ .pm = &arche_apb_ctrl_pm_ops,
+ .of_match_table = arche_apb_ctrl_of_match,
+ }
+};
+
+int __init arche_apb_init(void)
+{
+ return platform_driver_register(&arche_apb_ctrl_device_driver);
+}
+
+void __exit arche_apb_exit(void)
+{
+ platform_driver_unregister(&arche_apb_ctrl_device_driver);
+}
diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c
new file mode 100644
index 000000000000..e36ee984485b
--- /dev/null
+++ b/drivers/staging/greybus/arche-platform.c
@@ -0,0 +1,827 @@
+/*
+ * Arche Platform driver to enable Unipro link.
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/suspend.h>
+#include <linux/time.h>
+#include "arche_platform.h"
+#include "greybus.h"
+
+#include <linux/usb/usb3613.h>
+
+#define WD_COLDBOOT_PULSE_WIDTH_MS 30
+
+enum svc_wakedetect_state {
+ WD_STATE_IDLE, /* Default state = pulled high/low */
+ WD_STATE_BOOT_INIT, /* WD = falling edge (low) */
+ WD_STATE_COLDBOOT_TRIG, /* WD = rising edge (high), > 30msec */
+ WD_STATE_STANDBYBOOT_TRIG, /* As of now not used ?? */
+ WD_STATE_COLDBOOT_START, /* Cold boot process started */
+ WD_STATE_STANDBYBOOT_START, /* Not used */
+ WD_STATE_TIMESYNC,
+};
+
+struct arche_platform_drvdata {
+ /* Control GPIO signals to and from AP <=> SVC */
+ int svc_reset_gpio;
+ bool is_reset_act_hi;
+ int svc_sysboot_gpio;
+ int wake_detect_gpio; /* bi-dir,maps to WAKE_MOD & WAKE_FRAME signals */
+
+ enum arche_platform_state state;
+
+ int svc_refclk_req;
+ struct clk *svc_ref_clk;
+
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pin_default;
+
+ int num_apbs;
+
+ enum svc_wakedetect_state wake_detect_state;
+ int wake_detect_irq;
+ spinlock_t wake_lock; /* Protect wake_detect_state */
+ struct mutex platform_state_mutex; /* Protect state */
+ wait_queue_head_t wq; /* WQ for arche_pdata->state */
+ unsigned long wake_detect_start;
+ struct notifier_block pm_notifier;
+
+ struct device *dev;
+ struct gb_timesync_svc *timesync_svc_pdata;
+};
+
+static int arche_apb_bootret_assert(struct device *dev, void *data)
+{
+ apb_bootret_assert(dev);
+ return 0;
+}
+
+static int arche_apb_bootret_deassert(struct device *dev, void *data)
+{
+ apb_bootret_deassert(dev);
+ return 0;
+}
+
+/* Requires calling context to hold arche_pdata->platform_state_mutex */
+static void arche_platform_set_state(struct arche_platform_drvdata *arche_pdata,
+ enum arche_platform_state state)
+{
+ arche_pdata->state = state;
+}
+
+/*
+ * arche_platform_change_state: Change the operational state
+ *
+ * This exported function allows external drivers to change the state
+ * of the arche-platform driver.
+ * Note that this function only supports transitions between two states
+ * with limited functionality.
+ *
+ * - ARCHE_PLATFORM_STATE_TIME_SYNC:
+ * Once set, allows timesync operations between SVC <=> AP and makes
+ * sure that arche-platform driver ignores any subsequent events/pulses
+ * from SVC over wake/detect.
+ *
+ * - ARCHE_PLATFORM_STATE_ACTIVE:
+ * Puts back driver to active state, where any pulse from SVC on wake/detect
+ * line would trigger either cold/standby boot.
+ * Note: Transition request from this function does not trigger cold/standby
+ * boot. It just puts back driver book keeping variable back to ACTIVE
+ * state and restores the interrupt.
+ *
+ * Returns -ENODEV if device not found, -EAGAIN if the driver cannot currently
+ * satisfy the requested state-transition or -EINVAL for all other
+ * state-transition requests.
+ */
+int arche_platform_change_state(enum arche_platform_state state,
+ struct gb_timesync_svc *timesync_svc_pdata)
+{
+ struct arche_platform_drvdata *arche_pdata;
+ struct platform_device *pdev;
+ struct device_node *np;
+ int ret = -EAGAIN;
+ unsigned long flags;
+
+ np = of_find_compatible_node(NULL, NULL, "google,arche-platform");
+ if (!np) {
+ pr_err("google,arche-platform device node not found\n");
+ return -ENODEV;
+ }
+
+ pdev = of_find_device_by_node(np);
+ if (!pdev) {
+ pr_err("arche-platform device not found\n");
+ return -ENODEV;
+ }
+
+ arche_pdata = platform_get_drvdata(pdev);
+
+ mutex_lock(&arche_pdata->platform_state_mutex);
+ spin_lock_irqsave(&arche_pdata->wake_lock, flags);
+
+ if (arche_pdata->state == state) {
+ ret = 0;
+ goto exit;
+ }
+
+ switch (state) {
+ case ARCHE_PLATFORM_STATE_TIME_SYNC:
+ if (arche_pdata->state != ARCHE_PLATFORM_STATE_ACTIVE) {
+ ret = -EINVAL;
+ goto exit;
+ }
+ if (arche_pdata->wake_detect_state != WD_STATE_IDLE) {
+ dev_err(arche_pdata->dev,
+ "driver busy with wake/detect line ops\n");
+ goto exit;
+ }
+ device_for_each_child(arche_pdata->dev, NULL,
+ arche_apb_bootret_assert);
+ arche_pdata->wake_detect_state = WD_STATE_TIMESYNC;
+ break;
+ case ARCHE_PLATFORM_STATE_ACTIVE:
+ if (arche_pdata->state != ARCHE_PLATFORM_STATE_TIME_SYNC) {
+ ret = -EINVAL;
+ goto exit;
+ }
+ device_for_each_child(arche_pdata->dev, NULL,
+ arche_apb_bootret_deassert);
+ arche_pdata->wake_detect_state = WD_STATE_IDLE;
+ break;
+ case ARCHE_PLATFORM_STATE_OFF:
+ case ARCHE_PLATFORM_STATE_STANDBY:
+ case ARCHE_PLATFORM_STATE_FW_FLASHING:
+ dev_err(arche_pdata->dev, "busy, request to retry later\n");
+ goto exit;
+ default:
+ ret = -EINVAL;
+ dev_err(arche_pdata->dev,
+ "invalid state transition request\n");
+ goto exit;
+ }
+ arche_pdata->timesync_svc_pdata = timesync_svc_pdata;
+ arche_platform_set_state(arche_pdata, state);
+ if (state == ARCHE_PLATFORM_STATE_ACTIVE)
+ wake_up(&arche_pdata->wq);
+
+ ret = 0;
+exit:
+ spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
+ mutex_unlock(&arche_pdata->platform_state_mutex);
+ of_node_put(np);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(arche_platform_change_state);
+
+/* Requires arche_pdata->wake_lock is held by calling context */
+static void arche_platform_set_wake_detect_state(
+ struct arche_platform_drvdata *arche_pdata,
+ enum svc_wakedetect_state state)
+{
+ arche_pdata->wake_detect_state = state;
+}
+
+static inline void svc_reset_onoff(unsigned int gpio, bool onoff)
+{
+ gpio_set_value(gpio, onoff);
+}
+
+static int apb_cold_boot(struct device *dev, void *data)
+{
+ int ret;
+
+ ret = apb_ctrl_coldboot(dev);
+ if (ret)
+ dev_warn(dev, "failed to coldboot\n");
+
+ /*Child nodes are independent, so do not exit coldboot operation */
+ return 0;
+}
+
+static int apb_poweroff(struct device *dev, void *data)
+{
+ apb_ctrl_poweroff(dev);
+
+ /* Enable HUB3613 into HUB mode. */
+ if (usb3613_hub_mode_ctrl(false))
+ dev_warn(dev, "failed to control hub device\n");
+
+ return 0;
+}
+
+static void arche_platform_wd_irq_en(struct arche_platform_drvdata *arche_pdata)
+{
+ /* Enable interrupt here, to read event back from SVC */
+ gpio_direction_input(arche_pdata->wake_detect_gpio);
+ enable_irq(arche_pdata->wake_detect_irq);
+}
+
+static irqreturn_t arche_platform_wd_irq_thread(int irq, void *devid)
+{
+ struct arche_platform_drvdata *arche_pdata = devid;
+ unsigned long flags;
+
+ spin_lock_irqsave(&arche_pdata->wake_lock, flags);
+ if (arche_pdata->wake_detect_state != WD_STATE_COLDBOOT_TRIG) {
+ /* Something is wrong */
+ spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
+ return IRQ_HANDLED;
+ }
+
+ arche_platform_set_wake_detect_state(arche_pdata,
+ WD_STATE_COLDBOOT_START);
+ spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
+
+ /* It should complete power cycle, so first make sure it is poweroff */
+ device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
+
+ /* Bring APB out of reset: cold boot sequence */
+ device_for_each_child(arche_pdata->dev, NULL, apb_cold_boot);
+
+ /* Enable HUB3613 into HUB mode. */
+ if (usb3613_hub_mode_ctrl(true))
+ dev_warn(arche_pdata->dev, "failed to control hub device\n");
+
+ spin_lock_irqsave(&arche_pdata->wake_lock, flags);
+ arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_IDLE);
+ spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t arche_platform_wd_irq(int irq, void *devid)
+{
+ struct arche_platform_drvdata *arche_pdata = devid;
+ unsigned long flags;
+
+ spin_lock_irqsave(&arche_pdata->wake_lock, flags);
+
+ if (arche_pdata->wake_detect_state == WD_STATE_TIMESYNC) {
+ gb_timesync_irq(arche_pdata->timesync_svc_pdata);
+ goto exit;
+ }
+
+ if (gpio_get_value(arche_pdata->wake_detect_gpio)) {
+ /* wake/detect rising */
+
+ /*
+ * If wake/detect line goes high after low, within less than
+ * 30msec, then standby boot sequence is initiated, which is not
+ * supported/implemented as of now. So ignore it.
+ */
+ if (arche_pdata->wake_detect_state == WD_STATE_BOOT_INIT) {
+ if (time_before(jiffies,
+ arche_pdata->wake_detect_start +
+ msecs_to_jiffies(WD_COLDBOOT_PULSE_WIDTH_MS))) {
+ arche_platform_set_wake_detect_state(arche_pdata,
+ WD_STATE_IDLE);
+ } else {
+ /* Check we are not in middle of irq thread already */
+ if (arche_pdata->wake_detect_state !=
+ WD_STATE_COLDBOOT_START) {
+ arche_platform_set_wake_detect_state(arche_pdata,
+ WD_STATE_COLDBOOT_TRIG);
+ spin_unlock_irqrestore(
+ &arche_pdata->wake_lock,
+ flags);
+ return IRQ_WAKE_THREAD;
+ }
+ }
+ }
+ } else {
+ /* wake/detect falling */
+ if (arche_pdata->wake_detect_state == WD_STATE_IDLE) {
+ arche_pdata->wake_detect_start = jiffies;
+ /*
+ * In the begining, when wake/detect goes low (first time), we assume
+ * it is meant for coldboot and set the flag. If wake/detect line stays low
+ * beyond 30msec, then it is coldboot else fallback to standby boot.
+ */
+ arche_platform_set_wake_detect_state(arche_pdata,
+ WD_STATE_BOOT_INIT);
+ }
+ }
+
+exit:
+ spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Requires arche_pdata->platform_state_mutex to be held
+ */
+static int arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata)
+{
+ int ret;
+
+ if (arche_pdata->state == ARCHE_PLATFORM_STATE_ACTIVE)
+ return 0;
+
+ dev_info(arche_pdata->dev, "Booting from cold boot state\n");
+
+ svc_reset_onoff(arche_pdata->svc_reset_gpio,
+ arche_pdata->is_reset_act_hi);
+
+ gpio_set_value(arche_pdata->svc_sysboot_gpio, 0);
+ usleep_range(100, 200);
+
+ ret = clk_prepare_enable(arche_pdata->svc_ref_clk);
+ if (ret) {
+ dev_err(arche_pdata->dev, "failed to enable svc_ref_clk: %d\n",
+ ret);
+ return ret;
+ }
+
+ /* bring SVC out of reset */
+ svc_reset_onoff(arche_pdata->svc_reset_gpio,
+ !arche_pdata->is_reset_act_hi);
+
+ arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_ACTIVE);
+
+ return 0;
+}
+
+/*
+ * Requires arche_pdata->platform_state_mutex to be held
+ */
+static int arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata)
+{
+ int ret;
+
+ if (arche_pdata->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
+ return 0;
+
+ dev_info(arche_pdata->dev, "Switching to FW flashing state\n");
+
+ svc_reset_onoff(arche_pdata->svc_reset_gpio,
+ arche_pdata->is_reset_act_hi);
+
+ gpio_set_value(arche_pdata->svc_sysboot_gpio, 1);
+
+ usleep_range(100, 200);
+
+ ret = clk_prepare_enable(arche_pdata->svc_ref_clk);
+ if (ret) {
+ dev_err(arche_pdata->dev, "failed to enable svc_ref_clk: %d\n",
+ ret);
+ return ret;
+ }
+
+ svc_reset_onoff(arche_pdata->svc_reset_gpio,
+ !arche_pdata->is_reset_act_hi);
+
+ arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_FW_FLASHING);
+
+ return 0;
+}
+
+/*
+ * Requires arche_pdata->platform_state_mutex to be held
+ */
+static void arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pdata)
+{
+ unsigned long flags;
+
+ if (arche_pdata->state == ARCHE_PLATFORM_STATE_OFF)
+ return;
+
+ /* If in fw_flashing mode, then no need to repeate things again */
+ if (arche_pdata->state != ARCHE_PLATFORM_STATE_FW_FLASHING) {
+ disable_irq(arche_pdata->wake_detect_irq);
+
+ spin_lock_irqsave(&arche_pdata->wake_lock, flags);
+ arche_platform_set_wake_detect_state(arche_pdata,
+ WD_STATE_IDLE);
+ spin_unlock_irqrestore(&arche_pdata->wake_lock, flags);
+ }
+
+ clk_disable_unprepare(arche_pdata->svc_ref_clk);
+
+ /* As part of exit, put APB back in reset state */
+ svc_reset_onoff(arche_pdata->svc_reset_gpio,
+ arche_pdata->is_reset_act_hi);
+
+ arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF);
+}
+
+static ssize_t state_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct arche_platform_drvdata *arche_pdata = platform_get_drvdata(pdev);
+ int ret = 0;
+
+retry:
+ mutex_lock(&arche_pdata->platform_state_mutex);
+ if (arche_pdata->state == ARCHE_PLATFORM_STATE_TIME_SYNC) {
+ mutex_unlock(&arche_pdata->platform_state_mutex);
+ ret = wait_event_interruptible(
+ arche_pdata->wq,
+ arche_pdata->state != ARCHE_PLATFORM_STATE_TIME_SYNC);
+ if (ret)
+ return ret;
+ goto retry;
+ }
+
+ if (sysfs_streq(buf, "off")) {
+ if (arche_pdata->state == ARCHE_PLATFORM_STATE_OFF)
+ goto exit;
+
+ /* If SVC goes down, bring down APB's as well */
+ device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
+
+ arche_platform_poweroff_seq(arche_pdata);
+
+ } else if (sysfs_streq(buf, "active")) {
+ if (arche_pdata->state == ARCHE_PLATFORM_STATE_ACTIVE)
+ goto exit;
+
+ /* First we want to make sure we power off everything
+ * and then activate back again */
+ device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
+ arche_platform_poweroff_seq(arche_pdata);
+
+ arche_platform_wd_irq_en(arche_pdata);
+ ret = arche_platform_coldboot_seq(arche_pdata);
+ if (ret)
+ goto exit;
+
+ } else if (sysfs_streq(buf, "standby")) {
+ if (arche_pdata->state == ARCHE_PLATFORM_STATE_STANDBY)
+ goto exit;
+
+ dev_warn(arche_pdata->dev, "standby state not supported\n");
+ } else if (sysfs_streq(buf, "fw_flashing")) {
+ if (arche_pdata->state == ARCHE_PLATFORM_STATE_FW_FLASHING)
+ goto exit;
+
+ /*
+ * Here we only control SVC.
+ *
+ * In case of FW_FLASHING mode we do not want to control
+ * APBs, as in case of V2, SPI bus is shared between both
+ * the APBs. So let user chose which APB he wants to flash.
+ */
+ arche_platform_poweroff_seq(arche_pdata);
+
+ ret = arche_platform_fw_flashing_seq(arche_pdata);
+ if (ret)
+ goto exit;
+ } else {
+ dev_err(arche_pdata->dev, "unknown state\n");
+ ret = -EINVAL;
+ }
+
+exit:
+ mutex_unlock(&arche_pdata->platform_state_mutex);
+ return ret ? ret : count;
+}
+
+static ssize_t state_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct arche_platform_drvdata *arche_pdata = dev_get_drvdata(dev);
+
+ switch (arche_pdata->state) {
+ case ARCHE_PLATFORM_STATE_OFF:
+ return sprintf(buf, "off\n");
+ case ARCHE_PLATFORM_STATE_ACTIVE:
+ return sprintf(buf, "active\n");
+ case ARCHE_PLATFORM_STATE_STANDBY:
+ return sprintf(buf, "standby\n");
+ case ARCHE_PLATFORM_STATE_FW_FLASHING:
+ return sprintf(buf, "fw_flashing\n");
+ case ARCHE_PLATFORM_STATE_TIME_SYNC:
+ return sprintf(buf, "time_sync\n");
+ default:
+ return sprintf(buf, "unknown state\n");
+ }
+}
+
+static DEVICE_ATTR_RW(state);
+
+static int arche_platform_pm_notifier(struct notifier_block *notifier,
+ unsigned long pm_event, void *unused)
+{
+ struct arche_platform_drvdata *arche_pdata =
+ container_of(notifier, struct arche_platform_drvdata,
+ pm_notifier);
+ int ret = NOTIFY_DONE;
+
+ mutex_lock(&arche_pdata->platform_state_mutex);
+ switch (pm_event) {
+ case PM_SUSPEND_PREPARE:
+ if (arche_pdata->state != ARCHE_PLATFORM_STATE_ACTIVE) {
+ ret = NOTIFY_STOP;
+ break;
+ }
+ device_for_each_child(arche_pdata->dev, NULL, apb_poweroff);
+ arche_platform_poweroff_seq(arche_pdata);
+ break;
+ case PM_POST_SUSPEND:
+ if (arche_pdata->state != ARCHE_PLATFORM_STATE_OFF)
+ break;
+
+ arche_platform_wd_irq_en(arche_pdata);
+ arche_platform_coldboot_seq(arche_pdata);
+ break;
+ default:
+ break;
+ }
+ mutex_unlock(&arche_pdata->platform_state_mutex);
+
+ return ret;
+}
+
+static int arche_platform_probe(struct platform_device *pdev)
+{
+ struct arche_platform_drvdata *arche_pdata;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ int ret;
+
+ arche_pdata = devm_kzalloc(&pdev->dev, sizeof(*arche_pdata), GFP_KERNEL);
+ if (!arche_pdata)
+ return -ENOMEM;
+
+ /* setup svc reset gpio */
+ arche_pdata->is_reset_act_hi = of_property_read_bool(np,
+ "svc,reset-active-high");
+ arche_pdata->svc_reset_gpio = of_get_named_gpio(np, "svc,reset-gpio", 0);
+ if (arche_pdata->svc_reset_gpio < 0) {
+ dev_err(dev, "failed to get reset-gpio\n");
+ return arche_pdata->svc_reset_gpio;
+ }
+ ret = devm_gpio_request(dev, arche_pdata->svc_reset_gpio, "svc-reset");
+ if (ret) {
+ dev_err(dev, "failed to request svc-reset gpio:%d\n", ret);
+ return ret;
+ }
+ ret = gpio_direction_output(arche_pdata->svc_reset_gpio,
+ arche_pdata->is_reset_act_hi);
+ if (ret) {
+ dev_err(dev, "failed to set svc-reset gpio dir:%d\n", ret);
+ return ret;
+ }
+ arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF);
+
+ arche_pdata->svc_sysboot_gpio = of_get_named_gpio(np,
+ "svc,sysboot-gpio", 0);
+ if (arche_pdata->svc_sysboot_gpio < 0) {
+ dev_err(dev, "failed to get sysboot gpio\n");
+ return arche_pdata->svc_sysboot_gpio;
+ }
+ ret = devm_gpio_request(dev, arche_pdata->svc_sysboot_gpio, "sysboot0");
+ if (ret) {
+ dev_err(dev, "failed to request sysboot0 gpio:%d\n", ret);
+ return ret;
+ }
+ ret = gpio_direction_output(arche_pdata->svc_sysboot_gpio, 0);
+ if (ret) {
+ dev_err(dev, "failed to set svc-reset gpio dir:%d\n", ret);
+ return ret;
+ }
+
+ /* setup the clock request gpio first */
+ arche_pdata->svc_refclk_req = of_get_named_gpio(np,
+ "svc,refclk-req-gpio", 0);
+ if (arche_pdata->svc_refclk_req < 0) {
+ dev_err(dev, "failed to get svc clock-req gpio\n");
+ return arche_pdata->svc_refclk_req;
+ }
+ ret = devm_gpio_request(dev, arche_pdata->svc_refclk_req, "svc-clk-req");
+ if (ret) {
+ dev_err(dev, "failed to request svc-clk-req gpio: %d\n", ret);
+ return ret;
+ }
+ ret = gpio_direction_input(arche_pdata->svc_refclk_req);
+ if (ret) {
+ dev_err(dev, "failed to set svc-clk-req gpio dir :%d\n", ret);
+ return ret;
+ }
+
+ /* setup refclk2 to follow the pin */
+ arche_pdata->svc_ref_clk = devm_clk_get(dev, "svc_ref_clk");
+ if (IS_ERR(arche_pdata->svc_ref_clk)) {
+ ret = PTR_ERR(arche_pdata->svc_ref_clk);
+ dev_err(dev, "failed to get svc_ref_clk: %d\n", ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, arche_pdata);
+
+ arche_pdata->num_apbs = of_get_child_count(np);
+ dev_dbg(dev, "Number of APB's available - %d\n", arche_pdata->num_apbs);
+
+ arche_pdata->wake_detect_gpio = of_get_named_gpio(np, "svc,wake-detect-gpio", 0);
+ if (arche_pdata->wake_detect_gpio < 0) {
+ dev_err(dev, "failed to get wake detect gpio\n");
+ return arche_pdata->wake_detect_gpio;
+ }
+
+ ret = devm_gpio_request(dev, arche_pdata->wake_detect_gpio, "wake detect");
+ if (ret) {
+ dev_err(dev, "Failed requesting wake_detect gpio %d\n",
+ arche_pdata->wake_detect_gpio);
+ return ret;
+ }
+
+ arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_IDLE);
+
+ arche_pdata->dev = &pdev->dev;
+
+ spin_lock_init(&arche_pdata->wake_lock);
+ mutex_init(&arche_pdata->platform_state_mutex);
+ init_waitqueue_head(&arche_pdata->wq);
+ arche_pdata->wake_detect_irq =
+ gpio_to_irq(arche_pdata->wake_detect_gpio);
+
+ ret = devm_request_threaded_irq(dev, arche_pdata->wake_detect_irq,
+ arche_platform_wd_irq,
+ arche_platform_wd_irq_thread,
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+ dev_name(dev), arche_pdata);
+ if (ret) {
+ dev_err(dev, "failed to request wake detect IRQ %d\n", ret);
+ return ret;
+ }
+ disable_irq(arche_pdata->wake_detect_irq);
+
+ ret = device_create_file(dev, &dev_attr_state);
+ if (ret) {
+ dev_err(dev, "failed to create state file in sysfs\n");
+ return ret;
+ }
+
+ ret = of_platform_populate(np, NULL, NULL, dev);
+ if (ret) {
+ dev_err(dev, "failed to populate child nodes %d\n", ret);
+ goto err_device_remove;
+ }
+
+ arche_pdata->pm_notifier.notifier_call = arche_platform_pm_notifier;
+ ret = register_pm_notifier(&arche_pdata->pm_notifier);
+
+ if (ret) {
+ dev_err(dev, "failed to register pm notifier %d\n", ret);
+ goto err_device_remove;
+ }
+
+ /* Register callback pointer */
+ arche_platform_change_state_cb = arche_platform_change_state;
+
+ /* Explicitly power off if requested */
+ if (!of_property_read_bool(pdev->dev.of_node, "arche,init-off")) {
+ mutex_lock(&arche_pdata->platform_state_mutex);
+ ret = arche_platform_coldboot_seq(arche_pdata);
+ if (ret) {
+ dev_err(dev, "Failed to cold boot svc %d\n", ret);
+ goto err_coldboot;
+ }
+ arche_platform_wd_irq_en(arche_pdata);
+ mutex_unlock(&arche_pdata->platform_state_mutex);
+ }
+
+ dev_info(dev, "Device registered successfully\n");
+ return 0;
+
+err_coldboot:
+ mutex_unlock(&arche_pdata->platform_state_mutex);
+err_device_remove:
+ device_remove_file(&pdev->dev, &dev_attr_state);
+ return ret;
+}
+
+static int arche_remove_child(struct device *dev, void *unused)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ platform_device_unregister(pdev);
+
+ return 0;
+}
+
+static int arche_platform_remove(struct platform_device *pdev)
+{
+ struct arche_platform_drvdata *arche_pdata = platform_get_drvdata(pdev);
+
+ unregister_pm_notifier(&arche_pdata->pm_notifier);
+ device_remove_file(&pdev->dev, &dev_attr_state);
+ device_for_each_child(&pdev->dev, NULL, arche_remove_child);
+ arche_platform_poweroff_seq(arche_pdata);
+ platform_set_drvdata(pdev, NULL);
+
+ if (usb3613_hub_mode_ctrl(false))
+ dev_warn(arche_pdata->dev, "failed to control hub device\n");
+ /* TODO: Should we do anything more here ?? */
+ return 0;
+}
+
+static int arche_platform_suspend(struct device *dev)
+{
+ /*
+ * If timing profile premits, we may shutdown bridge
+ * completely
+ *
+ * TODO: sequence ??
+ *
+ * Also, need to make sure we meet precondition for unipro suspend
+ * Precondition: Definition ???
+ */
+ return 0;
+}
+
+static int arche_platform_resume(struct device *dev)
+{
+ /*
+ * Atleast for ES2 we have to meet the delay requirement between
+ * unipro switch and AP bridge init, depending on whether bridge is in
+ * OFF state or standby state.
+ *
+ * Based on whether bridge is in standby or OFF state we may have to
+ * assert multiple signals. Please refer to WDM spec, for more info.
+ *
+ */
+ return 0;
+}
+
+static void arche_platform_shutdown(struct platform_device *pdev)
+{
+ struct arche_platform_drvdata *arche_pdata = platform_get_drvdata(pdev);
+
+ arche_platform_poweroff_seq(arche_pdata);
+
+ usb3613_hub_mode_ctrl(false);
+}
+
+static SIMPLE_DEV_PM_OPS(arche_platform_pm_ops,
+ arche_platform_suspend,
+ arche_platform_resume);
+
+static const struct of_device_id arche_platform_of_match[] = {
+ { .compatible = "google,arche-platform", }, /* Use PID/VID of SVC device */
+ { },
+};
+
+static const struct of_device_id arche_combined_id[] = {
+ { .compatible = "google,arche-platform", }, /* Use PID/VID of SVC device */
+ { .compatible = "usbffff,2", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, arche_combined_id);
+
+static struct platform_driver arche_platform_device_driver = {
+ .probe = arche_platform_probe,
+ .remove = arche_platform_remove,
+ .shutdown = arche_platform_shutdown,
+ .driver = {
+ .name = "arche-platform-ctrl",
+ .pm = &arche_platform_pm_ops,
+ .of_match_table = arche_platform_of_match,
+ }
+};
+
+static int __init arche_init(void)
+{
+ int retval;
+
+ retval = platform_driver_register(&arche_platform_device_driver);
+ if (retval)
+ return retval;
+
+ retval = arche_apb_init();
+ if (retval)
+ platform_driver_unregister(&arche_platform_device_driver);
+
+ return retval;
+}
+module_init(arche_init);
+
+static void __exit arche_exit(void)
+{
+ arche_apb_exit();
+ platform_driver_unregister(&arche_platform_device_driver);
+}
+module_exit(arche_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Vaibhav Hiremath <vaibhav.hiremath@linaro.org>");
+MODULE_DESCRIPTION("Arche Platform Driver");
diff --git a/drivers/staging/greybus/arche_platform.h b/drivers/staging/greybus/arche_platform.h
new file mode 100644
index 000000000000..bd12345b82a2
--- /dev/null
+++ b/drivers/staging/greybus/arche_platform.h
@@ -0,0 +1,39 @@
+/*
+ * Arche Platform driver to enable Unipro link.
+ *
+ * Copyright 2015-2016 Google Inc.
+ * Copyright 2015-2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __ARCHE_PLATFORM_H
+#define __ARCHE_PLATFORM_H
+
+#include "timesync.h"
+
+enum arche_platform_state {
+ ARCHE_PLATFORM_STATE_OFF,
+ ARCHE_PLATFORM_STATE_ACTIVE,
+ ARCHE_PLATFORM_STATE_STANDBY,
+ ARCHE_PLATFORM_STATE_FW_FLASHING,
+ ARCHE_PLATFORM_STATE_TIME_SYNC,
+};
+
+int arche_platform_change_state(enum arche_platform_state state,
+ struct gb_timesync_svc *pdata);
+
+extern int (*arche_platform_change_state_cb)(enum arche_platform_state state,
+ struct gb_timesync_svc *pdata);
+int __init arche_apb_init(void);
+void __exit arche_apb_exit(void);
+
+/* Operational states for the APB device */
+int apb_ctrl_coldboot(struct device *dev);
+int apb_ctrl_fw_flashing(struct device *dev);
+int apb_ctrl_standby_boot(struct device *dev);
+void apb_ctrl_poweroff(struct device *dev);
+void apb_bootret_assert(struct device *dev);
+void apb_bootret_deassert(struct device *dev);
+
+#endif /* __ARCHE_PLATFORM_H */
diff --git a/drivers/staging/greybus/arpc.h b/drivers/staging/greybus/arpc.h
new file mode 100644
index 000000000000..7fbddfc40d83
--- /dev/null
+++ b/drivers/staging/greybus/arpc.h
@@ -0,0 +1,109 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2016 Google Inc. All rights reserved.
+ * Copyright(c) 2016 Linaro Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License 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 version 2 for more details.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Google Inc. All rights reserved.
+ * Copyright(c) 2016 Linaro Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. or Linaro Ltd. nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
+ * LINARO LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ARPC_H
+#define __ARPC_H
+
+/* APBridgeA RPC (ARPC) */
+
+enum arpc_result {
+ ARPC_SUCCESS = 0x00,
+ ARPC_NO_MEMORY = 0x01,
+ ARPC_INVALID = 0x02,
+ ARPC_TIMEOUT = 0x03,
+ ARPC_UNKNOWN_ERROR = 0xff,
+};
+
+struct arpc_request_message {
+ __le16 id; /* RPC unique id */
+ __le16 size; /* Size in bytes of header + payload */
+ __u8 type; /* RPC type */
+ __u8 data[0]; /* ARPC data */
+} __packed;
+
+struct arpc_response_message {
+ __le16 id; /* RPC unique id */
+ __u8 result; /* Result of RPC */
+} __packed;
+
+
+/* ARPC requests */
+#define ARPC_TYPE_CPORT_CONNECTED 0x01
+#define ARPC_TYPE_CPORT_QUIESCE 0x02
+#define ARPC_TYPE_CPORT_CLEAR 0x03
+#define ARPC_TYPE_CPORT_FLUSH 0x04
+#define ARPC_TYPE_CPORT_SHUTDOWN 0x05
+
+struct arpc_cport_connected_req {
+ __le16 cport_id;
+} __packed;
+
+struct arpc_cport_quiesce_req {
+ __le16 cport_id;
+ __le16 peer_space;
+ __le16 timeout;
+} __packed;
+
+struct arpc_cport_clear_req {
+ __le16 cport_id;
+} __packed;
+
+struct arpc_cport_flush_req {
+ __le16 cport_id;
+} __packed;
+
+struct arpc_cport_shutdown_req {
+ __le16 cport_id;
+ __le16 timeout;
+ __u8 phase;
+} __packed;
+
+#endif /* __ARPC_H */
diff --git a/drivers/staging/greybus/audio_apbridgea.c b/drivers/staging/greybus/audio_apbridgea.c
new file mode 100644
index 000000000000..1b4252d5d255
--- /dev/null
+++ b/drivers/staging/greybus/audio_apbridgea.c
@@ -0,0 +1,207 @@
+/*
+ * Greybus Audio Device Class Protocol helpers
+ *
+ * Copyright 2015-2016 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include "greybus.h"
+#include "greybus_protocols.h"
+#include "audio_apbridgea.h"
+#include "audio_codec.h"
+
+int gb_audio_apbridgea_set_config(struct gb_connection *connection,
+ __u16 i2s_port, __u32 format, __u32 rate,
+ __u32 mclk_freq)
+{
+ struct audio_apbridgea_set_config_request req;
+
+ req.hdr.type = AUDIO_APBRIDGEA_TYPE_SET_CONFIG;
+ req.hdr.i2s_port = cpu_to_le16(i2s_port);
+ req.format = cpu_to_le32(format);
+ req.rate = cpu_to_le32(rate);
+ req.mclk_freq = cpu_to_le32(mclk_freq);
+
+ return gb_hd_output(connection->hd, &req, sizeof(req),
+ GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_set_config);
+
+int gb_audio_apbridgea_register_cport(struct gb_connection *connection,
+ __u16 i2s_port, __u16 cportid,
+ __u8 direction)
+{
+ struct audio_apbridgea_register_cport_request req;
+ int ret;
+
+ req.hdr.type = AUDIO_APBRIDGEA_TYPE_REGISTER_CPORT;
+ req.hdr.i2s_port = cpu_to_le16(i2s_port);
+ req.cport = cpu_to_le16(cportid);
+ req.direction = direction;
+
+ ret = gb_pm_runtime_get_sync(connection->bundle);
+ if (ret)
+ return ret;
+
+ return gb_hd_output(connection->hd, &req, sizeof(req),
+ GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_register_cport);
+
+int gb_audio_apbridgea_unregister_cport(struct gb_connection *connection,
+ __u16 i2s_port, __u16 cportid,
+ __u8 direction)
+{
+ struct audio_apbridgea_unregister_cport_request req;
+ int ret;
+
+ req.hdr.type = AUDIO_APBRIDGEA_TYPE_UNREGISTER_CPORT;
+ req.hdr.i2s_port = cpu_to_le16(i2s_port);
+ req.cport = cpu_to_le16(cportid);
+ req.direction = direction;
+
+ ret = gb_hd_output(connection->hd, &req, sizeof(req),
+ GB_APB_REQUEST_AUDIO_CONTROL, true);
+
+ gb_pm_runtime_put_autosuspend(connection->bundle);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_unregister_cport);
+
+int gb_audio_apbridgea_set_tx_data_size(struct gb_connection *connection,
+ __u16 i2s_port, __u16 size)
+{
+ struct audio_apbridgea_set_tx_data_size_request req;
+
+ req.hdr.type = AUDIO_APBRIDGEA_TYPE_SET_TX_DATA_SIZE;
+ req.hdr.i2s_port = cpu_to_le16(i2s_port);
+ req.size = cpu_to_le16(size);
+
+ return gb_hd_output(connection->hd, &req, sizeof(req),
+ GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_set_tx_data_size);
+
+int gb_audio_apbridgea_prepare_tx(struct gb_connection *connection,
+ __u16 i2s_port)
+{
+ struct audio_apbridgea_prepare_tx_request req;
+
+ req.hdr.type = AUDIO_APBRIDGEA_TYPE_PREPARE_TX;
+ req.hdr.i2s_port = cpu_to_le16(i2s_port);
+
+ return gb_hd_output(connection->hd, &req, sizeof(req),
+ GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_prepare_tx);
+
+int gb_audio_apbridgea_start_tx(struct gb_connection *connection,
+ __u16 i2s_port, __u64 timestamp)
+{
+ struct audio_apbridgea_start_tx_request req;
+
+ req.hdr.type = AUDIO_APBRIDGEA_TYPE_START_TX;
+ req.hdr.i2s_port = cpu_to_le16(i2s_port);
+ req.timestamp = cpu_to_le64(timestamp);
+
+ return gb_hd_output(connection->hd, &req, sizeof(req),
+ GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_start_tx);
+
+int gb_audio_apbridgea_stop_tx(struct gb_connection *connection, __u16 i2s_port)
+{
+ struct audio_apbridgea_stop_tx_request req;
+
+ req.hdr.type = AUDIO_APBRIDGEA_TYPE_STOP_TX;
+ req.hdr.i2s_port = cpu_to_le16(i2s_port);
+
+ return gb_hd_output(connection->hd, &req, sizeof(req),
+ GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_stop_tx);
+
+int gb_audio_apbridgea_shutdown_tx(struct gb_connection *connection,
+ __u16 i2s_port)
+{
+ struct audio_apbridgea_shutdown_tx_request req;
+
+ req.hdr.type = AUDIO_APBRIDGEA_TYPE_SHUTDOWN_TX;
+ req.hdr.i2s_port = cpu_to_le16(i2s_port);
+
+ return gb_hd_output(connection->hd, &req, sizeof(req),
+ GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_shutdown_tx);
+
+int gb_audio_apbridgea_set_rx_data_size(struct gb_connection *connection,
+ __u16 i2s_port, __u16 size)
+{
+ struct audio_apbridgea_set_rx_data_size_request req;
+
+ req.hdr.type = AUDIO_APBRIDGEA_TYPE_SET_RX_DATA_SIZE;
+ req.hdr.i2s_port = cpu_to_le16(i2s_port);
+ req.size = cpu_to_le16(size);
+
+ return gb_hd_output(connection->hd, &req, sizeof(req),
+ GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_set_rx_data_size);
+
+int gb_audio_apbridgea_prepare_rx(struct gb_connection *connection,
+ __u16 i2s_port)
+{
+ struct audio_apbridgea_prepare_rx_request req;
+
+ req.hdr.type = AUDIO_APBRIDGEA_TYPE_PREPARE_RX;
+ req.hdr.i2s_port = cpu_to_le16(i2s_port);
+
+ return gb_hd_output(connection->hd, &req, sizeof(req),
+ GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_prepare_rx);
+
+int gb_audio_apbridgea_start_rx(struct gb_connection *connection,
+ __u16 i2s_port)
+{
+ struct audio_apbridgea_start_rx_request req;
+
+ req.hdr.type = AUDIO_APBRIDGEA_TYPE_START_RX;
+ req.hdr.i2s_port = cpu_to_le16(i2s_port);
+
+ return gb_hd_output(connection->hd, &req, sizeof(req),
+ GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_start_rx);
+
+int gb_audio_apbridgea_stop_rx(struct gb_connection *connection, __u16 i2s_port)
+{
+ struct audio_apbridgea_stop_rx_request req;
+
+ req.hdr.type = AUDIO_APBRIDGEA_TYPE_STOP_RX;
+ req.hdr.i2s_port = cpu_to_le16(i2s_port);
+
+ return gb_hd_output(connection->hd, &req, sizeof(req),
+ GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_stop_rx);
+
+int gb_audio_apbridgea_shutdown_rx(struct gb_connection *connection,
+ __u16 i2s_port)
+{
+ struct audio_apbridgea_shutdown_rx_request req;
+
+ req.hdr.type = AUDIO_APBRIDGEA_TYPE_SHUTDOWN_RX;
+ req.hdr.i2s_port = cpu_to_le16(i2s_port);
+
+ return gb_hd_output(connection->hd, &req, sizeof(req),
+ GB_APB_REQUEST_AUDIO_CONTROL, true);
+}
+EXPORT_SYMBOL_GPL(gb_audio_apbridgea_shutdown_rx);
+
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("greybus:audio-apbridgea");
+MODULE_DESCRIPTION("Greybus Special APBridgeA Audio Protocol library");
+MODULE_AUTHOR("Mark Greer <mgreer@animalcreek.com>");
diff --git a/drivers/staging/greybus/audio_apbridgea.h b/drivers/staging/greybus/audio_apbridgea.h
new file mode 100644
index 000000000000..b94cb05c89e4
--- /dev/null
+++ b/drivers/staging/greybus/audio_apbridgea.h
@@ -0,0 +1,156 @@
+/**
+ * Copyright (c) 2015-2016 Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * This is a special protocol for configuring communication over the
+ * I2S bus between the DSP on the MSM8994 and APBridgeA. Therefore,
+ * we can predefine several low-level attributes of the communication
+ * because we know that they are supported. In particular, the following
+ * assumptions are made:
+ * - there are two channels (i.e., stereo)
+ * - the low-level protocol is I2S as defined by Philips/NXP
+ * - the DSP on the MSM8994 is the clock master for MCLK, BCLK, and WCLK
+ * - WCLK changes on the falling edge of BCLK
+ * - WCLK low for left channel; high for right channel
+ * - TX data is sent on the falling edge of BCLK
+ * - RX data is received/latched on the rising edge of BCLK
+ */
+
+#ifndef __AUDIO_APBRIDGEA_H
+#define __AUDIO_APBRIDGEA_H
+
+#define AUDIO_APBRIDGEA_TYPE_SET_CONFIG 0x01
+#define AUDIO_APBRIDGEA_TYPE_REGISTER_CPORT 0x02
+#define AUDIO_APBRIDGEA_TYPE_UNREGISTER_CPORT 0x03
+#define AUDIO_APBRIDGEA_TYPE_SET_TX_DATA_SIZE 0x04
+ /* 0x05 unused */
+#define AUDIO_APBRIDGEA_TYPE_PREPARE_TX 0x06
+#define AUDIO_APBRIDGEA_TYPE_START_TX 0x07
+#define AUDIO_APBRIDGEA_TYPE_STOP_TX 0x08
+#define AUDIO_APBRIDGEA_TYPE_SHUTDOWN_TX 0x09
+#define AUDIO_APBRIDGEA_TYPE_SET_RX_DATA_SIZE 0x0a
+ /* 0x0b unused */
+#define AUDIO_APBRIDGEA_TYPE_PREPARE_RX 0x0c
+#define AUDIO_APBRIDGEA_TYPE_START_RX 0x0d
+#define AUDIO_APBRIDGEA_TYPE_STOP_RX 0x0e
+#define AUDIO_APBRIDGEA_TYPE_SHUTDOWN_RX 0x0f
+
+#define AUDIO_APBRIDGEA_PCM_FMT_8 BIT(0)
+#define AUDIO_APBRIDGEA_PCM_FMT_16 BIT(1)
+#define AUDIO_APBRIDGEA_PCM_FMT_24 BIT(2)
+#define AUDIO_APBRIDGEA_PCM_FMT_32 BIT(3)
+#define AUDIO_APBRIDGEA_PCM_FMT_64 BIT(4)
+
+#define AUDIO_APBRIDGEA_PCM_RATE_5512 BIT(0)
+#define AUDIO_APBRIDGEA_PCM_RATE_8000 BIT(1)
+#define AUDIO_APBRIDGEA_PCM_RATE_11025 BIT(2)
+#define AUDIO_APBRIDGEA_PCM_RATE_16000 BIT(3)
+#define AUDIO_APBRIDGEA_PCM_RATE_22050 BIT(4)
+#define AUDIO_APBRIDGEA_PCM_RATE_32000 BIT(5)
+#define AUDIO_APBRIDGEA_PCM_RATE_44100 BIT(6)
+#define AUDIO_APBRIDGEA_PCM_RATE_48000 BIT(7)
+#define AUDIO_APBRIDGEA_PCM_RATE_64000 BIT(8)
+#define AUDIO_APBRIDGEA_PCM_RATE_88200 BIT(9)
+#define AUDIO_APBRIDGEA_PCM_RATE_96000 BIT(10)
+#define AUDIO_APBRIDGEA_PCM_RATE_176400 BIT(11)
+#define AUDIO_APBRIDGEA_PCM_RATE_192000 BIT(12)
+
+#define AUDIO_APBRIDGEA_DIRECTION_TX BIT(0)
+#define AUDIO_APBRIDGEA_DIRECTION_RX BIT(1)
+
+/* The I2S port is passed in the 'index' parameter of the USB request */
+/* The CPort is passed in the 'value' parameter of the USB request */
+
+struct audio_apbridgea_hdr {
+ __u8 type;
+ __le16 i2s_port;
+ __u8 data[0];
+} __packed;
+
+struct audio_apbridgea_set_config_request {
+ struct audio_apbridgea_hdr hdr;
+ __le32 format; /* AUDIO_APBRIDGEA_PCM_FMT_* */
+ __le32 rate; /* AUDIO_APBRIDGEA_PCM_RATE_* */
+ __le32 mclk_freq; /* XXX Remove? */
+} __packed;
+
+struct audio_apbridgea_register_cport_request {
+ struct audio_apbridgea_hdr hdr;
+ __le16 cport;
+ __u8 direction;
+} __packed;
+
+struct audio_apbridgea_unregister_cport_request {
+ struct audio_apbridgea_hdr hdr;
+ __le16 cport;
+ __u8 direction;
+} __packed;
+
+struct audio_apbridgea_set_tx_data_size_request {
+ struct audio_apbridgea_hdr hdr;
+ __le16 size;
+} __packed;
+
+struct audio_apbridgea_prepare_tx_request {
+ struct audio_apbridgea_hdr hdr;
+} __packed;
+
+struct audio_apbridgea_start_tx_request {
+ struct audio_apbridgea_hdr hdr;
+ __le64 timestamp;
+} __packed;
+
+struct audio_apbridgea_stop_tx_request {
+ struct audio_apbridgea_hdr hdr;
+} __packed;
+
+struct audio_apbridgea_shutdown_tx_request {
+ struct audio_apbridgea_hdr hdr;
+} __packed;
+
+struct audio_apbridgea_set_rx_data_size_request {
+ struct audio_apbridgea_hdr hdr;
+ __le16 size;
+} __packed;
+
+struct audio_apbridgea_prepare_rx_request {
+ struct audio_apbridgea_hdr hdr;
+} __packed;
+
+struct audio_apbridgea_start_rx_request {
+ struct audio_apbridgea_hdr hdr;
+} __packed;
+
+struct audio_apbridgea_stop_rx_request {
+ struct audio_apbridgea_hdr hdr;
+} __packed;
+
+struct audio_apbridgea_shutdown_rx_request {
+ struct audio_apbridgea_hdr hdr;
+} __packed;
+
+#endif /*__AUDIO_APBRIDGEA_H */
diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c
new file mode 100644
index 000000000000..8a0744b58a32
--- /dev/null
+++ b/drivers/staging/greybus/audio_codec.c
@@ -0,0 +1,1132 @@
+/*
+ * APBridge ALSA SoC dummy codec driver
+ * Copyright 2016 Google Inc.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+#include <uapi/linux/input.h>
+
+#include "audio_codec.h"
+#include "audio_apbridgea.h"
+#include "audio_manager.h"
+
+static struct gbaudio_codec_info *gbcodec;
+
+static struct gbaudio_data_connection *
+find_data(struct gbaudio_module_info *module, int id)
+{
+ struct gbaudio_data_connection *data;
+
+ list_for_each_entry(data, &module->data_list, list) {
+ if (id == data->id)
+ return data;
+ }
+ return NULL;
+}
+
+static struct gbaudio_stream_params *
+find_dai_stream_params(struct gbaudio_codec_info *codec, int id, int stream)
+{
+ struct gbaudio_codec_dai *dai;
+
+ list_for_each_entry(dai, &codec->dai_list, list) {
+ if (dai->id == id)
+ return &dai->params[stream];
+ }
+ return NULL;
+}
+
+static int gbaudio_module_enable_tx(struct gbaudio_codec_info *codec,
+ struct gbaudio_module_info *module, int id)
+{
+ int module_state, ret = 0;
+ u16 data_cport, i2s_port, cportid;
+ u8 sig_bits, channels;
+ uint32_t format, rate;
+ struct gbaudio_data_connection *data;
+ struct gbaudio_stream_params *params;
+
+ /* find the dai */
+ data = find_data(module, id);
+ if (!data) {
+ dev_err(module->dev, "%d:DATA connection missing\n", id);
+ return -ENODEV;
+ }
+ module_state = data->state[SNDRV_PCM_STREAM_PLAYBACK];
+
+ params = find_dai_stream_params(codec, id, SNDRV_PCM_STREAM_PLAYBACK);
+ if (!params) {
+ dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
+ return -EINVAL;
+ }
+
+ /* register cport */
+ if (module_state < GBAUDIO_CODEC_STARTUP) {
+ i2s_port = 0; /* fixed for now */
+ cportid = data->connection->hd_cport_id;
+ ret = gb_audio_apbridgea_register_cport(data->connection,
+ i2s_port, cportid,
+ AUDIO_APBRIDGEA_DIRECTION_TX);
+ if (ret) {
+ dev_err_ratelimited(module->dev,
+ "reg_cport failed:%d\n", ret);
+ return ret;
+ }
+ data->state[SNDRV_PCM_STREAM_PLAYBACK] =
+ GBAUDIO_CODEC_STARTUP;
+ dev_dbg(module->dev, "Dynamic Register %d DAI\n", cportid);
+ }
+
+ /* hw_params */
+ if (module_state < GBAUDIO_CODEC_HWPARAMS) {
+ format = params->format;
+ channels = params->channels;
+ rate = params->rate;
+ sig_bits = params->sig_bits;
+ data_cport = data->connection->intf_cport_id;
+ ret = gb_audio_gb_set_pcm(module->mgmt_connection, data_cport,
+ format, rate, channels, sig_bits);
+ if (ret) {
+ dev_err_ratelimited(module->dev, "set_pcm failed:%d\n",
+ ret);
+ return ret;
+ }
+ data->state[SNDRV_PCM_STREAM_PLAYBACK] =
+ GBAUDIO_CODEC_HWPARAMS;
+ dev_dbg(module->dev, "Dynamic hw_params %d DAI\n", data_cport);
+ }
+
+ /* prepare */
+ if (module_state < GBAUDIO_CODEC_PREPARE) {
+ data_cport = data->connection->intf_cport_id;
+ ret = gb_audio_gb_set_tx_data_size(module->mgmt_connection,
+ data_cport, 192);
+ if (ret) {
+ dev_err_ratelimited(module->dev,
+ "set_tx_data_size failed:%d\n",
+ ret);
+ return ret;
+ }
+ ret = gb_audio_gb_activate_tx(module->mgmt_connection,
+ data_cport);
+ if (ret) {
+ dev_err_ratelimited(module->dev,
+ "activate_tx failed:%d\n", ret);
+ return ret;
+ }
+ data->state[SNDRV_PCM_STREAM_PLAYBACK] =
+ GBAUDIO_CODEC_PREPARE;
+ dev_dbg(module->dev, "Dynamic prepare %d DAI\n", data_cport);
+ }
+
+ return 0;
+}
+
+static int gbaudio_module_disable_tx(struct gbaudio_module_info *module, int id)
+{
+ int ret;
+ u16 data_cport, cportid, i2s_port;
+ int module_state;
+ struct gbaudio_data_connection *data;
+
+ /* find the dai */
+ data = find_data(module, id);
+ if (!data) {
+ dev_err(module->dev, "%d:DATA connection missing\n", id);
+ return -ENODEV;
+ }
+ module_state = data->state[SNDRV_PCM_STREAM_PLAYBACK];
+
+ if (module_state > GBAUDIO_CODEC_HWPARAMS) {
+ data_cport = data->connection->intf_cport_id;
+ ret = gb_audio_gb_deactivate_tx(module->mgmt_connection,
+ data_cport);
+ if (ret) {
+ dev_err_ratelimited(module->dev,
+ "deactivate_tx failed:%d\n", ret);
+ return ret;
+ }
+ dev_dbg(module->dev, "Dynamic deactivate %d DAI\n", data_cport);
+ data->state[SNDRV_PCM_STREAM_PLAYBACK] =
+ GBAUDIO_CODEC_HWPARAMS;
+ }
+
+ if (module_state > GBAUDIO_CODEC_SHUTDOWN) {
+ i2s_port = 0; /* fixed for now */
+ cportid = data->connection->hd_cport_id;
+ ret = gb_audio_apbridgea_unregister_cport(data->connection,
+ i2s_port, cportid,
+ AUDIO_APBRIDGEA_DIRECTION_TX);
+ if (ret) {
+ dev_err_ratelimited(module->dev,
+ "unregister_cport failed:%d\n",
+ ret);
+ return ret;
+ }
+ dev_dbg(module->dev, "Dynamic Unregister %d DAI\n", cportid);
+ data->state[SNDRV_PCM_STREAM_PLAYBACK] =
+ GBAUDIO_CODEC_SHUTDOWN;
+ }
+
+ return 0;
+}
+
+static int gbaudio_module_enable_rx(struct gbaudio_codec_info *codec,
+ struct gbaudio_module_info *module, int id)
+{
+ int module_state, ret = 0;
+ u16 data_cport, i2s_port, cportid;
+ u8 sig_bits, channels;
+ uint32_t format, rate;
+ struct gbaudio_data_connection *data;
+ struct gbaudio_stream_params *params;
+
+ /* find the dai */
+ data = find_data(module, id);
+ if (!data) {
+ dev_err(module->dev, "%d:DATA connection missing\n", id);
+ return -ENODEV;
+ }
+ module_state = data->state[SNDRV_PCM_STREAM_CAPTURE];
+
+ params = find_dai_stream_params(codec, id, SNDRV_PCM_STREAM_CAPTURE);
+ if (!params) {
+ dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
+ return -EINVAL;
+ }
+
+ /* register cport */
+ if (module_state < GBAUDIO_CODEC_STARTUP) {
+ i2s_port = 0; /* fixed for now */
+ cportid = data->connection->hd_cport_id;
+ ret = gb_audio_apbridgea_register_cport(data->connection,
+ i2s_port, cportid,
+ AUDIO_APBRIDGEA_DIRECTION_RX);
+ if (ret) {
+ dev_err_ratelimited(module->dev,
+ "reg_cport failed:%d\n", ret);
+ return ret;
+ }
+ data->state[SNDRV_PCM_STREAM_CAPTURE] =
+ GBAUDIO_CODEC_STARTUP;
+ dev_dbg(module->dev, "Dynamic Register %d DAI\n", cportid);
+ }
+
+ /* hw_params */
+ if (module_state < GBAUDIO_CODEC_HWPARAMS) {
+ format = params->format;
+ channels = params->channels;
+ rate = params->rate;
+ sig_bits = params->sig_bits;
+ data_cport = data->connection->intf_cport_id;
+ ret = gb_audio_gb_set_pcm(module->mgmt_connection, data_cport,
+ format, rate, channels, sig_bits);
+ if (ret) {
+ dev_err_ratelimited(module->dev, "set_pcm failed:%d\n",
+ ret);
+ return ret;
+ }
+ data->state[SNDRV_PCM_STREAM_CAPTURE] =
+ GBAUDIO_CODEC_HWPARAMS;
+ dev_dbg(module->dev, "Dynamic hw_params %d DAI\n", data_cport);
+ }
+
+ /* prepare */
+ if (module_state < GBAUDIO_CODEC_PREPARE) {
+ data_cport = data->connection->intf_cport_id;
+ ret = gb_audio_gb_set_rx_data_size(module->mgmt_connection,
+ data_cport, 192);
+ if (ret) {
+ dev_err_ratelimited(module->dev,
+ "set_rx_data_size failed:%d\n",
+ ret);
+ return ret;
+ }
+ ret = gb_audio_gb_activate_rx(module->mgmt_connection,
+ data_cport);
+ if (ret) {
+ dev_err_ratelimited(module->dev,
+ "activate_rx failed:%d\n", ret);
+ return ret;
+ }
+ data->state[SNDRV_PCM_STREAM_CAPTURE] =
+ GBAUDIO_CODEC_PREPARE;
+ dev_dbg(module->dev, "Dynamic prepare %d DAI\n", data_cport);
+ }
+
+ return 0;
+}
+
+static int gbaudio_module_disable_rx(struct gbaudio_module_info *module, int id)
+{
+ int ret;
+ u16 data_cport, cportid, i2s_port;
+ int module_state;
+ struct gbaudio_data_connection *data;
+
+ /* find the dai */
+ data = find_data(module, id);
+ if (!data) {
+ dev_err(module->dev, "%d:DATA connection missing\n", id);
+ return -ENODEV;
+ }
+ module_state = data->state[SNDRV_PCM_STREAM_CAPTURE];
+
+ if (module_state > GBAUDIO_CODEC_HWPARAMS) {
+ data_cport = data->connection->intf_cport_id;
+ ret = gb_audio_gb_deactivate_rx(module->mgmt_connection,
+ data_cport);
+ if (ret) {
+ dev_err_ratelimited(module->dev,
+ "deactivate_rx failed:%d\n", ret);
+ return ret;
+ }
+ dev_dbg(module->dev, "Dynamic deactivate %d DAI\n", data_cport);
+ data->state[SNDRV_PCM_STREAM_CAPTURE] =
+ GBAUDIO_CODEC_HWPARAMS;
+ }
+
+ if (module_state > GBAUDIO_CODEC_SHUTDOWN) {
+ i2s_port = 0; /* fixed for now */
+ cportid = data->connection->hd_cport_id;
+ ret = gb_audio_apbridgea_unregister_cport(data->connection,
+ i2s_port, cportid,
+ AUDIO_APBRIDGEA_DIRECTION_RX);
+ if (ret) {
+ dev_err_ratelimited(module->dev,
+ "unregister_cport failed:%d\n",
+ ret);
+ return ret;
+ }
+ dev_dbg(module->dev, "Dynamic Unregister %d DAI\n", cportid);
+ data->state[SNDRV_PCM_STREAM_CAPTURE] =
+ GBAUDIO_CODEC_SHUTDOWN;
+ }
+
+ return 0;
+}
+
+int gbaudio_module_update(struct gbaudio_codec_info *codec,
+ struct snd_soc_dapm_widget *w,
+ struct gbaudio_module_info *module, int enable)
+{
+ int dai_id, ret;
+ char intf_name[NAME_SIZE], dir[NAME_SIZE];
+
+ dev_dbg(module->dev, "%s:Module update %s sequence\n", w->name,
+ enable ? "Enable":"Disable");
+
+ if ((w->id != snd_soc_dapm_aif_in) && (w->id != snd_soc_dapm_aif_out)) {
+ dev_dbg(codec->dev, "No action required for %s\n", w->name);
+ return 0;
+ }
+
+ /* parse dai_id from AIF widget's stream_name */
+ ret = sscanf(w->sname, "%s %d %s", intf_name, &dai_id, dir);
+ if (ret < 3) {
+ dev_err(codec->dev, "Error while parsing dai_id for %s\n",
+ w->name);
+ return -EINVAL;
+ }
+
+ mutex_lock(&codec->lock);
+ if (w->id == snd_soc_dapm_aif_in) {
+ if (enable)
+ ret = gbaudio_module_enable_tx(codec, module, dai_id);
+ else
+ ret = gbaudio_module_disable_tx(module, dai_id);
+ } else if (w->id == snd_soc_dapm_aif_out) {
+ if (enable)
+ ret = gbaudio_module_enable_rx(codec, module, dai_id);
+ else
+ ret = gbaudio_module_disable_rx(module, dai_id);
+ }
+
+ mutex_unlock(&codec->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(gbaudio_module_update);
+
+/*
+ * codec DAI ops
+ */
+static int gbcodec_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
+ struct gbaudio_stream_params *params;
+
+ mutex_lock(&codec->lock);
+
+ if (list_empty(&codec->module_list)) {
+ dev_err(codec->dev, "No codec module available\n");
+ mutex_unlock(&codec->lock);
+ return -ENODEV;
+ }
+
+ params = find_dai_stream_params(codec, dai->id, substream->stream);
+ if (!params) {
+ dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
+ mutex_unlock(&codec->lock);
+ return -EINVAL;
+ }
+ params->state = GBAUDIO_CODEC_STARTUP;
+ mutex_unlock(&codec->lock);
+ /* to prevent suspend in case of active audio */
+ pm_stay_awake(dai->dev);
+
+ return 0;
+}
+
+static void gbcodec_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
+ struct gbaudio_stream_params *params;
+
+ mutex_lock(&codec->lock);
+
+ if (list_empty(&codec->module_list))
+ dev_info(codec->dev, "No codec module available during shutdown\n");
+
+ params = find_dai_stream_params(codec, dai->id, substream->stream);
+ if (!params) {
+ dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
+ mutex_unlock(&codec->lock);
+ return;
+ }
+ params->state = GBAUDIO_CODEC_SHUTDOWN;
+ mutex_unlock(&codec->lock);
+ pm_relax(dai->dev);
+ return;
+}
+
+static int gbcodec_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hwparams,
+ struct snd_soc_dai *dai)
+{
+ int ret;
+ u8 sig_bits, channels;
+ uint32_t format, rate;
+ struct gbaudio_module_info *module;
+ struct gbaudio_data_connection *data;
+ struct gb_bundle *bundle;
+ struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
+ struct gbaudio_stream_params *params;
+
+ mutex_lock(&codec->lock);
+
+ if (list_empty(&codec->module_list)) {
+ dev_err(codec->dev, "No codec module available\n");
+ mutex_unlock(&codec->lock);
+ return -ENODEV;
+ }
+
+ /*
+ * assuming, currently only 48000 Hz, 16BIT_LE, stereo
+ * is supported, validate params before configuring codec
+ */
+ if (params_channels(hwparams) != 2) {
+ dev_err(dai->dev, "Invalid channel count:%d\n",
+ params_channels(hwparams));
+ mutex_unlock(&codec->lock);
+ return -EINVAL;
+ }
+ channels = params_channels(hwparams);
+
+ if (params_rate(hwparams) != 48000) {
+ dev_err(dai->dev, "Invalid sampling rate:%d\n",
+ params_rate(hwparams));
+ mutex_unlock(&codec->lock);
+ return -EINVAL;
+ }
+ rate = GB_AUDIO_PCM_RATE_48000;
+
+ if (params_format(hwparams) != SNDRV_PCM_FORMAT_S16_LE) {
+ dev_err(dai->dev, "Invalid format:%d\n",
+ params_format(hwparams));
+ mutex_unlock(&codec->lock);
+ return -EINVAL;
+ }
+ format = GB_AUDIO_PCM_FMT_S16_LE;
+
+ /* find the data connection */
+ list_for_each_entry(module, &codec->module_list, list) {
+ data = find_data(module, dai->id);
+ if (data)
+ break;
+ }
+
+ if (!data) {
+ dev_err(dai->dev, "DATA connection missing\n");
+ mutex_unlock(&codec->lock);
+ return -EINVAL;
+ }
+
+ params = find_dai_stream_params(codec, dai->id, substream->stream);
+ if (!params) {
+ dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
+ mutex_unlock(&codec->lock);
+ return -EINVAL;
+ }
+
+ bundle = to_gb_bundle(module->dev);
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret) {
+ mutex_unlock(&codec->lock);
+ return ret;
+ }
+
+ ret = gb_audio_apbridgea_set_config(data->connection, 0,
+ AUDIO_APBRIDGEA_PCM_FMT_16,
+ AUDIO_APBRIDGEA_PCM_RATE_48000,
+ 6144000);
+ if (ret) {
+ dev_err_ratelimited(dai->dev, "%d: Error during set_config\n",
+ ret);
+ mutex_unlock(&codec->lock);
+ return ret;
+ }
+
+ gb_pm_runtime_put_noidle(bundle);
+
+ params->state = GBAUDIO_CODEC_HWPARAMS;
+ params->format = format;
+ params->rate = rate;
+ params->channels = channels;
+ params->sig_bits = sig_bits;
+
+ mutex_unlock(&codec->lock);
+ return 0;
+}
+
+static int gbcodec_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ int ret;
+ struct gbaudio_module_info *module;
+ struct gbaudio_data_connection *data;
+ struct gb_bundle *bundle;
+ struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
+ struct gbaudio_stream_params *params;
+
+ mutex_lock(&codec->lock);
+
+ if (list_empty(&codec->module_list)) {
+ dev_err(codec->dev, "No codec module available\n");
+ mutex_unlock(&codec->lock);
+ return -ENODEV;
+ }
+
+ list_for_each_entry(module, &codec->module_list, list) {
+ /* find the dai */
+ data = find_data(module, dai->id);
+ if (data)
+ break;
+ }
+ if (!data) {
+ dev_err(dai->dev, "DATA connection missing\n");
+ mutex_unlock(&codec->lock);
+ return -ENODEV;
+ }
+
+ params = find_dai_stream_params(codec, dai->id, substream->stream);
+ if (!params) {
+ dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
+ mutex_unlock(&codec->lock);
+ return -EINVAL;
+ }
+
+ bundle = to_gb_bundle(module->dev);
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret) {
+ mutex_unlock(&codec->lock);
+ return ret;
+ }
+
+ switch (substream->stream) {
+ case SNDRV_PCM_STREAM_PLAYBACK:
+ ret = gb_audio_apbridgea_set_tx_data_size(data->connection, 0,
+ 192);
+ break;
+ case SNDRV_PCM_STREAM_CAPTURE:
+ ret = gb_audio_apbridgea_set_rx_data_size(data->connection, 0,
+ 192);
+ break;
+ }
+ if (ret) {
+ mutex_unlock(&codec->lock);
+ dev_err_ratelimited(dai->dev, "set_data_size failed:%d\n",
+ ret);
+ return ret;
+ }
+
+ gb_pm_runtime_put_noidle(bundle);
+
+ params->state = GBAUDIO_CODEC_PREPARE;
+ mutex_unlock(&codec->lock);
+ return 0;
+}
+
+static int gbcodec_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
+{
+ int ret;
+ struct gbaudio_data_connection *data;
+ struct gbaudio_module_info *module;
+ struct gb_bundle *bundle;
+ struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev);
+ struct gbaudio_stream_params *params;
+
+
+ dev_dbg(dai->dev, "Mute:%d, Direction:%s\n", mute,
+ stream ? "CAPTURE":"PLAYBACK");
+
+ mutex_lock(&codec->lock);
+
+ params = find_dai_stream_params(codec, dai->id, stream);
+ if (!params) {
+ dev_err(codec->dev, "Failed to fetch dai_stream pointer\n");
+ mutex_unlock(&codec->lock);
+ return -EINVAL;
+ }
+
+ if (list_empty(&codec->module_list)) {
+ dev_err(codec->dev, "No codec module available\n");
+ if (mute) {
+ params->state = GBAUDIO_CODEC_STOP;
+ ret = 0;
+ } else {
+ ret = -ENODEV;
+ }
+ mutex_unlock(&codec->lock);
+ return ret;
+ }
+
+ list_for_each_entry(module, &codec->module_list, list) {
+ /* find the dai */
+ data = find_data(module, dai->id);
+ if (data)
+ break;
+ }
+ if (!data) {
+ dev_err(dai->dev, "%s:%s DATA connection missing\n",
+ dai->name, module->name);
+ mutex_unlock(&codec->lock);
+ return -ENODEV;
+ }
+
+ bundle = to_gb_bundle(module->dev);
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret) {
+ mutex_unlock(&codec->lock);
+ return ret;
+ }
+
+ if (!mute && !stream) {/* start playback */
+ ret = gb_audio_apbridgea_prepare_tx(data->connection,
+ 0);
+ if (!ret)
+ ret = gb_audio_apbridgea_start_tx(data->connection,
+ 0, 0);
+ params->state = GBAUDIO_CODEC_START;
+ } else if (!mute && stream) {/* start capture */
+ ret = gb_audio_apbridgea_prepare_rx(data->connection,
+ 0);
+ if (!ret)
+ ret = gb_audio_apbridgea_start_rx(data->connection,
+ 0);
+ params->state = GBAUDIO_CODEC_START;
+ } else if (mute && !stream) {/* stop playback */
+ ret = gb_audio_apbridgea_stop_tx(data->connection, 0);
+ if (!ret)
+ ret = gb_audio_apbridgea_shutdown_tx(data->connection,
+ 0);
+ params->state = GBAUDIO_CODEC_STOP;
+ } else if (mute && stream) {/* stop capture */
+ ret = gb_audio_apbridgea_stop_rx(data->connection, 0);
+ if (!ret)
+ ret = gb_audio_apbridgea_shutdown_rx(data->connection,
+ 0);
+ params->state = GBAUDIO_CODEC_STOP;
+ } else
+ ret = -EINVAL;
+ if (ret)
+ dev_err_ratelimited(dai->dev,
+ "%s:Error during %s %s stream:%d\n",
+ module->name, mute ? "Mute" : "Unmute",
+ stream ? "Capture" : "Playback", ret);
+
+ gb_pm_runtime_put_noidle(bundle);
+ mutex_unlock(&codec->lock);
+ return ret;
+}
+
+static struct snd_soc_dai_ops gbcodec_dai_ops = {
+ .startup = gbcodec_startup,
+ .shutdown = gbcodec_shutdown,
+ .hw_params = gbcodec_hw_params,
+ .prepare = gbcodec_prepare,
+ .mute_stream = gbcodec_mute_stream,
+};
+
+static struct snd_soc_dai_driver gbaudio_dai[] = {
+ {
+ .name = "apb-i2s0",
+ .id = 0,
+ .playback = {
+ .stream_name = "I2S 0 Playback",
+ .rates = SNDRV_PCM_RATE_48000,
+ .formats = SNDRV_PCM_FORMAT_S16_LE,
+ .rate_max = 48000,
+ .rate_min = 48000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .capture = {
+ .stream_name = "I2S 0 Capture",
+ .rates = SNDRV_PCM_RATE_48000,
+ .formats = SNDRV_PCM_FORMAT_S16_LE,
+ .rate_max = 48000,
+ .rate_min = 48000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &gbcodec_dai_ops,
+ },
+};
+
+static int gbaudio_init_jack(struct gbaudio_module_info *module,
+ struct snd_soc_codec *codec)
+{
+ int ret;
+
+ if (!module->jack_mask)
+ return 0;
+
+ snprintf(module->jack_name, NAME_SIZE, "GB %d Headset Jack",
+ module->dev_id);
+ ret = snd_soc_jack_new(codec, module->jack_name, module->jack_mask,
+ &module->headset_jack);
+ if (ret) {
+ dev_err(module->dev, "Failed to create new jack\n");
+ return ret;
+ }
+
+ if (!module->button_mask)
+ return 0;
+
+ snprintf(module->button_name, NAME_SIZE, "GB %d Button Jack",
+ module->dev_id);
+ ret = snd_soc_jack_new(codec, module->button_name, module->button_mask,
+ &module->button_jack);
+ if (ret) {
+ dev_err(module->dev, "Failed to create button jack\n");
+ return ret;
+ }
+
+ /*
+ * Currently, max 4 buttons are supported with following key mapping
+ * BTN_0 = KEY_MEDIA
+ * BTN_1 = KEY_VOICECOMMAND
+ * BTN_2 = KEY_VOLUMEUP
+ * BTN_3 = KEY_VOLUMEDOWN
+ */
+
+ if (module->button_mask & SND_JACK_BTN_0) {
+ ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_0,
+ KEY_MEDIA);
+ if (ret) {
+ dev_err(module->dev, "Failed to set BTN_0\n");
+ return ret;
+ }
+ }
+
+ if (module->button_mask & SND_JACK_BTN_1) {
+ ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_1,
+ KEY_VOICECOMMAND);
+ if (ret) {
+ dev_err(module->dev, "Failed to set BTN_1\n");
+ return ret;
+ }
+ }
+
+ if (module->button_mask & SND_JACK_BTN_2) {
+ ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_2,
+ KEY_VOLUMEUP);
+ if (ret) {
+ dev_err(module->dev, "Failed to set BTN_2\n");
+ return ret;
+ }
+ }
+
+ if (module->button_mask & SND_JACK_BTN_3) {
+ ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_3,
+ KEY_VOLUMEDOWN);
+ if (ret) {
+ dev_err(module->dev, "Failed to set BTN_0\n");
+ return ret;
+ }
+ }
+
+ /* FIXME
+ * verify if this is really required
+ set_bit(INPUT_PROP_NO_DUMMY_RELEASE,
+ module->button_jack.jack->input_dev->propbit);
+ */
+
+ return 0;
+}
+
+int gbaudio_register_module(struct gbaudio_module_info *module)
+{
+ int ret;
+ struct snd_soc_codec *codec;
+ struct snd_card *card;
+ struct snd_soc_jack *jack = NULL;
+
+ if (!gbcodec) {
+ dev_err(module->dev, "GB Codec not yet probed\n");
+ return -EAGAIN;
+ }
+
+ codec = gbcodec->codec;
+ card = codec->card->snd_card;
+
+ down_write(&card->controls_rwsem);
+
+ if (module->num_dais) {
+ dev_err(gbcodec->dev,
+ "%d:DAIs not supported via gbcodec driver\n",
+ module->num_dais);
+ up_write(&card->controls_rwsem);
+ return -EINVAL;
+ }
+
+ ret = gbaudio_init_jack(module, codec);
+ if (ret) {
+ up_write(&card->controls_rwsem);
+ return ret;
+ }
+
+ if (module->dapm_widgets)
+ snd_soc_dapm_new_controls(&codec->dapm, module->dapm_widgets,
+ module->num_dapm_widgets);
+ if (module->controls)
+ snd_soc_add_codec_controls(codec, module->controls,
+ module->num_controls);
+ if (module->dapm_routes)
+ snd_soc_dapm_add_routes(&codec->dapm, module->dapm_routes,
+ module->num_dapm_routes);
+
+ /* card already instantiated, create widgets here only */
+ if (codec->card->instantiated) {
+ snd_soc_dapm_link_component_dai_widgets(codec->card,
+ &codec->dapm);
+#ifdef CONFIG_SND_JACK
+ /* register jack devices for this module from codec->jack_list */
+ list_for_each_entry(jack, &codec->jack_list, list) {
+ if ((jack == &module->headset_jack)
+ || (jack == &module->button_jack))
+ snd_device_register(codec->card->snd_card,
+ jack->jack);
+ }
+#endif
+ }
+
+ mutex_lock(&gbcodec->lock);
+ list_add(&module->list, &gbcodec->module_list);
+ mutex_unlock(&gbcodec->lock);
+
+ if (codec->card->instantiated)
+ ret = snd_soc_dapm_new_widgets(&codec->dapm);
+ dev_dbg(codec->dev, "Registered %s module\n", module->name);
+
+ up_write(&card->controls_rwsem);
+ return ret;
+}
+EXPORT_SYMBOL(gbaudio_register_module);
+
+static void gbaudio_codec_clean_data_tx(struct gbaudio_data_connection *data)
+{
+ u16 i2s_port, cportid;
+ int ret;
+
+ if (list_is_singular(&gbcodec->module_list)) {
+ ret = gb_audio_apbridgea_stop_tx(data->connection, 0);
+ if (ret)
+ return;
+ ret = gb_audio_apbridgea_shutdown_tx(data->connection,
+ 0);
+ if (ret)
+ return;
+ }
+ i2s_port = 0; /* fixed for now */
+ cportid = data->connection->hd_cport_id;
+ ret = gb_audio_apbridgea_unregister_cport(data->connection,
+ i2s_port, cportid,
+ AUDIO_APBRIDGEA_DIRECTION_TX);
+ data->state[0] = GBAUDIO_CODEC_SHUTDOWN;
+}
+
+static void gbaudio_codec_clean_data_rx(struct gbaudio_data_connection *data)
+{
+ u16 i2s_port, cportid;
+ int ret;
+
+ if (list_is_singular(&gbcodec->module_list)) {
+ ret = gb_audio_apbridgea_stop_rx(data->connection, 0);
+ if (ret)
+ return;
+ ret = gb_audio_apbridgea_shutdown_rx(data->connection,
+ 0);
+ if (ret)
+ return;
+ }
+ i2s_port = 0; /* fixed for now */
+ cportid = data->connection->hd_cport_id;
+ ret = gb_audio_apbridgea_unregister_cport(data->connection,
+ i2s_port, cportid,
+ AUDIO_APBRIDGEA_DIRECTION_RX);
+ data->state[1] = GBAUDIO_CODEC_SHUTDOWN;
+}
+
+
+static void gbaudio_codec_cleanup(struct gbaudio_module_info *module)
+{
+ struct gbaudio_data_connection *data;
+ int pb_state, cap_state;
+
+ dev_dbg(gbcodec->dev, "%s: removed, cleanup APBridge\n", module->name);
+ list_for_each_entry(data, &module->data_list, list) {
+ pb_state = data->state[0];
+ cap_state = data->state[1];
+
+ if (pb_state > GBAUDIO_CODEC_SHUTDOWN)
+ gbaudio_codec_clean_data_tx(data);
+
+ if (cap_state > GBAUDIO_CODEC_SHUTDOWN)
+ gbaudio_codec_clean_data_rx(data);
+
+ }
+}
+
+void gbaudio_unregister_module(struct gbaudio_module_info *module)
+{
+ struct snd_soc_codec *codec = gbcodec->codec;
+ struct snd_card *card = codec->card->snd_card;
+ struct snd_soc_jack *jack, *next_j;
+ int mask;
+
+ dev_dbg(codec->dev, "Unregister %s module\n", module->name);
+
+ down_write(&card->controls_rwsem);
+ mutex_lock(&gbcodec->lock);
+ gbaudio_codec_cleanup(module);
+ list_del(&module->list);
+ dev_dbg(codec->dev, "Process Unregister %s module\n", module->name);
+ mutex_unlock(&gbcodec->lock);
+
+#ifdef CONFIG_SND_JACK
+ /* free jack devices for this module from codec->jack_list */
+ list_for_each_entry_safe(jack, next_j, &codec->jack_list, list) {
+ if (jack == &module->headset_jack)
+ mask = GBCODEC_JACK_MASK;
+ else if (jack == &module->button_jack)
+ mask = GBCODEC_JACK_BUTTON_MASK;
+ else
+ mask = 0;
+ if (mask) {
+ dev_dbg(module->dev, "Report %s removal\n",
+ jack->jack->id);
+ snd_soc_jack_report(jack, 0, mask);
+ snd_device_free(codec->card->snd_card, jack->jack);
+ list_del(&jack->list);
+ }
+ }
+#endif
+
+ if (module->dapm_routes) {
+ dev_dbg(codec->dev, "Removing %d routes\n",
+ module->num_dapm_routes);
+ snd_soc_dapm_del_routes(&codec->dapm, module->dapm_routes,
+ module->num_dapm_routes);
+ }
+ if (module->controls) {
+ dev_dbg(codec->dev, "Removing %d controls\n",
+ module->num_controls);
+ snd_soc_remove_codec_controls(codec, module->controls,
+ module->num_controls);
+ }
+ if (module->dapm_widgets) {
+ dev_dbg(codec->dev, "Removing %d widgets\n",
+ module->num_dapm_widgets);
+ snd_soc_dapm_free_controls(&codec->dapm, module->dapm_widgets,
+ module->num_dapm_widgets);
+ }
+
+ dev_dbg(codec->dev, "Unregistered %s module\n", module->name);
+
+ up_write(&card->controls_rwsem);
+}
+EXPORT_SYMBOL(gbaudio_unregister_module);
+
+/*
+ * codec driver ops
+ */
+static int gbcodec_probe(struct snd_soc_codec *codec)
+{
+ int i;
+ struct gbaudio_codec_info *info;
+ struct gbaudio_codec_dai *dai;
+
+ info = devm_kzalloc(codec->dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ info->dev = codec->dev;
+ INIT_LIST_HEAD(&info->module_list);
+ mutex_init(&info->lock);
+ INIT_LIST_HEAD(&info->dai_list);
+
+ /* init dai_list used to maintain runtime stream info */
+ for (i = 0; i < ARRAY_SIZE(gbaudio_dai); i++) {
+ dai = devm_kzalloc(codec->dev, sizeof(*dai), GFP_KERNEL);
+ if (!dai)
+ return -ENOMEM;
+ dai->id = gbaudio_dai[i].id;
+ list_add(&dai->list, &info->dai_list);
+ }
+
+ info->codec = codec;
+ snd_soc_codec_set_drvdata(codec, info);
+ gbcodec = info;
+
+ device_init_wakeup(codec->dev, 1);
+ return 0;
+}
+
+static int gbcodec_remove(struct snd_soc_codec *codec)
+{
+ /* Empty function for now */
+ return 0;
+}
+
+static u8 gbcodec_reg[GBCODEC_REG_COUNT] = {
+ [GBCODEC_CTL_REG] = GBCODEC_CTL_REG_DEFAULT,
+ [GBCODEC_MUTE_REG] = GBCODEC_MUTE_REG_DEFAULT,
+ [GBCODEC_PB_LVOL_REG] = GBCODEC_PB_VOL_REG_DEFAULT,
+ [GBCODEC_PB_RVOL_REG] = GBCODEC_PB_VOL_REG_DEFAULT,
+ [GBCODEC_CAP_LVOL_REG] = GBCODEC_CAP_VOL_REG_DEFAULT,
+ [GBCODEC_CAP_RVOL_REG] = GBCODEC_CAP_VOL_REG_DEFAULT,
+ [GBCODEC_APB1_MUX_REG] = GBCODEC_APB1_MUX_REG_DEFAULT,
+ [GBCODEC_APB2_MUX_REG] = GBCODEC_APB2_MUX_REG_DEFAULT,
+};
+
+static int gbcodec_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ int ret = 0;
+
+ if (reg == SND_SOC_NOPM)
+ return 0;
+
+ BUG_ON(reg >= GBCODEC_REG_COUNT);
+
+ gbcodec_reg[reg] = value;
+ dev_dbg(codec->dev, "reg[%d] = 0x%x\n", reg, value);
+
+ return ret;
+}
+
+static unsigned int gbcodec_read(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ unsigned int val = 0;
+
+ if (reg == SND_SOC_NOPM)
+ return 0;
+
+ BUG_ON(reg >= GBCODEC_REG_COUNT);
+
+ val = gbcodec_reg[reg];
+ dev_dbg(codec->dev, "reg[%d] = 0x%x\n", reg, val);
+
+ return val;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_gbaudio = {
+ .probe = gbcodec_probe,
+ .remove = gbcodec_remove,
+
+ .read = gbcodec_read,
+ .write = gbcodec_write,
+
+ .reg_cache_size = GBCODEC_REG_COUNT,
+ .reg_cache_default = gbcodec_reg_defaults,
+ .reg_word_size = 1,
+
+ .idle_bias_off = true,
+ .ignore_pmdown_time = 1,
+};
+
+#ifdef CONFIG_PM
+static int gbaudio_codec_suspend(struct device *dev)
+{
+ dev_dbg(dev, "%s: suspend\n", __func__);
+ return 0;
+}
+
+static int gbaudio_codec_resume(struct device *dev)
+{
+ dev_dbg(dev, "%s: resume\n", __func__);
+ return 0;
+}
+
+static const struct dev_pm_ops gbaudio_codec_pm_ops = {
+ .suspend = gbaudio_codec_suspend,
+ .resume = gbaudio_codec_resume,
+};
+#endif
+
+static int gbaudio_codec_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_gbaudio,
+ gbaudio_dai, ARRAY_SIZE(gbaudio_dai));
+}
+
+static int gbaudio_codec_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static const struct of_device_id greybus_asoc_machine_of_match[] = {
+ { .compatible = "toshiba,apb-dummy-codec", },
+ {},
+};
+
+static struct platform_driver gbaudio_codec_driver = {
+ .driver = {
+ .name = "apb-dummy-codec",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &gbaudio_codec_pm_ops,
+#endif
+ .of_match_table = greybus_asoc_machine_of_match,
+ },
+ .probe = gbaudio_codec_probe,
+ .remove = gbaudio_codec_remove,
+};
+module_platform_driver(gbaudio_codec_driver);
+
+MODULE_DESCRIPTION("APBridge ALSA SoC dummy codec driver");
+MODULE_AUTHOR("Vaibhav Agarwal <vaibhav.agarwal@linaro.org>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:apb-dummy-codec");
diff --git a/drivers/staging/greybus/audio_codec.h b/drivers/staging/greybus/audio_codec.h
new file mode 100644
index 000000000000..ca027bd99ad7
--- /dev/null
+++ b/drivers/staging/greybus/audio_codec.h
@@ -0,0 +1,283 @@
+/*
+ * Greybus audio driver
+ * Copyright 2015 Google Inc.
+ * Copyright 2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __LINUX_GBAUDIO_CODEC_H
+#define __LINUX_GBAUDIO_CODEC_H
+
+#include <sound/soc.h>
+#include <sound/jack.h>
+
+#include "greybus.h"
+#include "greybus_protocols.h"
+
+#define NAME_SIZE 32
+#define MAX_DAIS 2 /* APB1, APB2 */
+
+enum {
+ APB1_PCM = 0,
+ APB2_PCM,
+ NUM_CODEC_DAIS,
+};
+
+enum gbcodec_reg_index {
+ GBCODEC_CTL_REG,
+ GBCODEC_MUTE_REG,
+ GBCODEC_PB_LVOL_REG,
+ GBCODEC_PB_RVOL_REG,
+ GBCODEC_CAP_LVOL_REG,
+ GBCODEC_CAP_RVOL_REG,
+ GBCODEC_APB1_MUX_REG,
+ GBCODEC_APB2_MUX_REG,
+ GBCODEC_REG_COUNT
+};
+
+/* device_type should be same as defined in audio.h (Android media layer) */
+enum {
+ GBAUDIO_DEVICE_NONE = 0x0,
+ /* reserved bits */
+ GBAUDIO_DEVICE_BIT_IN = 0x80000000,
+ GBAUDIO_DEVICE_BIT_DEFAULT = 0x40000000,
+ /* output devices */
+ GBAUDIO_DEVICE_OUT_SPEAKER = 0x2,
+ GBAUDIO_DEVICE_OUT_WIRED_HEADSET = 0x4,
+ GBAUDIO_DEVICE_OUT_WIRED_HEADPHONE = 0x8,
+ /* input devices */
+ GBAUDIO_DEVICE_IN_BUILTIN_MIC = GBAUDIO_DEVICE_BIT_IN | 0x4,
+ GBAUDIO_DEVICE_IN_WIRED_HEADSET = GBAUDIO_DEVICE_BIT_IN | 0x10,
+};
+
+/* bit 0-SPK, 1-HP, 2-DAC,
+ * 4-MIC, 5-HSMIC, 6-MIC2
+ */
+#define GBCODEC_CTL_REG_DEFAULT 0x00
+
+/* bit 0,1 - APB1-PB-L/R
+ * bit 2,3 - APB2-PB-L/R
+ * bit 4,5 - APB1-Cap-L/R
+ * bit 6,7 - APB2-Cap-L/R
+ */
+#define GBCODEC_MUTE_REG_DEFAULT 0x00
+
+/* 0-127 steps */
+#define GBCODEC_PB_VOL_REG_DEFAULT 0x00
+#define GBCODEC_CAP_VOL_REG_DEFAULT 0x00
+
+/* bit 0,1,2 - PB stereo, left, right
+ * bit 8,9,10 - Cap stereo, left, right
+ */
+#define GBCODEC_APB1_MUX_REG_DEFAULT 0x00
+#define GBCODEC_APB2_MUX_REG_DEFAULT 0x00
+
+#define GBCODEC_JACK_MASK 0x0000FFFF
+#define GBCODEC_JACK_BUTTON_MASK 0xFFFF0000
+
+static const u8 gbcodec_reg_defaults[GBCODEC_REG_COUNT] = {
+ GBCODEC_CTL_REG_DEFAULT,
+ GBCODEC_MUTE_REG_DEFAULT,
+ GBCODEC_PB_VOL_REG_DEFAULT,
+ GBCODEC_PB_VOL_REG_DEFAULT,
+ GBCODEC_CAP_VOL_REG_DEFAULT,
+ GBCODEC_CAP_VOL_REG_DEFAULT,
+ GBCODEC_APB1_MUX_REG_DEFAULT,
+ GBCODEC_APB2_MUX_REG_DEFAULT,
+};
+
+enum gbaudio_codec_state {
+ GBAUDIO_CODEC_SHUTDOWN = 0,
+ GBAUDIO_CODEC_STARTUP,
+ GBAUDIO_CODEC_HWPARAMS,
+ GBAUDIO_CODEC_PREPARE,
+ GBAUDIO_CODEC_START,
+ GBAUDIO_CODEC_STOP,
+};
+
+struct gbaudio_stream_params {
+ int state;
+ u8 sig_bits, channels;
+ uint32_t format, rate;
+};
+
+struct gbaudio_codec_dai {
+ int id;
+ /* runtime params for playback/capture streams */
+ struct gbaudio_stream_params params[2];
+ struct list_head list;
+};
+
+struct gbaudio_codec_info {
+ struct device *dev;
+ struct snd_soc_codec *codec;
+ struct list_head module_list;
+ /* to maintain runtime stream params for each DAI */
+ struct list_head dai_list;
+ struct mutex lock;
+ u8 reg[GBCODEC_REG_COUNT];
+};
+
+struct gbaudio_widget {
+ __u8 id;
+ const char *name;
+ struct list_head list;
+};
+
+struct gbaudio_control {
+ __u8 id;
+ char *name;
+ char *wname;
+ const char * const *texts;
+ int items;
+ struct list_head list;
+};
+
+struct gbaudio_data_connection {
+ int id;
+ __le16 data_cport;
+ struct gb_connection *connection;
+ struct list_head list;
+ /* maintain runtime state for playback/capture stream */
+ int state[2];
+};
+
+/* stream direction */
+#define GB_PLAYBACK BIT(0)
+#define GB_CAPTURE BIT(1)
+
+enum gbaudio_module_state {
+ GBAUDIO_MODULE_OFF = 0,
+ GBAUDIO_MODULE_ON,
+};
+
+struct gbaudio_module_info {
+ /* module info */
+ struct device *dev;
+ int dev_id; /* check if it should be bundle_id/hd_cport_id */
+ int vid;
+ int pid;
+ int slot;
+ int type;
+ int set_uevent;
+ char vstr[NAME_SIZE];
+ char pstr[NAME_SIZE];
+ struct list_head list;
+ /* need to share this info to above user space */
+ int manager_id;
+ char name[NAME_SIZE];
+ unsigned int ip_devices;
+ unsigned int op_devices;
+
+ /* jack related */
+ char jack_name[NAME_SIZE];
+ char button_name[NAME_SIZE];
+ int jack_type;
+ int jack_mask;
+ int button_mask;
+ int button_status;
+ struct snd_soc_jack headset_jack;
+ struct snd_soc_jack button_jack;
+
+ /* connection info */
+ struct gb_connection *mgmt_connection;
+ size_t num_data_connections;
+ struct list_head data_list;
+
+ /* topology related */
+ int num_dais;
+ int num_controls;
+ int num_dapm_widgets;
+ int num_dapm_routes;
+ unsigned long dai_offset;
+ unsigned long widget_offset;
+ unsigned long control_offset;
+ unsigned long route_offset;
+ struct snd_kcontrol_new *controls;
+ struct snd_soc_dapm_widget *dapm_widgets;
+ struct snd_soc_dapm_route *dapm_routes;
+ struct snd_soc_dai_driver *dais;
+
+ struct list_head widget_list;
+ struct list_head ctl_list;
+ struct list_head widget_ctl_list;
+
+ struct gb_audio_topology *topology;
+};
+
+int gbaudio_tplg_parse_data(struct gbaudio_module_info *module,
+ struct gb_audio_topology *tplg_data);
+void gbaudio_tplg_release(struct gbaudio_module_info *module);
+
+int gbaudio_module_update(struct gbaudio_codec_info *codec,
+ struct snd_soc_dapm_widget *w,
+ struct gbaudio_module_info *module,
+ int enable);
+int gbaudio_register_module(struct gbaudio_module_info *module);
+void gbaudio_unregister_module(struct gbaudio_module_info *module);
+
+/* protocol related */
+extern int gb_audio_gb_get_topology(struct gb_connection *connection,
+ struct gb_audio_topology **topology);
+extern int gb_audio_gb_get_control(struct gb_connection *connection,
+ u8 control_id, u8 index,
+ struct gb_audio_ctl_elem_value *value);
+extern int gb_audio_gb_set_control(struct gb_connection *connection,
+ u8 control_id, u8 index,
+ struct gb_audio_ctl_elem_value *value);
+extern int gb_audio_gb_enable_widget(struct gb_connection *connection,
+ u8 widget_id);
+extern int gb_audio_gb_disable_widget(struct gb_connection *connection,
+ u8 widget_id);
+extern int gb_audio_gb_get_pcm(struct gb_connection *connection,
+ u16 data_cport, uint32_t *format,
+ uint32_t *rate, u8 *channels,
+ u8 *sig_bits);
+extern int gb_audio_gb_set_pcm(struct gb_connection *connection,
+ u16 data_cport, uint32_t format,
+ uint32_t rate, u8 channels,
+ u8 sig_bits);
+extern int gb_audio_gb_set_tx_data_size(struct gb_connection *connection,
+ u16 data_cport, u16 size);
+extern int gb_audio_gb_activate_tx(struct gb_connection *connection,
+ u16 data_cport);
+extern int gb_audio_gb_deactivate_tx(struct gb_connection *connection,
+ u16 data_cport);
+extern int gb_audio_gb_set_rx_data_size(struct gb_connection *connection,
+ u16 data_cport, u16 size);
+extern int gb_audio_gb_activate_rx(struct gb_connection *connection,
+ u16 data_cport);
+extern int gb_audio_gb_deactivate_rx(struct gb_connection *connection,
+ u16 data_cport);
+extern int gb_audio_apbridgea_set_config(struct gb_connection *connection,
+ __u16 i2s_port, __u32 format,
+ __u32 rate, __u32 mclk_freq);
+extern int gb_audio_apbridgea_register_cport(struct gb_connection *connection,
+ __u16 i2s_port, __u16 cportid,
+ __u8 direction);
+extern int gb_audio_apbridgea_unregister_cport(struct gb_connection *connection,
+ __u16 i2s_port, __u16 cportid,
+ __u8 direction);
+extern int gb_audio_apbridgea_set_tx_data_size(struct gb_connection *connection,
+ __u16 i2s_port, __u16 size);
+extern int gb_audio_apbridgea_prepare_tx(struct gb_connection *connection,
+ __u16 i2s_port);
+extern int gb_audio_apbridgea_start_tx(struct gb_connection *connection,
+ __u16 i2s_port, __u64 timestamp);
+extern int gb_audio_apbridgea_stop_tx(struct gb_connection *connection,
+ __u16 i2s_port);
+extern int gb_audio_apbridgea_shutdown_tx(struct gb_connection *connection,
+ __u16 i2s_port);
+extern int gb_audio_apbridgea_set_rx_data_size(struct gb_connection *connection,
+ __u16 i2s_port, __u16 size);
+extern int gb_audio_apbridgea_prepare_rx(struct gb_connection *connection,
+ __u16 i2s_port);
+extern int gb_audio_apbridgea_start_rx(struct gb_connection *connection,
+ __u16 i2s_port);
+extern int gb_audio_apbridgea_stop_rx(struct gb_connection *connection,
+ __u16 i2s_port);
+extern int gb_audio_apbridgea_shutdown_rx(struct gb_connection *connection,
+ __u16 i2s_port);
+
+#endif /* __LINUX_GBAUDIO_CODEC_H */
diff --git a/drivers/staging/greybus/audio_gb.c b/drivers/staging/greybus/audio_gb.c
new file mode 100644
index 000000000000..42f287dd7b84
--- /dev/null
+++ b/drivers/staging/greybus/audio_gb.c
@@ -0,0 +1,228 @@
+/*
+ * Greybus Audio Device Class Protocol helpers
+ *
+ * Copyright 2015-2016 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include "greybus.h"
+#include "greybus_protocols.h"
+#include "operation.h"
+#include "audio_codec.h"
+
+/* TODO: Split into separate calls */
+int gb_audio_gb_get_topology(struct gb_connection *connection,
+ struct gb_audio_topology **topology)
+{
+ struct gb_audio_get_topology_size_response size_resp;
+ struct gb_audio_topology *topo;
+ u16 size;
+ int ret;
+
+ ret = gb_operation_sync(connection, GB_AUDIO_TYPE_GET_TOPOLOGY_SIZE,
+ NULL, 0, &size_resp, sizeof(size_resp));
+ if (ret)
+ return ret;
+
+ size = le16_to_cpu(size_resp.size);
+ if (size < sizeof(*topo))
+ return -ENODATA;
+
+ topo = kzalloc(size, GFP_KERNEL);
+ if (!topo)
+ return -ENOMEM;
+
+ ret = gb_operation_sync(connection, GB_AUDIO_TYPE_GET_TOPOLOGY, NULL, 0,
+ topo, size);
+ if (ret) {
+ kfree(topo);
+ return ret;
+ }
+
+ *topology = topo;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gb_audio_gb_get_topology);
+
+int gb_audio_gb_get_control(struct gb_connection *connection,
+ u8 control_id, u8 index,
+ struct gb_audio_ctl_elem_value *value)
+{
+ struct gb_audio_get_control_request req;
+ struct gb_audio_get_control_response resp;
+ int ret;
+
+ req.control_id = control_id;
+ req.index = index;
+
+ ret = gb_operation_sync(connection, GB_AUDIO_TYPE_GET_CONTROL,
+ &req, sizeof(req), &resp, sizeof(resp));
+ if (ret)
+ return ret;
+
+ memcpy(value, &resp.value, sizeof(*value));
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gb_audio_gb_get_control);
+
+int gb_audio_gb_set_control(struct gb_connection *connection,
+ u8 control_id, u8 index,
+ struct gb_audio_ctl_elem_value *value)
+{
+ struct gb_audio_set_control_request req;
+
+ req.control_id = control_id;
+ req.index = index;
+ memcpy(&req.value, value, sizeof(req.value));
+
+ return gb_operation_sync(connection, GB_AUDIO_TYPE_SET_CONTROL,
+ &req, sizeof(req), NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_audio_gb_set_control);
+
+int gb_audio_gb_enable_widget(struct gb_connection *connection,
+ u8 widget_id)
+{
+ struct gb_audio_enable_widget_request req;
+
+ req.widget_id = widget_id;
+
+ return gb_operation_sync(connection, GB_AUDIO_TYPE_ENABLE_WIDGET,
+ &req, sizeof(req), NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_audio_gb_enable_widget);
+
+int gb_audio_gb_disable_widget(struct gb_connection *connection,
+ u8 widget_id)
+{
+ struct gb_audio_disable_widget_request req;
+
+ req.widget_id = widget_id;
+
+ return gb_operation_sync(connection, GB_AUDIO_TYPE_DISABLE_WIDGET,
+ &req, sizeof(req), NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_audio_gb_disable_widget);
+
+int gb_audio_gb_get_pcm(struct gb_connection *connection, u16 data_cport,
+ uint32_t *format, uint32_t *rate, u8 *channels,
+ u8 *sig_bits)
+{
+ struct gb_audio_get_pcm_request req;
+ struct gb_audio_get_pcm_response resp;
+ int ret;
+
+ req.data_cport = cpu_to_le16(data_cport);
+
+ ret = gb_operation_sync(connection, GB_AUDIO_TYPE_GET_PCM,
+ &req, sizeof(req), &resp, sizeof(resp));
+ if (ret)
+ return ret;
+
+ *format = le32_to_cpu(resp.format);
+ *rate = le32_to_cpu(resp.rate);
+ *channels = resp.channels;
+ *sig_bits = resp.sig_bits;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gb_audio_gb_get_pcm);
+
+int gb_audio_gb_set_pcm(struct gb_connection *connection, u16 data_cport,
+ uint32_t format, uint32_t rate, u8 channels,
+ u8 sig_bits)
+{
+ struct gb_audio_set_pcm_request req;
+
+ req.data_cport = cpu_to_le16(data_cport);
+ req.format = cpu_to_le32(format);
+ req.rate = cpu_to_le32(rate);
+ req.channels = channels;
+ req.sig_bits = sig_bits;
+
+ return gb_operation_sync(connection, GB_AUDIO_TYPE_SET_PCM,
+ &req, sizeof(req), NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_audio_gb_set_pcm);
+
+int gb_audio_gb_set_tx_data_size(struct gb_connection *connection,
+ u16 data_cport, u16 size)
+{
+ struct gb_audio_set_tx_data_size_request req;
+
+ req.data_cport = cpu_to_le16(data_cport);
+ req.size = cpu_to_le16(size);
+
+ return gb_operation_sync(connection, GB_AUDIO_TYPE_SET_TX_DATA_SIZE,
+ &req, sizeof(req), NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_audio_gb_set_tx_data_size);
+
+int gb_audio_gb_activate_tx(struct gb_connection *connection,
+ u16 data_cport)
+{
+ struct gb_audio_activate_tx_request req;
+
+ req.data_cport = cpu_to_le16(data_cport);
+
+ return gb_operation_sync(connection, GB_AUDIO_TYPE_ACTIVATE_TX,
+ &req, sizeof(req), NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_audio_gb_activate_tx);
+
+int gb_audio_gb_deactivate_tx(struct gb_connection *connection,
+ u16 data_cport)
+{
+ struct gb_audio_deactivate_tx_request req;
+
+ req.data_cport = cpu_to_le16(data_cport);
+
+ return gb_operation_sync(connection, GB_AUDIO_TYPE_DEACTIVATE_TX,
+ &req, sizeof(req), NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_audio_gb_deactivate_tx);
+
+int gb_audio_gb_set_rx_data_size(struct gb_connection *connection,
+ u16 data_cport, u16 size)
+{
+ struct gb_audio_set_rx_data_size_request req;
+
+ req.data_cport = cpu_to_le16(data_cport);
+ req.size = cpu_to_le16(size);
+
+ return gb_operation_sync(connection, GB_AUDIO_TYPE_SET_RX_DATA_SIZE,
+ &req, sizeof(req), NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_audio_gb_set_rx_data_size);
+
+int gb_audio_gb_activate_rx(struct gb_connection *connection,
+ u16 data_cport)
+{
+ struct gb_audio_activate_rx_request req;
+
+ req.data_cport = cpu_to_le16(data_cport);
+
+ return gb_operation_sync(connection, GB_AUDIO_TYPE_ACTIVATE_RX,
+ &req, sizeof(req), NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_audio_gb_activate_rx);
+
+int gb_audio_gb_deactivate_rx(struct gb_connection *connection,
+ u16 data_cport)
+{
+ struct gb_audio_deactivate_rx_request req;
+
+ req.data_cport = cpu_to_le16(data_cport);
+
+ return gb_operation_sync(connection, GB_AUDIO_TYPE_DEACTIVATE_RX,
+ &req, sizeof(req), NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_audio_gb_deactivate_rx);
+
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("greybus:audio-gb");
+MODULE_DESCRIPTION("Greybus Audio Device Class Protocol library");
+MODULE_AUTHOR("Mark Greer <mgreer@animalcreek.com>");
diff --git a/drivers/staging/greybus/audio_manager.c b/drivers/staging/greybus/audio_manager.c
new file mode 100644
index 000000000000..aa6508b44fab
--- /dev/null
+++ b/drivers/staging/greybus/audio_manager.c
@@ -0,0 +1,184 @@
+/*
+ * Greybus operations
+ *
+ * Copyright 2015-2016 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/rwlock.h>
+#include <linux/idr.h>
+
+#include "audio_manager.h"
+#include "audio_manager_private.h"
+
+static struct kset *manager_kset;
+
+static LIST_HEAD(modules_list);
+static DECLARE_RWSEM(modules_rwsem);
+static DEFINE_IDA(module_id);
+
+/* helpers */
+static struct gb_audio_manager_module *gb_audio_manager_get_locked(int id)
+{
+ struct gb_audio_manager_module *module;
+
+ if (id < 0)
+ return NULL;
+
+ list_for_each_entry(module, &modules_list, list) {
+ if (module->id == id)
+ return module;
+ }
+
+ return NULL;
+}
+
+/* public API */
+int gb_audio_manager_add(struct gb_audio_manager_module_descriptor *desc)
+{
+ struct gb_audio_manager_module *module;
+ int id;
+ int err;
+
+ id = ida_simple_get(&module_id, 0, 0, GFP_KERNEL);
+ err = gb_audio_manager_module_create(&module, manager_kset,
+ id, desc);
+ if (err) {
+ ida_simple_remove(&module_id, id);
+ return err;
+ }
+
+ /* Add it to the list */
+ down_write(&modules_rwsem);
+ list_add_tail(&module->list, &modules_list);
+ up_write(&modules_rwsem);
+
+ return module->id;
+}
+EXPORT_SYMBOL_GPL(gb_audio_manager_add);
+
+int gb_audio_manager_remove(int id)
+{
+ struct gb_audio_manager_module *module;
+
+ down_write(&modules_rwsem);
+
+ module = gb_audio_manager_get_locked(id);
+ if (!module) {
+ up_write(&modules_rwsem);
+ return -EINVAL;
+ }
+ list_del(&module->list);
+ kobject_put(&module->kobj);
+ up_write(&modules_rwsem);
+ ida_simple_remove(&module_id, id);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gb_audio_manager_remove);
+
+void gb_audio_manager_remove_all(void)
+{
+ struct gb_audio_manager_module *module, *next;
+ int is_empty = 1;
+
+ down_write(&modules_rwsem);
+
+ list_for_each_entry_safe(module, next, &modules_list, list) {
+ list_del(&module->list);
+ kobject_put(&module->kobj);
+ ida_simple_remove(&module_id, module->id);
+ }
+
+ is_empty = list_empty(&modules_list);
+
+ up_write(&modules_rwsem);
+
+ if (!is_empty)
+ pr_warn("Not all nodes were deleted\n");
+}
+EXPORT_SYMBOL_GPL(gb_audio_manager_remove_all);
+
+struct gb_audio_manager_module *gb_audio_manager_get_module(int id)
+{
+ struct gb_audio_manager_module *module;
+
+ down_read(&modules_rwsem);
+ module = gb_audio_manager_get_locked(id);
+ kobject_get(&module->kobj);
+ up_read(&modules_rwsem);
+ return module;
+}
+EXPORT_SYMBOL_GPL(gb_audio_manager_get_module);
+
+void gb_audio_manager_put_module(struct gb_audio_manager_module *module)
+{
+ kobject_put(&module->kobj);
+}
+EXPORT_SYMBOL_GPL(gb_audio_manager_put_module);
+
+int gb_audio_manager_dump_module(int id)
+{
+ struct gb_audio_manager_module *module;
+
+ down_read(&modules_rwsem);
+ module = gb_audio_manager_get_locked(id);
+ up_read(&modules_rwsem);
+
+ if (!module)
+ return -EINVAL;
+
+ gb_audio_manager_module_dump(module);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gb_audio_manager_dump_module);
+
+void gb_audio_manager_dump_all(void)
+{
+ struct gb_audio_manager_module *module;
+ int count = 0;
+
+ down_read(&modules_rwsem);
+ list_for_each_entry(module, &modules_list, list) {
+ gb_audio_manager_module_dump(module);
+ count++;
+ }
+ up_read(&modules_rwsem);
+
+ pr_info("Number of connected modules: %d\n", count);
+}
+EXPORT_SYMBOL_GPL(gb_audio_manager_dump_all);
+
+/*
+ * module init/deinit
+ */
+static int __init manager_init(void)
+{
+ manager_kset = kset_create_and_add(GB_AUDIO_MANAGER_NAME, NULL,
+ kernel_kobj);
+ if (!manager_kset)
+ return -ENOMEM;
+
+#ifdef GB_AUDIO_MANAGER_SYSFS
+ gb_audio_manager_sysfs_init(&manager_kset->kobj);
+#endif
+
+ return 0;
+}
+
+static void __exit manager_exit(void)
+{
+ gb_audio_manager_remove_all();
+ kset_unregister(manager_kset);
+ ida_destroy(&module_id);
+}
+
+module_init(manager_init);
+module_exit(manager_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Svetlin Ankov <ankov_svetlin@projectara.com>");
diff --git a/drivers/staging/greybus/audio_manager.h b/drivers/staging/greybus/audio_manager.h
new file mode 100644
index 000000000000..c4ca09754a6a
--- /dev/null
+++ b/drivers/staging/greybus/audio_manager.h
@@ -0,0 +1,83 @@
+/*
+ * Greybus operations
+ *
+ * Copyright 2015-2016 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef _GB_AUDIO_MANAGER_H_
+#define _GB_AUDIO_MANAGER_H_
+
+#include <linux/kobject.h>
+#include <linux/list.h>
+
+#define GB_AUDIO_MANAGER_NAME "gb_audio_manager"
+#define GB_AUDIO_MANAGER_MODULE_NAME_LEN 64
+#define GB_AUDIO_MANAGER_MODULE_NAME_LEN_SSCANF "63"
+
+struct gb_audio_manager_module_descriptor {
+ char name[GB_AUDIO_MANAGER_MODULE_NAME_LEN];
+ int slot;
+ int vid;
+ int pid;
+ int cport;
+ unsigned int ip_devices;
+ unsigned int op_devices;
+};
+
+struct gb_audio_manager_module {
+ struct kobject kobj;
+ struct list_head list;
+ int id;
+ struct gb_audio_manager_module_descriptor desc;
+};
+
+/*
+ * Creates a new gb_audio_manager_module_descriptor, using the specified
+ * descriptor.
+ *
+ * Returns a negative result on error, or the id of the newly created module.
+ *
+ */
+int gb_audio_manager_add(struct gb_audio_manager_module_descriptor *desc);
+
+/*
+ * Removes a connected gb_audio_manager_module_descriptor for the specified ID.
+ *
+ * Returns zero on success, or a negative value on error.
+ */
+int gb_audio_manager_remove(int id);
+
+/*
+ * Removes all connected gb_audio_modules
+ *
+ * Returns zero on success, or a negative value on error.
+ */
+void gb_audio_manager_remove_all(void);
+
+/*
+ * Retrieves a gb_audio_manager_module_descriptor for the specified id.
+ * Returns the gb_audio_manager_module_descriptor structure,
+ * or NULL if there is no module with the specified ID.
+ */
+struct gb_audio_manager_module *gb_audio_manager_get_module(int id);
+
+/*
+ * Decreases the refcount of the module, obtained by the get function.
+ * Modules are removed via gb_audio_manager_remove
+ */
+void gb_audio_manager_put_module(struct gb_audio_manager_module *module);
+
+/*
+ * Dumps the module for the specified id
+ * Return 0 on success
+ */
+int gb_audio_manager_dump_module(int id);
+
+/*
+ * Dumps all connected modules
+ */
+void gb_audio_manager_dump_all(void);
+
+#endif /* _GB_AUDIO_MANAGER_H_ */
diff --git a/drivers/staging/greybus/audio_manager_module.c b/drivers/staging/greybus/audio_manager_module.c
new file mode 100644
index 000000000000..a10e96ad79c1
--- /dev/null
+++ b/drivers/staging/greybus/audio_manager_module.c
@@ -0,0 +1,258 @@
+/*
+ * Greybus operations
+ *
+ * Copyright 2015-2016 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/slab.h>
+
+#include "audio_manager.h"
+#include "audio_manager_private.h"
+
+#define to_gb_audio_module_attr(x) \
+ container_of(x, struct gb_audio_manager_module_attribute, attr)
+#define to_gb_audio_module(x) \
+ container_of(x, struct gb_audio_manager_module, kobj)
+
+struct gb_audio_manager_module_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct gb_audio_manager_module *module,
+ struct gb_audio_manager_module_attribute *attr,
+ char *buf);
+ ssize_t (*store)(struct gb_audio_manager_module *module,
+ struct gb_audio_manager_module_attribute *attr,
+ const char *buf, size_t count);
+};
+
+static ssize_t gb_audio_module_attr_show(
+ struct kobject *kobj, struct attribute *attr, char *buf)
+{
+ struct gb_audio_manager_module_attribute *attribute;
+ struct gb_audio_manager_module *module;
+
+ attribute = to_gb_audio_module_attr(attr);
+ module = to_gb_audio_module(kobj);
+
+ if (!attribute->show)
+ return -EIO;
+
+ return attribute->show(module, attribute, buf);
+}
+
+static ssize_t gb_audio_module_attr_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buf, size_t len)
+{
+ struct gb_audio_manager_module_attribute *attribute;
+ struct gb_audio_manager_module *module;
+
+ attribute = to_gb_audio_module_attr(attr);
+ module = to_gb_audio_module(kobj);
+
+ if (!attribute->store)
+ return -EIO;
+
+ return attribute->store(module, attribute, buf, len);
+}
+
+static const struct sysfs_ops gb_audio_module_sysfs_ops = {
+ .show = gb_audio_module_attr_show,
+ .store = gb_audio_module_attr_store,
+};
+
+static void gb_audio_module_release(struct kobject *kobj)
+{
+ struct gb_audio_manager_module *module = to_gb_audio_module(kobj);
+
+ pr_info("Destroying audio module #%d\n", module->id);
+ /* TODO -> delete from list */
+ kfree(module);
+}
+
+static ssize_t gb_audio_module_name_show(
+ struct gb_audio_manager_module *module,
+ struct gb_audio_manager_module_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s", module->desc.name);
+}
+
+static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute =
+ __ATTR(name, 0664, gb_audio_module_name_show, NULL);
+
+static ssize_t gb_audio_module_slot_show(
+ struct gb_audio_manager_module *module,
+ struct gb_audio_manager_module_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d", module->desc.slot);
+}
+
+static struct gb_audio_manager_module_attribute gb_audio_module_slot_attribute =
+ __ATTR(slot, 0664, gb_audio_module_slot_show, NULL);
+
+static ssize_t gb_audio_module_vid_show(
+ struct gb_audio_manager_module *module,
+ struct gb_audio_manager_module_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d", module->desc.vid);
+}
+
+static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute =
+ __ATTR(vid, 0664, gb_audio_module_vid_show, NULL);
+
+static ssize_t gb_audio_module_pid_show(
+ struct gb_audio_manager_module *module,
+ struct gb_audio_manager_module_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d", module->desc.pid);
+}
+
+static struct gb_audio_manager_module_attribute gb_audio_module_pid_attribute =
+ __ATTR(pid, 0664, gb_audio_module_pid_show, NULL);
+
+static ssize_t gb_audio_module_cport_show(
+ struct gb_audio_manager_module *module,
+ struct gb_audio_manager_module_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d", module->desc.cport);
+}
+
+static struct gb_audio_manager_module_attribute
+ gb_audio_module_cport_attribute =
+ __ATTR(cport, 0664, gb_audio_module_cport_show, NULL);
+
+static ssize_t gb_audio_module_ip_devices_show(
+ struct gb_audio_manager_module *module,
+ struct gb_audio_manager_module_attribute *attr, char *buf)
+{
+ return sprintf(buf, "0x%X", module->desc.ip_devices);
+}
+
+static struct gb_audio_manager_module_attribute
+ gb_audio_module_ip_devices_attribute =
+ __ATTR(ip_devices, 0664, gb_audio_module_ip_devices_show, NULL);
+
+static ssize_t gb_audio_module_op_devices_show(
+ struct gb_audio_manager_module *module,
+ struct gb_audio_manager_module_attribute *attr, char *buf)
+{
+ return sprintf(buf, "0x%X", module->desc.op_devices);
+}
+
+static struct gb_audio_manager_module_attribute
+ gb_audio_module_op_devices_attribute =
+ __ATTR(op_devices, 0664, gb_audio_module_op_devices_show, NULL);
+
+static struct attribute *gb_audio_module_default_attrs[] = {
+ &gb_audio_module_name_attribute.attr,
+ &gb_audio_module_slot_attribute.attr,
+ &gb_audio_module_vid_attribute.attr,
+ &gb_audio_module_pid_attribute.attr,
+ &gb_audio_module_cport_attribute.attr,
+ &gb_audio_module_ip_devices_attribute.attr,
+ &gb_audio_module_op_devices_attribute.attr,
+ NULL, /* need to NULL terminate the list of attributes */
+};
+
+static struct kobj_type gb_audio_module_type = {
+ .sysfs_ops = &gb_audio_module_sysfs_ops,
+ .release = gb_audio_module_release,
+ .default_attrs = gb_audio_module_default_attrs,
+};
+
+static void send_add_uevent(struct gb_audio_manager_module *module)
+{
+ char name_string[128];
+ char slot_string[64];
+ char vid_string[64];
+ char pid_string[64];
+ char cport_string[64];
+ char ip_devices_string[64];
+ char op_devices_string[64];
+
+ char *envp[] = {
+ name_string,
+ slot_string,
+ vid_string,
+ pid_string,
+ cport_string,
+ ip_devices_string,
+ op_devices_string,
+ NULL
+ };
+
+ snprintf(name_string, 128, "NAME=%s", module->desc.name);
+ snprintf(slot_string, 64, "SLOT=%d", module->desc.slot);
+ snprintf(vid_string, 64, "VID=%d", module->desc.vid);
+ snprintf(pid_string, 64, "PID=%d", module->desc.pid);
+ snprintf(cport_string, 64, "CPORT=%d", module->desc.cport);
+ snprintf(ip_devices_string, 64, "I/P DEVICES=0x%X",
+ module->desc.ip_devices);
+ snprintf(op_devices_string, 64, "O/P DEVICES=0x%X",
+ module->desc.op_devices);
+
+ kobject_uevent_env(&module->kobj, KOBJ_ADD, envp);
+}
+
+int gb_audio_manager_module_create(
+ struct gb_audio_manager_module **module,
+ struct kset *manager_kset,
+ int id, struct gb_audio_manager_module_descriptor *desc)
+{
+ int err;
+ struct gb_audio_manager_module *m;
+
+ m = kzalloc(sizeof(*m), GFP_ATOMIC);
+ if (!m)
+ return -ENOMEM;
+
+ /* Initialize the node */
+ INIT_LIST_HEAD(&m->list);
+
+ /* Set the module id */
+ m->id = id;
+
+ /* Copy the provided descriptor */
+ memcpy(&m->desc, desc, sizeof(*desc));
+
+ /* set the kset */
+ m->kobj.kset = manager_kset;
+
+ /*
+ * Initialize and add the kobject to the kernel. All the default files
+ * will be created here. As we have already specified a kset for this
+ * kobject, we don't have to set a parent for the kobject, the kobject
+ * will be placed beneath that kset automatically.
+ */
+ err = kobject_init_and_add(&m->kobj, &gb_audio_module_type, NULL, "%d",
+ id);
+ if (err) {
+ pr_err("failed initializing kobject for audio module #%d\n",
+ id);
+ kobject_put(&m->kobj);
+ return err;
+ }
+
+ /*
+ * Notify the object was created
+ */
+ send_add_uevent(m);
+
+ *module = m;
+ pr_info("Created audio module #%d\n", id);
+ return 0;
+}
+
+void gb_audio_manager_module_dump(struct gb_audio_manager_module *module)
+{
+ pr_info("audio module #%d name=%s slot=%d vid=%d pid=%d cport=%d i/p devices=0x%X o/p devices=0x%X\n",
+ module->id,
+ module->desc.name,
+ module->desc.slot,
+ module->desc.vid,
+ module->desc.pid,
+ module->desc.cport,
+ module->desc.ip_devices,
+ module->desc.op_devices);
+}
diff --git a/drivers/staging/greybus/audio_manager_private.h b/drivers/staging/greybus/audio_manager_private.h
new file mode 100644
index 000000000000..079ce953c256
--- /dev/null
+++ b/drivers/staging/greybus/audio_manager_private.h
@@ -0,0 +1,28 @@
+/*
+ * Greybus operations
+ *
+ * Copyright 2015-2016 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef _GB_AUDIO_MANAGER_PRIVATE_H_
+#define _GB_AUDIO_MANAGER_PRIVATE_H_
+
+#include <linux/kobject.h>
+
+#include "audio_manager.h"
+
+int gb_audio_manager_module_create(
+ struct gb_audio_manager_module **module,
+ struct kset *manager_kset,
+ int id, struct gb_audio_manager_module_descriptor *desc);
+
+/* module destroyed via kobject_put */
+
+void gb_audio_manager_module_dump(struct gb_audio_manager_module *module);
+
+/* sysfs control */
+void gb_audio_manager_sysfs_init(struct kobject *kobj);
+
+#endif /* _GB_AUDIO_MANAGER_PRIVATE_H_ */
diff --git a/drivers/staging/greybus/audio_manager_sysfs.c b/drivers/staging/greybus/audio_manager_sysfs.c
new file mode 100644
index 000000000000..d8bf8591ff9e
--- /dev/null
+++ b/drivers/staging/greybus/audio_manager_sysfs.c
@@ -0,0 +1,102 @@
+/*
+ * Greybus operations
+ *
+ * Copyright 2015-2016 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/string.h>
+#include <linux/sysfs.h>
+
+#include "audio_manager.h"
+#include "audio_manager_private.h"
+
+static ssize_t manager_sysfs_add_store(
+ struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct gb_audio_manager_module_descriptor desc = { {0} };
+
+ int num = sscanf(buf,
+ "name=%" GB_AUDIO_MANAGER_MODULE_NAME_LEN_SSCANF "s "
+ "slot=%d vid=%d pid=%d cport=%d i/p devices=0x%X"
+ "o/p devices=0x%X",
+ desc.name, &desc.slot, &desc.vid, &desc.pid,
+ &desc.cport, &desc.ip_devices, &desc.op_devices);
+
+ if (num != 7)
+ return -EINVAL;
+
+ num = gb_audio_manager_add(&desc);
+ if (num < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static struct kobj_attribute manager_add_attribute =
+ __ATTR(add, 0664, NULL, manager_sysfs_add_store);
+
+static ssize_t manager_sysfs_remove_store(
+ struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int id;
+
+ int num = sscanf(buf, "%d", &id);
+
+ if (num != 1)
+ return -EINVAL;
+
+ num = gb_audio_manager_remove(id);
+ if (num)
+ return num;
+
+ return count;
+}
+
+static struct kobj_attribute manager_remove_attribute =
+ __ATTR(remove, 0664, NULL, manager_sysfs_remove_store);
+
+static ssize_t manager_sysfs_dump_store(
+ struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int id;
+
+ int num = sscanf(buf, "%d", &id);
+
+ if (num == 1) {
+ num = gb_audio_manager_dump_module(id);
+ if (num)
+ return num;
+ } else if (!strncmp("all", buf, 3))
+ gb_audio_manager_dump_all();
+ else
+ return -EINVAL;
+
+ return count;
+}
+
+static struct kobj_attribute manager_dump_attribute =
+ __ATTR(dump, 0664, NULL, manager_sysfs_dump_store);
+
+static void manager_sysfs_init_attribute(
+ struct kobject *kobj, struct kobj_attribute *kattr)
+{
+ int err;
+
+ err = sysfs_create_file(kobj, &kattr->attr);
+ if (err) {
+ pr_warn("creating the sysfs entry for %s failed: %d\n",
+ kattr->attr.name, err);
+ }
+}
+
+void gb_audio_manager_sysfs_init(struct kobject *kobj)
+{
+ manager_sysfs_init_attribute(kobj, &manager_add_attribute);
+ manager_sysfs_init_attribute(kobj, &manager_remove_attribute);
+ manager_sysfs_init_attribute(kobj, &manager_dump_attribute);
+}
diff --git a/drivers/staging/greybus/audio_module.c b/drivers/staging/greybus/audio_module.c
new file mode 100644
index 000000000000..ae1c0fa85752
--- /dev/null
+++ b/drivers/staging/greybus/audio_module.c
@@ -0,0 +1,482 @@
+/*
+ * Greybus audio driver
+ * Copyright 2015 Google Inc.
+ * Copyright 2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+
+#include "audio_codec.h"
+#include "audio_apbridgea.h"
+#include "audio_manager.h"
+
+/*
+ * gb_snd management functions
+ */
+
+static int gbaudio_request_jack(struct gbaudio_module_info *module,
+ struct gb_audio_jack_event_request *req)
+{
+ int report;
+ struct snd_jack *jack = module->headset_jack.jack;
+ struct snd_jack *btn_jack = module->button_jack.jack;
+
+ if (!jack) {
+ dev_err_ratelimited(module->dev,
+ "Invalid jack event received:type: %u, event: %u\n",
+ req->jack_attribute, req->event);
+ return -EINVAL;
+ }
+
+ dev_warn_ratelimited(module->dev,
+ "Jack Event received: type: %u, event: %u\n",
+ req->jack_attribute, req->event);
+
+ if (req->event == GB_AUDIO_JACK_EVENT_REMOVAL) {
+ module->jack_type = 0;
+ if (btn_jack && module->button_status) {
+ snd_soc_jack_report(&module->button_jack, 0,
+ module->button_mask);
+ module->button_status = 0;
+ }
+ snd_soc_jack_report(&module->headset_jack, 0,
+ module->jack_mask);
+ return 0;
+ }
+
+ report = req->jack_attribute & module->jack_mask;
+ if (!report) {
+ dev_err_ratelimited(module->dev,
+ "Invalid jack event received:type: %u, event: %u\n",
+ req->jack_attribute, req->event);
+ return -EINVAL;
+ }
+
+ if (module->jack_type)
+ dev_warn_ratelimited(module->dev,
+ "Modifying jack from %d to %d\n",
+ module->jack_type, report);
+
+ module->jack_type = report;
+ snd_soc_jack_report(&module->headset_jack, report, module->jack_mask);
+
+ return 0;
+}
+
+static int gbaudio_request_button(struct gbaudio_module_info *module,
+ struct gb_audio_button_event_request *req)
+{
+ int soc_button_id, report;
+ struct snd_jack *btn_jack = module->button_jack.jack;
+
+ if (!btn_jack) {
+ dev_err_ratelimited(module->dev,
+ "Invalid button event received:type: %u, event: %u\n",
+ req->button_id, req->event);
+ return -EINVAL;
+ }
+
+ dev_warn_ratelimited(module->dev,
+ "Button Event received: id: %u, event: %u\n",
+ req->button_id, req->event);
+
+ /* currently supports 4 buttons only */
+ if (!module->jack_type) {
+ dev_err_ratelimited(module->dev,
+ "Jack not present. Bogus event!!\n");
+ return -EINVAL;
+ }
+
+ report = module->button_status & module->button_mask;
+ soc_button_id = 0;
+
+ switch (req->button_id) {
+ case 1:
+ soc_button_id = SND_JACK_BTN_0 & module->button_mask;
+ break;
+
+ case 2:
+ soc_button_id = SND_JACK_BTN_1 & module->button_mask;
+ break;
+
+ case 3:
+ soc_button_id = SND_JACK_BTN_2 & module->button_mask;
+ break;
+
+ case 4:
+ soc_button_id = SND_JACK_BTN_3 & module->button_mask;
+ break;
+ }
+
+ if (!soc_button_id) {
+ dev_err_ratelimited(module->dev,
+ "Invalid button request received\n");
+ return -EINVAL;
+ }
+
+ if (req->event == GB_AUDIO_BUTTON_EVENT_PRESS)
+ report = report | soc_button_id;
+ else
+ report = report & ~soc_button_id;
+
+ module->button_status = report;
+
+ snd_soc_jack_report(&module->button_jack, report, module->button_mask);
+
+ return 0;
+}
+
+static int gbaudio_request_stream(struct gbaudio_module_info *module,
+ struct gb_audio_streaming_event_request *req)
+{
+ dev_warn(module->dev, "Audio Event received: cport: %u, event: %u\n",
+ req->data_cport, req->event);
+
+ return 0;
+}
+
+static int gbaudio_codec_request_handler(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct gbaudio_module_info *module =
+ greybus_get_drvdata(connection->bundle);
+ struct gb_operation_msg_hdr *header = op->request->header;
+ struct gb_audio_streaming_event_request *stream_req;
+ struct gb_audio_jack_event_request *jack_req;
+ struct gb_audio_button_event_request *button_req;
+ int ret;
+
+ switch (header->type) {
+ case GB_AUDIO_TYPE_STREAMING_EVENT:
+ stream_req = op->request->payload;
+ ret = gbaudio_request_stream(module, stream_req);
+ break;
+
+ case GB_AUDIO_TYPE_JACK_EVENT:
+ jack_req = op->request->payload;
+ ret = gbaudio_request_jack(module, jack_req);
+ break;
+
+ case GB_AUDIO_TYPE_BUTTON_EVENT:
+ button_req = op->request->payload;
+ ret = gbaudio_request_button(module, button_req);
+ break;
+
+ default:
+ dev_err_ratelimited(&connection->bundle->dev,
+ "Invalid Audio Event received\n");
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int gb_audio_add_mgmt_connection(struct gbaudio_module_info *gbmodule,
+ struct greybus_descriptor_cport *cport_desc,
+ struct gb_bundle *bundle)
+{
+ struct gb_connection *connection;
+
+ /* Management Cport */
+ if (gbmodule->mgmt_connection) {
+ dev_err(&bundle->dev,
+ "Can't have multiple Management connections\n");
+ return -ENODEV;
+ }
+
+ connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
+ gbaudio_codec_request_handler);
+ if (IS_ERR(connection))
+ return PTR_ERR(connection);
+
+ greybus_set_drvdata(bundle, gbmodule);
+ gbmodule->mgmt_connection = connection;
+
+ return 0;
+}
+
+static int gb_audio_add_data_connection(struct gbaudio_module_info *gbmodule,
+ struct greybus_descriptor_cport *cport_desc,
+ struct gb_bundle *bundle)
+{
+ struct gb_connection *connection;
+ struct gbaudio_data_connection *dai;
+
+ dai = devm_kzalloc(gbmodule->dev, sizeof(*dai), GFP_KERNEL);
+ if (!dai) {
+ dev_err(gbmodule->dev, "DAI Malloc failure\n");
+ return -ENOMEM;
+ }
+
+ connection = gb_connection_create_offloaded(bundle,
+ le16_to_cpu(cport_desc->id),
+ GB_CONNECTION_FLAG_CSD);
+ if (IS_ERR(connection)) {
+ devm_kfree(gbmodule->dev, dai);
+ return PTR_ERR(connection);
+ }
+
+ greybus_set_drvdata(bundle, gbmodule);
+ dai->id = 0;
+ dai->data_cport = connection->intf_cport_id;
+ dai->connection = connection;
+ list_add(&dai->list, &gbmodule->data_list);
+
+ return 0;
+}
+
+/*
+ * This is the basic hook get things initialized and registered w/ gb
+ */
+
+static int gb_audio_probe(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id)
+{
+ struct device *dev = &bundle->dev;
+ struct gbaudio_module_info *gbmodule;
+ struct greybus_descriptor_cport *cport_desc;
+ struct gb_audio_manager_module_descriptor desc;
+ struct gbaudio_data_connection *dai, *_dai;
+ int ret, i;
+ struct gb_audio_topology *topology;
+
+ /* There should be at least one Management and one Data cport */
+ if (bundle->num_cports < 2)
+ return -ENODEV;
+
+ /*
+ * There can be only one Management connection and any number of data
+ * connections.
+ */
+ gbmodule = devm_kzalloc(dev, sizeof(*gbmodule), GFP_KERNEL);
+ if (!gbmodule)
+ return -ENOMEM;
+
+ gbmodule->num_data_connections = bundle->num_cports - 1;
+ INIT_LIST_HEAD(&gbmodule->data_list);
+ INIT_LIST_HEAD(&gbmodule->widget_list);
+ INIT_LIST_HEAD(&gbmodule->ctl_list);
+ INIT_LIST_HEAD(&gbmodule->widget_ctl_list);
+ gbmodule->dev = dev;
+ snprintf(gbmodule->name, NAME_SIZE, "%s.%s", dev->driver->name,
+ dev_name(dev));
+ greybus_set_drvdata(bundle, gbmodule);
+
+ /* Create all connections */
+ for (i = 0; i < bundle->num_cports; i++) {
+ cport_desc = &bundle->cport_desc[i];
+
+ switch (cport_desc->protocol_id) {
+ case GREYBUS_PROTOCOL_AUDIO_MGMT:
+ ret = gb_audio_add_mgmt_connection(gbmodule, cport_desc,
+ bundle);
+ if (ret)
+ goto destroy_connections;
+ break;
+ case GREYBUS_PROTOCOL_AUDIO_DATA:
+ ret = gb_audio_add_data_connection(gbmodule, cport_desc,
+ bundle);
+ if (ret)
+ goto destroy_connections;
+ break;
+ default:
+ dev_err(dev, "Unsupported protocol: 0x%02x\n",
+ cport_desc->protocol_id);
+ ret = -ENODEV;
+ goto destroy_connections;
+ }
+ }
+
+ /* There must be a management cport */
+ if (!gbmodule->mgmt_connection) {
+ ret = -EINVAL;
+ dev_err(dev, "Missing management connection\n");
+ goto destroy_connections;
+ }
+
+ /* Initialize management connection */
+ ret = gb_connection_enable(gbmodule->mgmt_connection);
+ if (ret) {
+ dev_err(dev, "%d: Error while enabling mgmt connection\n", ret);
+ goto destroy_connections;
+ }
+ gbmodule->dev_id = gbmodule->mgmt_connection->intf->interface_id;
+
+ /*
+ * FIXME: malloc for topology happens via audio_gb driver
+ * should be done within codec driver itself
+ */
+ ret = gb_audio_gb_get_topology(gbmodule->mgmt_connection, &topology);
+ if (ret) {
+ dev_err(dev, "%d:Error while fetching topology\n", ret);
+ goto disable_connection;
+ }
+
+ /* process topology data */
+ ret = gbaudio_tplg_parse_data(gbmodule, topology);
+ if (ret) {
+ dev_err(dev, "%d:Error while parsing topology data\n",
+ ret);
+ goto free_topology;
+ }
+ gbmodule->topology = topology;
+
+ /* Initialize data connections */
+ list_for_each_entry(dai, &gbmodule->data_list, list) {
+ ret = gb_connection_enable(dai->connection);
+ if (ret) {
+ dev_err(dev,
+ "%d:Error while enabling %d:data connection\n",
+ ret, dai->data_cport);
+ goto disable_data_connection;
+ }
+ }
+
+ /* register module with gbcodec */
+ ret = gbaudio_register_module(gbmodule);
+ if (ret)
+ goto disable_data_connection;
+
+ /* inform above layer for uevent */
+ dev_dbg(dev, "Inform set_event:%d to above layer\n", 1);
+ /* prepare for the audio manager */
+ strlcpy(desc.name, gbmodule->name, GB_AUDIO_MANAGER_MODULE_NAME_LEN);
+ desc.slot = 1; /* todo */
+ desc.vid = 2; /* todo */
+ desc.pid = 3; /* todo */
+ desc.cport = gbmodule->dev_id;
+ desc.op_devices = gbmodule->op_devices;
+ desc.ip_devices = gbmodule->ip_devices;
+ gbmodule->manager_id = gb_audio_manager_add(&desc);
+
+ dev_dbg(dev, "Add GB Audio device:%s\n", gbmodule->name);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return 0;
+
+disable_data_connection:
+ list_for_each_entry_safe(dai, _dai, &gbmodule->data_list, list)
+ gb_connection_disable(dai->connection);
+ gbaudio_tplg_release(gbmodule);
+ gbmodule->topology = NULL;
+
+free_topology:
+ kfree(topology);
+
+disable_connection:
+ gb_connection_disable(gbmodule->mgmt_connection);
+
+destroy_connections:
+ list_for_each_entry_safe(dai, _dai, &gbmodule->data_list, list) {
+ gb_connection_destroy(dai->connection);
+ list_del(&dai->list);
+ devm_kfree(dev, dai);
+ }
+
+ if (gbmodule->mgmt_connection)
+ gb_connection_destroy(gbmodule->mgmt_connection);
+
+ devm_kfree(dev, gbmodule);
+
+ return ret;
+}
+
+static void gb_audio_disconnect(struct gb_bundle *bundle)
+{
+ struct gbaudio_module_info *gbmodule = greybus_get_drvdata(bundle);
+ struct gbaudio_data_connection *dai, *_dai;
+
+ gb_pm_runtime_get_sync(bundle);
+
+ /* cleanup module related resources first */
+ gbaudio_unregister_module(gbmodule);
+
+ /* inform uevent to above layers */
+ gb_audio_manager_remove(gbmodule->manager_id);
+
+ gbaudio_tplg_release(gbmodule);
+ kfree(gbmodule->topology);
+ gbmodule->topology = NULL;
+ gb_connection_disable(gbmodule->mgmt_connection);
+ list_for_each_entry_safe(dai, _dai, &gbmodule->data_list, list) {
+ gb_connection_disable(dai->connection);
+ gb_connection_destroy(dai->connection);
+ list_del(&dai->list);
+ devm_kfree(gbmodule->dev, dai);
+ }
+ gb_connection_destroy(gbmodule->mgmt_connection);
+ gbmodule->mgmt_connection = NULL;
+
+ devm_kfree(&bundle->dev, gbmodule);
+}
+
+static const struct greybus_bundle_id gb_audio_id_table[] = {
+ { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_AUDIO) },
+ { }
+};
+MODULE_DEVICE_TABLE(greybus, gb_audio_id_table);
+
+#ifdef CONFIG_PM
+static int gb_audio_suspend(struct device *dev)
+{
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+ struct gbaudio_module_info *gbmodule = greybus_get_drvdata(bundle);
+ struct gbaudio_data_connection *dai;
+
+ list_for_each_entry(dai, &gbmodule->data_list, list)
+ gb_connection_disable(dai->connection);
+
+ gb_connection_disable(gbmodule->mgmt_connection);
+
+ return 0;
+}
+
+static int gb_audio_resume(struct device *dev)
+{
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+ struct gbaudio_module_info *gbmodule = greybus_get_drvdata(bundle);
+ struct gbaudio_data_connection *dai;
+ int ret;
+
+ ret = gb_connection_enable(gbmodule->mgmt_connection);
+ if (ret) {
+ dev_err(dev, "%d:Error while enabling mgmt connection\n", ret);
+ return ret;
+ }
+
+ list_for_each_entry(dai, &gbmodule->data_list, list) {
+ ret = gb_connection_enable(dai->connection);
+ if (ret) {
+ dev_err(dev,
+ "%d:Error while enabling %d:data connection\n",
+ ret, dai->data_cport);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops gb_audio_pm_ops = {
+ SET_RUNTIME_PM_OPS(gb_audio_suspend, gb_audio_resume, NULL)
+};
+
+static struct greybus_driver gb_audio_driver = {
+ .name = "gb-audio",
+ .probe = gb_audio_probe,
+ .disconnect = gb_audio_disconnect,
+ .id_table = gb_audio_id_table,
+ .driver.pm = &gb_audio_pm_ops,
+};
+module_greybus_driver(gb_audio_driver);
+
+MODULE_DESCRIPTION("Greybus Audio module driver");
+MODULE_AUTHOR("Vaibhav Agarwal <vaibhav.agarwal@linaro.org>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:gbaudio-module");
diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c
new file mode 100644
index 000000000000..b6251691a33d
--- /dev/null
+++ b/drivers/staging/greybus/audio_topology.c
@@ -0,0 +1,1443 @@
+/*
+ * Greybus audio driver
+ * Copyright 2015-2016 Google Inc.
+ * Copyright 2015-2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include "audio_codec.h"
+#include "greybus_protocols.h"
+
+#define GBAUDIO_INVALID_ID 0xFF
+
+/* mixer control */
+struct gb_mixer_control {
+ int min, max;
+ unsigned int reg, rreg, shift, rshift, invert;
+};
+
+struct gbaudio_ctl_pvt {
+ unsigned int ctl_id;
+ unsigned int data_cport;
+ unsigned int access;
+ unsigned int vcount;
+ struct gb_audio_ctl_elem_info *info;
+};
+
+static struct gbaudio_module_info *find_gb_module(
+ struct gbaudio_codec_info *codec,
+ char const *name)
+{
+ int dev_id, ret;
+ char begin[NAME_SIZE];
+ struct gbaudio_module_info *module;
+
+ if (!name)
+ return NULL;
+
+ ret = sscanf(name, "%s %d", begin, &dev_id);
+ dev_dbg(codec->dev, "%s:Find module#%d\n", __func__, dev_id);
+
+ mutex_lock(&codec->lock);
+ list_for_each_entry(module, &codec->module_list, list) {
+ if (module->dev_id == dev_id) {
+ mutex_unlock(&codec->lock);
+ return module;
+ }
+ }
+ mutex_unlock(&codec->lock);
+ dev_warn(codec->dev, "%s: module#%d missing in codec list\n", name,
+ dev_id);
+ return NULL;
+}
+
+static const char *gbaudio_map_controlid(struct gbaudio_module_info *module,
+ __u8 control_id, __u8 index)
+{
+ struct gbaudio_control *control;
+
+ if (control_id == GBAUDIO_INVALID_ID)
+ return NULL;
+
+ list_for_each_entry(control, &module->ctl_list, list) {
+ if (control->id == control_id) {
+ if (index == GBAUDIO_INVALID_ID)
+ return control->name;
+ if (index >= control->items)
+ return NULL;
+ return control->texts[index];
+ }
+ }
+ list_for_each_entry(control, &module->widget_ctl_list, list) {
+ if (control->id == control_id) {
+ if (index == GBAUDIO_INVALID_ID)
+ return control->name;
+ if (index >= control->items)
+ return NULL;
+ return control->texts[index];
+ }
+ }
+ return NULL;
+}
+
+static int gbaudio_map_controlname(struct gbaudio_module_info *module,
+ const char *name)
+{
+ struct gbaudio_control *control;
+
+ list_for_each_entry(control, &module->ctl_list, list) {
+ if (!strncmp(control->name, name, NAME_SIZE))
+ return control->id;
+ }
+
+ dev_warn(module->dev, "%s: missing in modules controls list\n", name);
+
+ return -EINVAL;
+}
+
+static int gbaudio_map_wcontrolname(struct gbaudio_module_info *module,
+ const char *name)
+{
+ struct gbaudio_control *control;
+
+ list_for_each_entry(control, &module->widget_ctl_list, list) {
+ if (!strncmp(control->wname, name, NAME_SIZE))
+ return control->id;
+ }
+ dev_warn(module->dev, "%s: missing in modules controls list\n", name);
+
+ return -EINVAL;
+}
+
+static int gbaudio_map_widgetname(struct gbaudio_module_info *module,
+ const char *name)
+{
+ struct gbaudio_widget *widget;
+ list_for_each_entry(widget, &module->widget_list, list) {
+ if (!strncmp(widget->name, name, NAME_SIZE))
+ return widget->id;
+ }
+ dev_warn(module->dev, "%s: missing in modules widgets list\n", name);
+
+ return -EINVAL;
+}
+
+static const char *gbaudio_map_widgetid(struct gbaudio_module_info *module,
+ __u8 widget_id)
+{
+ struct gbaudio_widget *widget;
+
+ list_for_each_entry(widget, &module->widget_list, list) {
+ if (widget->id == widget_id)
+ return widget->name;
+ }
+ return NULL;
+}
+
+static const char **gb_generate_enum_strings(struct gbaudio_module_info *gb,
+ struct gb_audio_enumerated *gbenum)
+{
+ const char **strings;
+ int i;
+ __u8 *data;
+
+ strings = devm_kzalloc(gb->dev, sizeof(char *) * gbenum->items,
+ GFP_KERNEL);
+ data = gbenum->names;
+
+ for (i = 0; i < gbenum->items; i++) {
+ strings[i] = (const char *)data;
+ while (*data != '\0')
+ data++;
+ data++;
+ }
+
+ return strings;
+}
+
+static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ unsigned int max;
+ const char *name;
+ struct gbaudio_ctl_pvt *data;
+ struct gb_audio_ctl_elem_info *info;
+ struct gbaudio_module_info *module;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct gbaudio_codec_info *gbcodec = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
+ data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
+ info = (struct gb_audio_ctl_elem_info *)data->info;
+
+ if (!info) {
+ dev_err(codec->dev, "NULL info for %s\n", uinfo->id.name);
+ return -EINVAL;
+ }
+
+ /* update uinfo */
+ uinfo->access = data->access;
+ uinfo->count = data->vcount;
+ uinfo->type = (snd_ctl_elem_type_t)info->type;
+
+ switch (info->type) {
+ case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
+ case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
+ uinfo->value.integer.min = info->value.integer.min;
+ uinfo->value.integer.max = info->value.integer.max;
+ break;
+ case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
+ max = info->value.enumerated.items;
+ uinfo->value.enumerated.items = max;
+ if (uinfo->value.enumerated.item > max - 1)
+ uinfo->value.enumerated.item = max - 1;
+ module = find_gb_module(gbcodec, kcontrol->id.name);
+ if (!module)
+ return -EINVAL;
+ name = gbaudio_map_controlid(module, data->ctl_id,
+ uinfo->value.enumerated.item);
+ strlcpy(uinfo->value.enumerated.name, name, NAME_SIZE);
+ break;
+ default:
+ dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
+ info->type, kcontrol->id.name);
+ break;
+ }
+ return 0;
+}
+
+static int gbcodec_mixer_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret;
+ struct gb_audio_ctl_elem_info *info;
+ struct gbaudio_ctl_pvt *data;
+ struct gb_audio_ctl_elem_value gbvalue;
+ struct gbaudio_module_info *module;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+ struct gb_bundle *bundle;
+
+ dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
+ module = find_gb_module(gb, kcontrol->id.name);
+ if (!module)
+ return -EINVAL;
+
+ data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
+ info = (struct gb_audio_ctl_elem_info *)data->info;
+ bundle = to_gb_bundle(module->dev);
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ return ret;
+
+ ret = gb_audio_gb_get_control(module->mgmt_connection, data->ctl_id,
+ GB_AUDIO_INVALID_INDEX, &gbvalue);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ if (ret) {
+ dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
+ __func__, kcontrol->id.name);
+ return ret;
+ }
+
+ /* update ucontrol */
+ switch (info->type) {
+ case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
+ case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
+ ucontrol->value.integer.value[0] =
+ gbvalue.value.integer_value[0];
+ if (data->vcount == 2)
+ ucontrol->value.integer.value[1] =
+ gbvalue.value.integer_value[1];
+ break;
+ case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
+ ucontrol->value.enumerated.item[0] =
+ gbvalue.value.enumerated_item[0];
+ if (data->vcount == 2)
+ ucontrol->value.enumerated.item[1] =
+ gbvalue.value.enumerated_item[1];
+ break;
+ default:
+ dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
+ info->type, kcontrol->id.name);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret = 0;
+ struct gb_audio_ctl_elem_info *info;
+ struct gbaudio_ctl_pvt *data;
+ struct gb_audio_ctl_elem_value gbvalue;
+ struct gbaudio_module_info *module;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+ struct gb_bundle *bundle;
+
+ dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
+ module = find_gb_module(gb, kcontrol->id.name);
+ if (!module)
+ return -EINVAL;
+
+ data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
+ info = (struct gb_audio_ctl_elem_info *)data->info;
+ bundle = to_gb_bundle(module->dev);
+
+ /* update ucontrol */
+ switch (info->type) {
+ case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
+ case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
+ gbvalue.value.integer_value[0] =
+ ucontrol->value.integer.value[0];
+ if (data->vcount == 2)
+ gbvalue.value.integer_value[1] =
+ ucontrol->value.integer.value[1];
+ break;
+ case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
+ gbvalue.value.enumerated_item[0] =
+ ucontrol->value.enumerated.item[0];
+ if (data->vcount == 2)
+ gbvalue.value.enumerated_item[1] =
+ ucontrol->value.enumerated.item[1];
+ break;
+ default:
+ dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
+ info->type, kcontrol->id.name);
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret)
+ return ret;
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ return ret;
+
+ ret = gb_audio_gb_set_control(module->mgmt_connection, data->ctl_id,
+ GB_AUDIO_INVALID_INDEX, &gbvalue);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ if (ret) {
+ dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
+ __func__, kcontrol->id.name);
+ }
+
+ return ret;
+}
+
+#define SOC_MIXER_GB(xname, kcount, data) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .count = kcount, .info = gbcodec_mixer_ctl_info, \
+ .get = gbcodec_mixer_ctl_get, .put = gbcodec_mixer_ctl_put, \
+ .private_value = (unsigned long)data }
+
+/*
+ * although below callback functions seems redundant to above functions.
+ * same are kept to allow provision for different handling in case
+ * of DAPM related sequencing, etc.
+ */
+static int gbcodec_mixer_dapm_ctl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ int platform_max, platform_min;
+ struct gbaudio_ctl_pvt *data;
+ struct gb_audio_ctl_elem_info *info;
+ struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+ struct snd_soc_codec *codec = widget->codec;
+
+ dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
+ data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
+ info = (struct gb_audio_ctl_elem_info *)data->info;
+
+ /* update uinfo */
+ platform_max = info->value.integer.max;
+ platform_min = info->value.integer.min;
+
+ if (platform_max == 1 &&
+ !strnstr(kcontrol->id.name, " Volume", NAME_SIZE))
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ else
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+
+ uinfo->count = data->vcount;
+ uinfo->value.integer.min = 0;
+ if (info->value.integer.min < 0 &&
+ (uinfo->type == SNDRV_CTL_ELEM_TYPE_INTEGER))
+ uinfo->value.integer.max = platform_max - platform_min;
+ else
+ uinfo->value.integer.max = platform_max;
+
+ return 0;
+}
+
+static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret;
+ struct gb_audio_ctl_elem_info *info;
+ struct gbaudio_ctl_pvt *data;
+ struct gb_audio_ctl_elem_value gbvalue;
+ struct gbaudio_module_info *module;
+ struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+ struct snd_soc_codec *codec = widget->codec;
+ struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+ struct gb_bundle *bundle;
+
+ dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
+ module = find_gb_module(gb, kcontrol->id.name);
+ if (!module)
+ return -EINVAL;
+
+ data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
+ info = (struct gb_audio_ctl_elem_info *)data->info;
+ bundle = to_gb_bundle(module->dev);
+
+ if (data->vcount == 2)
+ dev_warn(widget->dapm->dev,
+ "GB: Control '%s' is stereo, which is not supported\n",
+ kcontrol->id.name);
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ return ret;
+
+ ret = gb_audio_gb_get_control(module->mgmt_connection, data->ctl_id,
+ GB_AUDIO_INVALID_INDEX, &gbvalue);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ if (ret) {
+ dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
+ __func__, kcontrol->id.name);
+ return ret;
+ }
+ /* update ucontrol */
+ ucontrol->value.integer.value[0] = gbvalue.value.integer_value[0];
+
+ return ret;
+}
+
+static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret, wi, max, connect;
+ unsigned int mask, val;
+ struct gb_audio_ctl_elem_info *info;
+ struct gbaudio_ctl_pvt *data;
+ struct gb_audio_ctl_elem_value gbvalue;
+ struct gbaudio_module_info *module;
+ struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+ struct snd_soc_codec *codec = widget->codec;
+ struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+ struct gb_bundle *bundle;
+
+ dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
+ module = find_gb_module(gb, kcontrol->id.name);
+ if (!module)
+ return -EINVAL;
+
+ data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
+ info = (struct gb_audio_ctl_elem_info *)data->info;
+ bundle = to_gb_bundle(module->dev);
+
+ if (data->vcount == 2)
+ dev_warn(widget->dapm->dev,
+ "GB: Control '%s' is stereo, which is not supported\n",
+ kcontrol->id.name);
+
+ max = info->value.integer.max;
+ mask = (1 << fls(max)) - 1;
+ val = ucontrol->value.integer.value[0] & mask;
+ connect = !!val;
+
+ /* update ucontrol */
+ if (gbvalue.value.integer_value[0] != val) {
+ for (wi = 0; wi < wlist->num_widgets; wi++) {
+ widget = wlist->widgets[wi];
+
+ widget->value = val;
+ widget->dapm->update = NULL;
+ snd_soc_dapm_mixer_update_power(widget, kcontrol,
+ connect);
+ }
+ gbvalue.value.integer_value[0] =
+ ucontrol->value.integer.value[0];
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ return ret;
+
+ ret = gb_audio_gb_set_control(module->mgmt_connection,
+ data->ctl_id,
+ GB_AUDIO_INVALID_INDEX, &gbvalue);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ if (ret) {
+ dev_err_ratelimited(codec->dev,
+ "%d:Error in %s for %s\n", ret,
+ __func__, kcontrol->id.name);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+#define SOC_DAPM_MIXER_GB(xname, kcount, data) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .count = kcount, .info = gbcodec_mixer_dapm_ctl_info, \
+ .get = gbcodec_mixer_dapm_ctl_get, .put = gbcodec_mixer_dapm_ctl_put, \
+ .private_value = (unsigned long)data}
+
+static int gbcodec_event_spk(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ /* Ensure GB speaker is connected */
+
+ return 0;
+}
+
+static int gbcodec_event_hp(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ /* Ensure GB module supports jack slot */
+
+ return 0;
+}
+
+static int gbcodec_event_int_mic(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ /* Ensure GB module supports jack slot */
+
+ return 0;
+}
+
+static int gbaudio_validate_kcontrol_count(struct gb_audio_widget *w)
+{
+ int ret = 0;
+
+ switch (w->type) {
+ case snd_soc_dapm_spk:
+ case snd_soc_dapm_hp:
+ case snd_soc_dapm_mic:
+ case snd_soc_dapm_output:
+ case snd_soc_dapm_input:
+ if (w->ncontrols)
+ ret = -EINVAL;
+ break;
+ case snd_soc_dapm_switch:
+ case snd_soc_dapm_mux:
+ if (w->ncontrols != 1)
+ ret = -EINVAL;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret, ctl_id;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ struct gb_audio_ctl_elem_value gbvalue;
+ struct gbaudio_module_info *module;
+ struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+ struct gb_bundle *bundle;
+
+ module = find_gb_module(gb, kcontrol->id.name);
+ if (!module)
+ return -EINVAL;
+
+ ctl_id = gbaudio_map_controlname(module, kcontrol->id.name);
+ if (ctl_id < 0)
+ return -EINVAL;
+
+ bundle = to_gb_bundle(module->dev);
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ return ret;
+
+ ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
+ GB_AUDIO_INVALID_INDEX, &gbvalue);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ if (ret) {
+ dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
+ __func__, kcontrol->id.name);
+ return ret;
+ }
+
+ ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0];
+ if (e->shift_l != e->shift_r)
+ ucontrol->value.enumerated.item[1] =
+ gbvalue.value.enumerated_item[1];
+
+ return 0;
+}
+
+static int gbcodec_enum_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret, ctl_id;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ struct gb_audio_ctl_elem_value gbvalue;
+ struct gbaudio_module_info *module;
+ struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+ struct gb_bundle *bundle;
+
+ module = find_gb_module(gb, kcontrol->id.name);
+ if (!module)
+ return -EINVAL;
+
+ ctl_id = gbaudio_map_controlname(module, kcontrol->id.name);
+ if (ctl_id < 0)
+ return -EINVAL;
+
+ if (ucontrol->value.enumerated.item[0] > e->max - 1)
+ return -EINVAL;
+ gbvalue.value.enumerated_item[0] = ucontrol->value.enumerated.item[0];
+
+ if (e->shift_l != e->shift_r) {
+ if (ucontrol->value.enumerated.item[1] > e->max - 1)
+ return -EINVAL;
+ gbvalue.value.enumerated_item[1] =
+ ucontrol->value.enumerated.item[1];
+ }
+
+ bundle = to_gb_bundle(module->dev);
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ return ret;
+
+ ret = gb_audio_gb_set_control(module->mgmt_connection, ctl_id,
+ GB_AUDIO_INVALID_INDEX, &gbvalue);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ if (ret) {
+ dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
+ __func__, kcontrol->id.name);
+ }
+
+ return ret;
+}
+
+static int gbaudio_tplg_create_enum_kctl(struct gbaudio_module_info *gb,
+ struct snd_kcontrol_new *kctl,
+ struct gb_audio_control *ctl)
+{
+ struct soc_enum *gbe;
+ struct gb_audio_enumerated *gb_enum;
+ int i;
+
+ gbe = devm_kzalloc(gb->dev, sizeof(*gbe), GFP_KERNEL);
+ if (!gbe)
+ return -ENOMEM;
+
+ gb_enum = &ctl->info.value.enumerated;
+
+ /* since count=1, and reg is dummy */
+ gbe->max = gb_enum->items;
+ gbe->texts = gb_generate_enum_strings(gb, gb_enum);
+
+ /* debug enum info */
+ dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items,
+ gb_enum->names_length);
+ for (i = 0; i < gb_enum->items; i++)
+ dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
+
+ *kctl = (struct snd_kcontrol_new)
+ SOC_ENUM_EXT(ctl->name, *gbe, gbcodec_enum_ctl_get,
+ gbcodec_enum_ctl_put);
+ return 0;
+}
+
+static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb,
+ struct snd_kcontrol_new *kctl,
+ struct gb_audio_control *ctl)
+{
+ int ret = 0;
+ struct gbaudio_ctl_pvt *ctldata;
+
+ switch (ctl->iface) {
+ case SNDRV_CTL_ELEM_IFACE_MIXER:
+ switch (ctl->info.type) {
+ case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
+ ret = gbaudio_tplg_create_enum_kctl(gb, kctl, ctl);
+ break;
+ default:
+ ctldata = devm_kzalloc(gb->dev,
+ sizeof(struct gbaudio_ctl_pvt),
+ GFP_KERNEL);
+ if (!ctldata)
+ return -ENOMEM;
+ ctldata->ctl_id = ctl->id;
+ ctldata->data_cport = ctl->data_cport;
+ ctldata->access = ctl->access;
+ ctldata->vcount = ctl->count_values;
+ ctldata->info = &ctl->info;
+ *kctl = (struct snd_kcontrol_new)
+ SOC_MIXER_GB(ctl->name, ctl->count, ctldata);
+ ctldata = NULL;
+ break;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ dev_dbg(gb->dev, "%s:%d control created\n", ctl->name, ctl->id);
+ return ret;
+}
+
+static int gbcodec_enum_dapm_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret, ctl_id;
+ struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+ struct gbaudio_module_info *module;
+ struct gb_audio_ctl_elem_value gbvalue;
+ struct snd_soc_codec *codec = widget->codec;
+ struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ struct gb_bundle *bundle;
+
+ module = find_gb_module(gb, kcontrol->id.name);
+ if (!module)
+ return -EINVAL;
+
+ ctl_id = gbaudio_map_wcontrolname(module, kcontrol->id.name);
+ if (ctl_id < 0)
+ return -EINVAL;
+
+ bundle = to_gb_bundle(module->dev);
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ return ret;
+
+ ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
+ GB_AUDIO_INVALID_INDEX, &gbvalue);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ if (ret) {
+ dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
+ __func__, kcontrol->id.name);
+ return ret;
+ }
+
+ ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0];
+ if (e->shift_l != e->shift_r)
+ ucontrol->value.enumerated.item[1] =
+ gbvalue.value.enumerated_item[1];
+
+ return 0;
+}
+
+static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret, wi, ctl_id;
+ unsigned int val, mux, change;
+ unsigned int mask;
+ struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+ struct gb_audio_ctl_elem_value gbvalue;
+ struct gbaudio_module_info *module;
+ struct snd_soc_codec *codec = widget->codec;
+ struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ struct gb_bundle *bundle;
+
+ if (ucontrol->value.enumerated.item[0] > e->max - 1)
+ return -EINVAL;
+
+ module = find_gb_module(gb, kcontrol->id.name);
+ if (!module)
+ return -EINVAL;
+
+ ctl_id = gbaudio_map_wcontrolname(module, kcontrol->id.name);
+ if (ctl_id < 0)
+ return -EINVAL;
+
+ change = 0;
+ bundle = to_gb_bundle(module->dev);
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ return ret;
+
+ ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
+ GB_AUDIO_INVALID_INDEX, &gbvalue);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ if (ret) {
+ dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
+ __func__, kcontrol->id.name);
+ return ret;
+ }
+
+ mux = ucontrol->value.enumerated.item[0];
+ val = mux << e->shift_l;
+ mask = e->mask << e->shift_l;
+
+ if (gbvalue.value.enumerated_item[0] !=
+ ucontrol->value.enumerated.item[0]) {
+ change = 1;
+ gbvalue.value.enumerated_item[0] =
+ ucontrol->value.enumerated.item[0];
+ }
+
+ if (e->shift_l != e->shift_r) {
+ if (ucontrol->value.enumerated.item[1] > e->max - 1)
+ return -EINVAL;
+ val |= ucontrol->value.enumerated.item[1] << e->shift_r;
+ mask |= e->mask << e->shift_r;
+ if (gbvalue.value.enumerated_item[1] !=
+ ucontrol->value.enumerated.item[1]) {
+ change = 1;
+ gbvalue.value.enumerated_item[1] =
+ ucontrol->value.enumerated.item[1];
+ }
+ }
+
+ if (change) {
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ return ret;
+
+ ret = gb_audio_gb_set_control(module->mgmt_connection, ctl_id,
+ GB_AUDIO_INVALID_INDEX, &gbvalue);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ if (ret) {
+ dev_err_ratelimited(codec->dev,
+ "%d:Error in %s for %s\n", ret,
+ __func__, kcontrol->id.name);
+ }
+ for (wi = 0; wi < wlist->num_widgets; wi++) {
+ widget = wlist->widgets[wi];
+
+ widget->value = val;
+ widget->dapm->update = NULL;
+ snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);
+ }
+ }
+
+ return change;
+}
+
+static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb,
+ struct snd_kcontrol_new *kctl,
+ struct gb_audio_control *ctl)
+{
+ struct soc_enum *gbe;
+ struct gb_audio_enumerated *gb_enum;
+ int i;
+
+ gbe = devm_kzalloc(gb->dev, sizeof(*gbe), GFP_KERNEL);
+ if (!gbe)
+ return -ENOMEM;
+
+ gb_enum = &ctl->info.value.enumerated;
+
+ /* since count=1, and reg is dummy */
+ gbe->max = gb_enum->items;
+ gbe->texts = gb_generate_enum_strings(gb, gb_enum);
+
+ /* debug enum info */
+ dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items,
+ gb_enum->names_length);
+ for (i = 0; i < gb_enum->items; i++)
+ dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
+
+ *kctl = (struct snd_kcontrol_new)
+ SOC_DAPM_ENUM_EXT(ctl->name, *gbe, gbcodec_enum_dapm_ctl_get,
+ gbcodec_enum_dapm_ctl_put);
+ return 0;
+}
+
+static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb,
+ struct snd_kcontrol_new *kctl,
+ struct gb_audio_control *ctl)
+{
+ struct gbaudio_ctl_pvt *ctldata;
+
+ ctldata = devm_kzalloc(gb->dev, sizeof(struct gbaudio_ctl_pvt),
+ GFP_KERNEL);
+ if (!ctldata)
+ return -ENOMEM;
+ ctldata->ctl_id = ctl->id;
+ ctldata->data_cport = ctl->data_cport;
+ ctldata->access = ctl->access;
+ ctldata->vcount = ctl->count_values;
+ ctldata->info = &ctl->info;
+ *kctl = (struct snd_kcontrol_new)
+ SOC_DAPM_MIXER_GB(ctl->name, ctl->count, ctldata);
+
+ return 0;
+}
+
+static int gbaudio_tplg_create_wcontrol(struct gbaudio_module_info *gb,
+ struct snd_kcontrol_new *kctl,
+ struct gb_audio_control *ctl)
+{
+ int ret;
+
+ switch (ctl->iface) {
+ case SNDRV_CTL_ELEM_IFACE_MIXER:
+ switch (ctl->info.type) {
+ case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
+ ret = gbaudio_tplg_create_enum_ctl(gb, kctl, ctl);
+ break;
+ default:
+ ret = gbaudio_tplg_create_mixer_ctl(gb, kctl, ctl);
+ break;
+ }
+ break;
+ default:
+ return -EINVAL;
+
+ }
+
+ dev_dbg(gb->dev, "%s:%d DAPM control created, ret:%d\n", ctl->name,
+ ctl->id, ret);
+ return ret;
+}
+
+static int gbaudio_widget_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ int wid;
+ int ret;
+ struct snd_soc_codec *codec = w->codec;
+ struct gbaudio_codec_info *gbcodec = snd_soc_codec_get_drvdata(codec);
+ struct gbaudio_module_info *module;
+ struct gb_bundle *bundle;
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+ /* Find relevant module */
+ module = find_gb_module(gbcodec, w->name);
+ if (!module)
+ return -EINVAL;
+
+ /* map name to widget id */
+ wid = gbaudio_map_widgetname(module, w->name);
+ if (wid < 0) {
+ dev_err(codec->dev, "Invalid widget name:%s\n", w->name);
+ return -EINVAL;
+ }
+
+ bundle = to_gb_bundle(module->dev);
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ return ret;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ ret = gb_audio_gb_enable_widget(module->mgmt_connection, wid);
+ if (!ret)
+ ret = gbaudio_module_update(gbcodec, w, module, 1);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret = gb_audio_gb_disable_widget(module->mgmt_connection, wid);
+ if (!ret)
+ ret = gbaudio_module_update(gbcodec, w, module, 0);
+ break;
+ }
+ if (ret)
+ dev_err_ratelimited(codec->dev,
+ "%d: widget, event:%d failed:%d\n", wid,
+ event, ret);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return ret;
+}
+
+static int gbaudio_tplg_create_widget(struct gbaudio_module_info *module,
+ struct snd_soc_dapm_widget *dw,
+ struct gb_audio_widget *w, int *w_size)
+{
+ int i, ret, csize;
+ struct snd_kcontrol_new *widget_kctls;
+ struct gb_audio_control *curr;
+ struct gbaudio_control *control, *_control;
+ size_t size;
+ char temp_name[NAME_SIZE];
+
+ ret = gbaudio_validate_kcontrol_count(w);
+ if (ret) {
+ dev_err(module->dev, "Inavlid kcontrol count=%d for %s\n",
+ w->ncontrols, w->name);
+ return ret;
+ }
+
+ /* allocate memory for kcontrol */
+ if (w->ncontrols) {
+ size = sizeof(struct snd_kcontrol_new) * w->ncontrols;
+ widget_kctls = devm_kzalloc(module->dev, size, GFP_KERNEL);
+ if (!widget_kctls)
+ return -ENOMEM;
+ }
+
+ *w_size = sizeof(struct gb_audio_widget);
+
+ /* create relevant kcontrols */
+ curr = w->ctl;
+ for (i = 0; i < w->ncontrols; i++) {
+ ret = gbaudio_tplg_create_wcontrol(module, &widget_kctls[i],
+ curr);
+ if (ret) {
+ dev_err(module->dev,
+ "%s:%d type widget_ctl not supported\n",
+ curr->name, curr->iface);
+ goto error;
+ }
+ control = devm_kzalloc(module->dev,
+ sizeof(struct gbaudio_control),
+ GFP_KERNEL);
+ if (!control) {
+ ret = -ENOMEM;
+ goto error;
+ }
+ control->id = curr->id;
+ control->name = curr->name;
+ control->wname = w->name;
+
+ if (curr->info.type == GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED) {
+ struct gb_audio_enumerated *gbenum =
+ &curr->info.value.enumerated;
+
+ csize = offsetof(struct gb_audio_control, info);
+ csize += offsetof(struct gb_audio_ctl_elem_info, value);
+ csize += offsetof(struct gb_audio_enumerated, names);
+ csize += gbenum->names_length;
+ control->texts = (const char * const *)
+ gb_generate_enum_strings(module, gbenum);
+ control->items = gbenum->items;
+ } else
+ csize = sizeof(struct gb_audio_control);
+ *w_size += csize;
+ curr = (void *)curr + csize;
+ list_add(&control->list, &module->widget_ctl_list);
+ dev_dbg(module->dev, "%s: control of type %d created\n",
+ widget_kctls[i].name, widget_kctls[i].iface);
+ }
+
+ /* Prefix dev_id to widget control_name */
+ strlcpy(temp_name, w->name, NAME_SIZE);
+ snprintf(w->name, NAME_SIZE, "GB %d %s", module->dev_id, temp_name);
+
+ switch (w->type) {
+ case snd_soc_dapm_spk:
+ *dw = (struct snd_soc_dapm_widget)
+ SND_SOC_DAPM_SPK(w->name, gbcodec_event_spk);
+ module->op_devices |= GBAUDIO_DEVICE_OUT_SPEAKER;
+ break;
+ case snd_soc_dapm_hp:
+ *dw = (struct snd_soc_dapm_widget)
+ SND_SOC_DAPM_HP(w->name, gbcodec_event_hp);
+ module->op_devices |= (GBAUDIO_DEVICE_OUT_WIRED_HEADSET
+ | GBAUDIO_DEVICE_OUT_WIRED_HEADPHONE);
+ module->ip_devices |= GBAUDIO_DEVICE_IN_WIRED_HEADSET;
+ break;
+ case snd_soc_dapm_mic:
+ *dw = (struct snd_soc_dapm_widget)
+ SND_SOC_DAPM_MIC(w->name, gbcodec_event_int_mic);
+ module->ip_devices |= GBAUDIO_DEVICE_IN_BUILTIN_MIC;
+ break;
+ case snd_soc_dapm_output:
+ *dw = (struct snd_soc_dapm_widget)SND_SOC_DAPM_OUTPUT(w->name);
+ break;
+ case snd_soc_dapm_input:
+ *dw = (struct snd_soc_dapm_widget)SND_SOC_DAPM_INPUT(w->name);
+ break;
+ case snd_soc_dapm_switch:
+ *dw = (struct snd_soc_dapm_widget)
+ SND_SOC_DAPM_SWITCH_E(w->name, SND_SOC_NOPM, 0, 0,
+ widget_kctls, gbaudio_widget_event,
+ SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD);
+ break;
+ case snd_soc_dapm_pga:
+ *dw = (struct snd_soc_dapm_widget)
+ SND_SOC_DAPM_PGA_E(w->name, SND_SOC_NOPM, 0, 0, NULL, 0,
+ gbaudio_widget_event,
+ SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD);
+ break;
+ case snd_soc_dapm_mixer:
+ *dw = (struct snd_soc_dapm_widget)
+ SND_SOC_DAPM_MIXER_E(w->name, SND_SOC_NOPM, 0, 0, NULL,
+ 0, gbaudio_widget_event,
+ SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD);
+ break;
+ case snd_soc_dapm_mux:
+ *dw = (struct snd_soc_dapm_widget)
+ SND_SOC_DAPM_MUX_E(w->name, SND_SOC_NOPM, 0, 0,
+ widget_kctls, gbaudio_widget_event,
+ SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD);
+ break;
+ case snd_soc_dapm_aif_in:
+ *dw = (struct snd_soc_dapm_widget)
+ SND_SOC_DAPM_AIF_IN_E(w->name, w->sname, 0,
+ SND_SOC_NOPM,
+ 0, 0, gbaudio_widget_event,
+ SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD);
+ break;
+ case snd_soc_dapm_aif_out:
+ *dw = (struct snd_soc_dapm_widget)
+ SND_SOC_DAPM_AIF_OUT_E(w->name, w->sname, 0,
+ SND_SOC_NOPM,
+ 0, 0, gbaudio_widget_event,
+ SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD);
+ break;
+ default:
+ ret = -EINVAL;
+ goto error;
+ }
+
+ dev_dbg(module->dev, "%s: widget of type %d created\n", dw->name,
+ dw->id);
+ return 0;
+error:
+ list_for_each_entry_safe(control, _control, &module->widget_ctl_list,
+ list) {
+ list_del(&control->list);
+ devm_kfree(module->dev, control);
+ }
+ return ret;
+}
+
+static int gbaudio_tplg_process_kcontrols(struct gbaudio_module_info *module,
+ struct gb_audio_control *controls)
+{
+ int i, csize, ret;
+ struct snd_kcontrol_new *dapm_kctls;
+ struct gb_audio_control *curr;
+ struct gbaudio_control *control, *_control;
+ size_t size;
+ char temp_name[NAME_SIZE];
+
+ size = sizeof(struct snd_kcontrol_new) * module->num_controls;
+ dapm_kctls = devm_kzalloc(module->dev, size, GFP_KERNEL);
+ if (!dapm_kctls)
+ return -ENOMEM;
+
+ curr = controls;
+ for (i = 0; i < module->num_controls; i++) {
+ ret = gbaudio_tplg_create_kcontrol(module, &dapm_kctls[i],
+ curr);
+ if (ret) {
+ dev_err(module->dev, "%s:%d type not supported\n",
+ curr->name, curr->iface);
+ goto error;
+ }
+ control = devm_kzalloc(module->dev, sizeof(struct
+ gbaudio_control),
+ GFP_KERNEL);
+ if (!control) {
+ ret = -ENOMEM;
+ goto error;
+ }
+ control->id = curr->id;
+ /* Prefix dev_id to widget_name */
+ strlcpy(temp_name, curr->name, NAME_SIZE);
+ snprintf(curr->name, NAME_SIZE, "GB %d %s", module->dev_id,
+ temp_name);
+ control->name = curr->name;
+ if (curr->info.type == GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED) {
+ struct gb_audio_enumerated *gbenum =
+ &curr->info.value.enumerated;
+
+ csize = offsetof(struct gb_audio_control, info);
+ csize += offsetof(struct gb_audio_ctl_elem_info, value);
+ csize += offsetof(struct gb_audio_enumerated, names);
+ csize += gbenum->names_length;
+ control->texts = (const char * const *)
+ gb_generate_enum_strings(module, gbenum);
+ control->items = gbenum->items;
+ } else
+ csize = sizeof(struct gb_audio_control);
+
+ list_add(&control->list, &module->ctl_list);
+ dev_dbg(module->dev, "%d:%s created of type %d\n", curr->id,
+ curr->name, curr->info.type);
+ curr = (void *)curr + csize;
+ }
+ module->controls = dapm_kctls;
+
+ return 0;
+error:
+ list_for_each_entry_safe(control, _control, &module->ctl_list,
+ list) {
+ list_del(&control->list);
+ devm_kfree(module->dev, control);
+ }
+ devm_kfree(module->dev, dapm_kctls);
+ return ret;
+}
+
+static int gbaudio_tplg_process_widgets(struct gbaudio_module_info *module,
+ struct gb_audio_widget *widgets)
+{
+ int i, ret, w_size;
+ struct snd_soc_dapm_widget *dapm_widgets;
+ struct gb_audio_widget *curr;
+ struct gbaudio_widget *widget, *_widget;
+ size_t size;
+
+ size = sizeof(struct snd_soc_dapm_widget) * module->num_dapm_widgets;
+ dapm_widgets = devm_kzalloc(module->dev, size, GFP_KERNEL);
+ if (!dapm_widgets)
+ return -ENOMEM;
+
+ curr = widgets;
+ for (i = 0; i < module->num_dapm_widgets; i++) {
+ ret = gbaudio_tplg_create_widget(module, &dapm_widgets[i],
+ curr, &w_size);
+ if (ret) {
+ dev_err(module->dev, "%s:%d type not supported\n",
+ curr->name, curr->type);
+ goto error;
+ }
+ widget = devm_kzalloc(module->dev, sizeof(struct
+ gbaudio_widget),
+ GFP_KERNEL);
+ if (!widget) {
+ ret = -ENOMEM;
+ goto error;
+ }
+ widget->id = curr->id;
+ widget->name = curr->name;
+ list_add(&widget->list, &module->widget_list);
+ curr = (void *)curr + w_size;
+ }
+ module->dapm_widgets = dapm_widgets;
+
+ return 0;
+
+error:
+ list_for_each_entry_safe(widget, _widget, &module->widget_list,
+ list) {
+ list_del(&widget->list);
+ devm_kfree(module->dev, widget);
+ }
+ devm_kfree(module->dev, dapm_widgets);
+ return ret;
+}
+
+static int gbaudio_tplg_process_routes(struct gbaudio_module_info *module,
+ struct gb_audio_route *routes)
+{
+ int i, ret;
+ struct snd_soc_dapm_route *dapm_routes;
+ struct gb_audio_route *curr;
+ size_t size;
+
+ size = sizeof(struct snd_soc_dapm_route) * module->num_dapm_routes;
+ dapm_routes = devm_kzalloc(module->dev, size, GFP_KERNEL);
+ if (!dapm_routes)
+ return -ENOMEM;
+
+ module->dapm_routes = dapm_routes;
+ curr = routes;
+
+ for (i = 0; i < module->num_dapm_routes; i++) {
+ dapm_routes->sink =
+ gbaudio_map_widgetid(module, curr->destination_id);
+ if (!dapm_routes->sink) {
+ dev_err(module->dev, "%d:%d:%d:%d - Invalid sink\n",
+ curr->source_id, curr->destination_id,
+ curr->control_id, curr->index);
+ ret = -EINVAL;
+ goto error;
+ }
+ dapm_routes->source =
+ gbaudio_map_widgetid(module, curr->source_id);
+ if (!dapm_routes->source) {
+ dev_err(module->dev, "%d:%d:%d:%d - Invalid source\n",
+ curr->source_id, curr->destination_id,
+ curr->control_id, curr->index);
+ ret = -EINVAL;
+ goto error;
+ }
+ dapm_routes->control =
+ gbaudio_map_controlid(module,
+ curr->control_id,
+ curr->index);
+ if ((curr->control_id != GBAUDIO_INVALID_ID) &&
+ !dapm_routes->control) {
+ dev_err(module->dev, "%d:%d:%d:%d - Invalid control\n",
+ curr->source_id, curr->destination_id,
+ curr->control_id, curr->index);
+ ret = -EINVAL;
+ goto error;
+ }
+ dev_dbg(module->dev, "Route {%s, %s, %s}\n", dapm_routes->sink,
+ (dapm_routes->control) ? dapm_routes->control:"NULL",
+ dapm_routes->source);
+ dapm_routes++;
+ curr++;
+ }
+
+ return 0;
+
+error:
+ devm_kfree(module->dev, module->dapm_routes);
+ return ret;
+}
+
+static int gbaudio_tplg_process_header(struct gbaudio_module_info *module,
+ struct gb_audio_topology *tplg_data)
+{
+ /* fetch no. of kcontrols, widgets & routes */
+ module->num_controls = tplg_data->num_controls;
+ module->num_dapm_widgets = tplg_data->num_widgets;
+ module->num_dapm_routes = tplg_data->num_routes;
+
+ /* update block offset */
+ module->dai_offset = (unsigned long)&tplg_data->data;
+ module->control_offset = module->dai_offset + tplg_data->size_dais;
+ module->widget_offset = module->control_offset +
+ tplg_data->size_controls;
+ module->route_offset = module->widget_offset +
+ tplg_data->size_widgets;
+
+ dev_dbg(module->dev, "DAI offset is 0x%lx\n", module->dai_offset);
+ dev_dbg(module->dev, "control offset is %lx\n",
+ module->control_offset);
+ dev_dbg(module->dev, "widget offset is %lx\n", module->widget_offset);
+ dev_dbg(module->dev, "route offset is %lx\n", module->route_offset);
+
+ return 0;
+}
+
+int gbaudio_tplg_parse_data(struct gbaudio_module_info *module,
+ struct gb_audio_topology *tplg_data)
+{
+ int ret;
+ struct gb_audio_control *controls;
+ struct gb_audio_widget *widgets;
+ struct gb_audio_route *routes;
+
+ if (!tplg_data)
+ return -EINVAL;
+
+ ret = gbaudio_tplg_process_header(module, tplg_data);
+ if (ret) {
+ dev_err(module->dev, "%d: Error in parsing topology header\n",
+ ret);
+ return ret;
+ }
+
+ /* process control */
+ controls = (struct gb_audio_control *)module->control_offset;
+ ret = gbaudio_tplg_process_kcontrols(module, controls);
+ if (ret) {
+ dev_err(module->dev,
+ "%d: Error in parsing controls data\n", ret);
+ return ret;
+ }
+ dev_dbg(module->dev, "Control parsing finished\n");
+
+ /* process widgets */
+ widgets = (struct gb_audio_widget *)module->widget_offset;
+ ret = gbaudio_tplg_process_widgets(module, widgets);
+ if (ret) {
+ dev_err(module->dev,
+ "%d: Error in parsing widgets data\n", ret);
+ return ret;
+ }
+ dev_dbg(module->dev, "Widget parsing finished\n");
+
+ /* process route */
+ routes = (struct gb_audio_route *)module->route_offset;
+ ret = gbaudio_tplg_process_routes(module, routes);
+ if (ret) {
+ dev_err(module->dev,
+ "%d: Error in parsing routes data\n", ret);
+ return ret;
+ }
+ dev_dbg(module->dev, "Route parsing finished\n");
+
+ /* parse jack capabilities */
+ if (tplg_data->jack_type) {
+ module->jack_mask = tplg_data->jack_type & GBCODEC_JACK_MASK;
+ module->button_mask = tplg_data->jack_type &
+ GBCODEC_JACK_BUTTON_MASK;
+ }
+
+ return ret;
+}
+
+void gbaudio_tplg_release(struct gbaudio_module_info *module)
+{
+ struct gbaudio_control *control, *_control;
+ struct gbaudio_widget *widget, *_widget;
+
+ if (!module->topology)
+ return;
+
+ /* release kcontrols */
+ list_for_each_entry_safe(control, _control, &module->ctl_list,
+ list) {
+ list_del(&control->list);
+ devm_kfree(module->dev, control);
+ }
+ if (module->controls)
+ devm_kfree(module->dev, module->controls);
+
+ /* release widget controls */
+ list_for_each_entry_safe(control, _control, &module->widget_ctl_list,
+ list) {
+ list_del(&control->list);
+ devm_kfree(module->dev, control);
+ }
+
+ /* release widgets */
+ list_for_each_entry_safe(widget, _widget, &module->widget_list,
+ list) {
+ list_del(&widget->list);
+ devm_kfree(module->dev, widget);
+ }
+ if (module->dapm_widgets)
+ devm_kfree(module->dev, module->dapm_widgets);
+
+ /* release routes */
+ if (module->dapm_routes)
+ devm_kfree(module->dev, module->dapm_routes);
+}
diff --git a/drivers/staging/greybus/authentication.c b/drivers/staging/greybus/authentication.c
new file mode 100644
index 000000000000..168626ba0c03
--- /dev/null
+++ b/drivers/staging/greybus/authentication.c
@@ -0,0 +1,429 @@
+/*
+ * Greybus Component Authentication Protocol (CAP) Driver.
+ *
+ * Copyright 2016 Google Inc.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include "greybus.h"
+
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/uaccess.h>
+
+#include "greybus_authentication.h"
+#include "firmware.h"
+#include "greybus.h"
+
+#define CAP_TIMEOUT_MS 1000
+
+/*
+ * Number of minor devices this driver supports.
+ * There will be exactly one required per Interface.
+ */
+#define NUM_MINORS U8_MAX
+
+struct gb_cap {
+ struct device *parent;
+ struct gb_connection *connection;
+ struct kref kref;
+ struct list_head node;
+ bool disabled; /* connection getting disabled */
+
+ struct mutex mutex;
+ struct cdev cdev;
+ struct device *class_device;
+ dev_t dev_num;
+};
+
+static struct class *cap_class;
+static dev_t cap_dev_num;
+static DEFINE_IDA(cap_minors_map);
+static LIST_HEAD(cap_list);
+static DEFINE_MUTEX(list_mutex);
+
+static void cap_kref_release(struct kref *kref)
+{
+ struct gb_cap *cap = container_of(kref, struct gb_cap, kref);
+
+ kfree(cap);
+}
+
+/*
+ * All users of cap take a reference (from within list_mutex lock), before
+ * they get a pointer to play with. And the structure will be freed only after
+ * the last user has put the reference to it.
+ */
+static void put_cap(struct gb_cap *cap)
+{
+ kref_put(&cap->kref, cap_kref_release);
+}
+
+/* Caller must call put_cap() after using struct gb_cap */
+static struct gb_cap *get_cap(struct cdev *cdev)
+{
+ struct gb_cap *cap;
+
+ mutex_lock(&list_mutex);
+
+ list_for_each_entry(cap, &cap_list, node) {
+ if (&cap->cdev == cdev) {
+ kref_get(&cap->kref);
+ goto unlock;
+ }
+ }
+
+ cap = NULL;
+
+unlock:
+ mutex_unlock(&list_mutex);
+
+ return cap;
+}
+
+static int cap_get_endpoint_uid(struct gb_cap *cap, u8 *euid)
+{
+ struct gb_connection *connection = cap->connection;
+ struct gb_cap_get_endpoint_uid_response response;
+ int ret;
+
+ ret = gb_operation_sync(connection, GB_CAP_TYPE_GET_ENDPOINT_UID, NULL,
+ 0, &response, sizeof(response));
+ if (ret) {
+ dev_err(cap->parent, "failed to get endpoint uid (%d)\n", ret);
+ return ret;
+ }
+
+ memcpy(euid, response.uid, sizeof(response.uid));
+
+ return 0;
+}
+
+static int cap_get_ims_certificate(struct gb_cap *cap, u32 class, u32 id,
+ u8 *certificate, u32 *size, u8 *result)
+{
+ struct gb_connection *connection = cap->connection;
+ struct gb_cap_get_ims_certificate_request *request;
+ struct gb_cap_get_ims_certificate_response *response;
+ size_t max_size = gb_operation_get_payload_size_max(connection);
+ struct gb_operation *op;
+ int ret;
+
+ op = gb_operation_create_flags(connection,
+ GB_CAP_TYPE_GET_IMS_CERTIFICATE,
+ sizeof(*request), max_size,
+ GB_OPERATION_FLAG_SHORT_RESPONSE,
+ GFP_KERNEL);
+ if (!op)
+ return -ENOMEM;
+
+ request = op->request->payload;
+ request->certificate_class = cpu_to_le32(class);
+ request->certificate_id = cpu_to_le32(id);
+
+ ret = gb_operation_request_send_sync(op);
+ if (ret) {
+ dev_err(cap->parent, "failed to get certificate (%d)\n", ret);
+ goto done;
+ }
+
+ response = op->response->payload;
+ *result = response->result_code;
+ *size = op->response->payload_size - sizeof(*response);
+ memcpy(certificate, response->certificate, *size);
+
+done:
+ gb_operation_put(op);
+ return ret;
+}
+
+static int cap_authenticate(struct gb_cap *cap, u32 auth_type, u8 *uid,
+ u8 *challenge, u8 *result, u8 *auth_response,
+ u32 *signature_size, u8 *signature)
+{
+ struct gb_connection *connection = cap->connection;
+ struct gb_cap_authenticate_request *request;
+ struct gb_cap_authenticate_response *response;
+ size_t max_size = gb_operation_get_payload_size_max(connection);
+ struct gb_operation *op;
+ int ret;
+
+ op = gb_operation_create_flags(connection, GB_CAP_TYPE_AUTHENTICATE,
+ sizeof(*request), max_size,
+ GB_OPERATION_FLAG_SHORT_RESPONSE,
+ GFP_KERNEL);
+ if (!op)
+ return -ENOMEM;
+
+ request = op->request->payload;
+ request->auth_type = cpu_to_le32(auth_type);
+ memcpy(request->uid, uid, sizeof(request->uid));
+ memcpy(request->challenge, challenge, sizeof(request->challenge));
+
+ ret = gb_operation_request_send_sync(op);
+ if (ret) {
+ dev_err(cap->parent, "failed to authenticate (%d)\n", ret);
+ goto done;
+ }
+
+ response = op->response->payload;
+ *result = response->result_code;
+ *signature_size = op->response->payload_size - sizeof(*response);
+ memcpy(auth_response, response->response, sizeof(response->response));
+ memcpy(signature, response->signature, *signature_size);
+
+done:
+ gb_operation_put(op);
+ return ret;
+}
+
+/* Char device fops */
+
+static int cap_open(struct inode *inode, struct file *file)
+{
+ struct gb_cap *cap = get_cap(inode->i_cdev);
+
+ /* cap structure can't get freed until file descriptor is closed */
+ if (cap) {
+ file->private_data = cap;
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
+static int cap_release(struct inode *inode, struct file *file)
+{
+ struct gb_cap *cap = file->private_data;
+
+ put_cap(cap);
+ return 0;
+}
+
+static int cap_ioctl(struct gb_cap *cap, unsigned int cmd,
+ void __user *buf)
+{
+ struct cap_ioc_get_endpoint_uid endpoint_uid;
+ struct cap_ioc_get_ims_certificate *ims_cert;
+ struct cap_ioc_authenticate *authenticate;
+ size_t size;
+ int ret;
+
+ switch (cmd) {
+ case CAP_IOC_GET_ENDPOINT_UID:
+ ret = cap_get_endpoint_uid(cap, endpoint_uid.uid);
+ if (ret)
+ return ret;
+
+ if (copy_to_user(buf, &endpoint_uid, sizeof(endpoint_uid)))
+ return -EFAULT;
+
+ return 0;
+ case CAP_IOC_GET_IMS_CERTIFICATE:
+ size = sizeof(*ims_cert);
+ ims_cert = memdup_user(buf, size);
+ if (IS_ERR(ims_cert))
+ return PTR_ERR(ims_cert);
+
+ ret = cap_get_ims_certificate(cap, ims_cert->certificate_class,
+ ims_cert->certificate_id,
+ ims_cert->certificate,
+ &ims_cert->cert_size,
+ &ims_cert->result_code);
+ if (!ret && copy_to_user(buf, ims_cert, size))
+ ret = -EFAULT;
+ kfree(ims_cert);
+
+ return ret;
+ case CAP_IOC_AUTHENTICATE:
+ size = sizeof(*authenticate);
+ authenticate = memdup_user(buf, size);
+ if (IS_ERR(authenticate))
+ return PTR_ERR(authenticate);
+
+ ret = cap_authenticate(cap, authenticate->auth_type,
+ authenticate->uid,
+ authenticate->challenge,
+ &authenticate->result_code,
+ authenticate->response,
+ &authenticate->signature_size,
+ authenticate->signature);
+ if (!ret && copy_to_user(buf, authenticate, size))
+ ret = -EFAULT;
+ kfree(authenticate);
+
+ return ret;
+ default:
+ return -ENOTTY;
+ }
+}
+
+static long cap_ioctl_unlocked(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct gb_cap *cap = file->private_data;
+ struct gb_bundle *bundle = cap->connection->bundle;
+ int ret = -ENODEV;
+
+ /*
+ * Serialize ioctls.
+ *
+ * We don't want the user to do multiple authentication operations in
+ * parallel.
+ *
+ * This is also used to protect ->disabled, which is used to check if
+ * the connection is getting disconnected, so that we don't start any
+ * new operations.
+ */
+ mutex_lock(&cap->mutex);
+ if (!cap->disabled) {
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (!ret) {
+ ret = cap_ioctl(cap, cmd, (void __user *)arg);
+ gb_pm_runtime_put_autosuspend(bundle);
+ }
+ }
+ mutex_unlock(&cap->mutex);
+
+ return ret;
+}
+
+static const struct file_operations cap_fops = {
+ .owner = THIS_MODULE,
+ .open = cap_open,
+ .release = cap_release,
+ .unlocked_ioctl = cap_ioctl_unlocked,
+};
+
+int gb_cap_connection_init(struct gb_connection *connection)
+{
+ struct gb_cap *cap;
+ int ret, minor;
+
+ if (!connection)
+ return 0;
+
+ cap = kzalloc(sizeof(*cap), GFP_KERNEL);
+ if (!cap)
+ return -ENOMEM;
+
+ cap->parent = &connection->bundle->dev;
+ cap->connection = connection;
+ mutex_init(&cap->mutex);
+ gb_connection_set_data(connection, cap);
+ kref_init(&cap->kref);
+
+ mutex_lock(&list_mutex);
+ list_add(&cap->node, &cap_list);
+ mutex_unlock(&list_mutex);
+
+ ret = gb_connection_enable(connection);
+ if (ret)
+ goto err_list_del;
+
+ minor = ida_simple_get(&cap_minors_map, 0, NUM_MINORS, GFP_KERNEL);
+ if (minor < 0) {
+ ret = minor;
+ goto err_connection_disable;
+ }
+
+ /* Add a char device to allow userspace to interact with cap */
+ cap->dev_num = MKDEV(MAJOR(cap_dev_num), minor);
+ cdev_init(&cap->cdev, &cap_fops);
+
+ ret = cdev_add(&cap->cdev, cap->dev_num, 1);
+ if (ret)
+ goto err_remove_ida;
+
+ /* Add a soft link to the previously added char-dev within the bundle */
+ cap->class_device = device_create(cap_class, cap->parent, cap->dev_num,
+ NULL, "gb-authenticate-%d", minor);
+ if (IS_ERR(cap->class_device)) {
+ ret = PTR_ERR(cap->class_device);
+ goto err_del_cdev;
+ }
+
+ return 0;
+
+err_del_cdev:
+ cdev_del(&cap->cdev);
+err_remove_ida:
+ ida_simple_remove(&cap_minors_map, minor);
+err_connection_disable:
+ gb_connection_disable(connection);
+err_list_del:
+ mutex_lock(&list_mutex);
+ list_del(&cap->node);
+ mutex_unlock(&list_mutex);
+
+ put_cap(cap);
+
+ return ret;
+}
+
+void gb_cap_connection_exit(struct gb_connection *connection)
+{
+ struct gb_cap *cap;
+
+ if (!connection)
+ return;
+
+ cap = gb_connection_get_data(connection);
+
+ device_destroy(cap_class, cap->dev_num);
+ cdev_del(&cap->cdev);
+ ida_simple_remove(&cap_minors_map, MINOR(cap->dev_num));
+
+ /*
+ * Disallow any new ioctl operations on the char device and wait for
+ * existing ones to finish.
+ */
+ mutex_lock(&cap->mutex);
+ cap->disabled = true;
+ mutex_unlock(&cap->mutex);
+
+ /* All pending greybus operations should have finished by now */
+ gb_connection_disable(cap->connection);
+
+ /* Disallow new users to get access to the cap structure */
+ mutex_lock(&list_mutex);
+ list_del(&cap->node);
+ mutex_unlock(&list_mutex);
+
+ /*
+ * All current users of cap would have taken a reference to it by
+ * now, we can drop our reference and wait the last user will get
+ * cap freed.
+ */
+ put_cap(cap);
+}
+
+int cap_init(void)
+{
+ int ret;
+
+ cap_class = class_create(THIS_MODULE, "gb_authenticate");
+ if (IS_ERR(cap_class))
+ return PTR_ERR(cap_class);
+
+ ret = alloc_chrdev_region(&cap_dev_num, 0, NUM_MINORS,
+ "gb_authenticate");
+ if (ret)
+ goto err_remove_class;
+
+ return 0;
+
+err_remove_class:
+ class_destroy(cap_class);
+ return ret;
+}
+
+void cap_exit(void)
+{
+ unregister_chrdev_region(cap_dev_num, NUM_MINORS);
+ class_destroy(cap_class);
+ ida_destroy(&cap_minors_map);
+}
diff --git a/drivers/staging/greybus/bootrom.c b/drivers/staging/greybus/bootrom.c
new file mode 100644
index 000000000000..5f90721bcc51
--- /dev/null
+++ b/drivers/staging/greybus/bootrom.c
@@ -0,0 +1,524 @@
+/*
+ * BOOTROM Greybus driver.
+ *
+ * Copyright 2016 Google Inc.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/firmware.h>
+#include <linux/jiffies.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+
+#include "greybus.h"
+#include "firmware.h"
+
+/* Timeout, in jiffies, within which the next request must be received */
+#define NEXT_REQ_TIMEOUT_MS 1000
+
+/*
+ * FIXME: Reduce this timeout once svc core handles parallel processing of
+ * events from the SVC, which are handled sequentially today.
+ */
+#define MODE_SWITCH_TIMEOUT_MS 10000
+
+enum next_request_type {
+ NEXT_REQ_FIRMWARE_SIZE,
+ NEXT_REQ_GET_FIRMWARE,
+ NEXT_REQ_READY_TO_BOOT,
+ NEXT_REQ_MODE_SWITCH,
+};
+
+struct gb_bootrom {
+ struct gb_connection *connection;
+ const struct firmware *fw;
+ u8 protocol_major;
+ u8 protocol_minor;
+ enum next_request_type next_request;
+ struct delayed_work dwork;
+ struct mutex mutex; /* Protects bootrom->fw */
+};
+
+static void free_firmware(struct gb_bootrom *bootrom)
+{
+ if (!bootrom->fw)
+ return;
+
+ release_firmware(bootrom->fw);
+ bootrom->fw = NULL;
+}
+
+static void gb_bootrom_timedout(struct work_struct *work)
+{
+ struct delayed_work *dwork = to_delayed_work(work);
+ struct gb_bootrom *bootrom = container_of(dwork, struct gb_bootrom, dwork);
+ struct device *dev = &bootrom->connection->bundle->dev;
+ const char *reason;
+
+ switch (bootrom->next_request) {
+ case NEXT_REQ_FIRMWARE_SIZE:
+ reason = "Firmware Size Request";
+ break;
+ case NEXT_REQ_GET_FIRMWARE:
+ reason = "Get Firmware Request";
+ break;
+ case NEXT_REQ_READY_TO_BOOT:
+ reason = "Ready to Boot Request";
+ break;
+ case NEXT_REQ_MODE_SWITCH:
+ reason = "Interface Mode Switch";
+ break;
+ default:
+ reason = NULL;
+ dev_err(dev, "Invalid next-request: %u", bootrom->next_request);
+ break;
+ }
+
+ dev_err(dev, "Timed out waiting for %s from the Module\n", reason);
+
+ mutex_lock(&bootrom->mutex);
+ free_firmware(bootrom);
+ mutex_unlock(&bootrom->mutex);
+
+ /* TODO: Power-off Module ? */
+}
+
+static void gb_bootrom_set_timeout(struct gb_bootrom *bootrom,
+ enum next_request_type next, unsigned long timeout)
+{
+ bootrom->next_request = next;
+ schedule_delayed_work(&bootrom->dwork, msecs_to_jiffies(timeout));
+}
+
+static void gb_bootrom_cancel_timeout(struct gb_bootrom *bootrom)
+{
+ cancel_delayed_work_sync(&bootrom->dwork);
+}
+
+/*
+ * The es2 chip doesn't have VID/PID programmed into the hardware and we need to
+ * hack that up to distinguish different modules and their firmware blobs.
+ *
+ * This fetches VID/PID (over bootrom protocol) for es2 chip only, when VID/PID
+ * already sent during hotplug are 0.
+ *
+ * Otherwise, we keep intf->vendor_id/product_id same as what's passed
+ * during hotplug.
+ */
+static void bootrom_es2_fixup_vid_pid(struct gb_bootrom *bootrom)
+{
+ struct gb_bootrom_get_vid_pid_response response;
+ struct gb_connection *connection = bootrom->connection;
+ struct gb_interface *intf = connection->bundle->intf;
+ int ret;
+
+ if (!(intf->quirks & GB_INTERFACE_QUIRK_NO_GMP_IDS))
+ return;
+
+ ret = gb_operation_sync(connection, GB_BOOTROM_TYPE_GET_VID_PID,
+ NULL, 0, &response, sizeof(response));
+ if (ret) {
+ dev_err(&connection->bundle->dev,
+ "Bootrom get vid/pid operation failed (%d)\n", ret);
+ return;
+ }
+
+ /*
+ * NOTE: This is hacked, so that the same values of VID/PID can be used
+ * by next firmware level as well. The uevent for bootrom will still
+ * have VID/PID as 0, though after this point the sysfs files will start
+ * showing the updated values. But yeah, that's a bit racy as the same
+ * sysfs files would be showing 0 before this point.
+ */
+ intf->vendor_id = le32_to_cpu(response.vendor_id);
+ intf->product_id = le32_to_cpu(response.product_id);
+
+ dev_dbg(&connection->bundle->dev, "Bootrom got vid (0x%x)/pid (0x%x)\n",
+ intf->vendor_id, intf->product_id);
+}
+
+/* This returns path of the firmware blob on the disk */
+static int find_firmware(struct gb_bootrom *bootrom, u8 stage)
+{
+ struct gb_connection *connection = bootrom->connection;
+ struct gb_interface *intf = connection->bundle->intf;
+ char firmware_name[49];
+ int rc;
+
+ /* Already have a firmware, free it */
+ free_firmware(bootrom);
+
+ /* Bootrom protocol is only supported for loading Stage 2 firmware */
+ if (stage != 2) {
+ dev_err(&connection->bundle->dev, "Invalid boot stage: %u\n",
+ stage);
+ return -EINVAL;
+ }
+
+ /*
+ * Create firmware name
+ *
+ * XXX Name it properly..
+ */
+ snprintf(firmware_name, sizeof(firmware_name),
+ FW_NAME_PREFIX "%08x_%08x_%08x_%08x_s2l.tftf",
+ intf->ddbl1_manufacturer_id, intf->ddbl1_product_id,
+ intf->vendor_id, intf->product_id);
+
+ // FIXME:
+ // Turn to dev_dbg later after everyone has valid bootloaders with good
+ // ids, but leave this as dev_info for now to make it easier to track
+ // down "empty" vid/pid modules.
+ dev_info(&connection->bundle->dev, "Firmware file '%s' requested\n",
+ firmware_name);
+
+ rc = request_firmware(&bootrom->fw, firmware_name,
+ &connection->bundle->dev);
+ if (rc) {
+ dev_err(&connection->bundle->dev,
+ "failed to find %s firmware (%d)\n", firmware_name, rc);
+ }
+
+ return rc;
+}
+
+static int gb_bootrom_firmware_size_request(struct gb_operation *op)
+{
+ struct gb_bootrom *bootrom = gb_connection_get_data(op->connection);
+ struct gb_bootrom_firmware_size_request *size_request = op->request->payload;
+ struct gb_bootrom_firmware_size_response *size_response;
+ struct device *dev = &op->connection->bundle->dev;
+ int ret;
+
+ /* Disable timeouts */
+ gb_bootrom_cancel_timeout(bootrom);
+
+ if (op->request->payload_size != sizeof(*size_request)) {
+ dev_err(dev, "%s: illegal size of firmware size request (%zu != %zu)\n",
+ __func__, op->request->payload_size,
+ sizeof(*size_request));
+ ret = -EINVAL;
+ goto queue_work;
+ }
+
+ mutex_lock(&bootrom->mutex);
+
+ ret = find_firmware(bootrom, size_request->stage);
+ if (ret)
+ goto unlock;
+
+ if (!gb_operation_response_alloc(op, sizeof(*size_response),
+ GFP_KERNEL)) {
+ dev_err(dev, "%s: error allocating response\n", __func__);
+ free_firmware(bootrom);
+ ret = -ENOMEM;
+ goto unlock;
+ }
+
+ size_response = op->response->payload;
+ size_response->size = cpu_to_le32(bootrom->fw->size);
+
+ dev_dbg(dev, "%s: firmware size %d bytes\n", __func__, size_response->size);
+
+unlock:
+ mutex_unlock(&bootrom->mutex);
+
+queue_work:
+ if (!ret) {
+ /* Refresh timeout */
+ gb_bootrom_set_timeout(bootrom, NEXT_REQ_GET_FIRMWARE,
+ NEXT_REQ_TIMEOUT_MS);
+ }
+
+ return ret;
+}
+
+static int gb_bootrom_get_firmware(struct gb_operation *op)
+{
+ struct gb_bootrom *bootrom = gb_connection_get_data(op->connection);
+ const struct firmware *fw;
+ struct gb_bootrom_get_firmware_request *firmware_request;
+ struct gb_bootrom_get_firmware_response *firmware_response;
+ struct device *dev = &op->connection->bundle->dev;
+ unsigned int offset, size;
+ enum next_request_type next_request;
+ int ret = 0;
+
+ /* Disable timeouts */
+ gb_bootrom_cancel_timeout(bootrom);
+
+ if (op->request->payload_size != sizeof(*firmware_request)) {
+ dev_err(dev, "%s: Illegal size of get firmware request (%zu %zu)\n",
+ __func__, op->request->payload_size,
+ sizeof(*firmware_request));
+ ret = -EINVAL;
+ goto queue_work;
+ }
+
+ mutex_lock(&bootrom->mutex);
+
+ fw = bootrom->fw;
+ if (!fw) {
+ dev_err(dev, "%s: firmware not available\n", __func__);
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ firmware_request = op->request->payload;
+ offset = le32_to_cpu(firmware_request->offset);
+ size = le32_to_cpu(firmware_request->size);
+
+ if (offset >= fw->size || size > fw->size - offset) {
+ dev_warn(dev, "bad firmware request (offs = %u, size = %u)\n",
+ offset, size);
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ if (!gb_operation_response_alloc(op, sizeof(*firmware_response) + size,
+ GFP_KERNEL)) {
+ dev_err(dev, "%s: error allocating response\n", __func__);
+ ret = -ENOMEM;
+ goto unlock;
+ }
+
+ firmware_response = op->response->payload;
+ memcpy(firmware_response->data, fw->data + offset, size);
+
+ dev_dbg(dev, "responding with firmware (offs = %u, size = %u)\n", offset,
+ size);
+
+unlock:
+ mutex_unlock(&bootrom->mutex);
+
+queue_work:
+ /* Refresh timeout */
+ if (!ret && (offset + size == fw->size))
+ next_request = NEXT_REQ_READY_TO_BOOT;
+ else
+ next_request = NEXT_REQ_GET_FIRMWARE;
+
+ gb_bootrom_set_timeout(bootrom, next_request, NEXT_REQ_TIMEOUT_MS);
+
+ return ret;
+}
+
+static int gb_bootrom_ready_to_boot(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct gb_bootrom *bootrom = gb_connection_get_data(connection);
+ struct gb_bootrom_ready_to_boot_request *rtb_request;
+ struct device *dev = &connection->bundle->dev;
+ u8 status;
+ int ret = 0;
+
+ /* Disable timeouts */
+ gb_bootrom_cancel_timeout(bootrom);
+
+ if (op->request->payload_size != sizeof(*rtb_request)) {
+ dev_err(dev, "%s: Illegal size of ready to boot request (%zu %zu)\n",
+ __func__, op->request->payload_size,
+ sizeof(*rtb_request));
+ ret = -EINVAL;
+ goto queue_work;
+ }
+
+ rtb_request = op->request->payload;
+ status = rtb_request->status;
+
+ /* Return error if the blob was invalid */
+ if (status == GB_BOOTROM_BOOT_STATUS_INVALID) {
+ ret = -EINVAL;
+ goto queue_work;
+ }
+
+ /*
+ * XXX Should we return error for insecure firmware?
+ */
+ dev_dbg(dev, "ready to boot: 0x%x, 0\n", status);
+
+queue_work:
+ /*
+ * Refresh timeout, the Interface shall load the new personality and
+ * send a new hotplug request, which shall get rid of the bootrom
+ * connection. As that can take some time, increase the timeout a bit.
+ */
+ gb_bootrom_set_timeout(bootrom, NEXT_REQ_MODE_SWITCH,
+ MODE_SWITCH_TIMEOUT_MS);
+
+ return ret;
+}
+
+static int gb_bootrom_request_handler(struct gb_operation *op)
+{
+ u8 type = op->type;
+
+ switch (type) {
+ case GB_BOOTROM_TYPE_FIRMWARE_SIZE:
+ return gb_bootrom_firmware_size_request(op);
+ case GB_BOOTROM_TYPE_GET_FIRMWARE:
+ return gb_bootrom_get_firmware(op);
+ case GB_BOOTROM_TYPE_READY_TO_BOOT:
+ return gb_bootrom_ready_to_boot(op);
+ default:
+ dev_err(&op->connection->bundle->dev,
+ "unsupported request: %u\n", type);
+ return -EINVAL;
+ }
+}
+
+static int gb_bootrom_get_version(struct gb_bootrom *bootrom)
+{
+ struct gb_bundle *bundle = bootrom->connection->bundle;
+ struct gb_bootrom_version_request request;
+ struct gb_bootrom_version_response response;
+ int ret;
+
+ request.major = GB_BOOTROM_VERSION_MAJOR;
+ request.minor = GB_BOOTROM_VERSION_MINOR;
+
+ ret = gb_operation_sync(bootrom->connection,
+ GB_BOOTROM_TYPE_VERSION,
+ &request, sizeof(request), &response,
+ sizeof(response));
+ if (ret) {
+ dev_err(&bundle->dev,
+ "failed to get protocol version: %d\n",
+ ret);
+ return ret;
+ }
+
+ if (response.major > request.major) {
+ dev_err(&bundle->dev,
+ "unsupported major protocol version (%u > %u)\n",
+ response.major, request.major);
+ return -ENOTSUPP;
+ }
+
+ bootrom->protocol_major = response.major;
+ bootrom->protocol_minor = response.minor;
+
+ dev_dbg(&bundle->dev, "%s - %u.%u\n", __func__, response.major,
+ response.minor);
+
+ return 0;
+}
+
+static int gb_bootrom_probe(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id)
+{
+ struct greybus_descriptor_cport *cport_desc;
+ struct gb_connection *connection;
+ struct gb_bootrom *bootrom;
+ int ret;
+
+ if (bundle->num_cports != 1)
+ return -ENODEV;
+
+ cport_desc = &bundle->cport_desc[0];
+ if (cport_desc->protocol_id != GREYBUS_PROTOCOL_BOOTROM)
+ return -ENODEV;
+
+ bootrom = kzalloc(sizeof(*bootrom), GFP_KERNEL);
+ if (!bootrom)
+ return -ENOMEM;
+
+ connection = gb_connection_create(bundle,
+ le16_to_cpu(cport_desc->id),
+ gb_bootrom_request_handler);
+ if (IS_ERR(connection)) {
+ ret = PTR_ERR(connection);
+ goto err_free_bootrom;
+ }
+
+ gb_connection_set_data(connection, bootrom);
+
+ bootrom->connection = connection;
+
+ mutex_init(&bootrom->mutex);
+ INIT_DELAYED_WORK(&bootrom->dwork, gb_bootrom_timedout);
+ greybus_set_drvdata(bundle, bootrom);
+
+ ret = gb_connection_enable_tx(connection);
+ if (ret)
+ goto err_connection_destroy;
+
+ ret = gb_bootrom_get_version(bootrom);
+ if (ret)
+ goto err_connection_disable;
+
+ bootrom_es2_fixup_vid_pid(bootrom);
+
+ ret = gb_connection_enable(connection);
+ if (ret)
+ goto err_connection_disable;
+
+ /* Refresh timeout */
+ gb_bootrom_set_timeout(bootrom, NEXT_REQ_FIRMWARE_SIZE,
+ NEXT_REQ_TIMEOUT_MS);
+
+ /* Tell bootrom we're ready. */
+ ret = gb_operation_sync(connection, GB_BOOTROM_TYPE_AP_READY, NULL, 0,
+ NULL, 0);
+ if (ret) {
+ dev_err(&connection->bundle->dev,
+ "failed to send AP READY: %d\n", ret);
+ goto err_cancel_timeout;
+ }
+
+ dev_dbg(&bundle->dev, "AP_READY sent\n");
+
+ return 0;
+
+err_cancel_timeout:
+ gb_bootrom_cancel_timeout(bootrom);
+err_connection_disable:
+ gb_connection_disable(connection);
+err_connection_destroy:
+ gb_connection_destroy(connection);
+err_free_bootrom:
+ kfree(bootrom);
+
+ return ret;
+}
+
+static void gb_bootrom_disconnect(struct gb_bundle *bundle)
+{
+ struct gb_bootrom *bootrom = greybus_get_drvdata(bundle);
+
+ dev_dbg(&bundle->dev, "%s\n", __func__);
+
+ gb_connection_disable(bootrom->connection);
+
+ /* Disable timeouts */
+ gb_bootrom_cancel_timeout(bootrom);
+
+ /*
+ * Release firmware:
+ *
+ * As the connection and the delayed work are already disabled, we don't
+ * need to lock access to bootrom->fw here.
+ */
+ free_firmware(bootrom);
+
+ gb_connection_destroy(bootrom->connection);
+ kfree(bootrom);
+}
+
+static const struct greybus_bundle_id gb_bootrom_id_table[] = {
+ { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_BOOTROM) },
+ { }
+};
+
+static struct greybus_driver gb_bootrom_driver = {
+ .name = "bootrom",
+ .probe = gb_bootrom_probe,
+ .disconnect = gb_bootrom_disconnect,
+ .id_table = gb_bootrom_id_table,
+};
+
+module_greybus_driver(gb_bootrom_driver);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/bundle.c b/drivers/staging/greybus/bundle.c
new file mode 100644
index 000000000000..d2ef57d090be
--- /dev/null
+++ b/drivers/staging/greybus/bundle.c
@@ -0,0 +1,253 @@
+/*
+ * Greybus bundles
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include "greybus.h"
+#include "greybus_trace.h"
+
+static ssize_t bundle_class_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+
+ return sprintf(buf, "0x%02x\n", bundle->class);
+}
+static DEVICE_ATTR_RO(bundle_class);
+
+static ssize_t bundle_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+
+ return sprintf(buf, "%u\n", bundle->id);
+}
+static DEVICE_ATTR_RO(bundle_id);
+
+static ssize_t state_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+
+ if (bundle->state == NULL)
+ return sprintf(buf, "\n");
+
+ return sprintf(buf, "%s\n", bundle->state);
+}
+
+static ssize_t state_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+
+ kfree(bundle->state);
+ bundle->state = kstrdup(buf, GFP_KERNEL);
+ if (!bundle->state)
+ return -ENOMEM;
+
+ /* Tell userspace that the file contents changed */
+ sysfs_notify(&bundle->dev.kobj, NULL, "state");
+
+ return size;
+}
+static DEVICE_ATTR_RW(state);
+
+static struct attribute *bundle_attrs[] = {
+ &dev_attr_bundle_class.attr,
+ &dev_attr_bundle_id.attr,
+ &dev_attr_state.attr,
+ NULL,
+};
+
+ATTRIBUTE_GROUPS(bundle);
+
+static struct gb_bundle *gb_bundle_find(struct gb_interface *intf,
+ u8 bundle_id)
+{
+ struct gb_bundle *bundle;
+
+ list_for_each_entry(bundle, &intf->bundles, links) {
+ if (bundle->id == bundle_id)
+ return bundle;
+ }
+
+ return NULL;
+}
+
+static void gb_bundle_release(struct device *dev)
+{
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+
+ trace_gb_bundle_release(bundle);
+
+ kfree(bundle->state);
+ kfree(bundle->cport_desc);
+ kfree(bundle);
+}
+
+#ifdef CONFIG_PM
+static void gb_bundle_disable_all_connections(struct gb_bundle *bundle)
+{
+ struct gb_connection *connection;
+
+ list_for_each_entry(connection, &bundle->connections, bundle_links)
+ gb_connection_disable(connection);
+}
+
+static void gb_bundle_enable_all_connections(struct gb_bundle *bundle)
+{
+ struct gb_connection *connection;
+
+ list_for_each_entry(connection, &bundle->connections, bundle_links)
+ gb_connection_enable(connection);
+}
+
+static int gb_bundle_suspend(struct device *dev)
+{
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+ const struct dev_pm_ops *pm = dev->driver->pm;
+ int ret;
+
+ if (pm && pm->runtime_suspend) {
+ ret = pm->runtime_suspend(&bundle->dev);
+ if (ret)
+ return ret;
+ } else {
+ gb_bundle_disable_all_connections(bundle);
+ }
+
+ ret = gb_control_bundle_suspend(bundle->intf->control, bundle->id);
+ if (ret) {
+ if (pm && pm->runtime_resume)
+ ret = pm->runtime_resume(dev);
+ else
+ gb_bundle_enable_all_connections(bundle);
+
+ return ret;
+ }
+
+ return 0;
+}
+
+static int gb_bundle_resume(struct device *dev)
+{
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+ const struct dev_pm_ops *pm = dev->driver->pm;
+ int ret;
+
+ ret = gb_control_bundle_resume(bundle->intf->control, bundle->id);
+ if (ret)
+ return ret;
+
+ if (pm && pm->runtime_resume) {
+ ret = pm->runtime_resume(dev);
+ if (ret)
+ return ret;
+ } else {
+ gb_bundle_enable_all_connections(bundle);
+ }
+
+ return 0;
+}
+
+static int gb_bundle_idle(struct device *dev)
+{
+ pm_runtime_mark_last_busy(dev);
+ pm_request_autosuspend(dev);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops gb_bundle_pm_ops = {
+ SET_RUNTIME_PM_OPS(gb_bundle_suspend, gb_bundle_resume, gb_bundle_idle)
+};
+
+struct device_type greybus_bundle_type = {
+ .name = "greybus_bundle",
+ .release = gb_bundle_release,
+ .pm = &gb_bundle_pm_ops,
+};
+
+/*
+ * Create a gb_bundle structure to represent a discovered
+ * bundle. Returns a pointer to the new bundle or a null
+ * pointer if a failure occurs due to memory exhaustion.
+ */
+struct gb_bundle *gb_bundle_create(struct gb_interface *intf, u8 bundle_id,
+ u8 class)
+{
+ struct gb_bundle *bundle;
+
+ if (bundle_id == BUNDLE_ID_NONE) {
+ dev_err(&intf->dev, "can't use bundle id %u\n", bundle_id);
+ return NULL;
+ }
+
+ /*
+ * Reject any attempt to reuse a bundle id. We initialize
+ * these serially, so there's no need to worry about keeping
+ * the interface bundle list locked here.
+ */
+ if (gb_bundle_find(intf, bundle_id)) {
+ dev_err(&intf->dev, "duplicate bundle id %u\n", bundle_id);
+ return NULL;
+ }
+
+ bundle = kzalloc(sizeof(*bundle), GFP_KERNEL);
+ if (!bundle)
+ return NULL;
+
+ bundle->intf = intf;
+ bundle->id = bundle_id;
+ bundle->class = class;
+ INIT_LIST_HEAD(&bundle->connections);
+
+ bundle->dev.parent = &intf->dev;
+ bundle->dev.bus = &greybus_bus_type;
+ bundle->dev.type = &greybus_bundle_type;
+ bundle->dev.groups = bundle_groups;
+ bundle->dev.dma_mask = intf->dev.dma_mask;
+ device_initialize(&bundle->dev);
+ dev_set_name(&bundle->dev, "%s.%d", dev_name(&intf->dev), bundle_id);
+
+ list_add(&bundle->links, &intf->bundles);
+
+ trace_gb_bundle_create(bundle);
+
+ return bundle;
+}
+
+int gb_bundle_add(struct gb_bundle *bundle)
+{
+ int ret;
+
+ ret = device_add(&bundle->dev);
+ if (ret) {
+ dev_err(&bundle->dev, "failed to register bundle: %d\n", ret);
+ return ret;
+ }
+
+ trace_gb_bundle_add(bundle);
+
+ return 0;
+}
+
+/*
+ * Tear down a previously set up bundle.
+ */
+void gb_bundle_destroy(struct gb_bundle *bundle)
+{
+ trace_gb_bundle_destroy(bundle);
+
+ if (device_is_registered(&bundle->dev))
+ device_del(&bundle->dev);
+
+ list_del(&bundle->links);
+
+ put_device(&bundle->dev);
+}
diff --git a/drivers/staging/greybus/bundle.h b/drivers/staging/greybus/bundle.h
new file mode 100644
index 000000000000..0c3491def96c
--- /dev/null
+++ b/drivers/staging/greybus/bundle.h
@@ -0,0 +1,90 @@
+/*
+ * Greybus bundles
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __BUNDLE_H
+#define __BUNDLE_H
+
+#include <linux/list.h>
+
+#define BUNDLE_ID_NONE U8_MAX
+
+/* Greybus "public" definitions" */
+struct gb_bundle {
+ struct device dev;
+ struct gb_interface *intf;
+
+ u8 id;
+ u8 class;
+ u8 class_major;
+ u8 class_minor;
+
+ size_t num_cports;
+ struct greybus_descriptor_cport *cport_desc;
+
+ struct list_head connections;
+ u8 *state;
+
+ struct list_head links; /* interface->bundles */
+};
+#define to_gb_bundle(d) container_of(d, struct gb_bundle, dev)
+
+/* Greybus "private" definitions" */
+struct gb_bundle *gb_bundle_create(struct gb_interface *intf, u8 bundle_id,
+ u8 class);
+int gb_bundle_add(struct gb_bundle *bundle);
+void gb_bundle_destroy(struct gb_bundle *bundle);
+
+/* Bundle Runtime PM wrappers */
+#ifdef CONFIG_PM
+static inline int gb_pm_runtime_get_sync(struct gb_bundle *bundle)
+{
+ int retval;
+
+ retval = pm_runtime_get_sync(&bundle->dev);
+ if (retval < 0) {
+ dev_err(&bundle->dev,
+ "pm_runtime_get_sync failed: %d\n", retval);
+ pm_runtime_put_noidle(&bundle->dev);
+ return retval;
+ }
+
+ return 0;
+}
+
+static inline int gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle)
+{
+ int retval;
+
+ pm_runtime_mark_last_busy(&bundle->dev);
+ retval = pm_runtime_put_autosuspend(&bundle->dev);
+
+ return retval;
+}
+
+static inline void gb_pm_runtime_get_noresume(struct gb_bundle *bundle)
+{
+ pm_runtime_get_noresume(&bundle->dev);
+}
+
+static inline void gb_pm_runtime_put_noidle(struct gb_bundle *bundle)
+{
+ pm_runtime_put_noidle(&bundle->dev);
+}
+
+#else
+static inline int gb_pm_runtime_get_sync(struct gb_bundle *bundle)
+{ return 0; }
+static inline int gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle)
+{ return 0; }
+
+static inline void gb_pm_runtime_get_noresume(struct gb_bundle *bundle) {}
+static inline void gb_pm_runtime_put_noidle(struct gb_bundle *bundle) {}
+#endif
+
+#endif /* __BUNDLE_H */
diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c
new file mode 100644
index 000000000000..491bdd720c0c
--- /dev/null
+++ b/drivers/staging/greybus/camera.c
@@ -0,0 +1,1400 @@
+/*
+ * Greybus Camera protocol driver.
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright 2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+
+#include "gb-camera.h"
+#include "greybus.h"
+#include "greybus_protocols.h"
+
+enum gb_camera_debugs_buffer_id {
+ GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES,
+ GB_CAMERA_DEBUGFS_BUFFER_STREAMS,
+ GB_CAMERA_DEBUGFS_BUFFER_CAPTURE,
+ GB_CAMERA_DEBUGFS_BUFFER_FLUSH,
+ GB_CAMERA_DEBUGFS_BUFFER_MAX,
+};
+
+struct gb_camera_debugfs_buffer {
+ char data[PAGE_SIZE];
+ size_t length;
+};
+
+enum gb_camera_state {
+ GB_CAMERA_STATE_UNCONFIGURED,
+ GB_CAMERA_STATE_CONFIGURED,
+};
+
+/**
+ * struct gb_camera - A Greybus Camera Device
+ * @connection: the greybus connection for camera management
+ * @data_connection: the greybus connection for camera data
+ * @data_cport_id: the data CPort ID on the module side
+ * @mutex: protects the connection and state fields
+ * @state: the current module state
+ * @debugfs: debugfs entries for camera protocol operations testing
+ * @module: Greybus camera module registered to HOST processor.
+ */
+struct gb_camera {
+ struct gb_bundle *bundle;
+ struct gb_connection *connection;
+ struct gb_connection *data_connection;
+ u16 data_cport_id;
+
+ struct mutex mutex;
+ enum gb_camera_state state;
+
+ struct {
+ struct dentry *root;
+ struct gb_camera_debugfs_buffer *buffers;
+ } debugfs;
+
+ struct gb_camera_module module;
+};
+
+struct gb_camera_stream_config {
+ unsigned int width;
+ unsigned int height;
+ unsigned int format;
+ unsigned int vc;
+ unsigned int dt[2];
+ unsigned int max_size;
+};
+
+struct gb_camera_fmt_info {
+ enum v4l2_mbus_pixelcode mbus_code;
+ unsigned int gb_format;
+ unsigned int bpp;
+};
+
+/* GB format to media code map */
+static const struct gb_camera_fmt_info gb_fmt_info[] = {
+ {
+ .mbus_code = V4L2_MBUS_FMT_UYVY8_1X16,
+ .gb_format = 0x01,
+ .bpp = 16,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_NV12_1x8,
+ .gb_format = 0x12,
+ .bpp = 12,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_NV21_1x8,
+ .gb_format = 0x13,
+ .bpp = 12,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_YU12_1x8,
+ .gb_format = 0x16,
+ .bpp = 12,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_YV12_1x8,
+ .gb_format = 0x17,
+ .bpp = 12,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_JPEG_1X8,
+ .gb_format = 0x40,
+ .bpp = 0,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_GB_CAM_METADATA_1X8,
+ .gb_format = 0x41,
+ .bpp = 0,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_GB_CAM_DEBUG_DATA_1X8,
+ .gb_format = 0x42,
+ .bpp = 0,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_SBGGR10_1X10,
+ .gb_format = 0x80,
+ .bpp = 10,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_SGBRG10_1X10,
+ .gb_format = 0x81,
+ .bpp = 10,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_SGRBG10_1X10,
+ .gb_format = 0x82,
+ .bpp = 10,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_SRGGB10_1X10,
+ .gb_format = 0x83,
+ .bpp = 10,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_SBGGR12_1X12,
+ .gb_format = 0x84,
+ .bpp = 12,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_SGBRG12_1X12,
+ .gb_format = 0x85,
+ .bpp = 12,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_SGRBG12_1X12,
+ .gb_format = 0x86,
+ .bpp = 12,
+ },
+ {
+ .mbus_code = V4L2_MBUS_FMT_SRGGB12_1X12,
+ .gb_format = 0x87,
+ .bpp = 12,
+ },
+};
+
+static const struct gb_camera_fmt_info *gb_camera_get_format_info(u16 gb_fmt)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(gb_fmt_info); i++) {
+ if (gb_fmt_info[i].gb_format == gb_fmt)
+ return &gb_fmt_info[i];
+ }
+
+ return NULL;
+}
+
+#define ES2_APB_CDSI0_CPORT 16
+#define ES2_APB_CDSI1_CPORT 17
+
+#define GB_CAMERA_MAX_SETTINGS_SIZE 8192
+
+#define gcam_dbg(gcam, format...) dev_dbg(&gcam->bundle->dev, format)
+#define gcam_info(gcam, format...) dev_info(&gcam->bundle->dev, format)
+#define gcam_err(gcam, format...) dev_err(&gcam->bundle->dev, format)
+
+static int gb_camera_operation_sync_flags(struct gb_connection *connection,
+ int type, unsigned int flags,
+ void *request, size_t request_size,
+ void *response, size_t *response_size)
+{
+ struct gb_operation *operation;
+ int ret;
+
+ operation = gb_operation_create_flags(connection, type, request_size,
+ *response_size, flags,
+ GFP_KERNEL);
+ if (!operation)
+ return -ENOMEM;
+
+ if (request_size)
+ memcpy(operation->request->payload, request, request_size);
+
+ ret = gb_operation_request_send_sync(operation);
+ if (ret) {
+ dev_err(&connection->hd->dev,
+ "%s: synchronous operation of type 0x%02x failed: %d\n",
+ connection->name, type, ret);
+ } else {
+ *response_size = operation->response->payload_size;
+
+ if (operation->response->payload_size)
+ memcpy(response, operation->response->payload,
+ operation->response->payload_size);
+ }
+
+ gb_operation_put(operation);
+
+ return ret;
+}
+
+static int gb_camera_get_max_pkt_size(struct gb_camera *gcam,
+ struct gb_camera_configure_streams_response *resp)
+{
+ unsigned int max_pkt_size = 0;
+ unsigned int i;
+
+ for (i = 0; i < resp->num_streams; i++) {
+ struct gb_camera_stream_config_response *cfg = &resp->config[i];
+ const struct gb_camera_fmt_info *fmt_info;
+ unsigned int pkt_size;
+
+ fmt_info = gb_camera_get_format_info(cfg->format);
+ if (!fmt_info) {
+ gcam_err(gcam, "unsupported greybus image format: %d\n",
+ cfg->format);
+ return -EIO;
+ }
+
+ if (fmt_info->bpp == 0) {
+ pkt_size = le32_to_cpu(cfg->max_pkt_size);
+
+ if (pkt_size == 0) {
+ gcam_err(gcam,
+ "Stream %u: invalid zero maximum packet size\n",
+ i);
+ return -EIO;
+ }
+ } else {
+ pkt_size = le16_to_cpu(cfg->width) * fmt_info->bpp / 8;
+
+ if (pkt_size != le32_to_cpu(cfg->max_pkt_size)) {
+ gcam_err(gcam,
+ "Stream %u: maximum packet size mismatch (%u/%u)\n",
+ i, pkt_size, cfg->max_pkt_size);
+ return -EIO;
+ }
+ }
+
+ max_pkt_size = max(pkt_size, max_pkt_size);
+ }
+
+ return max_pkt_size;
+}
+
+/*
+ * Validate the stream configuration response verifying padding is correctly
+ * set and the returned number of streams is supported
+ */
+static const int gb_camera_configure_streams_validate_response(
+ struct gb_camera *gcam,
+ struct gb_camera_configure_streams_response *resp,
+ unsigned int nstreams)
+{
+ unsigned int i;
+
+ /* Validate the returned response structure */
+ if (resp->padding[0] || resp->padding[1]) {
+ gcam_err(gcam, "response padding != 0\n");
+ return -EIO;
+ }
+
+ if (resp->num_streams > nstreams) {
+ gcam_err(gcam, "got #streams %u > request %u\n",
+ resp->num_streams, nstreams);
+ return -EIO;
+ }
+
+ for (i = 0; i < resp->num_streams; i++) {
+ struct gb_camera_stream_config_response *cfg = &resp->config[i];
+ if (cfg->padding) {
+ gcam_err(gcam, "stream #%u padding != 0\n", i);
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Hardware Configuration
+ */
+
+static int gb_camera_set_intf_power_mode(struct gb_camera *gcam, u8 intf_id,
+ bool hs)
+{
+ struct gb_svc *svc = gcam->connection->hd->svc;
+ int ret;
+
+ if (hs)
+ ret = gb_svc_intf_set_power_mode(svc, intf_id,
+ GB_SVC_UNIPRO_HS_SERIES_A,
+ GB_SVC_UNIPRO_FAST_MODE, 2, 2,
+ GB_SVC_SMALL_AMPLITUDE,
+ GB_SVC_NO_DE_EMPHASIS,
+ GB_SVC_UNIPRO_FAST_MODE, 2, 2,
+ GB_SVC_PWRM_RXTERMINATION |
+ GB_SVC_PWRM_TXTERMINATION, 0,
+ NULL, NULL);
+ else
+ ret = gb_svc_intf_set_power_mode(svc, intf_id,
+ GB_SVC_UNIPRO_HS_SERIES_A,
+ GB_SVC_UNIPRO_SLOW_AUTO_MODE,
+ 2, 1,
+ GB_SVC_SMALL_AMPLITUDE,
+ GB_SVC_NO_DE_EMPHASIS,
+ GB_SVC_UNIPRO_SLOW_AUTO_MODE,
+ 2, 1,
+ 0, 0,
+ NULL, NULL);
+
+ return ret;
+}
+
+static int gb_camera_set_power_mode(struct gb_camera *gcam, bool hs)
+{
+ struct gb_interface *intf = gcam->connection->intf;
+ struct gb_svc *svc = gcam->connection->hd->svc;
+ int ret;
+
+ ret = gb_camera_set_intf_power_mode(gcam, intf->interface_id, hs);
+ if (ret < 0) {
+ gcam_err(gcam, "failed to set module interface to %s (%d)\n",
+ hs ? "HS" : "PWM", ret);
+ return ret;
+ }
+
+ ret = gb_camera_set_intf_power_mode(gcam, svc->ap_intf_id, hs);
+ if (ret < 0) {
+ gb_camera_set_intf_power_mode(gcam, intf->interface_id, !hs);
+ gcam_err(gcam, "failed to set AP interface to %s (%d)\n",
+ hs ? "HS" : "PWM", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+struct ap_csi_config_request {
+ __u8 csi_id;
+ __u8 flags;
+#define GB_CAMERA_CSI_FLAG_CLOCK_CONTINUOUS 0x01
+ __u8 num_lanes;
+ __u8 padding;
+ __le32 csi_clk_freq;
+ __le32 max_pkt_size;
+} __packed;
+
+/*
+ * TODO: Compute the number of lanes dynamically based on bandwidth
+ * requirements.
+ */
+#define GB_CAMERA_CSI_NUM_DATA_LANES 4
+
+#define GB_CAMERA_CSI_CLK_FREQ_MAX 999000000U
+#define GB_CAMERA_CSI_CLK_FREQ_MIN 100000000U
+#define GB_CAMERA_CSI_CLK_FREQ_MARGIN 150000000U
+
+static int gb_camera_setup_data_connection(struct gb_camera *gcam,
+ struct gb_camera_configure_streams_response *resp,
+ struct gb_camera_csi_params *csi_params)
+{
+ struct ap_csi_config_request csi_cfg;
+ struct gb_connection *conn;
+ unsigned int clk_freq;
+ int ret;
+
+ /*
+ * Create the data connection between the camera module data CPort and
+ * APB CDSI1. The CDSI1 CPort ID is hardcoded by the ES2 bridge.
+ */
+ conn = gb_connection_create_offloaded(gcam->bundle, gcam->data_cport_id,
+ GB_CONNECTION_FLAG_NO_FLOWCTRL |
+ GB_CONNECTION_FLAG_CDSI1);
+ if (IS_ERR(conn))
+ return PTR_ERR(conn);
+
+ gcam->data_connection = conn;
+ gb_connection_set_data(conn, gcam);
+
+ ret = gb_connection_enable(conn);
+ if (ret)
+ goto error_conn_destroy;
+
+ /* Set the UniPro link to high speed mode. */
+ ret = gb_camera_set_power_mode(gcam, true);
+ if (ret < 0)
+ goto error_conn_disable;
+
+ /*
+ * Configure the APB-A CSI-2 transmitter.
+ *
+ * Hardcode the number of lanes to 4 and compute the bus clock frequency
+ * based on the module bandwidth requirements with a safety margin.
+ */
+ memset(&csi_cfg, 0, sizeof(csi_cfg));
+ csi_cfg.csi_id = 1;
+ csi_cfg.flags = 0;
+ csi_cfg.num_lanes = GB_CAMERA_CSI_NUM_DATA_LANES;
+
+ clk_freq = resp->data_rate / 2 / GB_CAMERA_CSI_NUM_DATA_LANES;
+ clk_freq = clamp(clk_freq + GB_CAMERA_CSI_CLK_FREQ_MARGIN,
+ GB_CAMERA_CSI_CLK_FREQ_MIN,
+ GB_CAMERA_CSI_CLK_FREQ_MAX);
+ csi_cfg.csi_clk_freq = clk_freq;
+
+ ret = gb_camera_get_max_pkt_size(gcam, resp);
+ if (ret < 0) {
+ ret = -EIO;
+ goto error_power;
+ }
+ csi_cfg.max_pkt_size = ret;
+
+ ret = gb_hd_output(gcam->connection->hd, &csi_cfg,
+ sizeof(csi_cfg),
+ GB_APB_REQUEST_CSI_TX_CONTROL, false);
+ if (ret < 0) {
+ gcam_err(gcam, "failed to start the CSI transmitter\n");
+ goto error_power;
+ }
+
+ if (csi_params) {
+ csi_params->clk_freq = csi_cfg.csi_clk_freq;
+ csi_params->num_lanes = csi_cfg.num_lanes;
+ }
+
+ return 0;
+
+error_power:
+ gb_camera_set_power_mode(gcam, false);
+error_conn_disable:
+ gb_connection_disable(gcam->data_connection);
+error_conn_destroy:
+ gb_connection_destroy(gcam->data_connection);
+ gcam->data_connection = NULL;
+ return ret;
+}
+
+static void gb_camera_teardown_data_connection(struct gb_camera *gcam)
+{
+ struct ap_csi_config_request csi_cfg;
+ int ret;
+
+ /* Stop the APB1 CSI transmitter. */
+ memset(&csi_cfg, 0, sizeof(csi_cfg));
+ csi_cfg.csi_id = 1;
+
+ ret = gb_hd_output(gcam->connection->hd, &csi_cfg,
+ sizeof(csi_cfg),
+ GB_APB_REQUEST_CSI_TX_CONTROL, false);
+
+ if (ret < 0)
+ gcam_err(gcam, "failed to stop the CSI transmitter\n");
+
+ /* Set the UniPro link to low speed mode. */
+ gb_camera_set_power_mode(gcam, false);
+
+ /* Destroy the data connection. */
+ gb_connection_disable(gcam->data_connection);
+ gb_connection_destroy(gcam->data_connection);
+ gcam->data_connection = NULL;
+}
+
+/* -----------------------------------------------------------------------------
+ * Camera Protocol Operations
+ */
+
+static int gb_camera_capabilities(struct gb_camera *gcam,
+ u8 *capabilities, size_t *size)
+{
+ int ret;
+
+ ret = gb_pm_runtime_get_sync(gcam->bundle);
+ if (ret)
+ return ret;
+
+ mutex_lock(&gcam->mutex);
+
+ if (!gcam->connection) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = gb_camera_operation_sync_flags(gcam->connection,
+ GB_CAMERA_TYPE_CAPABILITIES,
+ GB_OPERATION_FLAG_SHORT_RESPONSE,
+ NULL, 0,
+ (void *)capabilities, size);
+ if (ret)
+ gcam_err(gcam, "failed to retrieve capabilities: %d\n", ret);
+
+done:
+ mutex_unlock(&gcam->mutex);
+
+ gb_pm_runtime_put_autosuspend(gcam->bundle);
+
+ return ret;
+}
+
+static int gb_camera_configure_streams(struct gb_camera *gcam,
+ unsigned int *num_streams,
+ unsigned int *flags,
+ struct gb_camera_stream_config *streams,
+ struct gb_camera_csi_params *csi_params)
+{
+ struct gb_camera_configure_streams_request *req;
+ struct gb_camera_configure_streams_response *resp;
+ unsigned int nstreams = *num_streams;
+ unsigned int i;
+ size_t req_size;
+ size_t resp_size;
+ int ret;
+
+ if (nstreams > GB_CAMERA_MAX_STREAMS)
+ return -EINVAL;
+
+ req_size = sizeof(*req) + nstreams * sizeof(req->config[0]);
+ resp_size = sizeof(*resp) + nstreams * sizeof(resp->config[0]);
+
+ req = kmalloc(req_size, GFP_KERNEL);
+ resp = kmalloc(resp_size, GFP_KERNEL);
+ if (!req || !resp) {
+ kfree(req);
+ kfree(resp);
+ return -ENOMEM;
+ }
+
+ req->num_streams = nstreams;
+ req->flags = *flags;
+ req->padding = 0;
+
+ for (i = 0; i < nstreams; ++i) {
+ struct gb_camera_stream_config_request *cfg = &req->config[i];
+
+ cfg->width = cpu_to_le16(streams[i].width);
+ cfg->height = cpu_to_le16(streams[i].height);
+ cfg->format = cpu_to_le16(streams[i].format);
+ cfg->padding = 0;
+ }
+
+ mutex_lock(&gcam->mutex);
+
+ ret = gb_pm_runtime_get_sync(gcam->bundle);
+ if (ret)
+ goto done_skip_pm_put;
+
+ if (!gcam->connection) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = gb_camera_operation_sync_flags(gcam->connection,
+ GB_CAMERA_TYPE_CONFIGURE_STREAMS,
+ GB_OPERATION_FLAG_SHORT_RESPONSE,
+ req, req_size,
+ resp, &resp_size);
+ if (ret < 0)
+ goto done;
+
+ ret = gb_camera_configure_streams_validate_response(gcam, resp,
+ nstreams);
+ if (ret < 0)
+ goto done;
+
+ *flags = resp->flags;
+ *num_streams = resp->num_streams;
+
+ for (i = 0; i < resp->num_streams; ++i) {
+ struct gb_camera_stream_config_response *cfg = &resp->config[i];
+
+ streams[i].width = le16_to_cpu(cfg->width);
+ streams[i].height = le16_to_cpu(cfg->height);
+ streams[i].format = le16_to_cpu(cfg->format);
+ streams[i].vc = cfg->virtual_channel;
+ streams[i].dt[0] = cfg->data_type[0];
+ streams[i].dt[1] = cfg->data_type[1];
+ streams[i].max_size = le32_to_cpu(cfg->max_size);
+ }
+
+ if ((resp->flags & GB_CAMERA_CONFIGURE_STREAMS_ADJUSTED) ||
+ (req->flags & GB_CAMERA_CONFIGURE_STREAMS_TEST_ONLY))
+ goto done;
+
+ if (gcam->state == GB_CAMERA_STATE_CONFIGURED) {
+ gb_camera_teardown_data_connection(gcam);
+ gcam->state = GB_CAMERA_STATE_UNCONFIGURED;
+
+ /*
+ * When unconfiguring streams release the PM runtime reference
+ * that was acquired when streams were configured. The bundle
+ * won't be suspended until the PM runtime reference acquired at
+ * the beginning of this function gets released right before
+ * returning.
+ */
+ gb_pm_runtime_put_noidle(gcam->bundle);
+ }
+
+ if (resp->num_streams == 0)
+ goto done;
+
+ /*
+ * Make sure the bundle won't be suspended until streams get
+ * unconfigured after the stream is configured successfully
+ */
+ gb_pm_runtime_get_noresume(gcam->bundle);
+
+ /* Setup CSI-2 connection from APB-A to AP */
+ ret = gb_camera_setup_data_connection(gcam, resp, csi_params);
+ if (ret < 0) {
+ memset(req, 0, sizeof(*req));
+ gb_operation_sync(gcam->connection,
+ GB_CAMERA_TYPE_CONFIGURE_STREAMS,
+ req, sizeof(*req),
+ resp, sizeof(*resp));
+ *flags = 0;
+ *num_streams = 0;
+ gb_pm_runtime_put_noidle(gcam->bundle);
+ goto done;
+ }
+
+ gcam->state = GB_CAMERA_STATE_CONFIGURED;
+
+done:
+ gb_pm_runtime_put_autosuspend(gcam->bundle);
+
+done_skip_pm_put:
+ mutex_unlock(&gcam->mutex);
+ kfree(req);
+ kfree(resp);
+ return ret;
+}
+
+static int gb_camera_capture(struct gb_camera *gcam, u32 request_id,
+ unsigned int streams, unsigned int num_frames,
+ size_t settings_size, const void *settings)
+{
+ struct gb_camera_capture_request *req;
+ size_t req_size;
+ int ret;
+
+ if (settings_size > GB_CAMERA_MAX_SETTINGS_SIZE)
+ return -EINVAL;
+
+ req_size = sizeof(*req) + settings_size;
+ req = kmalloc(req_size, GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ req->request_id = cpu_to_le32(request_id);
+ req->streams = streams;
+ req->padding = 0;
+ req->num_frames = cpu_to_le16(num_frames);
+ memcpy(req->settings, settings, settings_size);
+
+ mutex_lock(&gcam->mutex);
+
+ if (!gcam->connection) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = gb_operation_sync(gcam->connection, GB_CAMERA_TYPE_CAPTURE,
+ req, req_size, NULL, 0);
+done:
+ mutex_unlock(&gcam->mutex);
+
+ kfree(req);
+
+ return ret;
+}
+
+static int gb_camera_flush(struct gb_camera *gcam, u32 *request_id)
+{
+ struct gb_camera_flush_response resp;
+ int ret;
+
+ mutex_lock(&gcam->mutex);
+
+ if (!gcam->connection) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = gb_operation_sync(gcam->connection, GB_CAMERA_TYPE_FLUSH, NULL, 0,
+ &resp, sizeof(resp));
+
+ if (ret < 0)
+ goto done;
+
+ if (request_id)
+ *request_id = le32_to_cpu(resp.request_id);
+
+done:
+ mutex_unlock(&gcam->mutex);
+
+ return ret;
+}
+
+static int gb_camera_request_handler(struct gb_operation *op)
+{
+ struct gb_camera *gcam = gb_connection_get_data(op->connection);
+ struct gb_camera_metadata_request *payload;
+ struct gb_message *request;
+
+ if (op->type != GB_CAMERA_TYPE_METADATA) {
+ gcam_err(gcam, "Unsupported unsolicited event: %u\n", op->type);
+ return -EINVAL;
+ }
+
+ request = op->request;
+
+ if (request->payload_size < sizeof(*payload)) {
+ gcam_err(gcam, "Wrong event size received (%zu < %zu)\n",
+ request->payload_size, sizeof(*payload));
+ return -EINVAL;
+ }
+
+ payload = request->payload;
+
+ gcam_dbg(gcam, "received metadata for request %u, frame %u, stream %u\n",
+ payload->request_id, payload->frame_number, payload->stream);
+
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Interface with HOST gmp camera.
+ */
+static unsigned int gb_camera_mbus_to_gb(enum v4l2_mbus_pixelcode mbus_code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(gb_fmt_info); i++) {
+ if (gb_fmt_info[i].mbus_code == mbus_code)
+ return gb_fmt_info[i].gb_format;
+ }
+ return gb_fmt_info[0].gb_format;
+}
+
+static enum v4l2_mbus_pixelcode gb_camera_gb_to_mbus(u16 gb_fmt)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(gb_fmt_info); i++) {
+ if (gb_fmt_info[i].gb_format == gb_fmt)
+ return gb_fmt_info[i].mbus_code;
+ }
+ return gb_fmt_info[0].mbus_code;
+}
+
+static ssize_t gb_camera_op_capabilities(void *priv, char *data, size_t len)
+{
+ struct gb_camera *gcam = priv;
+ size_t capabilities_len = len;
+ int ret;
+
+ ret = gb_camera_capabilities(gcam, data, &capabilities_len);
+ if (ret)
+ return ret;
+
+ return capabilities_len;
+}
+
+static int gb_camera_op_configure_streams(void *priv, unsigned int *nstreams,
+ unsigned int *flags, struct gb_camera_stream *streams,
+ struct gb_camera_csi_params *csi_params)
+{
+ struct gb_camera *gcam = priv;
+ struct gb_camera_stream_config *gb_streams;
+ unsigned int gb_flags = 0;
+ unsigned int gb_nstreams = *nstreams;
+ unsigned int i;
+ int ret;
+
+ if (gb_nstreams > GB_CAMERA_MAX_STREAMS)
+ return -EINVAL;
+
+ gb_streams = kzalloc(gb_nstreams * sizeof(*gb_streams), GFP_KERNEL);
+ if (!gb_streams)
+ return -ENOMEM;
+
+ for (i = 0; i < gb_nstreams; i++) {
+ gb_streams[i].width = streams[i].width;
+ gb_streams[i].height = streams[i].height;
+ gb_streams[i].format =
+ gb_camera_mbus_to_gb(streams[i].pixel_code);
+ }
+
+ if (*flags & GB_CAMERA_IN_FLAG_TEST)
+ gb_flags |= GB_CAMERA_CONFIGURE_STREAMS_TEST_ONLY;
+
+ ret = gb_camera_configure_streams(gcam, &gb_nstreams,
+ &gb_flags, gb_streams, csi_params);
+ if (ret < 0)
+ goto done;
+ if (gb_nstreams > *nstreams) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ *flags = 0;
+ if (gb_flags & GB_CAMERA_CONFIGURE_STREAMS_ADJUSTED)
+ *flags |= GB_CAMERA_OUT_FLAG_ADJUSTED;
+
+ for (i = 0; i < gb_nstreams; i++) {
+ streams[i].width = gb_streams[i].width;
+ streams[i].height = gb_streams[i].height;
+ streams[i].vc = gb_streams[i].vc;
+ streams[i].dt[0] = gb_streams[i].dt[0];
+ streams[i].dt[1] = gb_streams[i].dt[1];
+ streams[i].max_size = gb_streams[i].max_size;
+ streams[i].pixel_code =
+ gb_camera_gb_to_mbus(gb_streams[i].format);
+ }
+ *nstreams = gb_nstreams;
+
+done:
+ kfree(gb_streams);
+ return ret;
+}
+
+static int gb_camera_op_capture(void *priv, u32 request_id,
+ unsigned int streams, unsigned int num_frames,
+ size_t settings_size, const void *settings)
+{
+ struct gb_camera *gcam = priv;
+
+ return gb_camera_capture(gcam, request_id, streams, num_frames,
+ settings_size, settings);
+}
+
+static int gb_camera_op_flush(void *priv, u32 *request_id)
+{
+ struct gb_camera *gcam = priv;
+
+ return gb_camera_flush(gcam, request_id);
+}
+
+static const struct gb_camera_ops gb_cam_ops = {
+ .capabilities = gb_camera_op_capabilities,
+ .configure_streams = gb_camera_op_configure_streams,
+ .capture = gb_camera_op_capture,
+ .flush = gb_camera_op_flush,
+};
+
+/* -----------------------------------------------------------------------------
+ * DebugFS
+ */
+
+static ssize_t gb_camera_debugfs_capabilities(struct gb_camera *gcam,
+ char *buf, size_t len)
+{
+ struct gb_camera_debugfs_buffer *buffer =
+ &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES];
+ size_t size = 1024;
+ unsigned int i;
+ u8 *caps;
+ int ret;
+
+ caps = kmalloc(size, GFP_KERNEL);
+ if (!caps)
+ return -ENOMEM;
+
+ ret = gb_camera_capabilities(gcam, caps, &size);
+ if (ret < 0)
+ goto done;
+
+ /*
+ * hex_dump_to_buffer() doesn't return the number of bytes dumped prior
+ * to v4.0, we need our own implementation :-(
+ */
+ buffer->length = 0;
+
+ for (i = 0; i < size; i += 16) {
+ unsigned int nbytes = min_t(unsigned int, size - i, 16);
+
+ buffer->length += sprintf(buffer->data + buffer->length,
+ "%*ph\n", nbytes, caps + i);
+ }
+
+done:
+ kfree(caps);
+ return ret;
+}
+
+static ssize_t gb_camera_debugfs_configure_streams(struct gb_camera *gcam,
+ char *buf, size_t len)
+{
+ struct gb_camera_debugfs_buffer *buffer =
+ &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_STREAMS];
+ struct gb_camera_stream_config *streams;
+ unsigned int nstreams;
+ unsigned int flags;
+ unsigned int i;
+ char *token;
+ int ret;
+
+ /* Retrieve number of streams to configure */
+ token = strsep(&buf, ";");
+ if (token == NULL)
+ return -EINVAL;
+
+ ret = kstrtouint(token, 10, &nstreams);
+ if (ret < 0)
+ return ret;
+
+ if (nstreams > GB_CAMERA_MAX_STREAMS)
+ return -EINVAL;
+
+ token = strsep(&buf, ";");
+ if (token == NULL)
+ return -EINVAL;
+
+ ret = kstrtouint(token, 10, &flags);
+ if (ret < 0)
+ return ret;
+
+ /* For each stream to configure parse width, height and format */
+ streams = kzalloc(nstreams * sizeof(*streams), GFP_KERNEL);
+ if (!streams)
+ return -ENOMEM;
+
+ for (i = 0; i < nstreams; ++i) {
+ struct gb_camera_stream_config *stream = &streams[i];
+
+ /* width */
+ token = strsep(&buf, ";");
+ if (token == NULL) {
+ ret = -EINVAL;
+ goto done;
+ }
+ ret = kstrtouint(token, 10, &stream->width);
+ if (ret < 0)
+ goto done;
+
+ /* height */
+ token = strsep(&buf, ";");
+ if (token == NULL)
+ goto done;
+
+ ret = kstrtouint(token, 10, &stream->height);
+ if (ret < 0)
+ goto done;
+
+ /* Image format code */
+ token = strsep(&buf, ";");
+ if (token == NULL)
+ goto done;
+
+ ret = kstrtouint(token, 16, &stream->format);
+ if (ret < 0)
+ goto done;
+ }
+
+ ret = gb_camera_configure_streams(gcam, &nstreams, &flags, streams,
+ NULL);
+ if (ret < 0)
+ goto done;
+
+ buffer->length = sprintf(buffer->data, "%u;%u;", nstreams, flags);
+
+ for (i = 0; i < nstreams; ++i) {
+ struct gb_camera_stream_config *stream = &streams[i];
+
+ buffer->length += sprintf(buffer->data + buffer->length,
+ "%u;%u;%u;%u;%u;%u;%u;",
+ stream->width, stream->height,
+ stream->format, stream->vc,
+ stream->dt[0], stream->dt[1],
+ stream->max_size);
+ }
+
+ ret = len;
+
+done:
+ kfree(streams);
+ return ret;
+};
+
+static ssize_t gb_camera_debugfs_capture(struct gb_camera *gcam,
+ char *buf, size_t len)
+{
+ unsigned int request_id;
+ unsigned int streams_mask;
+ unsigned int num_frames;
+ char *token;
+ int ret;
+
+ /* Request id */
+ token = strsep(&buf, ";");
+ if (token == NULL)
+ return -EINVAL;
+ ret = kstrtouint(token, 10, &request_id);
+ if (ret < 0)
+ return ret;
+
+ /* Stream mask */
+ token = strsep(&buf, ";");
+ if (token == NULL)
+ return -EINVAL;
+ ret = kstrtouint(token, 16, &streams_mask);
+ if (ret < 0)
+ return ret;
+
+ /* number of frames */
+ token = strsep(&buf, ";");
+ if (token == NULL)
+ return -EINVAL;
+ ret = kstrtouint(token, 10, &num_frames);
+ if (ret < 0)
+ return ret;
+
+ ret = gb_camera_capture(gcam, request_id, streams_mask, num_frames, 0,
+ NULL);
+ if (ret < 0)
+ return ret;
+
+ return len;
+}
+
+static ssize_t gb_camera_debugfs_flush(struct gb_camera *gcam,
+ char *buf, size_t len)
+{
+ struct gb_camera_debugfs_buffer *buffer =
+ &gcam->debugfs.buffers[GB_CAMERA_DEBUGFS_BUFFER_FLUSH];
+ unsigned int req_id;
+ int ret;
+
+ ret = gb_camera_flush(gcam, &req_id);
+ if (ret < 0)
+ return ret;
+
+ buffer->length = sprintf(buffer->data, "%u", req_id);
+
+ return len;
+}
+
+struct gb_camera_debugfs_entry {
+ const char *name;
+ unsigned int mask;
+ unsigned int buffer;
+ ssize_t (*execute)(struct gb_camera *gcam, char *buf, size_t len);
+};
+
+static const struct gb_camera_debugfs_entry gb_camera_debugfs_entries[] = {
+ {
+ .name = "capabilities",
+ .mask = S_IFREG | S_IRUGO,
+ .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES,
+ .execute = gb_camera_debugfs_capabilities,
+ }, {
+ .name = "configure_streams",
+ .mask = S_IFREG | S_IRUGO | S_IWUGO,
+ .buffer = GB_CAMERA_DEBUGFS_BUFFER_STREAMS,
+ .execute = gb_camera_debugfs_configure_streams,
+ }, {
+ .name = "capture",
+ .mask = S_IFREG | S_IRUGO | S_IWUGO,
+ .buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPTURE,
+ .execute = gb_camera_debugfs_capture,
+ }, {
+ .name = "flush",
+ .mask = S_IFREG | S_IRUGO | S_IWUGO,
+ .buffer = GB_CAMERA_DEBUGFS_BUFFER_FLUSH,
+ .execute = gb_camera_debugfs_flush,
+ },
+};
+
+static ssize_t gb_camera_debugfs_read(struct file *file, char __user *buf,
+ size_t len, loff_t *offset)
+{
+ const struct gb_camera_debugfs_entry *op = file->private_data;
+ struct gb_camera *gcam = file->f_inode->i_private;
+ struct gb_camera_debugfs_buffer *buffer;
+ ssize_t ret;
+
+ /* For read-only entries the operation is triggered by a read. */
+ if (!(op->mask & S_IWUGO)) {
+ ret = op->execute(gcam, NULL, 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ buffer = &gcam->debugfs.buffers[op->buffer];
+
+ return simple_read_from_buffer(buf, len, offset, buffer->data,
+ buffer->length);
+}
+
+static ssize_t gb_camera_debugfs_write(struct file *file,
+ const char __user *buf, size_t len,
+ loff_t *offset)
+{
+ const struct gb_camera_debugfs_entry *op = file->private_data;
+ struct gb_camera *gcam = file->f_inode->i_private;
+ ssize_t ret;
+ char *kbuf;
+
+ if (len > 1024)
+ return -EINVAL;
+
+ kbuf = kmalloc(len + 1, GFP_KERNEL);
+ if (!kbuf)
+ return -ENOMEM;
+
+ if (copy_from_user(kbuf, buf, len)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ kbuf[len] = '\0';
+
+ ret = op->execute(gcam, kbuf, len);
+
+done:
+ kfree(kbuf);
+ return ret;
+}
+
+static int gb_camera_debugfs_open(struct inode *inode, struct file *file)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(gb_camera_debugfs_entries); ++i) {
+ const struct gb_camera_debugfs_entry *entry =
+ &gb_camera_debugfs_entries[i];
+
+ if (!strcmp(file->f_path.dentry->d_iname, entry->name)) {
+ file->private_data = (void *)entry;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static const struct file_operations gb_camera_debugfs_ops = {
+ .open = gb_camera_debugfs_open,
+ .read = gb_camera_debugfs_read,
+ .write = gb_camera_debugfs_write,
+};
+
+static int gb_camera_debugfs_init(struct gb_camera *gcam)
+{
+ struct gb_connection *connection = gcam->connection;
+ char dirname[27];
+ unsigned int i;
+
+ /*
+ * Create root debugfs entry and a file entry for each camera operation.
+ */
+ snprintf(dirname, 27, "camera-%u.%u", connection->intf->interface_id,
+ gcam->bundle->id);
+
+ gcam->debugfs.root = debugfs_create_dir(dirname, gb_debugfs_get());
+ if (IS_ERR(gcam->debugfs.root)) {
+ gcam_err(gcam, "debugfs root create failed (%ld)\n",
+ PTR_ERR(gcam->debugfs.root));
+ return PTR_ERR(gcam->debugfs.root);
+ }
+
+ gcam->debugfs.buffers = vmalloc(sizeof(*gcam->debugfs.buffers) *
+ GB_CAMERA_DEBUGFS_BUFFER_MAX);
+ if (!gcam->debugfs.buffers)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(gb_camera_debugfs_entries); ++i) {
+ const struct gb_camera_debugfs_entry *entry =
+ &gb_camera_debugfs_entries[i];
+ struct dentry *dentry;
+
+ gcam->debugfs.buffers[i].length = 0;
+
+ dentry = debugfs_create_file(entry->name, entry->mask,
+ gcam->debugfs.root, gcam,
+ &gb_camera_debugfs_ops);
+ if (IS_ERR(dentry)) {
+ gcam_err(gcam,
+ "debugfs operation %s create failed (%ld)\n",
+ entry->name, PTR_ERR(dentry));
+ return PTR_ERR(dentry);
+ }
+ }
+
+ return 0;
+}
+
+static void gb_camera_debugfs_cleanup(struct gb_camera *gcam)
+{
+ debugfs_remove_recursive(gcam->debugfs.root);
+
+ vfree(gcam->debugfs.buffers);
+}
+
+/* -----------------------------------------------------------------------------
+ * Init & Cleanup
+ */
+
+static void gb_camera_cleanup(struct gb_camera *gcam)
+{
+ gb_camera_debugfs_cleanup(gcam);
+
+ mutex_lock(&gcam->mutex);
+ if (gcam->data_connection) {
+ gb_connection_disable(gcam->data_connection);
+ gb_connection_destroy(gcam->data_connection);
+ gcam->data_connection = NULL;
+ }
+
+ if (gcam->connection) {
+ gb_connection_disable(gcam->connection);
+ gb_connection_destroy(gcam->connection);
+ gcam->connection = NULL;
+ }
+ mutex_unlock(&gcam->mutex);
+}
+
+static void gb_camera_release_module(struct kref *ref)
+{
+ struct gb_camera_module *cam_mod =
+ container_of(ref, struct gb_camera_module, refcount);
+ kfree(cam_mod->priv);
+}
+
+static int gb_camera_probe(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id)
+{
+ struct gb_connection *conn;
+ struct gb_camera *gcam;
+ u16 mgmt_cport_id = 0;
+ u16 data_cport_id = 0;
+ unsigned int i;
+ int ret;
+
+ /*
+ * The camera bundle must contain exactly two CPorts, one for the
+ * camera management protocol and one for the camera data protocol.
+ */
+ if (bundle->num_cports != 2)
+ return -ENODEV;
+
+ for (i = 0; i < bundle->num_cports; ++i) {
+ struct greybus_descriptor_cport *desc = &bundle->cport_desc[i];
+
+ switch (desc->protocol_id) {
+ case GREYBUS_PROTOCOL_CAMERA_MGMT:
+ mgmt_cport_id = le16_to_cpu(desc->id);
+ break;
+ case GREYBUS_PROTOCOL_CAMERA_DATA:
+ data_cport_id = le16_to_cpu(desc->id);
+ break;
+ default:
+ return -ENODEV;
+ }
+ }
+
+ if (!mgmt_cport_id || !data_cport_id)
+ return -ENODEV;
+
+ gcam = kzalloc(sizeof(*gcam), GFP_KERNEL);
+ if (!gcam)
+ return -ENOMEM;
+
+ mutex_init(&gcam->mutex);
+
+ gcam->bundle = bundle;
+ gcam->state = GB_CAMERA_STATE_UNCONFIGURED;
+ gcam->data_cport_id = data_cport_id;
+
+ conn = gb_connection_create(bundle, mgmt_cport_id,
+ gb_camera_request_handler);
+ if (IS_ERR(conn)) {
+ ret = PTR_ERR(conn);
+ goto error;
+ }
+
+ gcam->connection = conn;
+ gb_connection_set_data(conn, gcam);
+
+ ret = gb_connection_enable(conn);
+ if (ret)
+ goto error;
+
+ ret = gb_camera_debugfs_init(gcam);
+ if (ret < 0)
+ goto error;
+
+ gcam->module.priv = gcam;
+ gcam->module.ops = &gb_cam_ops;
+ gcam->module.interface_id = gcam->connection->intf->interface_id;
+ gcam->module.release = gb_camera_release_module;
+ ret = gb_camera_register(&gcam->module);
+ if (ret < 0)
+ goto error;
+
+ greybus_set_drvdata(bundle, gcam);
+
+ gb_pm_runtime_put_autosuspend(gcam->bundle);
+
+ return 0;
+
+error:
+ gb_camera_cleanup(gcam);
+ kfree(gcam);
+ return ret;
+}
+
+static void gb_camera_disconnect(struct gb_bundle *bundle)
+{
+ struct gb_camera *gcam = greybus_get_drvdata(bundle);
+ int ret;
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ gb_pm_runtime_get_noresume(bundle);
+
+ gb_camera_cleanup(gcam);
+ gb_camera_unregister(&gcam->module);
+}
+
+static const struct greybus_bundle_id gb_camera_id_table[] = {
+ { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_CAMERA) },
+ { },
+};
+
+#ifdef CONFIG_PM
+static int gb_camera_suspend(struct device *dev)
+{
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+ struct gb_camera *gcam = greybus_get_drvdata(bundle);
+
+ if (gcam->data_connection)
+ gb_connection_disable(gcam->data_connection);
+
+ gb_connection_disable(gcam->connection);
+
+ return 0;
+}
+
+static int gb_camera_resume(struct device *dev)
+{
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+ struct gb_camera *gcam = greybus_get_drvdata(bundle);
+ int ret;
+
+ ret = gb_connection_enable(gcam->connection);
+ if (ret) {
+ gcam_err(gcam, "failed to enable connection: %d\n", ret);
+ return ret;
+ }
+
+ if (gcam->data_connection) {
+ ret = gb_connection_enable(gcam->data_connection);
+ if (ret) {
+ gcam_err(gcam,
+ "failed to enable data connection: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops gb_camera_pm_ops = {
+ SET_RUNTIME_PM_OPS(gb_camera_suspend, gb_camera_resume, NULL)
+};
+
+static struct greybus_driver gb_camera_driver = {
+ .name = "camera",
+ .probe = gb_camera_probe,
+ .disconnect = gb_camera_disconnect,
+ .id_table = gb_camera_id_table,
+ .driver.pm = &gb_camera_pm_ops,
+};
+
+module_greybus_driver(gb_camera_driver);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c
new file mode 100644
index 000000000000..557075147f2d
--- /dev/null
+++ b/drivers/staging/greybus/connection.c
@@ -0,0 +1,938 @@
+/*
+ * Greybus connections
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/workqueue.h>
+
+#include "greybus.h"
+#include "greybus_trace.h"
+
+
+#define GB_CONNECTION_CPORT_QUIESCE_TIMEOUT 1000
+
+
+static void gb_connection_kref_release(struct kref *kref);
+
+
+static DEFINE_SPINLOCK(gb_connections_lock);
+static DEFINE_MUTEX(gb_connection_mutex);
+
+
+/* Caller holds gb_connection_mutex. */
+static bool gb_connection_cport_in_use(struct gb_interface *intf, u16 cport_id)
+{
+ struct gb_host_device *hd = intf->hd;
+ struct gb_connection *connection;
+
+ list_for_each_entry(connection, &hd->connections, hd_links) {
+ if (connection->intf == intf &&
+ connection->intf_cport_id == cport_id)
+ return true;
+ }
+
+ return false;
+}
+
+static void gb_connection_get(struct gb_connection *connection)
+{
+ kref_get(&connection->kref);
+
+ trace_gb_connection_get(connection);
+}
+
+static void gb_connection_put(struct gb_connection *connection)
+{
+ trace_gb_connection_put(connection);
+
+ kref_put(&connection->kref, gb_connection_kref_release);
+}
+
+/*
+ * Returns a reference-counted pointer to the connection if found.
+ */
+static struct gb_connection *
+gb_connection_hd_find(struct gb_host_device *hd, u16 cport_id)
+{
+ struct gb_connection *connection;
+ unsigned long flags;
+
+ spin_lock_irqsave(&gb_connections_lock, flags);
+ list_for_each_entry(connection, &hd->connections, hd_links)
+ if (connection->hd_cport_id == cport_id) {
+ gb_connection_get(connection);
+ goto found;
+ }
+ connection = NULL;
+found:
+ spin_unlock_irqrestore(&gb_connections_lock, flags);
+
+ return connection;
+}
+
+/*
+ * Callback from the host driver to let us know that data has been
+ * received on the bundle.
+ */
+void greybus_data_rcvd(struct gb_host_device *hd, u16 cport_id,
+ u8 *data, size_t length)
+{
+ struct gb_connection *connection;
+
+ trace_gb_hd_in(hd);
+
+ connection = gb_connection_hd_find(hd, cport_id);
+ if (!connection) {
+ dev_err(&hd->dev,
+ "nonexistent connection (%zu bytes dropped)\n", length);
+ return;
+ }
+ gb_connection_recv(connection, data, length);
+ gb_connection_put(connection);
+}
+EXPORT_SYMBOL_GPL(greybus_data_rcvd);
+
+static void gb_connection_kref_release(struct kref *kref)
+{
+ struct gb_connection *connection;
+
+ connection = container_of(kref, struct gb_connection, kref);
+
+ trace_gb_connection_release(connection);
+
+ kfree(connection);
+}
+
+static void gb_connection_init_name(struct gb_connection *connection)
+{
+ u16 hd_cport_id = connection->hd_cport_id;
+ u16 cport_id = 0;
+ u8 intf_id = 0;
+
+ if (connection->intf) {
+ intf_id = connection->intf->interface_id;
+ cport_id = connection->intf_cport_id;
+ }
+
+ snprintf(connection->name, sizeof(connection->name),
+ "%u/%u:%u", hd_cport_id, intf_id, cport_id);
+}
+
+/*
+ * _gb_connection_create() - create a Greybus connection
+ * @hd: host device of the connection
+ * @hd_cport_id: host-device cport id, or -1 for dynamic allocation
+ * @intf: remote interface, or NULL for static connections
+ * @bundle: remote-interface bundle (may be NULL)
+ * @cport_id: remote-interface cport id, or 0 for static connections
+ * @handler: request handler (may be NULL)
+ * @flags: connection flags
+ *
+ * Create a Greybus connection, representing the bidirectional link
+ * between a CPort on a (local) Greybus host device and a CPort on
+ * another Greybus interface.
+ *
+ * A connection also maintains the state of operations sent over the
+ * connection.
+ *
+ * Serialised against concurrent create and destroy using the
+ * gb_connection_mutex.
+ *
+ * Return: A pointer to the new connection if successful, or an ERR_PTR
+ * otherwise.
+ */
+static struct gb_connection *
+_gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
+ struct gb_interface *intf,
+ struct gb_bundle *bundle, int cport_id,
+ gb_request_handler_t handler,
+ unsigned long flags)
+{
+ struct gb_connection *connection;
+ int ret;
+
+ mutex_lock(&gb_connection_mutex);
+
+ if (intf && gb_connection_cport_in_use(intf, cport_id)) {
+ dev_err(&intf->dev, "cport %u already in use\n", cport_id);
+ ret = -EBUSY;
+ goto err_unlock;
+ }
+
+ ret = gb_hd_cport_allocate(hd, hd_cport_id, flags);
+ if (ret < 0) {
+ dev_err(&hd->dev, "failed to allocate cport: %d\n", ret);
+ goto err_unlock;
+ }
+ hd_cport_id = ret;
+
+ connection = kzalloc(sizeof(*connection), GFP_KERNEL);
+ if (!connection) {
+ ret = -ENOMEM;
+ goto err_hd_cport_release;
+ }
+
+ connection->hd_cport_id = hd_cport_id;
+ connection->intf_cport_id = cport_id;
+ connection->hd = hd;
+ connection->intf = intf;
+ connection->bundle = bundle;
+ connection->handler = handler;
+ connection->flags = flags;
+ if (intf && (intf->quirks & GB_INTERFACE_QUIRK_NO_CPORT_FEATURES))
+ connection->flags |= GB_CONNECTION_FLAG_NO_FLOWCTRL;
+ connection->state = GB_CONNECTION_STATE_DISABLED;
+
+ atomic_set(&connection->op_cycle, 0);
+ mutex_init(&connection->mutex);
+ spin_lock_init(&connection->lock);
+ INIT_LIST_HEAD(&connection->operations);
+
+ connection->wq = alloc_workqueue("%s:%d", WQ_UNBOUND, 1,
+ dev_name(&hd->dev), hd_cport_id);
+ if (!connection->wq) {
+ ret = -ENOMEM;
+ goto err_free_connection;
+ }
+
+ kref_init(&connection->kref);
+
+ gb_connection_init_name(connection);
+
+ spin_lock_irq(&gb_connections_lock);
+ list_add(&connection->hd_links, &hd->connections);
+
+ if (bundle)
+ list_add(&connection->bundle_links, &bundle->connections);
+ else
+ INIT_LIST_HEAD(&connection->bundle_links);
+
+ spin_unlock_irq(&gb_connections_lock);
+
+ mutex_unlock(&gb_connection_mutex);
+
+ trace_gb_connection_create(connection);
+
+ return connection;
+
+err_free_connection:
+ kfree(connection);
+err_hd_cport_release:
+ gb_hd_cport_release(hd, hd_cport_id);
+err_unlock:
+ mutex_unlock(&gb_connection_mutex);
+
+ return ERR_PTR(ret);
+}
+
+struct gb_connection *
+gb_connection_create_static(struct gb_host_device *hd, u16 hd_cport_id,
+ gb_request_handler_t handler)
+{
+ return _gb_connection_create(hd, hd_cport_id, NULL, NULL, 0, handler,
+ GB_CONNECTION_FLAG_HIGH_PRIO);
+}
+
+struct gb_connection *
+gb_connection_create_control(struct gb_interface *intf)
+{
+ return _gb_connection_create(intf->hd, -1, intf, NULL, 0, NULL,
+ GB_CONNECTION_FLAG_CONTROL |
+ GB_CONNECTION_FLAG_HIGH_PRIO);
+}
+
+struct gb_connection *
+gb_connection_create(struct gb_bundle *bundle, u16 cport_id,
+ gb_request_handler_t handler)
+{
+ struct gb_interface *intf = bundle->intf;
+
+ return _gb_connection_create(intf->hd, -1, intf, bundle, cport_id,
+ handler, 0);
+}
+EXPORT_SYMBOL_GPL(gb_connection_create);
+
+struct gb_connection *
+gb_connection_create_flags(struct gb_bundle *bundle, u16 cport_id,
+ gb_request_handler_t handler,
+ unsigned long flags)
+{
+ struct gb_interface *intf = bundle->intf;
+
+ if (WARN_ON_ONCE(flags & GB_CONNECTION_FLAG_CORE_MASK))
+ flags &= ~GB_CONNECTION_FLAG_CORE_MASK;
+
+ return _gb_connection_create(intf->hd, -1, intf, bundle, cport_id,
+ handler, flags);
+}
+EXPORT_SYMBOL_GPL(gb_connection_create_flags);
+
+struct gb_connection *
+gb_connection_create_offloaded(struct gb_bundle *bundle, u16 cport_id,
+ unsigned long flags)
+{
+ flags |= GB_CONNECTION_FLAG_OFFLOADED;
+
+ return gb_connection_create_flags(bundle, cport_id, NULL, flags);
+}
+EXPORT_SYMBOL_GPL(gb_connection_create_offloaded);
+
+static int gb_connection_hd_cport_enable(struct gb_connection *connection)
+{
+ struct gb_host_device *hd = connection->hd;
+ int ret;
+
+ if (!hd->driver->cport_enable)
+ return 0;
+
+ ret = hd->driver->cport_enable(hd, connection->hd_cport_id,
+ connection->flags);
+ if (ret) {
+ dev_err(&hd->dev, "%s: failed to enable host cport: %d\n",
+ connection->name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void gb_connection_hd_cport_disable(struct gb_connection *connection)
+{
+ struct gb_host_device *hd = connection->hd;
+ int ret;
+
+ if (!hd->driver->cport_disable)
+ return;
+
+ ret = hd->driver->cport_disable(hd, connection->hd_cport_id);
+ if (ret) {
+ dev_err(&hd->dev, "%s: failed to disable host cport: %d\n",
+ connection->name, ret);
+ }
+}
+
+static int gb_connection_hd_cport_connected(struct gb_connection *connection)
+{
+ struct gb_host_device *hd = connection->hd;
+ int ret;
+
+ if (!hd->driver->cport_connected)
+ return 0;
+
+ ret = hd->driver->cport_connected(hd, connection->hd_cport_id);
+ if (ret) {
+ dev_err(&hd->dev, "%s: failed to set connected state: %d\n",
+ connection->name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int gb_connection_hd_cport_flush(struct gb_connection *connection)
+{
+ struct gb_host_device *hd = connection->hd;
+ int ret;
+
+ if (!hd->driver->cport_flush)
+ return 0;
+
+ ret = hd->driver->cport_flush(hd, connection->hd_cport_id);
+ if (ret) {
+ dev_err(&hd->dev, "%s: failed to flush host cport: %d\n",
+ connection->name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int gb_connection_hd_cport_quiesce(struct gb_connection *connection)
+{
+ struct gb_host_device *hd = connection->hd;
+ size_t peer_space;
+ int ret;
+
+ peer_space = sizeof(struct gb_operation_msg_hdr) +
+ sizeof(struct gb_cport_shutdown_request);
+
+ if (connection->mode_switch)
+ peer_space += sizeof(struct gb_operation_msg_hdr);
+
+ ret = hd->driver->cport_quiesce(hd, connection->hd_cport_id,
+ peer_space,
+ GB_CONNECTION_CPORT_QUIESCE_TIMEOUT);
+ if (ret) {
+ dev_err(&hd->dev, "%s: failed to quiesce host cport: %d\n",
+ connection->name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int gb_connection_hd_cport_clear(struct gb_connection *connection)
+{
+ struct gb_host_device *hd = connection->hd;
+ int ret;
+
+ ret = hd->driver->cport_clear(hd, connection->hd_cport_id);
+ if (ret) {
+ dev_err(&hd->dev, "%s: failed to clear host cport: %d\n",
+ connection->name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Request the SVC to create a connection from AP's cport to interface's
+ * cport.
+ */
+static int
+gb_connection_svc_connection_create(struct gb_connection *connection)
+{
+ struct gb_host_device *hd = connection->hd;
+ struct gb_interface *intf;
+ u8 cport_flags;
+ int ret;
+
+ if (gb_connection_is_static(connection))
+ return 0;
+
+ intf = connection->intf;
+
+ /*
+ * Enable either E2EFC or CSD, unless no flow control is requested.
+ */
+ cport_flags = GB_SVC_CPORT_FLAG_CSV_N;
+ if (gb_connection_flow_control_disabled(connection)) {
+ cport_flags |= GB_SVC_CPORT_FLAG_CSD_N;
+ } else if (gb_connection_e2efc_enabled(connection)) {
+ cport_flags |= GB_SVC_CPORT_FLAG_CSD_N |
+ GB_SVC_CPORT_FLAG_E2EFC;
+ }
+
+ ret = gb_svc_connection_create(hd->svc,
+ hd->svc->ap_intf_id,
+ connection->hd_cport_id,
+ intf->interface_id,
+ connection->intf_cport_id,
+ cport_flags);
+ if (ret) {
+ dev_err(&connection->hd->dev,
+ "%s: failed to create svc connection: %d\n",
+ connection->name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void
+gb_connection_svc_connection_destroy(struct gb_connection *connection)
+{
+ if (gb_connection_is_static(connection))
+ return;
+
+ gb_svc_connection_destroy(connection->hd->svc,
+ connection->hd->svc->ap_intf_id,
+ connection->hd_cport_id,
+ connection->intf->interface_id,
+ connection->intf_cport_id);
+}
+
+/* Inform Interface about active CPorts */
+static int gb_connection_control_connected(struct gb_connection *connection)
+{
+ struct gb_control *control;
+ u16 cport_id = connection->intf_cport_id;
+ int ret;
+
+ if (gb_connection_is_static(connection))
+ return 0;
+
+ if (gb_connection_is_control(connection))
+ return 0;
+
+ control = connection->intf->control;
+
+ ret = gb_control_connected_operation(control, cport_id);
+ if (ret) {
+ dev_err(&connection->bundle->dev,
+ "failed to connect cport: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void
+gb_connection_control_disconnecting(struct gb_connection *connection)
+{
+ struct gb_control *control;
+ u16 cport_id = connection->intf_cport_id;
+ int ret;
+
+ if (gb_connection_is_static(connection))
+ return;
+
+ control = connection->intf->control;
+
+ ret = gb_control_disconnecting_operation(control, cport_id);
+ if (ret) {
+ dev_err(&connection->hd->dev,
+ "%s: failed to send disconnecting: %d\n",
+ connection->name, ret);
+ }
+}
+
+static void
+gb_connection_control_disconnected(struct gb_connection *connection)
+{
+ struct gb_control *control;
+ u16 cport_id = connection->intf_cport_id;
+ int ret;
+
+ if (gb_connection_is_static(connection))
+ return;
+
+ control = connection->intf->control;
+
+ if (gb_connection_is_control(connection)) {
+ if (connection->mode_switch) {
+ ret = gb_control_mode_switch_operation(control);
+ if (ret) {
+ /*
+ * Allow mode switch to time out waiting for
+ * mailbox event.
+ */
+ return;
+ }
+ }
+
+ return;
+ }
+
+ ret = gb_control_disconnected_operation(control, cport_id);
+ if (ret) {
+ dev_warn(&connection->bundle->dev,
+ "failed to disconnect cport: %d\n", ret);
+ }
+}
+
+static int gb_connection_shutdown_operation(struct gb_connection *connection,
+ u8 phase)
+{
+ struct gb_cport_shutdown_request *req;
+ struct gb_operation *operation;
+ int ret;
+
+ operation = gb_operation_create_core(connection,
+ GB_REQUEST_TYPE_CPORT_SHUTDOWN,
+ sizeof(*req), 0, 0,
+ GFP_KERNEL);
+ if (!operation)
+ return -ENOMEM;
+
+ req = operation->request->payload;
+ req->phase = phase;
+
+ ret = gb_operation_request_send_sync(operation);
+
+ gb_operation_put(operation);
+
+ return ret;
+}
+
+static int gb_connection_cport_shutdown(struct gb_connection *connection,
+ u8 phase)
+{
+ struct gb_host_device *hd = connection->hd;
+ const struct gb_hd_driver *drv = hd->driver;
+ int ret;
+
+ if (gb_connection_is_static(connection))
+ return 0;
+
+ if (gb_connection_is_offloaded(connection)) {
+ if (!drv->cport_shutdown)
+ return 0;
+
+ ret = drv->cport_shutdown(hd, connection->hd_cport_id, phase,
+ GB_OPERATION_TIMEOUT_DEFAULT);
+ } else {
+ ret = gb_connection_shutdown_operation(connection, phase);
+ }
+
+ if (ret) {
+ dev_err(&hd->dev, "%s: failed to send cport shutdown (phase %d): %d\n",
+ connection->name, phase, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+gb_connection_cport_shutdown_phase_1(struct gb_connection *connection)
+{
+ return gb_connection_cport_shutdown(connection, 1);
+}
+
+static int
+gb_connection_cport_shutdown_phase_2(struct gb_connection *connection)
+{
+ return gb_connection_cport_shutdown(connection, 2);
+}
+
+/*
+ * Cancel all active operations on a connection.
+ *
+ * Locking: Called with connection lock held and state set to DISABLED or
+ * DISCONNECTING.
+ */
+static void gb_connection_cancel_operations(struct gb_connection *connection,
+ int errno)
+ __must_hold(&connection->lock)
+{
+ struct gb_operation *operation;
+
+ while (!list_empty(&connection->operations)) {
+ operation = list_last_entry(&connection->operations,
+ struct gb_operation, links);
+ gb_operation_get(operation);
+ spin_unlock_irq(&connection->lock);
+
+ if (gb_operation_is_incoming(operation))
+ gb_operation_cancel_incoming(operation, errno);
+ else
+ gb_operation_cancel(operation, errno);
+
+ gb_operation_put(operation);
+
+ spin_lock_irq(&connection->lock);
+ }
+}
+
+/*
+ * Cancel all active incoming operations on a connection.
+ *
+ * Locking: Called with connection lock held and state set to ENABLED_TX.
+ */
+static void
+gb_connection_flush_incoming_operations(struct gb_connection *connection,
+ int errno)
+ __must_hold(&connection->lock)
+{
+ struct gb_operation *operation;
+ bool incoming;
+
+ while (!list_empty(&connection->operations)) {
+ incoming = false;
+ list_for_each_entry(operation, &connection->operations,
+ links) {
+ if (gb_operation_is_incoming(operation)) {
+ gb_operation_get(operation);
+ incoming = true;
+ break;
+ }
+ }
+
+ if (!incoming)
+ break;
+
+ spin_unlock_irq(&connection->lock);
+
+ /* FIXME: flush, not cancel? */
+ gb_operation_cancel_incoming(operation, errno);
+ gb_operation_put(operation);
+
+ spin_lock_irq(&connection->lock);
+ }
+}
+
+/*
+ * _gb_connection_enable() - enable a connection
+ * @connection: connection to enable
+ * @rx: whether to enable incoming requests
+ *
+ * Connection-enable helper for DISABLED->ENABLED, DISABLED->ENABLED_TX, and
+ * ENABLED_TX->ENABLED state transitions.
+ *
+ * Locking: Caller holds connection->mutex.
+ */
+static int _gb_connection_enable(struct gb_connection *connection, bool rx)
+{
+ int ret;
+
+ /* Handle ENABLED_TX -> ENABLED transitions. */
+ if (connection->state == GB_CONNECTION_STATE_ENABLED_TX) {
+ if (!(connection->handler && rx))
+ return 0;
+
+ spin_lock_irq(&connection->lock);
+ connection->state = GB_CONNECTION_STATE_ENABLED;
+ spin_unlock_irq(&connection->lock);
+
+ return 0;
+ }
+
+ ret = gb_connection_hd_cport_enable(connection);
+ if (ret)
+ return ret;
+
+ ret = gb_connection_svc_connection_create(connection);
+ if (ret)
+ goto err_hd_cport_clear;
+
+ ret = gb_connection_hd_cport_connected(connection);
+ if (ret)
+ goto err_svc_connection_destroy;
+
+ spin_lock_irq(&connection->lock);
+ if (connection->handler && rx)
+ connection->state = GB_CONNECTION_STATE_ENABLED;
+ else
+ connection->state = GB_CONNECTION_STATE_ENABLED_TX;
+ spin_unlock_irq(&connection->lock);
+
+ ret = gb_connection_control_connected(connection);
+ if (ret)
+ goto err_control_disconnecting;
+
+ return 0;
+
+err_control_disconnecting:
+ spin_lock_irq(&connection->lock);
+ connection->state = GB_CONNECTION_STATE_DISCONNECTING;
+ gb_connection_cancel_operations(connection, -ESHUTDOWN);
+ spin_unlock_irq(&connection->lock);
+
+ /* Transmit queue should already be empty. */
+ gb_connection_hd_cport_flush(connection);
+
+ gb_connection_control_disconnecting(connection);
+ gb_connection_cport_shutdown_phase_1(connection);
+ gb_connection_hd_cport_quiesce(connection);
+ gb_connection_cport_shutdown_phase_2(connection);
+ gb_connection_control_disconnected(connection);
+ connection->state = GB_CONNECTION_STATE_DISABLED;
+err_svc_connection_destroy:
+ gb_connection_svc_connection_destroy(connection);
+err_hd_cport_clear:
+ gb_connection_hd_cport_clear(connection);
+
+ gb_connection_hd_cport_disable(connection);
+
+ return ret;
+}
+
+int gb_connection_enable(struct gb_connection *connection)
+{
+ int ret = 0;
+
+ mutex_lock(&connection->mutex);
+
+ if (connection->state == GB_CONNECTION_STATE_ENABLED)
+ goto out_unlock;
+
+ ret = _gb_connection_enable(connection, true);
+ if (!ret)
+ trace_gb_connection_enable(connection);
+
+out_unlock:
+ mutex_unlock(&connection->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_connection_enable);
+
+int gb_connection_enable_tx(struct gb_connection *connection)
+{
+ int ret = 0;
+
+ mutex_lock(&connection->mutex);
+
+ if (connection->state == GB_CONNECTION_STATE_ENABLED) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ if (connection->state == GB_CONNECTION_STATE_ENABLED_TX)
+ goto out_unlock;
+
+ ret = _gb_connection_enable(connection, false);
+ if (!ret)
+ trace_gb_connection_enable(connection);
+
+out_unlock:
+ mutex_unlock(&connection->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_connection_enable_tx);
+
+void gb_connection_disable_rx(struct gb_connection *connection)
+{
+ mutex_lock(&connection->mutex);
+
+ spin_lock_irq(&connection->lock);
+ if (connection->state != GB_CONNECTION_STATE_ENABLED) {
+ spin_unlock_irq(&connection->lock);
+ goto out_unlock;
+ }
+ connection->state = GB_CONNECTION_STATE_ENABLED_TX;
+ gb_connection_flush_incoming_operations(connection, -ESHUTDOWN);
+ spin_unlock_irq(&connection->lock);
+
+ trace_gb_connection_disable(connection);
+
+out_unlock:
+ mutex_unlock(&connection->mutex);
+}
+EXPORT_SYMBOL_GPL(gb_connection_disable_rx);
+
+void gb_connection_mode_switch_prepare(struct gb_connection *connection)
+{
+ connection->mode_switch = true;
+}
+
+void gb_connection_mode_switch_complete(struct gb_connection *connection)
+{
+ gb_connection_svc_connection_destroy(connection);
+ gb_connection_hd_cport_clear(connection);
+
+ gb_connection_hd_cport_disable(connection);
+
+ connection->mode_switch = false;
+}
+
+void gb_connection_disable(struct gb_connection *connection)
+{
+ mutex_lock(&connection->mutex);
+
+ if (connection->state == GB_CONNECTION_STATE_DISABLED)
+ goto out_unlock;
+
+ trace_gb_connection_disable(connection);
+
+ spin_lock_irq(&connection->lock);
+ connection->state = GB_CONNECTION_STATE_DISCONNECTING;
+ gb_connection_cancel_operations(connection, -ESHUTDOWN);
+ spin_unlock_irq(&connection->lock);
+
+ gb_connection_hd_cport_flush(connection);
+
+ gb_connection_control_disconnecting(connection);
+ gb_connection_cport_shutdown_phase_1(connection);
+ gb_connection_hd_cport_quiesce(connection);
+ gb_connection_cport_shutdown_phase_2(connection);
+ gb_connection_control_disconnected(connection);
+
+ connection->state = GB_CONNECTION_STATE_DISABLED;
+
+ /* control-connection tear down is deferred when mode switching */
+ if (!connection->mode_switch) {
+ gb_connection_svc_connection_destroy(connection);
+ gb_connection_hd_cport_clear(connection);
+
+ gb_connection_hd_cport_disable(connection);
+ }
+
+out_unlock:
+ mutex_unlock(&connection->mutex);
+}
+EXPORT_SYMBOL_GPL(gb_connection_disable);
+
+/* Disable a connection without communicating with the remote end. */
+void gb_connection_disable_forced(struct gb_connection *connection)
+{
+ mutex_lock(&connection->mutex);
+
+ if (connection->state == GB_CONNECTION_STATE_DISABLED)
+ goto out_unlock;
+
+ trace_gb_connection_disable(connection);
+
+ spin_lock_irq(&connection->lock);
+ connection->state = GB_CONNECTION_STATE_DISABLED;
+ gb_connection_cancel_operations(connection, -ESHUTDOWN);
+ spin_unlock_irq(&connection->lock);
+
+ gb_connection_hd_cport_flush(connection);
+
+ gb_connection_svc_connection_destroy(connection);
+ gb_connection_hd_cport_clear(connection);
+
+ gb_connection_hd_cport_disable(connection);
+out_unlock:
+ mutex_unlock(&connection->mutex);
+}
+EXPORT_SYMBOL_GPL(gb_connection_disable_forced);
+
+/* Caller must have disabled the connection before destroying it. */
+void gb_connection_destroy(struct gb_connection *connection)
+{
+ if (!connection)
+ return;
+
+ if (WARN_ON(connection->state != GB_CONNECTION_STATE_DISABLED))
+ gb_connection_disable(connection);
+
+ mutex_lock(&gb_connection_mutex);
+
+ spin_lock_irq(&gb_connections_lock);
+ list_del(&connection->bundle_links);
+ list_del(&connection->hd_links);
+ spin_unlock_irq(&gb_connections_lock);
+
+ destroy_workqueue(connection->wq);
+
+ gb_hd_cport_release(connection->hd, connection->hd_cport_id);
+ connection->hd_cport_id = CPORT_ID_BAD;
+
+ mutex_unlock(&gb_connection_mutex);
+
+ gb_connection_put(connection);
+}
+EXPORT_SYMBOL_GPL(gb_connection_destroy);
+
+void gb_connection_latency_tag_enable(struct gb_connection *connection)
+{
+ struct gb_host_device *hd = connection->hd;
+ int ret;
+
+ if (!hd->driver->latency_tag_enable)
+ return;
+
+ ret = hd->driver->latency_tag_enable(hd, connection->hd_cport_id);
+ if (ret) {
+ dev_err(&connection->hd->dev,
+ "%s: failed to enable latency tag: %d\n",
+ connection->name, ret);
+ }
+}
+EXPORT_SYMBOL_GPL(gb_connection_latency_tag_enable);
+
+void gb_connection_latency_tag_disable(struct gb_connection *connection)
+{
+ struct gb_host_device *hd = connection->hd;
+ int ret;
+
+ if (!hd->driver->latency_tag_disable)
+ return;
+
+ ret = hd->driver->latency_tag_disable(hd, connection->hd_cport_id);
+ if (ret) {
+ dev_err(&connection->hd->dev,
+ "%s: failed to disable latency tag: %d\n",
+ connection->name, ret);
+ }
+}
+EXPORT_SYMBOL_GPL(gb_connection_latency_tag_disable);
diff --git a/drivers/staging/greybus/connection.h b/drivers/staging/greybus/connection.h
new file mode 100644
index 000000000000..4d9f4c64176c
--- /dev/null
+++ b/drivers/staging/greybus/connection.h
@@ -0,0 +1,129 @@
+/*
+ * Greybus connections
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __CONNECTION_H
+#define __CONNECTION_H
+
+#include <linux/list.h>
+#include <linux/kfifo.h>
+
+#define GB_CONNECTION_FLAG_CSD BIT(0)
+#define GB_CONNECTION_FLAG_NO_FLOWCTRL BIT(1)
+#define GB_CONNECTION_FLAG_OFFLOADED BIT(2)
+#define GB_CONNECTION_FLAG_CDSI1 BIT(3)
+#define GB_CONNECTION_FLAG_CONTROL BIT(4)
+#define GB_CONNECTION_FLAG_HIGH_PRIO BIT(5)
+
+#define GB_CONNECTION_FLAG_CORE_MASK GB_CONNECTION_FLAG_CONTROL
+
+enum gb_connection_state {
+ GB_CONNECTION_STATE_DISABLED = 0,
+ GB_CONNECTION_STATE_ENABLED_TX = 1,
+ GB_CONNECTION_STATE_ENABLED = 2,
+ GB_CONNECTION_STATE_DISCONNECTING = 3,
+};
+
+struct gb_operation;
+
+typedef int (*gb_request_handler_t)(struct gb_operation *);
+
+struct gb_connection {
+ struct gb_host_device *hd;
+ struct gb_interface *intf;
+ struct gb_bundle *bundle;
+ struct kref kref;
+ u16 hd_cport_id;
+ u16 intf_cport_id;
+
+ struct list_head hd_links;
+ struct list_head bundle_links;
+
+ gb_request_handler_t handler;
+ unsigned long flags;
+
+ struct mutex mutex;
+ spinlock_t lock;
+ enum gb_connection_state state;
+ struct list_head operations;
+
+ char name[16];
+ struct workqueue_struct *wq;
+
+ atomic_t op_cycle;
+
+ void *private;
+
+ bool mode_switch;
+};
+
+struct gb_connection *gb_connection_create_static(struct gb_host_device *hd,
+ u16 hd_cport_id, gb_request_handler_t handler);
+struct gb_connection *gb_connection_create_control(struct gb_interface *intf);
+struct gb_connection *gb_connection_create(struct gb_bundle *bundle,
+ u16 cport_id, gb_request_handler_t handler);
+struct gb_connection *gb_connection_create_flags(struct gb_bundle *bundle,
+ u16 cport_id, gb_request_handler_t handler,
+ unsigned long flags);
+struct gb_connection *gb_connection_create_offloaded(struct gb_bundle *bundle,
+ u16 cport_id, unsigned long flags);
+void gb_connection_destroy(struct gb_connection *connection);
+
+static inline bool gb_connection_is_static(struct gb_connection *connection)
+{
+ return !connection->intf;
+}
+
+int gb_connection_enable(struct gb_connection *connection);
+int gb_connection_enable_tx(struct gb_connection *connection);
+void gb_connection_disable_rx(struct gb_connection *connection);
+void gb_connection_disable(struct gb_connection *connection);
+void gb_connection_disable_forced(struct gb_connection *connection);
+
+void gb_connection_mode_switch_prepare(struct gb_connection *connection);
+void gb_connection_mode_switch_complete(struct gb_connection *connection);
+
+void greybus_data_rcvd(struct gb_host_device *hd, u16 cport_id,
+ u8 *data, size_t length);
+
+void gb_connection_latency_tag_enable(struct gb_connection *connection);
+void gb_connection_latency_tag_disable(struct gb_connection *connection);
+
+static inline bool gb_connection_e2efc_enabled(struct gb_connection *connection)
+{
+ return !(connection->flags & GB_CONNECTION_FLAG_CSD);
+}
+
+static inline bool
+gb_connection_flow_control_disabled(struct gb_connection *connection)
+{
+ return connection->flags & GB_CONNECTION_FLAG_NO_FLOWCTRL;
+}
+
+static inline bool gb_connection_is_offloaded(struct gb_connection *connection)
+{
+ return connection->flags & GB_CONNECTION_FLAG_OFFLOADED;
+}
+
+static inline bool gb_connection_is_control(struct gb_connection *connection)
+{
+ return connection->flags & GB_CONNECTION_FLAG_CONTROL;
+}
+
+static inline void *gb_connection_get_data(struct gb_connection *connection)
+{
+ return connection->private;
+}
+
+static inline void gb_connection_set_data(struct gb_connection *connection,
+ void *data)
+{
+ connection->private = data;
+}
+
+#endif /* __CONNECTION_H */
diff --git a/drivers/staging/greybus/control.c b/drivers/staging/greybus/control.c
new file mode 100644
index 000000000000..4716190e740a
--- /dev/null
+++ b/drivers/staging/greybus/control.c
@@ -0,0 +1,635 @@
+/*
+ * Greybus CPort control protocol.
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright 2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "greybus.h"
+
+/* Highest control-protocol version supported */
+#define GB_CONTROL_VERSION_MAJOR 0
+#define GB_CONTROL_VERSION_MINOR 1
+
+
+static int gb_control_get_version(struct gb_control *control)
+{
+ struct gb_interface *intf = control->connection->intf;
+ struct gb_control_version_request request;
+ struct gb_control_version_response response;
+ int ret;
+
+ request.major = GB_CONTROL_VERSION_MAJOR;
+ request.minor = GB_CONTROL_VERSION_MINOR;
+
+ ret = gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_VERSION,
+ &request, sizeof(request), &response,
+ sizeof(response));
+ if (ret) {
+ dev_err(&intf->dev,
+ "failed to get control-protocol version: %d\n",
+ ret);
+ return ret;
+ }
+
+ if (response.major > request.major) {
+ dev_err(&intf->dev,
+ "unsupported major control-protocol version (%u > %u)\n",
+ response.major, request.major);
+ return -ENOTSUPP;
+ }
+
+ control->protocol_major = response.major;
+ control->protocol_minor = response.minor;
+
+ dev_dbg(&intf->dev, "%s - %u.%u\n", __func__, response.major,
+ response.minor);
+
+ return 0;
+}
+
+static int gb_control_get_bundle_version(struct gb_control *control,
+ struct gb_bundle *bundle)
+{
+ struct gb_interface *intf = control->connection->intf;
+ struct gb_control_bundle_version_request request;
+ struct gb_control_bundle_version_response response;
+ int ret;
+
+ request.bundle_id = bundle->id;
+
+ ret = gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_BUNDLE_VERSION,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret) {
+ dev_err(&intf->dev,
+ "failed to get bundle %u class version: %d\n",
+ bundle->id, ret);
+ return ret;
+ }
+
+ bundle->class_major = response.major;
+ bundle->class_minor = response.minor;
+
+ dev_dbg(&intf->dev, "%s - %u: %u.%u\n", __func__, bundle->id,
+ response.major, response.minor);
+
+ return 0;
+}
+
+int gb_control_get_bundle_versions(struct gb_control *control)
+{
+ struct gb_interface *intf = control->connection->intf;
+ struct gb_bundle *bundle;
+ int ret;
+
+ if (!control->has_bundle_version)
+ return 0;
+
+ list_for_each_entry(bundle, &intf->bundles, links) {
+ ret = gb_control_get_bundle_version(control, bundle);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/* Get Manifest's size from the interface */
+int gb_control_get_manifest_size_operation(struct gb_interface *intf)
+{
+ struct gb_control_get_manifest_size_response response;
+ struct gb_connection *connection = intf->control->connection;
+ int ret;
+
+ ret = gb_operation_sync(connection, GB_CONTROL_TYPE_GET_MANIFEST_SIZE,
+ NULL, 0, &response, sizeof(response));
+ if (ret) {
+ dev_err(&connection->intf->dev,
+ "failed to get manifest size: %d\n", ret);
+ return ret;
+ }
+
+ return le16_to_cpu(response.size);
+}
+
+/* Reads Manifest from the interface */
+int gb_control_get_manifest_operation(struct gb_interface *intf, void *manifest,
+ size_t size)
+{
+ struct gb_connection *connection = intf->control->connection;
+
+ return gb_operation_sync(connection, GB_CONTROL_TYPE_GET_MANIFEST,
+ NULL, 0, manifest, size);
+}
+
+int gb_control_connected_operation(struct gb_control *control, u16 cport_id)
+{
+ struct gb_control_connected_request request;
+
+ request.cport_id = cpu_to_le16(cport_id);
+ return gb_operation_sync(control->connection, GB_CONTROL_TYPE_CONNECTED,
+ &request, sizeof(request), NULL, 0);
+}
+
+int gb_control_disconnected_operation(struct gb_control *control, u16 cport_id)
+{
+ struct gb_control_disconnected_request request;
+
+ request.cport_id = cpu_to_le16(cport_id);
+ return gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_DISCONNECTED, &request,
+ sizeof(request), NULL, 0);
+}
+
+int gb_control_disconnecting_operation(struct gb_control *control,
+ u16 cport_id)
+{
+ struct gb_control_disconnecting_request *request;
+ struct gb_operation *operation;
+ int ret;
+
+ operation = gb_operation_create_core(control->connection,
+ GB_CONTROL_TYPE_DISCONNECTING,
+ sizeof(*request), 0, 0,
+ GFP_KERNEL);
+ if (!operation)
+ return -ENOMEM;
+
+ request = operation->request->payload;
+ request->cport_id = cpu_to_le16(cport_id);
+
+ ret = gb_operation_request_send_sync(operation);
+ if (ret) {
+ dev_err(&control->dev, "failed to send disconnecting: %d\n",
+ ret);
+ }
+
+ gb_operation_put(operation);
+
+ return ret;
+}
+
+int gb_control_mode_switch_operation(struct gb_control *control)
+{
+ struct gb_operation *operation;
+ int ret;
+
+ operation = gb_operation_create_core(control->connection,
+ GB_CONTROL_TYPE_MODE_SWITCH,
+ 0, 0, GB_OPERATION_FLAG_UNIDIRECTIONAL,
+ GFP_KERNEL);
+ if (!operation)
+ return -ENOMEM;
+
+ ret = gb_operation_request_send_sync(operation);
+ if (ret)
+ dev_err(&control->dev, "failed to send mode switch: %d\n", ret);
+
+ gb_operation_put(operation);
+
+ return ret;
+}
+
+int gb_control_timesync_enable(struct gb_control *control, u8 count,
+ u64 frame_time, u32 strobe_delay, u32 refclk)
+{
+ struct gb_control_timesync_enable_request request;
+
+ request.count = count;
+ request.frame_time = cpu_to_le64(frame_time);
+ request.strobe_delay = cpu_to_le32(strobe_delay);
+ request.refclk = cpu_to_le32(refclk);
+ return gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_TIMESYNC_ENABLE, &request,
+ sizeof(request), NULL, 0);
+}
+
+int gb_control_timesync_disable(struct gb_control *control)
+{
+ return gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_TIMESYNC_DISABLE, NULL, 0,
+ NULL, 0);
+}
+
+int gb_control_timesync_get_last_event(struct gb_control *control,
+ u64 *frame_time)
+{
+ struct gb_control_timesync_get_last_event_response response;
+ int ret;
+
+ ret = gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_TIMESYNC_GET_LAST_EVENT,
+ NULL, 0, &response, sizeof(response));
+ if (!ret)
+ *frame_time = le64_to_cpu(response.frame_time);
+ return ret;
+}
+
+int gb_control_timesync_authoritative(struct gb_control *control,
+ u64 *frame_time)
+{
+ struct gb_control_timesync_authoritative_request request;
+ int i;
+
+ for (i = 0; i < GB_TIMESYNC_MAX_STROBES; i++)
+ request.frame_time[i] = cpu_to_le64(frame_time[i]);
+
+ return gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_TIMESYNC_AUTHORITATIVE,
+ &request, sizeof(request),
+ NULL, 0);
+}
+
+static int gb_control_bundle_pm_status_map(u8 status)
+{
+ switch (status) {
+ case GB_CONTROL_BUNDLE_PM_INVAL:
+ return -EINVAL;
+ case GB_CONTROL_BUNDLE_PM_BUSY:
+ return -EBUSY;
+ case GB_CONTROL_BUNDLE_PM_NA:
+ return -ENOMSG;
+ case GB_CONTROL_BUNDLE_PM_FAIL:
+ default:
+ return -EREMOTEIO;
+ }
+}
+
+int gb_control_bundle_suspend(struct gb_control *control, u8 bundle_id)
+{
+ struct gb_control_bundle_pm_request request;
+ struct gb_control_bundle_pm_response response;
+ int ret;
+
+ request.bundle_id = bundle_id;
+ ret = gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_BUNDLE_SUSPEND, &request,
+ sizeof(request), &response, sizeof(response));
+ if (ret) {
+ dev_err(&control->dev, "failed to send bundle %u suspend: %d\n",
+ bundle_id, ret);
+ return ret;
+ }
+
+ if (response.status != GB_CONTROL_BUNDLE_PM_OK) {
+ dev_err(&control->dev, "failed to suspend bundle %u: %d\n",
+ bundle_id, response.status);
+ return gb_control_bundle_pm_status_map(response.status);
+ }
+
+ return 0;
+}
+
+int gb_control_bundle_resume(struct gb_control *control, u8 bundle_id)
+{
+ struct gb_control_bundle_pm_request request;
+ struct gb_control_bundle_pm_response response;
+ int ret;
+
+ request.bundle_id = bundle_id;
+ ret = gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_BUNDLE_RESUME, &request,
+ sizeof(request), &response, sizeof(response));
+ if (ret) {
+ dev_err(&control->dev, "failed to send bundle %u resume: %d\n",
+ bundle_id, ret);
+ return ret;
+ }
+
+ if (response.status != GB_CONTROL_BUNDLE_PM_OK) {
+ dev_err(&control->dev, "failed to resume bundle %u: %d\n",
+ bundle_id, response.status);
+ return gb_control_bundle_pm_status_map(response.status);
+ }
+
+ return 0;
+}
+
+int gb_control_bundle_deactivate(struct gb_control *control, u8 bundle_id)
+{
+ struct gb_control_bundle_pm_request request;
+ struct gb_control_bundle_pm_response response;
+ int ret;
+
+ request.bundle_id = bundle_id;
+ ret = gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_BUNDLE_DEACTIVATE, &request,
+ sizeof(request), &response, sizeof(response));
+ if (ret) {
+ dev_err(&control->dev,
+ "failed to send bundle %u deactivate: %d\n", bundle_id,
+ ret);
+ return ret;
+ }
+
+ if (response.status != GB_CONTROL_BUNDLE_PM_OK) {
+ dev_err(&control->dev, "failed to deactivate bundle %u: %d\n",
+ bundle_id, response.status);
+ return gb_control_bundle_pm_status_map(response.status);
+ }
+
+ return 0;
+}
+
+int gb_control_bundle_activate(struct gb_control *control, u8 bundle_id)
+{
+ struct gb_control_bundle_pm_request request;
+ struct gb_control_bundle_pm_response response;
+ int ret;
+
+ if (!control->has_bundle_activate)
+ return 0;
+
+ request.bundle_id = bundle_id;
+ ret = gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_BUNDLE_ACTIVATE, &request,
+ sizeof(request), &response, sizeof(response));
+ if (ret) {
+ dev_err(&control->dev,
+ "failed to send bundle %u activate: %d\n", bundle_id,
+ ret);
+ return ret;
+ }
+
+ if (response.status != GB_CONTROL_BUNDLE_PM_OK) {
+ dev_err(&control->dev, "failed to activate bundle %u: %d\n",
+ bundle_id, response.status);
+ return gb_control_bundle_pm_status_map(response.status);
+ }
+
+ return 0;
+}
+
+static int gb_control_interface_pm_status_map(u8 status)
+{
+ switch (status) {
+ case GB_CONTROL_INTF_PM_BUSY:
+ return -EBUSY;
+ case GB_CONTROL_INTF_PM_NA:
+ return -ENOMSG;
+ default:
+ return -EREMOTEIO;
+ }
+}
+
+int gb_control_interface_suspend_prepare(struct gb_control *control)
+{
+ struct gb_control_intf_pm_response response;
+ int ret;
+
+ ret = gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_INTF_SUSPEND_PREPARE, NULL, 0,
+ &response, sizeof(response));
+ if (ret) {
+ dev_err(&control->dev,
+ "failed to send interface suspend prepare: %d\n", ret);
+ return ret;
+ }
+
+ if (response.status != GB_CONTROL_INTF_PM_OK) {
+ dev_err(&control->dev, "interface error while preparing suspend: %d\n",
+ response.status);
+ return gb_control_interface_pm_status_map(response.status);
+ }
+
+ return 0;
+}
+
+int gb_control_interface_deactivate_prepare(struct gb_control *control)
+{
+ struct gb_control_intf_pm_response response;
+ int ret;
+
+ ret = gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_INTF_DEACTIVATE_PREPARE, NULL,
+ 0, &response, sizeof(response));
+ if (ret) {
+ dev_err(&control->dev, "failed to send interface deactivate prepare: %d\n",
+ ret);
+ return ret;
+ }
+
+ if (response.status != GB_CONTROL_INTF_PM_OK) {
+ dev_err(&control->dev, "interface error while preparing deactivate: %d\n",
+ response.status);
+ return gb_control_interface_pm_status_map(response.status);
+ }
+
+ return 0;
+}
+
+int gb_control_interface_hibernate_abort(struct gb_control *control)
+{
+ struct gb_control_intf_pm_response response;
+ int ret;
+
+ ret = gb_operation_sync(control->connection,
+ GB_CONTROL_TYPE_INTF_HIBERNATE_ABORT, NULL, 0,
+ &response, sizeof(response));
+ if (ret) {
+ dev_err(&control->dev,
+ "failed to send interface aborting hibernate: %d\n",
+ ret);
+ return ret;
+ }
+
+ if (response.status != GB_CONTROL_INTF_PM_OK) {
+ dev_err(&control->dev, "interface error while aborting hibernate: %d\n",
+ response.status);
+ return gb_control_interface_pm_status_map(response.status);
+ }
+
+ return 0;
+}
+
+static ssize_t vendor_string_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_control *control = to_gb_control(dev);
+
+ return scnprintf(buf, PAGE_SIZE, "%s\n", control->vendor_string);
+}
+static DEVICE_ATTR_RO(vendor_string);
+
+static ssize_t product_string_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_control *control = to_gb_control(dev);
+
+ return scnprintf(buf, PAGE_SIZE, "%s\n", control->product_string);
+}
+static DEVICE_ATTR_RO(product_string);
+
+static struct attribute *control_attrs[] = {
+ &dev_attr_vendor_string.attr,
+ &dev_attr_product_string.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(control);
+
+static void gb_control_release(struct device *dev)
+{
+ struct gb_control *control = to_gb_control(dev);
+
+ gb_connection_destroy(control->connection);
+
+ kfree(control->vendor_string);
+ kfree(control->product_string);
+
+ kfree(control);
+}
+
+struct device_type greybus_control_type = {
+ .name = "greybus_control",
+ .release = gb_control_release,
+};
+
+struct gb_control *gb_control_create(struct gb_interface *intf)
+{
+ struct gb_connection *connection;
+ struct gb_control *control;
+
+ control = kzalloc(sizeof(*control), GFP_KERNEL);
+ if (!control)
+ return ERR_PTR(-ENOMEM);
+
+ control->intf = intf;
+
+ connection = gb_connection_create_control(intf);
+ if (IS_ERR(connection)) {
+ dev_err(&intf->dev,
+ "failed to create control connection: %ld\n",
+ PTR_ERR(connection));
+ kfree(control);
+ return ERR_CAST(connection);
+ }
+
+ control->connection = connection;
+
+ control->dev.parent = &intf->dev;
+ control->dev.bus = &greybus_bus_type;
+ control->dev.type = &greybus_control_type;
+ control->dev.groups = control_groups;
+ control->dev.dma_mask = intf->dev.dma_mask;
+ device_initialize(&control->dev);
+ dev_set_name(&control->dev, "%s.ctrl", dev_name(&intf->dev));
+
+ gb_connection_set_data(control->connection, control);
+
+ return control;
+}
+
+int gb_control_enable(struct gb_control *control)
+{
+ int ret;
+
+ dev_dbg(&control->connection->intf->dev, "%s\n", __func__);
+
+ ret = gb_connection_enable_tx(control->connection);
+ if (ret) {
+ dev_err(&control->connection->intf->dev,
+ "failed to enable control connection: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = gb_control_get_version(control);
+ if (ret)
+ goto err_disable_connection;
+
+ if (control->protocol_major > 0 || control->protocol_minor > 1)
+ control->has_bundle_version = true;
+
+ /* FIXME: use protocol version instead */
+ if (!(control->intf->quirks & GB_INTERFACE_QUIRK_NO_BUNDLE_ACTIVATE))
+ control->has_bundle_activate = true;
+
+ return 0;
+
+err_disable_connection:
+ gb_connection_disable(control->connection);
+
+ return ret;
+}
+
+void gb_control_disable(struct gb_control *control)
+{
+ dev_dbg(&control->connection->intf->dev, "%s\n", __func__);
+
+ if (control->intf->disconnected)
+ gb_connection_disable_forced(control->connection);
+ else
+ gb_connection_disable(control->connection);
+}
+
+int gb_control_suspend(struct gb_control *control)
+{
+ gb_connection_disable(control->connection);
+
+ return 0;
+}
+
+int gb_control_resume(struct gb_control *control)
+{
+ int ret;
+
+ ret = gb_connection_enable_tx(control->connection);
+ if (ret) {
+ dev_err(&control->connection->intf->dev,
+ "failed to enable control connection: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int gb_control_add(struct gb_control *control)
+{
+ int ret;
+
+ ret = device_add(&control->dev);
+ if (ret) {
+ dev_err(&control->dev,
+ "failed to register control device: %d\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+void gb_control_del(struct gb_control *control)
+{
+ if (device_is_registered(&control->dev))
+ device_del(&control->dev);
+}
+
+struct gb_control *gb_control_get(struct gb_control *control)
+{
+ get_device(&control->dev);
+
+ return control;
+}
+
+void gb_control_put(struct gb_control *control)
+{
+ put_device(&control->dev);
+}
+
+void gb_control_mode_switch_prepare(struct gb_control *control)
+{
+ gb_connection_mode_switch_prepare(control->connection);
+}
+
+void gb_control_mode_switch_complete(struct gb_control *control)
+{
+ gb_connection_mode_switch_complete(control->connection);
+}
diff --git a/drivers/staging/greybus/control.h b/drivers/staging/greybus/control.h
new file mode 100644
index 000000000000..f9a60daf9a72
--- /dev/null
+++ b/drivers/staging/greybus/control.h
@@ -0,0 +1,65 @@
+/*
+ * Greybus CPort control protocol
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright 2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __CONTROL_H
+#define __CONTROL_H
+
+struct gb_control {
+ struct device dev;
+ struct gb_interface *intf;
+
+ struct gb_connection *connection;
+
+ u8 protocol_major;
+ u8 protocol_minor;
+
+ bool has_bundle_activate;
+ bool has_bundle_version;
+
+ char *vendor_string;
+ char *product_string;
+};
+#define to_gb_control(d) container_of(d, struct gb_control, dev)
+
+struct gb_control *gb_control_create(struct gb_interface *intf);
+int gb_control_enable(struct gb_control *control);
+void gb_control_disable(struct gb_control *control);
+int gb_control_suspend(struct gb_control *control);
+int gb_control_resume(struct gb_control *control);
+int gb_control_add(struct gb_control *control);
+void gb_control_del(struct gb_control *control);
+struct gb_control *gb_control_get(struct gb_control *control);
+void gb_control_put(struct gb_control *control);
+
+int gb_control_get_bundle_versions(struct gb_control *control);
+int gb_control_connected_operation(struct gb_control *control, u16 cport_id);
+int gb_control_disconnected_operation(struct gb_control *control, u16 cport_id);
+int gb_control_disconnecting_operation(struct gb_control *control,
+ u16 cport_id);
+int gb_control_mode_switch_operation(struct gb_control *control);
+void gb_control_mode_switch_prepare(struct gb_control *control);
+void gb_control_mode_switch_complete(struct gb_control *control);
+int gb_control_get_manifest_size_operation(struct gb_interface *intf);
+int gb_control_get_manifest_operation(struct gb_interface *intf, void *manifest,
+ size_t size);
+int gb_control_timesync_enable(struct gb_control *control, u8 count,
+ u64 frame_time, u32 strobe_delay, u32 refclk);
+int gb_control_timesync_disable(struct gb_control *control);
+int gb_control_timesync_get_last_event(struct gb_control *control,
+ u64 *frame_time);
+int gb_control_timesync_authoritative(struct gb_control *control,
+ u64 *frame_time);
+int gb_control_bundle_suspend(struct gb_control *control, u8 bundle_id);
+int gb_control_bundle_resume(struct gb_control *control, u8 bundle_id);
+int gb_control_bundle_deactivate(struct gb_control *control, u8 bundle_id);
+int gb_control_bundle_activate(struct gb_control *control, u8 bundle_id);
+int gb_control_interface_suspend_prepare(struct gb_control *control);
+int gb_control_interface_deactivate_prepare(struct gb_control *control);
+int gb_control_interface_hibernate_abort(struct gb_control *control);
+#endif /* __CONTROL_H */
diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c
new file mode 100644
index 000000000000..1049e9c0edb0
--- /dev/null
+++ b/drivers/staging/greybus/core.c
@@ -0,0 +1,361 @@
+/*
+ * Greybus "Core"
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#define CREATE_TRACE_POINTS
+#include "greybus.h"
+#include "greybus_trace.h"
+
+#define GB_BUNDLE_AUTOSUSPEND_MS 3000
+
+/* Allow greybus to be disabled at boot if needed */
+static bool nogreybus;
+#ifdef MODULE
+module_param(nogreybus, bool, 0444);
+#else
+core_param(nogreybus, nogreybus, bool, 0444);
+#endif
+int greybus_disabled(void)
+{
+ return nogreybus;
+}
+EXPORT_SYMBOL_GPL(greybus_disabled);
+
+static bool greybus_match_one_id(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id)
+{
+ if ((id->match_flags & GREYBUS_ID_MATCH_VENDOR) &&
+ (id->vendor != bundle->intf->vendor_id))
+ return false;
+
+ if ((id->match_flags & GREYBUS_ID_MATCH_PRODUCT) &&
+ (id->product != bundle->intf->product_id))
+ return false;
+
+ if ((id->match_flags & GREYBUS_ID_MATCH_CLASS) &&
+ (id->class != bundle->class))
+ return false;
+
+ return true;
+}
+
+static const struct greybus_bundle_id *
+greybus_match_id(struct gb_bundle *bundle, const struct greybus_bundle_id *id)
+{
+ if (id == NULL)
+ return NULL;
+
+ for (; id->vendor || id->product || id->class || id->driver_info;
+ id++) {
+ if (greybus_match_one_id(bundle, id))
+ return id;
+ }
+
+ return NULL;
+}
+
+static int greybus_match_device(struct device *dev, struct device_driver *drv)
+{
+ struct greybus_driver *driver = to_greybus_driver(drv);
+ struct gb_bundle *bundle;
+ const struct greybus_bundle_id *id;
+
+ if (!is_gb_bundle(dev))
+ return 0;
+
+ bundle = to_gb_bundle(dev);
+
+ id = greybus_match_id(bundle, driver->id_table);
+ if (id)
+ return 1;
+ /* FIXME - Dynamic ids? */
+ return 0;
+}
+
+static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct gb_host_device *hd;
+ struct gb_module *module = NULL;
+ struct gb_interface *intf = NULL;
+ struct gb_control *control = NULL;
+ struct gb_bundle *bundle = NULL;
+ struct gb_svc *svc = NULL;
+
+ if (is_gb_host_device(dev)) {
+ hd = to_gb_host_device(dev);
+ } else if (is_gb_module(dev)) {
+ module = to_gb_module(dev);
+ hd = module->hd;
+ } else if (is_gb_interface(dev)) {
+ intf = to_gb_interface(dev);
+ module = intf->module;
+ hd = intf->hd;
+ } else if (is_gb_control(dev)) {
+ control = to_gb_control(dev);
+ intf = control->intf;
+ module = intf->module;
+ hd = intf->hd;
+ } else if (is_gb_bundle(dev)) {
+ bundle = to_gb_bundle(dev);
+ intf = bundle->intf;
+ module = intf->module;
+ hd = intf->hd;
+ } else if (is_gb_svc(dev)) {
+ svc = to_gb_svc(dev);
+ hd = svc->hd;
+ } else {
+ dev_WARN(dev, "uevent for unknown greybus device \"type\"!\n");
+ return -EINVAL;
+ }
+
+ if (add_uevent_var(env, "BUS=%u", hd->bus_id))
+ return -ENOMEM;
+
+ if (module) {
+ if (add_uevent_var(env, "MODULE=%u", module->module_id))
+ return -ENOMEM;
+ }
+
+ if (intf) {
+ if (add_uevent_var(env, "INTERFACE=%u", intf->interface_id))
+ return -ENOMEM;
+ if (add_uevent_var(env, "GREYBUS_ID=%08x/%08x",
+ intf->vendor_id, intf->product_id))
+ return -ENOMEM;
+ }
+
+ if (bundle) {
+ // FIXME
+ // add a uevent that can "load" a bundle type
+ // This is what we need to bind a driver to so use the info
+ // in gmod here as well
+
+ if (add_uevent_var(env, "BUNDLE=%u", bundle->id))
+ return -ENOMEM;
+ if (add_uevent_var(env, "BUNDLE_CLASS=%02x", bundle->class))
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void greybus_shutdown(struct device *dev)
+{
+ if (is_gb_host_device(dev)) {
+ struct gb_host_device *hd;
+
+ hd = to_gb_host_device(dev);
+ gb_hd_shutdown(hd);
+ }
+}
+
+struct bus_type greybus_bus_type = {
+ .name = "greybus",
+ .match = greybus_match_device,
+ .uevent = greybus_uevent,
+ .shutdown = greybus_shutdown,
+};
+
+static int greybus_probe(struct device *dev)
+{
+ struct greybus_driver *driver = to_greybus_driver(dev->driver);
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+ const struct greybus_bundle_id *id;
+ int retval;
+
+ /* match id */
+ id = greybus_match_id(bundle, driver->id_table);
+ if (!id)
+ return -ENODEV;
+
+ retval = pm_runtime_get_sync(&bundle->intf->dev);
+ if (retval < 0) {
+ pm_runtime_put_noidle(&bundle->intf->dev);
+ return retval;
+ }
+
+ retval = gb_control_bundle_activate(bundle->intf->control, bundle->id);
+ if (retval) {
+ pm_runtime_put(&bundle->intf->dev);
+ return retval;
+ }
+
+ /*
+ * Unbound bundle devices are always deactivated. During probe, the
+ * Runtime PM is set to enabled and active and the usage count is
+ * incremented. If the driver supports runtime PM, it should call
+ * pm_runtime_put() in its probe routine and pm_runtime_get_sync()
+ * in remove routine.
+ */
+ pm_runtime_set_autosuspend_delay(dev, GB_BUNDLE_AUTOSUSPEND_MS);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ retval = driver->probe(bundle, id);
+ if (retval) {
+ /*
+ * Catch buggy drivers that fail to destroy their connections.
+ */
+ WARN_ON(!list_empty(&bundle->connections));
+
+ gb_control_bundle_deactivate(bundle->intf->control, bundle->id);
+
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_put_noidle(dev);
+ pm_runtime_dont_use_autosuspend(dev);
+ pm_runtime_put(&bundle->intf->dev);
+
+ return retval;
+ }
+
+ gb_timesync_schedule_synchronous(bundle->intf);
+
+ pm_runtime_put(&bundle->intf->dev);
+
+ return 0;
+}
+
+static int greybus_remove(struct device *dev)
+{
+ struct greybus_driver *driver = to_greybus_driver(dev->driver);
+ struct gb_bundle *bundle = to_gb_bundle(dev);
+ struct gb_connection *connection;
+ int retval;
+
+ retval = pm_runtime_get_sync(dev);
+ if (retval < 0)
+ dev_err(dev, "failed to resume bundle: %d\n", retval);
+
+ /*
+ * Disable (non-offloaded) connections early in case the interface is
+ * already gone to avoid unceccessary operation timeouts during
+ * driver disconnect. Otherwise, only disable incoming requests.
+ */
+ list_for_each_entry(connection, &bundle->connections, bundle_links) {
+ if (gb_connection_is_offloaded(connection))
+ continue;
+
+ if (bundle->intf->disconnected)
+ gb_connection_disable_forced(connection);
+ else
+ gb_connection_disable_rx(connection);
+ }
+
+ driver->disconnect(bundle);
+
+ /* Catch buggy drivers that fail to destroy their connections. */
+ WARN_ON(!list_empty(&bundle->connections));
+
+ if (!bundle->intf->disconnected)
+ gb_control_bundle_deactivate(bundle->intf->control, bundle->id);
+
+ pm_runtime_put_noidle(dev);
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_dont_use_autosuspend(dev);
+ pm_runtime_put_noidle(dev);
+
+ return 0;
+}
+
+int greybus_register_driver(struct greybus_driver *driver, struct module *owner,
+ const char *mod_name)
+{
+ int retval;
+
+ if (greybus_disabled())
+ return -ENODEV;
+
+ driver->driver.bus = &greybus_bus_type;
+ driver->driver.name = driver->name;
+ driver->driver.probe = greybus_probe;
+ driver->driver.remove = greybus_remove;
+ driver->driver.owner = owner;
+ driver->driver.mod_name = mod_name;
+
+ retval = driver_register(&driver->driver);
+ if (retval)
+ return retval;
+
+ pr_info("registered new driver %s\n", driver->name);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(greybus_register_driver);
+
+void greybus_deregister_driver(struct greybus_driver *driver)
+{
+ driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(greybus_deregister_driver);
+
+static int __init gb_init(void)
+{
+ int retval;
+
+ if (greybus_disabled())
+ return -ENODEV;
+
+ BUILD_BUG_ON(CPORT_ID_MAX >= (long)CPORT_ID_BAD);
+
+ gb_debugfs_init();
+
+ retval = bus_register(&greybus_bus_type);
+ if (retval) {
+ pr_err("bus_register failed (%d)\n", retval);
+ goto error_bus;
+ }
+
+ retval = gb_hd_init();
+ if (retval) {
+ pr_err("gb_hd_init failed (%d)\n", retval);
+ goto error_hd;
+ }
+
+ retval = gb_operation_init();
+ if (retval) {
+ pr_err("gb_operation_init failed (%d)\n", retval);
+ goto error_operation;
+ }
+
+ retval = gb_timesync_init();
+ if (retval) {
+ pr_err("gb_timesync_init failed\n");
+ goto error_timesync;
+ }
+ return 0; /* Success */
+
+error_timesync:
+ gb_operation_exit();
+error_operation:
+ gb_hd_exit();
+error_hd:
+ bus_unregister(&greybus_bus_type);
+error_bus:
+ gb_debugfs_cleanup();
+
+ return retval;
+}
+module_init(gb_init);
+
+static void __exit gb_exit(void)
+{
+ gb_timesync_exit();
+ gb_operation_exit();
+ gb_hd_exit();
+ bus_unregister(&greybus_bus_type);
+ gb_debugfs_cleanup();
+ tracepoint_synchronize_unregister();
+}
+module_exit(gb_exit);
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@linuxfoundation.org>");
diff --git a/drivers/staging/greybus/debugfs.c b/drivers/staging/greybus/debugfs.c
new file mode 100644
index 000000000000..a9d4d3da99a0
--- /dev/null
+++ b/drivers/staging/greybus/debugfs.c
@@ -0,0 +1,31 @@
+/*
+ * Greybus debugfs code
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/debugfs.h>
+
+#include "greybus.h"
+
+static struct dentry *gb_debug_root;
+
+void __init gb_debugfs_init(void)
+{
+ gb_debug_root = debugfs_create_dir("greybus", NULL);
+}
+
+void gb_debugfs_cleanup(void)
+{
+ debugfs_remove_recursive(gb_debug_root);
+ gb_debug_root = NULL;
+}
+
+struct dentry *gb_debugfs_get(void)
+{
+ return gb_debug_root;
+}
+EXPORT_SYMBOL_GPL(gb_debugfs_get);
diff --git a/drivers/staging/greybus/es2.c b/drivers/staging/greybus/es2.c
new file mode 100644
index 000000000000..071bb1cfd3ae
--- /dev/null
+++ b/drivers/staging/greybus/es2.c
@@ -0,0 +1,1597 @@
+/*
+ * Greybus "AP" USB driver for "ES2" controller chips
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+#include <linux/kthread.h>
+#include <linux/sizes.h>
+#include <linux/usb.h>
+#include <linux/kfifo.h>
+#include <linux/debugfs.h>
+#include <linux/list.h>
+#include <asm/unaligned.h>
+
+#include "arpc.h"
+#include "greybus.h"
+#include "greybus_trace.h"
+#include "connection.h"
+
+
+/* Default timeout for USB vendor requests. */
+#define ES2_USB_CTRL_TIMEOUT 500
+
+/* Default timeout for ARPC CPort requests */
+#define ES2_ARPC_CPORT_TIMEOUT 500
+
+/* Fixed CPort numbers */
+#define ES2_CPORT_CDSI0 16
+#define ES2_CPORT_CDSI1 17
+
+/* Memory sizes for the buffers sent to/from the ES2 controller */
+#define ES2_GBUF_MSG_SIZE_MAX 2048
+
+/* Memory sizes for the ARPC buffers */
+#define ARPC_OUT_SIZE_MAX U16_MAX
+#define ARPC_IN_SIZE_MAX 128
+
+static const struct usb_device_id id_table[] = {
+ { USB_DEVICE(0x18d1, 0x1eaf) },
+ { },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+#define APB1_LOG_SIZE SZ_16K
+
+/*
+ * Number of CPort IN urbs in flight at any point in time.
+ * Adjust if we are having stalls in the USB buffer due to not enough urbs in
+ * flight.
+ */
+#define NUM_CPORT_IN_URB 4
+
+/* Number of CPort OUT urbs in flight at any point in time.
+ * Adjust if we get messages saying we are out of urbs in the system log.
+ */
+#define NUM_CPORT_OUT_URB 8
+
+/*
+ * Number of ARPC in urbs in flight at any point in time.
+ */
+#define NUM_ARPC_IN_URB 2
+
+/*
+ * @endpoint: bulk in endpoint for CPort data
+ * @urb: array of urbs for the CPort in messages
+ * @buffer: array of buffers for the @cport_in_urb urbs
+ */
+struct es2_cport_in {
+ __u8 endpoint;
+ struct urb *urb[NUM_CPORT_IN_URB];
+ u8 *buffer[NUM_CPORT_IN_URB];
+};
+
+/**
+ * es2_ap_dev - ES2 USB Bridge to AP structure
+ * @usb_dev: pointer to the USB device we are.
+ * @usb_intf: pointer to the USB interface we are bound to.
+ * @hd: pointer to our gb_host_device structure
+
+ * @cport_in: endpoint, urbs and buffer for cport in messages
+ * @cport_out_endpoint: endpoint for for cport out messages
+ * @cport_out_urb: array of urbs for the CPort out messages
+ * @cport_out_urb_busy: array of flags to see if the @cport_out_urb is busy or
+ * not.
+ * @cport_out_urb_cancelled: array of flags indicating whether the
+ * corresponding @cport_out_urb is being cancelled
+ * @cport_out_urb_lock: locks the @cport_out_urb_busy "list"
+ *
+ * @apb_log_task: task pointer for logging thread
+ * @apb_log_dentry: file system entry for the log file interface
+ * @apb_log_enable_dentry: file system entry for enabling logging
+ * @apb_log_fifo: kernel FIFO to carry logged data
+ * @arpc_urb: array of urbs for the ARPC in messages
+ * @arpc_buffer: array of buffers for the @arpc_urb urbs
+ * @arpc_endpoint_in: bulk in endpoint for APBridgeA RPC
+ * @arpc_id_cycle: gives an unique id to ARPC
+ * @arpc_lock: locks ARPC list
+ * @arpcs: list of in progress ARPCs
+ */
+struct es2_ap_dev {
+ struct usb_device *usb_dev;
+ struct usb_interface *usb_intf;
+ struct gb_host_device *hd;
+
+ struct es2_cport_in cport_in;
+ __u8 cport_out_endpoint;
+ struct urb *cport_out_urb[NUM_CPORT_OUT_URB];
+ bool cport_out_urb_busy[NUM_CPORT_OUT_URB];
+ bool cport_out_urb_cancelled[NUM_CPORT_OUT_URB];
+ spinlock_t cport_out_urb_lock;
+
+ bool cdsi1_in_use;
+
+ struct task_struct *apb_log_task;
+ struct dentry *apb_log_dentry;
+ struct dentry *apb_log_enable_dentry;
+ DECLARE_KFIFO(apb_log_fifo, char, APB1_LOG_SIZE);
+
+ __u8 arpc_endpoint_in;
+ struct urb *arpc_urb[NUM_ARPC_IN_URB];
+ u8 *arpc_buffer[NUM_ARPC_IN_URB];
+
+ int arpc_id_cycle;
+ spinlock_t arpc_lock;
+ struct list_head arpcs;
+};
+
+/**
+ * timesync_enable_request - Enable timesync in an APBridge
+ * @count: number of TimeSync Pulses to expect
+ * @frame_time: the initial FrameTime at the first TimeSync Pulse
+ * @strobe_delay: the expected delay in microseconds between each TimeSync Pulse
+ * @refclk: The AP mandated reference clock to run FrameTime at
+ */
+struct timesync_enable_request {
+ __u8 count;
+ __le64 frame_time;
+ __le32 strobe_delay;
+ __le32 refclk;
+} __packed;
+
+/**
+ * timesync_authoritative_request - Transmit authoritative FrameTime to APBridge
+ * @frame_time: An array of authoritative FrameTimes provided by the SVC
+ * and relayed to the APBridge by the AP
+ */
+struct timesync_authoritative_request {
+ __le64 frame_time[GB_TIMESYNC_MAX_STROBES];
+} __packed;
+
+struct arpc {
+ struct list_head list;
+ struct arpc_request_message *req;
+ struct arpc_response_message *resp;
+ struct completion response_received;
+ bool active;
+};
+
+static inline struct es2_ap_dev *hd_to_es2(struct gb_host_device *hd)
+{
+ return (struct es2_ap_dev *)&hd->hd_priv;
+}
+
+static void cport_out_callback(struct urb *urb);
+static void usb_log_enable(struct es2_ap_dev *es2);
+static void usb_log_disable(struct es2_ap_dev *es2);
+static int arpc_sync(struct es2_ap_dev *es2, u8 type, void *payload,
+ size_t size, int *result, unsigned int timeout);
+
+static int output_sync(struct es2_ap_dev *es2, void *req, u16 size, u8 cmd)
+{
+ struct usb_device *udev = es2->usb_dev;
+ u8 *data;
+ int retval;
+
+ data = kmalloc(size, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ memcpy(data, req, size);
+
+ retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ cmd,
+ USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_INTERFACE,
+ 0, 0, data, size, ES2_USB_CTRL_TIMEOUT);
+ if (retval < 0)
+ dev_err(&udev->dev, "%s: return error %d\n", __func__, retval);
+ else
+ retval = 0;
+
+ kfree(data);
+ return retval;
+}
+
+static void ap_urb_complete(struct urb *urb)
+{
+ struct usb_ctrlrequest *dr = urb->context;
+
+ kfree(dr);
+ usb_free_urb(urb);
+}
+
+static int output_async(struct es2_ap_dev *es2, void *req, u16 size, u8 cmd)
+{
+ struct usb_device *udev = es2->usb_dev;
+ struct urb *urb;
+ struct usb_ctrlrequest *dr;
+ u8 *buf;
+ int retval;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb)
+ return -ENOMEM;
+
+ dr = kmalloc(sizeof(*dr) + size, GFP_ATOMIC);
+ if (!dr) {
+ usb_free_urb(urb);
+ return -ENOMEM;
+ }
+
+ buf = (u8 *)dr + sizeof(*dr);
+ memcpy(buf, req, size);
+
+ dr->bRequest = cmd;
+ dr->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
+ dr->wValue = 0;
+ dr->wIndex = 0;
+ dr->wLength = cpu_to_le16(size);
+
+ usb_fill_control_urb(urb, udev, usb_sndctrlpipe(udev, 0),
+ (unsigned char *)dr, buf, size,
+ ap_urb_complete, dr);
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval) {
+ usb_free_urb(urb);
+ kfree(dr);
+ }
+ return retval;
+}
+
+static int output(struct gb_host_device *hd, void *req, u16 size, u8 cmd,
+ bool async)
+{
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+
+ if (async)
+ return output_async(es2, req, size, cmd);
+
+ return output_sync(es2, req, size, cmd);
+}
+
+static int es2_cport_in_enable(struct es2_ap_dev *es2,
+ struct es2_cport_in *cport_in)
+{
+ struct urb *urb;
+ int ret;
+ int i;
+
+ for (i = 0; i < NUM_CPORT_IN_URB; ++i) {
+ urb = cport_in->urb[i];
+
+ ret = usb_submit_urb(urb, GFP_KERNEL);
+ if (ret) {
+ dev_err(&es2->usb_dev->dev,
+ "failed to submit in-urb: %d\n", ret);
+ goto err_kill_urbs;
+ }
+ }
+
+ return 0;
+
+err_kill_urbs:
+ for (--i; i >= 0; --i) {
+ urb = cport_in->urb[i];
+ usb_kill_urb(urb);
+ }
+
+ return ret;
+}
+
+static void es2_cport_in_disable(struct es2_ap_dev *es2,
+ struct es2_cport_in *cport_in)
+{
+ struct urb *urb;
+ int i;
+
+ for (i = 0; i < NUM_CPORT_IN_URB; ++i) {
+ urb = cport_in->urb[i];
+ usb_kill_urb(urb);
+ }
+}
+
+static int es2_arpc_in_enable(struct es2_ap_dev *es2)
+{
+ struct urb *urb;
+ int ret;
+ int i;
+
+ for (i = 0; i < NUM_ARPC_IN_URB; ++i) {
+ urb = es2->arpc_urb[i];
+
+ ret = usb_submit_urb(urb, GFP_KERNEL);
+ if (ret) {
+ dev_err(&es2->usb_dev->dev,
+ "failed to submit arpc in-urb: %d\n", ret);
+ goto err_kill_urbs;
+ }
+ }
+
+ return 0;
+
+err_kill_urbs:
+ for (--i; i >= 0; --i) {
+ urb = es2->arpc_urb[i];
+ usb_kill_urb(urb);
+ }
+
+ return ret;
+}
+
+static void es2_arpc_in_disable(struct es2_ap_dev *es2)
+{
+ struct urb *urb;
+ int i;
+
+ for (i = 0; i < NUM_ARPC_IN_URB; ++i) {
+ urb = es2->arpc_urb[i];
+ usb_kill_urb(urb);
+ }
+}
+
+static struct urb *next_free_urb(struct es2_ap_dev *es2, gfp_t gfp_mask)
+{
+ struct urb *urb = NULL;
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&es2->cport_out_urb_lock, flags);
+
+ /* Look in our pool of allocated urbs first, as that's the "fastest" */
+ for (i = 0; i < NUM_CPORT_OUT_URB; ++i) {
+ if (es2->cport_out_urb_busy[i] == false &&
+ es2->cport_out_urb_cancelled[i] == false) {
+ es2->cport_out_urb_busy[i] = true;
+ urb = es2->cport_out_urb[i];
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&es2->cport_out_urb_lock, flags);
+ if (urb)
+ return urb;
+
+ /*
+ * Crap, pool is empty, complain to the syslog and go allocate one
+ * dynamically as we have to succeed.
+ */
+ dev_dbg(&es2->usb_dev->dev,
+ "No free CPort OUT urbs, having to dynamically allocate one!\n");
+ return usb_alloc_urb(0, gfp_mask);
+}
+
+static void free_urb(struct es2_ap_dev *es2, struct urb *urb)
+{
+ unsigned long flags;
+ int i;
+ /*
+ * See if this was an urb in our pool, if so mark it "free", otherwise
+ * we need to free it ourselves.
+ */
+ spin_lock_irqsave(&es2->cport_out_urb_lock, flags);
+ for (i = 0; i < NUM_CPORT_OUT_URB; ++i) {
+ if (urb == es2->cport_out_urb[i]) {
+ es2->cport_out_urb_busy[i] = false;
+ urb = NULL;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&es2->cport_out_urb_lock, flags);
+
+ /* If urb is not NULL, then we need to free this urb */
+ usb_free_urb(urb);
+}
+
+/*
+ * We (ab)use the operation-message header pad bytes to transfer the
+ * cport id in order to minimise overhead.
+ */
+static void
+gb_message_cport_pack(struct gb_operation_msg_hdr *header, u16 cport_id)
+{
+ header->pad[0] = cport_id;
+}
+
+/* Clear the pad bytes used for the CPort id */
+static void gb_message_cport_clear(struct gb_operation_msg_hdr *header)
+{
+ header->pad[0] = 0;
+}
+
+/* Extract the CPort id packed into the header, and clear it */
+static u16 gb_message_cport_unpack(struct gb_operation_msg_hdr *header)
+{
+ u16 cport_id = header->pad[0];
+
+ gb_message_cport_clear(header);
+
+ return cport_id;
+}
+
+/*
+ * Returns zero if the message was successfully queued, or a negative errno
+ * otherwise.
+ */
+static int message_send(struct gb_host_device *hd, u16 cport_id,
+ struct gb_message *message, gfp_t gfp_mask)
+{
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct usb_device *udev = es2->usb_dev;
+ size_t buffer_size;
+ int retval;
+ struct urb *urb;
+ unsigned long flags;
+
+ /*
+ * The data actually transferred will include an indication
+ * of where the data should be sent. Do one last check of
+ * the target CPort id before filling it in.
+ */
+ if (!cport_id_valid(hd, cport_id)) {
+ dev_err(&udev->dev, "invalid cport %u\n", cport_id);
+ return -EINVAL;
+ }
+
+ /* Find a free urb */
+ urb = next_free_urb(es2, gfp_mask);
+ if (!urb)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&es2->cport_out_urb_lock, flags);
+ message->hcpriv = urb;
+ spin_unlock_irqrestore(&es2->cport_out_urb_lock, flags);
+
+ /* Pack the cport id into the message header */
+ gb_message_cport_pack(message->header, cport_id);
+
+ buffer_size = sizeof(*message->header) + message->payload_size;
+
+ usb_fill_bulk_urb(urb, udev,
+ usb_sndbulkpipe(udev,
+ es2->cport_out_endpoint),
+ message->buffer, buffer_size,
+ cport_out_callback, message);
+ urb->transfer_flags |= URB_ZERO_PACKET;
+
+ trace_gb_message_submit(message);
+
+ retval = usb_submit_urb(urb, gfp_mask);
+ if (retval) {
+ dev_err(&udev->dev, "failed to submit out-urb: %d\n", retval);
+
+ spin_lock_irqsave(&es2->cport_out_urb_lock, flags);
+ message->hcpriv = NULL;
+ spin_unlock_irqrestore(&es2->cport_out_urb_lock, flags);
+
+ free_urb(es2, urb);
+ gb_message_cport_clear(message->header);
+
+ return retval;
+ }
+
+ return 0;
+}
+
+/*
+ * Can not be called in atomic context.
+ */
+static void message_cancel(struct gb_message *message)
+{
+ struct gb_host_device *hd = message->operation->connection->hd;
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct urb *urb;
+ int i;
+
+ might_sleep();
+
+ spin_lock_irq(&es2->cport_out_urb_lock);
+ urb = message->hcpriv;
+
+ /* Prevent dynamically allocated urb from being deallocated. */
+ usb_get_urb(urb);
+
+ /* Prevent pre-allocated urb from being reused. */
+ for (i = 0; i < NUM_CPORT_OUT_URB; ++i) {
+ if (urb == es2->cport_out_urb[i]) {
+ es2->cport_out_urb_cancelled[i] = true;
+ break;
+ }
+ }
+ spin_unlock_irq(&es2->cport_out_urb_lock);
+
+ usb_kill_urb(urb);
+
+ if (i < NUM_CPORT_OUT_URB) {
+ spin_lock_irq(&es2->cport_out_urb_lock);
+ es2->cport_out_urb_cancelled[i] = false;
+ spin_unlock_irq(&es2->cport_out_urb_lock);
+ }
+
+ usb_free_urb(urb);
+}
+
+static int es2_cport_allocate(struct gb_host_device *hd, int cport_id,
+ unsigned long flags)
+{
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct ida *id_map = &hd->cport_id_map;
+ int ida_start, ida_end;
+
+ switch (cport_id) {
+ case ES2_CPORT_CDSI0:
+ case ES2_CPORT_CDSI1:
+ dev_err(&hd->dev, "cport %d not available\n", cport_id);
+ return -EBUSY;
+ }
+
+ if (flags & GB_CONNECTION_FLAG_OFFLOADED &&
+ flags & GB_CONNECTION_FLAG_CDSI1) {
+ if (es2->cdsi1_in_use) {
+ dev_err(&hd->dev, "CDSI1 already in use\n");
+ return -EBUSY;
+ }
+
+ es2->cdsi1_in_use = true;
+
+ return ES2_CPORT_CDSI1;
+ }
+
+ if (cport_id < 0) {
+ ida_start = 0;
+ ida_end = hd->num_cports;
+ } else if (cport_id < hd->num_cports) {
+ ida_start = cport_id;
+ ida_end = cport_id + 1;
+ } else {
+ dev_err(&hd->dev, "cport %d not available\n", cport_id);
+ return -EINVAL;
+ }
+
+ return ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL);
+}
+
+static void es2_cport_release(struct gb_host_device *hd, u16 cport_id)
+{
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+
+ switch (cport_id) {
+ case ES2_CPORT_CDSI1:
+ es2->cdsi1_in_use = false;
+ return;
+ }
+
+ ida_simple_remove(&hd->cport_id_map, cport_id);
+}
+
+static int cport_enable(struct gb_host_device *hd, u16 cport_id,
+ unsigned long flags)
+{
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct usb_device *udev = es2->usb_dev;
+ struct gb_apb_request_cport_flags *req;
+ u32 connection_flags;
+ int ret;
+
+ req = kzalloc(sizeof(*req), GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ connection_flags = 0;
+ if (flags & GB_CONNECTION_FLAG_CONTROL)
+ connection_flags |= GB_APB_CPORT_FLAG_CONTROL;
+ if (flags & GB_CONNECTION_FLAG_HIGH_PRIO)
+ connection_flags |= GB_APB_CPORT_FLAG_HIGH_PRIO;
+
+ req->flags = cpu_to_le32(connection_flags);
+
+ dev_dbg(&hd->dev, "%s - cport = %u, flags = %02x\n", __func__,
+ cport_id, connection_flags);
+
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ GB_APB_REQUEST_CPORT_FLAGS,
+ USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_INTERFACE, cport_id, 0,
+ req, sizeof(*req), ES2_USB_CTRL_TIMEOUT);
+ if (ret != sizeof(*req)) {
+ dev_err(&udev->dev, "failed to set cport flags for port %d\n",
+ cport_id);
+ if (ret >= 0)
+ ret = -EIO;
+
+ goto out;
+ }
+
+ ret = 0;
+out:
+ kfree(req);
+
+ return ret;
+}
+
+static int es2_cport_connected(struct gb_host_device *hd, u16 cport_id)
+{
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct device *dev = &es2->usb_dev->dev;
+ struct arpc_cport_connected_req req;
+ int ret;
+
+ req.cport_id = cpu_to_le16(cport_id);
+ ret = arpc_sync(es2, ARPC_TYPE_CPORT_CONNECTED, &req, sizeof(req),
+ NULL, ES2_ARPC_CPORT_TIMEOUT);
+ if (ret) {
+ dev_err(dev, "failed to set connected state for cport %u: %d\n",
+ cport_id, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int es2_cport_flush(struct gb_host_device *hd, u16 cport_id)
+{
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct device *dev = &es2->usb_dev->dev;
+ struct arpc_cport_flush_req req;
+ int ret;
+
+ req.cport_id = cpu_to_le16(cport_id);
+ ret = arpc_sync(es2, ARPC_TYPE_CPORT_FLUSH, &req, sizeof(req),
+ NULL, ES2_ARPC_CPORT_TIMEOUT);
+ if (ret) {
+ dev_err(dev, "failed to flush cport %u: %d\n", cport_id, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int es2_cport_shutdown(struct gb_host_device *hd, u16 cport_id,
+ u8 phase, unsigned int timeout)
+{
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct device *dev = &es2->usb_dev->dev;
+ struct arpc_cport_shutdown_req req;
+ int result;
+ int ret;
+
+ if (timeout > U16_MAX)
+ return -EINVAL;
+
+ req.cport_id = cpu_to_le16(cport_id);
+ req.timeout = cpu_to_le16(timeout);
+ req.phase = phase;
+ ret = arpc_sync(es2, ARPC_TYPE_CPORT_SHUTDOWN, &req, sizeof(req),
+ &result, ES2_ARPC_CPORT_TIMEOUT + timeout);
+ if (ret) {
+ dev_err(dev, "failed to send shutdown over cport %u: %d (%d)\n",
+ cport_id, ret, result);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int es2_cport_quiesce(struct gb_host_device *hd, u16 cport_id,
+ size_t peer_space, unsigned int timeout)
+{
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct device *dev = &es2->usb_dev->dev;
+ struct arpc_cport_quiesce_req req;
+ int result;
+ int ret;
+
+ if (peer_space > U16_MAX)
+ return -EINVAL;
+
+ if (timeout > U16_MAX)
+ return -EINVAL;
+
+ req.cport_id = cpu_to_le16(cport_id);
+ req.peer_space = cpu_to_le16(peer_space);
+ req.timeout = cpu_to_le16(timeout);
+ ret = arpc_sync(es2, ARPC_TYPE_CPORT_QUIESCE, &req, sizeof(req),
+ &result, ES2_ARPC_CPORT_TIMEOUT + timeout);
+ if (ret) {
+ dev_err(dev, "failed to quiesce cport %u: %d (%d)\n",
+ cport_id, ret, result);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int es2_cport_clear(struct gb_host_device *hd, u16 cport_id)
+{
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct device *dev = &es2->usb_dev->dev;
+ struct arpc_cport_clear_req req;
+ int ret;
+
+ req.cport_id = cpu_to_le16(cport_id);
+ ret = arpc_sync(es2, ARPC_TYPE_CPORT_CLEAR, &req, sizeof(req),
+ NULL, ES2_ARPC_CPORT_TIMEOUT);
+ if (ret) {
+ dev_err(dev, "failed to clear cport %u: %d\n", cport_id, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int latency_tag_enable(struct gb_host_device *hd, u16 cport_id)
+{
+ int retval;
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct usb_device *udev = es2->usb_dev;
+
+ retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ GB_APB_REQUEST_LATENCY_TAG_EN,
+ USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_INTERFACE, cport_id, 0, NULL,
+ 0, ES2_USB_CTRL_TIMEOUT);
+
+ if (retval < 0)
+ dev_err(&udev->dev, "Cannot enable latency tag for cport %d\n",
+ cport_id);
+ return retval;
+}
+
+static int latency_tag_disable(struct gb_host_device *hd, u16 cport_id)
+{
+ int retval;
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct usb_device *udev = es2->usb_dev;
+
+ retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ GB_APB_REQUEST_LATENCY_TAG_DIS,
+ USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_INTERFACE, cport_id, 0, NULL,
+ 0, ES2_USB_CTRL_TIMEOUT);
+
+ if (retval < 0)
+ dev_err(&udev->dev, "Cannot disable latency tag for cport %d\n",
+ cport_id);
+ return retval;
+}
+
+static int timesync_enable(struct gb_host_device *hd, u8 count,
+ u64 frame_time, u32 strobe_delay, u32 refclk)
+{
+ int retval;
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct usb_device *udev = es2->usb_dev;
+ struct gb_control_timesync_enable_request *request;
+
+ request = kzalloc(sizeof(*request), GFP_KERNEL);
+ if (!request)
+ return -ENOMEM;
+
+ request->count = count;
+ request->frame_time = cpu_to_le64(frame_time);
+ request->strobe_delay = cpu_to_le32(strobe_delay);
+ request->refclk = cpu_to_le32(refclk);
+ retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ GB_APB_REQUEST_TIMESYNC_ENABLE,
+ USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_INTERFACE, 0, 0, request,
+ sizeof(*request), ES2_USB_CTRL_TIMEOUT);
+ if (retval < 0)
+ dev_err(&udev->dev, "Cannot enable timesync %d\n", retval);
+
+ kfree(request);
+ return retval;
+}
+
+static int timesync_disable(struct gb_host_device *hd)
+{
+ int retval;
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct usb_device *udev = es2->usb_dev;
+
+ retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ GB_APB_REQUEST_TIMESYNC_DISABLE,
+ USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_INTERFACE, 0, 0, NULL,
+ 0, ES2_USB_CTRL_TIMEOUT);
+ if (retval < 0)
+ dev_err(&udev->dev, "Cannot disable timesync %d\n", retval);
+
+ return retval;
+}
+
+static int timesync_authoritative(struct gb_host_device *hd, u64 *frame_time)
+{
+ int retval, i;
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct usb_device *udev = es2->usb_dev;
+ struct timesync_authoritative_request *request;
+
+ request = kzalloc(sizeof(*request), GFP_KERNEL);
+ if (!request)
+ return -ENOMEM;
+
+ for (i = 0; i < GB_TIMESYNC_MAX_STROBES; i++)
+ request->frame_time[i] = cpu_to_le64(frame_time[i]);
+
+ retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ GB_APB_REQUEST_TIMESYNC_AUTHORITATIVE,
+ USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_INTERFACE, 0, 0, request,
+ sizeof(*request), ES2_USB_CTRL_TIMEOUT);
+ if (retval < 0)
+ dev_err(&udev->dev, "Cannot timesync authoritative out %d\n", retval);
+
+ kfree(request);
+ return retval;
+}
+
+static int timesync_get_last_event(struct gb_host_device *hd, u64 *frame_time)
+{
+ int retval;
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ struct usb_device *udev = es2->usb_dev;
+ __le64 *response_frame_time;
+
+ response_frame_time = kzalloc(sizeof(*response_frame_time), GFP_KERNEL);
+ if (!response_frame_time)
+ return -ENOMEM;
+
+ retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ GB_APB_REQUEST_TIMESYNC_GET_LAST_EVENT,
+ USB_DIR_IN | USB_TYPE_VENDOR |
+ USB_RECIP_INTERFACE, 0, 0, response_frame_time,
+ sizeof(*response_frame_time),
+ ES2_USB_CTRL_TIMEOUT);
+
+ if (retval != sizeof(*response_frame_time)) {
+ dev_err(&udev->dev, "Cannot get last TimeSync event: %d\n",
+ retval);
+
+ if (retval >= 0)
+ retval = -EIO;
+
+ goto out;
+ }
+ *frame_time = le64_to_cpu(*response_frame_time);
+ retval = 0;
+out:
+ kfree(response_frame_time);
+ return retval;
+}
+
+static struct gb_hd_driver es2_driver = {
+ .hd_priv_size = sizeof(struct es2_ap_dev),
+ .message_send = message_send,
+ .message_cancel = message_cancel,
+ .cport_allocate = es2_cport_allocate,
+ .cport_release = es2_cport_release,
+ .cport_enable = cport_enable,
+ .cport_connected = es2_cport_connected,
+ .cport_flush = es2_cport_flush,
+ .cport_shutdown = es2_cport_shutdown,
+ .cport_quiesce = es2_cport_quiesce,
+ .cport_clear = es2_cport_clear,
+ .latency_tag_enable = latency_tag_enable,
+ .latency_tag_disable = latency_tag_disable,
+ .output = output,
+ .timesync_enable = timesync_enable,
+ .timesync_disable = timesync_disable,
+ .timesync_authoritative = timesync_authoritative,
+ .timesync_get_last_event = timesync_get_last_event,
+};
+
+/* Common function to report consistent warnings based on URB status */
+static int check_urb_status(struct urb *urb)
+{
+ struct device *dev = &urb->dev->dev;
+ int status = urb->status;
+
+ switch (status) {
+ case 0:
+ return 0;
+
+ case -EOVERFLOW:
+ dev_err(dev, "%s: overflow actual length is %d\n",
+ __func__, urb->actual_length);
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ case -EILSEQ:
+ case -EPROTO:
+ /* device is gone, stop sending */
+ return status;
+ }
+ dev_err(dev, "%s: unknown status %d\n", __func__, status);
+
+ return -EAGAIN;
+}
+
+static void es2_destroy(struct es2_ap_dev *es2)
+{
+ struct usb_device *udev;
+ struct urb *urb;
+ int i;
+
+ debugfs_remove(es2->apb_log_enable_dentry);
+ usb_log_disable(es2);
+
+ /* Tear down everything! */
+ for (i = 0; i < NUM_CPORT_OUT_URB; ++i) {
+ urb = es2->cport_out_urb[i];
+ usb_kill_urb(urb);
+ usb_free_urb(urb);
+ es2->cport_out_urb[i] = NULL;
+ es2->cport_out_urb_busy[i] = false; /* just to be anal */
+ }
+
+ for (i = 0; i < NUM_ARPC_IN_URB; ++i) {
+ usb_free_urb(es2->arpc_urb[i]);
+ kfree(es2->arpc_buffer[i]);
+ es2->arpc_buffer[i] = NULL;
+ }
+
+ for (i = 0; i < NUM_CPORT_IN_URB; ++i) {
+ usb_free_urb(es2->cport_in.urb[i]);
+ kfree(es2->cport_in.buffer[i]);
+ es2->cport_in.buffer[i] = NULL;
+ }
+
+ /* release reserved CDSI0 and CDSI1 cports */
+ gb_hd_cport_release_reserved(es2->hd, ES2_CPORT_CDSI1);
+ gb_hd_cport_release_reserved(es2->hd, ES2_CPORT_CDSI0);
+
+ udev = es2->usb_dev;
+ gb_hd_put(es2->hd);
+
+ usb_put_dev(udev);
+}
+
+static void cport_in_callback(struct urb *urb)
+{
+ struct gb_host_device *hd = urb->context;
+ struct device *dev = &urb->dev->dev;
+ struct gb_operation_msg_hdr *header;
+ int status = check_urb_status(urb);
+ int retval;
+ u16 cport_id;
+
+ if (status) {
+ if ((status == -EAGAIN) || (status == -EPROTO))
+ goto exit;
+
+ /* The urb is being unlinked */
+ if (status == -ENOENT || status == -ESHUTDOWN)
+ return;
+
+ dev_err(dev, "urb cport in error %d (dropped)\n", status);
+ return;
+ }
+
+ if (urb->actual_length < sizeof(*header)) {
+ dev_err(dev, "short message received\n");
+ goto exit;
+ }
+
+ /* Extract the CPort id, which is packed in the message header */
+ header = urb->transfer_buffer;
+ cport_id = gb_message_cport_unpack(header);
+
+ if (cport_id_valid(hd, cport_id)) {
+ greybus_data_rcvd(hd, cport_id, urb->transfer_buffer,
+ urb->actual_length);
+ } else {
+ dev_err(dev, "invalid cport id %u received\n", cport_id);
+ }
+exit:
+ /* put our urb back in the request pool */
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval)
+ dev_err(dev, "failed to resubmit in-urb: %d\n", retval);
+}
+
+static void cport_out_callback(struct urb *urb)
+{
+ struct gb_message *message = urb->context;
+ struct gb_host_device *hd = message->operation->connection->hd;
+ struct es2_ap_dev *es2 = hd_to_es2(hd);
+ int status = check_urb_status(urb);
+ unsigned long flags;
+
+ gb_message_cport_clear(message->header);
+
+ spin_lock_irqsave(&es2->cport_out_urb_lock, flags);
+ message->hcpriv = NULL;
+ spin_unlock_irqrestore(&es2->cport_out_urb_lock, flags);
+
+ /*
+ * Tell the submitter that the message send (attempt) is
+ * complete, and report the status.
+ */
+ greybus_message_sent(hd, message, status);
+
+ free_urb(es2, urb);
+}
+
+static struct arpc *arpc_alloc(void *payload, u16 size, u8 type)
+{
+ struct arpc *rpc;
+
+ if (size + sizeof(*rpc->req) > ARPC_OUT_SIZE_MAX)
+ return NULL;
+
+ rpc = kzalloc(sizeof(*rpc), GFP_KERNEL);
+ if (!rpc)
+ return NULL;
+
+ INIT_LIST_HEAD(&rpc->list);
+ rpc->req = kzalloc(sizeof(*rpc->req) + size, GFP_KERNEL);
+ if (!rpc->req)
+ goto err_free_rpc;
+
+ rpc->resp = kzalloc(sizeof(*rpc->resp), GFP_KERNEL);
+ if (!rpc->resp)
+ goto err_free_req;
+
+ rpc->req->type = type;
+ rpc->req->size = cpu_to_le16(sizeof(rpc->req) + size);
+ memcpy(rpc->req->data, payload, size);
+
+ init_completion(&rpc->response_received);
+
+ return rpc;
+
+err_free_req:
+ kfree(rpc->req);
+err_free_rpc:
+ kfree(rpc);
+
+ return NULL;
+}
+
+static void arpc_free(struct arpc *rpc)
+{
+ kfree(rpc->req);
+ kfree(rpc->resp);
+ kfree(rpc);
+}
+
+static struct arpc *arpc_find(struct es2_ap_dev *es2, __le16 id)
+{
+ struct arpc *rpc;
+
+ list_for_each_entry(rpc, &es2->arpcs, list) {
+ if (rpc->req->id == id)
+ return rpc;
+ }
+
+ return NULL;
+}
+
+static void arpc_add(struct es2_ap_dev *es2, struct arpc *rpc)
+{
+ rpc->active = true;
+ rpc->req->id = cpu_to_le16(es2->arpc_id_cycle++);
+ list_add_tail(&rpc->list, &es2->arpcs);
+}
+
+static void arpc_del(struct es2_ap_dev *es2, struct arpc *rpc)
+{
+ if (rpc->active) {
+ rpc->active = false;
+ list_del(&rpc->list);
+ }
+}
+
+static int arpc_send(struct es2_ap_dev *es2, struct arpc *rpc, int timeout)
+{
+ struct usb_device *udev = es2->usb_dev;
+ int retval;
+
+ retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ GB_APB_REQUEST_ARPC_RUN,
+ USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_INTERFACE,
+ 0, 0,
+ rpc->req, le16_to_cpu(rpc->req->size),
+ ES2_USB_CTRL_TIMEOUT);
+ if (retval != le16_to_cpu(rpc->req->size)) {
+ dev_err(&udev->dev,
+ "failed to send ARPC request %d: %d\n",
+ rpc->req->type, retval);
+ if (retval > 0)
+ retval = -EIO;
+ return retval;
+ }
+
+ return 0;
+}
+
+static int arpc_sync(struct es2_ap_dev *es2, u8 type, void *payload,
+ size_t size, int *result, unsigned int timeout)
+{
+ struct arpc *rpc;
+ unsigned long flags;
+ int retval;
+
+ if (result)
+ *result = 0;
+
+ rpc = arpc_alloc(payload, size, type);
+ if (!rpc)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&es2->arpc_lock, flags);
+ arpc_add(es2, rpc);
+ spin_unlock_irqrestore(&es2->arpc_lock, flags);
+
+ retval = arpc_send(es2, rpc, timeout);
+ if (retval)
+ goto out_arpc_del;
+
+ retval = wait_for_completion_interruptible_timeout(
+ &rpc->response_received,
+ msecs_to_jiffies(timeout));
+ if (retval <= 0) {
+ if (!retval)
+ retval = -ETIMEDOUT;
+ goto out_arpc_del;
+ }
+
+ if (rpc->resp->result) {
+ retval = -EREMOTEIO;
+ if (result)
+ *result = rpc->resp->result;
+ } else {
+ retval = 0;
+ }
+
+out_arpc_del:
+ spin_lock_irqsave(&es2->arpc_lock, flags);
+ arpc_del(es2, rpc);
+ spin_unlock_irqrestore(&es2->arpc_lock, flags);
+ arpc_free(rpc);
+
+ if (retval < 0 && retval != -EREMOTEIO) {
+ dev_err(&es2->usb_dev->dev,
+ "failed to execute ARPC: %d\n", retval);
+ }
+
+ return retval;
+}
+
+static void arpc_in_callback(struct urb *urb)
+{
+ struct es2_ap_dev *es2 = urb->context;
+ struct device *dev = &urb->dev->dev;
+ int status = check_urb_status(urb);
+ struct arpc *rpc;
+ struct arpc_response_message *resp;
+ unsigned long flags;
+ int retval;
+
+ if (status) {
+ if ((status == -EAGAIN) || (status == -EPROTO))
+ goto exit;
+
+ /* The urb is being unlinked */
+ if (status == -ENOENT || status == -ESHUTDOWN)
+ return;
+
+ dev_err(dev, "arpc in-urb error %d (dropped)\n", status);
+ return;
+ }
+
+ if (urb->actual_length < sizeof(*resp)) {
+ dev_err(dev, "short aprc response received\n");
+ goto exit;
+ }
+
+ resp = urb->transfer_buffer;
+ spin_lock_irqsave(&es2->arpc_lock, flags);
+ rpc = arpc_find(es2, resp->id);
+ if (!rpc) {
+ dev_err(dev, "invalid arpc response id received: %u\n",
+ le16_to_cpu(resp->id));
+ spin_unlock_irqrestore(&es2->arpc_lock, flags);
+ goto exit;
+ }
+
+ arpc_del(es2, rpc);
+ memcpy(rpc->resp, resp, sizeof(*resp));
+ complete(&rpc->response_received);
+ spin_unlock_irqrestore(&es2->arpc_lock, flags);
+
+exit:
+ /* put our urb back in the request pool */
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval)
+ dev_err(dev, "failed to resubmit arpc in-urb: %d\n", retval);
+}
+
+#define APB1_LOG_MSG_SIZE 64
+static void apb_log_get(struct es2_ap_dev *es2, char *buf)
+{
+ int retval;
+
+ do {
+ retval = usb_control_msg(es2->usb_dev,
+ usb_rcvctrlpipe(es2->usb_dev, 0),
+ GB_APB_REQUEST_LOG,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0x00, 0x00,
+ buf,
+ APB1_LOG_MSG_SIZE,
+ ES2_USB_CTRL_TIMEOUT);
+ if (retval > 0)
+ kfifo_in(&es2->apb_log_fifo, buf, retval);
+ } while (retval > 0);
+}
+
+static int apb_log_poll(void *data)
+{
+ struct es2_ap_dev *es2 = data;
+ char *buf;
+
+ buf = kmalloc(APB1_LOG_MSG_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ while (!kthread_should_stop()) {
+ msleep(1000);
+ apb_log_get(es2, buf);
+ }
+
+ kfree(buf);
+
+ return 0;
+}
+
+static ssize_t apb_log_read(struct file *f, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct es2_ap_dev *es2 = f->f_inode->i_private;
+ ssize_t ret;
+ size_t copied;
+ char *tmp_buf;
+
+ if (count > APB1_LOG_SIZE)
+ count = APB1_LOG_SIZE;
+
+ tmp_buf = kmalloc(count, GFP_KERNEL);
+ if (!tmp_buf)
+ return -ENOMEM;
+
+ copied = kfifo_out(&es2->apb_log_fifo, tmp_buf, count);
+ ret = simple_read_from_buffer(buf, count, ppos, tmp_buf, copied);
+
+ kfree(tmp_buf);
+
+ return ret;
+}
+
+static const struct file_operations apb_log_fops = {
+ .read = apb_log_read,
+};
+
+static void usb_log_enable(struct es2_ap_dev *es2)
+{
+ if (!IS_ERR_OR_NULL(es2->apb_log_task))
+ return;
+
+ /* get log from APB1 */
+ es2->apb_log_task = kthread_run(apb_log_poll, es2, "apb_log");
+ if (IS_ERR(es2->apb_log_task))
+ return;
+ /* XXX We will need to rename this per APB */
+ es2->apb_log_dentry = debugfs_create_file("apb_log", S_IRUGO,
+ gb_debugfs_get(), es2,
+ &apb_log_fops);
+}
+
+static void usb_log_disable(struct es2_ap_dev *es2)
+{
+ if (IS_ERR_OR_NULL(es2->apb_log_task))
+ return;
+
+ debugfs_remove(es2->apb_log_dentry);
+ es2->apb_log_dentry = NULL;
+
+ kthread_stop(es2->apb_log_task);
+ es2->apb_log_task = NULL;
+}
+
+static ssize_t apb_log_enable_read(struct file *f, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct es2_ap_dev *es2 = f->f_inode->i_private;
+ int enable = !IS_ERR_OR_NULL(es2->apb_log_task);
+ char tmp_buf[3];
+
+ sprintf(tmp_buf, "%d\n", enable);
+ return simple_read_from_buffer(buf, count, ppos, tmp_buf, 3);
+}
+
+static ssize_t apb_log_enable_write(struct file *f, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int enable;
+ ssize_t retval;
+ struct es2_ap_dev *es2 = f->f_inode->i_private;
+
+ retval = kstrtoint_from_user(buf, count, 10, &enable);
+ if (retval)
+ return retval;
+
+ if (enable)
+ usb_log_enable(es2);
+ else
+ usb_log_disable(es2);
+
+ return count;
+}
+
+static const struct file_operations apb_log_enable_fops = {
+ .read = apb_log_enable_read,
+ .write = apb_log_enable_write,
+};
+
+static int apb_get_cport_count(struct usb_device *udev)
+{
+ int retval;
+ __le16 *cport_count;
+
+ cport_count = kzalloc(sizeof(*cport_count), GFP_KERNEL);
+ if (!cport_count)
+ return -ENOMEM;
+
+ retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ GB_APB_REQUEST_CPORT_COUNT,
+ USB_DIR_IN | USB_TYPE_VENDOR |
+ USB_RECIP_INTERFACE, 0, 0, cport_count,
+ sizeof(*cport_count), ES2_USB_CTRL_TIMEOUT);
+ if (retval != sizeof(*cport_count)) {
+ dev_err(&udev->dev, "Cannot retrieve CPort count: %d\n",
+ retval);
+
+ if (retval >= 0)
+ retval = -EIO;
+
+ goto out;
+ }
+
+ retval = le16_to_cpu(*cport_count);
+
+ /* We need to fit a CPort ID in one byte of a message header */
+ if (retval > U8_MAX) {
+ retval = U8_MAX;
+ dev_warn(&udev->dev, "Limiting number of CPorts to U8_MAX\n");
+ }
+
+out:
+ kfree(cport_count);
+ return retval;
+}
+
+/*
+ * The ES2 USB Bridge device has 15 endpoints
+ * 1 Control - usual USB stuff + AP -> APBridgeA messages
+ * 7 Bulk IN - CPort data in
+ * 7 Bulk OUT - CPort data out
+ */
+static int ap_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct es2_ap_dev *es2;
+ struct gb_host_device *hd;
+ struct usb_device *udev;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ __u8 ep_addr;
+ int retval;
+ int i;
+ int num_cports;
+ bool bulk_out_found = false;
+ bool bulk_in_found = false;
+ bool arpc_in_found = false;
+
+ udev = usb_get_dev(interface_to_usbdev(interface));
+
+ num_cports = apb_get_cport_count(udev);
+ if (num_cports < 0) {
+ usb_put_dev(udev);
+ dev_err(&udev->dev, "Cannot retrieve CPort count: %d\n",
+ num_cports);
+ return num_cports;
+ }
+
+ hd = gb_hd_create(&es2_driver, &udev->dev, ES2_GBUF_MSG_SIZE_MAX,
+ num_cports);
+ if (IS_ERR(hd)) {
+ usb_put_dev(udev);
+ return PTR_ERR(hd);
+ }
+
+ es2 = hd_to_es2(hd);
+ es2->hd = hd;
+ es2->usb_intf = interface;
+ es2->usb_dev = udev;
+ spin_lock_init(&es2->cport_out_urb_lock);
+ INIT_KFIFO(es2->apb_log_fifo);
+ usb_set_intfdata(interface, es2);
+
+ /*
+ * Reserve the CDSI0 and CDSI1 CPorts so they won't be allocated
+ * dynamically.
+ */
+ retval = gb_hd_cport_reserve(hd, ES2_CPORT_CDSI0);
+ if (retval)
+ goto error;
+ retval = gb_hd_cport_reserve(hd, ES2_CPORT_CDSI1);
+ if (retval)
+ goto error;
+
+ /* find all bulk endpoints */
+ iface_desc = interface->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+ ep_addr = endpoint->bEndpointAddress;
+
+ if (usb_endpoint_is_bulk_in(endpoint)) {
+ if (!bulk_in_found) {
+ es2->cport_in.endpoint = ep_addr;
+ bulk_in_found = true;
+ } else if (!arpc_in_found) {
+ es2->arpc_endpoint_in = ep_addr;
+ arpc_in_found = true;
+ } else {
+ dev_warn(&udev->dev,
+ "Unused bulk IN endpoint found: 0x%02x\n",
+ ep_addr);
+ }
+ continue;
+ }
+ if (usb_endpoint_is_bulk_out(endpoint)) {
+ if (!bulk_out_found) {
+ es2->cport_out_endpoint = ep_addr;
+ bulk_out_found = true;
+ } else {
+ dev_warn(&udev->dev,
+ "Unused bulk OUT endpoint found: 0x%02x\n",
+ ep_addr);
+ }
+ continue;
+ }
+ dev_warn(&udev->dev,
+ "Unknown endpoint type found, address 0x%02x\n",
+ ep_addr);
+ }
+ if (!bulk_in_found || !arpc_in_found || !bulk_out_found) {
+ dev_err(&udev->dev, "Not enough endpoints found in device, aborting!\n");
+ retval = -ENODEV;
+ goto error;
+ }
+
+ /* Allocate buffers for our cport in messages */
+ for (i = 0; i < NUM_CPORT_IN_URB; ++i) {
+ struct urb *urb;
+ u8 *buffer;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ retval = -ENOMEM;
+ goto error;
+ }
+ es2->cport_in.urb[i] = urb;
+
+ buffer = kmalloc(ES2_GBUF_MSG_SIZE_MAX, GFP_KERNEL);
+ if (!buffer) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ usb_fill_bulk_urb(urb, udev,
+ usb_rcvbulkpipe(udev, es2->cport_in.endpoint),
+ buffer, ES2_GBUF_MSG_SIZE_MAX,
+ cport_in_callback, hd);
+
+ es2->cport_in.buffer[i] = buffer;
+ }
+
+ /* Allocate buffers for ARPC in messages */
+ for (i = 0; i < NUM_ARPC_IN_URB; ++i) {
+ struct urb *urb;
+ u8 *buffer;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ retval = -ENOMEM;
+ goto error;
+ }
+ es2->arpc_urb[i] = urb;
+
+ buffer = kmalloc(ARPC_IN_SIZE_MAX, GFP_KERNEL);
+ if (!buffer) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ usb_fill_bulk_urb(urb, udev,
+ usb_rcvbulkpipe(udev,
+ es2->arpc_endpoint_in),
+ buffer, ARPC_IN_SIZE_MAX,
+ arpc_in_callback, es2);
+
+ es2->arpc_buffer[i] = buffer;
+ }
+
+ /* Allocate urbs for our CPort OUT messages */
+ for (i = 0; i < NUM_CPORT_OUT_URB; ++i) {
+ struct urb *urb;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ es2->cport_out_urb[i] = urb;
+ es2->cport_out_urb_busy[i] = false; /* just to be anal */
+ }
+
+ /* XXX We will need to rename this per APB */
+ es2->apb_log_enable_dentry = debugfs_create_file("apb_log_enable",
+ (S_IWUSR | S_IRUGO),
+ gb_debugfs_get(), es2,
+ &apb_log_enable_fops);
+
+ INIT_LIST_HEAD(&es2->arpcs);
+ spin_lock_init(&es2->arpc_lock);
+
+ if (es2_arpc_in_enable(es2))
+ goto error;
+
+ retval = gb_hd_add(hd);
+ if (retval)
+ goto err_disable_arpc_in;
+
+ retval = es2_cport_in_enable(es2, &es2->cport_in);
+ if (retval)
+ goto err_hd_del;
+
+ return 0;
+
+err_hd_del:
+ gb_hd_del(hd);
+err_disable_arpc_in:
+ es2_arpc_in_disable(es2);
+error:
+ es2_destroy(es2);
+
+ return retval;
+}
+
+static void ap_disconnect(struct usb_interface *interface)
+{
+ struct es2_ap_dev *es2 = usb_get_intfdata(interface);
+
+ gb_hd_del(es2->hd);
+
+ es2_cport_in_disable(es2, &es2->cport_in);
+ es2_arpc_in_disable(es2);
+
+ es2_destroy(es2);
+}
+
+static struct usb_driver es2_ap_driver = {
+ .name = "es2_ap_driver",
+ .probe = ap_probe,
+ .disconnect = ap_disconnect,
+ .id_table = id_table,
+ .soft_unbind = 1,
+};
+
+module_usb_driver(es2_ap_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@linuxfoundation.org>");
diff --git a/drivers/staging/greybus/firmware.h b/drivers/staging/greybus/firmware.h
new file mode 100644
index 000000000000..f4f0db1cefe8
--- /dev/null
+++ b/drivers/staging/greybus/firmware.h
@@ -0,0 +1,42 @@
+/*
+ * Greybus Firmware Management Header
+ *
+ * Copyright 2016 Google Inc.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __FIRMWARE_H
+#define __FIRMWARE_H
+
+#include "greybus.h"
+
+#define FW_NAME_PREFIX "gmp_"
+
+/*
+ * Length of the string in format: "FW_NAME_PREFIX""%08x_%08x_%08x_%08x_%s.tftf"
+ * (3 + 1 + 4 * (8 + 1) + 10 + 1 + 4 + 1)
+ */
+#define FW_NAME_SIZE 56
+
+/* Firmware Management Protocol specific functions */
+int fw_mgmt_init(void);
+void fw_mgmt_exit(void);
+struct gb_connection *to_fw_mgmt_connection(struct device *dev);
+int gb_fw_mgmt_request_handler(struct gb_operation *op);
+int gb_fw_mgmt_connection_init(struct gb_connection *connection);
+void gb_fw_mgmt_connection_exit(struct gb_connection *connection);
+
+/* Firmware Download Protocol specific functions */
+int gb_fw_download_request_handler(struct gb_operation *op);
+int gb_fw_download_connection_init(struct gb_connection *connection);
+void gb_fw_download_connection_exit(struct gb_connection *connection);
+
+/* CAP Protocol specific functions */
+int cap_init(void);
+void cap_exit(void);
+int gb_cap_connection_init(struct gb_connection *connection);
+void gb_cap_connection_exit(struct gb_connection *connection);
+
+#endif /* __FIRMWARE_H */
diff --git a/drivers/staging/greybus/fw-core.c b/drivers/staging/greybus/fw-core.c
new file mode 100644
index 000000000000..454a98957ba5
--- /dev/null
+++ b/drivers/staging/greybus/fw-core.c
@@ -0,0 +1,312 @@
+/*
+ * Greybus Firmware Core Bundle Driver.
+ *
+ * Copyright 2016 Google Inc.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/firmware.h>
+#include "firmware.h"
+#include "greybus.h"
+#include "spilib.h"
+
+struct gb_fw_core {
+ struct gb_connection *download_connection;
+ struct gb_connection *mgmt_connection;
+ struct gb_connection *spi_connection;
+ struct gb_connection *cap_connection;
+};
+
+static struct spilib_ops *spilib_ops;
+
+struct gb_connection *to_fw_mgmt_connection(struct device *dev)
+{
+ struct gb_fw_core *fw_core = dev_get_drvdata(dev);
+
+ return fw_core->mgmt_connection;
+}
+
+static int gb_fw_spi_connection_init(struct gb_connection *connection)
+{
+ int ret;
+
+ if (!connection)
+ return 0;
+
+ ret = gb_connection_enable(connection);
+ if (ret)
+ return ret;
+
+ ret = gb_spilib_master_init(connection, &connection->bundle->dev,
+ spilib_ops);
+ if (ret) {
+ gb_connection_disable(connection);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void gb_fw_spi_connection_exit(struct gb_connection *connection)
+{
+ if (!connection)
+ return;
+
+ gb_spilib_master_exit(connection);
+ gb_connection_disable(connection);
+}
+
+static int gb_fw_core_probe(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id)
+{
+ struct greybus_descriptor_cport *cport_desc;
+ struct gb_connection *connection;
+ struct gb_fw_core *fw_core;
+ int ret, i;
+ u16 cport_id;
+ u8 protocol_id;
+
+ fw_core = kzalloc(sizeof(*fw_core), GFP_KERNEL);
+ if (!fw_core)
+ return -ENOMEM;
+
+ /* Parse CPorts and create connections */
+ for (i = 0; i < bundle->num_cports; i++) {
+ cport_desc = &bundle->cport_desc[i];
+ cport_id = le16_to_cpu(cport_desc->id);
+ protocol_id = cport_desc->protocol_id;
+
+ switch (protocol_id) {
+ case GREYBUS_PROTOCOL_FW_MANAGEMENT:
+ /* Disallow multiple Firmware Management CPorts */
+ if (fw_core->mgmt_connection) {
+ dev_err(&bundle->dev,
+ "multiple management CPorts found\n");
+ ret = -EINVAL;
+ goto err_destroy_connections;
+ }
+
+ connection = gb_connection_create(bundle, cport_id,
+ gb_fw_mgmt_request_handler);
+ if (IS_ERR(connection)) {
+ ret = PTR_ERR(connection);
+ dev_err(&bundle->dev,
+ "failed to create management connection (%d)\n",
+ ret);
+ goto err_destroy_connections;
+ }
+
+ fw_core->mgmt_connection = connection;
+ break;
+ case GREYBUS_PROTOCOL_FW_DOWNLOAD:
+ /* Disallow multiple Firmware Download CPorts */
+ if (fw_core->download_connection) {
+ dev_err(&bundle->dev,
+ "multiple download CPorts found\n");
+ ret = -EINVAL;
+ goto err_destroy_connections;
+ }
+
+ connection = gb_connection_create(bundle, cport_id,
+ gb_fw_download_request_handler);
+ if (IS_ERR(connection)) {
+ dev_err(&bundle->dev, "failed to create download connection (%ld)\n",
+ PTR_ERR(connection));
+ } else {
+ fw_core->download_connection = connection;
+ }
+
+ break;
+ case GREYBUS_PROTOCOL_SPI:
+ /* Disallow multiple SPI CPorts */
+ if (fw_core->spi_connection) {
+ dev_err(&bundle->dev,
+ "multiple SPI CPorts found\n");
+ ret = -EINVAL;
+ goto err_destroy_connections;
+ }
+
+ connection = gb_connection_create(bundle, cport_id,
+ NULL);
+ if (IS_ERR(connection)) {
+ dev_err(&bundle->dev, "failed to create SPI connection (%ld)\n",
+ PTR_ERR(connection));
+ } else {
+ fw_core->spi_connection = connection;
+ }
+
+ break;
+ case GREYBUS_PROTOCOL_AUTHENTICATION:
+ /* Disallow multiple CAP CPorts */
+ if (fw_core->cap_connection) {
+ dev_err(&bundle->dev, "multiple Authentication CPorts found\n");
+ ret = -EINVAL;
+ goto err_destroy_connections;
+ }
+
+ connection = gb_connection_create(bundle, cport_id,
+ NULL);
+ if (IS_ERR(connection)) {
+ dev_err(&bundle->dev, "failed to create Authentication connection (%ld)\n",
+ PTR_ERR(connection));
+ } else {
+ fw_core->cap_connection = connection;
+ }
+
+ break;
+ default:
+ dev_err(&bundle->dev, "invalid protocol id (0x%02x)\n",
+ protocol_id);
+ ret = -EINVAL;
+ goto err_destroy_connections;
+ }
+ }
+
+ /* Firmware Management connection is mandatory */
+ if (!fw_core->mgmt_connection) {
+ dev_err(&bundle->dev, "missing management connection\n");
+ ret = -ENODEV;
+ goto err_destroy_connections;
+ }
+
+ ret = gb_fw_download_connection_init(fw_core->download_connection);
+ if (ret) {
+ /* We may still be able to work with the Interface */
+ dev_err(&bundle->dev, "failed to initialize firmware download connection, disable it (%d)\n",
+ ret);
+ gb_connection_destroy(fw_core->download_connection);
+ fw_core->download_connection = NULL;
+ }
+
+ ret = gb_fw_spi_connection_init(fw_core->spi_connection);
+ if (ret) {
+ /* We may still be able to work with the Interface */
+ dev_err(&bundle->dev, "failed to initialize SPI connection, disable it (%d)\n",
+ ret);
+ gb_connection_destroy(fw_core->spi_connection);
+ fw_core->spi_connection = NULL;
+ }
+
+ ret = gb_cap_connection_init(fw_core->cap_connection);
+ if (ret) {
+ /* We may still be able to work with the Interface */
+ dev_err(&bundle->dev, "failed to initialize CAP connection, disable it (%d)\n",
+ ret);
+ gb_connection_destroy(fw_core->cap_connection);
+ fw_core->cap_connection = NULL;
+ }
+
+ ret = gb_fw_mgmt_connection_init(fw_core->mgmt_connection);
+ if (ret) {
+ /* We may still be able to work with the Interface */
+ dev_err(&bundle->dev, "failed to initialize firmware management connection, disable it (%d)\n",
+ ret);
+ goto err_exit_connections;
+ }
+
+ greybus_set_drvdata(bundle, fw_core);
+
+ /* FIXME: Remove this after S2 Loader gets runtime PM support */
+ if (!(bundle->intf->quirks & GB_INTERFACE_QUIRK_NO_PM))
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return 0;
+
+err_exit_connections:
+ gb_cap_connection_exit(fw_core->cap_connection);
+ gb_fw_spi_connection_exit(fw_core->spi_connection);
+ gb_fw_download_connection_exit(fw_core->download_connection);
+err_destroy_connections:
+ gb_connection_destroy(fw_core->mgmt_connection);
+ gb_connection_destroy(fw_core->cap_connection);
+ gb_connection_destroy(fw_core->spi_connection);
+ gb_connection_destroy(fw_core->download_connection);
+ kfree(fw_core);
+
+ return ret;
+}
+
+static void gb_fw_core_disconnect(struct gb_bundle *bundle)
+{
+ struct gb_fw_core *fw_core = greybus_get_drvdata(bundle);
+ int ret;
+
+ /* FIXME: Remove this after S2 Loader gets runtime PM support */
+ if (!(bundle->intf->quirks & GB_INTERFACE_QUIRK_NO_PM)) {
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ gb_pm_runtime_get_noresume(bundle);
+ }
+
+ gb_fw_mgmt_connection_exit(fw_core->mgmt_connection);
+ gb_cap_connection_exit(fw_core->cap_connection);
+ gb_fw_spi_connection_exit(fw_core->spi_connection);
+ gb_fw_download_connection_exit(fw_core->download_connection);
+
+ gb_connection_destroy(fw_core->mgmt_connection);
+ gb_connection_destroy(fw_core->cap_connection);
+ gb_connection_destroy(fw_core->spi_connection);
+ gb_connection_destroy(fw_core->download_connection);
+
+ kfree(fw_core);
+}
+
+static const struct greybus_bundle_id gb_fw_core_id_table[] = {
+ { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_FW_MANAGEMENT) },
+ { }
+};
+
+static struct greybus_driver gb_fw_core_driver = {
+ .name = "gb-firmware",
+ .probe = gb_fw_core_probe,
+ .disconnect = gb_fw_core_disconnect,
+ .id_table = gb_fw_core_id_table,
+};
+
+static int fw_core_init(void)
+{
+ int ret;
+
+ ret = fw_mgmt_init();
+ if (ret) {
+ pr_err("Failed to initialize fw-mgmt core (%d)\n", ret);
+ return ret;
+ }
+
+ ret = cap_init();
+ if (ret) {
+ pr_err("Failed to initialize component authentication core (%d)\n",
+ ret);
+ goto fw_mgmt_exit;
+ }
+
+ ret = greybus_register(&gb_fw_core_driver);
+ if (ret)
+ goto cap_exit;
+
+ return 0;
+
+cap_exit:
+ cap_exit();
+fw_mgmt_exit:
+ fw_mgmt_exit();
+
+ return ret;
+}
+module_init(fw_core_init);
+
+static void __exit fw_core_exit(void)
+{
+ greybus_deregister(&gb_fw_core_driver);
+ cap_exit();
+ fw_mgmt_exit();
+}
+module_exit(fw_core_exit);
+
+MODULE_ALIAS("greybus:firmware");
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>");
+MODULE_DESCRIPTION("Greybus Firmware Bundle Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/fw-download.c b/drivers/staging/greybus/fw-download.c
new file mode 100644
index 000000000000..2d7246887547
--- /dev/null
+++ b/drivers/staging/greybus/fw-download.c
@@ -0,0 +1,465 @@
+/*
+ * Greybus Firmware Download Protocol Driver.
+ *
+ * Copyright 2016 Google Inc.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/firmware.h>
+#include <linux/jiffies.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include "firmware.h"
+#include "greybus.h"
+
+/* Estimated minimum buffer size, actual size can be smaller than this */
+#define MIN_FETCH_SIZE 512
+/* Timeout, in jiffies, within which fetch or release firmware must be called */
+#define NEXT_REQ_TIMEOUT_J msecs_to_jiffies(1000)
+
+struct fw_request {
+ u8 firmware_id;
+ bool disabled;
+ bool timedout;
+ char name[FW_NAME_SIZE];
+ const struct firmware *fw;
+ struct list_head node;
+
+ struct delayed_work dwork;
+ /* Timeout, in jiffies, within which the firmware shall download */
+ unsigned long release_timeout_j;
+ struct kref kref;
+ struct fw_download *fw_download;
+};
+
+struct fw_download {
+ struct device *parent;
+ struct gb_connection *connection;
+ struct list_head fw_requests;
+ struct ida id_map;
+ struct mutex mutex;
+};
+
+static void fw_req_release(struct kref *kref)
+{
+ struct fw_request *fw_req = container_of(kref, struct fw_request, kref);
+
+ dev_dbg(fw_req->fw_download->parent, "firmware %s released\n",
+ fw_req->name);
+
+ release_firmware(fw_req->fw);
+
+ /*
+ * The request timed out and the module may send a fetch-fw or
+ * release-fw request later. Lets block the id we allocated for this
+ * request, so that the AP doesn't refer to a later fw-request (with
+ * same firmware_id) for the old timedout fw-request.
+ *
+ * NOTE:
+ *
+ * This also means that after 255 timeouts we will fail to service new
+ * firmware downloads. But what else can we do in that case anyway? Lets
+ * just hope that it never happens.
+ */
+ if (!fw_req->timedout)
+ ida_simple_remove(&fw_req->fw_download->id_map,
+ fw_req->firmware_id);
+
+ kfree(fw_req);
+}
+
+/*
+ * Incoming requests are serialized for a connection, and the only race possible
+ * is between the timeout handler freeing this and an incoming request.
+ *
+ * The operations on the fw-request list are protected by the mutex and
+ * get_fw_req() increments the reference count before returning a fw_req pointer
+ * to the users.
+ *
+ * free_firmware() also takes the mutex while removing an entry from the list,
+ * it guarantees that every user of fw_req has taken a kref-reference by now and
+ * we wouldn't have any new users.
+ *
+ * Once the last user drops the reference, the fw_req structure is freed.
+ */
+static void put_fw_req(struct fw_request *fw_req)
+{
+ kref_put(&fw_req->kref, fw_req_release);
+}
+
+/* Caller must call put_fw_req() after using struct fw_request */
+static struct fw_request *get_fw_req(struct fw_download *fw_download,
+ u8 firmware_id)
+{
+ struct fw_request *fw_req;
+
+ mutex_lock(&fw_download->mutex);
+
+ list_for_each_entry(fw_req, &fw_download->fw_requests, node) {
+ if (fw_req->firmware_id == firmware_id) {
+ kref_get(&fw_req->kref);
+ goto unlock;
+ }
+ }
+
+ fw_req = NULL;
+
+unlock:
+ mutex_unlock(&fw_download->mutex);
+
+ return fw_req;
+}
+
+static void free_firmware(struct fw_download *fw_download,
+ struct fw_request *fw_req)
+{
+ /* Already disabled from timeout handlers */
+ if (fw_req->disabled)
+ return;
+
+ mutex_lock(&fw_download->mutex);
+ list_del(&fw_req->node);
+ mutex_unlock(&fw_download->mutex);
+
+ fw_req->disabled = true;
+ put_fw_req(fw_req);
+}
+
+static void fw_request_timedout(struct work_struct *work)
+{
+ struct delayed_work *dwork = to_delayed_work(work);
+ struct fw_request *fw_req = container_of(dwork, struct fw_request, dwork);
+ struct fw_download *fw_download = fw_req->fw_download;
+
+ dev_err(fw_download->parent,
+ "Timed out waiting for fetch / release firmware requests: %u\n",
+ fw_req->firmware_id);
+
+ fw_req->timedout = true;
+ free_firmware(fw_download, fw_req);
+}
+
+static int exceeds_release_timeout(struct fw_request *fw_req)
+{
+ struct fw_download *fw_download = fw_req->fw_download;
+
+ if (time_before(jiffies, fw_req->release_timeout_j))
+ return 0;
+
+ dev_err(fw_download->parent,
+ "Firmware download didn't finish in time, abort: %d\n",
+ fw_req->firmware_id);
+
+ fw_req->timedout = true;
+ free_firmware(fw_download, fw_req);
+
+ return -ETIMEDOUT;
+}
+
+/* This returns path of the firmware blob on the disk */
+static struct fw_request *find_firmware(struct fw_download *fw_download,
+ const char *tag)
+{
+ struct gb_interface *intf = fw_download->connection->bundle->intf;
+ struct fw_request *fw_req;
+ int ret, req_count;
+
+ fw_req = kzalloc(sizeof(*fw_req), GFP_KERNEL);
+ if (!fw_req)
+ return ERR_PTR(-ENOMEM);
+
+ /* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
+ ret = ida_simple_get(&fw_download->id_map, 1, 256, GFP_KERNEL);
+ if (ret < 0) {
+ dev_err(fw_download->parent,
+ "failed to allocate firmware id (%d)\n", ret);
+ goto err_free_req;
+ }
+ fw_req->firmware_id = ret;
+
+ snprintf(fw_req->name, sizeof(fw_req->name),
+ FW_NAME_PREFIX "%08x_%08x_%08x_%08x_%s.tftf",
+ intf->ddbl1_manufacturer_id, intf->ddbl1_product_id,
+ intf->vendor_id, intf->product_id, tag);
+
+ dev_info(fw_download->parent, "Requested firmware package '%s'\n",
+ fw_req->name);
+
+ ret = request_firmware(&fw_req->fw, fw_req->name, fw_download->parent);
+ if (ret) {
+ dev_err(fw_download->parent,
+ "firmware request failed for %s (%d)\n", fw_req->name,
+ ret);
+ goto err_free_id;
+ }
+
+ fw_req->fw_download = fw_download;
+ kref_init(&fw_req->kref);
+
+ mutex_lock(&fw_download->mutex);
+ list_add(&fw_req->node, &fw_download->fw_requests);
+ mutex_unlock(&fw_download->mutex);
+
+ /* Timeout, in jiffies, within which firmware should get loaded */
+ req_count = DIV_ROUND_UP(fw_req->fw->size, MIN_FETCH_SIZE);
+ fw_req->release_timeout_j = jiffies + req_count * NEXT_REQ_TIMEOUT_J;
+
+ INIT_DELAYED_WORK(&fw_req->dwork, fw_request_timedout);
+ schedule_delayed_work(&fw_req->dwork, NEXT_REQ_TIMEOUT_J);
+
+ return fw_req;
+
+err_free_id:
+ ida_simple_remove(&fw_download->id_map, fw_req->firmware_id);
+err_free_req:
+ kfree(fw_req);
+
+ return ERR_PTR(ret);
+}
+
+static int fw_download_find_firmware(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct fw_download *fw_download = gb_connection_get_data(connection);
+ struct gb_fw_download_find_firmware_request *request;
+ struct gb_fw_download_find_firmware_response *response;
+ struct fw_request *fw_req;
+ const char *tag;
+
+ if (op->request->payload_size != sizeof(*request)) {
+ dev_err(fw_download->parent,
+ "illegal size of find firmware request (%zu != %zu)\n",
+ op->request->payload_size, sizeof(*request));
+ return -EINVAL;
+ }
+
+ request = op->request->payload;
+ tag = (const char *)request->firmware_tag;
+
+ /* firmware_tag must be null-terminated */
+ if (strnlen(tag, GB_FIRMWARE_TAG_MAX_SIZE) == GB_FIRMWARE_TAG_MAX_SIZE) {
+ dev_err(fw_download->parent,
+ "firmware-tag is not null-terminated\n");
+ return -EINVAL;
+ }
+
+ fw_req = find_firmware(fw_download, tag);
+ if (IS_ERR(fw_req))
+ return PTR_ERR(fw_req);
+
+ if (!gb_operation_response_alloc(op, sizeof(*response), GFP_KERNEL)) {
+ dev_err(fw_download->parent, "error allocating response\n");
+ free_firmware(fw_download, fw_req);
+ return -ENOMEM;
+ }
+
+ response = op->response->payload;
+ response->firmware_id = fw_req->firmware_id;
+ response->size = cpu_to_le32(fw_req->fw->size);
+
+ dev_dbg(fw_download->parent,
+ "firmware size is %zu bytes\n", fw_req->fw->size);
+
+ return 0;
+}
+
+static int fw_download_fetch_firmware(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct fw_download *fw_download = gb_connection_get_data(connection);
+ struct gb_fw_download_fetch_firmware_request *request;
+ struct gb_fw_download_fetch_firmware_response *response;
+ struct fw_request *fw_req;
+ const struct firmware *fw;
+ unsigned int offset, size;
+ u8 firmware_id;
+ int ret = 0;
+
+ if (op->request->payload_size != sizeof(*request)) {
+ dev_err(fw_download->parent,
+ "Illegal size of fetch firmware request (%zu %zu)\n",
+ op->request->payload_size, sizeof(*request));
+ return -EINVAL;
+ }
+
+ request = op->request->payload;
+ offset = le32_to_cpu(request->offset);
+ size = le32_to_cpu(request->size);
+ firmware_id = request->firmware_id;
+
+ fw_req = get_fw_req(fw_download, firmware_id);
+ if (!fw_req) {
+ dev_err(fw_download->parent,
+ "firmware not available for id: %02u\n", firmware_id);
+ return -EINVAL;
+ }
+
+ /* Make sure work handler isn't running in parallel */
+ cancel_delayed_work_sync(&fw_req->dwork);
+
+ /* We timed-out before reaching here ? */
+ if (fw_req->disabled) {
+ ret = -ETIMEDOUT;
+ goto put_fw;
+ }
+
+ /*
+ * Firmware download must finish within a limited time interval. If it
+ * doesn't, then we might have a buggy Module on the other side. Abort
+ * download.
+ */
+ ret = exceeds_release_timeout(fw_req);
+ if (ret)
+ goto put_fw;
+
+ fw = fw_req->fw;
+
+ if (offset >= fw->size || size > fw->size - offset) {
+ dev_err(fw_download->parent,
+ "bad fetch firmware request (offs = %u, size = %u)\n",
+ offset, size);
+ ret = -EINVAL;
+ goto put_fw;
+ }
+
+ if (!gb_operation_response_alloc(op, sizeof(*response) + size,
+ GFP_KERNEL)) {
+ dev_err(fw_download->parent,
+ "error allocating fetch firmware response\n");
+ ret = -ENOMEM;
+ goto put_fw;
+ }
+
+ response = op->response->payload;
+ memcpy(response->data, fw->data + offset, size);
+
+ dev_dbg(fw_download->parent,
+ "responding with firmware (offs = %u, size = %u)\n", offset,
+ size);
+
+ /* Refresh timeout */
+ schedule_delayed_work(&fw_req->dwork, NEXT_REQ_TIMEOUT_J);
+
+put_fw:
+ put_fw_req(fw_req);
+
+ return ret;
+}
+
+static int fw_download_release_firmware(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct fw_download *fw_download = gb_connection_get_data(connection);
+ struct gb_fw_download_release_firmware_request *request;
+ struct fw_request *fw_req;
+ u8 firmware_id;
+
+ if (op->request->payload_size != sizeof(*request)) {
+ dev_err(fw_download->parent,
+ "Illegal size of release firmware request (%zu %zu)\n",
+ op->request->payload_size, sizeof(*request));
+ return -EINVAL;
+ }
+
+ request = op->request->payload;
+ firmware_id = request->firmware_id;
+
+ fw_req = get_fw_req(fw_download, firmware_id);
+ if (!fw_req) {
+ dev_err(fw_download->parent,
+ "firmware not available for id: %02u\n", firmware_id);
+ return -EINVAL;
+ }
+
+ cancel_delayed_work_sync(&fw_req->dwork);
+
+ free_firmware(fw_download, fw_req);
+ put_fw_req(fw_req);
+
+ dev_dbg(fw_download->parent, "release firmware\n");
+
+ return 0;
+}
+
+int gb_fw_download_request_handler(struct gb_operation *op)
+{
+ u8 type = op->type;
+
+ switch (type) {
+ case GB_FW_DOWNLOAD_TYPE_FIND_FIRMWARE:
+ return fw_download_find_firmware(op);
+ case GB_FW_DOWNLOAD_TYPE_FETCH_FIRMWARE:
+ return fw_download_fetch_firmware(op);
+ case GB_FW_DOWNLOAD_TYPE_RELEASE_FIRMWARE:
+ return fw_download_release_firmware(op);
+ default:
+ dev_err(&op->connection->bundle->dev,
+ "unsupported request: %u\n", type);
+ return -EINVAL;
+ }
+}
+
+int gb_fw_download_connection_init(struct gb_connection *connection)
+{
+ struct fw_download *fw_download;
+ int ret;
+
+ if (!connection)
+ return 0;
+
+ fw_download = kzalloc(sizeof(*fw_download), GFP_KERNEL);
+ if (!fw_download)
+ return -ENOMEM;
+
+ fw_download->parent = &connection->bundle->dev;
+ INIT_LIST_HEAD(&fw_download->fw_requests);
+ ida_init(&fw_download->id_map);
+ gb_connection_set_data(connection, fw_download);
+ fw_download->connection = connection;
+ mutex_init(&fw_download->mutex);
+
+ ret = gb_connection_enable(connection);
+ if (ret)
+ goto err_destroy_id_map;
+
+ return 0;
+
+err_destroy_id_map:
+ ida_destroy(&fw_download->id_map);
+ kfree(fw_download);
+
+ return ret;
+}
+
+void gb_fw_download_connection_exit(struct gb_connection *connection)
+{
+ struct fw_download *fw_download;
+ struct fw_request *fw_req, *tmp;
+
+ if (!connection)
+ return;
+
+ fw_download = gb_connection_get_data(connection);
+ gb_connection_disable(fw_download->connection);
+
+ /*
+ * Make sure we have a reference to the pending requests, before they
+ * are freed from the timeout handler.
+ */
+ mutex_lock(&fw_download->mutex);
+ list_for_each_entry(fw_req, &fw_download->fw_requests, node)
+ kref_get(&fw_req->kref);
+ mutex_unlock(&fw_download->mutex);
+
+ /* Release pending firmware packages */
+ list_for_each_entry_safe(fw_req, tmp, &fw_download->fw_requests, node) {
+ cancel_delayed_work_sync(&fw_req->dwork);
+ free_firmware(fw_download, fw_req);
+ put_fw_req(fw_req);
+ }
+
+ ida_destroy(&fw_download->id_map);
+ kfree(fw_download);
+}
diff --git a/drivers/staging/greybus/fw-management.c b/drivers/staging/greybus/fw-management.c
new file mode 100644
index 000000000000..3cd6cf0a656b
--- /dev/null
+++ b/drivers/staging/greybus/fw-management.c
@@ -0,0 +1,721 @@
+/*
+ * Greybus Firmware Management Protocol Driver.
+ *
+ * Copyright 2016 Google Inc.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/cdev.h>
+#include <linux/completion.h>
+#include <linux/firmware.h>
+#include <linux/fs.h>
+#include <linux/idr.h>
+#include <linux/ioctl.h>
+#include <linux/uaccess.h>
+
+#include "firmware.h"
+#include "greybus_firmware.h"
+#include "greybus.h"
+
+#define FW_MGMT_TIMEOUT_MS 1000
+
+struct fw_mgmt {
+ struct device *parent;
+ struct gb_connection *connection;
+ struct kref kref;
+ struct list_head node;
+
+ /* Common id-map for interface and backend firmware requests */
+ struct ida id_map;
+ struct mutex mutex;
+ struct completion completion;
+ struct cdev cdev;
+ struct device *class_device;
+ dev_t dev_num;
+ unsigned int timeout_jiffies;
+ bool disabled; /* connection getting disabled */
+
+ /* Interface Firmware specific fields */
+ bool mode_switch_started;
+ bool intf_fw_loaded;
+ u8 intf_fw_request_id;
+ u8 intf_fw_status;
+ u16 intf_fw_major;
+ u16 intf_fw_minor;
+
+ /* Backend Firmware specific fields */
+ u8 backend_fw_request_id;
+ u8 backend_fw_status;
+};
+
+/*
+ * Number of minor devices this driver supports.
+ * There will be exactly one required per Interface.
+ */
+#define NUM_MINORS U8_MAX
+
+static struct class *fw_mgmt_class;
+static dev_t fw_mgmt_dev_num;
+static DEFINE_IDA(fw_mgmt_minors_map);
+static LIST_HEAD(fw_mgmt_list);
+static DEFINE_MUTEX(list_mutex);
+
+static void fw_mgmt_kref_release(struct kref *kref)
+{
+ struct fw_mgmt *fw_mgmt = container_of(kref, struct fw_mgmt, kref);
+
+ ida_destroy(&fw_mgmt->id_map);
+ kfree(fw_mgmt);
+}
+
+/*
+ * All users of fw_mgmt take a reference (from within list_mutex lock), before
+ * they get a pointer to play with. And the structure will be freed only after
+ * the last user has put the reference to it.
+ */
+static void put_fw_mgmt(struct fw_mgmt *fw_mgmt)
+{
+ kref_put(&fw_mgmt->kref, fw_mgmt_kref_release);
+}
+
+/* Caller must call put_fw_mgmt() after using struct fw_mgmt */
+static struct fw_mgmt *get_fw_mgmt(struct cdev *cdev)
+{
+ struct fw_mgmt *fw_mgmt;
+
+ mutex_lock(&list_mutex);
+
+ list_for_each_entry(fw_mgmt, &fw_mgmt_list, node) {
+ if (&fw_mgmt->cdev == cdev) {
+ kref_get(&fw_mgmt->kref);
+ goto unlock;
+ }
+ }
+
+ fw_mgmt = NULL;
+
+unlock:
+ mutex_unlock(&list_mutex);
+
+ return fw_mgmt;
+}
+
+static int fw_mgmt_interface_fw_version_operation(struct fw_mgmt *fw_mgmt,
+ struct fw_mgmt_ioc_get_intf_version *fw_info)
+{
+ struct gb_connection *connection = fw_mgmt->connection;
+ struct gb_fw_mgmt_interface_fw_version_response response;
+ int ret;
+
+ ret = gb_operation_sync(connection,
+ GB_FW_MGMT_TYPE_INTERFACE_FW_VERSION, NULL, 0,
+ &response, sizeof(response));
+ if (ret) {
+ dev_err(fw_mgmt->parent,
+ "failed to get interface firmware version (%d)\n", ret);
+ return ret;
+ }
+
+ fw_info->major = le16_to_cpu(response.major);
+ fw_info->minor = le16_to_cpu(response.minor);
+
+ strncpy(fw_info->firmware_tag, response.firmware_tag,
+ GB_FIRMWARE_TAG_MAX_SIZE);
+
+ /*
+ * The firmware-tag should be NULL terminated, otherwise throw error but
+ * don't fail.
+ */
+ if (fw_info->firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
+ dev_err(fw_mgmt->parent,
+ "fw-version: firmware-tag is not NULL terminated\n");
+ fw_info->firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] = '\0';
+ }
+
+ return 0;
+}
+
+static int fw_mgmt_load_and_validate_operation(struct fw_mgmt *fw_mgmt,
+ u8 load_method, const char *tag)
+{
+ struct gb_fw_mgmt_load_and_validate_fw_request request;
+ int ret;
+
+ if (load_method != GB_FW_LOAD_METHOD_UNIPRO &&
+ load_method != GB_FW_LOAD_METHOD_INTERNAL) {
+ dev_err(fw_mgmt->parent,
+ "invalid load-method (%d)\n", load_method);
+ return -EINVAL;
+ }
+
+ request.load_method = load_method;
+ strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);
+
+ /*
+ * The firmware-tag should be NULL terminated, otherwise throw error and
+ * fail.
+ */
+ if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
+ dev_err(fw_mgmt->parent, "load-and-validate: firmware-tag is not NULL terminated\n");
+ return -EINVAL;
+ }
+
+ /* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
+ ret = ida_simple_get(&fw_mgmt->id_map, 1, 256, GFP_KERNEL);
+ if (ret < 0) {
+ dev_err(fw_mgmt->parent, "failed to allocate request id (%d)\n",
+ ret);
+ return ret;
+ }
+
+ fw_mgmt->intf_fw_request_id = ret;
+ fw_mgmt->intf_fw_loaded = false;
+ request.request_id = ret;
+
+ ret = gb_operation_sync(fw_mgmt->connection,
+ GB_FW_MGMT_TYPE_LOAD_AND_VALIDATE_FW, &request,
+ sizeof(request), NULL, 0);
+ if (ret) {
+ ida_simple_remove(&fw_mgmt->id_map,
+ fw_mgmt->intf_fw_request_id);
+ fw_mgmt->intf_fw_request_id = 0;
+ dev_err(fw_mgmt->parent,
+ "load and validate firmware request failed (%d)\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fw_mgmt_interface_fw_loaded_operation(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct fw_mgmt *fw_mgmt = gb_connection_get_data(connection);
+ struct gb_fw_mgmt_loaded_fw_request *request;
+
+ /* No pending load and validate request ? */
+ if (!fw_mgmt->intf_fw_request_id) {
+ dev_err(fw_mgmt->parent,
+ "unexpected firmware loaded request received\n");
+ return -ENODEV;
+ }
+
+ if (op->request->payload_size != sizeof(*request)) {
+ dev_err(fw_mgmt->parent, "illegal size of firmware loaded request (%zu != %zu)\n",
+ op->request->payload_size, sizeof(*request));
+ return -EINVAL;
+ }
+
+ request = op->request->payload;
+
+ /* Invalid request-id ? */
+ if (request->request_id != fw_mgmt->intf_fw_request_id) {
+ dev_err(fw_mgmt->parent, "invalid request id for firmware loaded request (%02u != %02u)\n",
+ fw_mgmt->intf_fw_request_id, request->request_id);
+ return -ENODEV;
+ }
+
+ ida_simple_remove(&fw_mgmt->id_map, fw_mgmt->intf_fw_request_id);
+ fw_mgmt->intf_fw_request_id = 0;
+ fw_mgmt->intf_fw_status = request->status;
+ fw_mgmt->intf_fw_major = le16_to_cpu(request->major);
+ fw_mgmt->intf_fw_minor = le16_to_cpu(request->minor);
+
+ if (fw_mgmt->intf_fw_status == GB_FW_LOAD_STATUS_FAILED)
+ dev_err(fw_mgmt->parent,
+ "failed to load interface firmware, status:%02x\n",
+ fw_mgmt->intf_fw_status);
+ else if (fw_mgmt->intf_fw_status == GB_FW_LOAD_STATUS_VALIDATION_FAILED)
+ dev_err(fw_mgmt->parent,
+ "failed to validate interface firmware, status:%02x\n",
+ fw_mgmt->intf_fw_status);
+ else
+ fw_mgmt->intf_fw_loaded = true;
+
+ complete(&fw_mgmt->completion);
+
+ return 0;
+}
+
+static int fw_mgmt_backend_fw_version_operation(struct fw_mgmt *fw_mgmt,
+ struct fw_mgmt_ioc_get_backend_version *fw_info)
+{
+ struct gb_connection *connection = fw_mgmt->connection;
+ struct gb_fw_mgmt_backend_fw_version_request request;
+ struct gb_fw_mgmt_backend_fw_version_response response;
+ int ret;
+
+ strncpy(request.firmware_tag, fw_info->firmware_tag,
+ GB_FIRMWARE_TAG_MAX_SIZE);
+
+ /*
+ * The firmware-tag should be NULL terminated, otherwise throw error and
+ * fail.
+ */
+ if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
+ dev_err(fw_mgmt->parent, "backend-version: firmware-tag is not NULL terminated\n");
+ return -EINVAL;
+ }
+
+ ret = gb_operation_sync(connection,
+ GB_FW_MGMT_TYPE_BACKEND_FW_VERSION, &request,
+ sizeof(request), &response, sizeof(response));
+ if (ret) {
+ dev_err(fw_mgmt->parent, "failed to get version of %s backend firmware (%d)\n",
+ fw_info->firmware_tag, ret);
+ return ret;
+ }
+
+ fw_info->status = response.status;
+
+ /* Reset version as that should be non-zero only for success case */
+ fw_info->major = 0;
+ fw_info->minor = 0;
+
+ switch (fw_info->status) {
+ case GB_FW_BACKEND_VERSION_STATUS_SUCCESS:
+ fw_info->major = le16_to_cpu(response.major);
+ fw_info->minor = le16_to_cpu(response.minor);
+ break;
+ case GB_FW_BACKEND_VERSION_STATUS_NOT_AVAILABLE:
+ case GB_FW_BACKEND_VERSION_STATUS_RETRY:
+ break;
+ case GB_FW_BACKEND_VERSION_STATUS_NOT_SUPPORTED:
+ dev_err(fw_mgmt->parent,
+ "Firmware with tag %s is not supported by Interface\n",
+ fw_info->firmware_tag);
+ break;
+ default:
+ dev_err(fw_mgmt->parent, "Invalid status received: %u\n",
+ fw_info->status);
+ }
+
+ return 0;
+}
+
+static int fw_mgmt_backend_fw_update_operation(struct fw_mgmt *fw_mgmt,
+ char *tag)
+{
+ struct gb_fw_mgmt_backend_fw_update_request request;
+ int ret;
+
+ strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);
+
+ /*
+ * The firmware-tag should be NULL terminated, otherwise throw error and
+ * fail.
+ */
+ if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
+ dev_err(fw_mgmt->parent, "backend-update: firmware-tag is not NULL terminated\n");
+ return -EINVAL;
+ }
+
+ /* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
+ ret = ida_simple_get(&fw_mgmt->id_map, 1, 256, GFP_KERNEL);
+ if (ret < 0) {
+ dev_err(fw_mgmt->parent, "failed to allocate request id (%d)\n",
+ ret);
+ return ret;
+ }
+
+ fw_mgmt->backend_fw_request_id = ret;
+ request.request_id = ret;
+
+ ret = gb_operation_sync(fw_mgmt->connection,
+ GB_FW_MGMT_TYPE_BACKEND_FW_UPDATE, &request,
+ sizeof(request), NULL, 0);
+ if (ret) {
+ ida_simple_remove(&fw_mgmt->id_map,
+ fw_mgmt->backend_fw_request_id);
+ fw_mgmt->backend_fw_request_id = 0;
+ dev_err(fw_mgmt->parent,
+ "backend %s firmware update request failed (%d)\n", tag,
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fw_mgmt_backend_fw_updated_operation(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct fw_mgmt *fw_mgmt = gb_connection_get_data(connection);
+ struct gb_fw_mgmt_backend_fw_updated_request *request;
+
+ /* No pending load and validate request ? */
+ if (!fw_mgmt->backend_fw_request_id) {
+ dev_err(fw_mgmt->parent, "unexpected backend firmware updated request received\n");
+ return -ENODEV;
+ }
+
+ if (op->request->payload_size != sizeof(*request)) {
+ dev_err(fw_mgmt->parent, "illegal size of backend firmware updated request (%zu != %zu)\n",
+ op->request->payload_size, sizeof(*request));
+ return -EINVAL;
+ }
+
+ request = op->request->payload;
+
+ /* Invalid request-id ? */
+ if (request->request_id != fw_mgmt->backend_fw_request_id) {
+ dev_err(fw_mgmt->parent, "invalid request id for backend firmware updated request (%02u != %02u)\n",
+ fw_mgmt->backend_fw_request_id, request->request_id);
+ return -ENODEV;
+ }
+
+ ida_simple_remove(&fw_mgmt->id_map, fw_mgmt->backend_fw_request_id);
+ fw_mgmt->backend_fw_request_id = 0;
+ fw_mgmt->backend_fw_status = request->status;
+
+ if ((fw_mgmt->backend_fw_status != GB_FW_BACKEND_FW_STATUS_SUCCESS) &&
+ (fw_mgmt->backend_fw_status != GB_FW_BACKEND_FW_STATUS_RETRY))
+ dev_err(fw_mgmt->parent,
+ "failed to load backend firmware: %02x\n",
+ fw_mgmt->backend_fw_status);
+
+ complete(&fw_mgmt->completion);
+
+ return 0;
+}
+
+/* Char device fops */
+
+static int fw_mgmt_open(struct inode *inode, struct file *file)
+{
+ struct fw_mgmt *fw_mgmt = get_fw_mgmt(inode->i_cdev);
+
+ /* fw_mgmt structure can't get freed until file descriptor is closed */
+ if (fw_mgmt) {
+ file->private_data = fw_mgmt;
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
+static int fw_mgmt_release(struct inode *inode, struct file *file)
+{
+ struct fw_mgmt *fw_mgmt = file->private_data;
+
+ put_fw_mgmt(fw_mgmt);
+ return 0;
+}
+
+static int fw_mgmt_ioctl(struct fw_mgmt *fw_mgmt, unsigned int cmd,
+ void __user *buf)
+{
+ struct fw_mgmt_ioc_get_intf_version intf_fw_info;
+ struct fw_mgmt_ioc_get_backend_version backend_fw_info;
+ struct fw_mgmt_ioc_intf_load_and_validate intf_load;
+ struct fw_mgmt_ioc_backend_fw_update backend_update;
+ unsigned int timeout;
+ int ret;
+
+ /* Reject any operations after mode-switch has started */
+ if (fw_mgmt->mode_switch_started)
+ return -EBUSY;
+
+ switch (cmd) {
+ case FW_MGMT_IOC_GET_INTF_FW:
+ ret = fw_mgmt_interface_fw_version_operation(fw_mgmt,
+ &intf_fw_info);
+ if (ret)
+ return ret;
+
+ if (copy_to_user(buf, &intf_fw_info, sizeof(intf_fw_info)))
+ return -EFAULT;
+
+ return 0;
+ case FW_MGMT_IOC_GET_BACKEND_FW:
+ if (copy_from_user(&backend_fw_info, buf,
+ sizeof(backend_fw_info)))
+ return -EFAULT;
+
+ ret = fw_mgmt_backend_fw_version_operation(fw_mgmt,
+ &backend_fw_info);
+ if (ret)
+ return ret;
+
+ if (copy_to_user(buf, &backend_fw_info,
+ sizeof(backend_fw_info)))
+ return -EFAULT;
+
+ return 0;
+ case FW_MGMT_IOC_INTF_LOAD_AND_VALIDATE:
+ if (copy_from_user(&intf_load, buf, sizeof(intf_load)))
+ return -EFAULT;
+
+ ret = fw_mgmt_load_and_validate_operation(fw_mgmt,
+ intf_load.load_method, intf_load.firmware_tag);
+ if (ret)
+ return ret;
+
+ if (!wait_for_completion_timeout(&fw_mgmt->completion,
+ fw_mgmt->timeout_jiffies)) {
+ dev_err(fw_mgmt->parent, "timed out waiting for firmware load and validation to finish\n");
+ return -ETIMEDOUT;
+ }
+
+ intf_load.status = fw_mgmt->intf_fw_status;
+ intf_load.major = fw_mgmt->intf_fw_major;
+ intf_load.minor = fw_mgmt->intf_fw_minor;
+
+ if (copy_to_user(buf, &intf_load, sizeof(intf_load)))
+ return -EFAULT;
+
+ return 0;
+ case FW_MGMT_IOC_INTF_BACKEND_FW_UPDATE:
+ if (copy_from_user(&backend_update, buf,
+ sizeof(backend_update)))
+ return -EFAULT;
+
+ ret = fw_mgmt_backend_fw_update_operation(fw_mgmt,
+ backend_update.firmware_tag);
+ if (ret)
+ return ret;
+
+ if (!wait_for_completion_timeout(&fw_mgmt->completion,
+ fw_mgmt->timeout_jiffies)) {
+ dev_err(fw_mgmt->parent, "timed out waiting for backend firmware update to finish\n");
+ return -ETIMEDOUT;
+ }
+
+ backend_update.status = fw_mgmt->backend_fw_status;
+
+ if (copy_to_user(buf, &backend_update, sizeof(backend_update)))
+ return -EFAULT;
+
+ return 0;
+ case FW_MGMT_IOC_SET_TIMEOUT_MS:
+ if (get_user(timeout, (unsigned int __user *)buf))
+ return -EFAULT;
+
+ if (!timeout) {
+ dev_err(fw_mgmt->parent, "timeout can't be zero\n");
+ return -EINVAL;
+ }
+
+ fw_mgmt->timeout_jiffies = msecs_to_jiffies(timeout);
+
+ return 0;
+ case FW_MGMT_IOC_MODE_SWITCH:
+ if (!fw_mgmt->intf_fw_loaded) {
+ dev_err(fw_mgmt->parent,
+ "Firmware not loaded for mode-switch\n");
+ return -EPERM;
+ }
+
+ /*
+ * Disallow new ioctls as the fw-core bundle driver is going to
+ * get disconnected soon and the character device will get
+ * removed.
+ */
+ fw_mgmt->mode_switch_started = true;
+
+ ret = gb_interface_request_mode_switch(fw_mgmt->connection->intf);
+ if (ret) {
+ dev_err(fw_mgmt->parent, "Mode-switch failed: %d\n",
+ ret);
+ fw_mgmt->mode_switch_started = false;
+ return ret;
+ }
+
+ return 0;
+ default:
+ return -ENOTTY;
+ }
+}
+
+static long fw_mgmt_ioctl_unlocked(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct fw_mgmt *fw_mgmt = file->private_data;
+ struct gb_bundle *bundle = fw_mgmt->connection->bundle;
+ int ret = -ENODEV;
+
+ /*
+ * Serialize ioctls.
+ *
+ * We don't want the user to do few operations in parallel. For example,
+ * updating Interface firmware in parallel for the same Interface. There
+ * is no need to do things in parallel for speed and we can avoid having
+ * complicated code for now.
+ *
+ * This is also used to protect ->disabled, which is used to check if
+ * the connection is getting disconnected, so that we don't start any
+ * new operations.
+ */
+ mutex_lock(&fw_mgmt->mutex);
+ if (!fw_mgmt->disabled) {
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (!ret) {
+ ret = fw_mgmt_ioctl(fw_mgmt, cmd, (void __user *)arg);
+ gb_pm_runtime_put_autosuspend(bundle);
+ }
+ }
+ mutex_unlock(&fw_mgmt->mutex);
+
+ return ret;
+}
+
+static const struct file_operations fw_mgmt_fops = {
+ .owner = THIS_MODULE,
+ .open = fw_mgmt_open,
+ .release = fw_mgmt_release,
+ .unlocked_ioctl = fw_mgmt_ioctl_unlocked,
+};
+
+int gb_fw_mgmt_request_handler(struct gb_operation *op)
+{
+ u8 type = op->type;
+
+ switch (type) {
+ case GB_FW_MGMT_TYPE_LOADED_FW:
+ return fw_mgmt_interface_fw_loaded_operation(op);
+ case GB_FW_MGMT_TYPE_BACKEND_FW_UPDATED:
+ return fw_mgmt_backend_fw_updated_operation(op);
+ default:
+ dev_err(&op->connection->bundle->dev,
+ "unsupported request: %u\n", type);
+ return -EINVAL;
+ }
+}
+
+int gb_fw_mgmt_connection_init(struct gb_connection *connection)
+{
+ struct fw_mgmt *fw_mgmt;
+ int ret, minor;
+
+ if (!connection)
+ return 0;
+
+ fw_mgmt = kzalloc(sizeof(*fw_mgmt), GFP_KERNEL);
+ if (!fw_mgmt)
+ return -ENOMEM;
+
+ fw_mgmt->parent = &connection->bundle->dev;
+ fw_mgmt->timeout_jiffies = msecs_to_jiffies(FW_MGMT_TIMEOUT_MS);
+ fw_mgmt->connection = connection;
+
+ gb_connection_set_data(connection, fw_mgmt);
+ init_completion(&fw_mgmt->completion);
+ ida_init(&fw_mgmt->id_map);
+ mutex_init(&fw_mgmt->mutex);
+ kref_init(&fw_mgmt->kref);
+
+ mutex_lock(&list_mutex);
+ list_add(&fw_mgmt->node, &fw_mgmt_list);
+ mutex_unlock(&list_mutex);
+
+ ret = gb_connection_enable(connection);
+ if (ret)
+ goto err_list_del;
+
+ minor = ida_simple_get(&fw_mgmt_minors_map, 0, NUM_MINORS, GFP_KERNEL);
+ if (minor < 0) {
+ ret = minor;
+ goto err_connection_disable;
+ }
+
+ /* Add a char device to allow userspace to interact with fw-mgmt */
+ fw_mgmt->dev_num = MKDEV(MAJOR(fw_mgmt_dev_num), minor);
+ cdev_init(&fw_mgmt->cdev, &fw_mgmt_fops);
+
+ ret = cdev_add(&fw_mgmt->cdev, fw_mgmt->dev_num, 1);
+ if (ret)
+ goto err_remove_ida;
+
+ /* Add a soft link to the previously added char-dev within the bundle */
+ fw_mgmt->class_device = device_create(fw_mgmt_class, fw_mgmt->parent,
+ fw_mgmt->dev_num, NULL,
+ "gb-fw-mgmt-%d", minor);
+ if (IS_ERR(fw_mgmt->class_device)) {
+ ret = PTR_ERR(fw_mgmt->class_device);
+ goto err_del_cdev;
+ }
+
+ return 0;
+
+err_del_cdev:
+ cdev_del(&fw_mgmt->cdev);
+err_remove_ida:
+ ida_simple_remove(&fw_mgmt_minors_map, minor);
+err_connection_disable:
+ gb_connection_disable(connection);
+err_list_del:
+ mutex_lock(&list_mutex);
+ list_del(&fw_mgmt->node);
+ mutex_unlock(&list_mutex);
+
+ put_fw_mgmt(fw_mgmt);
+
+ return ret;
+}
+
+void gb_fw_mgmt_connection_exit(struct gb_connection *connection)
+{
+ struct fw_mgmt *fw_mgmt;
+
+ if (!connection)
+ return;
+
+ fw_mgmt = gb_connection_get_data(connection);
+
+ device_destroy(fw_mgmt_class, fw_mgmt->dev_num);
+ cdev_del(&fw_mgmt->cdev);
+ ida_simple_remove(&fw_mgmt_minors_map, MINOR(fw_mgmt->dev_num));
+
+ /*
+ * Disallow any new ioctl operations on the char device and wait for
+ * existing ones to finish.
+ */
+ mutex_lock(&fw_mgmt->mutex);
+ fw_mgmt->disabled = true;
+ mutex_unlock(&fw_mgmt->mutex);
+
+ /* All pending greybus operations should have finished by now */
+ gb_connection_disable(fw_mgmt->connection);
+
+ /* Disallow new users to get access to the fw_mgmt structure */
+ mutex_lock(&list_mutex);
+ list_del(&fw_mgmt->node);
+ mutex_unlock(&list_mutex);
+
+ /*
+ * All current users of fw_mgmt would have taken a reference to it by
+ * now, we can drop our reference and wait the last user will get
+ * fw_mgmt freed.
+ */
+ put_fw_mgmt(fw_mgmt);
+}
+
+int fw_mgmt_init(void)
+{
+ int ret;
+
+ fw_mgmt_class = class_create(THIS_MODULE, "gb_fw_mgmt");
+ if (IS_ERR(fw_mgmt_class))
+ return PTR_ERR(fw_mgmt_class);
+
+ ret = alloc_chrdev_region(&fw_mgmt_dev_num, 0, NUM_MINORS,
+ "gb_fw_mgmt");
+ if (ret)
+ goto err_remove_class;
+
+ return 0;
+
+err_remove_class:
+ class_destroy(fw_mgmt_class);
+ return ret;
+}
+
+void fw_mgmt_exit(void)
+{
+ unregister_chrdev_region(fw_mgmt_dev_num, NUM_MINORS);
+ class_destroy(fw_mgmt_class);
+ ida_destroy(&fw_mgmt_minors_map);
+}
diff --git a/drivers/staging/greybus/gb-camera.h b/drivers/staging/greybus/gb-camera.h
new file mode 100644
index 000000000000..d45dabc5b367
--- /dev/null
+++ b/drivers/staging/greybus/gb-camera.h
@@ -0,0 +1,127 @@
+/*
+ * Greybus Camera protocol driver.
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+#ifndef __GB_CAMERA_H
+#define __GB_CAMERA_H
+
+#include <linux/v4l2-mediabus.h>
+
+/* Input flags need to be set from the caller */
+#define GB_CAMERA_IN_FLAG_TEST (1 << 0)
+/* Output flags returned */
+#define GB_CAMERA_OUT_FLAG_ADJUSTED (1 << 0)
+
+/**
+ * struct gb_camera_stream - Represents greybus camera stream.
+ * @width: Stream width in pixels.
+ * @height: Stream height in pixels.
+ * @pixel_code: Media bus pixel code.
+ * @vc: MIPI CSI virtual channel.
+ * @dt: MIPI CSI data types. Most formats use a single data type, in which case
+ * the second element will be ignored.
+ * @max_size: Maximum size of a frame in bytes. The camera module guarantees
+ * that all data between the Frame Start and Frame End packet for
+ * the associated virtual channel and data type(s) will not exceed
+ * this size.
+ */
+struct gb_camera_stream {
+ unsigned int width;
+ unsigned int height;
+ enum v4l2_mbus_pixelcode pixel_code;
+ unsigned int vc;
+ unsigned int dt[2];
+ unsigned int max_size;
+};
+
+/**
+ * struct gb_camera_csi_params - CSI configuration parameters
+ * @num_lanes: number of CSI data lanes
+ * @clk_freq: CSI clock frequency in Hz
+ */
+struct gb_camera_csi_params {
+ unsigned int num_lanes;
+ unsigned int clk_freq;
+};
+
+/**
+ * struct gb_camera_ops - Greybus camera operations, used by the Greybus camera
+ * driver to expose operations to the host camera driver.
+ * @capabilities: Retrieve camera capabilities and store them in the buffer
+ * 'buf' capabilities. The buffer maximum size is specified by
+ * the caller in the 'size' parameter, and the effective
+ * capabilities size is returned from the function. If the buffer
+ * size is too small to hold the capabilities an error is
+ * returned and the buffer is left untouched.
+ *
+ * @configure_streams: Negotiate configuration and prepare the module for video
+ * capture. The caller specifies the number of streams it
+ * requests in the 'nstreams' argument and the associated
+ * streams configurations in the 'streams' argument. The
+ * GB_CAMERA_IN_FLAG_TEST 'flag' can be set to test a
+ * configuration without applying it, otherwise the
+ * configuration is applied by the module. The module can
+ * decide to modify the requested configuration, including
+ * using a different number of streams. In that case the
+ * modified configuration won't be applied, the
+ * GB_CAMERA_OUT_FLAG_ADJUSTED 'flag' will be set upon
+ * return, and the modified configuration and number of
+ * streams stored in 'streams' and 'array'. The module
+ * returns its CSI-2 bus parameters in the 'csi_params'
+ * structure in all cases.
+ *
+ * @capture: Submit a capture request. The supplied 'request_id' must be unique
+ * and higher than the IDs of all the previously submitted requests.
+ * The 'streams' argument specifies which streams are affected by the
+ * request in the form of a bitmask, with bits corresponding to the
+ * configured streams indexes. If the request contains settings, the
+ * 'settings' argument points to the settings buffer and its size is
+ * specified by the 'settings_size' argument. Otherwise the 'settings'
+ * argument should be set to NULL and 'settings_size' to 0.
+ *
+ * @flush: Flush the capture requests queue. Return the ID of the last request
+ * that will processed by the device before it stops transmitting video
+ * frames. All queued capture requests with IDs higher than the returned
+ * ID will be dropped without being processed.
+ */
+struct gb_camera_ops {
+ ssize_t (*capabilities)(void *priv, char *buf, size_t len);
+ int (*configure_streams)(void *priv, unsigned int *nstreams,
+ unsigned int *flags, struct gb_camera_stream *streams,
+ struct gb_camera_csi_params *csi_params);
+ int (*capture)(void *priv, u32 request_id,
+ unsigned int streams, unsigned int num_frames,
+ size_t settings_size, const void *settings);
+ int (*flush)(void *priv, u32 *request_id);
+};
+
+/**
+ * struct gb_camera_module - Represents greybus camera module.
+ * @priv: Module private data, passed to all camera operations.
+ * @ops: Greybus camera operation callbacks.
+ * @interface_id: Interface id of the module.
+ * @refcount: Reference counting object.
+ * @release: Module release function.
+ * @list: List entry in the camera modules list.
+ */
+struct gb_camera_module {
+ void *priv;
+ const struct gb_camera_ops *ops;
+
+ unsigned int interface_id;
+ struct kref refcount;
+ void (*release)(struct kref *kref);
+ struct list_head list; /* Global list */
+};
+
+#define gb_camera_call(f, op, args...) \
+ (!(f) ? -ENODEV : (((f)->ops->op) ? \
+ (f)->ops->op((f)->priv, ##args) : -ENOIOCTLCMD))
+
+int gb_camera_register(struct gb_camera_module *module);
+int gb_camera_unregister(struct gb_camera_module *module);
+
+#endif /* __GB_CAMERA_H */
diff --git a/drivers/staging/greybus/gbphy.c b/drivers/staging/greybus/gbphy.c
new file mode 100644
index 000000000000..bcde7c9a0f17
--- /dev/null
+++ b/drivers/staging/greybus/gbphy.c
@@ -0,0 +1,360 @@
+/*
+ * Greybus Bridged-Phy Bus driver
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+
+#include "greybus.h"
+#include "gbphy.h"
+
+#define GB_GBPHY_AUTOSUSPEND_MS 3000
+
+struct gbphy_host {
+ struct gb_bundle *bundle;
+ struct list_head devices;
+};
+
+static DEFINE_IDA(gbphy_id);
+
+static ssize_t protocol_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
+
+ return sprintf(buf, "0x%02x\n", gbphy_dev->cport_desc->protocol_id);
+}
+static DEVICE_ATTR_RO(protocol_id);
+
+static struct attribute *gbphy_dev_attrs[] = {
+ &dev_attr_protocol_id.attr,
+ NULL,
+};
+
+ATTRIBUTE_GROUPS(gbphy_dev);
+
+static void gbphy_dev_release(struct device *dev)
+{
+ struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
+
+ ida_simple_remove(&gbphy_id, gbphy_dev->id);
+ kfree(gbphy_dev);
+}
+
+#ifdef CONFIG_PM
+static int gb_gbphy_idle(struct device *dev)
+{
+ pm_runtime_mark_last_busy(dev);
+ pm_request_autosuspend(dev);
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops gb_gbphy_pm_ops = {
+ SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend,
+ pm_generic_runtime_resume,
+ gb_gbphy_idle)
+};
+
+static struct device_type greybus_gbphy_dev_type = {
+ .name = "gbphy_device",
+ .release = gbphy_dev_release,
+ .pm = &gb_gbphy_pm_ops,
+};
+
+static int gbphy_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
+ struct greybus_descriptor_cport *cport_desc = gbphy_dev->cport_desc;
+ struct gb_bundle *bundle = gbphy_dev->bundle;
+ struct gb_interface *intf = bundle->intf;
+ struct gb_module *module = intf->module;
+ struct gb_host_device *hd = intf->hd;
+
+ if (add_uevent_var(env, "BUS=%u", hd->bus_id))
+ return -ENOMEM;
+ if (add_uevent_var(env, "MODULE=%u", module->module_id))
+ return -ENOMEM;
+ if (add_uevent_var(env, "INTERFACE=%u", intf->interface_id))
+ return -ENOMEM;
+ if (add_uevent_var(env, "GREYBUS_ID=%08x/%08x",
+ intf->vendor_id, intf->product_id))
+ return -ENOMEM;
+ if (add_uevent_var(env, "BUNDLE=%u", gbphy_dev->bundle->id))
+ return -ENOMEM;
+ if (add_uevent_var(env, "BUNDLE_CLASS=%02x", bundle->class))
+ return -ENOMEM;
+ if (add_uevent_var(env, "GBPHY=%u", gbphy_dev->id))
+ return -ENOMEM;
+ if (add_uevent_var(env, "PROTOCOL_ID=%02x", cport_desc->protocol_id))
+ return -ENOMEM;
+
+ return 0;
+}
+
+static const struct gbphy_device_id *
+gbphy_dev_match_id(struct gbphy_device *gbphy_dev, struct gbphy_driver *gbphy_drv)
+{
+ const struct gbphy_device_id *id = gbphy_drv->id_table;
+
+ if (!id)
+ return NULL;
+
+ for (; id->protocol_id; id++)
+ if (id->protocol_id == gbphy_dev->cport_desc->protocol_id)
+ return id;
+
+ return NULL;
+}
+
+static int gbphy_dev_match(struct device *dev, struct device_driver *drv)
+{
+ struct gbphy_driver *gbphy_drv = to_gbphy_driver(drv);
+ struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
+ const struct gbphy_device_id *id;
+
+ id = gbphy_dev_match_id(gbphy_dev, gbphy_drv);
+ if (id)
+ return 1;
+
+ return 0;
+}
+
+static int gbphy_dev_probe(struct device *dev)
+{
+ struct gbphy_driver *gbphy_drv = to_gbphy_driver(dev->driver);
+ struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
+ const struct gbphy_device_id *id;
+ int ret;
+
+ id = gbphy_dev_match_id(gbphy_dev, gbphy_drv);
+ if (!id)
+ return -ENODEV;
+
+ /* for old kernels we need get_sync to resume parent devices */
+ ret = gb_pm_runtime_get_sync(gbphy_dev->bundle);
+ if (ret < 0)
+ return ret;
+
+ pm_runtime_set_autosuspend_delay(dev, GB_GBPHY_AUTOSUSPEND_MS);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ /*
+ * Drivers should call put on the gbphy dev before returning
+ * from probe if they support runtime pm.
+ */
+ ret = gbphy_drv->probe(gbphy_dev, id);
+ if (ret) {
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_put_noidle(dev);
+ pm_runtime_dont_use_autosuspend(dev);
+ }
+
+ gb_pm_runtime_put_autosuspend(gbphy_dev->bundle);
+
+ return ret;
+}
+
+static int gbphy_dev_remove(struct device *dev)
+{
+ struct gbphy_driver *gbphy_drv = to_gbphy_driver(dev->driver);
+ struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
+
+ gbphy_drv->remove(gbphy_dev);
+
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_put_noidle(dev);
+ pm_runtime_dont_use_autosuspend(dev);
+
+ return 0;
+}
+
+static struct bus_type gbphy_bus_type = {
+ .name = "gbphy",
+ .match = gbphy_dev_match,
+ .probe = gbphy_dev_probe,
+ .remove = gbphy_dev_remove,
+ .uevent = gbphy_dev_uevent,
+};
+
+int gb_gbphy_register_driver(struct gbphy_driver *driver,
+ struct module *owner, const char *mod_name)
+{
+ int retval;
+
+ if (greybus_disabled())
+ return -ENODEV;
+
+ driver->driver.bus = &gbphy_bus_type;
+ driver->driver.name = driver->name;
+ driver->driver.owner = owner;
+ driver->driver.mod_name = mod_name;
+
+ retval = driver_register(&driver->driver);
+ if (retval)
+ return retval;
+
+ pr_info("registered new driver %s\n", driver->name);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gb_gbphy_register_driver);
+
+void gb_gbphy_deregister_driver(struct gbphy_driver *driver)
+{
+ driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(gb_gbphy_deregister_driver);
+
+static struct gbphy_device *gb_gbphy_create_dev(struct gb_bundle *bundle,
+ struct greybus_descriptor_cport *cport_desc)
+{
+ struct gbphy_device *gbphy_dev;
+ int retval;
+ int id;
+
+ id = ida_simple_get(&gbphy_id, 1, 0, GFP_KERNEL);
+ if (id < 0)
+ return ERR_PTR(id);
+
+ gbphy_dev = kzalloc(sizeof(*gbphy_dev), GFP_KERNEL);
+ if (!gbphy_dev) {
+ ida_simple_remove(&gbphy_id, id);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ gbphy_dev->id = id;
+ gbphy_dev->bundle = bundle;
+ gbphy_dev->cport_desc = cport_desc;
+ gbphy_dev->dev.parent = &bundle->dev;
+ gbphy_dev->dev.bus = &gbphy_bus_type;
+ gbphy_dev->dev.type = &greybus_gbphy_dev_type;
+ gbphy_dev->dev.groups = gbphy_dev_groups;
+ gbphy_dev->dev.dma_mask = bundle->dev.dma_mask;
+ dev_set_name(&gbphy_dev->dev, "gbphy%d", id);
+
+ retval = device_register(&gbphy_dev->dev);
+ if (retval) {
+ put_device(&gbphy_dev->dev);
+ return ERR_PTR(retval);
+ }
+
+ return gbphy_dev;
+}
+
+static void gb_gbphy_disconnect(struct gb_bundle *bundle)
+{
+ struct gbphy_host *gbphy_host = greybus_get_drvdata(bundle);
+ struct gbphy_device *gbphy_dev, *temp;
+ int ret;
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret < 0)
+ gb_pm_runtime_get_noresume(bundle);
+
+ list_for_each_entry_safe(gbphy_dev, temp, &gbphy_host->devices, list) {
+ list_del(&gbphy_dev->list);
+ device_unregister(&gbphy_dev->dev);
+ }
+
+ kfree(gbphy_host);
+}
+
+static int gb_gbphy_probe(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id)
+{
+ struct gbphy_host *gbphy_host;
+ struct gbphy_device *gbphy_dev;
+ int i;
+
+ if (bundle->num_cports == 0)
+ return -ENODEV;
+
+ gbphy_host = kzalloc(sizeof(*gbphy_host), GFP_KERNEL);
+ if (!gbphy_host)
+ return -ENOMEM;
+
+ gbphy_host->bundle = bundle;
+ INIT_LIST_HEAD(&gbphy_host->devices);
+ greybus_set_drvdata(bundle, gbphy_host);
+
+ /*
+ * Create a bunch of children devices, one per cport, and bind the
+ * bridged phy drivers to them.
+ */
+ for (i = 0; i < bundle->num_cports; ++i) {
+ gbphy_dev = gb_gbphy_create_dev(bundle, &bundle->cport_desc[i]);
+ if (IS_ERR(gbphy_dev)) {
+ gb_gbphy_disconnect(bundle);
+ return PTR_ERR(gbphy_dev);
+ }
+ list_add(&gbphy_dev->list, &gbphy_host->devices);
+ }
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return 0;
+}
+
+static const struct greybus_bundle_id gb_gbphy_id_table[] = {
+ { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_BRIDGED_PHY) },
+ { },
+};
+MODULE_DEVICE_TABLE(greybus, gb_gbphy_id_table);
+
+static struct greybus_driver gb_gbphy_driver = {
+ .name = "gbphy",
+ .probe = gb_gbphy_probe,
+ .disconnect = gb_gbphy_disconnect,
+ .id_table = gb_gbphy_id_table,
+};
+
+static int __init gbphy_init(void)
+{
+ int retval;
+
+ retval = bus_register(&gbphy_bus_type);
+ if (retval) {
+ pr_err("gbphy bus register failed (%d)\n", retval);
+ return retval;
+ }
+
+ retval = greybus_register(&gb_gbphy_driver);
+ if (retval) {
+ pr_err("error registering greybus driver\n");
+ goto error_gbphy;
+ }
+
+ return 0;
+
+error_gbphy:
+ bus_unregister(&gbphy_bus_type);
+ ida_destroy(&gbphy_id);
+ return retval;
+}
+module_init(gbphy_init);
+
+static void __exit gbphy_exit(void)
+{
+ greybus_deregister(&gb_gbphy_driver);
+ bus_unregister(&gbphy_bus_type);
+ ida_destroy(&gbphy_id);
+}
+module_exit(gbphy_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/gbphy.h b/drivers/staging/greybus/gbphy.h
new file mode 100644
index 000000000000..8ee68055ccc4
--- /dev/null
+++ b/drivers/staging/greybus/gbphy.h
@@ -0,0 +1,110 @@
+/*
+ * Greybus Bridged-Phy Bus driver
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __GBPHY_H
+#define __GBPHY_H
+
+struct gbphy_device {
+ u32 id;
+ struct greybus_descriptor_cport *cport_desc;
+ struct gb_bundle *bundle;
+ struct list_head list;
+ struct device dev;
+};
+#define to_gbphy_dev(d) container_of(d, struct gbphy_device, dev)
+
+static inline void *gb_gbphy_get_data(struct gbphy_device *gdev)
+{
+ return dev_get_drvdata(&gdev->dev);
+}
+
+static inline void gb_gbphy_set_data(struct gbphy_device *gdev, void *data)
+{
+ dev_set_drvdata(&gdev->dev, data);
+}
+
+struct gbphy_device_id {
+ __u8 protocol_id;
+};
+
+#define GBPHY_PROTOCOL(p) \
+ .protocol_id = (p),
+
+struct gbphy_driver {
+ const char *name;
+ int (*probe)(struct gbphy_device *,
+ const struct gbphy_device_id *id);
+ void (*remove)(struct gbphy_device *);
+ const struct gbphy_device_id *id_table;
+
+ struct device_driver driver;
+};
+#define to_gbphy_driver(d) container_of(d, struct gbphy_driver, driver)
+
+int gb_gbphy_register_driver(struct gbphy_driver *driver,
+ struct module *owner, const char *mod_name);
+void gb_gbphy_deregister_driver(struct gbphy_driver *driver);
+
+#define gb_gbphy_register(driver) \
+ gb_gbphy_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
+#define gb_gbphy_deregister(driver) \
+ gb_gbphy_deregister_driver(driver)
+
+/**
+ * module_gbphy_driver() - Helper macro for registering a gbphy driver
+ * @__gbphy_driver: gbphy_driver structure
+ *
+ * Helper macro for gbphy drivers to set up proper module init / exit
+ * functions. Replaces module_init() and module_exit() and keeps people from
+ * printing pointless things to the kernel log when their driver is loaded.
+ */
+#define module_gbphy_driver(__gbphy_driver) \
+ module_driver(__gbphy_driver, gb_gbphy_register, gb_gbphy_deregister)
+
+#ifdef CONFIG_PM
+static inline int gbphy_runtime_get_sync(struct gbphy_device *gbphy_dev)
+{
+ struct device *dev = &gbphy_dev->dev;
+ int ret;
+
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ dev_err(dev, "pm_runtime_get_sync failed: %d\n", ret);
+ pm_runtime_put_noidle(dev);
+ return ret;
+ }
+
+ return 0;
+}
+
+static inline void gbphy_runtime_put_autosuspend(struct gbphy_device *gbphy_dev)
+{
+ struct device *dev = &gbphy_dev->dev;
+
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
+}
+
+static inline void gbphy_runtime_get_noresume(struct gbphy_device *gbphy_dev)
+{
+ pm_runtime_get_noresume(&gbphy_dev->dev);
+}
+
+static inline void gbphy_runtime_put_noidle(struct gbphy_device *gbphy_dev)
+{
+ pm_runtime_put_noidle(&gbphy_dev->dev);
+}
+#else
+static inline int gbphy_runtime_get_sync(struct gbphy_device *gbphy_dev) { return 0; }
+static inline void gbphy_runtime_put_autosuspend(struct gbphy_device *gbphy_dev) {}
+static inline void gbphy_runtime_get_noresume(struct gbphy_device *gbphy_dev) {}
+static inline void gbphy_runtime_put_noidle(struct gbphy_device *gbphy_dev) {}
+#endif
+
+#endif /* __GBPHY_H */
+
diff --git a/drivers/staging/greybus/gpio.c b/drivers/staging/greybus/gpio.c
new file mode 100644
index 000000000000..5e06e4229e42
--- /dev/null
+++ b/drivers/staging/greybus/gpio.c
@@ -0,0 +1,766 @@
+/*
+ * GPIO Greybus driver.
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/mutex.h>
+
+#include "greybus.h"
+#include "gbphy.h"
+
+struct gb_gpio_line {
+ /* The following has to be an array of line_max entries */
+ /* --> make them just a flags field */
+ u8 active: 1,
+ direction: 1, /* 0 = output, 1 = input */
+ value: 1; /* 0 = low, 1 = high */
+ u16 debounce_usec;
+
+ u8 irq_type;
+ bool irq_type_pending;
+ bool masked;
+ bool masked_pending;
+};
+
+struct gb_gpio_controller {
+ struct gbphy_device *gbphy_dev;
+ struct gb_connection *connection;
+ u8 line_max; /* max line number */
+ struct gb_gpio_line *lines;
+
+ struct gpio_chip chip;
+ struct irq_chip irqc;
+ struct irq_chip *irqchip;
+ struct irq_domain *irqdomain;
+ unsigned int irq_base;
+ irq_flow_handler_t irq_handler;
+ unsigned int irq_default_type;
+ struct mutex irq_lock;
+};
+#define gpio_chip_to_gb_gpio_controller(chip) \
+ container_of(chip, struct gb_gpio_controller, chip)
+#define irq_data_to_gpio_chip(d) (d->domain->host_data)
+
+static int gb_gpio_line_count_operation(struct gb_gpio_controller *ggc)
+{
+ struct gb_gpio_line_count_response response;
+ int ret;
+
+ ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_LINE_COUNT,
+ NULL, 0, &response, sizeof(response));
+ if (!ret)
+ ggc->line_max = response.count;
+ return ret;
+}
+
+static int gb_gpio_activate_operation(struct gb_gpio_controller *ggc, u8 which)
+{
+ struct gb_gpio_activate_request request;
+ struct gbphy_device *gbphy_dev = ggc->gbphy_dev;
+ int ret;
+
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ return ret;
+
+ request.which = which;
+ ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_ACTIVATE,
+ &request, sizeof(request), NULL, 0);
+ if (ret) {
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+ return ret;
+ }
+
+ ggc->lines[which].active = true;
+
+ return 0;
+}
+
+static void gb_gpio_deactivate_operation(struct gb_gpio_controller *ggc,
+ u8 which)
+{
+ struct gbphy_device *gbphy_dev = ggc->gbphy_dev;
+ struct device *dev = &gbphy_dev->dev;
+ struct gb_gpio_deactivate_request request;
+ int ret;
+
+ request.which = which;
+ ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_DEACTIVATE,
+ &request, sizeof(request), NULL, 0);
+ if (ret) {
+ dev_err(dev, "failed to deactivate gpio %u\n", which);
+ goto out_pm_put;
+ }
+
+ ggc->lines[which].active = false;
+
+out_pm_put:
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+}
+
+static int gb_gpio_get_direction_operation(struct gb_gpio_controller *ggc,
+ u8 which)
+{
+ struct device *dev = &ggc->gbphy_dev->dev;
+ struct gb_gpio_get_direction_request request;
+ struct gb_gpio_get_direction_response response;
+ int ret;
+ u8 direction;
+
+ request.which = which;
+ ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_GET_DIRECTION,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret)
+ return ret;
+
+ direction = response.direction;
+ if (direction && direction != 1) {
+ dev_warn(dev, "gpio %u direction was %u (should be 0 or 1)\n",
+ which, direction);
+ }
+ ggc->lines[which].direction = direction ? 1 : 0;
+ return 0;
+}
+
+static int gb_gpio_direction_in_operation(struct gb_gpio_controller *ggc,
+ u8 which)
+{
+ struct gb_gpio_direction_in_request request;
+ int ret;
+
+ request.which = which;
+ ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_DIRECTION_IN,
+ &request, sizeof(request), NULL, 0);
+ if (!ret)
+ ggc->lines[which].direction = 1;
+ return ret;
+}
+
+static int gb_gpio_direction_out_operation(struct gb_gpio_controller *ggc,
+ u8 which, bool value_high)
+{
+ struct gb_gpio_direction_out_request request;
+ int ret;
+
+ request.which = which;
+ request.value = value_high ? 1 : 0;
+ ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_DIRECTION_OUT,
+ &request, sizeof(request), NULL, 0);
+ if (!ret)
+ ggc->lines[which].direction = 0;
+ return ret;
+}
+
+static int gb_gpio_get_value_operation(struct gb_gpio_controller *ggc,
+ u8 which)
+{
+ struct device *dev = &ggc->gbphy_dev->dev;
+ struct gb_gpio_get_value_request request;
+ struct gb_gpio_get_value_response response;
+ int ret;
+ u8 value;
+
+ request.which = which;
+ ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_GET_VALUE,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret) {
+ dev_err(dev, "failed to get value of gpio %u\n", which);
+ return ret;
+ }
+
+ value = response.value;
+ if (value && value != 1) {
+ dev_warn(dev, "gpio %u value was %u (should be 0 or 1)\n",
+ which, value);
+ }
+ ggc->lines[which].value = value ? 1 : 0;
+ return 0;
+}
+
+static void gb_gpio_set_value_operation(struct gb_gpio_controller *ggc,
+ u8 which, bool value_high)
+{
+ struct device *dev = &ggc->gbphy_dev->dev;
+ struct gb_gpio_set_value_request request;
+ int ret;
+
+ if (ggc->lines[which].direction == 1) {
+ dev_warn(dev, "refusing to set value of input gpio %u\n",
+ which);
+ return;
+ }
+
+ request.which = which;
+ request.value = value_high ? 1 : 0;
+ ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_SET_VALUE,
+ &request, sizeof(request), NULL, 0);
+ if (ret) {
+ dev_err(dev, "failed to set value of gpio %u\n", which);
+ return;
+ }
+
+ ggc->lines[which].value = request.value;
+}
+
+static int gb_gpio_set_debounce_operation(struct gb_gpio_controller *ggc,
+ u8 which, u16 debounce_usec)
+{
+ struct gb_gpio_set_debounce_request request;
+ int ret;
+
+ request.which = which;
+ request.usec = cpu_to_le16(debounce_usec);
+ ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_SET_DEBOUNCE,
+ &request, sizeof(request), NULL, 0);
+ if (!ret)
+ ggc->lines[which].debounce_usec = debounce_usec;
+ return ret;
+}
+
+static void _gb_gpio_irq_mask(struct gb_gpio_controller *ggc, u8 hwirq)
+{
+ struct device *dev = &ggc->gbphy_dev->dev;
+ struct gb_gpio_irq_mask_request request;
+ int ret;
+
+ request.which = hwirq;
+ ret = gb_operation_sync(ggc->connection,
+ GB_GPIO_TYPE_IRQ_MASK,
+ &request, sizeof(request), NULL, 0);
+ if (ret)
+ dev_err(dev, "failed to mask irq: %d\n", ret);
+}
+
+static void _gb_gpio_irq_unmask(struct gb_gpio_controller *ggc, u8 hwirq)
+{
+ struct device *dev = &ggc->gbphy_dev->dev;
+ struct gb_gpio_irq_unmask_request request;
+ int ret;
+
+ request.which = hwirq;
+ ret = gb_operation_sync(ggc->connection,
+ GB_GPIO_TYPE_IRQ_UNMASK,
+ &request, sizeof(request), NULL, 0);
+ if (ret)
+ dev_err(dev, "failed to unmask irq: %d\n", ret);
+}
+
+static void _gb_gpio_irq_set_type(struct gb_gpio_controller *ggc,
+ u8 hwirq, u8 type)
+{
+ struct device *dev = &ggc->gbphy_dev->dev;
+ struct gb_gpio_irq_type_request request;
+ int ret;
+
+ request.which = hwirq;
+ request.type = type;
+
+ ret = gb_operation_sync(ggc->connection,
+ GB_GPIO_TYPE_IRQ_TYPE,
+ &request, sizeof(request), NULL, 0);
+ if (ret)
+ dev_err(dev, "failed to set irq type: %d\n", ret);
+}
+
+static void gb_gpio_irq_mask(struct irq_data *d)
+{
+ struct gpio_chip *chip = irq_data_to_gpio_chip(d);
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+ struct gb_gpio_line *line = &ggc->lines[d->hwirq];
+
+ line->masked = true;
+ line->masked_pending = true;
+}
+
+static void gb_gpio_irq_unmask(struct irq_data *d)
+{
+ struct gpio_chip *chip = irq_data_to_gpio_chip(d);
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+ struct gb_gpio_line *line = &ggc->lines[d->hwirq];
+
+ line->masked = false;
+ line->masked_pending = true;
+}
+
+static int gb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+ struct gpio_chip *chip = irq_data_to_gpio_chip(d);
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+ struct gb_gpio_line *line = &ggc->lines[d->hwirq];
+ struct device *dev = &ggc->gbphy_dev->dev;
+ u8 irq_type;
+
+ switch (type) {
+ case IRQ_TYPE_NONE:
+ irq_type = GB_GPIO_IRQ_TYPE_NONE;
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ irq_type = GB_GPIO_IRQ_TYPE_EDGE_RISING;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ irq_type = GB_GPIO_IRQ_TYPE_EDGE_FALLING;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ irq_type = GB_GPIO_IRQ_TYPE_EDGE_BOTH;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ irq_type = GB_GPIO_IRQ_TYPE_LEVEL_LOW;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ irq_type = GB_GPIO_IRQ_TYPE_LEVEL_HIGH;
+ break;
+ default:
+ dev_err(dev, "unsupported irq type: %u\n", type);
+ return -EINVAL;
+ }
+
+ line->irq_type = irq_type;
+ line->irq_type_pending = true;
+
+ return 0;
+}
+
+static void gb_gpio_irq_bus_lock(struct irq_data *d)
+{
+ struct gpio_chip *chip = irq_data_to_gpio_chip(d);
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+
+ mutex_lock(&ggc->irq_lock);
+}
+
+static void gb_gpio_irq_bus_sync_unlock(struct irq_data *d)
+{
+ struct gpio_chip *chip = irq_data_to_gpio_chip(d);
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+ struct gb_gpio_line *line = &ggc->lines[d->hwirq];
+
+ if (line->irq_type_pending) {
+ _gb_gpio_irq_set_type(ggc, d->hwirq, line->irq_type);
+ line->irq_type_pending = false;
+ }
+
+ if (line->masked_pending) {
+ if (line->masked)
+ _gb_gpio_irq_mask(ggc, d->hwirq);
+ else
+ _gb_gpio_irq_unmask(ggc, d->hwirq);
+ line->masked_pending = false;
+ }
+
+ mutex_unlock(&ggc->irq_lock);
+}
+
+static int gb_gpio_request_handler(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct gb_gpio_controller *ggc = gb_connection_get_data(connection);
+ struct device *dev = &ggc->gbphy_dev->dev;
+ struct gb_message *request;
+ struct gb_gpio_irq_event_request *event;
+ u8 type = op->type;
+ int irq;
+ struct irq_desc *desc;
+
+ if (type != GB_GPIO_TYPE_IRQ_EVENT) {
+ dev_err(dev, "unsupported unsolicited request: %u\n", type);
+ return -EINVAL;
+ }
+
+ request = op->request;
+
+ if (request->payload_size < sizeof(*event)) {
+ dev_err(dev, "short event received (%zu < %zu)\n",
+ request->payload_size, sizeof(*event));
+ return -EINVAL;
+ }
+
+ event = request->payload;
+ if (event->which > ggc->line_max) {
+ dev_err(dev, "invalid hw irq: %d\n", event->which);
+ return -EINVAL;
+ }
+
+ irq = irq_find_mapping(ggc->irqdomain, event->which);
+ if (!irq) {
+ dev_err(dev, "failed to find IRQ\n");
+ return -EINVAL;
+ }
+ desc = irq_to_desc(irq);
+ if (!desc) {
+ dev_err(dev, "failed to look up irq\n");
+ return -EINVAL;
+ }
+
+ local_irq_disable();
+ generic_handle_irq_desc(desc);
+ local_irq_enable();
+
+ return 0;
+}
+
+static int gb_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+
+ return gb_gpio_activate_operation(ggc, (u8)offset);
+}
+
+static void gb_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+
+ gb_gpio_deactivate_operation(ggc, (u8)offset);
+}
+
+static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+ u8 which;
+ int ret;
+
+ which = (u8)offset;
+ ret = gb_gpio_get_direction_operation(ggc, which);
+ if (ret)
+ return ret;
+
+ return ggc->lines[which].direction ? 1 : 0;
+}
+
+static int gb_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+
+ return gb_gpio_direction_in_operation(ggc, (u8)offset);
+}
+
+static int gb_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+
+ return gb_gpio_direction_out_operation(ggc, (u8)offset, !!value);
+}
+
+static int gb_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+ u8 which;
+ int ret;
+
+ which = (u8)offset;
+ ret = gb_gpio_get_value_operation(ggc, which);
+ if (ret)
+ return ret;
+
+ return ggc->lines[which].value;
+}
+
+static void gb_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+
+ gb_gpio_set_value_operation(ggc, (u8)offset, !!value);
+}
+
+static int gb_gpio_set_debounce(struct gpio_chip *chip, unsigned offset,
+ unsigned debounce)
+{
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+ u16 usec;
+
+ if (debounce > U16_MAX)
+ return -EINVAL;
+ usec = (u16)debounce;
+
+ return gb_gpio_set_debounce_operation(ggc, (u8)offset, usec);
+}
+
+static int gb_gpio_controller_setup(struct gb_gpio_controller *ggc)
+{
+ int ret;
+
+ /* Now find out how many lines there are */
+ ret = gb_gpio_line_count_operation(ggc);
+ if (ret)
+ return ret;
+
+ ggc->lines = kcalloc(ggc->line_max + 1, sizeof(*ggc->lines),
+ GFP_KERNEL);
+ if (!ggc->lines)
+ return -ENOMEM;
+
+ return ret;
+}
+
+/**
+ * gb_gpio_irq_map() - maps an IRQ into a GB gpio irqchip
+ * @d: the irqdomain used by this irqchip
+ * @irq: the global irq number used by this GB gpio irqchip irq
+ * @hwirq: the local IRQ/GPIO line offset on this GB gpio
+ *
+ * This function will set up the mapping for a certain IRQ line on a
+ * GB gpio by assigning the GB gpio as chip data, and using the irqchip
+ * stored inside the GB gpio.
+ */
+static int gb_gpio_irq_map(struct irq_domain *domain, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ struct gpio_chip *chip = domain->host_data;
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+
+ irq_set_chip_data(irq, ggc);
+ irq_set_chip_and_handler(irq, ggc->irqchip, ggc->irq_handler);
+ irq_set_noprobe(irq);
+ /*
+ * No set-up of the hardware will happen if IRQ_TYPE_NONE
+ * is passed as default type.
+ */
+ if (ggc->irq_default_type != IRQ_TYPE_NONE)
+ irq_set_irq_type(irq, ggc->irq_default_type);
+
+ return 0;
+}
+
+static void gb_gpio_irq_unmap(struct irq_domain *d, unsigned int irq)
+{
+ irq_set_chip_and_handler(irq, NULL, NULL);
+ irq_set_chip_data(irq, NULL);
+}
+
+static const struct irq_domain_ops gb_gpio_domain_ops = {
+ .map = gb_gpio_irq_map,
+ .unmap = gb_gpio_irq_unmap,
+};
+
+/**
+ * gb_gpio_irqchip_remove() - removes an irqchip added to a gb_gpio_controller
+ * @ggc: the gb_gpio_controller to remove the irqchip from
+ *
+ * This is called only from gb_gpio_remove()
+ */
+static void gb_gpio_irqchip_remove(struct gb_gpio_controller *ggc)
+{
+ unsigned int offset;
+
+ /* Remove all IRQ mappings and delete the domain */
+ if (ggc->irqdomain) {
+ for (offset = 0; offset < (ggc->line_max + 1); offset++)
+ irq_dispose_mapping(irq_find_mapping(ggc->irqdomain, offset));
+ irq_domain_remove(ggc->irqdomain);
+ }
+
+ if (ggc->irqchip)
+ ggc->irqchip = NULL;
+}
+
+/**
+ * gb_gpio_irqchip_add() - adds an irqchip to a gpio chip
+ * @chip: the gpio chip to add the irqchip to
+ * @irqchip: the irqchip to add to the adapter
+ * @first_irq: if not dynamically assigned, the base (first) IRQ to
+ * allocate gpio irqs from
+ * @handler: the irq handler to use (often a predefined irq core function)
+ * @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE
+ * to have the core avoid setting up any default type in the hardware.
+ *
+ * This function closely associates a certain irqchip with a certain
+ * gpio chip, providing an irq domain to translate the local IRQs to
+ * global irqs, and making sure that the gpio chip
+ * is passed as chip data to all related functions. Driver callbacks
+ * need to use container_of() to get their local state containers back
+ * from the gpio chip passed as chip data. An irqdomain will be stored
+ * in the gpio chip that shall be used by the driver to handle IRQ number
+ * translation. The gpio chip will need to be initialized and registered
+ * before calling this function.
+ */
+static int gb_gpio_irqchip_add(struct gpio_chip *chip,
+ struct irq_chip *irqchip,
+ unsigned int first_irq,
+ irq_flow_handler_t handler,
+ unsigned int type)
+{
+ struct gb_gpio_controller *ggc;
+ unsigned int offset;
+ unsigned irq_base;
+
+ if (!chip || !irqchip)
+ return -EINVAL;
+
+ ggc = gpio_chip_to_gb_gpio_controller(chip);
+
+ ggc->irqchip = irqchip;
+ ggc->irq_handler = handler;
+ ggc->irq_default_type = type;
+ ggc->irqdomain = irq_domain_add_simple(NULL,
+ ggc->line_max + 1, first_irq,
+ &gb_gpio_domain_ops, chip);
+ if (!ggc->irqdomain) {
+ ggc->irqchip = NULL;
+ return -EINVAL;
+ }
+
+ /*
+ * Prepare the mapping since the irqchip shall be orthogonal to
+ * any gpio calls. If the first_irq was zero, this is
+ * necessary to allocate descriptors for all IRQs.
+ */
+ for (offset = 0; offset < (ggc->line_max + 1); offset++) {
+ irq_base = irq_create_mapping(ggc->irqdomain, offset);
+ if (offset == 0)
+ ggc->irq_base = irq_base;
+ }
+
+ return 0;
+}
+
+static int gb_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
+
+ return irq_find_mapping(ggc->irqdomain, offset);
+}
+
+static int gb_gpio_probe(struct gbphy_device *gbphy_dev,
+ const struct gbphy_device_id *id)
+{
+ struct gb_connection *connection;
+ struct gb_gpio_controller *ggc;
+ struct gpio_chip *gpio;
+ struct irq_chip *irqc;
+ int ret;
+
+ ggc = kzalloc(sizeof(*ggc), GFP_KERNEL);
+ if (!ggc)
+ return -ENOMEM;
+
+ connection = gb_connection_create(gbphy_dev->bundle,
+ le16_to_cpu(gbphy_dev->cport_desc->id),
+ gb_gpio_request_handler);
+ if (IS_ERR(connection)) {
+ ret = PTR_ERR(connection);
+ goto exit_ggc_free;
+ }
+
+ ggc->connection = connection;
+ gb_connection_set_data(connection, ggc);
+ ggc->gbphy_dev = gbphy_dev;
+ gb_gbphy_set_data(gbphy_dev, ggc);
+
+ ret = gb_connection_enable_tx(connection);
+ if (ret)
+ goto exit_connection_destroy;
+
+ ret = gb_gpio_controller_setup(ggc);
+ if (ret)
+ goto exit_connection_disable;
+
+ irqc = &ggc->irqc;
+ irqc->irq_mask = gb_gpio_irq_mask;
+ irqc->irq_unmask = gb_gpio_irq_unmask;
+ irqc->irq_set_type = gb_gpio_irq_set_type;
+ irqc->irq_bus_lock = gb_gpio_irq_bus_lock;
+ irqc->irq_bus_sync_unlock = gb_gpio_irq_bus_sync_unlock;
+ irqc->name = "greybus_gpio";
+
+ mutex_init(&ggc->irq_lock);
+
+ gpio = &ggc->chip;
+
+ gpio->label = "greybus_gpio";
+ gpio->parent = &gbphy_dev->dev;
+ gpio->owner = THIS_MODULE;
+
+ gpio->request = gb_gpio_request;
+ gpio->free = gb_gpio_free;
+ gpio->get_direction = gb_gpio_get_direction;
+ gpio->direction_input = gb_gpio_direction_input;
+ gpio->direction_output = gb_gpio_direction_output;
+ gpio->get = gb_gpio_get;
+ gpio->set = gb_gpio_set;
+ gpio->set_debounce = gb_gpio_set_debounce;
+ gpio->to_irq = gb_gpio_to_irq;
+ gpio->base = -1; /* Allocate base dynamically */
+ gpio->ngpio = ggc->line_max + 1;
+ gpio->can_sleep = true;
+
+ ret = gb_connection_enable(connection);
+ if (ret)
+ goto exit_line_free;
+
+ ret = gb_gpio_irqchip_add(gpio, irqc, 0,
+ handle_level_irq, IRQ_TYPE_NONE);
+ if (ret) {
+ dev_err(&connection->bundle->dev,
+ "failed to add irq chip: %d\n", ret);
+ goto exit_line_free;
+ }
+
+ ret = gpiochip_add(gpio);
+ if (ret) {
+ dev_err(&connection->bundle->dev,
+ "failed to add gpio chip: %d\n", ret);
+ goto exit_gpio_irqchip_remove;
+ }
+
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+ return 0;
+
+exit_gpio_irqchip_remove:
+ gb_gpio_irqchip_remove(ggc);
+exit_line_free:
+ kfree(ggc->lines);
+exit_connection_disable:
+ gb_connection_disable(connection);
+exit_connection_destroy:
+ gb_connection_destroy(connection);
+exit_ggc_free:
+ kfree(ggc);
+ return ret;
+}
+
+static void gb_gpio_remove(struct gbphy_device *gbphy_dev)
+{
+ struct gb_gpio_controller *ggc = gb_gbphy_get_data(gbphy_dev);
+ struct gb_connection *connection = ggc->connection;
+ int ret;
+
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ gbphy_runtime_get_noresume(gbphy_dev);
+
+ gb_connection_disable_rx(connection);
+ gpiochip_remove(&ggc->chip);
+ gb_gpio_irqchip_remove(ggc);
+ gb_connection_disable(connection);
+ gb_connection_destroy(connection);
+ kfree(ggc->lines);
+ kfree(ggc);
+}
+
+static const struct gbphy_device_id gb_gpio_id_table[] = {
+ { GBPHY_PROTOCOL(GREYBUS_PROTOCOL_GPIO) },
+ { },
+};
+MODULE_DEVICE_TABLE(gbphy, gb_gpio_id_table);
+
+static struct gbphy_driver gpio_driver = {
+ .name = "gpio",
+ .probe = gb_gpio_probe,
+ .remove = gb_gpio_remove,
+ .id_table = gb_gpio_id_table,
+};
+
+module_gbphy_driver(gpio_driver);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h
new file mode 100644
index 000000000000..12526887ae2e
--- /dev/null
+++ b/drivers/staging/greybus/greybus.h
@@ -0,0 +1,154 @@
+/*
+ * Greybus driver and device API
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __LINUX_GREYBUS_H
+#define __LINUX_GREYBUS_H
+
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/idr.h>
+
+#include "greybus_id.h"
+#include "greybus_manifest.h"
+#include "greybus_protocols.h"
+#include "manifest.h"
+#include "hd.h"
+#include "svc.h"
+#include "control.h"
+#include "module.h"
+#include "interface.h"
+#include "bundle.h"
+#include "connection.h"
+#include "operation.h"
+#include "timesync.h"
+
+/* Matches up with the Greybus Protocol specification document */
+#define GREYBUS_VERSION_MAJOR 0x00
+#define GREYBUS_VERSION_MINOR 0x01
+
+#define GREYBUS_ID_MATCH_DEVICE \
+ (GREYBUS_ID_MATCH_VENDOR | GREYBUS_ID_MATCH_PRODUCT)
+
+#define GREYBUS_DEVICE(v, p) \
+ .match_flags = GREYBUS_ID_MATCH_DEVICE, \
+ .vendor = (v), \
+ .product = (p),
+
+#define GREYBUS_DEVICE_CLASS(c) \
+ .match_flags = GREYBUS_ID_MATCH_CLASS, \
+ .class = (c),
+
+/* Maximum number of CPorts */
+#define CPORT_ID_MAX 4095 /* UniPro max id is 4095 */
+#define CPORT_ID_BAD U16_MAX
+
+struct greybus_driver {
+ const char *name;
+
+ int (*probe)(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id);
+ void (*disconnect)(struct gb_bundle *bundle);
+
+ const struct greybus_bundle_id *id_table;
+
+ struct device_driver driver;
+};
+#define to_greybus_driver(d) container_of(d, struct greybus_driver, driver)
+
+static inline void greybus_set_drvdata(struct gb_bundle *bundle, void *data)
+{
+ dev_set_drvdata(&bundle->dev, data);
+}
+
+static inline void *greybus_get_drvdata(struct gb_bundle *bundle)
+{
+ return dev_get_drvdata(&bundle->dev);
+}
+
+/* Don't call these directly, use the module_greybus_driver() macro instead */
+int greybus_register_driver(struct greybus_driver *driver,
+ struct module *module, const char *mod_name);
+void greybus_deregister_driver(struct greybus_driver *driver);
+
+/* define to get proper THIS_MODULE and KBUILD_MODNAME values */
+#define greybus_register(driver) \
+ greybus_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
+#define greybus_deregister(driver) \
+ greybus_deregister_driver(driver)
+
+/**
+ * module_greybus_driver() - Helper macro for registering a Greybus driver
+ * @__greybus_driver: greybus_driver structure
+ *
+ * Helper macro for Greybus drivers to set up proper module init / exit
+ * functions. Replaces module_init() and module_exit() and keeps people from
+ * printing pointless things to the kernel log when their driver is loaded.
+ */
+#define module_greybus_driver(__greybus_driver) \
+ module_driver(__greybus_driver, greybus_register, greybus_deregister)
+
+int greybus_disabled(void);
+
+void gb_debugfs_init(void);
+void gb_debugfs_cleanup(void);
+struct dentry *gb_debugfs_get(void);
+
+extern struct bus_type greybus_bus_type;
+
+extern struct device_type greybus_hd_type;
+extern struct device_type greybus_module_type;
+extern struct device_type greybus_interface_type;
+extern struct device_type greybus_control_type;
+extern struct device_type greybus_bundle_type;
+extern struct device_type greybus_svc_type;
+
+static inline int is_gb_host_device(const struct device *dev)
+{
+ return dev->type == &greybus_hd_type;
+}
+
+static inline int is_gb_module(const struct device *dev)
+{
+ return dev->type == &greybus_module_type;
+}
+
+static inline int is_gb_interface(const struct device *dev)
+{
+ return dev->type == &greybus_interface_type;
+}
+
+static inline int is_gb_control(const struct device *dev)
+{
+ return dev->type == &greybus_control_type;
+}
+
+static inline int is_gb_bundle(const struct device *dev)
+{
+ return dev->type == &greybus_bundle_type;
+}
+
+static inline int is_gb_svc(const struct device *dev)
+{
+ return dev->type == &greybus_svc_type;
+}
+
+static inline bool cport_id_valid(struct gb_host_device *hd, u16 cport_id)
+{
+ return cport_id != CPORT_ID_BAD && cport_id < hd->num_cports;
+}
+
+#endif /* __KERNEL__ */
+#endif /* __LINUX_GREYBUS_H */
diff --git a/drivers/staging/greybus/greybus_authentication.h b/drivers/staging/greybus/greybus_authentication.h
new file mode 100644
index 000000000000..4784ed98e8a3
--- /dev/null
+++ b/drivers/staging/greybus/greybus_authentication.h
@@ -0,0 +1,120 @@
+/*
+ * Greybus Component Authentication User Header
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2016 Google Inc. All rights reserved.
+ * Copyright(c) 2016 Linaro Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License 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 version 2 for more details.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Google Inc. All rights reserved.
+ * Copyright(c) 2016 Linaro Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. or Linaro Ltd. nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
+ * LINARO LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GREYBUS_AUTHENTICATION_USER_H
+#define __GREYBUS_AUTHENTICATION_USER_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define CAP_CERTIFICATE_MAX_SIZE 1600
+#define CAP_SIGNATURE_MAX_SIZE 320
+
+/* Certificate class types */
+#define CAP_CERT_IMS_EAPC 0x00000001
+#define CAP_CERT_IMS_EASC 0x00000002
+#define CAP_CERT_IMS_EARC 0x00000003
+#define CAP_CERT_IMS_IAPC 0x00000004
+#define CAP_CERT_IMS_IASC 0x00000005
+#define CAP_CERT_IMS_IARC 0x00000006
+
+/* IMS Certificate response result codes */
+#define CAP_IMS_RESULT_CERT_FOUND 0x00
+#define CAP_IMS_RESULT_CERT_CLASS_INVAL 0x01
+#define CAP_IMS_RESULT_CERT_CORRUPT 0x02
+#define CAP_IMS_RESULT_CERT_NOT_FOUND 0x03
+
+/* Authentication types */
+#define CAP_AUTH_IMS_PRI 0x00000001
+#define CAP_AUTH_IMS_SEC 0x00000002
+#define CAP_AUTH_IMS_RSA 0x00000003
+
+/* Authenticate response result codes */
+#define CAP_AUTH_RESULT_CR_SUCCESS 0x00
+#define CAP_AUTH_RESULT_CR_BAD_TYPE 0x01
+#define CAP_AUTH_RESULT_CR_WRONG_EP 0x02
+#define CAP_AUTH_RESULT_CR_NO_KEY 0x03
+#define CAP_AUTH_RESULT_CR_SIG_FAIL 0x04
+
+
+/* IOCTL support */
+struct cap_ioc_get_endpoint_uid {
+ __u8 uid[8];
+} __attribute__ ((__packed__));
+
+struct cap_ioc_get_ims_certificate {
+ __u32 certificate_class;
+ __u32 certificate_id;
+
+ __u8 result_code;
+ __u32 cert_size;
+ __u8 certificate[CAP_CERTIFICATE_MAX_SIZE];
+} __attribute__ ((__packed__));
+
+struct cap_ioc_authenticate {
+ __u32 auth_type;
+ __u8 uid[8];
+ __u8 challenge[32];
+
+ __u8 result_code;
+ __u8 response[64];
+ __u32 signature_size;
+ __u8 signature[CAP_SIGNATURE_MAX_SIZE];
+} __attribute__ ((__packed__));
+
+#define CAP_IOCTL_BASE 'C'
+#define CAP_IOC_GET_ENDPOINT_UID _IOR(CAP_IOCTL_BASE, 0, struct cap_ioc_get_endpoint_uid)
+#define CAP_IOC_GET_IMS_CERTIFICATE _IOWR(CAP_IOCTL_BASE, 1, struct cap_ioc_get_ims_certificate)
+#define CAP_IOC_AUTHENTICATE _IOWR(CAP_IOCTL_BASE, 2, struct cap_ioc_authenticate)
+
+#endif /* __GREYBUS_AUTHENTICATION_USER_H */
diff --git a/drivers/staging/greybus/greybus_firmware.h b/drivers/staging/greybus/greybus_firmware.h
new file mode 100644
index 000000000000..277a2acce6fd
--- /dev/null
+++ b/drivers/staging/greybus/greybus_firmware.h
@@ -0,0 +1,120 @@
+/*
+ * Greybus Firmware Management User Header
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2016 Google Inc. All rights reserved.
+ * Copyright(c) 2016 Linaro Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License 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 version 2 for more details.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Google Inc. All rights reserved.
+ * Copyright(c) 2016 Linaro Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. or Linaro Ltd. nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
+ * LINARO LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GREYBUS_FIRMWARE_USER_H
+#define __GREYBUS_FIRMWARE_USER_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define GB_FIRMWARE_U_TAG_MAX_SIZE 10
+
+#define GB_FW_U_LOAD_METHOD_UNIPRO 0x01
+#define GB_FW_U_LOAD_METHOD_INTERNAL 0x02
+
+#define GB_FW_U_LOAD_STATUS_FAILED 0x00
+#define GB_FW_U_LOAD_STATUS_UNVALIDATED 0x01
+#define GB_FW_U_LOAD_STATUS_VALIDATED 0x02
+#define GB_FW_U_LOAD_STATUS_VALIDATION_FAILED 0x03
+
+#define GB_FW_U_BACKEND_FW_STATUS_SUCCESS 0x01
+#define GB_FW_U_BACKEND_FW_STATUS_FAIL_FIND 0x02
+#define GB_FW_U_BACKEND_FW_STATUS_FAIL_FETCH 0x03
+#define GB_FW_U_BACKEND_FW_STATUS_FAIL_WRITE 0x04
+#define GB_FW_U_BACKEND_FW_STATUS_INT 0x05
+#define GB_FW_U_BACKEND_FW_STATUS_RETRY 0x06
+#define GB_FW_U_BACKEND_FW_STATUS_NOT_SUPPORTED 0x07
+
+#define GB_FW_U_BACKEND_VERSION_STATUS_SUCCESS 0x01
+#define GB_FW_U_BACKEND_VERSION_STATUS_NOT_AVAILABLE 0x02
+#define GB_FW_U_BACKEND_VERSION_STATUS_NOT_SUPPORTED 0x03
+#define GB_FW_U_BACKEND_VERSION_STATUS_RETRY 0x04
+#define GB_FW_U_BACKEND_VERSION_STATUS_FAIL_INT 0x05
+
+/* IOCTL support */
+struct fw_mgmt_ioc_get_intf_version {
+ __u8 firmware_tag[GB_FIRMWARE_U_TAG_MAX_SIZE];
+ __u16 major;
+ __u16 minor;
+} __attribute__ ((__packed__));
+
+struct fw_mgmt_ioc_get_backend_version {
+ __u8 firmware_tag[GB_FIRMWARE_U_TAG_MAX_SIZE];
+ __u16 major;
+ __u16 minor;
+ __u8 status;
+} __attribute__ ((__packed__));
+
+struct fw_mgmt_ioc_intf_load_and_validate {
+ __u8 firmware_tag[GB_FIRMWARE_U_TAG_MAX_SIZE];
+ __u8 load_method;
+ __u8 status;
+ __u16 major;
+ __u16 minor;
+} __attribute__ ((__packed__));
+
+struct fw_mgmt_ioc_backend_fw_update {
+ __u8 firmware_tag[GB_FIRMWARE_U_TAG_MAX_SIZE];
+ __u8 status;
+} __attribute__ ((__packed__));
+
+#define FW_MGMT_IOCTL_BASE 'F'
+#define FW_MGMT_IOC_GET_INTF_FW _IOR(FW_MGMT_IOCTL_BASE, 0, struct fw_mgmt_ioc_get_intf_version)
+#define FW_MGMT_IOC_GET_BACKEND_FW _IOWR(FW_MGMT_IOCTL_BASE, 1, struct fw_mgmt_ioc_get_backend_version)
+#define FW_MGMT_IOC_INTF_LOAD_AND_VALIDATE _IOWR(FW_MGMT_IOCTL_BASE, 2, struct fw_mgmt_ioc_intf_load_and_validate)
+#define FW_MGMT_IOC_INTF_BACKEND_FW_UPDATE _IOWR(FW_MGMT_IOCTL_BASE, 3, struct fw_mgmt_ioc_backend_fw_update)
+#define FW_MGMT_IOC_SET_TIMEOUT_MS _IOW(FW_MGMT_IOCTL_BASE, 4, unsigned int)
+#define FW_MGMT_IOC_MODE_SWITCH _IO(FW_MGMT_IOCTL_BASE, 5)
+
+#endif /* __GREYBUS_FIRMWARE_USER_H */
+
diff --git a/drivers/staging/greybus/greybus_id.h b/drivers/staging/greybus/greybus_id.h
new file mode 100644
index 000000000000..4bb1fc1b811d
--- /dev/null
+++ b/drivers/staging/greybus/greybus_id.h
@@ -0,0 +1,26 @@
+/* FIXME
+ * move this to include/linux/mod_devicetable.h when merging
+ */
+
+#ifndef __LINUX_GREYBUS_ID_H
+#define __LINUX_GREYBUS_ID_H
+
+#include <linux/types.h>
+#include <linux/mod_devicetable.h>
+
+
+struct greybus_bundle_id {
+ __u16 match_flags;
+ __u32 vendor;
+ __u32 product;
+ __u8 class;
+
+ kernel_ulong_t driver_info __aligned(sizeof(kernel_ulong_t));
+};
+
+/* Used to match the greybus_bundle_id */
+#define GREYBUS_ID_MATCH_VENDOR BIT(0)
+#define GREYBUS_ID_MATCH_PRODUCT BIT(1)
+#define GREYBUS_ID_MATCH_CLASS BIT(2)
+
+#endif /* __LINUX_GREYBUS_ID_H */
diff --git a/drivers/staging/greybus/greybus_manifest.h b/drivers/staging/greybus/greybus_manifest.h
new file mode 100644
index 000000000000..d135945cefe1
--- /dev/null
+++ b/drivers/staging/greybus/greybus_manifest.h
@@ -0,0 +1,177 @@
+/*
+ * Greybus manifest definition
+ *
+ * See "Greybus Application Protocol" document (version 0.1) for
+ * details on these values and structures.
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 and BSD licenses.
+ */
+
+#ifndef __GREYBUS_MANIFEST_H
+#define __GREYBUS_MANIFEST_H
+
+enum greybus_descriptor_type {
+ GREYBUS_TYPE_INVALID = 0x00,
+ GREYBUS_TYPE_INTERFACE = 0x01,
+ GREYBUS_TYPE_STRING = 0x02,
+ GREYBUS_TYPE_BUNDLE = 0x03,
+ GREYBUS_TYPE_CPORT = 0x04,
+};
+
+enum greybus_protocol {
+ GREYBUS_PROTOCOL_CONTROL = 0x00,
+ /* 0x01 is unused */
+ GREYBUS_PROTOCOL_GPIO = 0x02,
+ GREYBUS_PROTOCOL_I2C = 0x03,
+ GREYBUS_PROTOCOL_UART = 0x04,
+ GREYBUS_PROTOCOL_HID = 0x05,
+ GREYBUS_PROTOCOL_USB = 0x06,
+ GREYBUS_PROTOCOL_SDIO = 0x07,
+ GREYBUS_PROTOCOL_POWER_SUPPLY = 0x08,
+ GREYBUS_PROTOCOL_PWM = 0x09,
+ /* 0x0a is unused */
+ GREYBUS_PROTOCOL_SPI = 0x0b,
+ GREYBUS_PROTOCOL_DISPLAY = 0x0c,
+ GREYBUS_PROTOCOL_CAMERA_MGMT = 0x0d,
+ GREYBUS_PROTOCOL_SENSOR = 0x0e,
+ GREYBUS_PROTOCOL_LIGHTS = 0x0f,
+ GREYBUS_PROTOCOL_VIBRATOR = 0x10,
+ GREYBUS_PROTOCOL_LOOPBACK = 0x11,
+ GREYBUS_PROTOCOL_AUDIO_MGMT = 0x12,
+ GREYBUS_PROTOCOL_AUDIO_DATA = 0x13,
+ GREYBUS_PROTOCOL_SVC = 0x14,
+ GREYBUS_PROTOCOL_BOOTROM = 0x15,
+ GREYBUS_PROTOCOL_CAMERA_DATA = 0x16,
+ GREYBUS_PROTOCOL_FW_DOWNLOAD = 0x17,
+ GREYBUS_PROTOCOL_FW_MANAGEMENT = 0x18,
+ GREYBUS_PROTOCOL_AUTHENTICATION = 0x19,
+ GREYBUS_PROTOCOL_LOG = 0x1a,
+ /* ... */
+ GREYBUS_PROTOCOL_RAW = 0xfe,
+ GREYBUS_PROTOCOL_VENDOR = 0xff,
+};
+
+enum greybus_class_type {
+ GREYBUS_CLASS_CONTROL = 0x00,
+ /* 0x01 is unused */
+ /* 0x02 is unused */
+ /* 0x03 is unused */
+ /* 0x04 is unused */
+ GREYBUS_CLASS_HID = 0x05,
+ /* 0x06 is unused */
+ /* 0x07 is unused */
+ GREYBUS_CLASS_POWER_SUPPLY = 0x08,
+ /* 0x09 is unused */
+ GREYBUS_CLASS_BRIDGED_PHY = 0x0a,
+ /* 0x0b is unused */
+ GREYBUS_CLASS_DISPLAY = 0x0c,
+ GREYBUS_CLASS_CAMERA = 0x0d,
+ GREYBUS_CLASS_SENSOR = 0x0e,
+ GREYBUS_CLASS_LIGHTS = 0x0f,
+ GREYBUS_CLASS_VIBRATOR = 0x10,
+ GREYBUS_CLASS_LOOPBACK = 0x11,
+ GREYBUS_CLASS_AUDIO = 0x12,
+ /* 0x13 is unused */
+ /* 0x14 is unused */
+ GREYBUS_CLASS_BOOTROM = 0x15,
+ GREYBUS_CLASS_FW_MANAGEMENT = 0x16,
+ GREYBUS_CLASS_LOG = 0x17,
+ /* ... */
+ GREYBUS_CLASS_RAW = 0xfe,
+ GREYBUS_CLASS_VENDOR = 0xff,
+};
+
+enum {
+ GREYBUS_INTERFACE_FEATURE_TIMESYNC = BIT(0),
+};
+
+/*
+ * The string in a string descriptor is not NUL-terminated. The
+ * size of the descriptor will be rounded up to a multiple of 4
+ * bytes, by padding the string with 0x00 bytes if necessary.
+ */
+struct greybus_descriptor_string {
+ __u8 length;
+ __u8 id;
+ __u8 string[0];
+} __packed;
+
+/*
+ * An interface descriptor describes information about an interface as a whole,
+ * *not* the functions within it.
+ */
+struct greybus_descriptor_interface {
+ __u8 vendor_stringid;
+ __u8 product_stringid;
+ __u8 features;
+ __u8 pad;
+} __packed;
+
+/*
+ * An bundle descriptor defines an identification number and a class for
+ * each bundle.
+ *
+ * @id: Uniquely identifies a bundle within a interface, its sole purpose is to
+ * allow CPort descriptors to specify which bundle they are associated with.
+ * The first bundle will have id 0, second will have 1 and so on.
+ *
+ * The largest CPort id associated with an bundle (defined by a
+ * CPort descriptor in the manifest) is used to determine how to
+ * encode the device id and module number in UniPro packets
+ * that use the bundle.
+ *
+ * @class: It is used by kernel to know the functionality provided by the
+ * bundle and will be matched against drivers functinality while probing greybus
+ * driver. It should contain one of the values defined in
+ * 'enum greybus_class_type'.
+ *
+ */
+struct greybus_descriptor_bundle {
+ __u8 id; /* interface-relative id (0..) */
+ __u8 class;
+ __u8 pad[2];
+} __packed;
+
+/*
+ * A CPort descriptor indicates the id of the bundle within the
+ * module it's associated with, along with the CPort id used to
+ * address the CPort. The protocol id defines the format of messages
+ * exchanged using the CPort.
+ */
+struct greybus_descriptor_cport {
+ __le16 id;
+ __u8 bundle;
+ __u8 protocol_id; /* enum greybus_protocol */
+} __packed;
+
+struct greybus_descriptor_header {
+ __le16 size;
+ __u8 type; /* enum greybus_descriptor_type */
+ __u8 pad;
+} __packed;
+
+struct greybus_descriptor {
+ struct greybus_descriptor_header header;
+ union {
+ struct greybus_descriptor_string string;
+ struct greybus_descriptor_interface interface;
+ struct greybus_descriptor_bundle bundle;
+ struct greybus_descriptor_cport cport;
+ };
+} __packed;
+
+struct greybus_manifest_header {
+ __le16 size;
+ __u8 version_major;
+ __u8 version_minor;
+} __packed;
+
+struct greybus_manifest {
+ struct greybus_manifest_header header;
+ struct greybus_descriptor descriptors[0];
+} __packed;
+
+#endif /* __GREYBUS_MANIFEST_H */
diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h
new file mode 100644
index 000000000000..639578309c2a
--- /dev/null
+++ b/drivers/staging/greybus/greybus_protocols.h
@@ -0,0 +1,2268 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2014 - 2015 Google Inc. All rights reserved.
+ * Copyright(c) 2014 - 2015 Linaro Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License 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 version 2 for more details.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014 - 2015 Google Inc. All rights reserved.
+ * Copyright(c) 2014 - 2015 Linaro Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. or Linaro Ltd. nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
+ * LINARO LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GREYBUS_PROTOCOLS_H
+#define __GREYBUS_PROTOCOLS_H
+
+/* Fixed IDs for control/svc protocols */
+
+/* SVC switch-port device ids */
+#define GB_SVC_DEVICE_ID_SVC 0
+#define GB_SVC_DEVICE_ID_AP 1
+#define GB_SVC_DEVICE_ID_MIN 2
+#define GB_SVC_DEVICE_ID_MAX 31
+
+#define GB_SVC_CPORT_ID 0
+#define GB_CONTROL_BUNDLE_ID 0
+#define GB_CONTROL_CPORT_ID 0
+
+
+/*
+ * All operation messages (both requests and responses) begin with
+ * a header that encodes the size of the message (header included).
+ * This header also contains a unique identifier, that associates a
+ * response message with its operation. The header contains an
+ * operation type field, whose interpretation is dependent on what
+ * type of protocol is used over the connection. The high bit
+ * (0x80) of the operation type field is used to indicate whether
+ * the message is a request (clear) or a response (set).
+ *
+ * Response messages include an additional result byte, which
+ * communicates the result of the corresponding request. A zero
+ * result value means the operation completed successfully. Any
+ * other value indicates an error; in this case, the payload of the
+ * response message (if any) is ignored. The result byte must be
+ * zero in the header for a request message.
+ *
+ * The wire format for all numeric fields in the header is little
+ * endian. Any operation-specific data begins immediately after the
+ * header.
+ */
+struct gb_operation_msg_hdr {
+ __le16 size; /* Size in bytes of header + payload */
+ __le16 operation_id; /* Operation unique id */
+ __u8 type; /* E.g GB_I2C_TYPE_* or GB_GPIO_TYPE_* */
+ __u8 result; /* Result of request (in responses only) */
+ __u8 pad[2]; /* must be zero (ignore when read) */
+} __packed;
+
+
+/* Generic request types */
+#define GB_REQUEST_TYPE_CPORT_SHUTDOWN 0x00
+#define GB_REQUEST_TYPE_INVALID 0x7f
+
+struct gb_cport_shutdown_request {
+ __u8 phase;
+} __packed;
+
+
+/* Control Protocol */
+
+/* Greybus control request types */
+#define GB_CONTROL_TYPE_VERSION 0x01
+#define GB_CONTROL_TYPE_PROBE_AP 0x02
+#define GB_CONTROL_TYPE_GET_MANIFEST_SIZE 0x03
+#define GB_CONTROL_TYPE_GET_MANIFEST 0x04
+#define GB_CONTROL_TYPE_CONNECTED 0x05
+#define GB_CONTROL_TYPE_DISCONNECTED 0x06
+#define GB_CONTROL_TYPE_TIMESYNC_ENABLE 0x07
+#define GB_CONTROL_TYPE_TIMESYNC_DISABLE 0x08
+#define GB_CONTROL_TYPE_TIMESYNC_AUTHORITATIVE 0x09
+/* Unused 0x0a */
+#define GB_CONTROL_TYPE_BUNDLE_VERSION 0x0b
+#define GB_CONTROL_TYPE_DISCONNECTING 0x0c
+#define GB_CONTROL_TYPE_TIMESYNC_GET_LAST_EVENT 0x0d
+#define GB_CONTROL_TYPE_MODE_SWITCH 0x0e
+#define GB_CONTROL_TYPE_BUNDLE_SUSPEND 0x0f
+#define GB_CONTROL_TYPE_BUNDLE_RESUME 0x10
+#define GB_CONTROL_TYPE_BUNDLE_DEACTIVATE 0x11
+#define GB_CONTROL_TYPE_BUNDLE_ACTIVATE 0x12
+#define GB_CONTROL_TYPE_INTF_SUSPEND_PREPARE 0x13
+#define GB_CONTROL_TYPE_INTF_DEACTIVATE_PREPARE 0x14
+#define GB_CONTROL_TYPE_INTF_HIBERNATE_ABORT 0x15
+
+struct gb_control_version_request {
+ __u8 major;
+ __u8 minor;
+} __packed;
+
+struct gb_control_version_response {
+ __u8 major;
+ __u8 minor;
+} __packed;
+
+struct gb_control_bundle_version_request {
+ __u8 bundle_id;
+} __packed;
+
+struct gb_control_bundle_version_response {
+ __u8 major;
+ __u8 minor;
+} __packed;
+
+/* Control protocol manifest get size request has no payload*/
+struct gb_control_get_manifest_size_response {
+ __le16 size;
+} __packed;
+
+/* Control protocol manifest get request has no payload */
+struct gb_control_get_manifest_response {
+ __u8 data[0];
+} __packed;
+
+/* Control protocol [dis]connected request */
+struct gb_control_connected_request {
+ __le16 cport_id;
+} __packed;
+
+struct gb_control_disconnecting_request {
+ __le16 cport_id;
+} __packed;
+/* disconnecting response has no payload */
+
+struct gb_control_disconnected_request {
+ __le16 cport_id;
+} __packed;
+/* Control protocol [dis]connected response has no payload */
+
+#define GB_TIMESYNC_MAX_STROBES 0x04
+
+struct gb_control_timesync_enable_request {
+ __u8 count;
+ __le64 frame_time;
+ __le32 strobe_delay;
+ __le32 refclk;
+} __packed;
+/* timesync enable response has no payload */
+
+struct gb_control_timesync_authoritative_request {
+ __le64 frame_time[GB_TIMESYNC_MAX_STROBES];
+} __packed;
+/* timesync authoritative response has no payload */
+
+/* timesync get_last_event_request has no payload */
+struct gb_control_timesync_get_last_event_response {
+ __le64 frame_time;
+} __packed;
+
+/*
+ * All Bundle power management operations use the same request and response
+ * layout and status codes.
+ */
+
+#define GB_CONTROL_BUNDLE_PM_OK 0x00
+#define GB_CONTROL_BUNDLE_PM_INVAL 0x01
+#define GB_CONTROL_BUNDLE_PM_BUSY 0x02
+#define GB_CONTROL_BUNDLE_PM_FAIL 0x03
+#define GB_CONTROL_BUNDLE_PM_NA 0x04
+
+struct gb_control_bundle_pm_request {
+ __u8 bundle_id;
+} __packed;
+
+struct gb_control_bundle_pm_response {
+ __u8 status;
+} __packed;
+
+/*
+ * Interface Suspend Prepare and Deactivate Prepare operations use the same
+ * response layout and error codes. Define a single response structure and reuse
+ * it. Both operations have no payload.
+ */
+
+#define GB_CONTROL_INTF_PM_OK 0x00
+#define GB_CONTROL_INTF_PM_BUSY 0x01
+#define GB_CONTROL_INTF_PM_NA 0x02
+
+struct gb_control_intf_pm_response {
+ __u8 status;
+} __packed;
+
+/* APBridge protocol */
+
+/* request APB1 log */
+#define GB_APB_REQUEST_LOG 0x02
+
+/* request to map a cport to bulk in and bulk out endpoints */
+#define GB_APB_REQUEST_EP_MAPPING 0x03
+
+/* request to get the number of cports available */
+#define GB_APB_REQUEST_CPORT_COUNT 0x04
+
+/* request to reset a cport state */
+#define GB_APB_REQUEST_RESET_CPORT 0x05
+
+/* request to time the latency of messages on a given cport */
+#define GB_APB_REQUEST_LATENCY_TAG_EN 0x06
+#define GB_APB_REQUEST_LATENCY_TAG_DIS 0x07
+
+/* request to control the CSI transmitter */
+#define GB_APB_REQUEST_CSI_TX_CONTROL 0x08
+
+/* request to control audio streaming */
+#define GB_APB_REQUEST_AUDIO_CONTROL 0x09
+
+/* TimeSync requests */
+#define GB_APB_REQUEST_TIMESYNC_ENABLE 0x0d
+#define GB_APB_REQUEST_TIMESYNC_DISABLE 0x0e
+#define GB_APB_REQUEST_TIMESYNC_AUTHORITATIVE 0x0f
+#define GB_APB_REQUEST_TIMESYNC_GET_LAST_EVENT 0x10
+
+/* requests to set Greybus CPort flags */
+#define GB_APB_REQUEST_CPORT_FLAGS 0x11
+
+/* ARPC request */
+#define GB_APB_REQUEST_ARPC_RUN 0x12
+
+struct gb_apb_request_cport_flags {
+ __le32 flags;
+#define GB_APB_CPORT_FLAG_CONTROL 0x01
+#define GB_APB_CPORT_FLAG_HIGH_PRIO 0x02
+} __packed;
+
+
+/* Firmware Download Protocol */
+
+/* Request Types */
+#define GB_FW_DOWNLOAD_TYPE_FIND_FIRMWARE 0x01
+#define GB_FW_DOWNLOAD_TYPE_FETCH_FIRMWARE 0x02
+#define GB_FW_DOWNLOAD_TYPE_RELEASE_FIRMWARE 0x03
+
+#define GB_FIRMWARE_TAG_MAX_SIZE 10
+
+/* firmware download find firmware request/response */
+struct gb_fw_download_find_firmware_request {
+ __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE];
+} __packed;
+
+struct gb_fw_download_find_firmware_response {
+ __u8 firmware_id;
+ __le32 size;
+} __packed;
+
+/* firmware download fetch firmware request/response */
+struct gb_fw_download_fetch_firmware_request {
+ __u8 firmware_id;
+ __le32 offset;
+ __le32 size;
+} __packed;
+
+struct gb_fw_download_fetch_firmware_response {
+ __u8 data[0];
+} __packed;
+
+/* firmware download release firmware request */
+struct gb_fw_download_release_firmware_request {
+ __u8 firmware_id;
+} __packed;
+/* firmware download release firmware response has no payload */
+
+
+/* Firmware Management Protocol */
+
+/* Request Types */
+#define GB_FW_MGMT_TYPE_INTERFACE_FW_VERSION 0x01
+#define GB_FW_MGMT_TYPE_LOAD_AND_VALIDATE_FW 0x02
+#define GB_FW_MGMT_TYPE_LOADED_FW 0x03
+#define GB_FW_MGMT_TYPE_BACKEND_FW_VERSION 0x04
+#define GB_FW_MGMT_TYPE_BACKEND_FW_UPDATE 0x05
+#define GB_FW_MGMT_TYPE_BACKEND_FW_UPDATED 0x06
+
+#define GB_FW_LOAD_METHOD_UNIPRO 0x01
+#define GB_FW_LOAD_METHOD_INTERNAL 0x02
+
+#define GB_FW_LOAD_STATUS_FAILED 0x00
+#define GB_FW_LOAD_STATUS_UNVALIDATED 0x01
+#define GB_FW_LOAD_STATUS_VALIDATED 0x02
+#define GB_FW_LOAD_STATUS_VALIDATION_FAILED 0x03
+
+#define GB_FW_BACKEND_FW_STATUS_SUCCESS 0x01
+#define GB_FW_BACKEND_FW_STATUS_FAIL_FIND 0x02
+#define GB_FW_BACKEND_FW_STATUS_FAIL_FETCH 0x03
+#define GB_FW_BACKEND_FW_STATUS_FAIL_WRITE 0x04
+#define GB_FW_BACKEND_FW_STATUS_INT 0x05
+#define GB_FW_BACKEND_FW_STATUS_RETRY 0x06
+#define GB_FW_BACKEND_FW_STATUS_NOT_SUPPORTED 0x07
+
+#define GB_FW_BACKEND_VERSION_STATUS_SUCCESS 0x01
+#define GB_FW_BACKEND_VERSION_STATUS_NOT_AVAILABLE 0x02
+#define GB_FW_BACKEND_VERSION_STATUS_NOT_SUPPORTED 0x03
+#define GB_FW_BACKEND_VERSION_STATUS_RETRY 0x04
+#define GB_FW_BACKEND_VERSION_STATUS_FAIL_INT 0x05
+
+/* firmware management interface firmware version request has no payload */
+struct gb_fw_mgmt_interface_fw_version_response {
+ __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE];
+ __le16 major;
+ __le16 minor;
+} __packed;
+
+/* firmware management load and validate firmware request/response */
+struct gb_fw_mgmt_load_and_validate_fw_request {
+ __u8 request_id;
+ __u8 load_method;
+ __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE];
+} __packed;
+/* firmware management load and validate firmware response has no payload*/
+
+/* firmware management loaded firmware request */
+struct gb_fw_mgmt_loaded_fw_request {
+ __u8 request_id;
+ __u8 status;
+ __le16 major;
+ __le16 minor;
+} __packed;
+/* firmware management loaded firmware response has no payload */
+
+/* firmware management backend firmware version request/response */
+struct gb_fw_mgmt_backend_fw_version_request {
+ __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE];
+} __packed;
+
+struct gb_fw_mgmt_backend_fw_version_response {
+ __le16 major;
+ __le16 minor;
+ __u8 status;
+} __packed;
+
+/* firmware management backend firmware update request */
+struct gb_fw_mgmt_backend_fw_update_request {
+ __u8 request_id;
+ __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE];
+} __packed;
+/* firmware management backend firmware update response has no payload */
+
+/* firmware management backend firmware updated request */
+struct gb_fw_mgmt_backend_fw_updated_request {
+ __u8 request_id;
+ __u8 status;
+} __packed;
+/* firmware management backend firmware updated response has no payload */
+
+
+/* Component Authentication Protocol (CAP) */
+
+/* Request Types */
+#define GB_CAP_TYPE_GET_ENDPOINT_UID 0x01
+#define GB_CAP_TYPE_GET_IMS_CERTIFICATE 0x02
+#define GB_CAP_TYPE_AUTHENTICATE 0x03
+
+/* CAP get endpoint uid request has no payload */
+struct gb_cap_get_endpoint_uid_response {
+ __u8 uid[8];
+} __packed;
+
+/* CAP get endpoint ims certificate request/response */
+struct gb_cap_get_ims_certificate_request {
+ __le32 certificate_class;
+ __le32 certificate_id;
+} __packed;
+
+struct gb_cap_get_ims_certificate_response {
+ __u8 result_code;
+ __u8 certificate[0];
+} __packed;
+
+/* CAP authenticate request/response */
+struct gb_cap_authenticate_request {
+ __le32 auth_type;
+ __u8 uid[8];
+ __u8 challenge[32];
+} __packed;
+
+struct gb_cap_authenticate_response {
+ __u8 result_code;
+ __u8 response[64];
+ __u8 signature[0];
+} __packed;
+
+
+/* Bootrom Protocol */
+
+/* Version of the Greybus bootrom protocol we support */
+#define GB_BOOTROM_VERSION_MAJOR 0x00
+#define GB_BOOTROM_VERSION_MINOR 0x01
+
+/* Greybus bootrom request types */
+#define GB_BOOTROM_TYPE_VERSION 0x01
+#define GB_BOOTROM_TYPE_FIRMWARE_SIZE 0x02
+#define GB_BOOTROM_TYPE_GET_FIRMWARE 0x03
+#define GB_BOOTROM_TYPE_READY_TO_BOOT 0x04
+#define GB_BOOTROM_TYPE_AP_READY 0x05 /* Request with no-payload */
+#define GB_BOOTROM_TYPE_GET_VID_PID 0x06 /* Request with no-payload */
+
+/* Greybus bootrom boot stages */
+#define GB_BOOTROM_BOOT_STAGE_ONE 0x01 /* Reserved for the boot ROM */
+#define GB_BOOTROM_BOOT_STAGE_TWO 0x02 /* Bootrom package to be loaded by the boot ROM */
+#define GB_BOOTROM_BOOT_STAGE_THREE 0x03 /* Module personality package loaded by Stage 2 firmware */
+
+/* Greybus bootrom ready to boot status */
+#define GB_BOOTROM_BOOT_STATUS_INVALID 0x00 /* Firmware blob could not be validated */
+#define GB_BOOTROM_BOOT_STATUS_INSECURE 0x01 /* Firmware blob is valid but insecure */
+#define GB_BOOTROM_BOOT_STATUS_SECURE 0x02 /* Firmware blob is valid and secure */
+
+/* Max bootrom data fetch size in bytes */
+#define GB_BOOTROM_FETCH_MAX 2000
+
+struct gb_bootrom_version_request {
+ __u8 major;
+ __u8 minor;
+} __packed;
+
+struct gb_bootrom_version_response {
+ __u8 major;
+ __u8 minor;
+} __packed;
+
+/* Bootrom protocol firmware size request/response */
+struct gb_bootrom_firmware_size_request {
+ __u8 stage;
+} __packed;
+
+struct gb_bootrom_firmware_size_response {
+ __le32 size;
+} __packed;
+
+/* Bootrom protocol get firmware request/response */
+struct gb_bootrom_get_firmware_request {
+ __le32 offset;
+ __le32 size;
+} __packed;
+
+struct gb_bootrom_get_firmware_response {
+ __u8 data[0];
+} __packed;
+
+/* Bootrom protocol Ready to boot request */
+struct gb_bootrom_ready_to_boot_request {
+ __u8 status;
+} __packed;
+/* Bootrom protocol Ready to boot response has no payload */
+
+/* Bootrom protocol get VID/PID request has no payload */
+struct gb_bootrom_get_vid_pid_response {
+ __le32 vendor_id;
+ __le32 product_id;
+} __packed;
+
+
+/* Power Supply */
+
+/* Greybus power supply request types */
+#define GB_POWER_SUPPLY_TYPE_GET_SUPPLIES 0x02
+#define GB_POWER_SUPPLY_TYPE_GET_DESCRIPTION 0x03
+#define GB_POWER_SUPPLY_TYPE_GET_PROP_DESCRIPTORS 0x04
+#define GB_POWER_SUPPLY_TYPE_GET_PROPERTY 0x05
+#define GB_POWER_SUPPLY_TYPE_SET_PROPERTY 0x06
+#define GB_POWER_SUPPLY_TYPE_EVENT 0x07
+
+/* Greybus power supply battery technologies types */
+#define GB_POWER_SUPPLY_TECH_UNKNOWN 0x0000
+#define GB_POWER_SUPPLY_TECH_NiMH 0x0001
+#define GB_POWER_SUPPLY_TECH_LION 0x0002
+#define GB_POWER_SUPPLY_TECH_LIPO 0x0003
+#define GB_POWER_SUPPLY_TECH_LiFe 0x0004
+#define GB_POWER_SUPPLY_TECH_NiCd 0x0005
+#define GB_POWER_SUPPLY_TECH_LiMn 0x0006
+
+/* Greybus power supply types */
+#define GB_POWER_SUPPLY_UNKNOWN_TYPE 0x0000
+#define GB_POWER_SUPPLY_BATTERY_TYPE 0x0001
+#define GB_POWER_SUPPLY_UPS_TYPE 0x0002
+#define GB_POWER_SUPPLY_MAINS_TYPE 0x0003
+#define GB_POWER_SUPPLY_USB_TYPE 0x0004
+#define GB_POWER_SUPPLY_USB_DCP_TYPE 0x0005
+#define GB_POWER_SUPPLY_USB_CDP_TYPE 0x0006
+#define GB_POWER_SUPPLY_USB_ACA_TYPE 0x0007
+
+/* Greybus power supply health values */
+#define GB_POWER_SUPPLY_HEALTH_UNKNOWN 0x0000
+#define GB_POWER_SUPPLY_HEALTH_GOOD 0x0001
+#define GB_POWER_SUPPLY_HEALTH_OVERHEAT 0x0002
+#define GB_POWER_SUPPLY_HEALTH_DEAD 0x0003
+#define GB_POWER_SUPPLY_HEALTH_OVERVOLTAGE 0x0004
+#define GB_POWER_SUPPLY_HEALTH_UNSPEC_FAILURE 0x0005
+#define GB_POWER_SUPPLY_HEALTH_COLD 0x0006
+#define GB_POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE 0x0007
+#define GB_POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE 0x0008
+
+/* Greybus power supply status values */
+#define GB_POWER_SUPPLY_STATUS_UNKNOWN 0x0000
+#define GB_POWER_SUPPLY_STATUS_CHARGING 0x0001
+#define GB_POWER_SUPPLY_STATUS_DISCHARGING 0x0002
+#define GB_POWER_SUPPLY_STATUS_NOT_CHARGING 0x0003
+#define GB_POWER_SUPPLY_STATUS_FULL 0x0004
+
+/* Greybus power supply capacity level values */
+#define GB_POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN 0x0000
+#define GB_POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL 0x0001
+#define GB_POWER_SUPPLY_CAPACITY_LEVEL_LOW 0x0002
+#define GB_POWER_SUPPLY_CAPACITY_LEVEL_NORMAL 0x0003
+#define GB_POWER_SUPPLY_CAPACITY_LEVEL_HIGH 0x0004
+#define GB_POWER_SUPPLY_CAPACITY_LEVEL_FULL 0x0005
+
+/* Greybus power supply scope values */
+#define GB_POWER_SUPPLY_SCOPE_UNKNOWN 0x0000
+#define GB_POWER_SUPPLY_SCOPE_SYSTEM 0x0001
+#define GB_POWER_SUPPLY_SCOPE_DEVICE 0x0002
+
+struct gb_power_supply_get_supplies_response {
+ __u8 supplies_count;
+} __packed;
+
+struct gb_power_supply_get_description_request {
+ __u8 psy_id;
+} __packed;
+
+struct gb_power_supply_get_description_response {
+ __u8 manufacturer[32];
+ __u8 model[32];
+ __u8 serial_number[32];
+ __le16 type;
+ __u8 properties_count;
+} __packed;
+
+struct gb_power_supply_props_desc {
+ __u8 property;
+#define GB_POWER_SUPPLY_PROP_STATUS 0x00
+#define GB_POWER_SUPPLY_PROP_CHARGE_TYPE 0x01
+#define GB_POWER_SUPPLY_PROP_HEALTH 0x02
+#define GB_POWER_SUPPLY_PROP_PRESENT 0x03
+#define GB_POWER_SUPPLY_PROP_ONLINE 0x04
+#define GB_POWER_SUPPLY_PROP_AUTHENTIC 0x05
+#define GB_POWER_SUPPLY_PROP_TECHNOLOGY 0x06
+#define GB_POWER_SUPPLY_PROP_CYCLE_COUNT 0x07
+#define GB_POWER_SUPPLY_PROP_VOLTAGE_MAX 0x08
+#define GB_POWER_SUPPLY_PROP_VOLTAGE_MIN 0x09
+#define GB_POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN 0x0A
+#define GB_POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN 0x0B
+#define GB_POWER_SUPPLY_PROP_VOLTAGE_NOW 0x0C
+#define GB_POWER_SUPPLY_PROP_VOLTAGE_AVG 0x0D
+#define GB_POWER_SUPPLY_PROP_VOLTAGE_OCV 0x0E
+#define GB_POWER_SUPPLY_PROP_VOLTAGE_BOOT 0x0F
+#define GB_POWER_SUPPLY_PROP_CURRENT_MAX 0x10
+#define GB_POWER_SUPPLY_PROP_CURRENT_NOW 0x11
+#define GB_POWER_SUPPLY_PROP_CURRENT_AVG 0x12
+#define GB_POWER_SUPPLY_PROP_CURRENT_BOOT 0x13
+#define GB_POWER_SUPPLY_PROP_POWER_NOW 0x14
+#define GB_POWER_SUPPLY_PROP_POWER_AVG 0x15
+#define GB_POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN 0x16
+#define GB_POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN 0x17
+#define GB_POWER_SUPPLY_PROP_CHARGE_FULL 0x18
+#define GB_POWER_SUPPLY_PROP_CHARGE_EMPTY 0x19
+#define GB_POWER_SUPPLY_PROP_CHARGE_NOW 0x1A
+#define GB_POWER_SUPPLY_PROP_CHARGE_AVG 0x1B
+#define GB_POWER_SUPPLY_PROP_CHARGE_COUNTER 0x1C
+#define GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT 0x1D
+#define GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX 0x1E
+#define GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE 0x1F
+#define GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX 0x20
+#define GB_POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT 0x21
+#define GB_POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX 0x22
+#define GB_POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT 0x23
+#define GB_POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN 0x24
+#define GB_POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN 0x25
+#define GB_POWER_SUPPLY_PROP_ENERGY_FULL 0x26
+#define GB_POWER_SUPPLY_PROP_ENERGY_EMPTY 0x27
+#define GB_POWER_SUPPLY_PROP_ENERGY_NOW 0x28
+#define GB_POWER_SUPPLY_PROP_ENERGY_AVG 0x29
+#define GB_POWER_SUPPLY_PROP_CAPACITY 0x2A
+#define GB_POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN 0x2B
+#define GB_POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX 0x2C
+#define GB_POWER_SUPPLY_PROP_CAPACITY_LEVEL 0x2D
+#define GB_POWER_SUPPLY_PROP_TEMP 0x2E
+#define GB_POWER_SUPPLY_PROP_TEMP_MAX 0x2F
+#define GB_POWER_SUPPLY_PROP_TEMP_MIN 0x30
+#define GB_POWER_SUPPLY_PROP_TEMP_ALERT_MIN 0x31
+#define GB_POWER_SUPPLY_PROP_TEMP_ALERT_MAX 0x32
+#define GB_POWER_SUPPLY_PROP_TEMP_AMBIENT 0x33
+#define GB_POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN 0x34
+#define GB_POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX 0x35
+#define GB_POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW 0x36
+#define GB_POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG 0x37
+#define GB_POWER_SUPPLY_PROP_TIME_TO_FULL_NOW 0x38
+#define GB_POWER_SUPPLY_PROP_TIME_TO_FULL_AVG 0x39
+#define GB_POWER_SUPPLY_PROP_TYPE 0x3A
+#define GB_POWER_SUPPLY_PROP_SCOPE 0x3B
+#define GB_POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT 0x3C
+#define GB_POWER_SUPPLY_PROP_CALIBRATE 0x3D
+ __u8 is_writeable;
+} __packed;
+
+struct gb_power_supply_get_property_descriptors_request {
+ __u8 psy_id;
+} __packed;
+
+struct gb_power_supply_get_property_descriptors_response {
+ __u8 properties_count;
+ struct gb_power_supply_props_desc props[];
+} __packed;
+
+struct gb_power_supply_get_property_request {
+ __u8 psy_id;
+ __u8 property;
+} __packed;
+
+struct gb_power_supply_get_property_response {
+ __le32 prop_val;
+};
+
+struct gb_power_supply_set_property_request {
+ __u8 psy_id;
+ __u8 property;
+ __le32 prop_val;
+} __packed;
+
+struct gb_power_supply_event_request {
+ __u8 psy_id;
+ __u8 event;
+#define GB_POWER_SUPPLY_UPDATE 0x01
+} __packed;
+
+
+/* HID */
+
+/* Greybus HID operation types */
+#define GB_HID_TYPE_GET_DESC 0x02
+#define GB_HID_TYPE_GET_REPORT_DESC 0x03
+#define GB_HID_TYPE_PWR_ON 0x04
+#define GB_HID_TYPE_PWR_OFF 0x05
+#define GB_HID_TYPE_GET_REPORT 0x06
+#define GB_HID_TYPE_SET_REPORT 0x07
+#define GB_HID_TYPE_IRQ_EVENT 0x08
+
+/* Report type */
+#define GB_HID_INPUT_REPORT 0
+#define GB_HID_OUTPUT_REPORT 1
+#define GB_HID_FEATURE_REPORT 2
+
+/* Different request/response structures */
+/* HID get descriptor response */
+struct gb_hid_desc_response {
+ __u8 bLength;
+ __le16 wReportDescLength;
+ __le16 bcdHID;
+ __le16 wProductID;
+ __le16 wVendorID;
+ __u8 bCountryCode;
+} __packed;
+
+/* HID get report request/response */
+struct gb_hid_get_report_request {
+ __u8 report_type;
+ __u8 report_id;
+} __packed;
+
+/* HID set report request */
+struct gb_hid_set_report_request {
+ __u8 report_type;
+ __u8 report_id;
+ __u8 report[0];
+} __packed;
+
+/* HID input report request, via interrupt pipe */
+struct gb_hid_input_report_request {
+ __u8 report[0];
+} __packed;
+
+
+/* I2C */
+
+/* Greybus i2c request types */
+#define GB_I2C_TYPE_FUNCTIONALITY 0x02
+#define GB_I2C_TYPE_TRANSFER 0x05
+
+/* functionality request has no payload */
+struct gb_i2c_functionality_response {
+ __le32 functionality;
+} __packed;
+
+/*
+ * Outgoing data immediately follows the op count and ops array.
+ * The data for each write (master -> slave) op in the array is sent
+ * in order, with no (e.g. pad) bytes separating them.
+ *
+ * Short reads cause the entire transfer request to fail So response
+ * payload consists only of bytes read, and the number of bytes is
+ * exactly what was specified in the corresponding op. Like
+ * outgoing data, the incoming data is in order and contiguous.
+ */
+struct gb_i2c_transfer_op {
+ __le16 addr;
+ __le16 flags;
+ __le16 size;
+} __packed;
+
+struct gb_i2c_transfer_request {
+ __le16 op_count;
+ struct gb_i2c_transfer_op ops[0]; /* op_count of these */
+} __packed;
+struct gb_i2c_transfer_response {
+ __u8 data[0]; /* inbound data */
+} __packed;
+
+
+/* GPIO */
+
+/* Greybus GPIO request types */
+#define GB_GPIO_TYPE_LINE_COUNT 0x02
+#define GB_GPIO_TYPE_ACTIVATE 0x03
+#define GB_GPIO_TYPE_DEACTIVATE 0x04
+#define GB_GPIO_TYPE_GET_DIRECTION 0x05
+#define GB_GPIO_TYPE_DIRECTION_IN 0x06
+#define GB_GPIO_TYPE_DIRECTION_OUT 0x07
+#define GB_GPIO_TYPE_GET_VALUE 0x08
+#define GB_GPIO_TYPE_SET_VALUE 0x09
+#define GB_GPIO_TYPE_SET_DEBOUNCE 0x0a
+#define GB_GPIO_TYPE_IRQ_TYPE 0x0b
+#define GB_GPIO_TYPE_IRQ_MASK 0x0c
+#define GB_GPIO_TYPE_IRQ_UNMASK 0x0d
+#define GB_GPIO_TYPE_IRQ_EVENT 0x0e
+
+#define GB_GPIO_IRQ_TYPE_NONE 0x00
+#define GB_GPIO_IRQ_TYPE_EDGE_RISING 0x01
+#define GB_GPIO_IRQ_TYPE_EDGE_FALLING 0x02
+#define GB_GPIO_IRQ_TYPE_EDGE_BOTH 0x03
+#define GB_GPIO_IRQ_TYPE_LEVEL_HIGH 0x04
+#define GB_GPIO_IRQ_TYPE_LEVEL_LOW 0x08
+
+/* line count request has no payload */
+struct gb_gpio_line_count_response {
+ __u8 count;
+} __packed;
+
+struct gb_gpio_activate_request {
+ __u8 which;
+} __packed;
+/* activate response has no payload */
+
+struct gb_gpio_deactivate_request {
+ __u8 which;
+} __packed;
+/* deactivate response has no payload */
+
+struct gb_gpio_get_direction_request {
+ __u8 which;
+} __packed;
+struct gb_gpio_get_direction_response {
+ __u8 direction;
+} __packed;
+
+struct gb_gpio_direction_in_request {
+ __u8 which;
+} __packed;
+/* direction in response has no payload */
+
+struct gb_gpio_direction_out_request {
+ __u8 which;
+ __u8 value;
+} __packed;
+/* direction out response has no payload */
+
+struct gb_gpio_get_value_request {
+ __u8 which;
+} __packed;
+struct gb_gpio_get_value_response {
+ __u8 value;
+} __packed;
+
+struct gb_gpio_set_value_request {
+ __u8 which;
+ __u8 value;
+} __packed;
+/* set value response has no payload */
+
+struct gb_gpio_set_debounce_request {
+ __u8 which;
+ __le16 usec;
+} __packed;
+/* debounce response has no payload */
+
+struct gb_gpio_irq_type_request {
+ __u8 which;
+ __u8 type;
+} __packed;
+/* irq type response has no payload */
+
+struct gb_gpio_irq_mask_request {
+ __u8 which;
+} __packed;
+/* irq mask response has no payload */
+
+struct gb_gpio_irq_unmask_request {
+ __u8 which;
+} __packed;
+/* irq unmask response has no payload */
+
+/* irq event requests originate on another module and are handled on the AP */
+struct gb_gpio_irq_event_request {
+ __u8 which;
+} __packed;
+/* irq event has no response */
+
+
+/* PWM */
+
+/* Greybus PWM operation types */
+#define GB_PWM_TYPE_PWM_COUNT 0x02
+#define GB_PWM_TYPE_ACTIVATE 0x03
+#define GB_PWM_TYPE_DEACTIVATE 0x04
+#define GB_PWM_TYPE_CONFIG 0x05
+#define GB_PWM_TYPE_POLARITY 0x06
+#define GB_PWM_TYPE_ENABLE 0x07
+#define GB_PWM_TYPE_DISABLE 0x08
+
+/* pwm count request has no payload */
+struct gb_pwm_count_response {
+ __u8 count;
+} __packed;
+
+struct gb_pwm_activate_request {
+ __u8 which;
+} __packed;
+
+struct gb_pwm_deactivate_request {
+ __u8 which;
+} __packed;
+
+struct gb_pwm_config_request {
+ __u8 which;
+ __le32 duty;
+ __le32 period;
+} __packed;
+
+struct gb_pwm_polarity_request {
+ __u8 which;
+ __u8 polarity;
+} __packed;
+
+struct gb_pwm_enable_request {
+ __u8 which;
+} __packed;
+
+struct gb_pwm_disable_request {
+ __u8 which;
+} __packed;
+
+/* SPI */
+
+/* Should match up with modes in linux/spi/spi.h */
+#define GB_SPI_MODE_CPHA 0x01 /* clock phase */
+#define GB_SPI_MODE_CPOL 0x02 /* clock polarity */
+#define GB_SPI_MODE_MODE_0 (0|0) /* (original MicroWire) */
+#define GB_SPI_MODE_MODE_1 (0|GB_SPI_MODE_CPHA)
+#define GB_SPI_MODE_MODE_2 (GB_SPI_MODE_CPOL|0)
+#define GB_SPI_MODE_MODE_3 (GB_SPI_MODE_CPOL|GB_SPI_MODE_CPHA)
+#define GB_SPI_MODE_CS_HIGH 0x04 /* chipselect active high? */
+#define GB_SPI_MODE_LSB_FIRST 0x08 /* per-word bits-on-wire */
+#define GB_SPI_MODE_3WIRE 0x10 /* SI/SO signals shared */
+#define GB_SPI_MODE_LOOP 0x20 /* loopback mode */
+#define GB_SPI_MODE_NO_CS 0x40 /* 1 dev/bus, no chipselect */
+#define GB_SPI_MODE_READY 0x80 /* slave pulls low to pause */
+
+/* Should match up with flags in linux/spi/spi.h */
+#define GB_SPI_FLAG_HALF_DUPLEX BIT(0) /* can't do full duplex */
+#define GB_SPI_FLAG_NO_RX BIT(1) /* can't do buffer read */
+#define GB_SPI_FLAG_NO_TX BIT(2) /* can't do buffer write */
+
+/* Greybus spi operation types */
+#define GB_SPI_TYPE_MASTER_CONFIG 0x02
+#define GB_SPI_TYPE_DEVICE_CONFIG 0x03
+#define GB_SPI_TYPE_TRANSFER 0x04
+
+/* mode request has no payload */
+struct gb_spi_master_config_response {
+ __le32 bits_per_word_mask;
+ __le32 min_speed_hz;
+ __le32 max_speed_hz;
+ __le16 mode;
+ __le16 flags;
+ __u8 num_chipselect;
+} __packed;
+
+struct gb_spi_device_config_request {
+ __u8 chip_select;
+} __packed;
+
+struct gb_spi_device_config_response {
+ __le16 mode;
+ __u8 bits_per_word;
+ __le32 max_speed_hz;
+ __u8 device_type;
+#define GB_SPI_SPI_DEV 0x00
+#define GB_SPI_SPI_NOR 0x01
+#define GB_SPI_SPI_MODALIAS 0x02
+ __u8 name[32];
+} __packed;
+
+/**
+ * struct gb_spi_transfer - a read/write buffer pair
+ * @speed_hz: Select a speed other than the device default for this transfer. If
+ * 0 the default (from @spi_device) is used.
+ * @len: size of rx and tx buffers (in bytes)
+ * @delay_usecs: microseconds to delay after this transfer before (optionally)
+ * changing the chipselect status, then starting the next transfer or
+ * completing this spi_message.
+ * @cs_change: affects chipselect after this transfer completes
+ * @bits_per_word: select a bits_per_word other than the device default for this
+ * transfer. If 0 the default (from @spi_device) is used.
+ */
+struct gb_spi_transfer {
+ __le32 speed_hz;
+ __le32 len;
+ __le16 delay_usecs;
+ __u8 cs_change;
+ __u8 bits_per_word;
+ __u8 xfer_flags;
+#define GB_SPI_XFER_READ 0x01
+#define GB_SPI_XFER_WRITE 0x02
+#define GB_SPI_XFER_INPROGRESS 0x04
+} __packed;
+
+struct gb_spi_transfer_request {
+ __u8 chip_select; /* of the spi device */
+ __u8 mode; /* of the spi device */
+ __le16 count;
+ struct gb_spi_transfer transfers[0]; /* count of these */
+} __packed;
+
+struct gb_spi_transfer_response {
+ __u8 data[0]; /* inbound data */
+} __packed;
+
+/* Version of the Greybus SVC protocol we support */
+#define GB_SVC_VERSION_MAJOR 0x00
+#define GB_SVC_VERSION_MINOR 0x01
+
+/* Greybus SVC request types */
+#define GB_SVC_TYPE_PROTOCOL_VERSION 0x01
+#define GB_SVC_TYPE_SVC_HELLO 0x02
+#define GB_SVC_TYPE_INTF_DEVICE_ID 0x03
+#define GB_SVC_TYPE_INTF_RESET 0x06
+#define GB_SVC_TYPE_CONN_CREATE 0x07
+#define GB_SVC_TYPE_CONN_DESTROY 0x08
+#define GB_SVC_TYPE_DME_PEER_GET 0x09
+#define GB_SVC_TYPE_DME_PEER_SET 0x0a
+#define GB_SVC_TYPE_ROUTE_CREATE 0x0b
+#define GB_SVC_TYPE_ROUTE_DESTROY 0x0c
+#define GB_SVC_TYPE_TIMESYNC_ENABLE 0x0d
+#define GB_SVC_TYPE_TIMESYNC_DISABLE 0x0e
+#define GB_SVC_TYPE_TIMESYNC_AUTHORITATIVE 0x0f
+#define GB_SVC_TYPE_INTF_SET_PWRM 0x10
+#define GB_SVC_TYPE_INTF_EJECT 0x11
+#define GB_SVC_TYPE_PING 0x13
+#define GB_SVC_TYPE_PWRMON_RAIL_COUNT_GET 0x14
+#define GB_SVC_TYPE_PWRMON_RAIL_NAMES_GET 0x15
+#define GB_SVC_TYPE_PWRMON_SAMPLE_GET 0x16
+#define GB_SVC_TYPE_PWRMON_INTF_SAMPLE_GET 0x17
+#define GB_SVC_TYPE_TIMESYNC_WAKE_PINS_ACQUIRE 0x18
+#define GB_SVC_TYPE_TIMESYNC_WAKE_PINS_RELEASE 0x19
+#define GB_SVC_TYPE_TIMESYNC_PING 0x1a
+#define GB_SVC_TYPE_MODULE_INSERTED 0x1f
+#define GB_SVC_TYPE_MODULE_REMOVED 0x20
+#define GB_SVC_TYPE_INTF_VSYS_ENABLE 0x21
+#define GB_SVC_TYPE_INTF_VSYS_DISABLE 0x22
+#define GB_SVC_TYPE_INTF_REFCLK_ENABLE 0x23
+#define GB_SVC_TYPE_INTF_REFCLK_DISABLE 0x24
+#define GB_SVC_TYPE_INTF_UNIPRO_ENABLE 0x25
+#define GB_SVC_TYPE_INTF_UNIPRO_DISABLE 0x26
+#define GB_SVC_TYPE_INTF_ACTIVATE 0x27
+#define GB_SVC_TYPE_INTF_RESUME 0x28
+#define GB_SVC_TYPE_INTF_MAILBOX_EVENT 0x29
+#define GB_SVC_TYPE_INTF_OOPS 0x2a
+
+/* Greybus SVC protocol status values */
+#define GB_SVC_OP_SUCCESS 0x00
+#define GB_SVC_OP_UNKNOWN_ERROR 0x01
+#define GB_SVC_INTF_NOT_DETECTED 0x02
+#define GB_SVC_INTF_NO_UPRO_LINK 0x03
+#define GB_SVC_INTF_UPRO_NOT_DOWN 0x04
+#define GB_SVC_INTF_UPRO_NOT_HIBERNATED 0x05
+#define GB_SVC_INTF_NO_V_SYS 0x06
+#define GB_SVC_INTF_V_CHG 0x07
+#define GB_SVC_INTF_WAKE_BUSY 0x08
+#define GB_SVC_INTF_NO_REFCLK 0x09
+#define GB_SVC_INTF_RELEASING 0x0a
+#define GB_SVC_INTF_NO_ORDER 0x0b
+#define GB_SVC_INTF_MBOX_SET 0x0c
+#define GB_SVC_INTF_BAD_MBOX 0x0d
+#define GB_SVC_INTF_OP_TIMEOUT 0x0e
+#define GB_SVC_PWRMON_OP_NOT_PRESENT 0x0f
+
+struct gb_svc_version_request {
+ __u8 major;
+ __u8 minor;
+} __packed;
+
+struct gb_svc_version_response {
+ __u8 major;
+ __u8 minor;
+} __packed;
+
+/* SVC protocol hello request */
+struct gb_svc_hello_request {
+ __le16 endo_id;
+ __u8 interface_id;
+} __packed;
+/* hello response has no payload */
+
+struct gb_svc_intf_device_id_request {
+ __u8 intf_id;
+ __u8 device_id;
+} __packed;
+/* device id response has no payload */
+
+struct gb_svc_intf_reset_request {
+ __u8 intf_id;
+} __packed;
+/* interface reset response has no payload */
+
+struct gb_svc_intf_eject_request {
+ __u8 intf_id;
+} __packed;
+/* interface eject response has no payload */
+
+struct gb_svc_conn_create_request {
+ __u8 intf1_id;
+ __le16 cport1_id;
+ __u8 intf2_id;
+ __le16 cport2_id;
+ __u8 tc;
+ __u8 flags;
+} __packed;
+/* connection create response has no payload */
+
+struct gb_svc_conn_destroy_request {
+ __u8 intf1_id;
+ __le16 cport1_id;
+ __u8 intf2_id;
+ __le16 cport2_id;
+} __packed;
+/* connection destroy response has no payload */
+
+struct gb_svc_dme_peer_get_request {
+ __u8 intf_id;
+ __le16 attr;
+ __le16 selector;
+} __packed;
+
+struct gb_svc_dme_peer_get_response {
+ __le16 result_code;
+ __le32 attr_value;
+} __packed;
+
+struct gb_svc_dme_peer_set_request {
+ __u8 intf_id;
+ __le16 attr;
+ __le16 selector;
+ __le32 value;
+} __packed;
+
+struct gb_svc_dme_peer_set_response {
+ __le16 result_code;
+} __packed;
+
+/* Greybus init-status values, currently retrieved using DME peer gets. */
+#define GB_INIT_SPI_BOOT_STARTED 0x02
+#define GB_INIT_TRUSTED_SPI_BOOT_FINISHED 0x03
+#define GB_INIT_UNTRUSTED_SPI_BOOT_FINISHED 0x04
+#define GB_INIT_BOOTROM_UNIPRO_BOOT_STARTED 0x06
+#define GB_INIT_BOOTROM_FALLBACK_UNIPRO_BOOT_STARTED 0x09
+#define GB_INIT_S2_LOADER_BOOT_STARTED 0x0D
+
+struct gb_svc_route_create_request {
+ __u8 intf1_id;
+ __u8 dev1_id;
+ __u8 intf2_id;
+ __u8 dev2_id;
+} __packed;
+/* route create response has no payload */
+
+struct gb_svc_route_destroy_request {
+ __u8 intf1_id;
+ __u8 intf2_id;
+} __packed;
+/* route destroy response has no payload */
+
+/* used for svc_intf_vsys_{enable,disable} */
+struct gb_svc_intf_vsys_request {
+ __u8 intf_id;
+} __packed;
+
+struct gb_svc_intf_vsys_response {
+ __u8 result_code;
+#define GB_SVC_INTF_VSYS_OK 0x00
+ /* 0x01 is reserved */
+#define GB_SVC_INTF_VSYS_FAIL 0x02
+} __packed;
+
+/* used for svc_intf_refclk_{enable,disable} */
+struct gb_svc_intf_refclk_request {
+ __u8 intf_id;
+} __packed;
+
+struct gb_svc_intf_refclk_response {
+ __u8 result_code;
+#define GB_SVC_INTF_REFCLK_OK 0x00
+ /* 0x01 is reserved */
+#define GB_SVC_INTF_REFCLK_FAIL 0x02
+} __packed;
+
+/* used for svc_intf_unipro_{enable,disable} */
+struct gb_svc_intf_unipro_request {
+ __u8 intf_id;
+} __packed;
+
+struct gb_svc_intf_unipro_response {
+ __u8 result_code;
+#define GB_SVC_INTF_UNIPRO_OK 0x00
+ /* 0x01 is reserved */
+#define GB_SVC_INTF_UNIPRO_FAIL 0x02
+#define GB_SVC_INTF_UNIPRO_NOT_OFF 0x03
+} __packed;
+
+struct gb_svc_timesync_enable_request {
+ __u8 count;
+ __le64 frame_time;
+ __le32 strobe_delay;
+ __le32 refclk;
+} __packed;
+/* timesync enable response has no payload */
+
+/* timesync authoritative request has no payload */
+struct gb_svc_timesync_authoritative_response {
+ __le64 frame_time[GB_TIMESYNC_MAX_STROBES];
+};
+
+struct gb_svc_timesync_wake_pins_acquire_request {
+ __le32 strobe_mask;
+};
+
+/* timesync wake pins acquire response has no payload */
+
+/* timesync wake pins release request has no payload */
+/* timesync wake pins release response has no payload */
+
+/* timesync svc ping request has no payload */
+struct gb_svc_timesync_ping_response {
+ __le64 frame_time;
+} __packed;
+
+#define GB_SVC_UNIPRO_FAST_MODE 0x01
+#define GB_SVC_UNIPRO_SLOW_MODE 0x02
+#define GB_SVC_UNIPRO_FAST_AUTO_MODE 0x04
+#define GB_SVC_UNIPRO_SLOW_AUTO_MODE 0x05
+#define GB_SVC_UNIPRO_MODE_UNCHANGED 0x07
+#define GB_SVC_UNIPRO_HIBERNATE_MODE 0x11
+#define GB_SVC_UNIPRO_OFF_MODE 0x12
+
+#define GB_SVC_SMALL_AMPLITUDE 0x01
+#define GB_SVC_LARGE_AMPLITUDE 0x02
+
+#define GB_SVC_NO_DE_EMPHASIS 0x00
+#define GB_SVC_SMALL_DE_EMPHASIS 0x01
+#define GB_SVC_LARGE_DE_EMPHASIS 0x02
+
+#define GB_SVC_PWRM_RXTERMINATION 0x01
+#define GB_SVC_PWRM_TXTERMINATION 0x02
+#define GB_SVC_PWRM_LINE_RESET 0x04
+#define GB_SVC_PWRM_SCRAMBLING 0x20
+
+#define GB_SVC_PWRM_QUIRK_HSSER 0x00000001
+
+#define GB_SVC_UNIPRO_HS_SERIES_A 0x01
+#define GB_SVC_UNIPRO_HS_SERIES_B 0x02
+
+#define GB_SVC_SETPWRM_PWR_OK 0x00
+#define GB_SVC_SETPWRM_PWR_LOCAL 0x01
+#define GB_SVC_SETPWRM_PWR_REMOTE 0x02
+#define GB_SVC_SETPWRM_PWR_BUSY 0x03
+#define GB_SVC_SETPWRM_PWR_ERROR_CAP 0x04
+#define GB_SVC_SETPWRM_PWR_FATAL_ERROR 0x05
+
+struct gb_svc_l2_timer_cfg {
+ __le16 tsb_fc0_protection_timeout;
+ __le16 tsb_tc0_replay_timeout;
+ __le16 tsb_afc0_req_timeout;
+ __le16 tsb_fc1_protection_timeout;
+ __le16 tsb_tc1_replay_timeout;
+ __le16 tsb_afc1_req_timeout;
+ __le16 reserved_for_tc2[3];
+ __le16 reserved_for_tc3[3];
+} __packed;
+
+struct gb_svc_intf_set_pwrm_request {
+ __u8 intf_id;
+ __u8 hs_series;
+ __u8 tx_mode;
+ __u8 tx_gear;
+ __u8 tx_nlanes;
+ __u8 tx_amplitude;
+ __u8 tx_hs_equalizer;
+ __u8 rx_mode;
+ __u8 rx_gear;
+ __u8 rx_nlanes;
+ __u8 flags;
+ __le32 quirks;
+ struct gb_svc_l2_timer_cfg local_l2timerdata, remote_l2timerdata;
+} __packed;
+
+struct gb_svc_intf_set_pwrm_response {
+ __u8 result_code;
+} __packed;
+
+struct gb_svc_key_event_request {
+ __le16 key_code;
+#define GB_KEYCODE_ARA 0x00
+
+ __u8 key_event;
+#define GB_SVC_KEY_RELEASED 0x00
+#define GB_SVC_KEY_PRESSED 0x01
+} __packed;
+
+#define GB_SVC_PWRMON_MAX_RAIL_COUNT 254
+
+struct gb_svc_pwrmon_rail_count_get_response {
+ __u8 rail_count;
+} __packed;
+
+#define GB_SVC_PWRMON_RAIL_NAME_BUFSIZE 32
+
+struct gb_svc_pwrmon_rail_names_get_response {
+ __u8 status;
+ __u8 name[0][GB_SVC_PWRMON_RAIL_NAME_BUFSIZE];
+} __packed;
+
+#define GB_SVC_PWRMON_TYPE_CURR 0x01
+#define GB_SVC_PWRMON_TYPE_VOL 0x02
+#define GB_SVC_PWRMON_TYPE_PWR 0x03
+
+#define GB_SVC_PWRMON_GET_SAMPLE_OK 0x00
+#define GB_SVC_PWRMON_GET_SAMPLE_INVAL 0x01
+#define GB_SVC_PWRMON_GET_SAMPLE_NOSUPP 0x02
+#define GB_SVC_PWRMON_GET_SAMPLE_HWERR 0x03
+
+struct gb_svc_pwrmon_sample_get_request {
+ __u8 rail_id;
+ __u8 measurement_type;
+} __packed;
+
+struct gb_svc_pwrmon_sample_get_response {
+ __u8 result;
+ __le32 measurement;
+} __packed;
+
+struct gb_svc_pwrmon_intf_sample_get_request {
+ __u8 intf_id;
+ __u8 measurement_type;
+} __packed;
+
+struct gb_svc_pwrmon_intf_sample_get_response {
+ __u8 result;
+ __le32 measurement;
+} __packed;
+
+#define GB_SVC_MODULE_INSERTED_FLAG_NO_PRIMARY 0x0001
+
+struct gb_svc_module_inserted_request {
+ __u8 primary_intf_id;
+ __u8 intf_count;
+ __le16 flags;
+} __packed;
+/* module_inserted response has no payload */
+
+struct gb_svc_module_removed_request {
+ __u8 primary_intf_id;
+} __packed;
+/* module_removed response has no payload */
+
+struct gb_svc_intf_activate_request {
+ __u8 intf_id;
+} __packed;
+
+#define GB_SVC_INTF_TYPE_UNKNOWN 0x00
+#define GB_SVC_INTF_TYPE_DUMMY 0x01
+#define GB_SVC_INTF_TYPE_UNIPRO 0x02
+#define GB_SVC_INTF_TYPE_GREYBUS 0x03
+
+struct gb_svc_intf_activate_response {
+ __u8 status;
+ __u8 intf_type;
+} __packed;
+
+struct gb_svc_intf_resume_request {
+ __u8 intf_id;
+} __packed;
+
+struct gb_svc_intf_resume_response {
+ __u8 status;
+} __packed;
+
+#define GB_SVC_INTF_MAILBOX_NONE 0x00
+#define GB_SVC_INTF_MAILBOX_AP 0x01
+#define GB_SVC_INTF_MAILBOX_GREYBUS 0x02
+
+struct gb_svc_intf_mailbox_event_request {
+ __u8 intf_id;
+ __le16 result_code;
+ __le32 mailbox;
+} __packed;
+/* intf_mailbox_event response has no payload */
+
+struct gb_svc_intf_oops_request {
+ __u8 intf_id;
+ __u8 reason;
+} __packed;
+/* intf_oops response has no payload */
+
+
+/* RAW */
+
+/* Greybus raw request types */
+#define GB_RAW_TYPE_SEND 0x02
+
+struct gb_raw_send_request {
+ __le32 len;
+ __u8 data[0];
+} __packed;
+
+
+/* UART */
+
+/* Greybus UART operation types */
+#define GB_UART_TYPE_SEND_DATA 0x02
+#define GB_UART_TYPE_RECEIVE_DATA 0x03 /* Unsolicited data */
+#define GB_UART_TYPE_SET_LINE_CODING 0x04
+#define GB_UART_TYPE_SET_CONTROL_LINE_STATE 0x05
+#define GB_UART_TYPE_SEND_BREAK 0x06
+#define GB_UART_TYPE_SERIAL_STATE 0x07 /* Unsolicited data */
+#define GB_UART_TYPE_RECEIVE_CREDITS 0x08
+#define GB_UART_TYPE_FLUSH_FIFOS 0x09
+
+/* Represents data from AP -> Module */
+struct gb_uart_send_data_request {
+ __le16 size;
+ __u8 data[0];
+} __packed;
+
+/* recv-data-request flags */
+#define GB_UART_RECV_FLAG_FRAMING 0x01 /* Framing error */
+#define GB_UART_RECV_FLAG_PARITY 0x02 /* Parity error */
+#define GB_UART_RECV_FLAG_OVERRUN 0x04 /* Overrun error */
+#define GB_UART_RECV_FLAG_BREAK 0x08 /* Break */
+
+/* Represents data from Module -> AP */
+struct gb_uart_recv_data_request {
+ __le16 size;
+ __u8 flags;
+ __u8 data[0];
+} __packed;
+
+struct gb_uart_receive_credits_request {
+ __le16 count;
+} __packed;
+
+struct gb_uart_set_line_coding_request {
+ __le32 rate;
+ __u8 format;
+#define GB_SERIAL_1_STOP_BITS 0
+#define GB_SERIAL_1_5_STOP_BITS 1
+#define GB_SERIAL_2_STOP_BITS 2
+
+ __u8 parity;
+#define GB_SERIAL_NO_PARITY 0
+#define GB_SERIAL_ODD_PARITY 1
+#define GB_SERIAL_EVEN_PARITY 2
+#define GB_SERIAL_MARK_PARITY 3
+#define GB_SERIAL_SPACE_PARITY 4
+
+ __u8 data_bits;
+
+ __u8 flow_control;
+#define GB_SERIAL_AUTO_RTSCTS_EN 0x1
+} __packed;
+
+/* output control lines */
+#define GB_UART_CTRL_DTR 0x01
+#define GB_UART_CTRL_RTS 0x02
+
+struct gb_uart_set_control_line_state_request {
+ __u8 control;
+} __packed;
+
+struct gb_uart_set_break_request {
+ __u8 state;
+} __packed;
+
+/* input control lines and line errors */
+#define GB_UART_CTRL_DCD 0x01
+#define GB_UART_CTRL_DSR 0x02
+#define GB_UART_CTRL_RI 0x04
+
+struct gb_uart_serial_state_request {
+ __u8 control;
+} __packed;
+
+struct gb_uart_serial_flush_request {
+ __u8 flags;
+#define GB_SERIAL_FLAG_FLUSH_TRANSMITTER 0x01
+#define GB_SERIAL_FLAG_FLUSH_RECEIVER 0x02
+} __packed;
+
+/* Loopback */
+
+/* Greybus loopback request types */
+#define GB_LOOPBACK_TYPE_PING 0x02
+#define GB_LOOPBACK_TYPE_TRANSFER 0x03
+#define GB_LOOPBACK_TYPE_SINK 0x04
+
+/*
+ * Loopback request/response header format should be identical
+ * to simplify bandwidth and data movement analysis.
+ */
+struct gb_loopback_transfer_request {
+ __le32 len;
+ __le32 reserved0;
+ __le32 reserved1;
+ __u8 data[0];
+} __packed;
+
+struct gb_loopback_transfer_response {
+ __le32 len;
+ __le32 reserved0;
+ __le32 reserved1;
+ __u8 data[0];
+} __packed;
+
+/* SDIO */
+/* Greybus SDIO operation types */
+#define GB_SDIO_TYPE_GET_CAPABILITIES 0x02
+#define GB_SDIO_TYPE_SET_IOS 0x03
+#define GB_SDIO_TYPE_COMMAND 0x04
+#define GB_SDIO_TYPE_TRANSFER 0x05
+#define GB_SDIO_TYPE_EVENT 0x06
+
+/* get caps response: request has no payload */
+struct gb_sdio_get_caps_response {
+ __le32 caps;
+#define GB_SDIO_CAP_NONREMOVABLE 0x00000001
+#define GB_SDIO_CAP_4_BIT_DATA 0x00000002
+#define GB_SDIO_CAP_8_BIT_DATA 0x00000004
+#define GB_SDIO_CAP_MMC_HS 0x00000008
+#define GB_SDIO_CAP_SD_HS 0x00000010
+#define GB_SDIO_CAP_ERASE 0x00000020
+#define GB_SDIO_CAP_1_2V_DDR 0x00000040
+#define GB_SDIO_CAP_1_8V_DDR 0x00000080
+#define GB_SDIO_CAP_POWER_OFF_CARD 0x00000100
+#define GB_SDIO_CAP_UHS_SDR12 0x00000200
+#define GB_SDIO_CAP_UHS_SDR25 0x00000400
+#define GB_SDIO_CAP_UHS_SDR50 0x00000800
+#define GB_SDIO_CAP_UHS_SDR104 0x00001000
+#define GB_SDIO_CAP_UHS_DDR50 0x00002000
+#define GB_SDIO_CAP_DRIVER_TYPE_A 0x00004000
+#define GB_SDIO_CAP_DRIVER_TYPE_C 0x00008000
+#define GB_SDIO_CAP_DRIVER_TYPE_D 0x00010000
+#define GB_SDIO_CAP_HS200_1_2V 0x00020000
+#define GB_SDIO_CAP_HS200_1_8V 0x00040000
+#define GB_SDIO_CAP_HS400_1_2V 0x00080000
+#define GB_SDIO_CAP_HS400_1_8V 0x00100000
+
+ /* see possible values below at vdd */
+ __le32 ocr;
+ __le32 f_min;
+ __le32 f_max;
+ __le16 max_blk_count;
+ __le16 max_blk_size;
+} __packed;
+
+/* set ios request: response has no payload */
+struct gb_sdio_set_ios_request {
+ __le32 clock;
+ __le32 vdd;
+#define GB_SDIO_VDD_165_195 0x00000001
+#define GB_SDIO_VDD_20_21 0x00000002
+#define GB_SDIO_VDD_21_22 0x00000004
+#define GB_SDIO_VDD_22_23 0x00000008
+#define GB_SDIO_VDD_23_24 0x00000010
+#define GB_SDIO_VDD_24_25 0x00000020
+#define GB_SDIO_VDD_25_26 0x00000040
+#define GB_SDIO_VDD_26_27 0x00000080
+#define GB_SDIO_VDD_27_28 0x00000100
+#define GB_SDIO_VDD_28_29 0x00000200
+#define GB_SDIO_VDD_29_30 0x00000400
+#define GB_SDIO_VDD_30_31 0x00000800
+#define GB_SDIO_VDD_31_32 0x00001000
+#define GB_SDIO_VDD_32_33 0x00002000
+#define GB_SDIO_VDD_33_34 0x00004000
+#define GB_SDIO_VDD_34_35 0x00008000
+#define GB_SDIO_VDD_35_36 0x00010000
+
+ __u8 bus_mode;
+#define GB_SDIO_BUSMODE_OPENDRAIN 0x00
+#define GB_SDIO_BUSMODE_PUSHPULL 0x01
+
+ __u8 power_mode;
+#define GB_SDIO_POWER_OFF 0x00
+#define GB_SDIO_POWER_UP 0x01
+#define GB_SDIO_POWER_ON 0x02
+#define GB_SDIO_POWER_UNDEFINED 0x03
+
+ __u8 bus_width;
+#define GB_SDIO_BUS_WIDTH_1 0x00
+#define GB_SDIO_BUS_WIDTH_4 0x02
+#define GB_SDIO_BUS_WIDTH_8 0x03
+
+ __u8 timing;
+#define GB_SDIO_TIMING_LEGACY 0x00
+#define GB_SDIO_TIMING_MMC_HS 0x01
+#define GB_SDIO_TIMING_SD_HS 0x02
+#define GB_SDIO_TIMING_UHS_SDR12 0x03
+#define GB_SDIO_TIMING_UHS_SDR25 0x04
+#define GB_SDIO_TIMING_UHS_SDR50 0x05
+#define GB_SDIO_TIMING_UHS_SDR104 0x06
+#define GB_SDIO_TIMING_UHS_DDR50 0x07
+#define GB_SDIO_TIMING_MMC_DDR52 0x08
+#define GB_SDIO_TIMING_MMC_HS200 0x09
+#define GB_SDIO_TIMING_MMC_HS400 0x0A
+
+ __u8 signal_voltage;
+#define GB_SDIO_SIGNAL_VOLTAGE_330 0x00
+#define GB_SDIO_SIGNAL_VOLTAGE_180 0x01
+#define GB_SDIO_SIGNAL_VOLTAGE_120 0x02
+
+ __u8 drv_type;
+#define GB_SDIO_SET_DRIVER_TYPE_B 0x00
+#define GB_SDIO_SET_DRIVER_TYPE_A 0x01
+#define GB_SDIO_SET_DRIVER_TYPE_C 0x02
+#define GB_SDIO_SET_DRIVER_TYPE_D 0x03
+} __packed;
+
+/* command request */
+struct gb_sdio_command_request {
+ __u8 cmd;
+ __u8 cmd_flags;
+#define GB_SDIO_RSP_NONE 0x00
+#define GB_SDIO_RSP_PRESENT 0x01
+#define GB_SDIO_RSP_136 0x02
+#define GB_SDIO_RSP_CRC 0x04
+#define GB_SDIO_RSP_BUSY 0x08
+#define GB_SDIO_RSP_OPCODE 0x10
+
+ __u8 cmd_type;
+#define GB_SDIO_CMD_AC 0x00
+#define GB_SDIO_CMD_ADTC 0x01
+#define GB_SDIO_CMD_BC 0x02
+#define GB_SDIO_CMD_BCR 0x03
+
+ __le32 cmd_arg;
+ __le16 data_blocks;
+ __le16 data_blksz;
+} __packed;
+
+struct gb_sdio_command_response {
+ __le32 resp[4];
+} __packed;
+
+/* transfer request */
+struct gb_sdio_transfer_request {
+ __u8 data_flags;
+#define GB_SDIO_DATA_WRITE 0x01
+#define GB_SDIO_DATA_READ 0x02
+#define GB_SDIO_DATA_STREAM 0x04
+
+ __le16 data_blocks;
+ __le16 data_blksz;
+ __u8 data[0];
+} __packed;
+
+struct gb_sdio_transfer_response {
+ __le16 data_blocks;
+ __le16 data_blksz;
+ __u8 data[0];
+} __packed;
+
+/* event request: generated by module and is defined as unidirectional */
+struct gb_sdio_event_request {
+ __u8 event;
+#define GB_SDIO_CARD_INSERTED 0x01
+#define GB_SDIO_CARD_REMOVED 0x02
+#define GB_SDIO_WP 0x04
+} __packed;
+
+/* Camera */
+
+/* Greybus Camera request types */
+#define GB_CAMERA_TYPE_CAPABILITIES 0x02
+#define GB_CAMERA_TYPE_CONFIGURE_STREAMS 0x03
+#define GB_CAMERA_TYPE_CAPTURE 0x04
+#define GB_CAMERA_TYPE_FLUSH 0x05
+#define GB_CAMERA_TYPE_METADATA 0x06
+
+#define GB_CAMERA_MAX_STREAMS 4
+#define GB_CAMERA_MAX_SETTINGS_SIZE 8192
+
+/* Greybus Camera Configure Streams request payload */
+struct gb_camera_stream_config_request {
+ __le16 width;
+ __le16 height;
+ __le16 format;
+ __le16 padding;
+} __packed;
+
+struct gb_camera_configure_streams_request {
+ __u8 num_streams;
+ __u8 flags;
+#define GB_CAMERA_CONFIGURE_STREAMS_TEST_ONLY 0x01
+ __le16 padding;
+ struct gb_camera_stream_config_request config[0];
+} __packed;
+
+/* Greybus Camera Configure Streams response payload */
+struct gb_camera_stream_config_response {
+ __le16 width;
+ __le16 height;
+ __le16 format;
+ __u8 virtual_channel;
+ __u8 data_type[2];
+ __le16 max_pkt_size;
+ __u8 padding;
+ __le32 max_size;
+} __packed;
+
+struct gb_camera_configure_streams_response {
+ __u8 num_streams;
+#define GB_CAMERA_CONFIGURE_STREAMS_ADJUSTED 0x01
+ __u8 flags;
+ __u8 padding[2];
+ __le32 data_rate;
+ struct gb_camera_stream_config_response config[0];
+};
+
+/* Greybus Camera Capture request payload - response has no payload */
+struct gb_camera_capture_request {
+ __le32 request_id;
+ __u8 streams;
+ __u8 padding;
+ __le16 num_frames;
+ __u8 settings[0];
+} __packed;
+
+/* Greybus Camera Flush response payload - request has no payload */
+struct gb_camera_flush_response {
+ __le32 request_id;
+} __packed;
+
+/* Greybus Camera Metadata request payload - operation has no response */
+struct gb_camera_metadata_request {
+ __le32 request_id;
+ __le16 frame_number;
+ __u8 stream;
+ __u8 padding;
+ __u8 metadata[0];
+} __packed;
+
+/* Lights */
+
+/* Greybus Lights request types */
+#define GB_LIGHTS_TYPE_GET_LIGHTS 0x02
+#define GB_LIGHTS_TYPE_GET_LIGHT_CONFIG 0x03
+#define GB_LIGHTS_TYPE_GET_CHANNEL_CONFIG 0x04
+#define GB_LIGHTS_TYPE_GET_CHANNEL_FLASH_CONFIG 0x05
+#define GB_LIGHTS_TYPE_SET_BRIGHTNESS 0x06
+#define GB_LIGHTS_TYPE_SET_BLINK 0x07
+#define GB_LIGHTS_TYPE_SET_COLOR 0x08
+#define GB_LIGHTS_TYPE_SET_FADE 0x09
+#define GB_LIGHTS_TYPE_EVENT 0x0A
+#define GB_LIGHTS_TYPE_SET_FLASH_INTENSITY 0x0B
+#define GB_LIGHTS_TYPE_SET_FLASH_STROBE 0x0C
+#define GB_LIGHTS_TYPE_SET_FLASH_TIMEOUT 0x0D
+#define GB_LIGHTS_TYPE_GET_FLASH_FAULT 0x0E
+
+/* Greybus Light modes */
+
+/*
+ * if you add any specific mode below, update also the
+ * GB_CHANNEL_MODE_DEFINED_RANGE value accordingly
+ */
+#define GB_CHANNEL_MODE_NONE 0x00000000
+#define GB_CHANNEL_MODE_BATTERY 0x00000001
+#define GB_CHANNEL_MODE_POWER 0x00000002
+#define GB_CHANNEL_MODE_WIRELESS 0x00000004
+#define GB_CHANNEL_MODE_BLUETOOTH 0x00000008
+#define GB_CHANNEL_MODE_KEYBOARD 0x00000010
+#define GB_CHANNEL_MODE_BUTTONS 0x00000020
+#define GB_CHANNEL_MODE_NOTIFICATION 0x00000040
+#define GB_CHANNEL_MODE_ATTENTION 0x00000080
+#define GB_CHANNEL_MODE_FLASH 0x00000100
+#define GB_CHANNEL_MODE_TORCH 0x00000200
+#define GB_CHANNEL_MODE_INDICATOR 0x00000400
+
+/* Lights Mode valid bit values */
+#define GB_CHANNEL_MODE_DEFINED_RANGE 0x000004FF
+#define GB_CHANNEL_MODE_VENDOR_RANGE 0x00F00000
+
+/* Greybus Light Channels Flags */
+#define GB_LIGHT_CHANNEL_MULTICOLOR 0x00000001
+#define GB_LIGHT_CHANNEL_FADER 0x00000002
+#define GB_LIGHT_CHANNEL_BLINK 0x00000004
+
+/* get count of lights in module */
+struct gb_lights_get_lights_response {
+ __u8 lights_count;
+} __packed;
+
+/* light config request payload */
+struct gb_lights_get_light_config_request {
+ __u8 id;
+} __packed;
+
+/* light config response payload */
+struct gb_lights_get_light_config_response {
+ __u8 channel_count;
+ __u8 name[32];
+} __packed;
+
+/* channel config request payload */
+struct gb_lights_get_channel_config_request {
+ __u8 light_id;
+ __u8 channel_id;
+} __packed;
+
+/* channel flash config request payload */
+struct gb_lights_get_channel_flash_config_request {
+ __u8 light_id;
+ __u8 channel_id;
+} __packed;
+
+/* channel config response payload */
+struct gb_lights_get_channel_config_response {
+ __u8 max_brightness;
+ __le32 flags;
+ __le32 color;
+ __u8 color_name[32];
+ __le32 mode;
+ __u8 mode_name[32];
+} __packed;
+
+/* channel flash config response payload */
+struct gb_lights_get_channel_flash_config_response {
+ __le32 intensity_min_uA;
+ __le32 intensity_max_uA;
+ __le32 intensity_step_uA;
+ __le32 timeout_min_us;
+ __le32 timeout_max_us;
+ __le32 timeout_step_us;
+} __packed;
+
+/* blink request payload: response have no payload */
+struct gb_lights_blink_request {
+ __u8 light_id;
+ __u8 channel_id;
+ __le16 time_on_ms;
+ __le16 time_off_ms;
+} __packed;
+
+/* set brightness request payload: response have no payload */
+struct gb_lights_set_brightness_request {
+ __u8 light_id;
+ __u8 channel_id;
+ __u8 brightness;
+} __packed;
+
+/* set color request payload: response have no payload */
+struct gb_lights_set_color_request {
+ __u8 light_id;
+ __u8 channel_id;
+ __le32 color;
+} __packed;
+
+/* set fade request payload: response have no payload */
+struct gb_lights_set_fade_request {
+ __u8 light_id;
+ __u8 channel_id;
+ __u8 fade_in;
+ __u8 fade_out;
+} __packed;
+
+/* event request: generated by module */
+struct gb_lights_event_request {
+ __u8 light_id;
+ __u8 event;
+#define GB_LIGHTS_LIGHT_CONFIG 0x01
+} __packed;
+
+/* set flash intensity request payload: response have no payload */
+struct gb_lights_set_flash_intensity_request {
+ __u8 light_id;
+ __u8 channel_id;
+ __le32 intensity_uA;
+} __packed;
+
+/* set flash strobe state request payload: response have no payload */
+struct gb_lights_set_flash_strobe_request {
+ __u8 light_id;
+ __u8 channel_id;
+ __u8 state;
+} __packed;
+
+/* set flash timeout request payload: response have no payload */
+struct gb_lights_set_flash_timeout_request {
+ __u8 light_id;
+ __u8 channel_id;
+ __le32 timeout_us;
+} __packed;
+
+/* get flash fault request payload */
+struct gb_lights_get_flash_fault_request {
+ __u8 light_id;
+ __u8 channel_id;
+} __packed;
+
+/* get flash fault response payload */
+struct gb_lights_get_flash_fault_response {
+ __le32 fault;
+#define GB_LIGHTS_FLASH_FAULT_OVER_VOLTAGE 0x00000000
+#define GB_LIGHTS_FLASH_FAULT_TIMEOUT 0x00000001
+#define GB_LIGHTS_FLASH_FAULT_OVER_TEMPERATURE 0x00000002
+#define GB_LIGHTS_FLASH_FAULT_SHORT_CIRCUIT 0x00000004
+#define GB_LIGHTS_FLASH_FAULT_OVER_CURRENT 0x00000008
+#define GB_LIGHTS_FLASH_FAULT_INDICATOR 0x00000010
+#define GB_LIGHTS_FLASH_FAULT_UNDER_VOLTAGE 0x00000020
+#define GB_LIGHTS_FLASH_FAULT_INPUT_VOLTAGE 0x00000040
+#define GB_LIGHTS_FLASH_FAULT_LED_OVER_TEMPERATURE 0x00000080
+} __packed;
+
+/* Audio */
+
+#define GB_AUDIO_TYPE_GET_TOPOLOGY_SIZE 0x02
+#define GB_AUDIO_TYPE_GET_TOPOLOGY 0x03
+#define GB_AUDIO_TYPE_GET_CONTROL 0x04
+#define GB_AUDIO_TYPE_SET_CONTROL 0x05
+#define GB_AUDIO_TYPE_ENABLE_WIDGET 0x06
+#define GB_AUDIO_TYPE_DISABLE_WIDGET 0x07
+#define GB_AUDIO_TYPE_GET_PCM 0x08
+#define GB_AUDIO_TYPE_SET_PCM 0x09
+#define GB_AUDIO_TYPE_SET_TX_DATA_SIZE 0x0a
+ /* 0x0b unused */
+#define GB_AUDIO_TYPE_ACTIVATE_TX 0x0c
+#define GB_AUDIO_TYPE_DEACTIVATE_TX 0x0d
+#define GB_AUDIO_TYPE_SET_RX_DATA_SIZE 0x0e
+ /* 0x0f unused */
+#define GB_AUDIO_TYPE_ACTIVATE_RX 0x10
+#define GB_AUDIO_TYPE_DEACTIVATE_RX 0x11
+#define GB_AUDIO_TYPE_JACK_EVENT 0x12
+#define GB_AUDIO_TYPE_BUTTON_EVENT 0x13
+#define GB_AUDIO_TYPE_STREAMING_EVENT 0x14
+#define GB_AUDIO_TYPE_SEND_DATA 0x15
+
+/* Module must be able to buffer 10ms of audio data, minimum */
+#define GB_AUDIO_SAMPLE_BUFFER_MIN_US 10000
+
+#define GB_AUDIO_PCM_NAME_MAX 32
+#define AUDIO_DAI_NAME_MAX 32
+#define AUDIO_CONTROL_NAME_MAX 32
+#define AUDIO_CTL_ELEM_NAME_MAX 44
+#define AUDIO_ENUM_NAME_MAX 64
+#define AUDIO_WIDGET_NAME_MAX 32
+
+/* See SNDRV_PCM_FMTBIT_* in Linux source */
+#define GB_AUDIO_PCM_FMT_S8 BIT(0)
+#define GB_AUDIO_PCM_FMT_U8 BIT(1)
+#define GB_AUDIO_PCM_FMT_S16_LE BIT(2)
+#define GB_AUDIO_PCM_FMT_S16_BE BIT(3)
+#define GB_AUDIO_PCM_FMT_U16_LE BIT(4)
+#define GB_AUDIO_PCM_FMT_U16_BE BIT(5)
+#define GB_AUDIO_PCM_FMT_S24_LE BIT(6)
+#define GB_AUDIO_PCM_FMT_S24_BE BIT(7)
+#define GB_AUDIO_PCM_FMT_U24_LE BIT(8)
+#define GB_AUDIO_PCM_FMT_U24_BE BIT(9)
+#define GB_AUDIO_PCM_FMT_S32_LE BIT(10)
+#define GB_AUDIO_PCM_FMT_S32_BE BIT(11)
+#define GB_AUDIO_PCM_FMT_U32_LE BIT(12)
+#define GB_AUDIO_PCM_FMT_U32_BE BIT(13)
+
+/* See SNDRV_PCM_RATE_* in Linux source */
+#define GB_AUDIO_PCM_RATE_5512 BIT(0)
+#define GB_AUDIO_PCM_RATE_8000 BIT(1)
+#define GB_AUDIO_PCM_RATE_11025 BIT(2)
+#define GB_AUDIO_PCM_RATE_16000 BIT(3)
+#define GB_AUDIO_PCM_RATE_22050 BIT(4)
+#define GB_AUDIO_PCM_RATE_32000 BIT(5)
+#define GB_AUDIO_PCM_RATE_44100 BIT(6)
+#define GB_AUDIO_PCM_RATE_48000 BIT(7)
+#define GB_AUDIO_PCM_RATE_64000 BIT(8)
+#define GB_AUDIO_PCM_RATE_88200 BIT(9)
+#define GB_AUDIO_PCM_RATE_96000 BIT(10)
+#define GB_AUDIO_PCM_RATE_176400 BIT(11)
+#define GB_AUDIO_PCM_RATE_192000 BIT(12)
+
+#define GB_AUDIO_STREAM_TYPE_CAPTURE 0x1
+#define GB_AUDIO_STREAM_TYPE_PLAYBACK 0x2
+
+#define GB_AUDIO_CTL_ELEM_ACCESS_READ BIT(0)
+#define GB_AUDIO_CTL_ELEM_ACCESS_WRITE BIT(1)
+
+/* See SNDRV_CTL_ELEM_TYPE_* in Linux source */
+#define GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN 0x01
+#define GB_AUDIO_CTL_ELEM_TYPE_INTEGER 0x02
+#define GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED 0x03
+#define GB_AUDIO_CTL_ELEM_TYPE_INTEGER64 0x06
+
+/* See SNDRV_CTL_ELEM_IFACE_* in Linux source */
+#define GB_AUDIO_CTL_ELEM_IFACE_CARD 0x00
+#define GB_AUDIO_CTL_ELEM_IFACE_HWDEP 0x01
+#define GB_AUDIO_CTL_ELEM_IFACE_MIXER 0x02
+#define GB_AUDIO_CTL_ELEM_IFACE_PCM 0x03
+#define GB_AUDIO_CTL_ELEM_IFACE_RAWMIDI 0x04
+#define GB_AUDIO_CTL_ELEM_IFACE_TIMER 0x05
+#define GB_AUDIO_CTL_ELEM_IFACE_SEQUENCER 0x06
+
+/* SNDRV_CTL_ELEM_ACCESS_* in Linux source */
+#define GB_AUDIO_ACCESS_READ BIT(0)
+#define GB_AUDIO_ACCESS_WRITE BIT(1)
+#define GB_AUDIO_ACCESS_VOLATILE BIT(2)
+#define GB_AUDIO_ACCESS_TIMESTAMP BIT(3)
+#define GB_AUDIO_ACCESS_TLV_READ BIT(4)
+#define GB_AUDIO_ACCESS_TLV_WRITE BIT(5)
+#define GB_AUDIO_ACCESS_TLV_COMMAND BIT(6)
+#define GB_AUDIO_ACCESS_INACTIVE BIT(7)
+#define GB_AUDIO_ACCESS_LOCK BIT(8)
+#define GB_AUDIO_ACCESS_OWNER BIT(9)
+
+/* enum snd_soc_dapm_type */
+#define GB_AUDIO_WIDGET_TYPE_INPUT 0x0
+#define GB_AUDIO_WIDGET_TYPE_OUTPUT 0x1
+#define GB_AUDIO_WIDGET_TYPE_MUX 0x2
+#define GB_AUDIO_WIDGET_TYPE_VIRT_MUX 0x3
+#define GB_AUDIO_WIDGET_TYPE_VALUE_MUX 0x4
+#define GB_AUDIO_WIDGET_TYPE_MIXER 0x5
+#define GB_AUDIO_WIDGET_TYPE_MIXER_NAMED_CTL 0x6
+#define GB_AUDIO_WIDGET_TYPE_PGA 0x7
+#define GB_AUDIO_WIDGET_TYPE_OUT_DRV 0x8
+#define GB_AUDIO_WIDGET_TYPE_ADC 0x9
+#define GB_AUDIO_WIDGET_TYPE_DAC 0xa
+#define GB_AUDIO_WIDGET_TYPE_MICBIAS 0xb
+#define GB_AUDIO_WIDGET_TYPE_MIC 0xc
+#define GB_AUDIO_WIDGET_TYPE_HP 0xd
+#define GB_AUDIO_WIDGET_TYPE_SPK 0xe
+#define GB_AUDIO_WIDGET_TYPE_LINE 0xf
+#define GB_AUDIO_WIDGET_TYPE_SWITCH 0x10
+#define GB_AUDIO_WIDGET_TYPE_VMID 0x11
+#define GB_AUDIO_WIDGET_TYPE_PRE 0x12
+#define GB_AUDIO_WIDGET_TYPE_POST 0x13
+#define GB_AUDIO_WIDGET_TYPE_SUPPLY 0x14
+#define GB_AUDIO_WIDGET_TYPE_REGULATOR_SUPPLY 0x15
+#define GB_AUDIO_WIDGET_TYPE_CLOCK_SUPPLY 0x16
+#define GB_AUDIO_WIDGET_TYPE_AIF_IN 0x17
+#define GB_AUDIO_WIDGET_TYPE_AIF_OUT 0x18
+#define GB_AUDIO_WIDGET_TYPE_SIGGEN 0x19
+#define GB_AUDIO_WIDGET_TYPE_DAI_IN 0x1a
+#define GB_AUDIO_WIDGET_TYPE_DAI_OUT 0x1b
+#define GB_AUDIO_WIDGET_TYPE_DAI_LINK 0x1c
+
+#define GB_AUDIO_WIDGET_STATE_DISABLED 0x01
+#define GB_AUDIO_WIDGET_STATE_ENAABLED 0x02
+
+#define GB_AUDIO_JACK_EVENT_INSERTION 0x1
+#define GB_AUDIO_JACK_EVENT_REMOVAL 0x2
+
+#define GB_AUDIO_BUTTON_EVENT_PRESS 0x1
+#define GB_AUDIO_BUTTON_EVENT_RELEASE 0x2
+
+#define GB_AUDIO_STREAMING_EVENT_UNSPECIFIED 0x1
+#define GB_AUDIO_STREAMING_EVENT_HALT 0x2
+#define GB_AUDIO_STREAMING_EVENT_INTERNAL_ERROR 0x3
+#define GB_AUDIO_STREAMING_EVENT_PROTOCOL_ERROR 0x4
+#define GB_AUDIO_STREAMING_EVENT_FAILURE 0x5
+#define GB_AUDIO_STREAMING_EVENT_UNDERRUN 0x6
+#define GB_AUDIO_STREAMING_EVENT_OVERRUN 0x7
+#define GB_AUDIO_STREAMING_EVENT_CLOCKING 0x8
+#define GB_AUDIO_STREAMING_EVENT_DATA_LEN 0x9
+
+#define GB_AUDIO_INVALID_INDEX 0xff
+
+/* enum snd_jack_types */
+#define GB_AUDIO_JACK_HEADPHONE 0x0000001
+#define GB_AUDIO_JACK_MICROPHONE 0x0000002
+#define GB_AUDIO_JACK_HEADSET (GB_AUDIO_JACK_HEADPHONE | \
+ GB_AUDIO_JACK_MICROPHONE)
+#define GB_AUDIO_JACK_LINEOUT 0x0000004
+#define GB_AUDIO_JACK_MECHANICAL 0x0000008
+#define GB_AUDIO_JACK_VIDEOOUT 0x0000010
+#define GB_AUDIO_JACK_AVOUT (GB_AUDIO_JACK_LINEOUT | \
+ GB_AUDIO_JACK_VIDEOOUT)
+#define GB_AUDIO_JACK_LINEIN 0x0000020
+#define GB_AUDIO_JACK_OC_HPHL 0x0000040
+#define GB_AUDIO_JACK_OC_HPHR 0x0000080
+#define GB_AUDIO_JACK_MICROPHONE2 0x0000200
+#define GB_AUDIO_JACK_ANC_HEADPHONE (GB_AUDIO_JACK_HEADPHONE | \
+ GB_AUDIO_JACK_MICROPHONE | \
+ GB_AUDIO_JACK_MICROPHONE2)
+/* Kept separate from switches to facilitate implementation */
+#define GB_AUDIO_JACK_BTN_0 0x4000000
+#define GB_AUDIO_JACK_BTN_1 0x2000000
+#define GB_AUDIO_JACK_BTN_2 0x1000000
+#define GB_AUDIO_JACK_BTN_3 0x0800000
+
+struct gb_audio_pcm {
+ __u8 stream_name[GB_AUDIO_PCM_NAME_MAX];
+ __le32 formats; /* GB_AUDIO_PCM_FMT_* */
+ __le32 rates; /* GB_AUDIO_PCM_RATE_* */
+ __u8 chan_min;
+ __u8 chan_max;
+ __u8 sig_bits; /* number of bits of content */
+} __packed;
+
+struct gb_audio_dai {
+ __u8 name[AUDIO_DAI_NAME_MAX];
+ __le16 data_cport;
+ struct gb_audio_pcm capture;
+ struct gb_audio_pcm playback;
+} __packed;
+
+struct gb_audio_integer {
+ __le32 min;
+ __le32 max;
+ __le32 step;
+} __packed;
+
+struct gb_audio_integer64 {
+ __le64 min;
+ __le64 max;
+ __le64 step;
+} __packed;
+
+struct gb_audio_enumerated {
+ __le32 items;
+ __le16 names_length;
+ __u8 names[0];
+} __packed;
+
+struct gb_audio_ctl_elem_info { /* See snd_ctl_elem_info in Linux source */
+ __u8 type; /* GB_AUDIO_CTL_ELEM_TYPE_* */
+ __le16 dimen[4];
+ union {
+ struct gb_audio_integer integer;
+ struct gb_audio_integer64 integer64;
+ struct gb_audio_enumerated enumerated;
+ } value;
+} __packed;
+
+struct gb_audio_ctl_elem_value { /* See snd_ctl_elem_value in Linux source */
+ __le64 timestamp; /* XXX needed? */
+ union {
+ __le32 integer_value[2]; /* consider CTL_DOUBLE_xxx */
+ __le64 integer64_value[2];
+ __le32 enumerated_item[2];
+ } value;
+} __packed;
+
+struct gb_audio_control {
+ __u8 name[AUDIO_CONTROL_NAME_MAX];
+ __u8 id; /* 0-63 */
+ __u8 iface; /* GB_AUDIO_IFACE_* */
+ __le16 data_cport;
+ __le32 access; /* GB_AUDIO_ACCESS_* */
+ __u8 count; /* count of same elements */
+ __u8 count_values; /* count of values, max=2 for CTL_DOUBLE_xxx */
+ struct gb_audio_ctl_elem_info info;
+} __packed;
+
+struct gb_audio_widget {
+ __u8 name[AUDIO_WIDGET_NAME_MAX];
+ __u8 sname[AUDIO_WIDGET_NAME_MAX];
+ __u8 id;
+ __u8 type; /* GB_AUDIO_WIDGET_TYPE_* */
+ __u8 state; /* GB_AUDIO_WIDGET_STATE_* */
+ __u8 ncontrols;
+ struct gb_audio_control ctl[0]; /* 'ncontrols' entries */
+} __packed;
+
+struct gb_audio_route {
+ __u8 source_id; /* widget id */
+ __u8 destination_id; /* widget id */
+ __u8 control_id; /* 0-63 */
+ __u8 index; /* Selection within the control */
+} __packed;
+
+struct gb_audio_topology {
+ __u8 num_dais;
+ __u8 num_controls;
+ __u8 num_widgets;
+ __u8 num_routes;
+ __le32 size_dais;
+ __le32 size_controls;
+ __le32 size_widgets;
+ __le32 size_routes;
+ __le32 jack_type;
+ /*
+ * struct gb_audio_dai dai[num_dais];
+ * struct gb_audio_control controls[num_controls];
+ * struct gb_audio_widget widgets[num_widgets];
+ * struct gb_audio_route routes[num_routes];
+ */
+ __u8 data[0];
+} __packed;
+
+struct gb_audio_get_topology_size_response {
+ __le16 size;
+} __packed;
+
+struct gb_audio_get_topology_response {
+ struct gb_audio_topology topology;
+} __packed;
+
+struct gb_audio_get_control_request {
+ __u8 control_id;
+ __u8 index;
+} __packed;
+
+struct gb_audio_get_control_response {
+ struct gb_audio_ctl_elem_value value;
+} __packed;
+
+struct gb_audio_set_control_request {
+ __u8 control_id;
+ __u8 index;
+ struct gb_audio_ctl_elem_value value;
+} __packed;
+
+struct gb_audio_enable_widget_request {
+ __u8 widget_id;
+} __packed;
+
+struct gb_audio_disable_widget_request {
+ __u8 widget_id;
+} __packed;
+
+struct gb_audio_get_pcm_request {
+ __le16 data_cport;
+} __packed;
+
+struct gb_audio_get_pcm_response {
+ __le32 format;
+ __le32 rate;
+ __u8 channels;
+ __u8 sig_bits;
+} __packed;
+
+struct gb_audio_set_pcm_request {
+ __le16 data_cport;
+ __le32 format;
+ __le32 rate;
+ __u8 channels;
+ __u8 sig_bits;
+} __packed;
+
+struct gb_audio_set_tx_data_size_request {
+ __le16 data_cport;
+ __le16 size;
+} __packed;
+
+struct gb_audio_activate_tx_request {
+ __le16 data_cport;
+} __packed;
+
+struct gb_audio_deactivate_tx_request {
+ __le16 data_cport;
+} __packed;
+
+struct gb_audio_set_rx_data_size_request {
+ __le16 data_cport;
+ __le16 size;
+} __packed;
+
+struct gb_audio_activate_rx_request {
+ __le16 data_cport;
+} __packed;
+
+struct gb_audio_deactivate_rx_request {
+ __le16 data_cport;
+} __packed;
+
+struct gb_audio_jack_event_request {
+ __u8 widget_id;
+ __u8 jack_attribute;
+ __u8 event;
+} __packed;
+
+struct gb_audio_button_event_request {
+ __u8 widget_id;
+ __u8 button_id;
+ __u8 event;
+} __packed;
+
+struct gb_audio_streaming_event_request {
+ __le16 data_cport;
+ __u8 event;
+} __packed;
+
+struct gb_audio_send_data_request {
+ __le64 timestamp;
+ __u8 data[0];
+} __packed;
+
+
+/* Log */
+
+/* operations */
+#define GB_LOG_TYPE_SEND_LOG 0x02
+
+/* length */
+#define GB_LOG_MAX_LEN 1024
+
+struct gb_log_send_log_request {
+ __le16 len;
+ __u8 msg[0];
+} __packed;
+
+#endif /* __GREYBUS_PROTOCOLS_H */
+
diff --git a/drivers/staging/greybus/greybus_trace.h b/drivers/staging/greybus/greybus_trace.h
new file mode 100644
index 000000000000..6f8692da9ec8
--- /dev/null
+++ b/drivers/staging/greybus/greybus_trace.h
@@ -0,0 +1,531 @@
+/*
+ * Greybus driver and device API
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright 2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM greybus
+
+#if !defined(_TRACE_GREYBUS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_GREYBUS_H
+
+#include <linux/tracepoint.h>
+
+struct gb_message;
+struct gb_operation;
+struct gb_connection;
+struct gb_bundle;
+struct gb_host_device;
+
+DECLARE_EVENT_CLASS(gb_message,
+
+ TP_PROTO(struct gb_message *message),
+
+ TP_ARGS(message),
+
+ TP_STRUCT__entry(
+ __field(u16, size)
+ __field(u16, operation_id)
+ __field(u8, type)
+ __field(u8, result)
+ ),
+
+ TP_fast_assign(
+ __entry->size = le16_to_cpu(message->header->size);
+ __entry->operation_id =
+ le16_to_cpu(message->header->operation_id);
+ __entry->type = message->header->type;
+ __entry->result = message->header->result;
+ ),
+
+ TP_printk("size=%hu operation_id=0x%04x type=0x%02x result=0x%02x",
+ __entry->size, __entry->operation_id,
+ __entry->type, __entry->result)
+);
+
+#define DEFINE_MESSAGE_EVENT(name) \
+ DEFINE_EVENT(gb_message, name, \
+ TP_PROTO(struct gb_message *message), \
+ TP_ARGS(message))
+
+/*
+ * Occurs immediately before calling a host device's message_send()
+ * method.
+ */
+DEFINE_MESSAGE_EVENT(gb_message_send);
+
+/*
+ * Occurs after an incoming request message has been received
+ */
+DEFINE_MESSAGE_EVENT(gb_message_recv_request);
+
+/*
+ * Occurs after an incoming response message has been received,
+ * after its matching request has been found.
+ */
+DEFINE_MESSAGE_EVENT(gb_message_recv_response);
+
+/*
+ * Occurs after an operation has been canceled, possibly before the
+ * cancellation is complete.
+ */
+DEFINE_MESSAGE_EVENT(gb_message_cancel_outgoing);
+
+/*
+ * Occurs when an incoming request is cancelled; if the response has
+ * been queued for sending, this occurs after it is sent.
+ */
+DEFINE_MESSAGE_EVENT(gb_message_cancel_incoming);
+
+/*
+ * Occurs in the host driver message_send() function just prior to
+ * handing off the data to be processed by hardware.
+ */
+DEFINE_MESSAGE_EVENT(gb_message_submit);
+
+#undef DEFINE_MESSAGE_EVENT
+
+DECLARE_EVENT_CLASS(gb_operation,
+
+ TP_PROTO(struct gb_operation *operation),
+
+ TP_ARGS(operation),
+
+ TP_STRUCT__entry(
+ __field(u16, cport_id) /* CPort of HD side of connection */
+ __field(u16, id) /* Operation ID */
+ __field(u8, type)
+ __field(unsigned long, flags)
+ __field(int, active)
+ __field(int, waiters)
+ __field(int, errno)
+ ),
+
+ TP_fast_assign(
+ __entry->cport_id = operation->connection->hd_cport_id;
+ __entry->id = operation->id;
+ __entry->type = operation->type;
+ __entry->flags = operation->flags;
+ __entry->active = operation->active;
+ __entry->waiters = atomic_read(&operation->waiters);
+ __entry->errno = operation->errno;
+ ),
+
+ TP_printk("id=%04x type=0x%02x cport_id=%04x flags=0x%lx active=%d waiters=%d errno=%d",
+ __entry->id, __entry->cport_id, __entry->type, __entry->flags,
+ __entry->active, __entry->waiters, __entry->errno)
+);
+
+#define DEFINE_OPERATION_EVENT(name) \
+ DEFINE_EVENT(gb_operation, name, \
+ TP_PROTO(struct gb_operation *operation), \
+ TP_ARGS(operation))
+
+/*
+ * Occurs after a new operation is created for an outgoing request
+ * has been successfully created.
+ */
+DEFINE_OPERATION_EVENT(gb_operation_create);
+
+/*
+ * Occurs after a new core operation has been created.
+ */
+DEFINE_OPERATION_EVENT(gb_operation_create_core);
+
+/*
+ * Occurs after a new operation has been created for an incoming
+ * request has been successfully created and initialized.
+ */
+DEFINE_OPERATION_EVENT(gb_operation_create_incoming);
+
+/*
+ * Occurs when the last reference to an operation has been dropped,
+ * prior to freeing resources.
+ */
+DEFINE_OPERATION_EVENT(gb_operation_destroy);
+
+/*
+ * Occurs when an operation has been marked active, after updating
+ * its active count.
+ */
+DEFINE_OPERATION_EVENT(gb_operation_get_active);
+
+/*
+ * Occurs when an operation has been marked active, before updating
+ * its active count.
+ */
+DEFINE_OPERATION_EVENT(gb_operation_put_active);
+
+#undef DEFINE_OPERATION_EVENT
+
+DECLARE_EVENT_CLASS(gb_connection,
+
+ TP_PROTO(struct gb_connection *connection),
+
+ TP_ARGS(connection),
+
+ TP_STRUCT__entry(
+ __field(int, hd_bus_id)
+ __field(u8, bundle_id)
+ /* name contains "hd_cport_id/intf_id:cport_id" */
+ __dynamic_array(char, name, sizeof(connection->name))
+ __field(enum gb_connection_state, state)
+ __field(unsigned long, flags)
+ ),
+
+ TP_fast_assign(
+ __entry->hd_bus_id = connection->hd->bus_id;
+ __entry->bundle_id = connection->bundle ?
+ connection->bundle->id : BUNDLE_ID_NONE;
+ memcpy(__get_str(name), connection->name,
+ sizeof(connection->name));
+ __entry->state = connection->state;
+ __entry->flags = connection->flags;
+ ),
+
+ TP_printk("hd_bus_id=%d bundle_id=0x%02x name=\"%s\" state=%u flags=0x%lx",
+ __entry->hd_bus_id, __entry->bundle_id, __get_str(name),
+ (unsigned int)__entry->state, __entry->flags)
+);
+
+#define DEFINE_CONNECTION_EVENT(name) \
+ DEFINE_EVENT(gb_connection, name, \
+ TP_PROTO(struct gb_connection *connection), \
+ TP_ARGS(connection))
+
+/*
+ * Occurs after a new connection is successfully created.
+ */
+DEFINE_CONNECTION_EVENT(gb_connection_create);
+
+/*
+ * Occurs when the last reference to a connection has been dropped,
+ * before its resources are freed.
+ */
+DEFINE_CONNECTION_EVENT(gb_connection_release);
+
+/*
+ * Occurs when a new reference to connection is added, currently
+ * only when a message over the connection is received.
+ */
+DEFINE_CONNECTION_EVENT(gb_connection_get);
+
+/*
+ * Occurs when a new reference to connection is dropped, after a
+ * a received message is handled, or when the connection is
+ * destroyed.
+ */
+DEFINE_CONNECTION_EVENT(gb_connection_put);
+
+/*
+ * Occurs when a request to enable a connection is made, either for
+ * transmit only, or for both transmit and receive.
+ */
+DEFINE_CONNECTION_EVENT(gb_connection_enable);
+
+/*
+ * Occurs when a request to disable a connection is made, either for
+ * receive only, or for both transmit and receive. Also occurs when
+ * a request to forcefully disable a connection is made.
+ */
+DEFINE_CONNECTION_EVENT(gb_connection_disable);
+
+#undef DEFINE_CONNECTION_EVENT
+
+DECLARE_EVENT_CLASS(gb_bundle,
+
+ TP_PROTO(struct gb_bundle *bundle),
+
+ TP_ARGS(bundle),
+
+ TP_STRUCT__entry(
+ __field(u8, intf_id)
+ __field(u8, id)
+ __field(u8, class)
+ __field(size_t, num_cports)
+ ),
+
+ TP_fast_assign(
+ __entry->intf_id = bundle->intf->interface_id;
+ __entry->id = bundle->id;
+ __entry->class = bundle->class;
+ __entry->num_cports = bundle->num_cports;
+ ),
+
+ TP_printk("intf_id=0x%02x id=%02x class=0x%02x num_cports=%zu",
+ __entry->intf_id, __entry->id, __entry->class,
+ __entry->num_cports)
+);
+
+#define DEFINE_BUNDLE_EVENT(name) \
+ DEFINE_EVENT(gb_bundle, name, \
+ TP_PROTO(struct gb_bundle *bundle), \
+ TP_ARGS(bundle))
+
+/*
+ * Occurs after a new bundle is successfully created.
+ */
+DEFINE_BUNDLE_EVENT(gb_bundle_create);
+
+/*
+ * Occurs when the last reference to a bundle has been dropped,
+ * before its resources are freed.
+ */
+DEFINE_BUNDLE_EVENT(gb_bundle_release);
+
+/*
+ * Occurs when a bundle is added to an interface when the interface
+ * is enabled.
+ */
+DEFINE_BUNDLE_EVENT(gb_bundle_add);
+
+/*
+ * Occurs when a registered bundle gets destroyed, normally at the
+ * time an interface is disabled.
+ */
+DEFINE_BUNDLE_EVENT(gb_bundle_destroy);
+
+#undef DEFINE_BUNDLE_EVENT
+
+DECLARE_EVENT_CLASS(gb_interface,
+
+ TP_PROTO(struct gb_interface *intf),
+
+ TP_ARGS(intf),
+
+ TP_STRUCT__entry(
+ __field(u8, module_id)
+ __field(u8, id) /* Interface id */
+ __field(u8, device_id)
+ __field(int, disconnected) /* bool */
+ __field(int, ejected) /* bool */
+ __field(int, active) /* bool */
+ __field(int, enabled) /* bool */
+ __field(int, mode_switch) /* bool */
+ ),
+
+ TP_fast_assign(
+ __entry->module_id = intf->module->module_id;
+ __entry->id = intf->interface_id;
+ __entry->device_id = intf->device_id;
+ __entry->disconnected = intf->disconnected;
+ __entry->ejected = intf->ejected;
+ __entry->active = intf->active;
+ __entry->enabled = intf->enabled;
+ __entry->mode_switch = intf->mode_switch;
+ ),
+
+ TP_printk("intf_id=%hhu device_id=%hhu module_id=%hhu D=%d J=%d A=%d E=%d M=%d",
+ __entry->id, __entry->device_id, __entry->module_id,
+ __entry->disconnected, __entry->ejected, __entry->active,
+ __entry->enabled, __entry->mode_switch)
+);
+
+#define DEFINE_INTERFACE_EVENT(name) \
+ DEFINE_EVENT(gb_interface, name, \
+ TP_PROTO(struct gb_interface *intf), \
+ TP_ARGS(intf))
+
+/*
+ * Occurs after a new interface is successfully created.
+ */
+DEFINE_INTERFACE_EVENT(gb_interface_create);
+
+/*
+ * Occurs after the last reference to an interface has been dropped.
+ */
+DEFINE_INTERFACE_EVENT(gb_interface_release);
+
+/*
+ * Occurs after an interface been registerd.
+ */
+DEFINE_INTERFACE_EVENT(gb_interface_add);
+
+/*
+ * Occurs when a registered interface gets deregisterd.
+ */
+DEFINE_INTERFACE_EVENT(gb_interface_del);
+
+/*
+ * Occurs when a registered interface has been successfully
+ * activated.
+ */
+DEFINE_INTERFACE_EVENT(gb_interface_activate);
+
+/*
+ * Occurs when an activated interface is being deactivated.
+ */
+DEFINE_INTERFACE_EVENT(gb_interface_deactivate);
+
+/*
+ * Occurs when an interface has been successfully enabled.
+ */
+DEFINE_INTERFACE_EVENT(gb_interface_enable);
+
+/*
+ * Occurs when an enabled interface is being disabled.
+ */
+DEFINE_INTERFACE_EVENT(gb_interface_disable);
+
+#undef DEFINE_INTERFACE_EVENT
+
+DECLARE_EVENT_CLASS(gb_module,
+
+ TP_PROTO(struct gb_module *module),
+
+ TP_ARGS(module),
+
+ TP_STRUCT__entry(
+ __field(int, hd_bus_id)
+ __field(u8, module_id)
+ __field(size_t, num_interfaces)
+ __field(int, disconnected) /* bool */
+ ),
+
+ TP_fast_assign(
+ __entry->hd_bus_id = module->hd->bus_id;
+ __entry->module_id = module->module_id;
+ __entry->num_interfaces = module->num_interfaces;
+ __entry->disconnected = module->disconnected;
+ ),
+
+ TP_printk("hd_bus_id=%d module_id=%hhu num_interfaces=%zu disconnected=%d",
+ __entry->hd_bus_id, __entry->module_id,
+ __entry->num_interfaces, __entry->disconnected)
+);
+
+#define DEFINE_MODULE_EVENT(name) \
+ DEFINE_EVENT(gb_module, name, \
+ TP_PROTO(struct gb_module *module), \
+ TP_ARGS(module))
+
+/*
+ * Occurs after a new module is successfully created, before
+ * creating any of its interfaces.
+ */
+DEFINE_MODULE_EVENT(gb_module_create);
+
+/*
+ * Occurs after the last reference to a module has been dropped.
+ */
+DEFINE_MODULE_EVENT(gb_module_release);
+
+/*
+ * Occurs after a module is successfully created, before registering
+ * any of its interfaces.
+ */
+DEFINE_MODULE_EVENT(gb_module_add);
+
+/*
+ * Occurs when a module is deleted, before deregistering its
+ * interfaces.
+ */
+DEFINE_MODULE_EVENT(gb_module_del);
+
+#undef DEFINE_MODULE_EVENT
+
+DECLARE_EVENT_CLASS(gb_host_device,
+
+ TP_PROTO(struct gb_host_device *hd),
+
+ TP_ARGS(hd),
+
+ TP_STRUCT__entry(
+ __field(int, bus_id)
+ __field(size_t, num_cports)
+ __field(size_t, buffer_size_max)
+ ),
+
+ TP_fast_assign(
+ __entry->bus_id = hd->bus_id;
+ __entry->num_cports = hd->num_cports;
+ __entry->buffer_size_max = hd->buffer_size_max;
+ ),
+
+ TP_printk("bus_id=%d num_cports=%zu mtu=%zu",
+ __entry->bus_id, __entry->num_cports,
+ __entry->buffer_size_max)
+);
+
+#define DEFINE_HD_EVENT(name) \
+ DEFINE_EVENT(gb_host_device, name, \
+ TP_PROTO(struct gb_host_device *hd), \
+ TP_ARGS(hd))
+
+/*
+ * Occurs after a new host device is successfully created, before
+ * its SVC has been set up.
+ */
+DEFINE_HD_EVENT(gb_hd_create);
+
+/*
+ * Occurs after the last reference to a host device has been
+ * dropped.
+ */
+DEFINE_HD_EVENT(gb_hd_release);
+
+/*
+ * Occurs after a new host device has been added, after the
+ * connection to its SVC has been enabled.
+ */
+DEFINE_HD_EVENT(gb_hd_add);
+
+/*
+ * Occurs when a host device is being disconnected from the AP USB
+ * host controller.
+ */
+DEFINE_HD_EVENT(gb_hd_del);
+
+/*
+ * Occurs when a host device has passed received data to the Greybus
+ * core, after it has been determined it is destined for a valid
+ * CPort.
+ */
+DEFINE_HD_EVENT(gb_hd_in);
+
+#undef DEFINE_HD_EVENT
+
+/*
+ * Occurs on a TimeSync synchronization event or a TimeSync ping event.
+ */
+TRACE_EVENT(gb_timesync_irq,
+
+ TP_PROTO(u8 ping, u8 strobe, u8 count, u64 frame_time),
+
+ TP_ARGS(ping, strobe, count, frame_time),
+
+ TP_STRUCT__entry(
+ __field(u8, ping)
+ __field(u8, strobe)
+ __field(u8, count)
+ __field(u64, frame_time)
+ ),
+
+ TP_fast_assign(
+ __entry->ping = ping;
+ __entry->strobe = strobe;
+ __entry->count = count;
+ __entry->frame_time = frame_time;
+ ),
+
+ TP_printk("%s %d/%d frame-time %llu\n",
+ __entry->ping ? "ping" : "strobe", __entry->strobe,
+ __entry->count, __entry->frame_time)
+);
+
+#endif /* _TRACE_GREYBUS_H */
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+
+/*
+ * TRACE_INCLUDE_FILE is not needed if the filename and TRACE_SYSTEM are equal
+ */
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE greybus_trace
+#include <trace/define_trace.h>
+
diff --git a/drivers/staging/greybus/hd.c b/drivers/staging/greybus/hd.c
new file mode 100644
index 000000000000..185ae3fa10fd
--- /dev/null
+++ b/drivers/staging/greybus/hd.c
@@ -0,0 +1,257 @@
+/*
+ * Greybus Host Device
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "greybus.h"
+#include "greybus_trace.h"
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(gb_hd_create);
+EXPORT_TRACEPOINT_SYMBOL_GPL(gb_hd_release);
+EXPORT_TRACEPOINT_SYMBOL_GPL(gb_hd_add);
+EXPORT_TRACEPOINT_SYMBOL_GPL(gb_hd_del);
+EXPORT_TRACEPOINT_SYMBOL_GPL(gb_hd_in);
+EXPORT_TRACEPOINT_SYMBOL_GPL(gb_message_submit);
+
+static struct ida gb_hd_bus_id_map;
+
+int gb_hd_output(struct gb_host_device *hd, void *req, u16 size, u8 cmd,
+ bool async)
+{
+ if (!hd || !hd->driver || !hd->driver->output)
+ return -EINVAL;
+ return hd->driver->output(hd, req, size, cmd, async);
+}
+EXPORT_SYMBOL_GPL(gb_hd_output);
+
+static ssize_t bus_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_host_device *hd = to_gb_host_device(dev);
+
+ return sprintf(buf, "%d\n", hd->bus_id);
+}
+static DEVICE_ATTR_RO(bus_id);
+
+static struct attribute *bus_attrs[] = {
+ &dev_attr_bus_id.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(bus);
+
+int gb_hd_cport_reserve(struct gb_host_device *hd, u16 cport_id)
+{
+ struct ida *id_map = &hd->cport_id_map;
+ int ret;
+
+ ret = ida_simple_get(id_map, cport_id, cport_id + 1, GFP_KERNEL);
+ if (ret < 0) {
+ dev_err(&hd->dev, "failed to reserve cport %u\n", cport_id);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gb_hd_cport_reserve);
+
+void gb_hd_cport_release_reserved(struct gb_host_device *hd, u16 cport_id)
+{
+ struct ida *id_map = &hd->cport_id_map;
+
+ ida_simple_remove(id_map, cport_id);
+}
+EXPORT_SYMBOL_GPL(gb_hd_cport_release_reserved);
+
+/* Locking: Caller guarantees serialisation */
+int gb_hd_cport_allocate(struct gb_host_device *hd, int cport_id,
+ unsigned long flags)
+{
+ struct ida *id_map = &hd->cport_id_map;
+ int ida_start, ida_end;
+
+ if (hd->driver->cport_allocate)
+ return hd->driver->cport_allocate(hd, cport_id, flags);
+
+ if (cport_id < 0) {
+ ida_start = 0;
+ ida_end = hd->num_cports;
+ } else if (cport_id < hd->num_cports) {
+ ida_start = cport_id;
+ ida_end = cport_id + 1;
+ } else {
+ dev_err(&hd->dev, "cport %d not available\n", cport_id);
+ return -EINVAL;
+ }
+
+ return ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL);
+}
+
+/* Locking: Caller guarantees serialisation */
+void gb_hd_cport_release(struct gb_host_device *hd, u16 cport_id)
+{
+ if (hd->driver->cport_release) {
+ hd->driver->cport_release(hd, cport_id);
+ return;
+ }
+
+ ida_simple_remove(&hd->cport_id_map, cport_id);
+}
+
+static void gb_hd_release(struct device *dev)
+{
+ struct gb_host_device *hd = to_gb_host_device(dev);
+
+ trace_gb_hd_release(hd);
+
+ if (hd->svc)
+ gb_svc_put(hd->svc);
+ ida_simple_remove(&gb_hd_bus_id_map, hd->bus_id);
+ ida_destroy(&hd->cport_id_map);
+ kfree(hd);
+}
+
+struct device_type greybus_hd_type = {
+ .name = "greybus_host_device",
+ .release = gb_hd_release,
+};
+
+struct gb_host_device *gb_hd_create(struct gb_hd_driver *driver,
+ struct device *parent,
+ size_t buffer_size_max,
+ size_t num_cports)
+{
+ struct gb_host_device *hd;
+ int ret;
+
+ /*
+ * Validate that the driver implements all of the callbacks
+ * so that we don't have to every time we make them.
+ */
+ if ((!driver->message_send) || (!driver->message_cancel)) {
+ dev_err(parent, "mandatory hd-callbacks missing\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (buffer_size_max < GB_OPERATION_MESSAGE_SIZE_MIN) {
+ dev_err(parent, "greybus host-device buffers too small\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (num_cports == 0 || num_cports > CPORT_ID_MAX + 1) {
+ dev_err(parent, "Invalid number of CPorts: %zu\n", num_cports);
+ return ERR_PTR(-EINVAL);
+ }
+
+ /*
+ * Make sure to never allocate messages larger than what the Greybus
+ * protocol supports.
+ */
+ if (buffer_size_max > GB_OPERATION_MESSAGE_SIZE_MAX) {
+ dev_warn(parent, "limiting buffer size to %u\n",
+ GB_OPERATION_MESSAGE_SIZE_MAX);
+ buffer_size_max = GB_OPERATION_MESSAGE_SIZE_MAX;
+ }
+
+ hd = kzalloc(sizeof(*hd) + driver->hd_priv_size, GFP_KERNEL);
+ if (!hd)
+ return ERR_PTR(-ENOMEM);
+
+ ret = ida_simple_get(&gb_hd_bus_id_map, 1, 0, GFP_KERNEL);
+ if (ret < 0) {
+ kfree(hd);
+ return ERR_PTR(ret);
+ }
+ hd->bus_id = ret;
+
+ hd->driver = driver;
+ INIT_LIST_HEAD(&hd->modules);
+ INIT_LIST_HEAD(&hd->connections);
+ ida_init(&hd->cport_id_map);
+ hd->buffer_size_max = buffer_size_max;
+ hd->num_cports = num_cports;
+
+ hd->dev.parent = parent;
+ hd->dev.bus = &greybus_bus_type;
+ hd->dev.type = &greybus_hd_type;
+ hd->dev.groups = bus_groups;
+ hd->dev.dma_mask = hd->dev.parent->dma_mask;
+ device_initialize(&hd->dev);
+ dev_set_name(&hd->dev, "greybus%d", hd->bus_id);
+
+ trace_gb_hd_create(hd);
+
+ hd->svc = gb_svc_create(hd);
+ if (!hd->svc) {
+ dev_err(&hd->dev, "failed to create svc\n");
+ put_device(&hd->dev);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ return hd;
+}
+EXPORT_SYMBOL_GPL(gb_hd_create);
+
+int gb_hd_add(struct gb_host_device *hd)
+{
+ int ret;
+
+ ret = device_add(&hd->dev);
+ if (ret)
+ return ret;
+
+ ret = gb_svc_add(hd->svc);
+ if (ret) {
+ device_del(&hd->dev);
+ return ret;
+ }
+
+ trace_gb_hd_add(hd);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gb_hd_add);
+
+void gb_hd_del(struct gb_host_device *hd)
+{
+ trace_gb_hd_del(hd);
+
+ /*
+ * Tear down the svc and flush any on-going hotplug processing before
+ * removing the remaining interfaces.
+ */
+ gb_svc_del(hd->svc);
+
+ device_del(&hd->dev);
+}
+EXPORT_SYMBOL_GPL(gb_hd_del);
+
+void gb_hd_shutdown(struct gb_host_device *hd)
+{
+ gb_svc_del(hd->svc);
+}
+EXPORT_SYMBOL_GPL(gb_hd_shutdown);
+
+void gb_hd_put(struct gb_host_device *hd)
+{
+ put_device(&hd->dev);
+}
+EXPORT_SYMBOL_GPL(gb_hd_put);
+
+int __init gb_hd_init(void)
+{
+ ida_init(&gb_hd_bus_id_map);
+
+ return 0;
+}
+
+void gb_hd_exit(void)
+{
+ ida_destroy(&gb_hd_bus_id_map);
+}
diff --git a/drivers/staging/greybus/hd.h b/drivers/staging/greybus/hd.h
new file mode 100644
index 000000000000..c4250cfe595f
--- /dev/null
+++ b/drivers/staging/greybus/hd.h
@@ -0,0 +1,90 @@
+/*
+ * Greybus Host Device
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __HD_H
+#define __HD_H
+
+struct gb_host_device;
+struct gb_message;
+
+struct gb_hd_driver {
+ size_t hd_priv_size;
+
+ int (*cport_allocate)(struct gb_host_device *hd, int cport_id,
+ unsigned long flags);
+ void (*cport_release)(struct gb_host_device *hd, u16 cport_id);
+ int (*cport_enable)(struct gb_host_device *hd, u16 cport_id,
+ unsigned long flags);
+ int (*cport_disable)(struct gb_host_device *hd, u16 cport_id);
+ int (*cport_connected)(struct gb_host_device *hd, u16 cport_id);
+ int (*cport_flush)(struct gb_host_device *hd, u16 cport_id);
+ int (*cport_shutdown)(struct gb_host_device *hd, u16 cport_id,
+ u8 phase, unsigned int timeout);
+ int (*cport_quiesce)(struct gb_host_device *hd, u16 cport_id,
+ size_t peer_space, unsigned int timeout);
+ int (*cport_clear)(struct gb_host_device *hd, u16 cport_id);
+
+ int (*message_send)(struct gb_host_device *hd, u16 dest_cport_id,
+ struct gb_message *message, gfp_t gfp_mask);
+ void (*message_cancel)(struct gb_message *message);
+ int (*latency_tag_enable)(struct gb_host_device *hd, u16 cport_id);
+ int (*latency_tag_disable)(struct gb_host_device *hd, u16 cport_id);
+ int (*output)(struct gb_host_device *hd, void *req, u16 size, u8 cmd,
+ bool async);
+ int (*timesync_enable)(struct gb_host_device *hd, u8 count,
+ u64 frame_time, u32 strobe_delay, u32 refclk);
+ int (*timesync_disable)(struct gb_host_device *hd);
+ int (*timesync_authoritative)(struct gb_host_device *hd,
+ u64 *frame_time);
+ int (*timesync_get_last_event)(struct gb_host_device *hd,
+ u64 *frame_time);
+};
+
+struct gb_host_device {
+ struct device dev;
+ int bus_id;
+ const struct gb_hd_driver *driver;
+
+ struct list_head modules;
+ struct list_head connections;
+ struct ida cport_id_map;
+
+ /* Number of CPorts supported by the UniPro IP */
+ size_t num_cports;
+
+ /* Host device buffer constraints */
+ size_t buffer_size_max;
+
+ struct gb_svc *svc;
+ /* Private data for the host driver */
+ unsigned long hd_priv[0] __aligned(sizeof(s64));
+};
+#define to_gb_host_device(d) container_of(d, struct gb_host_device, dev)
+
+int gb_hd_cport_reserve(struct gb_host_device *hd, u16 cport_id);
+void gb_hd_cport_release_reserved(struct gb_host_device *hd, u16 cport_id);
+int gb_hd_cport_allocate(struct gb_host_device *hd, int cport_id,
+ unsigned long flags);
+void gb_hd_cport_release(struct gb_host_device *hd, u16 cport_id);
+
+struct gb_host_device *gb_hd_create(struct gb_hd_driver *driver,
+ struct device *parent,
+ size_t buffer_size_max,
+ size_t num_cports);
+int gb_hd_add(struct gb_host_device *hd);
+void gb_hd_del(struct gb_host_device *hd);
+void gb_hd_shutdown(struct gb_host_device *hd);
+void gb_hd_put(struct gb_host_device *hd);
+int gb_hd_output(struct gb_host_device *hd, void *req, u16 size, u8 cmd,
+ bool in_irq);
+
+int gb_hd_init(void);
+void gb_hd_exit(void);
+
+#endif /* __HD_H */
diff --git a/drivers/staging/greybus/hid.c b/drivers/staging/greybus/hid.c
new file mode 100644
index 000000000000..730d746fc4c2
--- /dev/null
+++ b/drivers/staging/greybus/hid.c
@@ -0,0 +1,536 @@
+/*
+ * HID class driver for the Greybus.
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/bitops.h>
+#include <linux/hid.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+
+#include "greybus.h"
+
+/* Greybus HID device's structure */
+struct gb_hid {
+ struct gb_bundle *bundle;
+ struct gb_connection *connection;
+
+ struct hid_device *hid;
+ struct gb_hid_desc_response hdesc;
+
+ unsigned long flags;
+#define GB_HID_STARTED 0x01
+#define GB_HID_READ_PENDING 0x04
+
+ unsigned int bufsize;
+ char *inbuf;
+};
+
+static DEFINE_MUTEX(gb_hid_open_mutex);
+
+/* Routines to get controller's information over greybus */
+
+/* Operations performed on greybus */
+static int gb_hid_get_desc(struct gb_hid *ghid)
+{
+ return gb_operation_sync(ghid->connection, GB_HID_TYPE_GET_DESC, NULL,
+ 0, &ghid->hdesc, sizeof(ghid->hdesc));
+}
+
+static int gb_hid_get_report_desc(struct gb_hid *ghid, char *rdesc)
+{
+ int ret;
+
+ ret = gb_pm_runtime_get_sync(ghid->bundle);
+ if (ret)
+ return ret;
+
+ ret = gb_operation_sync(ghid->connection, GB_HID_TYPE_GET_REPORT_DESC,
+ NULL, 0, rdesc,
+ le16_to_cpu(ghid->hdesc.wReportDescLength));
+
+ gb_pm_runtime_put_autosuspend(ghid->bundle);
+
+ return ret;
+}
+
+static int gb_hid_set_power(struct gb_hid *ghid, int type)
+{
+ int ret;
+
+ ret = gb_pm_runtime_get_sync(ghid->bundle);
+ if (ret)
+ return ret;
+
+ ret = gb_operation_sync(ghid->connection, type, NULL, 0, NULL, 0);
+
+ gb_pm_runtime_put_autosuspend(ghid->bundle);
+
+ return ret;
+}
+
+static int gb_hid_get_report(struct gb_hid *ghid, u8 report_type, u8 report_id,
+ unsigned char *buf, int len)
+{
+ struct gb_hid_get_report_request request;
+ int ret;
+
+ ret = gb_pm_runtime_get_sync(ghid->bundle);
+ if (ret)
+ return ret;
+
+ request.report_type = report_type;
+ request.report_id = report_id;
+
+ ret = gb_operation_sync(ghid->connection, GB_HID_TYPE_GET_REPORT,
+ &request, sizeof(request), buf, len);
+
+ gb_pm_runtime_put_autosuspend(ghid->bundle);
+
+ return ret;
+}
+
+static int gb_hid_set_report(struct gb_hid *ghid, u8 report_type, u8 report_id,
+ unsigned char *buf, int len)
+{
+ struct gb_hid_set_report_request *request;
+ struct gb_operation *operation;
+ int ret, size = sizeof(*request) + len - 1;
+
+ ret = gb_pm_runtime_get_sync(ghid->bundle);
+ if (ret)
+ return ret;
+
+ operation = gb_operation_create(ghid->connection,
+ GB_HID_TYPE_SET_REPORT, size, 0,
+ GFP_KERNEL);
+ if (!operation) {
+ gb_pm_runtime_put_autosuspend(ghid->bundle);
+ return -ENOMEM;
+ }
+
+ request = operation->request->payload;
+ request->report_type = report_type;
+ request->report_id = report_id;
+ memcpy(request->report, buf, len);
+
+ ret = gb_operation_request_send_sync(operation);
+ if (ret) {
+ dev_err(&operation->connection->bundle->dev,
+ "failed to set report: %d\n", ret);
+ } else {
+ ret = len;
+ }
+
+ gb_operation_put(operation);
+ gb_pm_runtime_put_autosuspend(ghid->bundle);
+
+ return ret;
+}
+
+static int gb_hid_request_handler(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct gb_hid *ghid = gb_connection_get_data(connection);
+ struct gb_hid_input_report_request *request = op->request->payload;
+
+ if (op->type != GB_HID_TYPE_IRQ_EVENT) {
+ dev_err(&connection->bundle->dev,
+ "unsupported unsolicited request\n");
+ return -EINVAL;
+ }
+
+ if (test_bit(GB_HID_STARTED, &ghid->flags))
+ hid_input_report(ghid->hid, HID_INPUT_REPORT,
+ request->report, op->request->payload_size, 1);
+
+ return 0;
+}
+
+static int gb_hid_report_len(struct hid_report *report)
+{
+ return ((report->size - 1) >> 3) + 1 +
+ report->device->report_enum[report->type].numbered;
+}
+
+static void gb_hid_find_max_report(struct hid_device *hid, unsigned int type,
+ unsigned int *max)
+{
+ struct hid_report *report;
+ unsigned int size;
+
+ list_for_each_entry(report, &hid->report_enum[type].report_list, list) {
+ size = gb_hid_report_len(report);
+ if (*max < size)
+ *max = size;
+ }
+}
+
+static void gb_hid_free_buffers(struct gb_hid *ghid)
+{
+ kfree(ghid->inbuf);
+ ghid->inbuf = NULL;
+ ghid->bufsize = 0;
+}
+
+static int gb_hid_alloc_buffers(struct gb_hid *ghid, size_t bufsize)
+{
+ ghid->inbuf = kzalloc(bufsize, GFP_KERNEL);
+ if (!ghid->inbuf)
+ return -ENOMEM;
+
+ ghid->bufsize = bufsize;
+
+ return 0;
+}
+
+/* Routines dealing with reports */
+static void gb_hid_init_report(struct gb_hid *ghid, struct hid_report *report)
+{
+ unsigned int size;
+
+ size = gb_hid_report_len(report);
+ if (gb_hid_get_report(ghid, report->type, report->id, ghid->inbuf,
+ size))
+ return;
+
+ /*
+ * hid->driver_lock is held as we are in probe function,
+ * we just need to setup the input fields, so using
+ * hid_report_raw_event is safe.
+ */
+ hid_report_raw_event(ghid->hid, report->type, ghid->inbuf, size, 1);
+}
+
+static void gb_hid_init_reports(struct gb_hid *ghid)
+{
+ struct hid_device *hid = ghid->hid;
+ struct hid_report *report;
+
+ list_for_each_entry(report,
+ &hid->report_enum[HID_INPUT_REPORT].report_list, list)
+ gb_hid_init_report(ghid, report);
+
+ list_for_each_entry(report,
+ &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
+ gb_hid_init_report(ghid, report);
+}
+
+static int __gb_hid_get_raw_report(struct hid_device *hid,
+ unsigned char report_number, __u8 *buf, size_t count,
+ unsigned char report_type)
+{
+ struct gb_hid *ghid = hid->driver_data;
+ int ret;
+
+ if (report_type == HID_OUTPUT_REPORT)
+ return -EINVAL;
+
+ ret = gb_hid_get_report(ghid, report_type, report_number, buf, count);
+ if (!ret)
+ ret = count;
+
+ return ret;
+}
+
+static int __gb_hid_output_raw_report(struct hid_device *hid, __u8 *buf,
+ size_t len, unsigned char report_type)
+{
+ struct gb_hid *ghid = hid->driver_data;
+ int report_id = buf[0];
+ int ret;
+
+ if (report_type == HID_INPUT_REPORT)
+ return -EINVAL;
+
+ if (report_id) {
+ buf++;
+ len--;
+ }
+
+ ret = gb_hid_set_report(ghid, report_type, report_id, buf, len);
+ if (report_id && ret >= 0)
+ ret++; /* add report_id to the number of transfered bytes */
+
+ return 0;
+}
+
+static int gb_hid_raw_request(struct hid_device *hid, unsigned char reportnum,
+ __u8 *buf, size_t len, unsigned char rtype,
+ int reqtype)
+{
+ switch (reqtype) {
+ case HID_REQ_GET_REPORT:
+ return __gb_hid_get_raw_report(hid, reportnum, buf, len, rtype);
+ case HID_REQ_SET_REPORT:
+ if (buf[0] != reportnum)
+ return -EINVAL;
+ return __gb_hid_output_raw_report(hid, buf, len, rtype);
+ default:
+ return -EIO;
+ }
+}
+
+/* HID Callbacks */
+static int gb_hid_parse(struct hid_device *hid)
+{
+ struct gb_hid *ghid = hid->driver_data;
+ unsigned int rsize;
+ char *rdesc;
+ int ret;
+
+ rsize = le16_to_cpu(ghid->hdesc.wReportDescLength);
+ if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
+ dbg_hid("weird size of report descriptor (%u)\n", rsize);
+ return -EINVAL;
+ }
+
+ rdesc = kzalloc(rsize, GFP_KERNEL);
+ if (!rdesc) {
+ dbg_hid("couldn't allocate rdesc memory\n");
+ return -ENOMEM;
+ }
+
+ ret = gb_hid_get_report_desc(ghid, rdesc);
+ if (ret) {
+ hid_err(hid, "reading report descriptor failed\n");
+ goto free_rdesc;
+ }
+
+ ret = hid_parse_report(hid, rdesc, rsize);
+ if (ret)
+ dbg_hid("parsing report descriptor failed\n");
+
+free_rdesc:
+ kfree(rdesc);
+
+ return ret;
+}
+
+static int gb_hid_start(struct hid_device *hid)
+{
+ struct gb_hid *ghid = hid->driver_data;
+ unsigned int bufsize = HID_MIN_BUFFER_SIZE;
+ int ret;
+
+ gb_hid_find_max_report(hid, HID_INPUT_REPORT, &bufsize);
+ gb_hid_find_max_report(hid, HID_OUTPUT_REPORT, &bufsize);
+ gb_hid_find_max_report(hid, HID_FEATURE_REPORT, &bufsize);
+
+ if (bufsize > HID_MAX_BUFFER_SIZE)
+ bufsize = HID_MAX_BUFFER_SIZE;
+
+ ret = gb_hid_alloc_buffers(ghid, bufsize);
+ if (ret)
+ return ret;
+
+ if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS))
+ gb_hid_init_reports(ghid);
+
+ return 0;
+}
+
+static void gb_hid_stop(struct hid_device *hid)
+{
+ struct gb_hid *ghid = hid->driver_data;
+
+ gb_hid_free_buffers(ghid);
+}
+
+static int gb_hid_open(struct hid_device *hid)
+{
+ struct gb_hid *ghid = hid->driver_data;
+ int ret = 0;
+
+ mutex_lock(&gb_hid_open_mutex);
+ if (!hid->open++) {
+ ret = gb_hid_set_power(ghid, GB_HID_TYPE_PWR_ON);
+ if (ret < 0)
+ hid->open--;
+ else
+ set_bit(GB_HID_STARTED, &ghid->flags);
+ }
+ mutex_unlock(&gb_hid_open_mutex);
+
+ return ret;
+}
+
+static void gb_hid_close(struct hid_device *hid)
+{
+ struct gb_hid *ghid = hid->driver_data;
+ int ret;
+
+ /*
+ * Protecting hid->open to make sure we don't restart data acquistion
+ * due to a resumption we no longer care about..
+ */
+ mutex_lock(&gb_hid_open_mutex);
+ if (!--hid->open) {
+ clear_bit(GB_HID_STARTED, &ghid->flags);
+
+ /* Save some power */
+ ret = gb_hid_set_power(ghid, GB_HID_TYPE_PWR_OFF);
+ if (ret)
+ dev_err(&ghid->connection->bundle->dev,
+ "failed to power off (%d)\n", ret);
+ }
+ mutex_unlock(&gb_hid_open_mutex);
+}
+
+static int gb_hid_power(struct hid_device *hid, int lvl)
+{
+ struct gb_hid *ghid = hid->driver_data;
+
+ switch (lvl) {
+ case PM_HINT_FULLON:
+ return gb_hid_set_power(ghid, GB_HID_TYPE_PWR_ON);
+ case PM_HINT_NORMAL:
+ return gb_hid_set_power(ghid, GB_HID_TYPE_PWR_OFF);
+ }
+
+ return 0;
+}
+
+/* HID structure to pass callbacks */
+static struct hid_ll_driver gb_hid_ll_driver = {
+ .parse = gb_hid_parse,
+ .start = gb_hid_start,
+ .stop = gb_hid_stop,
+ .open = gb_hid_open,
+ .close = gb_hid_close,
+ .power = gb_hid_power,
+ .raw_request = gb_hid_raw_request,
+};
+
+static int gb_hid_init(struct gb_hid *ghid)
+{
+ struct hid_device *hid = ghid->hid;
+ int ret;
+
+ ret = gb_hid_get_desc(ghid);
+ if (ret)
+ return ret;
+
+ hid->version = le16_to_cpu(ghid->hdesc.bcdHID);
+ hid->vendor = le16_to_cpu(ghid->hdesc.wVendorID);
+ hid->product = le16_to_cpu(ghid->hdesc.wProductID);
+ hid->country = ghid->hdesc.bCountryCode;
+
+ hid->driver_data = ghid;
+ hid->ll_driver = &gb_hid_ll_driver;
+ hid->dev.parent = &ghid->connection->bundle->dev;
+// hid->bus = BUS_GREYBUS; /* Need a bustype for GREYBUS in <linux/input.h> */
+
+ /* Set HID device's name */
+ snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X",
+ dev_name(&ghid->connection->bundle->dev),
+ hid->vendor, hid->product);
+
+ return 0;
+}
+
+static int gb_hid_probe(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id)
+{
+ struct greybus_descriptor_cport *cport_desc;
+ struct gb_connection *connection;
+ struct hid_device *hid;
+ struct gb_hid *ghid;
+ int ret;
+
+ if (bundle->num_cports != 1)
+ return -ENODEV;
+
+ cport_desc = &bundle->cport_desc[0];
+ if (cport_desc->protocol_id != GREYBUS_PROTOCOL_HID)
+ return -ENODEV;
+
+ ghid = kzalloc(sizeof(*ghid), GFP_KERNEL);
+ if (!ghid)
+ return -ENOMEM;
+
+ connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
+ gb_hid_request_handler);
+ if (IS_ERR(connection)) {
+ ret = PTR_ERR(connection);
+ goto err_free_ghid;
+ }
+
+ gb_connection_set_data(connection, ghid);
+ ghid->connection = connection;
+
+ hid = hid_allocate_device();
+ if (IS_ERR(hid)) {
+ ret = PTR_ERR(hid);
+ goto err_connection_destroy;
+ }
+
+ ghid->hid = hid;
+ ghid->bundle = bundle;
+
+ greybus_set_drvdata(bundle, ghid);
+
+ ret = gb_connection_enable(connection);
+ if (ret)
+ goto err_destroy_hid;
+
+ ret = gb_hid_init(ghid);
+ if (ret)
+ goto err_connection_disable;
+
+ ret = hid_add_device(hid);
+ if (ret) {
+ hid_err(hid, "can't add hid device: %d\n", ret);
+ goto err_connection_disable;
+ }
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return 0;
+
+err_connection_disable:
+ gb_connection_disable(connection);
+err_destroy_hid:
+ hid_destroy_device(hid);
+err_connection_destroy:
+ gb_connection_destroy(connection);
+err_free_ghid:
+ kfree(ghid);
+
+ return ret;
+}
+
+static void gb_hid_disconnect(struct gb_bundle *bundle)
+{
+ struct gb_hid *ghid = greybus_get_drvdata(bundle);
+
+ if (gb_pm_runtime_get_sync(bundle))
+ gb_pm_runtime_get_noresume(bundle);
+
+ hid_destroy_device(ghid->hid);
+ gb_connection_disable(ghid->connection);
+ gb_connection_destroy(ghid->connection);
+ kfree(ghid);
+}
+
+static const struct greybus_bundle_id gb_hid_id_table[] = {
+ { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_HID) },
+ { }
+};
+MODULE_DEVICE_TABLE(greybus, gb_hid_id_table);
+
+static struct greybus_driver gb_hid_driver = {
+ .name = "hid",
+ .probe = gb_hid_probe,
+ .disconnect = gb_hid_disconnect,
+ .id_table = gb_hid_id_table,
+};
+module_greybus_driver(gb_hid_driver);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/i2c.c b/drivers/staging/greybus/i2c.c
new file mode 100644
index 000000000000..c2a50087000c
--- /dev/null
+++ b/drivers/staging/greybus/i2c.c
@@ -0,0 +1,343 @@
+/*
+ * I2C bridge driver for the Greybus "generic" I2C module.
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+
+#include "greybus.h"
+#include "gbphy.h"
+
+struct gb_i2c_device {
+ struct gb_connection *connection;
+ struct gbphy_device *gbphy_dev;
+
+ u32 functionality;
+
+ struct i2c_adapter adapter;
+};
+
+/*
+ * Map Greybus i2c functionality bits into Linux ones
+ */
+static u32 gb_i2c_functionality_map(u32 gb_i2c_functionality)
+{
+ return gb_i2c_functionality; /* All bits the same for now */
+}
+
+static int gb_i2c_functionality_operation(struct gb_i2c_device *gb_i2c_dev)
+{
+ struct gb_i2c_functionality_response response;
+ u32 functionality;
+ int ret;
+
+ ret = gb_operation_sync(gb_i2c_dev->connection,
+ GB_I2C_TYPE_FUNCTIONALITY,
+ NULL, 0, &response, sizeof(response));
+ if (ret)
+ return ret;
+
+ functionality = le32_to_cpu(response.functionality);
+ gb_i2c_dev->functionality = gb_i2c_functionality_map(functionality);
+
+ return 0;
+}
+
+/*
+ * Map Linux i2c_msg flags into Greybus i2c transfer op flags.
+ */
+static u16 gb_i2c_transfer_op_flags_map(u16 flags)
+{
+ return flags; /* All flags the same for now */
+}
+
+static void
+gb_i2c_fill_transfer_op(struct gb_i2c_transfer_op *op, struct i2c_msg *msg)
+{
+ u16 flags = gb_i2c_transfer_op_flags_map(msg->flags);
+
+ op->addr = cpu_to_le16(msg->addr);
+ op->flags = cpu_to_le16(flags);
+ op->size = cpu_to_le16(msg->len);
+}
+
+static struct gb_operation *
+gb_i2c_operation_create(struct gb_connection *connection,
+ struct i2c_msg *msgs, u32 msg_count)
+{
+ struct gb_i2c_device *gb_i2c_dev = gb_connection_get_data(connection);
+ struct gb_i2c_transfer_request *request;
+ struct gb_operation *operation;
+ struct gb_i2c_transfer_op *op;
+ struct i2c_msg *msg;
+ u32 data_out_size = 0;
+ u32 data_in_size = 0;
+ size_t request_size;
+ void *data;
+ u16 op_count;
+ u32 i;
+
+ if (msg_count > (u32)U16_MAX) {
+ dev_err(&gb_i2c_dev->gbphy_dev->dev, "msg_count (%u) too big\n",
+ msg_count);
+ return NULL;
+ }
+ op_count = (u16)msg_count;
+
+ /*
+ * In addition to space for all message descriptors we need
+ * to have enough to hold all outbound message data.
+ */
+ msg = msgs;
+ for (i = 0; i < msg_count; i++, msg++)
+ if (msg->flags & I2C_M_RD)
+ data_in_size += (u32)msg->len;
+ else
+ data_out_size += (u32)msg->len;
+
+ request_size = sizeof(*request);
+ request_size += msg_count * sizeof(*op);
+ request_size += data_out_size;
+
+ /* Response consists only of incoming data */
+ operation = gb_operation_create(connection, GB_I2C_TYPE_TRANSFER,
+ request_size, data_in_size, GFP_KERNEL);
+ if (!operation)
+ return NULL;
+
+ request = operation->request->payload;
+ request->op_count = cpu_to_le16(op_count);
+ /* Fill in the ops array */
+ op = &request->ops[0];
+ msg = msgs;
+ for (i = 0; i < msg_count; i++)
+ gb_i2c_fill_transfer_op(op++, msg++);
+
+ if (!data_out_size)
+ return operation;
+
+ /* Copy over the outgoing data; it starts after the last op */
+ data = op;
+ msg = msgs;
+ for (i = 0; i < msg_count; i++) {
+ if (!(msg->flags & I2C_M_RD)) {
+ memcpy(data, msg->buf, msg->len);
+ data += msg->len;
+ }
+ msg++;
+ }
+
+ return operation;
+}
+
+static void gb_i2c_decode_response(struct i2c_msg *msgs, u32 msg_count,
+ struct gb_i2c_transfer_response *response)
+{
+ struct i2c_msg *msg = msgs;
+ u8 *data;
+ u32 i;
+
+ if (!response)
+ return;
+ data = response->data;
+ for (i = 0; i < msg_count; i++) {
+ if (msg->flags & I2C_M_RD) {
+ memcpy(msg->buf, data, msg->len);
+ data += msg->len;
+ }
+ msg++;
+ }
+}
+
+/*
+ * Some i2c transfer operations return results that are expected.
+ */
+static bool gb_i2c_expected_transfer_error(int errno)
+{
+ return errno == -EAGAIN || errno == -ENODEV;
+}
+
+static int gb_i2c_transfer_operation(struct gb_i2c_device *gb_i2c_dev,
+ struct i2c_msg *msgs, u32 msg_count)
+{
+ struct gb_connection *connection = gb_i2c_dev->connection;
+ struct device *dev = &gb_i2c_dev->gbphy_dev->dev;
+ struct gb_operation *operation;
+ int ret;
+
+ operation = gb_i2c_operation_create(connection, msgs, msg_count);
+ if (!operation)
+ return -ENOMEM;
+
+ ret = gbphy_runtime_get_sync(gb_i2c_dev->gbphy_dev);
+ if (ret)
+ goto exit_operation_put;
+
+ ret = gb_operation_request_send_sync(operation);
+ if (!ret) {
+ struct gb_i2c_transfer_response *response;
+
+ response = operation->response->payload;
+ gb_i2c_decode_response(msgs, msg_count, response);
+ ret = msg_count;
+ } else if (!gb_i2c_expected_transfer_error(ret)) {
+ dev_err(dev, "transfer operation failed (%d)\n", ret);
+ }
+
+ gbphy_runtime_put_autosuspend(gb_i2c_dev->gbphy_dev);
+
+exit_operation_put:
+ gb_operation_put(operation);
+
+ return ret;
+}
+
+static int gb_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int msg_count)
+{
+ struct gb_i2c_device *gb_i2c_dev;
+
+ gb_i2c_dev = i2c_get_adapdata(adap);
+
+ return gb_i2c_transfer_operation(gb_i2c_dev, msgs, msg_count);
+}
+
+#if 0
+/* Later */
+static int gb_i2c_smbus_xfer(struct i2c_adapter *adap,
+ u16 addr, unsigned short flags, char read_write,
+ u8 command, int size, union i2c_smbus_data *data)
+{
+ struct gb_i2c_device *gb_i2c_dev;
+
+ gb_i2c_dev = i2c_get_adapdata(adap);
+
+ return 0;
+}
+#endif
+
+static u32 gb_i2c_functionality(struct i2c_adapter *adap)
+{
+ struct gb_i2c_device *gb_i2c_dev = i2c_get_adapdata(adap);
+
+ return gb_i2c_dev->functionality;
+}
+
+static const struct i2c_algorithm gb_i2c_algorithm = {
+ .master_xfer = gb_i2c_master_xfer,
+ /* .smbus_xfer = gb_i2c_smbus_xfer, */
+ .functionality = gb_i2c_functionality,
+};
+
+/*
+ * Do initial setup of the i2c device. This includes verifying we
+ * can support it (based on the protocol version it advertises).
+ * If that's OK, we get and cached its functionality bits.
+ *
+ * Note: gb_i2c_dev->connection is assumed to have been valid.
+ */
+static int gb_i2c_device_setup(struct gb_i2c_device *gb_i2c_dev)
+{
+ /* Assume the functionality never changes, just get it once */
+ return gb_i2c_functionality_operation(gb_i2c_dev);
+}
+
+static int gb_i2c_probe(struct gbphy_device *gbphy_dev,
+ const struct gbphy_device_id *id)
+{
+ struct gb_connection *connection;
+ struct gb_i2c_device *gb_i2c_dev;
+ struct i2c_adapter *adapter;
+ int ret;
+
+ gb_i2c_dev = kzalloc(sizeof(*gb_i2c_dev), GFP_KERNEL);
+ if (!gb_i2c_dev)
+ return -ENOMEM;
+
+ connection = gb_connection_create(gbphy_dev->bundle,
+ le16_to_cpu(gbphy_dev->cport_desc->id),
+ NULL);
+ if (IS_ERR(connection)) {
+ ret = PTR_ERR(connection);
+ goto exit_i2cdev_free;
+ }
+
+ gb_i2c_dev->connection = connection;
+ gb_connection_set_data(connection, gb_i2c_dev);
+ gb_i2c_dev->gbphy_dev = gbphy_dev;
+ gb_gbphy_set_data(gbphy_dev, gb_i2c_dev);
+
+ ret = gb_connection_enable(connection);
+ if (ret)
+ goto exit_connection_destroy;
+
+ ret = gb_i2c_device_setup(gb_i2c_dev);
+ if (ret)
+ goto exit_connection_disable;
+
+ /* Looks good; up our i2c adapter */
+ adapter = &gb_i2c_dev->adapter;
+ adapter->owner = THIS_MODULE;
+ adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+ adapter->algo = &gb_i2c_algorithm;
+ /* adapter->algo_data = what? */
+
+ adapter->dev.parent = &gbphy_dev->dev;
+ snprintf(adapter->name, sizeof(adapter->name), "Greybus i2c adapter");
+ i2c_set_adapdata(adapter, gb_i2c_dev);
+
+ ret = i2c_add_adapter(adapter);
+ if (ret)
+ goto exit_connection_disable;
+
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+ return 0;
+
+exit_connection_disable:
+ gb_connection_disable(connection);
+exit_connection_destroy:
+ gb_connection_destroy(connection);
+exit_i2cdev_free:
+ kfree(gb_i2c_dev);
+
+ return ret;
+}
+
+static void gb_i2c_remove(struct gbphy_device *gbphy_dev)
+{
+ struct gb_i2c_device *gb_i2c_dev = gb_gbphy_get_data(gbphy_dev);
+ struct gb_connection *connection = gb_i2c_dev->connection;
+ int ret;
+
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ gbphy_runtime_get_noresume(gbphy_dev);
+
+ i2c_del_adapter(&gb_i2c_dev->adapter);
+ gb_connection_disable(connection);
+ gb_connection_destroy(connection);
+ kfree(gb_i2c_dev);
+}
+
+static const struct gbphy_device_id gb_i2c_id_table[] = {
+ { GBPHY_PROTOCOL(GREYBUS_PROTOCOL_I2C) },
+ { },
+};
+MODULE_DEVICE_TABLE(gbphy, gb_i2c_id_table);
+
+static struct gbphy_driver i2c_driver = {
+ .name = "i2c",
+ .probe = gb_i2c_probe,
+ .remove = gb_i2c_remove,
+ .id_table = gb_i2c_id_table,
+};
+
+module_gbphy_driver(i2c_driver);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c
new file mode 100644
index 000000000000..546b090e2d51
--- /dev/null
+++ b/drivers/staging/greybus/interface.c
@@ -0,0 +1,1316 @@
+/*
+ * Greybus interface code
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/delay.h>
+
+#include "greybus.h"
+#include "greybus_trace.h"
+
+#define GB_INTERFACE_MODE_SWITCH_TIMEOUT 2000
+
+#define GB_INTERFACE_DEVICE_ID_BAD 0xff
+
+#define GB_INTERFACE_AUTOSUSPEND_MS 3000
+
+/* Time required for interface to enter standby before disabling REFCLK */
+#define GB_INTERFACE_SUSPEND_HIBERNATE_DELAY_MS 20
+
+/* Don't-care selector index */
+#define DME_SELECTOR_INDEX_NULL 0
+
+/* DME attributes */
+/* FIXME: remove ES2 support and DME_T_TST_SRC_INCREMENT */
+#define DME_T_TST_SRC_INCREMENT 0x4083
+
+#define DME_DDBL1_MANUFACTURERID 0x5003
+#define DME_DDBL1_PRODUCTID 0x5004
+
+#define DME_TOSHIBA_GMP_VID 0x6000
+#define DME_TOSHIBA_GMP_PID 0x6001
+#define DME_TOSHIBA_GMP_SN0 0x6002
+#define DME_TOSHIBA_GMP_SN1 0x6003
+#define DME_TOSHIBA_GMP_INIT_STATUS 0x6101
+
+/* DDBL1 Manufacturer and Product ids */
+#define TOSHIBA_DMID 0x0126
+#define TOSHIBA_ES2_BRIDGE_DPID 0x1000
+#define TOSHIBA_ES3_APBRIDGE_DPID 0x1001
+#define TOSHIBA_ES3_GBPHY_DPID 0x1002
+
+static int gb_interface_hibernate_link(struct gb_interface *intf);
+static int gb_interface_refclk_set(struct gb_interface *intf, bool enable);
+
+static int gb_interface_dme_attr_get(struct gb_interface *intf,
+ u16 attr, u32 *val)
+{
+ return gb_svc_dme_peer_get(intf->hd->svc, intf->interface_id,
+ attr, DME_SELECTOR_INDEX_NULL, val);
+}
+
+static int gb_interface_read_ara_dme(struct gb_interface *intf)
+{
+ u32 sn0, sn1;
+ int ret;
+
+ /*
+ * Unless this is a Toshiba bridge, bail out until we have defined
+ * standard GMP attributes.
+ */
+ if (intf->ddbl1_manufacturer_id != TOSHIBA_DMID) {
+ dev_err(&intf->dev, "unknown manufacturer %08x\n",
+ intf->ddbl1_manufacturer_id);
+ return -ENODEV;
+ }
+
+ ret = gb_interface_dme_attr_get(intf, DME_TOSHIBA_GMP_VID,
+ &intf->vendor_id);
+ if (ret)
+ return ret;
+
+ ret = gb_interface_dme_attr_get(intf, DME_TOSHIBA_GMP_PID,
+ &intf->product_id);
+ if (ret)
+ return ret;
+
+ ret = gb_interface_dme_attr_get(intf, DME_TOSHIBA_GMP_SN0, &sn0);
+ if (ret)
+ return ret;
+
+ ret = gb_interface_dme_attr_get(intf, DME_TOSHIBA_GMP_SN1, &sn1);
+ if (ret)
+ return ret;
+
+ intf->serial_number = (u64)sn1 << 32 | sn0;
+
+ return 0;
+}
+
+static int gb_interface_read_dme(struct gb_interface *intf)
+{
+ int ret;
+
+ /* DME attributes have already been read */
+ if (intf->dme_read)
+ return 0;
+
+ ret = gb_interface_dme_attr_get(intf, DME_DDBL1_MANUFACTURERID,
+ &intf->ddbl1_manufacturer_id);
+ if (ret)
+ return ret;
+
+ ret = gb_interface_dme_attr_get(intf, DME_DDBL1_PRODUCTID,
+ &intf->ddbl1_product_id);
+ if (ret)
+ return ret;
+
+ if (intf->ddbl1_manufacturer_id == TOSHIBA_DMID &&
+ intf->ddbl1_product_id == TOSHIBA_ES2_BRIDGE_DPID) {
+ intf->quirks |= GB_INTERFACE_QUIRK_NO_GMP_IDS;
+ intf->quirks |= GB_INTERFACE_QUIRK_NO_INIT_STATUS;
+ }
+
+ ret = gb_interface_read_ara_dme(intf);
+ if (ret)
+ return ret;
+
+ intf->dme_read = true;
+
+ return 0;
+}
+
+static int gb_interface_route_create(struct gb_interface *intf)
+{
+ struct gb_svc *svc = intf->hd->svc;
+ u8 intf_id = intf->interface_id;
+ u8 device_id;
+ int ret;
+
+ /* Allocate an interface device id. */
+ ret = ida_simple_get(&svc->device_id_map,
+ GB_SVC_DEVICE_ID_MIN, GB_SVC_DEVICE_ID_MAX + 1,
+ GFP_KERNEL);
+ if (ret < 0) {
+ dev_err(&intf->dev, "failed to allocate device id: %d\n", ret);
+ return ret;
+ }
+ device_id = ret;
+
+ ret = gb_svc_intf_device_id(svc, intf_id, device_id);
+ if (ret) {
+ dev_err(&intf->dev, "failed to set device id %u: %d\n",
+ device_id, ret);
+ goto err_ida_remove;
+ }
+
+ /* FIXME: Hard-coded AP device id. */
+ ret = gb_svc_route_create(svc, svc->ap_intf_id, GB_SVC_DEVICE_ID_AP,
+ intf_id, device_id);
+ if (ret) {
+ dev_err(&intf->dev, "failed to create route: %d\n", ret);
+ goto err_svc_id_free;
+ }
+
+ intf->device_id = device_id;
+
+ return 0;
+
+err_svc_id_free:
+ /*
+ * XXX Should we tell SVC that this id doesn't belong to interface
+ * XXX anymore.
+ */
+err_ida_remove:
+ ida_simple_remove(&svc->device_id_map, device_id);
+
+ return ret;
+}
+
+static void gb_interface_route_destroy(struct gb_interface *intf)
+{
+ struct gb_svc *svc = intf->hd->svc;
+
+ if (intf->device_id == GB_INTERFACE_DEVICE_ID_BAD)
+ return;
+
+ gb_svc_route_destroy(svc, svc->ap_intf_id, intf->interface_id);
+ ida_simple_remove(&svc->device_id_map, intf->device_id);
+ intf->device_id = GB_INTERFACE_DEVICE_ID_BAD;
+}
+
+/* Locking: Caller holds the interface mutex. */
+static int gb_interface_legacy_mode_switch(struct gb_interface *intf)
+{
+ int ret;
+
+ dev_info(&intf->dev, "legacy mode switch detected\n");
+
+ /* Mark as disconnected to prevent I/O during disable. */
+ intf->disconnected = true;
+ gb_interface_disable(intf);
+ intf->disconnected = false;
+
+ ret = gb_interface_enable(intf);
+ if (ret) {
+ dev_err(&intf->dev, "failed to re-enable interface: %d\n", ret);
+ gb_interface_deactivate(intf);
+ }
+
+ return ret;
+}
+
+void gb_interface_mailbox_event(struct gb_interface *intf, u16 result,
+ u32 mailbox)
+{
+ mutex_lock(&intf->mutex);
+
+ if (result) {
+ dev_warn(&intf->dev,
+ "mailbox event with UniPro error: 0x%04x\n",
+ result);
+ goto err_disable;
+ }
+
+ if (mailbox != GB_SVC_INTF_MAILBOX_GREYBUS) {
+ dev_warn(&intf->dev,
+ "mailbox event with unexpected value: 0x%08x\n",
+ mailbox);
+ goto err_disable;
+ }
+
+ if (intf->quirks & GB_INTERFACE_QUIRK_LEGACY_MODE_SWITCH) {
+ gb_interface_legacy_mode_switch(intf);
+ goto out_unlock;
+ }
+
+ if (!intf->mode_switch) {
+ dev_warn(&intf->dev, "unexpected mailbox event: 0x%08x\n",
+ mailbox);
+ goto err_disable;
+ }
+
+ dev_info(&intf->dev, "mode switch detected\n");
+
+ complete(&intf->mode_switch_completion);
+
+out_unlock:
+ mutex_unlock(&intf->mutex);
+
+ return;
+
+err_disable:
+ gb_interface_disable(intf);
+ gb_interface_deactivate(intf);
+ mutex_unlock(&intf->mutex);
+}
+
+static void gb_interface_mode_switch_work(struct work_struct *work)
+{
+ struct gb_interface *intf;
+ struct gb_control *control;
+ unsigned long timeout;
+ int ret;
+
+ intf = container_of(work, struct gb_interface, mode_switch_work);
+
+ mutex_lock(&intf->mutex);
+ /* Make sure interface is still enabled. */
+ if (!intf->enabled) {
+ dev_dbg(&intf->dev, "mode switch aborted\n");
+ intf->mode_switch = false;
+ mutex_unlock(&intf->mutex);
+ goto out_interface_put;
+ }
+
+ /*
+ * Prepare the control device for mode switch and make sure to get an
+ * extra reference before it goes away during interface disable.
+ */
+ control = gb_control_get(intf->control);
+ gb_control_mode_switch_prepare(control);
+ gb_interface_disable(intf);
+ mutex_unlock(&intf->mutex);
+
+ timeout = msecs_to_jiffies(GB_INTERFACE_MODE_SWITCH_TIMEOUT);
+ ret = wait_for_completion_interruptible_timeout(
+ &intf->mode_switch_completion, timeout);
+
+ /* Finalise control-connection mode switch. */
+ gb_control_mode_switch_complete(control);
+ gb_control_put(control);
+
+ if (ret < 0) {
+ dev_err(&intf->dev, "mode switch interrupted\n");
+ goto err_deactivate;
+ } else if (ret == 0) {
+ dev_err(&intf->dev, "mode switch timed out\n");
+ goto err_deactivate;
+ }
+
+ /* Re-enable (re-enumerate) interface if still active. */
+ mutex_lock(&intf->mutex);
+ intf->mode_switch = false;
+ if (intf->active) {
+ ret = gb_interface_enable(intf);
+ if (ret) {
+ dev_err(&intf->dev, "failed to re-enable interface: %d\n",
+ ret);
+ gb_interface_deactivate(intf);
+ }
+ }
+ mutex_unlock(&intf->mutex);
+
+out_interface_put:
+ gb_interface_put(intf);
+
+ return;
+
+err_deactivate:
+ mutex_lock(&intf->mutex);
+ intf->mode_switch = false;
+ gb_interface_deactivate(intf);
+ mutex_unlock(&intf->mutex);
+
+ gb_interface_put(intf);
+}
+
+int gb_interface_request_mode_switch(struct gb_interface *intf)
+{
+ int ret = 0;
+
+ mutex_lock(&intf->mutex);
+ if (intf->mode_switch) {
+ ret = -EBUSY;
+ goto out_unlock;
+ }
+
+ intf->mode_switch = true;
+ reinit_completion(&intf->mode_switch_completion);
+
+ /*
+ * Get a reference to the interface device, which will be put once the
+ * mode switch is complete.
+ */
+ get_device(&intf->dev);
+
+ if (!queue_work(system_long_wq, &intf->mode_switch_work)) {
+ put_device(&intf->dev);
+ ret = -EBUSY;
+ goto out_unlock;
+ }
+
+out_unlock:
+ mutex_unlock(&intf->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_interface_request_mode_switch);
+
+/*
+ * T_TstSrcIncrement is written by the module on ES2 as a stand-in for the
+ * init-status attribute DME_TOSHIBA_INIT_STATUS. The AP needs to read and
+ * clear it after reading a non-zero value from it.
+ *
+ * FIXME: This is module-hardware dependent and needs to be extended for every
+ * type of module we want to support.
+ */
+static int gb_interface_read_and_clear_init_status(struct gb_interface *intf)
+{
+ struct gb_host_device *hd = intf->hd;
+ unsigned long bootrom_quirks;
+ unsigned long s2l_quirks;
+ int ret;
+ u32 value;
+ u16 attr;
+ u8 init_status;
+
+ /*
+ * ES2 bridges use T_TstSrcIncrement for the init status.
+ *
+ * FIXME: Remove ES2 support
+ */
+ if (intf->quirks & GB_INTERFACE_QUIRK_NO_INIT_STATUS)
+ attr = DME_T_TST_SRC_INCREMENT;
+ else
+ attr = DME_TOSHIBA_GMP_INIT_STATUS;
+
+ ret = gb_svc_dme_peer_get(hd->svc, intf->interface_id, attr,
+ DME_SELECTOR_INDEX_NULL, &value);
+ if (ret)
+ return ret;
+
+ /*
+ * A nonzero init status indicates the module has finished
+ * initializing.
+ */
+ if (!value) {
+ dev_err(&intf->dev, "invalid init status\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Extract the init status.
+ *
+ * For ES2: We need to check lowest 8 bits of 'value'.
+ * For ES3: We need to check highest 8 bits out of 32 of 'value'.
+ *
+ * FIXME: Remove ES2 support
+ */
+ if (intf->quirks & GB_INTERFACE_QUIRK_NO_INIT_STATUS)
+ init_status = value & 0xff;
+ else
+ init_status = value >> 24;
+
+ /*
+ * Check if the interface is executing the quirky ES3 bootrom that,
+ * for example, requires E2EFC, CSD and CSV to be disabled.
+ */
+ bootrom_quirks = GB_INTERFACE_QUIRK_NO_CPORT_FEATURES |
+ GB_INTERFACE_QUIRK_FORCED_DISABLE |
+ GB_INTERFACE_QUIRK_LEGACY_MODE_SWITCH |
+ GB_INTERFACE_QUIRK_NO_BUNDLE_ACTIVATE;
+
+ s2l_quirks = GB_INTERFACE_QUIRK_NO_PM;
+
+ switch (init_status) {
+ case GB_INIT_BOOTROM_UNIPRO_BOOT_STARTED:
+ case GB_INIT_BOOTROM_FALLBACK_UNIPRO_BOOT_STARTED:
+ intf->quirks |= bootrom_quirks;
+ break;
+ case GB_INIT_S2_LOADER_BOOT_STARTED:
+ /* S2 Loader doesn't support runtime PM */
+ intf->quirks &= ~bootrom_quirks;
+ intf->quirks |= s2l_quirks;
+ break;
+ default:
+ intf->quirks &= ~bootrom_quirks;
+ intf->quirks &= ~s2l_quirks;
+ }
+
+ /* Clear the init status. */
+ return gb_svc_dme_peer_set(hd->svc, intf->interface_id, attr,
+ DME_SELECTOR_INDEX_NULL, 0);
+}
+
+/* interface sysfs attributes */
+#define gb_interface_attr(field, type) \
+static ssize_t field##_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct gb_interface *intf = to_gb_interface(dev); \
+ return scnprintf(buf, PAGE_SIZE, type"\n", intf->field); \
+} \
+static DEVICE_ATTR_RO(field)
+
+gb_interface_attr(ddbl1_manufacturer_id, "0x%08x");
+gb_interface_attr(ddbl1_product_id, "0x%08x");
+gb_interface_attr(interface_id, "%u");
+gb_interface_attr(vendor_id, "0x%08x");
+gb_interface_attr(product_id, "0x%08x");
+gb_interface_attr(serial_number, "0x%016llx");
+
+static ssize_t voltage_now_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_interface *intf = to_gb_interface(dev);
+ int ret;
+ u32 measurement;
+
+ ret = gb_svc_pwrmon_intf_sample_get(intf->hd->svc, intf->interface_id,
+ GB_SVC_PWRMON_TYPE_VOL,
+ &measurement);
+ if (ret) {
+ dev_err(&intf->dev, "failed to get voltage sample (%d)\n", ret);
+ return ret;
+ }
+
+ return sprintf(buf, "%u\n", measurement);
+}
+static DEVICE_ATTR_RO(voltage_now);
+
+static ssize_t current_now_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_interface *intf = to_gb_interface(dev);
+ int ret;
+ u32 measurement;
+
+ ret = gb_svc_pwrmon_intf_sample_get(intf->hd->svc, intf->interface_id,
+ GB_SVC_PWRMON_TYPE_CURR,
+ &measurement);
+ if (ret) {
+ dev_err(&intf->dev, "failed to get current sample (%d)\n", ret);
+ return ret;
+ }
+
+ return sprintf(buf, "%u\n", measurement);
+}
+static DEVICE_ATTR_RO(current_now);
+
+static ssize_t power_now_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_interface *intf = to_gb_interface(dev);
+ int ret;
+ u32 measurement;
+
+ ret = gb_svc_pwrmon_intf_sample_get(intf->hd->svc, intf->interface_id,
+ GB_SVC_PWRMON_TYPE_PWR,
+ &measurement);
+ if (ret) {
+ dev_err(&intf->dev, "failed to get power sample (%d)\n", ret);
+ return ret;
+ }
+
+ return sprintf(buf, "%u\n", measurement);
+}
+static DEVICE_ATTR_RO(power_now);
+
+static ssize_t power_state_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_interface *intf = to_gb_interface(dev);
+
+ if (intf->active)
+ return scnprintf(buf, PAGE_SIZE, "on\n");
+ else
+ return scnprintf(buf, PAGE_SIZE, "off\n");
+}
+
+static ssize_t power_state_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t len)
+{
+ struct gb_interface *intf = to_gb_interface(dev);
+ bool activate;
+ int ret = 0;
+
+ if (kstrtobool(buf, &activate))
+ return -EINVAL;
+
+ mutex_lock(&intf->mutex);
+
+ if (activate == intf->active)
+ goto unlock;
+
+ if (activate) {
+ ret = gb_interface_activate(intf);
+ if (ret) {
+ dev_err(&intf->dev,
+ "failed to activate interface: %d\n", ret);
+ goto unlock;
+ }
+
+ ret = gb_interface_enable(intf);
+ if (ret) {
+ dev_err(&intf->dev,
+ "failed to enable interface: %d\n", ret);
+ gb_interface_deactivate(intf);
+ goto unlock;
+ }
+ } else {
+ gb_interface_disable(intf);
+ gb_interface_deactivate(intf);
+ }
+
+unlock:
+ mutex_unlock(&intf->mutex);
+
+ if (ret)
+ return ret;
+
+ return len;
+}
+static DEVICE_ATTR_RW(power_state);
+
+static const char *gb_interface_type_string(struct gb_interface *intf)
+{
+ static const char * const types[] = {
+ [GB_INTERFACE_TYPE_INVALID] = "invalid",
+ [GB_INTERFACE_TYPE_UNKNOWN] = "unknown",
+ [GB_INTERFACE_TYPE_DUMMY] = "dummy",
+ [GB_INTERFACE_TYPE_UNIPRO] = "unipro",
+ [GB_INTERFACE_TYPE_GREYBUS] = "greybus",
+ };
+
+ return types[intf->type];
+}
+
+static ssize_t interface_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_interface *intf = to_gb_interface(dev);
+
+ return sprintf(buf, "%s\n", gb_interface_type_string(intf));
+}
+static DEVICE_ATTR_RO(interface_type);
+
+static struct attribute *interface_unipro_attrs[] = {
+ &dev_attr_ddbl1_manufacturer_id.attr,
+ &dev_attr_ddbl1_product_id.attr,
+ NULL
+};
+
+static struct attribute *interface_greybus_attrs[] = {
+ &dev_attr_vendor_id.attr,
+ &dev_attr_product_id.attr,
+ &dev_attr_serial_number.attr,
+ NULL
+};
+
+static struct attribute *interface_power_attrs[] = {
+ &dev_attr_voltage_now.attr,
+ &dev_attr_current_now.attr,
+ &dev_attr_power_now.attr,
+ &dev_attr_power_state.attr,
+ NULL
+};
+
+static struct attribute *interface_common_attrs[] = {
+ &dev_attr_interface_id.attr,
+ &dev_attr_interface_type.attr,
+ NULL
+};
+
+static umode_t interface_unipro_is_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct gb_interface *intf = to_gb_interface(dev);
+
+ switch (intf->type) {
+ case GB_INTERFACE_TYPE_UNIPRO:
+ case GB_INTERFACE_TYPE_GREYBUS:
+ return attr->mode;
+ default:
+ return 0;
+ }
+}
+
+static umode_t interface_greybus_is_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct gb_interface *intf = to_gb_interface(dev);
+
+ switch (intf->type) {
+ case GB_INTERFACE_TYPE_GREYBUS:
+ return attr->mode;
+ default:
+ return 0;
+ }
+}
+
+static umode_t interface_power_is_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct gb_interface *intf = to_gb_interface(dev);
+
+ switch (intf->type) {
+ case GB_INTERFACE_TYPE_UNIPRO:
+ case GB_INTERFACE_TYPE_GREYBUS:
+ return attr->mode;
+ default:
+ return 0;
+ }
+}
+
+static const struct attribute_group interface_unipro_group = {
+ .is_visible = interface_unipro_is_visible,
+ .attrs = interface_unipro_attrs,
+};
+
+static const struct attribute_group interface_greybus_group = {
+ .is_visible = interface_greybus_is_visible,
+ .attrs = interface_greybus_attrs,
+};
+
+static const struct attribute_group interface_power_group = {
+ .is_visible = interface_power_is_visible,
+ .attrs = interface_power_attrs,
+};
+
+static const struct attribute_group interface_common_group = {
+ .attrs = interface_common_attrs,
+};
+
+static const struct attribute_group *interface_groups[] = {
+ &interface_unipro_group,
+ &interface_greybus_group,
+ &interface_power_group,
+ &interface_common_group,
+ NULL
+};
+
+static void gb_interface_release(struct device *dev)
+{
+ struct gb_interface *intf = to_gb_interface(dev);
+
+ trace_gb_interface_release(intf);
+
+ kfree(intf);
+}
+
+#ifdef CONFIG_PM
+static int gb_interface_suspend(struct device *dev)
+{
+ struct gb_interface *intf = to_gb_interface(dev);
+ int ret, timesync_ret;
+
+ ret = gb_control_interface_suspend_prepare(intf->control);
+ if (ret)
+ return ret;
+
+ gb_timesync_interface_remove(intf);
+
+ ret = gb_control_suspend(intf->control);
+ if (ret)
+ goto err_hibernate_abort;
+
+ ret = gb_interface_hibernate_link(intf);
+ if (ret)
+ return ret;
+
+ /* Delay to allow interface to enter standby before disabling refclk */
+ msleep(GB_INTERFACE_SUSPEND_HIBERNATE_DELAY_MS);
+
+ ret = gb_interface_refclk_set(intf, false);
+ if (ret)
+ return ret;
+
+ return 0;
+
+err_hibernate_abort:
+ gb_control_interface_hibernate_abort(intf->control);
+
+ timesync_ret = gb_timesync_interface_add(intf);
+ if (timesync_ret) {
+ dev_err(dev, "failed to add to timesync: %d\n", timesync_ret);
+ return timesync_ret;
+ }
+
+ return ret;
+}
+
+static int gb_interface_resume(struct device *dev)
+{
+ struct gb_interface *intf = to_gb_interface(dev);
+ struct gb_svc *svc = intf->hd->svc;
+ int ret;
+
+ ret = gb_interface_refclk_set(intf, true);
+ if (ret)
+ return ret;
+
+ ret = gb_svc_intf_resume(svc, intf->interface_id);
+ if (ret)
+ return ret;
+
+ ret = gb_control_resume(intf->control);
+ if (ret)
+ return ret;
+
+ ret = gb_timesync_interface_add(intf);
+ if (ret) {
+ dev_err(dev, "failed to add to timesync: %d\n", ret);
+ return ret;
+ }
+
+ ret = gb_timesync_schedule_synchronous(intf);
+ if (ret) {
+ dev_err(dev, "failed to synchronize FrameTime: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int gb_interface_runtime_idle(struct device *dev)
+{
+ pm_runtime_mark_last_busy(dev);
+ pm_request_autosuspend(dev);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops gb_interface_pm_ops = {
+ SET_RUNTIME_PM_OPS(gb_interface_suspend, gb_interface_resume,
+ gb_interface_runtime_idle)
+};
+
+struct device_type greybus_interface_type = {
+ .name = "greybus_interface",
+ .release = gb_interface_release,
+ .pm = &gb_interface_pm_ops,
+};
+
+/*
+ * A Greybus module represents a user-replaceable component on a GMP
+ * phone. An interface is the physical connection on that module. A
+ * module may have more than one interface.
+ *
+ * Create a gb_interface structure to represent a discovered interface.
+ * The position of interface within the Endo is encoded in "interface_id"
+ * argument.
+ *
+ * Returns a pointer to the new interfce or a null pointer if a
+ * failure occurs due to memory exhaustion.
+ */
+struct gb_interface *gb_interface_create(struct gb_module *module,
+ u8 interface_id)
+{
+ struct gb_host_device *hd = module->hd;
+ struct gb_interface *intf;
+
+ intf = kzalloc(sizeof(*intf), GFP_KERNEL);
+ if (!intf)
+ return NULL;
+
+ intf->hd = hd; /* XXX refcount? */
+ intf->module = module;
+ intf->interface_id = interface_id;
+ INIT_LIST_HEAD(&intf->bundles);
+ INIT_LIST_HEAD(&intf->manifest_descs);
+ mutex_init(&intf->mutex);
+ INIT_WORK(&intf->mode_switch_work, gb_interface_mode_switch_work);
+ init_completion(&intf->mode_switch_completion);
+
+ /* Invalid device id to start with */
+ intf->device_id = GB_INTERFACE_DEVICE_ID_BAD;
+
+ intf->dev.parent = &module->dev;
+ intf->dev.bus = &greybus_bus_type;
+ intf->dev.type = &greybus_interface_type;
+ intf->dev.groups = interface_groups;
+ intf->dev.dma_mask = module->dev.dma_mask;
+ device_initialize(&intf->dev);
+ dev_set_name(&intf->dev, "%s.%u", dev_name(&module->dev),
+ interface_id);
+
+ pm_runtime_set_autosuspend_delay(&intf->dev,
+ GB_INTERFACE_AUTOSUSPEND_MS);
+
+ trace_gb_interface_create(intf);
+
+ return intf;
+}
+
+static int gb_interface_vsys_set(struct gb_interface *intf, bool enable)
+{
+ struct gb_svc *svc = intf->hd->svc;
+ int ret;
+
+ dev_dbg(&intf->dev, "%s - %d\n", __func__, enable);
+
+ ret = gb_svc_intf_vsys_set(svc, intf->interface_id, enable);
+ if (ret) {
+ dev_err(&intf->dev, "failed to set v_sys: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int gb_interface_refclk_set(struct gb_interface *intf, bool enable)
+{
+ struct gb_svc *svc = intf->hd->svc;
+ int ret;
+
+ dev_dbg(&intf->dev, "%s - %d\n", __func__, enable);
+
+ ret = gb_svc_intf_refclk_set(svc, intf->interface_id, enable);
+ if (ret) {
+ dev_err(&intf->dev, "failed to set refclk: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int gb_interface_unipro_set(struct gb_interface *intf, bool enable)
+{
+ struct gb_svc *svc = intf->hd->svc;
+ int ret;
+
+ dev_dbg(&intf->dev, "%s - %d\n", __func__, enable);
+
+ ret = gb_svc_intf_unipro_set(svc, intf->interface_id, enable);
+ if (ret) {
+ dev_err(&intf->dev, "failed to set UniPro: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int gb_interface_activate_operation(struct gb_interface *intf,
+ enum gb_interface_type *intf_type)
+{
+ struct gb_svc *svc = intf->hd->svc;
+ u8 type;
+ int ret;
+
+ dev_dbg(&intf->dev, "%s\n", __func__);
+
+ ret = gb_svc_intf_activate(svc, intf->interface_id, &type);
+ if (ret) {
+ dev_err(&intf->dev, "failed to activate: %d\n", ret);
+ return ret;
+ }
+
+ switch (type) {
+ case GB_SVC_INTF_TYPE_DUMMY:
+ *intf_type = GB_INTERFACE_TYPE_DUMMY;
+ /* FIXME: handle as an error for now */
+ return -ENODEV;
+ case GB_SVC_INTF_TYPE_UNIPRO:
+ *intf_type = GB_INTERFACE_TYPE_UNIPRO;
+ dev_err(&intf->dev, "interface type UniPro not supported\n");
+ /* FIXME: handle as an error for now */
+ return -ENODEV;
+ case GB_SVC_INTF_TYPE_GREYBUS:
+ *intf_type = GB_INTERFACE_TYPE_GREYBUS;
+ break;
+ default:
+ dev_err(&intf->dev, "unknown interface type: %u\n", type);
+ *intf_type = GB_INTERFACE_TYPE_UNKNOWN;
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int gb_interface_hibernate_link(struct gb_interface *intf)
+{
+ struct gb_svc *svc = intf->hd->svc;
+
+ return gb_svc_intf_set_power_mode_hibernate(svc, intf->interface_id);
+}
+
+static int _gb_interface_activate(struct gb_interface *intf,
+ enum gb_interface_type *type)
+{
+ int ret;
+
+ *type = GB_INTERFACE_TYPE_UNKNOWN;
+
+ if (intf->ejected || intf->removed)
+ return -ENODEV;
+
+ ret = gb_interface_vsys_set(intf, true);
+ if (ret)
+ return ret;
+
+ ret = gb_interface_refclk_set(intf, true);
+ if (ret)
+ goto err_vsys_disable;
+
+ ret = gb_interface_unipro_set(intf, true);
+ if (ret)
+ goto err_refclk_disable;
+
+ ret = gb_interface_activate_operation(intf, type);
+ if (ret) {
+ switch (*type) {
+ case GB_INTERFACE_TYPE_UNIPRO:
+ case GB_INTERFACE_TYPE_GREYBUS:
+ goto err_hibernate_link;
+ default:
+ goto err_unipro_disable;
+ }
+ }
+
+ ret = gb_interface_read_dme(intf);
+ if (ret)
+ goto err_hibernate_link;
+
+ ret = gb_interface_route_create(intf);
+ if (ret)
+ goto err_hibernate_link;
+
+ intf->active = true;
+
+ trace_gb_interface_activate(intf);
+
+ return 0;
+
+err_hibernate_link:
+ gb_interface_hibernate_link(intf);
+err_unipro_disable:
+ gb_interface_unipro_set(intf, false);
+err_refclk_disable:
+ gb_interface_refclk_set(intf, false);
+err_vsys_disable:
+ gb_interface_vsys_set(intf, false);
+
+ return ret;
+}
+
+/*
+ * At present, we assume a UniPro-only module to be a Greybus module that
+ * failed to send its mailbox poke. There is some reason to believe that this
+ * is because of a bug in the ES3 bootrom.
+ *
+ * FIXME: Check if this is a Toshiba bridge before retrying?
+ */
+static int _gb_interface_activate_es3_hack(struct gb_interface *intf,
+ enum gb_interface_type *type)
+{
+ int retries = 3;
+ int ret;
+
+ while (retries--) {
+ ret = _gb_interface_activate(intf, type);
+ if (ret == -ENODEV && *type == GB_INTERFACE_TYPE_UNIPRO)
+ continue;
+
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * Activate an interface.
+ *
+ * Locking: Caller holds the interface mutex.
+ */
+int gb_interface_activate(struct gb_interface *intf)
+{
+ enum gb_interface_type type;
+ int ret;
+
+ switch (intf->type) {
+ case GB_INTERFACE_TYPE_INVALID:
+ case GB_INTERFACE_TYPE_GREYBUS:
+ ret = _gb_interface_activate_es3_hack(intf, &type);
+ break;
+ default:
+ ret = _gb_interface_activate(intf, &type);
+ }
+
+ /* Make sure type is detected correctly during reactivation. */
+ if (intf->type != GB_INTERFACE_TYPE_INVALID) {
+ if (type != intf->type) {
+ dev_err(&intf->dev, "failed to detect interface type\n");
+
+ if (!ret)
+ gb_interface_deactivate(intf);
+
+ return -EIO;
+ }
+ } else {
+ intf->type = type;
+ }
+
+ return ret;
+}
+
+/*
+ * Deactivate an interface.
+ *
+ * Locking: Caller holds the interface mutex.
+ */
+void gb_interface_deactivate(struct gb_interface *intf)
+{
+ if (!intf->active)
+ return;
+
+ trace_gb_interface_deactivate(intf);
+
+ /* Abort any ongoing mode switch. */
+ if (intf->mode_switch)
+ complete(&intf->mode_switch_completion);
+
+ gb_interface_route_destroy(intf);
+ gb_interface_hibernate_link(intf);
+ gb_interface_unipro_set(intf, false);
+ gb_interface_refclk_set(intf, false);
+ gb_interface_vsys_set(intf, false);
+
+ intf->active = false;
+}
+
+/*
+ * Enable an interface by enabling its control connection, fetching the
+ * manifest and other information over it, and finally registering its child
+ * devices.
+ *
+ * Locking: Caller holds the interface mutex.
+ */
+int gb_interface_enable(struct gb_interface *intf)
+{
+ struct gb_control *control;
+ struct gb_bundle *bundle, *tmp;
+ int ret, size;
+ void *manifest;
+
+ ret = gb_interface_read_and_clear_init_status(intf);
+ if (ret) {
+ dev_err(&intf->dev, "failed to clear init status: %d\n", ret);
+ return ret;
+ }
+
+ /* Establish control connection */
+ control = gb_control_create(intf);
+ if (IS_ERR(control)) {
+ dev_err(&intf->dev, "failed to create control device: %ld\n",
+ PTR_ERR(control));
+ return PTR_ERR(control);
+ }
+ intf->control = control;
+
+ ret = gb_control_enable(intf->control);
+ if (ret)
+ goto err_put_control;
+
+ /* Get manifest size using control protocol on CPort */
+ size = gb_control_get_manifest_size_operation(intf);
+ if (size <= 0) {
+ dev_err(&intf->dev, "failed to get manifest size: %d\n", size);
+
+ if (size)
+ ret = size;
+ else
+ ret = -EINVAL;
+
+ goto err_disable_control;
+ }
+
+ manifest = kmalloc(size, GFP_KERNEL);
+ if (!manifest) {
+ ret = -ENOMEM;
+ goto err_disable_control;
+ }
+
+ /* Get manifest using control protocol on CPort */
+ ret = gb_control_get_manifest_operation(intf, manifest, size);
+ if (ret) {
+ dev_err(&intf->dev, "failed to get manifest: %d\n", ret);
+ goto err_free_manifest;
+ }
+
+ /*
+ * Parse the manifest and build up our data structures representing
+ * what's in it.
+ */
+ if (!gb_manifest_parse(intf, manifest, size)) {
+ dev_err(&intf->dev, "failed to parse manifest\n");
+ ret = -EINVAL;
+ goto err_destroy_bundles;
+ }
+
+ ret = gb_control_get_bundle_versions(intf->control);
+ if (ret)
+ goto err_destroy_bundles;
+
+ ret = gb_timesync_interface_add(intf);
+ if (ret) {
+ dev_err(&intf->dev, "failed to add to timesync: %d\n", ret);
+ goto err_destroy_bundles;
+ }
+
+ /* Register the control device and any bundles */
+ ret = gb_control_add(intf->control);
+ if (ret)
+ goto err_remove_timesync;
+
+ pm_runtime_use_autosuspend(&intf->dev);
+ pm_runtime_get_noresume(&intf->dev);
+ pm_runtime_set_active(&intf->dev);
+ pm_runtime_enable(&intf->dev);
+
+ list_for_each_entry_safe_reverse(bundle, tmp, &intf->bundles, links) {
+ ret = gb_bundle_add(bundle);
+ if (ret) {
+ gb_bundle_destroy(bundle);
+ continue;
+ }
+ }
+
+ kfree(manifest);
+
+ intf->enabled = true;
+
+ pm_runtime_put(&intf->dev);
+
+ trace_gb_interface_enable(intf);
+
+ return 0;
+
+err_remove_timesync:
+ gb_timesync_interface_remove(intf);
+err_destroy_bundles:
+ list_for_each_entry_safe(bundle, tmp, &intf->bundles, links)
+ gb_bundle_destroy(bundle);
+err_free_manifest:
+ kfree(manifest);
+err_disable_control:
+ gb_control_disable(intf->control);
+err_put_control:
+ gb_control_put(intf->control);
+ intf->control = NULL;
+
+ return ret;
+}
+
+/*
+ * Disable an interface and destroy its bundles.
+ *
+ * Locking: Caller holds the interface mutex.
+ */
+void gb_interface_disable(struct gb_interface *intf)
+{
+ struct gb_bundle *bundle;
+ struct gb_bundle *next;
+
+ if (!intf->enabled)
+ return;
+
+ trace_gb_interface_disable(intf);
+
+ pm_runtime_get_sync(&intf->dev);
+
+ /* Set disconnected flag to avoid I/O during connection tear down. */
+ if (intf->quirks & GB_INTERFACE_QUIRK_FORCED_DISABLE)
+ intf->disconnected = true;
+
+ list_for_each_entry_safe(bundle, next, &intf->bundles, links)
+ gb_bundle_destroy(bundle);
+
+ if (!intf->mode_switch && !intf->disconnected)
+ gb_control_interface_deactivate_prepare(intf->control);
+
+ gb_control_del(intf->control);
+ gb_timesync_interface_remove(intf);
+ gb_control_disable(intf->control);
+ gb_control_put(intf->control);
+ intf->control = NULL;
+
+ intf->enabled = false;
+
+ pm_runtime_disable(&intf->dev);
+ pm_runtime_set_suspended(&intf->dev);
+ pm_runtime_dont_use_autosuspend(&intf->dev);
+ pm_runtime_put_noidle(&intf->dev);
+}
+
+/* Enable TimeSync on an Interface control connection. */
+int gb_interface_timesync_enable(struct gb_interface *intf, u8 count,
+ u64 frame_time, u32 strobe_delay, u32 refclk)
+{
+ return gb_control_timesync_enable(intf->control, count,
+ frame_time, strobe_delay,
+ refclk);
+}
+
+/* Disable TimeSync on an Interface control connection. */
+int gb_interface_timesync_disable(struct gb_interface *intf)
+{
+ return gb_control_timesync_disable(intf->control);
+}
+
+/* Transmit the Authoritative FrameTime via an Interface control connection. */
+int gb_interface_timesync_authoritative(struct gb_interface *intf,
+ u64 *frame_time)
+{
+ return gb_control_timesync_authoritative(intf->control,
+ frame_time);
+}
+
+/* Register an interface. */
+int gb_interface_add(struct gb_interface *intf)
+{
+ int ret;
+
+ ret = device_add(&intf->dev);
+ if (ret) {
+ dev_err(&intf->dev, "failed to register interface: %d\n", ret);
+ return ret;
+ }
+
+ trace_gb_interface_add(intf);
+
+ dev_info(&intf->dev, "Interface added (%s)\n",
+ gb_interface_type_string(intf));
+
+ switch (intf->type) {
+ case GB_INTERFACE_TYPE_GREYBUS:
+ dev_info(&intf->dev, "GMP VID=0x%08x, PID=0x%08x\n",
+ intf->vendor_id, intf->product_id);
+ /* fall-through */
+ case GB_INTERFACE_TYPE_UNIPRO:
+ dev_info(&intf->dev, "DDBL1 Manufacturer=0x%08x, Product=0x%08x\n",
+ intf->ddbl1_manufacturer_id,
+ intf->ddbl1_product_id);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/* Deregister an interface. */
+void gb_interface_del(struct gb_interface *intf)
+{
+ if (device_is_registered(&intf->dev)) {
+ trace_gb_interface_del(intf);
+
+ device_del(&intf->dev);
+ dev_info(&intf->dev, "Interface removed\n");
+ }
+}
+
+void gb_interface_put(struct gb_interface *intf)
+{
+ put_device(&intf->dev);
+}
diff --git a/drivers/staging/greybus/interface.h b/drivers/staging/greybus/interface.h
new file mode 100644
index 000000000000..03299d2a8be5
--- /dev/null
+++ b/drivers/staging/greybus/interface.h
@@ -0,0 +1,88 @@
+/*
+ * Greybus Interface Block code
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __INTERFACE_H
+#define __INTERFACE_H
+
+enum gb_interface_type {
+ GB_INTERFACE_TYPE_INVALID = 0,
+ GB_INTERFACE_TYPE_UNKNOWN,
+ GB_INTERFACE_TYPE_DUMMY,
+ GB_INTERFACE_TYPE_UNIPRO,
+ GB_INTERFACE_TYPE_GREYBUS,
+};
+
+#define GB_INTERFACE_QUIRK_NO_CPORT_FEATURES BIT(0)
+#define GB_INTERFACE_QUIRK_NO_INIT_STATUS BIT(1)
+#define GB_INTERFACE_QUIRK_NO_GMP_IDS BIT(2)
+#define GB_INTERFACE_QUIRK_FORCED_DISABLE BIT(3)
+#define GB_INTERFACE_QUIRK_LEGACY_MODE_SWITCH BIT(4)
+#define GB_INTERFACE_QUIRK_NO_BUNDLE_ACTIVATE BIT(5)
+#define GB_INTERFACE_QUIRK_NO_PM BIT(6)
+
+struct gb_interface {
+ struct device dev;
+ struct gb_control *control;
+
+ struct list_head bundles;
+ struct list_head module_node;
+ struct list_head manifest_descs;
+ u8 interface_id; /* Physical location within the Endo */
+ u8 device_id;
+ u8 features; /* Feature flags set in the manifest */
+
+ enum gb_interface_type type;
+
+ u32 ddbl1_manufacturer_id;
+ u32 ddbl1_product_id;
+ u32 vendor_id;
+ u32 product_id;
+ u64 serial_number;
+
+ struct gb_host_device *hd;
+ struct gb_module *module;
+
+ unsigned long quirks;
+
+ struct mutex mutex;
+
+ bool disconnected;
+
+ bool ejected;
+ bool removed;
+ bool active;
+ bool enabled;
+ bool mode_switch;
+ bool dme_read;
+
+ struct work_struct mode_switch_work;
+ struct completion mode_switch_completion;
+};
+#define to_gb_interface(d) container_of(d, struct gb_interface, dev)
+
+struct gb_interface *gb_interface_create(struct gb_module *module,
+ u8 interface_id);
+int gb_interface_activate(struct gb_interface *intf);
+void gb_interface_deactivate(struct gb_interface *intf);
+int gb_interface_enable(struct gb_interface *intf);
+void gb_interface_disable(struct gb_interface *intf);
+int gb_interface_timesync_enable(struct gb_interface *intf, u8 count,
+ u64 frame_time, u32 strobe_delay, u32 refclk);
+int gb_interface_timesync_authoritative(struct gb_interface *intf,
+ u64 *frame_time);
+int gb_interface_timesync_disable(struct gb_interface *intf);
+int gb_interface_add(struct gb_interface *intf);
+void gb_interface_del(struct gb_interface *intf);
+void gb_interface_put(struct gb_interface *intf);
+void gb_interface_mailbox_event(struct gb_interface *intf, u16 result,
+ u32 mailbox);
+
+int gb_interface_request_mode_switch(struct gb_interface *intf);
+
+#endif /* __INTERFACE_H */
diff --git a/drivers/staging/greybus/light.c b/drivers/staging/greybus/light.c
new file mode 100644
index 000000000000..8dffd8a7e762
--- /dev/null
+++ b/drivers/staging/greybus/light.c
@@ -0,0 +1,1361 @@
+/*
+ * Greybus Lights protocol driver.
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright 2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/led-class-flash.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <media/v4l2-flash-led-class.h>
+
+#include "greybus.h"
+#include "greybus_protocols.h"
+
+#define NAMES_MAX 32
+
+struct gb_channel {
+ u8 id;
+ u32 flags;
+ u32 color;
+ char *color_name;
+ u8 fade_in;
+ u8 fade_out;
+ u32 mode;
+ char *mode_name;
+ struct attribute **attrs;
+ struct attribute_group *attr_group;
+ const struct attribute_group **attr_groups;
+ struct led_classdev *led;
+#if IS_REACHABLE(CONFIG_LEDS_CLASS_FLASH)
+ struct led_classdev_flash fled;
+ struct led_flash_setting intensity_uA;
+ struct led_flash_setting timeout_us;
+#else
+ struct led_classdev cled;
+#endif
+ struct gb_light *light;
+ bool is_registered;
+ bool releasing;
+ bool strobe_state;
+ bool active;
+ struct mutex lock;
+};
+
+struct gb_light {
+ u8 id;
+ char *name;
+ struct gb_lights *glights;
+ u32 flags;
+ u8 channels_count;
+ struct gb_channel *channels;
+ bool has_flash;
+ bool ready;
+#if IS_REACHABLE(CONFIG_V4L2_FLASH_LED_CLASS)
+ struct v4l2_flash *v4l2_flash;
+#endif
+};
+
+struct gb_lights {
+ struct gb_connection *connection;
+ u8 lights_count;
+ struct gb_light *lights;
+ struct mutex lights_lock;
+};
+
+static void gb_lights_channel_free(struct gb_channel *channel);
+
+static struct gb_connection *get_conn_from_channel(struct gb_channel *channel)
+{
+ return channel->light->glights->connection;
+}
+
+static struct gb_connection *get_conn_from_light(struct gb_light *light)
+{
+ return light->glights->connection;
+}
+
+static bool is_channel_flash(struct gb_channel *channel)
+{
+ return !!(channel->mode & (GB_CHANNEL_MODE_FLASH | GB_CHANNEL_MODE_TORCH
+ | GB_CHANNEL_MODE_INDICATOR));
+}
+
+#if IS_REACHABLE(CONFIG_LEDS_CLASS_FLASH)
+static struct gb_channel *get_channel_from_cdev(struct led_classdev *cdev)
+{
+ struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(cdev);
+
+ return container_of(fled_cdev, struct gb_channel, fled);
+}
+
+static struct led_classdev *get_channel_cdev(struct gb_channel *channel)
+{
+ return &channel->fled.led_cdev;
+}
+
+static struct gb_channel *get_channel_from_mode(struct gb_light *light,
+ u32 mode)
+{
+ struct gb_channel *channel = NULL;
+ int i;
+
+ for (i = 0; i < light->channels_count; i++) {
+ channel = &light->channels[i];
+ if (channel && channel->mode == mode)
+ break;
+ }
+ return channel;
+}
+
+static int __gb_lights_flash_intensity_set(struct gb_channel *channel,
+ u32 intensity)
+{
+ struct gb_connection *connection = get_conn_from_channel(channel);
+ struct gb_bundle *bundle = connection->bundle;
+ struct gb_lights_set_flash_intensity_request req;
+ int ret;
+
+ if (channel->releasing)
+ return -ESHUTDOWN;
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret < 0)
+ return ret;
+
+ req.light_id = channel->light->id;
+ req.channel_id = channel->id;
+ req.intensity_uA = cpu_to_le32(intensity);
+
+ ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FLASH_INTENSITY,
+ &req, sizeof(req), NULL, 0);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return ret;
+}
+
+static int __gb_lights_flash_brightness_set(struct gb_channel *channel)
+{
+ u32 intensity;
+
+ /* If the channel is flash we need to get the attached torch channel */
+ if (channel->mode & GB_CHANNEL_MODE_FLASH)
+ channel = get_channel_from_mode(channel->light,
+ GB_CHANNEL_MODE_TORCH);
+
+ /* For not flash we need to convert brightness to intensity */
+ intensity = channel->intensity_uA.min +
+ (channel->intensity_uA.step * channel->led->brightness);
+
+ return __gb_lights_flash_intensity_set(channel, intensity);
+}
+#else
+static struct gb_channel *get_channel_from_cdev(struct led_classdev *cdev)
+{
+ return container_of(cdev, struct gb_channel, cled);
+}
+
+static struct led_classdev *get_channel_cdev(struct gb_channel *channel)
+{
+ return &channel->cled;
+}
+
+static int __gb_lights_flash_brightness_set(struct gb_channel *channel)
+{
+ return 0;
+}
+#endif
+
+static int gb_lights_color_set(struct gb_channel *channel, u32 color);
+static int gb_lights_fade_set(struct gb_channel *channel);
+
+static void led_lock(struct led_classdev *cdev)
+{
+ mutex_lock(&cdev->led_access);
+}
+
+static void led_unlock(struct led_classdev *cdev)
+{
+ mutex_unlock(&cdev->led_access);
+}
+
+#define gb_lights_fade_attr(__dir) \
+static ssize_t fade_##__dir##_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct led_classdev *cdev = dev_get_drvdata(dev); \
+ struct gb_channel *channel = get_channel_from_cdev(cdev); \
+ \
+ return sprintf(buf, "%u\n", channel->fade_##__dir); \
+} \
+ \
+static ssize_t fade_##__dir##_store(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t size) \
+{ \
+ struct led_classdev *cdev = dev_get_drvdata(dev); \
+ struct gb_channel *channel = get_channel_from_cdev(cdev); \
+ u8 fade; \
+ int ret; \
+ \
+ led_lock(cdev); \
+ if (led_sysfs_is_disabled(cdev)) { \
+ ret = -EBUSY; \
+ goto unlock; \
+ } \
+ \
+ ret = kstrtou8(buf, 0, &fade); \
+ if (ret < 0) { \
+ dev_err(dev, "could not parse fade value %d\n", ret); \
+ goto unlock; \
+ } \
+ if (channel->fade_##__dir == fade) \
+ goto unlock; \
+ channel->fade_##__dir = fade; \
+ \
+ ret = gb_lights_fade_set(channel); \
+ if (ret < 0) \
+ goto unlock; \
+ \
+ ret = size; \
+unlock: \
+ led_unlock(cdev); \
+ return ret; \
+} \
+static DEVICE_ATTR_RW(fade_##__dir)
+
+gb_lights_fade_attr(in);
+gb_lights_fade_attr(out);
+
+static ssize_t color_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct led_classdev *cdev = dev_get_drvdata(dev);
+ struct gb_channel *channel = get_channel_from_cdev(cdev);
+
+ return sprintf(buf, "0x%08x\n", channel->color);
+}
+
+static ssize_t color_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct led_classdev *cdev = dev_get_drvdata(dev);
+ struct gb_channel *channel = get_channel_from_cdev(cdev);
+ u32 color;
+ int ret;
+
+ led_lock(cdev);
+ if (led_sysfs_is_disabled(cdev)) {
+ ret = -EBUSY;
+ goto unlock;
+ }
+ ret = kstrtou32(buf, 0, &color);
+ if (ret < 0) {
+ dev_err(dev, "could not parse color value %d\n", ret);
+ goto unlock;
+ }
+
+ ret = gb_lights_color_set(channel, color);
+ if (ret < 0)
+ goto unlock;
+
+ channel->color = color;
+ ret = size;
+unlock:
+ led_unlock(cdev);
+ return ret;
+}
+static DEVICE_ATTR_RW(color);
+
+static int channel_attr_groups_set(struct gb_channel *channel,
+ struct led_classdev *cdev)
+{
+ int attr = 0;
+ int size = 0;
+
+ if (channel->flags & GB_LIGHT_CHANNEL_MULTICOLOR)
+ size++;
+ if (channel->flags & GB_LIGHT_CHANNEL_FADER)
+ size += 2;
+
+ if (!size)
+ return 0;
+
+ /* Set attributes based in the channel flags */
+ channel->attrs = kcalloc(size + 1, sizeof(*channel->attrs), GFP_KERNEL);
+ if (!channel->attrs)
+ return -ENOMEM;
+ channel->attr_group = kcalloc(1, sizeof(*channel->attr_group),
+ GFP_KERNEL);
+ if (!channel->attr_group)
+ return -ENOMEM;
+ channel->attr_groups = kcalloc(2, sizeof(*channel->attr_groups),
+ GFP_KERNEL);
+ if (!channel->attr_groups)
+ return -ENOMEM;
+
+ if (channel->flags & GB_LIGHT_CHANNEL_MULTICOLOR)
+ channel->attrs[attr++] = &dev_attr_color.attr;
+ if (channel->flags & GB_LIGHT_CHANNEL_FADER) {
+ channel->attrs[attr++] = &dev_attr_fade_in.attr;
+ channel->attrs[attr++] = &dev_attr_fade_out.attr;
+ }
+
+ channel->attr_group->attrs = channel->attrs;
+
+ channel->attr_groups[0] = channel->attr_group;
+
+ cdev->groups = channel->attr_groups;
+
+ return 0;
+}
+
+static int gb_lights_fade_set(struct gb_channel *channel)
+{
+ struct gb_connection *connection = get_conn_from_channel(channel);
+ struct gb_bundle *bundle = connection->bundle;
+ struct gb_lights_set_fade_request req;
+ int ret;
+
+ if (channel->releasing)
+ return -ESHUTDOWN;
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret < 0)
+ return ret;
+
+ req.light_id = channel->light->id;
+ req.channel_id = channel->id;
+ req.fade_in = channel->fade_in;
+ req.fade_out = channel->fade_out;
+ ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FADE,
+ &req, sizeof(req), NULL, 0);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return ret;
+}
+
+static int gb_lights_color_set(struct gb_channel *channel, u32 color)
+{
+ struct gb_connection *connection = get_conn_from_channel(channel);
+ struct gb_bundle *bundle = connection->bundle;
+ struct gb_lights_set_color_request req;
+ int ret;
+
+ if (channel->releasing)
+ return -ESHUTDOWN;
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret < 0)
+ return ret;
+
+ req.light_id = channel->light->id;
+ req.channel_id = channel->id;
+ req.color = cpu_to_le32(color);
+ ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_COLOR,
+ &req, sizeof(req), NULL, 0);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return ret;
+}
+
+static int __gb_lights_led_brightness_set(struct gb_channel *channel)
+{
+ struct gb_lights_set_brightness_request req;
+ struct gb_connection *connection = get_conn_from_channel(channel);
+ struct gb_bundle *bundle = connection->bundle;
+ bool old_active;
+ int ret;
+
+ mutex_lock(&channel->lock);
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret < 0)
+ goto out_unlock;
+
+ old_active = channel->active;
+
+ req.light_id = channel->light->id;
+ req.channel_id = channel->id;
+ req.brightness = (u8)channel->led->brightness;
+
+ ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_BRIGHTNESS,
+ &req, sizeof(req), NULL, 0);
+ if (ret < 0)
+ goto out_pm_put;
+
+ if (channel->led->brightness)
+ channel->active = true;
+ else
+ channel->active = false;
+
+ /* we need to keep module alive when turning to active state */
+ if (!old_active && channel->active)
+ goto out_unlock;
+
+ /*
+ * on the other hand if going to inactive we still hold a reference and
+ * need to put it, so we could go to suspend.
+ */
+ if (old_active && !channel->active)
+ gb_pm_runtime_put_autosuspend(bundle);
+
+out_pm_put:
+ gb_pm_runtime_put_autosuspend(bundle);
+out_unlock:
+ mutex_unlock(&channel->lock);
+
+ return ret;
+}
+
+static int __gb_lights_brightness_set(struct gb_channel *channel)
+{
+ int ret;
+
+ if (channel->releasing)
+ return 0;
+
+ if (is_channel_flash(channel))
+ ret = __gb_lights_flash_brightness_set(channel);
+ else
+ ret = __gb_lights_led_brightness_set(channel);
+
+ return ret;
+}
+
+static int gb_brightness_set(struct led_classdev *cdev,
+ enum led_brightness value)
+{
+ struct gb_channel *channel = get_channel_from_cdev(cdev);
+
+ channel->led->brightness = value;
+
+ return __gb_lights_brightness_set(channel);
+}
+
+static enum led_brightness gb_brightness_get(struct led_classdev *cdev)
+
+{
+ struct gb_channel *channel = get_channel_from_cdev(cdev);
+
+ return channel->led->brightness;
+}
+
+static int gb_blink_set(struct led_classdev *cdev, unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ struct gb_channel *channel = get_channel_from_cdev(cdev);
+ struct gb_connection *connection = get_conn_from_channel(channel);
+ struct gb_bundle *bundle = connection->bundle;
+ struct gb_lights_blink_request req;
+ bool old_active;
+ int ret;
+
+ if (channel->releasing)
+ return -ESHUTDOWN;
+
+ if (!delay_on || !delay_off)
+ return -EINVAL;
+
+ mutex_lock(&channel->lock);
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret < 0)
+ goto out_unlock;
+
+ old_active = channel->active;
+
+ req.light_id = channel->light->id;
+ req.channel_id = channel->id;
+ req.time_on_ms = cpu_to_le16(*delay_on);
+ req.time_off_ms = cpu_to_le16(*delay_off);
+
+ ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_BLINK, &req,
+ sizeof(req), NULL, 0);
+ if (ret < 0)
+ goto out_pm_put;
+
+ if (*delay_on)
+ channel->active = true;
+ else
+ channel->active = false;
+
+ /* we need to keep module alive when turning to active state */
+ if (!old_active && channel->active)
+ goto out_unlock;
+
+ /*
+ * on the other hand if going to inactive we still hold a reference and
+ * need to put it, so we could go to suspend.
+ */
+ if (old_active && !channel->active)
+ gb_pm_runtime_put_autosuspend(bundle);
+
+out_pm_put:
+ gb_pm_runtime_put_autosuspend(bundle);
+out_unlock:
+ mutex_unlock(&channel->lock);
+
+ return ret;
+}
+
+static void gb_lights_led_operations_set(struct gb_channel *channel,
+ struct led_classdev *cdev)
+{
+ cdev->brightness_get = gb_brightness_get;
+ cdev->brightness_set_blocking = gb_brightness_set;
+
+ if (channel->flags & GB_LIGHT_CHANNEL_BLINK)
+ cdev->blink_set = gb_blink_set;
+}
+
+#if IS_REACHABLE(CONFIG_V4L2_FLASH_LED_CLASS)
+/* V4L2 specific helpers */
+static const struct v4l2_flash_ops v4l2_flash_ops;
+
+static void __gb_lights_channel_v4l2_config(struct led_flash_setting *channel_s,
+ struct led_flash_setting *v4l2_s)
+{
+ v4l2_s->min = channel_s->min;
+ v4l2_s->max = channel_s->max;
+ v4l2_s->step = channel_s->step;
+ /* For v4l2 val is the default value */
+ v4l2_s->val = channel_s->max;
+}
+
+static int gb_lights_light_v4l2_register(struct gb_light *light)
+{
+ struct gb_connection *connection = get_conn_from_light(light);
+ struct device *dev = &connection->bundle->dev;
+ struct v4l2_flash_config *sd_cfg;
+ struct led_classdev_flash *fled;
+ struct led_classdev_flash *iled = NULL;
+ struct gb_channel *channel_torch, *channel_ind, *channel_flash;
+ int ret = 0;
+
+ sd_cfg = kcalloc(1, sizeof(*sd_cfg), GFP_KERNEL);
+ if (!sd_cfg)
+ return -ENOMEM;
+
+ channel_torch = get_channel_from_mode(light, GB_CHANNEL_MODE_TORCH);
+ if (channel_torch)
+ __gb_lights_channel_v4l2_config(&channel_torch->intensity_uA,
+ &sd_cfg->torch_intensity);
+
+ channel_ind = get_channel_from_mode(light, GB_CHANNEL_MODE_INDICATOR);
+ if (channel_ind) {
+ __gb_lights_channel_v4l2_config(&channel_ind->intensity_uA,
+ &sd_cfg->indicator_intensity);
+ iled = &channel_ind->fled;
+ }
+
+ channel_flash = get_channel_from_mode(light, GB_CHANNEL_MODE_FLASH);
+ WARN_ON(!channel_flash);
+
+ fled = &channel_flash->fled;
+
+ snprintf(sd_cfg->dev_name, sizeof(sd_cfg->dev_name), "%s", light->name);
+
+ /* Set the possible values to faults, in our case all faults */
+ sd_cfg->flash_faults = LED_FAULT_OVER_VOLTAGE | LED_FAULT_TIMEOUT |
+ LED_FAULT_OVER_TEMPERATURE | LED_FAULT_SHORT_CIRCUIT |
+ LED_FAULT_OVER_CURRENT | LED_FAULT_INDICATOR |
+ LED_FAULT_UNDER_VOLTAGE | LED_FAULT_INPUT_VOLTAGE |
+ LED_FAULT_LED_OVER_TEMPERATURE;
+
+ light->v4l2_flash = v4l2_flash_init(dev, NULL, fled, iled,
+ &v4l2_flash_ops, sd_cfg);
+ if (IS_ERR_OR_NULL(light->v4l2_flash)) {
+ ret = PTR_ERR(light->v4l2_flash);
+ goto out_free;
+ }
+
+ return ret;
+
+out_free:
+ kfree(sd_cfg);
+ return ret;
+}
+
+static void gb_lights_light_v4l2_unregister(struct gb_light *light)
+{
+ v4l2_flash_release(light->v4l2_flash);
+}
+#else
+static int gb_lights_light_v4l2_register(struct gb_light *light)
+{
+ struct gb_connection *connection = get_conn_from_light(light);
+
+ dev_err(&connection->bundle->dev, "no support for v4l2 subdevices\n");
+ return 0;
+}
+
+static void gb_lights_light_v4l2_unregister(struct gb_light *light)
+{
+}
+#endif
+
+#if IS_REACHABLE(CONFIG_LEDS_CLASS_FLASH)
+/* Flash specific operations */
+static int gb_lights_flash_intensity_set(struct led_classdev_flash *fcdev,
+ u32 brightness)
+{
+ struct gb_channel *channel = container_of(fcdev, struct gb_channel,
+ fled);
+ int ret;
+
+ ret = __gb_lights_flash_intensity_set(channel, brightness);
+ if (ret < 0)
+ return ret;
+
+ fcdev->brightness.val = brightness;
+
+ return 0;
+}
+
+static int gb_lights_flash_intensity_get(struct led_classdev_flash *fcdev,
+ u32 *brightness)
+{
+ *brightness = fcdev->brightness.val;
+
+ return 0;
+}
+
+static int gb_lights_flash_strobe_set(struct led_classdev_flash *fcdev,
+ bool state)
+{
+ struct gb_channel *channel = container_of(fcdev, struct gb_channel,
+ fled);
+ struct gb_connection *connection = get_conn_from_channel(channel);
+ struct gb_bundle *bundle = connection->bundle;
+ struct gb_lights_set_flash_strobe_request req;
+ int ret;
+
+ if (channel->releasing)
+ return -ESHUTDOWN;
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret < 0)
+ return ret;
+
+ req.light_id = channel->light->id;
+ req.channel_id = channel->id;
+ req.state = state ? 1 : 0;
+
+ ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FLASH_STROBE,
+ &req, sizeof(req), NULL, 0);
+ if (!ret)
+ channel->strobe_state = state;
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return ret;
+}
+
+static int gb_lights_flash_strobe_get(struct led_classdev_flash *fcdev,
+ bool *state)
+{
+ struct gb_channel *channel = container_of(fcdev, struct gb_channel,
+ fled);
+
+ *state = channel->strobe_state;
+ return 0;
+}
+
+static int gb_lights_flash_timeout_set(struct led_classdev_flash *fcdev,
+ u32 timeout)
+{
+ struct gb_channel *channel = container_of(fcdev, struct gb_channel,
+ fled);
+ struct gb_connection *connection = get_conn_from_channel(channel);
+ struct gb_bundle *bundle = connection->bundle;
+ struct gb_lights_set_flash_timeout_request req;
+ int ret;
+
+ if (channel->releasing)
+ return -ESHUTDOWN;
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret < 0)
+ return ret;
+
+ req.light_id = channel->light->id;
+ req.channel_id = channel->id;
+ req.timeout_us = cpu_to_le32(timeout);
+
+ ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_SET_FLASH_TIMEOUT,
+ &req, sizeof(req), NULL, 0);
+ if (!ret)
+ fcdev->timeout.val = timeout;
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return ret;
+}
+
+static int gb_lights_flash_fault_get(struct led_classdev_flash *fcdev,
+ u32 *fault)
+{
+ struct gb_channel *channel = container_of(fcdev, struct gb_channel,
+ fled);
+ struct gb_connection *connection = get_conn_from_channel(channel);
+ struct gb_bundle *bundle = connection->bundle;
+ struct gb_lights_get_flash_fault_request req;
+ struct gb_lights_get_flash_fault_response resp;
+ int ret;
+
+ if (channel->releasing)
+ return -ESHUTDOWN;
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret < 0)
+ return ret;
+
+ req.light_id = channel->light->id;
+ req.channel_id = channel->id;
+
+ ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_GET_FLASH_FAULT,
+ &req, sizeof(req), &resp, sizeof(resp));
+ if (!ret)
+ *fault = le32_to_cpu(resp.fault);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return ret;
+}
+
+static const struct led_flash_ops gb_lights_flash_ops = {
+ .flash_brightness_set = gb_lights_flash_intensity_set,
+ .flash_brightness_get = gb_lights_flash_intensity_get,
+ .strobe_set = gb_lights_flash_strobe_set,
+ .strobe_get = gb_lights_flash_strobe_get,
+ .timeout_set = gb_lights_flash_timeout_set,
+ .fault_get = gb_lights_flash_fault_get,
+};
+
+static int __gb_lights_channel_torch_attach(struct gb_channel *channel,
+ struct gb_channel *channel_torch)
+{
+ char *name;
+
+ /* we can only attach torch to a flash channel */
+ if (!(channel->mode & GB_CHANNEL_MODE_FLASH))
+ return 0;
+
+ /* Move torch brightness to the destination */
+ channel->led->max_brightness = channel_torch->led->max_brightness;
+
+ /* append mode name to flash name */
+ name = kasprintf(GFP_KERNEL, "%s_%s", channel->led->name,
+ channel_torch->mode_name);
+ if (!name)
+ return -ENOMEM;
+ kfree(channel->led->name);
+ channel->led->name = name;
+
+ channel_torch->led = channel->led;
+
+ return 0;
+}
+
+static int __gb_lights_flash_led_register(struct gb_channel *channel)
+{
+ struct gb_connection *connection = get_conn_from_channel(channel);
+ struct led_classdev_flash *fled = &channel->fled;
+ struct led_flash_setting *fset;
+ struct gb_channel *channel_torch;
+ int ret;
+
+ fled->ops = &gb_lights_flash_ops;
+
+ fled->led_cdev.flags |= LED_DEV_CAP_FLASH;
+
+ fset = &fled->brightness;
+ fset->min = channel->intensity_uA.min;
+ fset->max = channel->intensity_uA.max;
+ fset->step = channel->intensity_uA.step;
+ fset->val = channel->intensity_uA.max;
+
+ /* Only the flash mode have the timeout constraints settings */
+ if (channel->mode & GB_CHANNEL_MODE_FLASH) {
+ fset = &fled->timeout;
+ fset->min = channel->timeout_us.min;
+ fset->max = channel->timeout_us.max;
+ fset->step = channel->timeout_us.step;
+ fset->val = channel->timeout_us.max;
+ }
+
+ /*
+ * If light have torch mode channel, this channel will be the led
+ * classdev of the registered above flash classdev
+ */
+ channel_torch = get_channel_from_mode(channel->light,
+ GB_CHANNEL_MODE_TORCH);
+ if (channel_torch) {
+ ret = __gb_lights_channel_torch_attach(channel, channel_torch);
+ if (ret < 0)
+ goto fail;
+ }
+
+ ret = led_classdev_flash_register(&connection->bundle->dev, fled);
+ if (ret < 0)
+ goto fail;
+
+ channel->is_registered = true;
+ return 0;
+fail:
+ channel->led = NULL;
+ return ret;
+}
+
+static void __gb_lights_flash_led_unregister(struct gb_channel *channel)
+{
+ if (!channel->is_registered)
+ return;
+
+ led_classdev_flash_unregister(&channel->fled);
+}
+
+static int gb_lights_channel_flash_config(struct gb_channel *channel)
+{
+ struct gb_connection *connection = get_conn_from_channel(channel);
+ struct gb_lights_get_channel_flash_config_request req;
+ struct gb_lights_get_channel_flash_config_response conf;
+ struct led_flash_setting *fset;
+ int ret;
+
+ req.light_id = channel->light->id;
+ req.channel_id = channel->id;
+
+ ret = gb_operation_sync(connection,
+ GB_LIGHTS_TYPE_GET_CHANNEL_FLASH_CONFIG,
+ &req, sizeof(req), &conf, sizeof(conf));
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Intensity constraints for flash related modes: flash, torch,
+ * indicator. They will be needed for v4l2 registration.
+ */
+ fset = &channel->intensity_uA;
+ fset->min = le32_to_cpu(conf.intensity_min_uA);
+ fset->max = le32_to_cpu(conf.intensity_max_uA);
+ fset->step = le32_to_cpu(conf.intensity_step_uA);
+
+ /*
+ * On flash type, max brightness is set as the number of intensity steps
+ * available.
+ */
+ channel->led->max_brightness = (fset->max - fset->min) / fset->step;
+
+ /* Only the flash mode have the timeout constraints settings */
+ if (channel->mode & GB_CHANNEL_MODE_FLASH) {
+ fset = &channel->timeout_us;
+ fset->min = le32_to_cpu(conf.timeout_min_us);
+ fset->max = le32_to_cpu(conf.timeout_max_us);
+ fset->step = le32_to_cpu(conf.timeout_step_us);
+ }
+
+ return 0;
+}
+#else
+static int gb_lights_channel_flash_config(struct gb_channel *channel)
+{
+ struct gb_connection *connection = get_conn_from_channel(channel);
+
+ dev_err(&connection->bundle->dev, "no support for flash devices\n");
+ return 0;
+}
+
+static int __gb_lights_flash_led_register(struct gb_channel *channel)
+{
+ return 0;
+}
+
+static void __gb_lights_flash_led_unregister(struct gb_channel *channel)
+{
+}
+
+#endif
+
+static int __gb_lights_led_register(struct gb_channel *channel)
+{
+ struct gb_connection *connection = get_conn_from_channel(channel);
+ struct led_classdev *cdev = get_channel_cdev(channel);
+ int ret;
+
+ ret = led_classdev_register(&connection->bundle->dev, cdev);
+ if (ret < 0)
+ channel->led = NULL;
+ else
+ channel->is_registered = true;
+ return ret;
+}
+
+static int gb_lights_channel_register(struct gb_channel *channel)
+{
+ /* Normal LED channel, just register in led classdev and we are done */
+ if (!is_channel_flash(channel))
+ return __gb_lights_led_register(channel);
+
+ /*
+ * Flash Type need more work, register flash classdev, indicator as
+ * flash classdev, torch will be led classdev of the flash classdev.
+ */
+ if (!(channel->mode & GB_CHANNEL_MODE_TORCH))
+ return __gb_lights_flash_led_register(channel);
+
+ return 0;
+}
+
+static void __gb_lights_led_unregister(struct gb_channel *channel)
+{
+ struct led_classdev *cdev = get_channel_cdev(channel);
+
+ if (!channel->is_registered)
+ return;
+
+ led_classdev_unregister(cdev);
+ channel->led = NULL;
+}
+
+static void gb_lights_channel_unregister(struct gb_channel *channel)
+{
+ /* The same as register, handle channels differently */
+ if (!is_channel_flash(channel)) {
+ __gb_lights_led_unregister(channel);
+ return;
+ }
+
+ if (channel->mode & GB_CHANNEL_MODE_TORCH)
+ __gb_lights_led_unregister(channel);
+ else
+ __gb_lights_flash_led_unregister(channel);
+}
+
+static int gb_lights_channel_config(struct gb_light *light,
+ struct gb_channel *channel)
+{
+ struct gb_lights_get_channel_config_response conf;
+ struct gb_lights_get_channel_config_request req;
+ struct gb_connection *connection = get_conn_from_light(light);
+ struct led_classdev *cdev = get_channel_cdev(channel);
+ char *name;
+ int ret;
+
+ req.light_id = light->id;
+ req.channel_id = channel->id;
+
+ ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_GET_CHANNEL_CONFIG,
+ &req, sizeof(req), &conf, sizeof(conf));
+ if (ret < 0)
+ return ret;
+
+ channel->light = light;
+ channel->mode = le32_to_cpu(conf.mode);
+ channel->flags = le32_to_cpu(conf.flags);
+ channel->color = le32_to_cpu(conf.color);
+ channel->color_name = kstrndup(conf.color_name, NAMES_MAX, GFP_KERNEL);
+ if (!channel->color_name)
+ return -ENOMEM;
+ channel->mode_name = kstrndup(conf.mode_name, NAMES_MAX, GFP_KERNEL);
+ if (!channel->mode_name)
+ return -ENOMEM;
+
+ channel->led = cdev;
+
+ name = kasprintf(GFP_KERNEL, "%s:%s:%s", light->name,
+ channel->color_name, channel->mode_name);
+ if (!name)
+ return -ENOMEM;
+
+ cdev->name = name;
+
+ cdev->max_brightness = conf.max_brightness;
+
+ ret = channel_attr_groups_set(channel, cdev);
+ if (ret < 0)
+ return ret;
+
+ gb_lights_led_operations_set(channel, cdev);
+
+ /*
+ * If it is not a flash related channel (flash, torch or indicator) we
+ * are done here. If not, continue and fetch flash related
+ * configurations.
+ */
+ if (!is_channel_flash(channel))
+ return ret;
+
+ light->has_flash = true;
+
+ ret = gb_lights_channel_flash_config(channel);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+
+static int gb_lights_light_config(struct gb_lights *glights, u8 id)
+{
+ struct gb_light *light = &glights->lights[id];
+ struct gb_lights_get_light_config_request req;
+ struct gb_lights_get_light_config_response conf;
+ int ret;
+ int i;
+
+ light->glights = glights;
+ light->id = id;
+
+ req.id = id;
+
+ ret = gb_operation_sync(glights->connection,
+ GB_LIGHTS_TYPE_GET_LIGHT_CONFIG,
+ &req, sizeof(req), &conf, sizeof(conf));
+ if (ret < 0)
+ return ret;
+
+ if (!conf.channel_count)
+ return -EINVAL;
+ if (!strlen(conf.name))
+ return -EINVAL;
+
+ light->channels_count = conf.channel_count;
+ light->name = kstrndup(conf.name, NAMES_MAX, GFP_KERNEL);
+
+ light->channels = kzalloc(light->channels_count *
+ sizeof(struct gb_channel), GFP_KERNEL);
+ if (!light->channels)
+ return -ENOMEM;
+
+ /* First we collect all the configurations for all channels */
+ for (i = 0; i < light->channels_count; i++) {
+ light->channels[i].id = i;
+ ret = gb_lights_channel_config(light, &light->channels[i]);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int gb_lights_light_register(struct gb_light *light)
+{
+ int ret;
+ int i;
+
+ /*
+ * Then, if everything went ok in getting configurations, we register
+ * the classdev, flash classdev and v4l2 subsystem, if a flash device is
+ * found.
+ */
+ for (i = 0; i < light->channels_count; i++) {
+ ret = gb_lights_channel_register(&light->channels[i]);
+ if (ret < 0)
+ return ret;
+
+ mutex_init(&light->channels[i].lock);
+ }
+
+ light->ready = true;
+
+ if (light->has_flash) {
+ ret = gb_lights_light_v4l2_register(light);
+ if (ret < 0) {
+ light->has_flash = false;
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void gb_lights_channel_free(struct gb_channel *channel)
+{
+ kfree(channel->attrs);
+ kfree(channel->attr_group);
+ kfree(channel->attr_groups);
+ kfree(channel->color_name);
+ kfree(channel->mode_name);
+ mutex_destroy(&channel->lock);
+}
+
+static void gb_lights_channel_release(struct gb_channel *channel)
+{
+ channel->releasing = true;
+
+ gb_lights_channel_unregister(channel);
+
+ gb_lights_channel_free(channel);
+}
+
+static void gb_lights_light_release(struct gb_light *light)
+{
+ int i;
+ int count;
+
+ light->ready = false;
+
+ count = light->channels_count;
+
+ if (light->has_flash)
+ gb_lights_light_v4l2_unregister(light);
+
+ for (i = 0; i < count; i++) {
+ gb_lights_channel_release(&light->channels[i]);
+ light->channels_count--;
+ }
+ kfree(light->channels);
+ kfree(light->name);
+}
+
+static void gb_lights_release(struct gb_lights *glights)
+{
+ int i;
+
+ if (!glights)
+ return;
+
+ mutex_lock(&glights->lights_lock);
+ if (!glights->lights)
+ goto free_glights;
+
+ for (i = 0; i < glights->lights_count; i++)
+ gb_lights_light_release(&glights->lights[i]);
+
+ kfree(glights->lights);
+
+free_glights:
+ mutex_unlock(&glights->lights_lock);
+ mutex_destroy(&glights->lights_lock);
+ kfree(glights);
+}
+
+static int gb_lights_get_count(struct gb_lights *glights)
+{
+ struct gb_lights_get_lights_response resp;
+ int ret;
+
+ ret = gb_operation_sync(glights->connection, GB_LIGHTS_TYPE_GET_LIGHTS,
+ NULL, 0, &resp, sizeof(resp));
+ if (ret < 0)
+ return ret;
+
+ if (!resp.lights_count)
+ return -EINVAL;
+
+ glights->lights_count = resp.lights_count;
+
+ return 0;
+}
+
+static int gb_lights_create_all(struct gb_lights *glights)
+{
+ struct gb_connection *connection = glights->connection;
+ int ret;
+ int i;
+
+ mutex_lock(&glights->lights_lock);
+ ret = gb_lights_get_count(glights);
+ if (ret < 0)
+ goto out;
+
+ glights->lights = kzalloc(glights->lights_count *
+ sizeof(struct gb_light), GFP_KERNEL);
+ if (!glights->lights) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ for (i = 0; i < glights->lights_count; i++) {
+ ret = gb_lights_light_config(glights, i);
+ if (ret < 0) {
+ dev_err(&connection->bundle->dev,
+ "Fail to configure lights device\n");
+ goto out;
+ }
+ }
+
+out:
+ mutex_unlock(&glights->lights_lock);
+ return ret;
+}
+
+static int gb_lights_register_all(struct gb_lights *glights)
+{
+ struct gb_connection *connection = glights->connection;
+ int ret = 0;
+ int i;
+
+ mutex_lock(&glights->lights_lock);
+ for (i = 0; i < glights->lights_count; i++) {
+ ret = gb_lights_light_register(&glights->lights[i]);
+ if (ret < 0) {
+ dev_err(&connection->bundle->dev,
+ "Fail to enable lights device\n");
+ break;
+ }
+ }
+
+ mutex_unlock(&glights->lights_lock);
+ return ret;
+}
+
+static int gb_lights_request_handler(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct device *dev = &connection->bundle->dev;
+ struct gb_lights *glights = gb_connection_get_data(connection);
+ struct gb_light *light;
+ struct gb_message *request;
+ struct gb_lights_event_request *payload;
+ int ret = 0;
+ u8 light_id;
+ u8 event;
+
+ if (op->type != GB_LIGHTS_TYPE_EVENT) {
+ dev_err(dev, "Unsupported unsolicited event: %u\n", op->type);
+ return -EINVAL;
+ }
+
+ request = op->request;
+
+ if (request->payload_size < sizeof(*payload)) {
+ dev_err(dev, "Wrong event size received (%zu < %zu)\n",
+ request->payload_size, sizeof(*payload));
+ return -EINVAL;
+ }
+
+ payload = request->payload;
+ light_id = payload->light_id;
+
+ if (light_id >= glights->lights_count ||
+ !glights->lights[light_id].ready) {
+ dev_err(dev, "Event received for unconfigured light id: %d\n",
+ light_id);
+ return -EINVAL;
+ }
+
+ event = payload->event;
+
+ if (event & GB_LIGHTS_LIGHT_CONFIG) {
+ light = &glights->lights[light_id];
+
+ mutex_lock(&glights->lights_lock);
+ gb_lights_light_release(light);
+ ret = gb_lights_light_config(glights, light_id);
+ if (!ret)
+ ret = gb_lights_light_register(light);
+ if (ret < 0)
+ gb_lights_light_release(light);
+ mutex_unlock(&glights->lights_lock);
+ }
+
+ return ret;
+}
+
+static int gb_lights_probe(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id)
+{
+ struct greybus_descriptor_cport *cport_desc;
+ struct gb_connection *connection;
+ struct gb_lights *glights;
+ int ret;
+
+ if (bundle->num_cports != 1)
+ return -ENODEV;
+
+ cport_desc = &bundle->cport_desc[0];
+ if (cport_desc->protocol_id != GREYBUS_PROTOCOL_LIGHTS)
+ return -ENODEV;
+
+ glights = kzalloc(sizeof(*glights), GFP_KERNEL);
+ if (!glights)
+ return -ENOMEM;
+
+ mutex_init(&glights->lights_lock);
+
+ connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
+ gb_lights_request_handler);
+ if (IS_ERR(connection)) {
+ ret = PTR_ERR(connection);
+ goto out;
+ }
+
+ glights->connection = connection;
+ gb_connection_set_data(connection, glights);
+
+ greybus_set_drvdata(bundle, glights);
+
+ /* We aren't ready to receive an incoming request yet */
+ ret = gb_connection_enable_tx(connection);
+ if (ret)
+ goto error_connection_destroy;
+
+ /*
+ * Setup all the lights devices over this connection, if anything goes
+ * wrong tear down all lights
+ */
+ ret = gb_lights_create_all(glights);
+ if (ret < 0)
+ goto error_connection_disable;
+
+ /* We are ready to receive an incoming request now, enable RX as well */
+ ret = gb_connection_enable(connection);
+ if (ret)
+ goto error_connection_disable;
+
+ /* Enable & register lights */
+ ret = gb_lights_register_all(glights);
+ if (ret < 0)
+ goto error_connection_disable;
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return 0;
+
+error_connection_disable:
+ gb_connection_disable(connection);
+error_connection_destroy:
+ gb_connection_destroy(connection);
+out:
+ gb_lights_release(glights);
+ return ret;
+}
+
+static void gb_lights_disconnect(struct gb_bundle *bundle)
+{
+ struct gb_lights *glights = greybus_get_drvdata(bundle);
+
+ if (gb_pm_runtime_get_sync(bundle))
+ gb_pm_runtime_get_noresume(bundle);
+
+ gb_connection_disable(glights->connection);
+ gb_connection_destroy(glights->connection);
+
+ gb_lights_release(glights);
+}
+
+static const struct greybus_bundle_id gb_lights_id_table[] = {
+ { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LIGHTS) },
+ { }
+};
+MODULE_DEVICE_TABLE(greybus, gb_lights_id_table);
+
+static struct greybus_driver gb_lights_driver = {
+ .name = "lights",
+ .probe = gb_lights_probe,
+ .disconnect = gb_lights_disconnect,
+ .id_table = gb_lights_id_table,
+};
+module_greybus_driver(gb_lights_driver);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/log.c b/drivers/staging/greybus/log.c
new file mode 100644
index 000000000000..70dd9e5a1cf2
--- /dev/null
+++ b/drivers/staging/greybus/log.c
@@ -0,0 +1,132 @@
+/*
+ * Greybus driver for the log protocol
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sizes.h>
+#include <linux/uaccess.h>
+
+#include "greybus.h"
+
+struct gb_log {
+ struct gb_connection *connection;
+};
+
+static int gb_log_request_handler(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct device *dev = &connection->bundle->dev;
+ struct gb_log_send_log_request *receive;
+ u16 len;
+
+ if (op->type != GB_LOG_TYPE_SEND_LOG) {
+ dev_err(dev, "unknown request type 0x%02x\n", op->type);
+ return -EINVAL;
+ }
+
+ /* Verify size of payload */
+ if (op->request->payload_size < sizeof(*receive)) {
+ dev_err(dev, "log request too small (%zu < %zu)\n",
+ op->request->payload_size, sizeof(*receive));
+ return -EINVAL;
+ }
+ receive = op->request->payload;
+ len = le16_to_cpu(receive->len);
+ if (len != (int)(op->request->payload_size - sizeof(*receive))) {
+ dev_err(dev, "log request wrong size %d vs %d\n", len,
+ (int)(op->request->payload_size - sizeof(*receive)));
+ return -EINVAL;
+ }
+ if (len == 0) {
+ dev_err(dev, "log request of 0 bytes?\n");
+ return -EINVAL;
+ }
+
+ if (len > GB_LOG_MAX_LEN) {
+ dev_err(dev, "log request too big: %d\n", len);
+ return -EINVAL;
+ }
+
+ /* Ensure the buffer is 0 terminated */
+ receive->msg[len - 1] = '\0';
+
+ /* Print with dev_dbg() so that it can be easily turned off using
+ * dynamic debugging (and prevent any DoS) */
+ dev_dbg(dev, "%s", receive->msg);
+
+ return 0;
+}
+
+static int gb_log_probe(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id)
+{
+ struct greybus_descriptor_cport *cport_desc;
+ struct gb_connection *connection;
+ struct gb_log *log;
+ int retval;
+
+ if (bundle->num_cports != 1)
+ return -ENODEV;
+
+ cport_desc = &bundle->cport_desc[0];
+ if (cport_desc->protocol_id != GREYBUS_PROTOCOL_LOG)
+ return -ENODEV;
+
+ log = kzalloc(sizeof(*log), GFP_KERNEL);
+ if (!log)
+ return -ENOMEM;
+
+ connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
+ gb_log_request_handler);
+ if (IS_ERR(connection)) {
+ retval = PTR_ERR(connection);
+ goto error_free;
+ }
+
+ log->connection = connection;
+ greybus_set_drvdata(bundle, log);
+
+ retval = gb_connection_enable(connection);
+ if (retval)
+ goto error_connection_destroy;
+
+ return 0;
+
+error_connection_destroy:
+ gb_connection_destroy(connection);
+error_free:
+ kfree(log);
+ return retval;
+}
+
+static void gb_log_disconnect(struct gb_bundle *bundle)
+{
+ struct gb_log *log = greybus_get_drvdata(bundle);
+ struct gb_connection *connection = log->connection;
+
+ gb_connection_disable(connection);
+ gb_connection_destroy(connection);
+
+ kfree(log);
+}
+
+static const struct greybus_bundle_id gb_log_id_table[] = {
+ { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LOG) },
+ { }
+};
+MODULE_DEVICE_TABLE(greybus, gb_log_id_table);
+
+static struct greybus_driver gb_log_driver = {
+ .name = "log",
+ .probe = gb_log_probe,
+ .disconnect = gb_log_disconnect,
+ .id_table = gb_log_id_table,
+};
+module_greybus_driver(gb_log_driver);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c
new file mode 100644
index 000000000000..7882306adeca
--- /dev/null
+++ b/drivers/staging/greybus/loopback.c
@@ -0,0 +1,1364 @@
+/*
+ * Loopback bridge driver for the Greybus loopback module.
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+#include <linux/sizes.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/kfifo.h>
+#include <linux/debugfs.h>
+#include <linux/list_sort.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/atomic.h>
+#include <linux/pm_runtime.h>
+
+#include <asm/div64.h>
+
+#include "greybus.h"
+#include "connection.h"
+
+#define NSEC_PER_DAY 86400000000000ULL
+
+struct gb_loopback_stats {
+ u32 min;
+ u32 max;
+ u64 sum;
+ u32 count;
+};
+
+struct gb_loopback_device {
+ struct dentry *root;
+ u32 count;
+ size_t size_max;
+
+ /* We need to take a lock in atomic context */
+ spinlock_t lock;
+ struct list_head list;
+ struct list_head list_op_async;
+ wait_queue_head_t wq;
+};
+
+static struct gb_loopback_device gb_dev;
+
+struct gb_loopback_async_operation {
+ struct gb_loopback *gb;
+ struct gb_operation *operation;
+ struct timeval ts;
+ struct timer_list timer;
+ struct list_head entry;
+ struct work_struct work;
+ struct kref kref;
+ bool pending;
+ int (*completion)(struct gb_loopback_async_operation *op_async);
+};
+
+struct gb_loopback {
+ struct gb_connection *connection;
+
+ struct dentry *file;
+ struct kfifo kfifo_lat;
+ struct kfifo kfifo_ts;
+ struct mutex mutex;
+ struct task_struct *task;
+ struct list_head entry;
+ struct device *dev;
+ wait_queue_head_t wq;
+ wait_queue_head_t wq_completion;
+ atomic_t outstanding_operations;
+
+ /* Per connection stats */
+ struct timeval ts;
+ struct gb_loopback_stats latency;
+ struct gb_loopback_stats throughput;
+ struct gb_loopback_stats requests_per_second;
+ struct gb_loopback_stats apbridge_unipro_latency;
+ struct gb_loopback_stats gbphy_firmware_latency;
+
+ int type;
+ int async;
+ int id;
+ u32 size;
+ u32 iteration_max;
+ u32 iteration_count;
+ int us_wait;
+ u32 error;
+ u32 requests_completed;
+ u32 requests_timedout;
+ u32 timeout;
+ u32 jiffy_timeout;
+ u32 timeout_min;
+ u32 timeout_max;
+ u32 outstanding_operations_max;
+ u32 lbid;
+ u64 elapsed_nsecs;
+ u32 apbridge_latency_ts;
+ u32 gbphy_latency_ts;
+
+ u32 send_count;
+};
+
+static struct class loopback_class = {
+ .name = "gb_loopback",
+ .owner = THIS_MODULE,
+};
+static DEFINE_IDA(loopback_ida);
+
+/* Min/max values in jiffies */
+#define GB_LOOPBACK_TIMEOUT_MIN 1
+#define GB_LOOPBACK_TIMEOUT_MAX 10000
+
+#define GB_LOOPBACK_FIFO_DEFAULT 8192
+
+static unsigned kfifo_depth = GB_LOOPBACK_FIFO_DEFAULT;
+module_param(kfifo_depth, uint, 0444);
+
+/* Maximum size of any one send data buffer we support */
+#define MAX_PACKET_SIZE (PAGE_SIZE * 2)
+
+#define GB_LOOPBACK_US_WAIT_MAX 1000000
+
+/* interface sysfs attributes */
+#define gb_loopback_ro_attr(field) \
+static ssize_t field##_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct gb_loopback *gb = dev_get_drvdata(dev); \
+ return sprintf(buf, "%u\n", gb->field); \
+} \
+static DEVICE_ATTR_RO(field)
+
+#define gb_loopback_ro_stats_attr(name, field, type) \
+static ssize_t name##_##field##_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct gb_loopback *gb = dev_get_drvdata(dev); \
+ /* Report 0 for min and max if no transfer successed */ \
+ if (!gb->requests_completed) \
+ return sprintf(buf, "0\n"); \
+ return sprintf(buf, "%"#type"\n", gb->name.field); \
+} \
+static DEVICE_ATTR_RO(name##_##field)
+
+#define gb_loopback_ro_avg_attr(name) \
+static ssize_t name##_avg_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct gb_loopback_stats *stats; \
+ struct gb_loopback *gb; \
+ u64 avg, rem; \
+ u32 count; \
+ gb = dev_get_drvdata(dev); \
+ stats = &gb->name; \
+ count = stats->count ? stats->count : 1; \
+ avg = stats->sum + count / 2000000; /* round closest */ \
+ rem = do_div(avg, count); \
+ rem *= 1000000; \
+ do_div(rem, count); \
+ return sprintf(buf, "%llu.%06u\n", avg, (u32)rem); \
+} \
+static DEVICE_ATTR_RO(name##_avg)
+
+#define gb_loopback_stats_attrs(field) \
+ gb_loopback_ro_stats_attr(field, min, u); \
+ gb_loopback_ro_stats_attr(field, max, u); \
+ gb_loopback_ro_avg_attr(field)
+
+#define gb_loopback_attr(field, type) \
+static ssize_t field##_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct gb_loopback *gb = dev_get_drvdata(dev); \
+ return sprintf(buf, "%"#type"\n", gb->field); \
+} \
+static ssize_t field##_store(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, \
+ size_t len) \
+{ \
+ int ret; \
+ struct gb_loopback *gb = dev_get_drvdata(dev); \
+ mutex_lock(&gb->mutex); \
+ ret = sscanf(buf, "%"#type, &gb->field); \
+ if (ret != 1) \
+ len = -EINVAL; \
+ else \
+ gb_loopback_check_attr(gb, bundle); \
+ mutex_unlock(&gb->mutex); \
+ return len; \
+} \
+static DEVICE_ATTR_RW(field)
+
+#define gb_dev_loopback_ro_attr(field, conn) \
+static ssize_t field##_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct gb_loopback *gb = dev_get_drvdata(dev); \
+ return sprintf(buf, "%u\n", gb->field); \
+} \
+static DEVICE_ATTR_RO(field)
+
+#define gb_dev_loopback_rw_attr(field, type) \
+static ssize_t field##_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct gb_loopback *gb = dev_get_drvdata(dev); \
+ return sprintf(buf, "%"#type"\n", gb->field); \
+} \
+static ssize_t field##_store(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, \
+ size_t len) \
+{ \
+ int ret; \
+ struct gb_loopback *gb = dev_get_drvdata(dev); \
+ mutex_lock(&gb->mutex); \
+ ret = sscanf(buf, "%"#type, &gb->field); \
+ if (ret != 1) \
+ len = -EINVAL; \
+ else \
+ gb_loopback_check_attr(gb); \
+ mutex_unlock(&gb->mutex); \
+ return len; \
+} \
+static DEVICE_ATTR_RW(field)
+
+static void gb_loopback_reset_stats(struct gb_loopback *gb);
+static void gb_loopback_check_attr(struct gb_loopback *gb)
+{
+ if (gb->us_wait > GB_LOOPBACK_US_WAIT_MAX)
+ gb->us_wait = GB_LOOPBACK_US_WAIT_MAX;
+ if (gb->size > gb_dev.size_max)
+ gb->size = gb_dev.size_max;
+ gb->requests_timedout = 0;
+ gb->requests_completed = 0;
+ gb->iteration_count = 0;
+ gb->send_count = 0;
+ gb->error = 0;
+
+ if (kfifo_depth < gb->iteration_max) {
+ dev_warn(gb->dev,
+ "cannot log bytes %u kfifo_depth %u\n",
+ gb->iteration_max, kfifo_depth);
+ }
+ kfifo_reset_out(&gb->kfifo_lat);
+ kfifo_reset_out(&gb->kfifo_ts);
+
+ switch (gb->type) {
+ case GB_LOOPBACK_TYPE_PING:
+ case GB_LOOPBACK_TYPE_TRANSFER:
+ case GB_LOOPBACK_TYPE_SINK:
+ gb->jiffy_timeout = usecs_to_jiffies(gb->timeout);
+ if (!gb->jiffy_timeout)
+ gb->jiffy_timeout = GB_LOOPBACK_TIMEOUT_MIN;
+ else if (gb->jiffy_timeout > GB_LOOPBACK_TIMEOUT_MAX)
+ gb->jiffy_timeout = GB_LOOPBACK_TIMEOUT_MAX;
+ gb_loopback_reset_stats(gb);
+ wake_up(&gb->wq);
+ break;
+ default:
+ gb->type = 0;
+ break;
+ }
+}
+
+/* Time to send and receive one message */
+gb_loopback_stats_attrs(latency);
+/* Number of requests sent per second on this cport */
+gb_loopback_stats_attrs(requests_per_second);
+/* Quantity of data sent and received on this cport */
+gb_loopback_stats_attrs(throughput);
+/* Latency across the UniPro link from APBridge's perspective */
+gb_loopback_stats_attrs(apbridge_unipro_latency);
+/* Firmware induced overhead in the GPBridge */
+gb_loopback_stats_attrs(gbphy_firmware_latency);
+
+/* Number of errors encountered during loop */
+gb_loopback_ro_attr(error);
+/* Number of requests successfully completed async */
+gb_loopback_ro_attr(requests_completed);
+/* Number of requests timed out async */
+gb_loopback_ro_attr(requests_timedout);
+/* Timeout minimum in useconds */
+gb_loopback_ro_attr(timeout_min);
+/* Timeout minimum in useconds */
+gb_loopback_ro_attr(timeout_max);
+
+/*
+ * Type of loopback message to send based on protocol type definitions
+ * 0 => Don't send message
+ * 2 => Send ping message continuously (message without payload)
+ * 3 => Send transfer message continuously (message with payload,
+ * payload returned in response)
+ * 4 => Send a sink message (message with payload, no payload in response)
+ */
+gb_dev_loopback_rw_attr(type, d);
+/* Size of transfer message payload: 0-4096 bytes */
+gb_dev_loopback_rw_attr(size, u);
+/* Time to wait between two messages: 0-1000 ms */
+gb_dev_loopback_rw_attr(us_wait, d);
+/* Maximum iterations for a given operation: 1-(2^32-1), 0 implies infinite */
+gb_dev_loopback_rw_attr(iteration_max, u);
+/* The current index of the for (i = 0; i < iteration_max; i++) loop */
+gb_dev_loopback_ro_attr(iteration_count, false);
+/* A flag to indicate synchronous or asynchronous operations */
+gb_dev_loopback_rw_attr(async, u);
+/* Timeout of an individual asynchronous request */
+gb_dev_loopback_rw_attr(timeout, u);
+/* Maximum number of in-flight operations before back-off */
+gb_dev_loopback_rw_attr(outstanding_operations_max, u);
+
+static struct attribute *loopback_attrs[] = {
+ &dev_attr_latency_min.attr,
+ &dev_attr_latency_max.attr,
+ &dev_attr_latency_avg.attr,
+ &dev_attr_requests_per_second_min.attr,
+ &dev_attr_requests_per_second_max.attr,
+ &dev_attr_requests_per_second_avg.attr,
+ &dev_attr_throughput_min.attr,
+ &dev_attr_throughput_max.attr,
+ &dev_attr_throughput_avg.attr,
+ &dev_attr_apbridge_unipro_latency_min.attr,
+ &dev_attr_apbridge_unipro_latency_max.attr,
+ &dev_attr_apbridge_unipro_latency_avg.attr,
+ &dev_attr_gbphy_firmware_latency_min.attr,
+ &dev_attr_gbphy_firmware_latency_max.attr,
+ &dev_attr_gbphy_firmware_latency_avg.attr,
+ &dev_attr_type.attr,
+ &dev_attr_size.attr,
+ &dev_attr_us_wait.attr,
+ &dev_attr_iteration_count.attr,
+ &dev_attr_iteration_max.attr,
+ &dev_attr_async.attr,
+ &dev_attr_error.attr,
+ &dev_attr_requests_completed.attr,
+ &dev_attr_requests_timedout.attr,
+ &dev_attr_timeout.attr,
+ &dev_attr_outstanding_operations_max.attr,
+ &dev_attr_timeout_min.attr,
+ &dev_attr_timeout_max.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(loopback);
+
+static void gb_loopback_calculate_stats(struct gb_loopback *gb, bool error);
+
+static u32 gb_loopback_nsec_to_usec_latency(u64 elapsed_nsecs)
+{
+ u32 lat;
+
+ do_div(elapsed_nsecs, NSEC_PER_USEC);
+ lat = elapsed_nsecs;
+ return lat;
+}
+
+static u64 __gb_loopback_calc_latency(u64 t1, u64 t2)
+{
+ if (t2 > t1)
+ return t2 - t1;
+ else
+ return NSEC_PER_DAY - t2 + t1;
+}
+
+static u64 gb_loopback_calc_latency(struct timeval *ts, struct timeval *te)
+{
+ u64 t1, t2;
+
+ t1 = timeval_to_ns(ts);
+ t2 = timeval_to_ns(te);
+
+ return __gb_loopback_calc_latency(t1, t2);
+}
+
+static void gb_loopback_push_latency_ts(struct gb_loopback *gb,
+ struct timeval *ts, struct timeval *te)
+{
+ kfifo_in(&gb->kfifo_ts, (unsigned char *)ts, sizeof(*ts));
+ kfifo_in(&gb->kfifo_ts, (unsigned char *)te, sizeof(*te));
+}
+
+static int gb_loopback_operation_sync(struct gb_loopback *gb, int type,
+ void *request, int request_size,
+ void *response, int response_size)
+{
+ struct gb_operation *operation;
+ struct timeval ts, te;
+ int ret;
+
+ do_gettimeofday(&ts);
+ operation = gb_operation_create(gb->connection, type, request_size,
+ response_size, GFP_KERNEL);
+ if (!operation)
+ return -ENOMEM;
+
+ if (request_size)
+ memcpy(operation->request->payload, request, request_size);
+
+ ret = gb_operation_request_send_sync(operation);
+ if (ret) {
+ dev_err(&gb->connection->bundle->dev,
+ "synchronous operation failed: %d\n", ret);
+ goto out_put_operation;
+ } else {
+ if (response_size == operation->response->payload_size) {
+ memcpy(response, operation->response->payload,
+ response_size);
+ } else {
+ dev_err(&gb->connection->bundle->dev,
+ "response size %zu expected %d\n",
+ operation->response->payload_size,
+ response_size);
+ ret = -EINVAL;
+ goto out_put_operation;
+ }
+ }
+
+ do_gettimeofday(&te);
+
+ /* Calculate the total time the message took */
+ gb_loopback_push_latency_ts(gb, &ts, &te);
+ gb->elapsed_nsecs = gb_loopback_calc_latency(&ts, &te);
+
+out_put_operation:
+ gb_operation_put(operation);
+
+ return ret;
+}
+
+static void __gb_loopback_async_operation_destroy(struct kref *kref)
+{
+ struct gb_loopback_async_operation *op_async;
+
+ op_async = container_of(kref, struct gb_loopback_async_operation, kref);
+
+ list_del(&op_async->entry);
+ if (op_async->operation)
+ gb_operation_put(op_async->operation);
+ atomic_dec(&op_async->gb->outstanding_operations);
+ wake_up(&op_async->gb->wq_completion);
+ kfree(op_async);
+}
+
+static void gb_loopback_async_operation_get(struct gb_loopback_async_operation
+ *op_async)
+{
+ kref_get(&op_async->kref);
+}
+
+static void gb_loopback_async_operation_put(struct gb_loopback_async_operation
+ *op_async)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&gb_dev.lock, flags);
+ kref_put(&op_async->kref, __gb_loopback_async_operation_destroy);
+ spin_unlock_irqrestore(&gb_dev.lock, flags);
+}
+
+static struct gb_loopback_async_operation *
+ gb_loopback_operation_find(u16 id)
+{
+ struct gb_loopback_async_operation *op_async;
+ bool found = false;
+ unsigned long flags;
+
+ spin_lock_irqsave(&gb_dev.lock, flags);
+ list_for_each_entry(op_async, &gb_dev.list_op_async, entry) {
+ if (op_async->operation->id == id) {
+ gb_loopback_async_operation_get(op_async);
+ found = true;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&gb_dev.lock, flags);
+
+ return found ? op_async : NULL;
+}
+
+static void gb_loopback_async_wait_all(struct gb_loopback *gb)
+{
+ wait_event(gb->wq_completion,
+ !atomic_read(&gb->outstanding_operations));
+}
+
+static void gb_loopback_async_operation_callback(struct gb_operation *operation)
+{
+ struct gb_loopback_async_operation *op_async;
+ struct gb_loopback *gb;
+ struct timeval te;
+ bool err = false;
+
+ do_gettimeofday(&te);
+ op_async = gb_loopback_operation_find(operation->id);
+ if (!op_async)
+ return;
+
+ gb = op_async->gb;
+ mutex_lock(&gb->mutex);
+
+ if (!op_async->pending || gb_operation_result(operation)) {
+ err = true;
+ } else {
+ if (op_async->completion)
+ if (op_async->completion(op_async))
+ err = true;
+ }
+
+ if (!err) {
+ gb_loopback_push_latency_ts(gb, &op_async->ts, &te);
+ gb->elapsed_nsecs = gb_loopback_calc_latency(&op_async->ts,
+ &te);
+ }
+
+ if (op_async->pending) {
+ if (err)
+ gb->error++;
+ gb->iteration_count++;
+ op_async->pending = false;
+ del_timer_sync(&op_async->timer);
+ gb_loopback_async_operation_put(op_async);
+ gb_loopback_calculate_stats(gb, err);
+ }
+ mutex_unlock(&gb->mutex);
+
+ dev_dbg(&gb->connection->bundle->dev, "complete operation %d\n",
+ operation->id);
+
+ gb_loopback_async_operation_put(op_async);
+}
+
+static void gb_loopback_async_operation_work(struct work_struct *work)
+{
+ struct gb_loopback *gb;
+ struct gb_operation *operation;
+ struct gb_loopback_async_operation *op_async;
+
+ op_async = container_of(work, struct gb_loopback_async_operation, work);
+ gb = op_async->gb;
+ operation = op_async->operation;
+
+ mutex_lock(&gb->mutex);
+ if (op_async->pending) {
+ gb->requests_timedout++;
+ gb->error++;
+ gb->iteration_count++;
+ op_async->pending = false;
+ gb_loopback_async_operation_put(op_async);
+ gb_loopback_calculate_stats(gb, true);
+ }
+ mutex_unlock(&gb->mutex);
+
+ dev_dbg(&gb->connection->bundle->dev, "timeout operation %d\n",
+ operation->id);
+
+ gb_operation_cancel(operation, -ETIMEDOUT);
+ gb_loopback_async_operation_put(op_async);
+}
+
+static void gb_loopback_async_operation_timeout(unsigned long data)
+{
+ struct gb_loopback_async_operation *op_async;
+ u16 id = data;
+
+ op_async = gb_loopback_operation_find(id);
+ if (!op_async) {
+ pr_err("operation %d not found - time out ?\n", id);
+ return;
+ }
+ schedule_work(&op_async->work);
+}
+
+static int gb_loopback_async_operation(struct gb_loopback *gb, int type,
+ void *request, int request_size,
+ int response_size,
+ void *completion)
+{
+ struct gb_loopback_async_operation *op_async;
+ struct gb_operation *operation;
+ int ret;
+ unsigned long flags;
+
+ op_async = kzalloc(sizeof(*op_async), GFP_KERNEL);
+ if (!op_async)
+ return -ENOMEM;
+
+ INIT_WORK(&op_async->work, gb_loopback_async_operation_work);
+ kref_init(&op_async->kref);
+
+ operation = gb_operation_create(gb->connection, type, request_size,
+ response_size, GFP_KERNEL);
+ if (!operation) {
+ kfree(op_async);
+ return -ENOMEM;
+ }
+
+ if (request_size)
+ memcpy(operation->request->payload, request, request_size);
+
+ op_async->gb = gb;
+ op_async->operation = operation;
+ op_async->completion = completion;
+
+ spin_lock_irqsave(&gb_dev.lock, flags);
+ list_add_tail(&op_async->entry, &gb_dev.list_op_async);
+ spin_unlock_irqrestore(&gb_dev.lock, flags);
+
+ do_gettimeofday(&op_async->ts);
+ op_async->pending = true;
+ atomic_inc(&gb->outstanding_operations);
+ mutex_lock(&gb->mutex);
+ ret = gb_operation_request_send(operation,
+ gb_loopback_async_operation_callback,
+ GFP_KERNEL);
+ if (ret)
+ goto error;
+
+ setup_timer(&op_async->timer, gb_loopback_async_operation_timeout,
+ (unsigned long)operation->id);
+ op_async->timer.expires = jiffies + gb->jiffy_timeout;
+ add_timer(&op_async->timer);
+
+ goto done;
+error:
+ gb_loopback_async_operation_put(op_async);
+done:
+ mutex_unlock(&gb->mutex);
+ return ret;
+}
+
+static int gb_loopback_sync_sink(struct gb_loopback *gb, u32 len)
+{
+ struct gb_loopback_transfer_request *request;
+ int retval;
+
+ request = kmalloc(len + sizeof(*request), GFP_KERNEL);
+ if (!request)
+ return -ENOMEM;
+
+ request->len = cpu_to_le32(len);
+ retval = gb_loopback_operation_sync(gb, GB_LOOPBACK_TYPE_SINK,
+ request, len + sizeof(*request),
+ NULL, 0);
+ kfree(request);
+ return retval;
+}
+
+static int gb_loopback_sync_transfer(struct gb_loopback *gb, u32 len)
+{
+ struct gb_loopback_transfer_request *request;
+ struct gb_loopback_transfer_response *response;
+ int retval;
+
+ gb->apbridge_latency_ts = 0;
+ gb->gbphy_latency_ts = 0;
+
+ request = kmalloc(len + sizeof(*request), GFP_KERNEL);
+ if (!request)
+ return -ENOMEM;
+ response = kmalloc(len + sizeof(*response), GFP_KERNEL);
+ if (!response) {
+ kfree(request);
+ return -ENOMEM;
+ }
+
+ memset(request->data, 0x5A, len);
+
+ request->len = cpu_to_le32(len);
+ retval = gb_loopback_operation_sync(gb, GB_LOOPBACK_TYPE_TRANSFER,
+ request, len + sizeof(*request),
+ response, len + sizeof(*response));
+ if (retval)
+ goto gb_error;
+
+ if (memcmp(request->data, response->data, len)) {
+ dev_err(&gb->connection->bundle->dev,
+ "Loopback Data doesn't match\n");
+ retval = -EREMOTEIO;
+ }
+ gb->apbridge_latency_ts = (u32)__le32_to_cpu(response->reserved0);
+ gb->gbphy_latency_ts = (u32)__le32_to_cpu(response->reserved1);
+
+gb_error:
+ kfree(request);
+ kfree(response);
+
+ return retval;
+}
+
+static int gb_loopback_sync_ping(struct gb_loopback *gb)
+{
+ return gb_loopback_operation_sync(gb, GB_LOOPBACK_TYPE_PING,
+ NULL, 0, NULL, 0);
+}
+
+static int gb_loopback_async_sink(struct gb_loopback *gb, u32 len)
+{
+ struct gb_loopback_transfer_request *request;
+ int retval;
+
+ request = kmalloc(len + sizeof(*request), GFP_KERNEL);
+ if (!request)
+ return -ENOMEM;
+
+ request->len = cpu_to_le32(len);
+ retval = gb_loopback_async_operation(gb, GB_LOOPBACK_TYPE_SINK,
+ request, len + sizeof(*request),
+ 0, NULL);
+ kfree(request);
+ return retval;
+}
+
+static int gb_loopback_async_transfer_complete(
+ struct gb_loopback_async_operation *op_async)
+{
+ struct gb_loopback *gb;
+ struct gb_operation *operation;
+ struct gb_loopback_transfer_request *request;
+ struct gb_loopback_transfer_response *response;
+ size_t len;
+ int retval = 0;
+
+ gb = op_async->gb;
+ operation = op_async->operation;
+ request = operation->request->payload;
+ response = operation->response->payload;
+ len = le32_to_cpu(request->len);
+
+ if (memcmp(request->data, response->data, len)) {
+ dev_err(&gb->connection->bundle->dev,
+ "Loopback Data doesn't match operation id %d\n",
+ operation->id);
+ retval = -EREMOTEIO;
+ } else {
+ gb->apbridge_latency_ts =
+ (u32)__le32_to_cpu(response->reserved0);
+ gb->gbphy_latency_ts =
+ (u32)__le32_to_cpu(response->reserved1);
+ }
+
+ return retval;
+}
+
+static int gb_loopback_async_transfer(struct gb_loopback *gb, u32 len)
+{
+ struct gb_loopback_transfer_request *request;
+ int retval, response_len;
+
+ request = kmalloc(len + sizeof(*request), GFP_KERNEL);
+ if (!request)
+ return -ENOMEM;
+
+ memset(request->data, 0x5A, len);
+
+ request->len = cpu_to_le32(len);
+ response_len = sizeof(struct gb_loopback_transfer_response);
+ retval = gb_loopback_async_operation(gb, GB_LOOPBACK_TYPE_TRANSFER,
+ request, len + sizeof(*request),
+ len + response_len,
+ gb_loopback_async_transfer_complete);
+ if (retval)
+ goto gb_error;
+
+gb_error:
+ kfree(request);
+ return retval;
+}
+
+static int gb_loopback_async_ping(struct gb_loopback *gb)
+{
+ return gb_loopback_async_operation(gb, GB_LOOPBACK_TYPE_PING,
+ NULL, 0, 0, NULL);
+}
+
+static int gb_loopback_request_handler(struct gb_operation *operation)
+{
+ struct gb_connection *connection = operation->connection;
+ struct gb_loopback_transfer_request *request;
+ struct gb_loopback_transfer_response *response;
+ struct device *dev = &connection->bundle->dev;
+ size_t len;
+
+ /* By convention, the AP initiates the version operation */
+ switch (operation->type) {
+ case GB_LOOPBACK_TYPE_PING:
+ case GB_LOOPBACK_TYPE_SINK:
+ return 0;
+ case GB_LOOPBACK_TYPE_TRANSFER:
+ if (operation->request->payload_size < sizeof(*request)) {
+ dev_err(dev, "transfer request too small (%zu < %zu)\n",
+ operation->request->payload_size,
+ sizeof(*request));
+ return -EINVAL; /* -EMSGSIZE */
+ }
+ request = operation->request->payload;
+ len = le32_to_cpu(request->len);
+ if (len > gb_dev.size_max) {
+ dev_err(dev, "transfer request too large (%zu > %zu)\n",
+ len, gb_dev.size_max);
+ return -EINVAL;
+ }
+
+ if (!gb_operation_response_alloc(operation,
+ len + sizeof(*response), GFP_KERNEL)) {
+ dev_err(dev, "error allocating response\n");
+ return -ENOMEM;
+ }
+ response = operation->response->payload;
+ response->len = cpu_to_le32(len);
+ if (len)
+ memcpy(response->data, request->data, len);
+
+ return 0;
+ default:
+ dev_err(dev, "unsupported request: %u\n", operation->type);
+ return -EINVAL;
+ }
+}
+
+static void gb_loopback_reset_stats(struct gb_loopback *gb)
+{
+ struct gb_loopback_stats reset = {
+ .min = U32_MAX,
+ };
+
+ /* Reset per-connection stats */
+ memcpy(&gb->latency, &reset,
+ sizeof(struct gb_loopback_stats));
+ memcpy(&gb->throughput, &reset,
+ sizeof(struct gb_loopback_stats));
+ memcpy(&gb->requests_per_second, &reset,
+ sizeof(struct gb_loopback_stats));
+ memcpy(&gb->apbridge_unipro_latency, &reset,
+ sizeof(struct gb_loopback_stats));
+ memcpy(&gb->gbphy_firmware_latency, &reset,
+ sizeof(struct gb_loopback_stats));
+
+ /* Should be initialized at least once per transaction set */
+ gb->apbridge_latency_ts = 0;
+ gb->gbphy_latency_ts = 0;
+ memset(&gb->ts, 0, sizeof(struct timeval));
+}
+
+static void gb_loopback_update_stats(struct gb_loopback_stats *stats, u32 val)
+{
+ if (stats->min > val)
+ stats->min = val;
+ if (stats->max < val)
+ stats->max = val;
+ stats->sum += val;
+ stats->count++;
+}
+
+static void gb_loopback_update_stats_window(struct gb_loopback_stats *stats,
+ u64 val, u32 count)
+{
+ stats->sum += val;
+ stats->count += count;
+
+ do_div(val, count);
+ if (stats->min > val)
+ stats->min = val;
+ if (stats->max < val)
+ stats->max = val;
+}
+
+static void gb_loopback_requests_update(struct gb_loopback *gb, u32 latency)
+{
+ u64 req = gb->requests_completed * USEC_PER_SEC;
+
+ gb_loopback_update_stats_window(&gb->requests_per_second, req, latency);
+}
+
+static void gb_loopback_throughput_update(struct gb_loopback *gb, u32 latency)
+{
+ u64 aggregate_size = sizeof(struct gb_operation_msg_hdr) * 2;
+
+ switch (gb->type) {
+ case GB_LOOPBACK_TYPE_PING:
+ break;
+ case GB_LOOPBACK_TYPE_SINK:
+ aggregate_size += sizeof(struct gb_loopback_transfer_request) +
+ gb->size;
+ break;
+ case GB_LOOPBACK_TYPE_TRANSFER:
+ aggregate_size += sizeof(struct gb_loopback_transfer_request) +
+ sizeof(struct gb_loopback_transfer_response) +
+ gb->size * 2;
+ break;
+ default:
+ return;
+ }
+
+ aggregate_size *= gb->requests_completed;
+ aggregate_size *= USEC_PER_SEC;
+ gb_loopback_update_stats_window(&gb->throughput, aggregate_size,
+ latency);
+}
+
+static void gb_loopback_calculate_latency_stats(struct gb_loopback *gb)
+{
+ u32 lat;
+
+ /* Express latency in terms of microseconds */
+ lat = gb_loopback_nsec_to_usec_latency(gb->elapsed_nsecs);
+
+ /* Log latency stastic */
+ gb_loopback_update_stats(&gb->latency, lat);
+
+ /* Raw latency log on a per thread basis */
+ kfifo_in(&gb->kfifo_lat, (unsigned char *)&lat, sizeof(lat));
+
+ /* Log the firmware supplied latency values */
+ gb_loopback_update_stats(&gb->apbridge_unipro_latency,
+ gb->apbridge_latency_ts);
+ gb_loopback_update_stats(&gb->gbphy_firmware_latency,
+ gb->gbphy_latency_ts);
+}
+
+static void gb_loopback_calculate_stats(struct gb_loopback *gb, bool error)
+{
+ u64 nlat;
+ u32 lat;
+ struct timeval te;
+
+ if (!error) {
+ gb->requests_completed++;
+ gb_loopback_calculate_latency_stats(gb);
+ }
+
+ do_gettimeofday(&te);
+ nlat = gb_loopback_calc_latency(&gb->ts, &te);
+ if (nlat >= NSEC_PER_SEC || gb->iteration_count == gb->iteration_max) {
+ lat = gb_loopback_nsec_to_usec_latency(nlat);
+
+ gb_loopback_throughput_update(gb, lat);
+ gb_loopback_requests_update(gb, lat);
+
+ if (gb->iteration_count != gb->iteration_max) {
+ gb->ts = te;
+ gb->requests_completed = 0;
+ }
+ }
+}
+
+static void gb_loopback_async_wait_to_send(struct gb_loopback *gb)
+{
+ if (!(gb->async && gb->outstanding_operations_max))
+ return;
+ wait_event_interruptible(gb->wq_completion,
+ (atomic_read(&gb->outstanding_operations) <
+ gb->outstanding_operations_max) ||
+ kthread_should_stop());
+}
+
+static int gb_loopback_fn(void *data)
+{
+ int error = 0;
+ int us_wait = 0;
+ int type;
+ int ret;
+ u32 size;
+
+ struct gb_loopback *gb = data;
+ struct gb_bundle *bundle = gb->connection->bundle;
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ return ret;
+
+ while (1) {
+ if (!gb->type) {
+ gb_pm_runtime_put_autosuspend(bundle);
+ wait_event_interruptible(gb->wq, gb->type ||
+ kthread_should_stop());
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ return ret;
+ }
+
+ if (kthread_should_stop())
+ break;
+
+ /* Limit the maximum number of in-flight async operations */
+ gb_loopback_async_wait_to_send(gb);
+ if (kthread_should_stop())
+ break;
+
+ mutex_lock(&gb->mutex);
+
+ /* Optionally terminate */
+ if (gb->send_count == gb->iteration_max) {
+ if (gb->iteration_count == gb->iteration_max) {
+ gb->type = 0;
+ gb->send_count = 0;
+ sysfs_notify(&gb->dev->kobj, NULL,
+ "iteration_count");
+ }
+ mutex_unlock(&gb->mutex);
+ continue;
+ }
+ size = gb->size;
+ us_wait = gb->us_wait;
+ type = gb->type;
+ if (gb->ts.tv_usec == 0 && gb->ts.tv_sec == 0)
+ do_gettimeofday(&gb->ts);
+ mutex_unlock(&gb->mutex);
+
+ /* Else operations to perform */
+ if (gb->async) {
+ if (type == GB_LOOPBACK_TYPE_PING) {
+ error = gb_loopback_async_ping(gb);
+ } else if (type == GB_LOOPBACK_TYPE_TRANSFER) {
+ error = gb_loopback_async_transfer(gb, size);
+ } else if (type == GB_LOOPBACK_TYPE_SINK) {
+ error = gb_loopback_async_sink(gb, size);
+ }
+
+ if (error)
+ gb->error++;
+ } else {
+ /* We are effectively single threaded here */
+ if (type == GB_LOOPBACK_TYPE_PING)
+ error = gb_loopback_sync_ping(gb);
+ else if (type == GB_LOOPBACK_TYPE_TRANSFER)
+ error = gb_loopback_sync_transfer(gb, size);
+ else if (type == GB_LOOPBACK_TYPE_SINK)
+ error = gb_loopback_sync_sink(gb, size);
+
+ if (error)
+ gb->error++;
+ gb->iteration_count++;
+ gb_loopback_calculate_stats(gb, !!error);
+ }
+ gb->send_count++;
+ if (us_wait)
+ udelay(us_wait);
+ }
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return 0;
+}
+
+static int gb_loopback_dbgfs_latency_show_common(struct seq_file *s,
+ struct kfifo *kfifo,
+ struct mutex *mutex)
+{
+ u32 latency;
+ int retval;
+
+ if (kfifo_len(kfifo) == 0) {
+ retval = -EAGAIN;
+ goto done;
+ }
+
+ mutex_lock(mutex);
+ retval = kfifo_out(kfifo, &latency, sizeof(latency));
+ if (retval > 0) {
+ seq_printf(s, "%u", latency);
+ retval = 0;
+ }
+ mutex_unlock(mutex);
+done:
+ return retval;
+}
+
+static int gb_loopback_dbgfs_latency_show(struct seq_file *s, void *unused)
+{
+ struct gb_loopback *gb = s->private;
+
+ return gb_loopback_dbgfs_latency_show_common(s, &gb->kfifo_lat,
+ &gb->mutex);
+}
+
+static int gb_loopback_latency_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, gb_loopback_dbgfs_latency_show,
+ inode->i_private);
+}
+
+static const struct file_operations gb_loopback_debugfs_latency_ops = {
+ .open = gb_loopback_latency_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int gb_loopback_bus_id_compare(void *priv, struct list_head *lha,
+ struct list_head *lhb)
+{
+ struct gb_loopback *a = list_entry(lha, struct gb_loopback, entry);
+ struct gb_loopback *b = list_entry(lhb, struct gb_loopback, entry);
+ struct gb_connection *ca = a->connection;
+ struct gb_connection *cb = b->connection;
+
+ if (ca->bundle->intf->interface_id < cb->bundle->intf->interface_id)
+ return -1;
+ if (cb->bundle->intf->interface_id < ca->bundle->intf->interface_id)
+ return 1;
+ if (ca->bundle->id < cb->bundle->id)
+ return -1;
+ if (cb->bundle->id < ca->bundle->id)
+ return 1;
+ if (ca->intf_cport_id < cb->intf_cport_id)
+ return -1;
+ else if (cb->intf_cport_id < ca->intf_cport_id)
+ return 1;
+
+ return 0;
+}
+
+static void gb_loopback_insert_id(struct gb_loopback *gb)
+{
+ struct gb_loopback *gb_list;
+ u32 new_lbid = 0;
+
+ /* perform an insertion sort */
+ list_add_tail(&gb->entry, &gb_dev.list);
+ list_sort(NULL, &gb_dev.list, gb_loopback_bus_id_compare);
+ list_for_each_entry(gb_list, &gb_dev.list, entry) {
+ gb_list->lbid = 1 << new_lbid;
+ new_lbid++;
+ }
+}
+
+#define DEBUGFS_NAMELEN 32
+
+static int gb_loopback_probe(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id)
+{
+ struct greybus_descriptor_cport *cport_desc;
+ struct gb_connection *connection;
+ struct gb_loopback *gb;
+ struct device *dev;
+ int retval;
+ char name[DEBUGFS_NAMELEN];
+ unsigned long flags;
+
+ if (bundle->num_cports != 1)
+ return -ENODEV;
+
+ cport_desc = &bundle->cport_desc[0];
+ if (cport_desc->protocol_id != GREYBUS_PROTOCOL_LOOPBACK)
+ return -ENODEV;
+
+ gb = kzalloc(sizeof(*gb), GFP_KERNEL);
+ if (!gb)
+ return -ENOMEM;
+
+ connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
+ gb_loopback_request_handler);
+ if (IS_ERR(connection)) {
+ retval = PTR_ERR(connection);
+ goto out_kzalloc;
+ }
+
+ gb->connection = connection;
+ greybus_set_drvdata(bundle, gb);
+
+ init_waitqueue_head(&gb->wq);
+ init_waitqueue_head(&gb->wq_completion);
+ atomic_set(&gb->outstanding_operations, 0);
+ gb_loopback_reset_stats(gb);
+
+ /* Reported values to user-space for min/max timeouts */
+ gb->timeout_min = jiffies_to_usecs(GB_LOOPBACK_TIMEOUT_MIN);
+ gb->timeout_max = jiffies_to_usecs(GB_LOOPBACK_TIMEOUT_MAX);
+
+ if (!gb_dev.count) {
+ /* Calculate maximum payload */
+ gb_dev.size_max = gb_operation_get_payload_size_max(connection);
+ if (gb_dev.size_max <=
+ sizeof(struct gb_loopback_transfer_request)) {
+ retval = -EINVAL;
+ goto out_connection_destroy;
+ }
+ gb_dev.size_max -= sizeof(struct gb_loopback_transfer_request);
+ }
+
+ /* Create per-connection sysfs and debugfs data-points */
+ snprintf(name, sizeof(name), "raw_latency_%s",
+ dev_name(&connection->bundle->dev));
+ gb->file = debugfs_create_file(name, S_IFREG | S_IRUGO, gb_dev.root, gb,
+ &gb_loopback_debugfs_latency_ops);
+
+ gb->id = ida_simple_get(&loopback_ida, 0, 0, GFP_KERNEL);
+ if (gb->id < 0) {
+ retval = gb->id;
+ goto out_debugfs_remove;
+ }
+
+ retval = gb_connection_enable(connection);
+ if (retval)
+ goto out_ida_remove;
+
+ dev = device_create_with_groups(&loopback_class,
+ &connection->bundle->dev,
+ MKDEV(0, 0), gb, loopback_groups,
+ "gb_loopback%d", gb->id);
+ if (IS_ERR(dev)) {
+ retval = PTR_ERR(dev);
+ goto out_connection_disable;
+ }
+ gb->dev = dev;
+
+ /* Allocate kfifo */
+ if (kfifo_alloc(&gb->kfifo_lat, kfifo_depth * sizeof(u32),
+ GFP_KERNEL)) {
+ retval = -ENOMEM;
+ goto out_conn;
+ }
+ if (kfifo_alloc(&gb->kfifo_ts, kfifo_depth * sizeof(struct timeval) * 2,
+ GFP_KERNEL)) {
+ retval = -ENOMEM;
+ goto out_kfifo0;
+ }
+
+ /* Fork worker thread */
+ mutex_init(&gb->mutex);
+ gb->task = kthread_run(gb_loopback_fn, gb, "gb_loopback");
+ if (IS_ERR(gb->task)) {
+ retval = PTR_ERR(gb->task);
+ goto out_kfifo1;
+ }
+
+ spin_lock_irqsave(&gb_dev.lock, flags);
+ gb_loopback_insert_id(gb);
+ gb_dev.count++;
+ spin_unlock_irqrestore(&gb_dev.lock, flags);
+
+ gb_connection_latency_tag_enable(connection);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return 0;
+
+out_kfifo1:
+ kfifo_free(&gb->kfifo_ts);
+out_kfifo0:
+ kfifo_free(&gb->kfifo_lat);
+out_conn:
+ device_unregister(dev);
+out_connection_disable:
+ gb_connection_disable(connection);
+out_ida_remove:
+ ida_simple_remove(&loopback_ida, gb->id);
+out_debugfs_remove:
+ debugfs_remove(gb->file);
+out_connection_destroy:
+ gb_connection_destroy(connection);
+out_kzalloc:
+ kfree(gb);
+
+ return retval;
+}
+
+static void gb_loopback_disconnect(struct gb_bundle *bundle)
+{
+ struct gb_loopback *gb = greybus_get_drvdata(bundle);
+ unsigned long flags;
+ int ret;
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ gb_pm_runtime_get_noresume(bundle);
+
+ gb_connection_disable(gb->connection);
+
+ if (!IS_ERR_OR_NULL(gb->task))
+ kthread_stop(gb->task);
+
+ kfifo_free(&gb->kfifo_lat);
+ kfifo_free(&gb->kfifo_ts);
+ gb_connection_latency_tag_disable(gb->connection);
+ debugfs_remove(gb->file);
+
+ /*
+ * FIXME: gb_loopback_async_wait_all() is redundant now, as connection
+ * is disabled at the beginning and so we can't have any more
+ * incoming/outgoing requests.
+ */
+ gb_loopback_async_wait_all(gb);
+
+ spin_lock_irqsave(&gb_dev.lock, flags);
+ gb_dev.count--;
+ list_del(&gb->entry);
+ spin_unlock_irqrestore(&gb_dev.lock, flags);
+
+ device_unregister(gb->dev);
+ ida_simple_remove(&loopback_ida, gb->id);
+
+ gb_connection_destroy(gb->connection);
+ kfree(gb);
+}
+
+static const struct greybus_bundle_id gb_loopback_id_table[] = {
+ { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LOOPBACK) },
+ { }
+};
+MODULE_DEVICE_TABLE(greybus, gb_loopback_id_table);
+
+static struct greybus_driver gb_loopback_driver = {
+ .name = "loopback",
+ .probe = gb_loopback_probe,
+ .disconnect = gb_loopback_disconnect,
+ .id_table = gb_loopback_id_table,
+};
+
+static int loopback_init(void)
+{
+ int retval;
+
+ INIT_LIST_HEAD(&gb_dev.list);
+ INIT_LIST_HEAD(&gb_dev.list_op_async);
+ spin_lock_init(&gb_dev.lock);
+ gb_dev.root = debugfs_create_dir("gb_loopback", NULL);
+
+ retval = class_register(&loopback_class);
+ if (retval)
+ goto err;
+
+ retval = greybus_register(&gb_loopback_driver);
+ if (retval)
+ goto err_unregister;
+
+ return 0;
+
+err_unregister:
+ class_unregister(&loopback_class);
+err:
+ debugfs_remove_recursive(gb_dev.root);
+ return retval;
+}
+module_init(loopback_init);
+
+static void __exit loopback_exit(void)
+{
+ debugfs_remove_recursive(gb_dev.root);
+ greybus_deregister(&gb_loopback_driver);
+ class_unregister(&loopback_class);
+ ida_destroy(&loopback_ida);
+}
+module_exit(loopback_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/manifest.c b/drivers/staging/greybus/manifest.c
new file mode 100644
index 000000000000..7b903770a684
--- /dev/null
+++ b/drivers/staging/greybus/manifest.c
@@ -0,0 +1,535 @@
+/*
+ * Greybus manifest parsing
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include "greybus.h"
+
+static const char *get_descriptor_type_string(u8 type)
+{
+ switch (type) {
+ case GREYBUS_TYPE_INVALID:
+ return "invalid";
+ case GREYBUS_TYPE_STRING:
+ return "string";
+ case GREYBUS_TYPE_INTERFACE:
+ return "interface";
+ case GREYBUS_TYPE_CPORT:
+ return "cport";
+ case GREYBUS_TYPE_BUNDLE:
+ return "bundle";
+ default:
+ WARN_ON(1);
+ return "unknown";
+ }
+}
+
+/*
+ * We scan the manifest once to identify where all the descriptors
+ * are. The result is a list of these manifest_desc structures. We
+ * then pick through them for what we're looking for (starting with
+ * the interface descriptor). As each is processed we remove it from
+ * the list. When we're done the list should (probably) be empty.
+ */
+struct manifest_desc {
+ struct list_head links;
+
+ size_t size;
+ void *data;
+ enum greybus_descriptor_type type;
+};
+
+static void release_manifest_descriptor(struct manifest_desc *descriptor)
+{
+ list_del(&descriptor->links);
+ kfree(descriptor);
+}
+
+static void release_manifest_descriptors(struct gb_interface *intf)
+{
+ struct manifest_desc *descriptor;
+ struct manifest_desc *next;
+
+ list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links)
+ release_manifest_descriptor(descriptor);
+}
+
+static void release_cport_descriptors(struct list_head *head, u8 bundle_id)
+{
+ struct manifest_desc *desc, *tmp;
+ struct greybus_descriptor_cport *desc_cport;
+
+ list_for_each_entry_safe(desc, tmp, head, links) {
+ desc_cport = desc->data;
+
+ if (desc->type != GREYBUS_TYPE_CPORT)
+ continue;
+
+ if (desc_cport->bundle == bundle_id)
+ release_manifest_descriptor(desc);
+ }
+}
+
+static struct manifest_desc *get_next_bundle_desc(struct gb_interface *intf)
+{
+ struct manifest_desc *descriptor;
+ struct manifest_desc *next;
+
+ list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links)
+ if (descriptor->type == GREYBUS_TYPE_BUNDLE)
+ return descriptor;
+
+ return NULL;
+}
+
+/*
+ * Validate the given descriptor. Its reported size must fit within
+ * the number of bytes remaining, and it must have a recognized
+ * type. Check that the reported size is at least as big as what
+ * we expect to see. (It could be bigger, perhaps for a new version
+ * of the format.)
+ *
+ * Returns the (non-zero) number of bytes consumed by the descriptor,
+ * or a negative errno.
+ */
+static int identify_descriptor(struct gb_interface *intf,
+ struct greybus_descriptor *desc, size_t size)
+{
+ struct greybus_descriptor_header *desc_header = &desc->header;
+ struct manifest_desc *descriptor;
+ size_t desc_size;
+ size_t expected_size;
+
+ if (size < sizeof(*desc_header)) {
+ dev_err(&intf->dev, "manifest too small (%zu < %zu)\n",
+ size, sizeof(*desc_header));
+ return -EINVAL; /* Must at least have header */
+ }
+
+ desc_size = le16_to_cpu(desc_header->size);
+ if (desc_size > size) {
+ dev_err(&intf->dev, "descriptor too big (%zu > %zu)\n",
+ desc_size, size);
+ return -EINVAL;
+ }
+
+ /* Descriptor needs to at least have a header */
+ expected_size = sizeof(*desc_header);
+
+ switch (desc_header->type) {
+ case GREYBUS_TYPE_STRING:
+ expected_size += sizeof(struct greybus_descriptor_string);
+ expected_size += desc->string.length;
+
+ /* String descriptors are padded to 4 byte boundaries */
+ expected_size = ALIGN(expected_size, 4);
+ break;
+ case GREYBUS_TYPE_INTERFACE:
+ expected_size += sizeof(struct greybus_descriptor_interface);
+ break;
+ case GREYBUS_TYPE_BUNDLE:
+ expected_size += sizeof(struct greybus_descriptor_bundle);
+ break;
+ case GREYBUS_TYPE_CPORT:
+ expected_size += sizeof(struct greybus_descriptor_cport);
+ break;
+ case GREYBUS_TYPE_INVALID:
+ default:
+ dev_err(&intf->dev, "invalid descriptor type (%u)\n",
+ desc_header->type);
+ return -EINVAL;
+ }
+
+ if (desc_size < expected_size) {
+ dev_err(&intf->dev, "%s descriptor too small (%zu < %zu)\n",
+ get_descriptor_type_string(desc_header->type),
+ desc_size, expected_size);
+ return -EINVAL;
+ }
+
+ /* Descriptor bigger than what we expect */
+ if (desc_size > expected_size) {
+ dev_warn(&intf->dev, "%s descriptor size mismatch (want %zu got %zu)\n",
+ get_descriptor_type_string(desc_header->type),
+ expected_size, desc_size);
+ }
+
+ descriptor = kzalloc(sizeof(*descriptor), GFP_KERNEL);
+ if (!descriptor)
+ return -ENOMEM;
+
+ descriptor->size = desc_size;
+ descriptor->data = (char *)desc + sizeof(*desc_header);
+ descriptor->type = desc_header->type;
+ list_add_tail(&descriptor->links, &intf->manifest_descs);
+
+ /* desc_size is positive and is known to fit in a signed int */
+
+ return desc_size;
+}
+
+/*
+ * Find the string descriptor having the given id, validate it, and
+ * allocate a duplicate copy of it. The duplicate has an extra byte
+ * which guarantees the returned string is NUL-terminated.
+ *
+ * String index 0 is valid (it represents "no string"), and for
+ * that a null pointer is returned.
+ *
+ * Otherwise returns a pointer to a newly-allocated copy of the
+ * descriptor string, or an error-coded pointer on failure.
+ */
+static char *gb_string_get(struct gb_interface *intf, u8 string_id)
+{
+ struct greybus_descriptor_string *desc_string;
+ struct manifest_desc *descriptor;
+ bool found = false;
+ char *string;
+
+ /* A zero string id means no string (but no error) */
+ if (!string_id)
+ return NULL;
+
+ list_for_each_entry(descriptor, &intf->manifest_descs, links) {
+ if (descriptor->type != GREYBUS_TYPE_STRING)
+ continue;
+
+ desc_string = descriptor->data;
+ if (desc_string->id == string_id) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return ERR_PTR(-ENOENT);
+
+ /* Allocate an extra byte so we can guarantee it's NUL-terminated */
+ string = kmemdup(&desc_string->string, desc_string->length + 1,
+ GFP_KERNEL);
+ if (!string)
+ return ERR_PTR(-ENOMEM);
+ string[desc_string->length] = '\0';
+
+ /* Ok we've used this string, so we're done with it */
+ release_manifest_descriptor(descriptor);
+
+ return string;
+}
+
+/*
+ * Find cport descriptors in the manifest associated with the given
+ * bundle, and set up data structures for the functions that use
+ * them. Returns the number of cports set up for the bundle, or 0
+ * if there is an error.
+ */
+static u32 gb_manifest_parse_cports(struct gb_bundle *bundle)
+{
+ struct gb_interface *intf = bundle->intf;
+ struct greybus_descriptor_cport *desc_cport;
+ struct manifest_desc *desc, *next, *tmp;
+ LIST_HEAD(list);
+ u8 bundle_id = bundle->id;
+ u16 cport_id;
+ u32 count = 0;
+ int i;
+
+ /* Set up all cport descriptors associated with this bundle */
+ list_for_each_entry_safe(desc, next, &intf->manifest_descs, links) {
+ if (desc->type != GREYBUS_TYPE_CPORT)
+ continue;
+
+ desc_cport = desc->data;
+ if (desc_cport->bundle != bundle_id)
+ continue;
+
+ cport_id = le16_to_cpu(desc_cport->id);
+ if (cport_id > CPORT_ID_MAX)
+ goto exit;
+
+ /* Nothing else should have its cport_id as control cport id */
+ if (cport_id == GB_CONTROL_CPORT_ID) {
+ dev_err(&bundle->dev, "invalid cport id found (%02u)\n",
+ cport_id);
+ goto exit;
+ }
+
+ /*
+ * Found one, move it to our temporary list after checking for
+ * duplicates.
+ */
+ list_for_each_entry(tmp, &list, links) {
+ desc_cport = tmp->data;
+ if (cport_id == le16_to_cpu(desc_cport->id)) {
+ dev_err(&bundle->dev,
+ "duplicate CPort %u found\n",
+ cport_id);
+ goto exit;
+ }
+ }
+ list_move_tail(&desc->links, &list);
+ count++;
+ }
+
+ if (!count)
+ return 0;
+
+ bundle->cport_desc = kcalloc(count, sizeof(*bundle->cport_desc),
+ GFP_KERNEL);
+ if (!bundle->cport_desc)
+ goto exit;
+
+ bundle->num_cports = count;
+
+ i = 0;
+ list_for_each_entry_safe(desc, next, &list, links) {
+ desc_cport = desc->data;
+ memcpy(&bundle->cport_desc[i++], desc_cport,
+ sizeof(*desc_cport));
+
+ /* Release the cport descriptor */
+ release_manifest_descriptor(desc);
+ }
+
+ return count;
+exit:
+ release_cport_descriptors(&list, bundle_id);
+ /*
+ * Free all cports for this bundle to avoid 'excess descriptors'
+ * warnings.
+ */
+ release_cport_descriptors(&intf->manifest_descs, bundle_id);
+
+ return 0; /* Error; count should also be 0 */
+}
+
+/*
+ * Find bundle descriptors in the manifest and set up their data
+ * structures. Returns the number of bundles set up for the
+ * given interface.
+ */
+static u32 gb_manifest_parse_bundles(struct gb_interface *intf)
+{
+ struct manifest_desc *desc;
+ struct gb_bundle *bundle;
+ struct gb_bundle *bundle_next;
+ u32 count = 0;
+ u8 bundle_id;
+ u8 class;
+
+ while ((desc = get_next_bundle_desc(intf))) {
+ struct greybus_descriptor_bundle *desc_bundle;
+
+ /* Found one. Set up its bundle structure*/
+ desc_bundle = desc->data;
+ bundle_id = desc_bundle->id;
+ class = desc_bundle->class;
+
+ /* Done with this bundle descriptor */
+ release_manifest_descriptor(desc);
+
+ /* Ignore any legacy control bundles */
+ if (bundle_id == GB_CONTROL_BUNDLE_ID) {
+ dev_dbg(&intf->dev, "%s - ignoring control bundle\n",
+ __func__);
+ release_cport_descriptors(&intf->manifest_descs,
+ bundle_id);
+ continue;
+ }
+
+ /* Nothing else should have its class set to control class */
+ if (class == GREYBUS_CLASS_CONTROL) {
+ dev_err(&intf->dev,
+ "bundle %u cannot use control class\n",
+ bundle_id);
+ goto cleanup;
+ }
+
+ bundle = gb_bundle_create(intf, bundle_id, class);
+ if (!bundle)
+ goto cleanup;
+
+ /*
+ * Now go set up this bundle's functions and cports.
+ *
+ * A 'bundle' represents a device in greybus. It may require
+ * multiple cports for its functioning. If we fail to setup any
+ * cport of a bundle, we better reject the complete bundle as
+ * the device may not be able to function properly then.
+ *
+ * But, failing to setup a cport of bundle X doesn't mean that
+ * the device corresponding to bundle Y will not work properly.
+ * Bundles should be treated as separate independent devices.
+ *
+ * While parsing manifest for an interface, treat bundles as
+ * separate entities and don't reject entire interface and its
+ * bundles on failing to initialize a cport. But make sure the
+ * bundle which needs the cport, gets destroyed properly.
+ */
+ if (!gb_manifest_parse_cports(bundle)) {
+ gb_bundle_destroy(bundle);
+ continue;
+ }
+
+ count++;
+ }
+
+ return count;
+cleanup:
+ /* An error occurred; undo any changes we've made */
+ list_for_each_entry_safe(bundle, bundle_next, &intf->bundles, links) {
+ gb_bundle_destroy(bundle);
+ count--;
+ }
+ return 0; /* Error; count should also be 0 */
+}
+
+static bool gb_manifest_parse_interface(struct gb_interface *intf,
+ struct manifest_desc *interface_desc)
+{
+ struct greybus_descriptor_interface *desc_intf = interface_desc->data;
+ struct gb_control *control = intf->control;
+ char *str;
+
+ /* Handle the strings first--they can fail */
+ str = gb_string_get(intf, desc_intf->vendor_stringid);
+ if (IS_ERR(str))
+ return false;
+ control->vendor_string = str;
+
+ str = gb_string_get(intf, desc_intf->product_stringid);
+ if (IS_ERR(str))
+ goto out_free_vendor_string;
+ control->product_string = str;
+
+ /* Assign feature flags communicated via manifest */
+ intf->features = desc_intf->features;
+
+ /* Release the interface descriptor, now that we're done with it */
+ release_manifest_descriptor(interface_desc);
+
+ /* An interface must have at least one bundle descriptor */
+ if (!gb_manifest_parse_bundles(intf)) {
+ dev_err(&intf->dev, "manifest bundle descriptors not valid\n");
+ goto out_err;
+ }
+
+ return true;
+out_err:
+ kfree(control->product_string);
+ control->product_string = NULL;
+out_free_vendor_string:
+ kfree(control->vendor_string);
+ control->vendor_string = NULL;
+
+ return false;
+}
+
+/*
+ * Parse a buffer containing an interface manifest.
+ *
+ * If we find anything wrong with the content/format of the buffer
+ * we reject it.
+ *
+ * The first requirement is that the manifest's version is
+ * one we can parse.
+ *
+ * We make an initial pass through the buffer and identify all of
+ * the descriptors it contains, keeping track for each its type
+ * and the location size of its data in the buffer.
+ *
+ * Next we scan the descriptors, looking for an interface descriptor;
+ * there must be exactly one of those. When found, we record the
+ * information it contains, and then remove that descriptor (and any
+ * string descriptors it refers to) from further consideration.
+ *
+ * After that we look for the interface's bundles--there must be at
+ * least one of those.
+ *
+ * Returns true if parsing was successful, false otherwise.
+ */
+bool gb_manifest_parse(struct gb_interface *intf, void *data, size_t size)
+{
+ struct greybus_manifest *manifest;
+ struct greybus_manifest_header *header;
+ struct greybus_descriptor *desc;
+ struct manifest_desc *descriptor;
+ struct manifest_desc *interface_desc = NULL;
+ u16 manifest_size;
+ u32 found = 0;
+ bool result;
+
+ /* Manifest descriptor list should be empty here */
+ if (WARN_ON(!list_empty(&intf->manifest_descs)))
+ return false;
+
+ /* we have to have at _least_ the manifest header */
+ if (size < sizeof(*header)) {
+ dev_err(&intf->dev, "short manifest (%zu < %zu)\n",
+ size, sizeof(*header));
+ return false;
+ }
+
+ /* Make sure the size is right */
+ manifest = data;
+ header = &manifest->header;
+ manifest_size = le16_to_cpu(header->size);
+ if (manifest_size != size) {
+ dev_err(&intf->dev, "manifest size mismatch (%zu != %u)\n",
+ size, manifest_size);
+ return false;
+ }
+
+ /* Validate major/minor number */
+ if (header->version_major > GREYBUS_VERSION_MAJOR) {
+ dev_err(&intf->dev, "manifest version too new (%u.%u > %u.%u)\n",
+ header->version_major, header->version_minor,
+ GREYBUS_VERSION_MAJOR, GREYBUS_VERSION_MINOR);
+ return false;
+ }
+
+ /* OK, find all the descriptors */
+ desc = manifest->descriptors;
+ size -= sizeof(*header);
+ while (size) {
+ int desc_size;
+
+ desc_size = identify_descriptor(intf, desc, size);
+ if (desc_size < 0) {
+ result = false;
+ goto out;
+ }
+ desc = (struct greybus_descriptor *)((char *)desc + desc_size);
+ size -= desc_size;
+ }
+
+ /* There must be a single interface descriptor */
+ list_for_each_entry(descriptor, &intf->manifest_descs, links) {
+ if (descriptor->type == GREYBUS_TYPE_INTERFACE)
+ if (!found++)
+ interface_desc = descriptor;
+ }
+ if (found != 1) {
+ dev_err(&intf->dev, "manifest must have 1 interface descriptor (%u found)\n",
+ found);
+ result = false;
+ goto out;
+ }
+
+ /* Parse the manifest, starting with the interface descriptor */
+ result = gb_manifest_parse_interface(intf, interface_desc);
+
+ /*
+ * We really should have no remaining descriptors, but we
+ * don't know what newer format manifests might leave.
+ */
+ if (result && !list_empty(&intf->manifest_descs))
+ dev_info(&intf->dev, "excess descriptors in interface manifest\n");
+out:
+ release_manifest_descriptors(intf);
+
+ return result;
+}
diff --git a/drivers/staging/greybus/manifest.h b/drivers/staging/greybus/manifest.h
new file mode 100644
index 000000000000..d96428407cd7
--- /dev/null
+++ b/drivers/staging/greybus/manifest.h
@@ -0,0 +1,16 @@
+/*
+ * Greybus manifest parsing
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __MANIFEST_H
+#define __MANIFEST_H
+
+struct gb_interface;
+bool gb_manifest_parse(struct gb_interface *intf, void *data, size_t size);
+
+#endif /* __MANIFEST_H */
diff --git a/drivers/staging/greybus/module.c b/drivers/staging/greybus/module.c
new file mode 100644
index 000000000000..69f67ddbd4a3
--- /dev/null
+++ b/drivers/staging/greybus/module.c
@@ -0,0 +1,238 @@
+/*
+ * Greybus Module code
+ *
+ * Copyright 2016 Google Inc.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include "greybus.h"
+#include "greybus_trace.h"
+
+
+static ssize_t eject_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct gb_module *module = to_gb_module(dev);
+ struct gb_interface *intf;
+ size_t i;
+ long val;
+ int ret;
+
+ ret = kstrtol(buf, 0, &val);
+ if (ret)
+ return ret;
+
+ if (!val)
+ return len;
+
+ for (i = 0; i < module->num_interfaces; ++i) {
+ intf = module->interfaces[i];
+
+ mutex_lock(&intf->mutex);
+ /* Set flag to prevent concurrent activation. */
+ intf->ejected = true;
+ gb_interface_disable(intf);
+ gb_interface_deactivate(intf);
+ mutex_unlock(&intf->mutex);
+ }
+
+ /* Tell the SVC to eject the primary interface. */
+ ret = gb_svc_intf_eject(module->hd->svc, module->module_id);
+ if (ret)
+ return ret;
+
+ return len;
+}
+static DEVICE_ATTR_WO(eject);
+
+static ssize_t module_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_module *module = to_gb_module(dev);
+
+ return sprintf(buf, "%u\n", module->module_id);
+}
+static DEVICE_ATTR_RO(module_id);
+
+static ssize_t num_interfaces_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_module *module = to_gb_module(dev);
+
+ return sprintf(buf, "%zu\n", module->num_interfaces);
+}
+static DEVICE_ATTR_RO(num_interfaces);
+
+static struct attribute *module_attrs[] = {
+ &dev_attr_eject.attr,
+ &dev_attr_module_id.attr,
+ &dev_attr_num_interfaces.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(module);
+
+static void gb_module_release(struct device *dev)
+{
+ struct gb_module *module = to_gb_module(dev);
+
+ trace_gb_module_release(module);
+
+ kfree(module);
+}
+
+struct device_type greybus_module_type = {
+ .name = "greybus_module",
+ .release = gb_module_release,
+};
+
+struct gb_module *gb_module_create(struct gb_host_device *hd, u8 module_id,
+ size_t num_interfaces)
+{
+ struct gb_interface *intf;
+ struct gb_module *module;
+ int i;
+
+ module = kzalloc(sizeof(*module) + num_interfaces * sizeof(intf),
+ GFP_KERNEL);
+ if (!module)
+ return NULL;
+
+ module->hd = hd;
+ module->module_id = module_id;
+ module->num_interfaces = num_interfaces;
+
+ module->dev.parent = &hd->dev;
+ module->dev.bus = &greybus_bus_type;
+ module->dev.type = &greybus_module_type;
+ module->dev.groups = module_groups;
+ module->dev.dma_mask = hd->dev.dma_mask;
+ device_initialize(&module->dev);
+ dev_set_name(&module->dev, "%d-%u", hd->bus_id, module_id);
+
+ trace_gb_module_create(module);
+
+ for (i = 0; i < num_interfaces; ++i) {
+ intf = gb_interface_create(module, module_id + i);
+ if (!intf) {
+ dev_err(&module->dev, "failed to create interface %u\n",
+ module_id + i);
+ goto err_put_interfaces;
+ }
+ module->interfaces[i] = intf;
+ }
+
+ return module;
+
+err_put_interfaces:
+ for (--i; i > 0; --i)
+ gb_interface_put(module->interfaces[i]);
+
+ put_device(&module->dev);
+
+ return NULL;
+}
+
+/*
+ * Register and enable an interface after first attempting to activate it.
+ */
+static void gb_module_register_interface(struct gb_interface *intf)
+{
+ struct gb_module *module = intf->module;
+ u8 intf_id = intf->interface_id;
+ int ret;
+
+ mutex_lock(&intf->mutex);
+
+ ret = gb_interface_activate(intf);
+ if (ret) {
+ if (intf->type != GB_INTERFACE_TYPE_DUMMY) {
+ dev_err(&module->dev,
+ "failed to activate interface %u: %d\n",
+ intf_id, ret);
+ }
+
+ gb_interface_add(intf);
+ goto err_unlock;
+ }
+
+ ret = gb_interface_add(intf);
+ if (ret)
+ goto err_interface_deactivate;
+
+ ret = gb_interface_enable(intf);
+ if (ret) {
+ dev_err(&module->dev, "failed to enable interface %u: %d\n",
+ intf_id, ret);
+ goto err_interface_deactivate;
+ }
+
+ mutex_unlock(&intf->mutex);
+
+ return;
+
+err_interface_deactivate:
+ gb_interface_deactivate(intf);
+err_unlock:
+ mutex_unlock(&intf->mutex);
+}
+
+static void gb_module_deregister_interface(struct gb_interface *intf)
+{
+ /* Mark as disconnected to prevent I/O during disable. */
+ if (intf->module->disconnected)
+ intf->disconnected = true;
+
+ mutex_lock(&intf->mutex);
+ intf->removed = true;
+ gb_interface_disable(intf);
+ gb_interface_deactivate(intf);
+ mutex_unlock(&intf->mutex);
+
+ gb_interface_del(intf);
+}
+
+/* Register a module and its interfaces. */
+int gb_module_add(struct gb_module *module)
+{
+ size_t i;
+ int ret;
+
+ ret = device_add(&module->dev);
+ if (ret) {
+ dev_err(&module->dev, "failed to register module: %d\n", ret);
+ return ret;
+ }
+
+ trace_gb_module_add(module);
+
+ for (i = 0; i < module->num_interfaces; ++i)
+ gb_module_register_interface(module->interfaces[i]);
+
+ return 0;
+}
+
+/* Deregister a module and its interfaces. */
+void gb_module_del(struct gb_module *module)
+{
+ size_t i;
+
+ for (i = 0; i < module->num_interfaces; ++i)
+ gb_module_deregister_interface(module->interfaces[i]);
+
+ trace_gb_module_del(module);
+
+ device_del(&module->dev);
+}
+
+void gb_module_put(struct gb_module *module)
+{
+ size_t i;
+
+ for (i = 0; i < module->num_interfaces; ++i)
+ gb_interface_put(module->interfaces[i]);
+
+ put_device(&module->dev);
+}
diff --git a/drivers/staging/greybus/module.h b/drivers/staging/greybus/module.h
new file mode 100644
index 000000000000..88a97ce04243
--- /dev/null
+++ b/drivers/staging/greybus/module.h
@@ -0,0 +1,34 @@
+/*
+ * Greybus Module code
+ *
+ * Copyright 2016 Google Inc.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __MODULE_H
+#define __MODULE_H
+
+struct gb_module {
+ struct device dev;
+ struct gb_host_device *hd;
+
+ struct list_head hd_node;
+
+ u8 module_id;
+ size_t num_interfaces;
+
+ bool disconnected;
+
+ struct gb_interface *interfaces[0];
+};
+#define to_gb_module(d) container_of(d, struct gb_module, dev)
+
+struct gb_module *gb_module_create(struct gb_host_device *hd, u8 module_id,
+ size_t num_interfaces);
+int gb_module_add(struct gb_module *module);
+void gb_module_del(struct gb_module *module);
+void gb_module_put(struct gb_module *module);
+
+#endif /* __MODULE_H */
diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c
new file mode 100644
index 000000000000..0123109a1070
--- /dev/null
+++ b/drivers/staging/greybus/operation.c
@@ -0,0 +1,1239 @@
+/*
+ * Greybus operations
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include "greybus.h"
+#include "greybus_trace.h"
+
+static struct kmem_cache *gb_operation_cache;
+static struct kmem_cache *gb_message_cache;
+
+/* Workqueue to handle Greybus operation completions. */
+static struct workqueue_struct *gb_operation_completion_wq;
+
+/* Wait queue for synchronous cancellations. */
+static DECLARE_WAIT_QUEUE_HEAD(gb_operation_cancellation_queue);
+
+/*
+ * Protects updates to operation->errno.
+ */
+static DEFINE_SPINLOCK(gb_operations_lock);
+
+static int gb_operation_response_send(struct gb_operation *operation,
+ int errno);
+
+/*
+ * Increment operation active count and add to connection list unless the
+ * connection is going away.
+ *
+ * Caller holds operation reference.
+ */
+static int gb_operation_get_active(struct gb_operation *operation)
+{
+ struct gb_connection *connection = operation->connection;
+ unsigned long flags;
+
+ spin_lock_irqsave(&connection->lock, flags);
+ switch (connection->state) {
+ case GB_CONNECTION_STATE_ENABLED:
+ break;
+ case GB_CONNECTION_STATE_ENABLED_TX:
+ if (gb_operation_is_incoming(operation))
+ goto err_unlock;
+ break;
+ case GB_CONNECTION_STATE_DISCONNECTING:
+ if (!gb_operation_is_core(operation))
+ goto err_unlock;
+ break;
+ default:
+ goto err_unlock;
+ }
+
+ if (operation->active++ == 0)
+ list_add_tail(&operation->links, &connection->operations);
+
+ trace_gb_operation_get_active(operation);
+
+ spin_unlock_irqrestore(&connection->lock, flags);
+
+ return 0;
+
+err_unlock:
+ spin_unlock_irqrestore(&connection->lock, flags);
+
+ return -ENOTCONN;
+}
+
+/* Caller holds operation reference. */
+static void gb_operation_put_active(struct gb_operation *operation)
+{
+ struct gb_connection *connection = operation->connection;
+ unsigned long flags;
+
+ spin_lock_irqsave(&connection->lock, flags);
+
+ trace_gb_operation_put_active(operation);
+
+ if (--operation->active == 0) {
+ list_del(&operation->links);
+ if (atomic_read(&operation->waiters))
+ wake_up(&gb_operation_cancellation_queue);
+ }
+ spin_unlock_irqrestore(&connection->lock, flags);
+}
+
+static bool gb_operation_is_active(struct gb_operation *operation)
+{
+ struct gb_connection *connection = operation->connection;
+ unsigned long flags;
+ bool ret;
+
+ spin_lock_irqsave(&connection->lock, flags);
+ ret = operation->active;
+ spin_unlock_irqrestore(&connection->lock, flags);
+
+ return ret;
+}
+
+/*
+ * Set an operation's result.
+ *
+ * Initially an outgoing operation's errno value is -EBADR.
+ * If no error occurs before sending the request message the only
+ * valid value operation->errno can be set to is -EINPROGRESS,
+ * indicating the request has been (or rather is about to be) sent.
+ * At that point nobody should be looking at the result until the
+ * response arrives.
+ *
+ * The first time the result gets set after the request has been
+ * sent, that result "sticks." That is, if two concurrent threads
+ * race to set the result, the first one wins. The return value
+ * tells the caller whether its result was recorded; if not the
+ * caller has nothing more to do.
+ *
+ * The result value -EILSEQ is reserved to signal an implementation
+ * error; if it's ever observed, the code performing the request has
+ * done something fundamentally wrong. It is an error to try to set
+ * the result to -EBADR, and attempts to do so result in a warning,
+ * and -EILSEQ is used instead. Similarly, the only valid result
+ * value to set for an operation in initial state is -EINPROGRESS.
+ * Attempts to do otherwise will also record a (successful) -EILSEQ
+ * operation result.
+ */
+static bool gb_operation_result_set(struct gb_operation *operation, int result)
+{
+ unsigned long flags;
+ int prev;
+
+ if (result == -EINPROGRESS) {
+ /*
+ * -EINPROGRESS is used to indicate the request is
+ * in flight. It should be the first result value
+ * set after the initial -EBADR. Issue a warning
+ * and record an implementation error if it's
+ * set at any other time.
+ */
+ spin_lock_irqsave(&gb_operations_lock, flags);
+ prev = operation->errno;
+ if (prev == -EBADR)
+ operation->errno = result;
+ else
+ operation->errno = -EILSEQ;
+ spin_unlock_irqrestore(&gb_operations_lock, flags);
+ WARN_ON(prev != -EBADR);
+
+ return true;
+ }
+
+ /*
+ * The first result value set after a request has been sent
+ * will be the final result of the operation. Subsequent
+ * attempts to set the result are ignored.
+ *
+ * Note that -EBADR is a reserved "initial state" result
+ * value. Attempts to set this value result in a warning,
+ * and the result code is set to -EILSEQ instead.
+ */
+ if (WARN_ON(result == -EBADR))
+ result = -EILSEQ; /* Nobody should be setting -EBADR */
+
+ spin_lock_irqsave(&gb_operations_lock, flags);
+ prev = operation->errno;
+ if (prev == -EINPROGRESS)
+ operation->errno = result; /* First and final result */
+ spin_unlock_irqrestore(&gb_operations_lock, flags);
+
+ return prev == -EINPROGRESS;
+}
+
+int gb_operation_result(struct gb_operation *operation)
+{
+ int result = operation->errno;
+
+ WARN_ON(result == -EBADR);
+ WARN_ON(result == -EINPROGRESS);
+
+ return result;
+}
+EXPORT_SYMBOL_GPL(gb_operation_result);
+
+/*
+ * Looks up an outgoing operation on a connection and returns a refcounted
+ * pointer if found, or NULL otherwise.
+ */
+static struct gb_operation *
+gb_operation_find_outgoing(struct gb_connection *connection, u16 operation_id)
+{
+ struct gb_operation *operation;
+ unsigned long flags;
+ bool found = false;
+
+ spin_lock_irqsave(&connection->lock, flags);
+ list_for_each_entry(operation, &connection->operations, links)
+ if (operation->id == operation_id &&
+ !gb_operation_is_incoming(operation)) {
+ gb_operation_get(operation);
+ found = true;
+ break;
+ }
+ spin_unlock_irqrestore(&connection->lock, flags);
+
+ return found ? operation : NULL;
+}
+
+static int gb_message_send(struct gb_message *message, gfp_t gfp)
+{
+ struct gb_connection *connection = message->operation->connection;
+
+ trace_gb_message_send(message);
+ return connection->hd->driver->message_send(connection->hd,
+ connection->hd_cport_id,
+ message,
+ gfp);
+}
+
+/*
+ * Cancel a message we have passed to the host device layer to be sent.
+ */
+static void gb_message_cancel(struct gb_message *message)
+{
+ struct gb_host_device *hd = message->operation->connection->hd;
+
+ hd->driver->message_cancel(message);
+}
+
+static void gb_operation_request_handle(struct gb_operation *operation)
+{
+ struct gb_connection *connection = operation->connection;
+ int status;
+ int ret;
+
+ if (connection->handler) {
+ status = connection->handler(operation);
+ } else {
+ dev_err(&connection->hd->dev,
+ "%s: unexpected incoming request of type 0x%02x\n",
+ connection->name, operation->type);
+
+ status = -EPROTONOSUPPORT;
+ }
+
+ ret = gb_operation_response_send(operation, status);
+ if (ret) {
+ dev_err(&connection->hd->dev,
+ "%s: failed to send response %d for type 0x%02x: %d\n",
+ connection->name, status, operation->type, ret);
+ return;
+ }
+}
+
+/*
+ * Process operation work.
+ *
+ * For incoming requests, call the protocol request handler. The operation
+ * result should be -EINPROGRESS at this point.
+ *
+ * For outgoing requests, the operation result value should have
+ * been set before queueing this. The operation callback function
+ * allows the original requester to know the request has completed
+ * and its result is available.
+ */
+static void gb_operation_work(struct work_struct *work)
+{
+ struct gb_operation *operation;
+
+ operation = container_of(work, struct gb_operation, work);
+
+ if (gb_operation_is_incoming(operation))
+ gb_operation_request_handle(operation);
+ else
+ operation->callback(operation);
+
+ gb_operation_put_active(operation);
+ gb_operation_put(operation);
+}
+
+static void gb_operation_message_init(struct gb_host_device *hd,
+ struct gb_message *message, u16 operation_id,
+ size_t payload_size, u8 type)
+{
+ struct gb_operation_msg_hdr *header;
+
+ header = message->buffer;
+
+ message->header = header;
+ message->payload = payload_size ? header + 1 : NULL;
+ message->payload_size = payload_size;
+
+ /*
+ * The type supplied for incoming message buffers will be
+ * GB_REQUEST_TYPE_INVALID. Such buffers will be overwritten by
+ * arriving data so there's no need to initialize the message header.
+ */
+ if (type != GB_REQUEST_TYPE_INVALID) {
+ u16 message_size = (u16)(sizeof(*header) + payload_size);
+
+ /*
+ * For a request, the operation id gets filled in
+ * when the message is sent. For a response, it
+ * will be copied from the request by the caller.
+ *
+ * The result field in a request message must be
+ * zero. It will be set just prior to sending for
+ * a response.
+ */
+ header->size = cpu_to_le16(message_size);
+ header->operation_id = 0;
+ header->type = type;
+ header->result = 0;
+ }
+}
+
+/*
+ * Allocate a message to be used for an operation request or response.
+ * Both types of message contain a common header. The request message
+ * for an outgoing operation is outbound, as is the response message
+ * for an incoming operation. The message header for an outbound
+ * message is partially initialized here.
+ *
+ * The headers for inbound messages don't need to be initialized;
+ * they'll be filled in by arriving data.
+ *
+ * Our message buffers have the following layout:
+ * message header \_ these combined are
+ * message payload / the message size
+ */
+static struct gb_message *
+gb_operation_message_alloc(struct gb_host_device *hd, u8 type,
+ size_t payload_size, gfp_t gfp_flags)
+{
+ struct gb_message *message;
+ struct gb_operation_msg_hdr *header;
+ size_t message_size = payload_size + sizeof(*header);
+
+ if (message_size > hd->buffer_size_max) {
+ dev_warn(&hd->dev, "requested message size too big (%zu > %zu)\n",
+ message_size, hd->buffer_size_max);
+ return NULL;
+ }
+
+ /* Allocate the message structure and buffer. */
+ message = kmem_cache_zalloc(gb_message_cache, gfp_flags);
+ if (!message)
+ return NULL;
+
+ message->buffer = kzalloc(message_size, gfp_flags);
+ if (!message->buffer)
+ goto err_free_message;
+
+ /* Initialize the message. Operation id is filled in later. */
+ gb_operation_message_init(hd, message, 0, payload_size, type);
+
+ return message;
+
+err_free_message:
+ kmem_cache_free(gb_message_cache, message);
+
+ return NULL;
+}
+
+static void gb_operation_message_free(struct gb_message *message)
+{
+ kfree(message->buffer);
+ kmem_cache_free(gb_message_cache, message);
+}
+
+/*
+ * Map an enum gb_operation_status value (which is represented in a
+ * message as a single byte) to an appropriate Linux negative errno.
+ */
+static int gb_operation_status_map(u8 status)
+{
+ switch (status) {
+ case GB_OP_SUCCESS:
+ return 0;
+ case GB_OP_INTERRUPTED:
+ return -EINTR;
+ case GB_OP_TIMEOUT:
+ return -ETIMEDOUT;
+ case GB_OP_NO_MEMORY:
+ return -ENOMEM;
+ case GB_OP_PROTOCOL_BAD:
+ return -EPROTONOSUPPORT;
+ case GB_OP_OVERFLOW:
+ return -EMSGSIZE;
+ case GB_OP_INVALID:
+ return -EINVAL;
+ case GB_OP_RETRY:
+ return -EAGAIN;
+ case GB_OP_NONEXISTENT:
+ return -ENODEV;
+ case GB_OP_MALFUNCTION:
+ return -EILSEQ;
+ case GB_OP_UNKNOWN_ERROR:
+ default:
+ return -EIO;
+ }
+}
+
+/*
+ * Map a Linux errno value (from operation->errno) into the value
+ * that should represent it in a response message status sent
+ * over the wire. Returns an enum gb_operation_status value (which
+ * is represented in a message as a single byte).
+ */
+static u8 gb_operation_errno_map(int errno)
+{
+ switch (errno) {
+ case 0:
+ return GB_OP_SUCCESS;
+ case -EINTR:
+ return GB_OP_INTERRUPTED;
+ case -ETIMEDOUT:
+ return GB_OP_TIMEOUT;
+ case -ENOMEM:
+ return GB_OP_NO_MEMORY;
+ case -EPROTONOSUPPORT:
+ return GB_OP_PROTOCOL_BAD;
+ case -EMSGSIZE:
+ return GB_OP_OVERFLOW; /* Could be underflow too */
+ case -EINVAL:
+ return GB_OP_INVALID;
+ case -EAGAIN:
+ return GB_OP_RETRY;
+ case -EILSEQ:
+ return GB_OP_MALFUNCTION;
+ case -ENODEV:
+ return GB_OP_NONEXISTENT;
+ case -EIO:
+ default:
+ return GB_OP_UNKNOWN_ERROR;
+ }
+}
+
+bool gb_operation_response_alloc(struct gb_operation *operation,
+ size_t response_size, gfp_t gfp)
+{
+ struct gb_host_device *hd = operation->connection->hd;
+ struct gb_operation_msg_hdr *request_header;
+ struct gb_message *response;
+ u8 type;
+
+ type = operation->type | GB_MESSAGE_TYPE_RESPONSE;
+ response = gb_operation_message_alloc(hd, type, response_size, gfp);
+ if (!response)
+ return false;
+ response->operation = operation;
+
+ /*
+ * Size and type get initialized when the message is
+ * allocated. The errno will be set before sending. All
+ * that's left is the operation id, which we copy from the
+ * request message header (as-is, in little-endian order).
+ */
+ request_header = operation->request->header;
+ response->header->operation_id = request_header->operation_id;
+ operation->response = response;
+
+ return true;
+}
+EXPORT_SYMBOL_GPL(gb_operation_response_alloc);
+
+/*
+ * Create a Greybus operation to be sent over the given connection.
+ * The request buffer will be big enough for a payload of the given
+ * size.
+ *
+ * For outgoing requests, the request message's header will be
+ * initialized with the type of the request and the message size.
+ * Outgoing operations must also specify the response buffer size,
+ * which must be sufficient to hold all expected response data. The
+ * response message header will eventually be overwritten, so there's
+ * no need to initialize it here.
+ *
+ * Request messages for incoming operations can arrive in interrupt
+ * context, so they must be allocated with GFP_ATOMIC. In this case
+ * the request buffer will be immediately overwritten, so there is
+ * no need to initialize the message header. Responsibility for
+ * allocating a response buffer lies with the incoming request
+ * handler for a protocol. So we don't allocate that here.
+ *
+ * Returns a pointer to the new operation or a null pointer if an
+ * error occurs.
+ */
+static struct gb_operation *
+gb_operation_create_common(struct gb_connection *connection, u8 type,
+ size_t request_size, size_t response_size,
+ unsigned long op_flags, gfp_t gfp_flags)
+{
+ struct gb_host_device *hd = connection->hd;
+ struct gb_operation *operation;
+
+ operation = kmem_cache_zalloc(gb_operation_cache, gfp_flags);
+ if (!operation)
+ return NULL;
+ operation->connection = connection;
+
+ operation->request = gb_operation_message_alloc(hd, type, request_size,
+ gfp_flags);
+ if (!operation->request)
+ goto err_cache;
+ operation->request->operation = operation;
+
+ /* Allocate the response buffer for outgoing operations */
+ if (!(op_flags & GB_OPERATION_FLAG_INCOMING)) {
+ if (!gb_operation_response_alloc(operation, response_size,
+ gfp_flags)) {
+ goto err_request;
+ }
+ }
+
+ operation->flags = op_flags;
+ operation->type = type;
+ operation->errno = -EBADR; /* Initial value--means "never set" */
+
+ INIT_WORK(&operation->work, gb_operation_work);
+ init_completion(&operation->completion);
+ kref_init(&operation->kref);
+ atomic_set(&operation->waiters, 0);
+
+ return operation;
+
+err_request:
+ gb_operation_message_free(operation->request);
+err_cache:
+ kmem_cache_free(gb_operation_cache, operation);
+
+ return NULL;
+}
+
+/*
+ * Create a new operation associated with the given connection. The
+ * request and response sizes provided are the number of bytes
+ * required to hold the request/response payload only. Both of
+ * these are allowed to be 0. Note that 0x00 is reserved as an
+ * invalid operation type for all protocols, and this is enforced
+ * here.
+ */
+struct gb_operation *
+gb_operation_create_flags(struct gb_connection *connection,
+ u8 type, size_t request_size,
+ size_t response_size, unsigned long flags,
+ gfp_t gfp)
+{
+ struct gb_operation *operation;
+
+ if (WARN_ON_ONCE(type == GB_REQUEST_TYPE_INVALID))
+ return NULL;
+ if (WARN_ON_ONCE(type & GB_MESSAGE_TYPE_RESPONSE))
+ type &= ~GB_MESSAGE_TYPE_RESPONSE;
+
+ if (WARN_ON_ONCE(flags & ~GB_OPERATION_FLAG_USER_MASK))
+ flags &= GB_OPERATION_FLAG_USER_MASK;
+
+ operation = gb_operation_create_common(connection, type,
+ request_size, response_size,
+ flags, gfp);
+ if (operation)
+ trace_gb_operation_create(operation);
+
+ return operation;
+}
+EXPORT_SYMBOL_GPL(gb_operation_create_flags);
+
+struct gb_operation *
+gb_operation_create_core(struct gb_connection *connection,
+ u8 type, size_t request_size,
+ size_t response_size, unsigned long flags,
+ gfp_t gfp)
+{
+ struct gb_operation *operation;
+
+ flags |= GB_OPERATION_FLAG_CORE;
+
+ operation = gb_operation_create_common(connection, type,
+ request_size, response_size,
+ flags, gfp);
+ if (operation)
+ trace_gb_operation_create_core(operation);
+
+ return operation;
+}
+/* Do not export this function. */
+
+size_t gb_operation_get_payload_size_max(struct gb_connection *connection)
+{
+ struct gb_host_device *hd = connection->hd;
+
+ return hd->buffer_size_max - sizeof(struct gb_operation_msg_hdr);
+}
+EXPORT_SYMBOL_GPL(gb_operation_get_payload_size_max);
+
+static struct gb_operation *
+gb_operation_create_incoming(struct gb_connection *connection, u16 id,
+ u8 type, void *data, size_t size)
+{
+ struct gb_operation *operation;
+ size_t request_size;
+ unsigned long flags = GB_OPERATION_FLAG_INCOMING;
+
+ /* Caller has made sure we at least have a message header. */
+ request_size = size - sizeof(struct gb_operation_msg_hdr);
+
+ if (!id)
+ flags |= GB_OPERATION_FLAG_UNIDIRECTIONAL;
+
+ operation = gb_operation_create_common(connection, type,
+ request_size,
+ GB_REQUEST_TYPE_INVALID,
+ flags, GFP_ATOMIC);
+ if (!operation)
+ return NULL;
+
+ operation->id = id;
+ memcpy(operation->request->header, data, size);
+ trace_gb_operation_create_incoming(operation);
+
+ return operation;
+}
+
+/*
+ * Get an additional reference on an operation.
+ */
+void gb_operation_get(struct gb_operation *operation)
+{
+ kref_get(&operation->kref);
+}
+EXPORT_SYMBOL_GPL(gb_operation_get);
+
+/*
+ * Destroy a previously created operation.
+ */
+static void _gb_operation_destroy(struct kref *kref)
+{
+ struct gb_operation *operation;
+
+ operation = container_of(kref, struct gb_operation, kref);
+
+ trace_gb_operation_destroy(operation);
+
+ if (operation->response)
+ gb_operation_message_free(operation->response);
+ gb_operation_message_free(operation->request);
+
+ kmem_cache_free(gb_operation_cache, operation);
+}
+
+/*
+ * Drop a reference on an operation, and destroy it when the last
+ * one is gone.
+ */
+void gb_operation_put(struct gb_operation *operation)
+{
+ if (WARN_ON(!operation))
+ return;
+
+ kref_put(&operation->kref, _gb_operation_destroy);
+}
+EXPORT_SYMBOL_GPL(gb_operation_put);
+
+/* Tell the requester we're done */
+static void gb_operation_sync_callback(struct gb_operation *operation)
+{
+ complete(&operation->completion);
+}
+
+/**
+ * gb_operation_request_send() - send an operation request message
+ * @operation: the operation to initiate
+ * @callback: the operation completion callback
+ * @gfp: the memory flags to use for any allocations
+ *
+ * The caller has filled in any payload so the request message is ready to go.
+ * The callback function supplied will be called when the response message has
+ * arrived, a unidirectional request has been sent, or the operation is
+ * cancelled, indicating that the operation is complete. The callback function
+ * can fetch the result of the operation using gb_operation_result() if
+ * desired.
+ *
+ * Return: 0 if the request was successfully queued in the host-driver queues,
+ * or a negative errno.
+ */
+int gb_operation_request_send(struct gb_operation *operation,
+ gb_operation_callback callback,
+ gfp_t gfp)
+{
+ struct gb_connection *connection = operation->connection;
+ struct gb_operation_msg_hdr *header;
+ unsigned int cycle;
+ int ret;
+
+ if (gb_connection_is_offloaded(connection))
+ return -EBUSY;
+
+ if (!callback)
+ return -EINVAL;
+
+ /*
+ * Record the callback function, which is executed in
+ * non-atomic (workqueue) context when the final result
+ * of an operation has been set.
+ */
+ operation->callback = callback;
+
+ /*
+ * Assign the operation's id, and store it in the request header.
+ * Zero is a reserved operation id for unidirectional operations.
+ */
+ if (gb_operation_is_unidirectional(operation)) {
+ operation->id = 0;
+ } else {
+ cycle = (unsigned int)atomic_inc_return(&connection->op_cycle);
+ operation->id = (u16)(cycle % U16_MAX + 1);
+ }
+
+ header = operation->request->header;
+ header->operation_id = cpu_to_le16(operation->id);
+
+ gb_operation_result_set(operation, -EINPROGRESS);
+
+ /*
+ * Get an extra reference on the operation. It'll be dropped when the
+ * operation completes.
+ */
+ gb_operation_get(operation);
+ ret = gb_operation_get_active(operation);
+ if (ret)
+ goto err_put;
+
+ ret = gb_message_send(operation->request, gfp);
+ if (ret)
+ goto err_put_active;
+
+ return 0;
+
+err_put_active:
+ gb_operation_put_active(operation);
+err_put:
+ gb_operation_put(operation);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_operation_request_send);
+
+/*
+ * Send a synchronous operation. This function is expected to
+ * block, returning only when the response has arrived, (or when an
+ * error is detected. The return value is the result of the
+ * operation.
+ */
+int gb_operation_request_send_sync_timeout(struct gb_operation *operation,
+ unsigned int timeout)
+{
+ int ret;
+ unsigned long timeout_jiffies;
+
+ ret = gb_operation_request_send(operation, gb_operation_sync_callback,
+ GFP_KERNEL);
+ if (ret)
+ return ret;
+
+ if (timeout)
+ timeout_jiffies = msecs_to_jiffies(timeout);
+ else
+ timeout_jiffies = MAX_SCHEDULE_TIMEOUT;
+
+ ret = wait_for_completion_interruptible_timeout(&operation->completion,
+ timeout_jiffies);
+ if (ret < 0) {
+ /* Cancel the operation if interrupted */
+ gb_operation_cancel(operation, -ECANCELED);
+ } else if (ret == 0) {
+ /* Cancel the operation if op timed out */
+ gb_operation_cancel(operation, -ETIMEDOUT);
+ }
+
+ return gb_operation_result(operation);
+}
+EXPORT_SYMBOL_GPL(gb_operation_request_send_sync_timeout);
+
+/*
+ * Send a response for an incoming operation request. A non-zero
+ * errno indicates a failed operation.
+ *
+ * If there is any response payload, the incoming request handler is
+ * responsible for allocating the response message. Otherwise the
+ * it can simply supply the result errno; this function will
+ * allocate the response message if necessary.
+ */
+static int gb_operation_response_send(struct gb_operation *operation,
+ int errno)
+{
+ struct gb_connection *connection = operation->connection;
+ int ret;
+
+ if (!operation->response &&
+ !gb_operation_is_unidirectional(operation)) {
+ if (!gb_operation_response_alloc(operation, 0, GFP_KERNEL))
+ return -ENOMEM;
+ }
+
+ /* Record the result */
+ if (!gb_operation_result_set(operation, errno)) {
+ dev_err(&connection->hd->dev, "request result already set\n");
+ return -EIO; /* Shouldn't happen */
+ }
+
+ /* Sender of request does not care about response. */
+ if (gb_operation_is_unidirectional(operation))
+ return 0;
+
+ /* Reference will be dropped when message has been sent. */
+ gb_operation_get(operation);
+ ret = gb_operation_get_active(operation);
+ if (ret)
+ goto err_put;
+
+ /* Fill in the response header and send it */
+ operation->response->header->result = gb_operation_errno_map(errno);
+
+ ret = gb_message_send(operation->response, GFP_KERNEL);
+ if (ret)
+ goto err_put_active;
+
+ return 0;
+
+err_put_active:
+ gb_operation_put_active(operation);
+err_put:
+ gb_operation_put(operation);
+
+ return ret;
+}
+
+/*
+ * This function is called when a message send request has completed.
+ */
+void greybus_message_sent(struct gb_host_device *hd,
+ struct gb_message *message, int status)
+{
+ struct gb_operation *operation = message->operation;
+ struct gb_connection *connection = operation->connection;
+
+ /*
+ * If the message was a response, we just need to drop our
+ * reference to the operation. If an error occurred, report
+ * it.
+ *
+ * For requests, if there's no error and the operation in not
+ * unidirectional, there's nothing more to do until the response
+ * arrives. If an error occurred attempting to send it, or if the
+ * operation is unidrectional, record the result of the operation and
+ * schedule its completion.
+ */
+ if (message == operation->response) {
+ if (status) {
+ dev_err(&connection->hd->dev,
+ "%s: error sending response 0x%02x: %d\n",
+ connection->name, operation->type, status);
+ }
+
+ gb_operation_put_active(operation);
+ gb_operation_put(operation);
+ } else if (status || gb_operation_is_unidirectional(operation)) {
+ if (gb_operation_result_set(operation, status)) {
+ queue_work(gb_operation_completion_wq,
+ &operation->work);
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(greybus_message_sent);
+
+/*
+ * We've received data on a connection, and it doesn't look like a
+ * response, so we assume it's a request.
+ *
+ * This is called in interrupt context, so just copy the incoming
+ * data into the request buffer and handle the rest via workqueue.
+ */
+static void gb_connection_recv_request(struct gb_connection *connection,
+ const struct gb_operation_msg_hdr *header,
+ void *data, size_t size)
+{
+ struct gb_operation *operation;
+ u16 operation_id;
+ u8 type;
+ int ret;
+
+ operation_id = le16_to_cpu(header->operation_id);
+ type = header->type;
+
+ operation = gb_operation_create_incoming(connection, operation_id,
+ type, data, size);
+ if (!operation) {
+ dev_err(&connection->hd->dev,
+ "%s: can't create incoming operation\n",
+ connection->name);
+ return;
+ }
+
+ ret = gb_operation_get_active(operation);
+ if (ret) {
+ gb_operation_put(operation);
+ return;
+ }
+ trace_gb_message_recv_request(operation->request);
+
+ /*
+ * The initial reference to the operation will be dropped when the
+ * request handler returns.
+ */
+ if (gb_operation_result_set(operation, -EINPROGRESS))
+ queue_work(connection->wq, &operation->work);
+}
+
+/*
+ * We've received data that appears to be an operation response
+ * message. Look up the operation, and record that we've received
+ * its response.
+ *
+ * This is called in interrupt context, so just copy the incoming
+ * data into the response buffer and handle the rest via workqueue.
+ */
+static void gb_connection_recv_response(struct gb_connection *connection,
+ const struct gb_operation_msg_hdr *header,
+ void *data, size_t size)
+{
+ struct gb_operation *operation;
+ struct gb_message *message;
+ size_t message_size;
+ u16 operation_id;
+ int errno;
+
+ operation_id = le16_to_cpu(header->operation_id);
+
+ if (!operation_id) {
+ dev_err_ratelimited(&connection->hd->dev,
+ "%s: invalid response id 0 received\n",
+ connection->name);
+ return;
+ }
+
+ operation = gb_operation_find_outgoing(connection, operation_id);
+ if (!operation) {
+ dev_err_ratelimited(&connection->hd->dev,
+ "%s: unexpected response id 0x%04x received\n",
+ connection->name, operation_id);
+ return;
+ }
+
+ errno = gb_operation_status_map(header->result);
+ message = operation->response;
+ message_size = sizeof(*header) + message->payload_size;
+ if (!errno && size > message_size) {
+ dev_err_ratelimited(&connection->hd->dev,
+ "%s: malformed response 0x%02x received (%zu > %zu)\n",
+ connection->name, header->type,
+ size, message_size);
+ errno = -EMSGSIZE;
+ } else if (!errno && size < message_size) {
+ if (gb_operation_short_response_allowed(operation)) {
+ message->payload_size = size - sizeof(*header);
+ } else {
+ dev_err_ratelimited(&connection->hd->dev,
+ "%s: short response 0x%02x received (%zu < %zu)\n",
+ connection->name, header->type,
+ size, message_size);
+ errno = -EMSGSIZE;
+ }
+ }
+
+ /* We must ignore the payload if a bad status is returned */
+ if (errno)
+ size = sizeof(*header);
+
+ /* The rest will be handled in work queue context */
+ if (gb_operation_result_set(operation, errno)) {
+ memcpy(message->buffer, data, size);
+
+ trace_gb_message_recv_response(message);
+
+ queue_work(gb_operation_completion_wq, &operation->work);
+ }
+
+ gb_operation_put(operation);
+}
+
+/*
+ * Handle data arriving on a connection. As soon as we return the
+ * supplied data buffer will be reused (so unless we do something
+ * with, it's effectively dropped).
+ */
+void gb_connection_recv(struct gb_connection *connection,
+ void *data, size_t size)
+{
+ struct gb_operation_msg_hdr header;
+ struct device *dev = &connection->hd->dev;
+ size_t msg_size;
+
+ if (connection->state == GB_CONNECTION_STATE_DISABLED ||
+ gb_connection_is_offloaded(connection)) {
+ dev_warn_ratelimited(dev, "%s: dropping %zu received bytes\n",
+ connection->name, size);
+ return;
+ }
+
+ if (size < sizeof(header)) {
+ dev_err_ratelimited(dev, "%s: short message received\n",
+ connection->name);
+ return;
+ }
+
+ /* Use memcpy as data may be unaligned */
+ memcpy(&header, data, sizeof(header));
+ msg_size = le16_to_cpu(header.size);
+ if (size < msg_size) {
+ dev_err_ratelimited(dev,
+ "%s: incomplete message 0x%04x of type 0x%02x received (%zu < %zu)\n",
+ connection->name,
+ le16_to_cpu(header.operation_id),
+ header.type, size, msg_size);
+ return; /* XXX Should still complete operation */
+ }
+
+ if (header.type & GB_MESSAGE_TYPE_RESPONSE) {
+ gb_connection_recv_response(connection, &header, data,
+ msg_size);
+ } else {
+ gb_connection_recv_request(connection, &header, data,
+ msg_size);
+ }
+}
+
+/*
+ * Cancel an outgoing operation synchronously, and record the given error to
+ * indicate why.
+ */
+void gb_operation_cancel(struct gb_operation *operation, int errno)
+{
+ if (WARN_ON(gb_operation_is_incoming(operation)))
+ return;
+
+ if (gb_operation_result_set(operation, errno)) {
+ gb_message_cancel(operation->request);
+ queue_work(gb_operation_completion_wq, &operation->work);
+ }
+ trace_gb_message_cancel_outgoing(operation->request);
+
+ atomic_inc(&operation->waiters);
+ wait_event(gb_operation_cancellation_queue,
+ !gb_operation_is_active(operation));
+ atomic_dec(&operation->waiters);
+}
+EXPORT_SYMBOL_GPL(gb_operation_cancel);
+
+/*
+ * Cancel an incoming operation synchronously. Called during connection tear
+ * down.
+ */
+void gb_operation_cancel_incoming(struct gb_operation *operation, int errno)
+{
+ if (WARN_ON(!gb_operation_is_incoming(operation)))
+ return;
+
+ if (!gb_operation_is_unidirectional(operation)) {
+ /*
+ * Make sure the request handler has submitted the response
+ * before cancelling it.
+ */
+ flush_work(&operation->work);
+ if (!gb_operation_result_set(operation, errno))
+ gb_message_cancel(operation->response);
+ }
+ trace_gb_message_cancel_incoming(operation->response);
+
+ atomic_inc(&operation->waiters);
+ wait_event(gb_operation_cancellation_queue,
+ !gb_operation_is_active(operation));
+ atomic_dec(&operation->waiters);
+}
+
+/**
+ * gb_operation_sync_timeout() - implement a "simple" synchronous operation
+ * @connection: the Greybus connection to send this to
+ * @type: the type of operation to send
+ * @request: pointer to a memory buffer to copy the request from
+ * @request_size: size of @request
+ * @response: pointer to a memory buffer to copy the response to
+ * @response_size: the size of @response.
+ * @timeout: operation timeout in milliseconds
+ *
+ * This function implements a simple synchronous Greybus operation. It sends
+ * the provided operation request and waits (sleeps) until the corresponding
+ * operation response message has been successfully received, or an error
+ * occurs. @request and @response are buffers to hold the request and response
+ * data respectively, and if they are not NULL, their size must be specified in
+ * @request_size and @response_size.
+ *
+ * If a response payload is to come back, and @response is not NULL,
+ * @response_size number of bytes will be copied into @response if the operation
+ * is successful.
+ *
+ * If there is an error, the response buffer is left alone.
+ */
+int gb_operation_sync_timeout(struct gb_connection *connection, int type,
+ void *request, int request_size,
+ void *response, int response_size,
+ unsigned int timeout)
+{
+ struct gb_operation *operation;
+ int ret;
+
+ if ((response_size && !response) ||
+ (request_size && !request))
+ return -EINVAL;
+
+ operation = gb_operation_create(connection, type,
+ request_size, response_size,
+ GFP_KERNEL);
+ if (!operation)
+ return -ENOMEM;
+
+ if (request_size)
+ memcpy(operation->request->payload, request, request_size);
+
+ ret = gb_operation_request_send_sync_timeout(operation, timeout);
+ if (ret) {
+ dev_err(&connection->hd->dev,
+ "%s: synchronous operation id 0x%04x of type 0x%02x failed: %d\n",
+ connection->name, operation->id, type, ret);
+ } else {
+ if (response_size) {
+ memcpy(response, operation->response->payload,
+ response_size);
+ }
+ }
+
+ gb_operation_put(operation);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_operation_sync_timeout);
+
+/**
+ * gb_operation_unidirectional_timeout() - initiate a unidirectional operation
+ * @connection: connection to use
+ * @type: type of operation to send
+ * @request: memory buffer to copy the request from
+ * @request_size: size of @request
+ * @timeout: send timeout in milliseconds
+ *
+ * Initiate a unidirectional operation by sending a request message and
+ * waiting for it to be acknowledged as sent by the host device.
+ *
+ * Note that successful send of a unidirectional operation does not imply that
+ * the request as actually reached the remote end of the connection.
+ */
+int gb_operation_unidirectional_timeout(struct gb_connection *connection,
+ int type, void *request, int request_size,
+ unsigned int timeout)
+{
+ struct gb_operation *operation;
+ int ret;
+
+ if (request_size && !request)
+ return -EINVAL;
+
+ operation = gb_operation_create_flags(connection, type,
+ request_size, 0,
+ GB_OPERATION_FLAG_UNIDIRECTIONAL,
+ GFP_KERNEL);
+ if (!operation)
+ return -ENOMEM;
+
+ if (request_size)
+ memcpy(operation->request->payload, request, request_size);
+
+ ret = gb_operation_request_send_sync_timeout(operation, timeout);
+ if (ret) {
+ dev_err(&connection->hd->dev,
+ "%s: unidirectional operation of type 0x%02x failed: %d\n",
+ connection->name, type, ret);
+ }
+
+ gb_operation_put(operation);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_operation_unidirectional_timeout);
+
+int __init gb_operation_init(void)
+{
+ gb_message_cache = kmem_cache_create("gb_message_cache",
+ sizeof(struct gb_message), 0, 0, NULL);
+ if (!gb_message_cache)
+ return -ENOMEM;
+
+ gb_operation_cache = kmem_cache_create("gb_operation_cache",
+ sizeof(struct gb_operation), 0, 0, NULL);
+ if (!gb_operation_cache)
+ goto err_destroy_message_cache;
+
+ gb_operation_completion_wq = alloc_workqueue("greybus_completion",
+ 0, 0);
+ if (!gb_operation_completion_wq)
+ goto err_destroy_operation_cache;
+
+ return 0;
+
+err_destroy_operation_cache:
+ kmem_cache_destroy(gb_operation_cache);
+ gb_operation_cache = NULL;
+err_destroy_message_cache:
+ kmem_cache_destroy(gb_message_cache);
+ gb_message_cache = NULL;
+
+ return -ENOMEM;
+}
+
+void gb_operation_exit(void)
+{
+ destroy_workqueue(gb_operation_completion_wq);
+ gb_operation_completion_wq = NULL;
+ kmem_cache_destroy(gb_operation_cache);
+ gb_operation_cache = NULL;
+ kmem_cache_destroy(gb_message_cache);
+ gb_message_cache = NULL;
+}
diff --git a/drivers/staging/greybus/operation.h b/drivers/staging/greybus/operation.h
new file mode 100644
index 000000000000..de09a2c7de54
--- /dev/null
+++ b/drivers/staging/greybus/operation.h
@@ -0,0 +1,210 @@
+/*
+ * Greybus operations
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __OPERATION_H
+#define __OPERATION_H
+
+#include <linux/completion.h>
+
+struct gb_operation;
+
+/* The default amount of time a request is given to complete */
+#define GB_OPERATION_TIMEOUT_DEFAULT 1000 /* milliseconds */
+
+/*
+ * The top bit of the type in an operation message header indicates
+ * whether the message is a request (bit clear) or response (bit set)
+ */
+#define GB_MESSAGE_TYPE_RESPONSE ((u8)0x80)
+
+enum gb_operation_result {
+ GB_OP_SUCCESS = 0x00,
+ GB_OP_INTERRUPTED = 0x01,
+ GB_OP_TIMEOUT = 0x02,
+ GB_OP_NO_MEMORY = 0x03,
+ GB_OP_PROTOCOL_BAD = 0x04,
+ GB_OP_OVERFLOW = 0x05,
+ GB_OP_INVALID = 0x06,
+ GB_OP_RETRY = 0x07,
+ GB_OP_NONEXISTENT = 0x08,
+ GB_OP_UNKNOWN_ERROR = 0xfe,
+ GB_OP_MALFUNCTION = 0xff,
+};
+
+#define GB_OPERATION_MESSAGE_SIZE_MIN sizeof(struct gb_operation_msg_hdr)
+#define GB_OPERATION_MESSAGE_SIZE_MAX U16_MAX
+
+/*
+ * Protocol code should only examine the payload and payload_size fields, and
+ * host-controller drivers may use the hcpriv field. All other fields are
+ * intended to be private to the operations core code.
+ */
+struct gb_message {
+ struct gb_operation *operation;
+ struct gb_operation_msg_hdr *header;
+
+ void *payload;
+ size_t payload_size;
+
+ void *buffer;
+
+ void *hcpriv;
+};
+
+#define GB_OPERATION_FLAG_INCOMING BIT(0)
+#define GB_OPERATION_FLAG_UNIDIRECTIONAL BIT(1)
+#define GB_OPERATION_FLAG_SHORT_RESPONSE BIT(2)
+#define GB_OPERATION_FLAG_CORE BIT(3)
+
+#define GB_OPERATION_FLAG_USER_MASK (GB_OPERATION_FLAG_SHORT_RESPONSE | \
+ GB_OPERATION_FLAG_UNIDIRECTIONAL)
+
+/*
+ * A Greybus operation is a remote procedure call performed over a
+ * connection between two UniPro interfaces.
+ *
+ * Every operation consists of a request message sent to the other
+ * end of the connection coupled with a reply message returned to
+ * the sender. Every operation has a type, whose interpretation is
+ * dependent on the protocol associated with the connection.
+ *
+ * Only four things in an operation structure are intended to be
+ * directly usable by protocol handlers: the operation's connection
+ * pointer; the operation type; the request message payload (and
+ * size); and the response message payload (and size). Note that a
+ * message with a 0-byte payload has a null message payload pointer.
+ *
+ * In addition, every operation has a result, which is an errno
+ * value. Protocol handlers access the operation result using
+ * gb_operation_result().
+ */
+typedef void (*gb_operation_callback)(struct gb_operation *);
+struct gb_operation {
+ struct gb_connection *connection;
+ struct gb_message *request;
+ struct gb_message *response;
+
+ unsigned long flags;
+ u8 type;
+ u16 id;
+ int errno; /* Operation result */
+
+ struct work_struct work;
+ gb_operation_callback callback;
+ struct completion completion;
+
+ struct kref kref;
+ atomic_t waiters;
+
+ int active;
+ struct list_head links; /* connection->operations */
+};
+
+static inline bool
+gb_operation_is_incoming(struct gb_operation *operation)
+{
+ return operation->flags & GB_OPERATION_FLAG_INCOMING;
+}
+
+static inline bool
+gb_operation_is_unidirectional(struct gb_operation *operation)
+{
+ return operation->flags & GB_OPERATION_FLAG_UNIDIRECTIONAL;
+}
+
+static inline bool
+gb_operation_short_response_allowed(struct gb_operation *operation)
+{
+ return operation->flags & GB_OPERATION_FLAG_SHORT_RESPONSE;
+}
+
+static inline bool gb_operation_is_core(struct gb_operation *operation)
+{
+ return operation->flags & GB_OPERATION_FLAG_CORE;
+}
+
+void gb_connection_recv(struct gb_connection *connection,
+ void *data, size_t size);
+
+int gb_operation_result(struct gb_operation *operation);
+
+size_t gb_operation_get_payload_size_max(struct gb_connection *connection);
+struct gb_operation *
+gb_operation_create_flags(struct gb_connection *connection,
+ u8 type, size_t request_size,
+ size_t response_size, unsigned long flags,
+ gfp_t gfp);
+
+static inline struct gb_operation *
+gb_operation_create(struct gb_connection *connection,
+ u8 type, size_t request_size,
+ size_t response_size, gfp_t gfp)
+{
+ return gb_operation_create_flags(connection, type, request_size,
+ response_size, 0, gfp);
+}
+
+struct gb_operation *
+gb_operation_create_core(struct gb_connection *connection,
+ u8 type, size_t request_size,
+ size_t response_size, unsigned long flags,
+ gfp_t gfp);
+
+void gb_operation_get(struct gb_operation *operation);
+void gb_operation_put(struct gb_operation *operation);
+
+bool gb_operation_response_alloc(struct gb_operation *operation,
+ size_t response_size, gfp_t gfp);
+
+int gb_operation_request_send(struct gb_operation *operation,
+ gb_operation_callback callback,
+ gfp_t gfp);
+int gb_operation_request_send_sync_timeout(struct gb_operation *operation,
+ unsigned int timeout);
+static inline int
+gb_operation_request_send_sync(struct gb_operation *operation)
+{
+ return gb_operation_request_send_sync_timeout(operation,
+ GB_OPERATION_TIMEOUT_DEFAULT);
+}
+
+void gb_operation_cancel(struct gb_operation *operation, int errno);
+void gb_operation_cancel_incoming(struct gb_operation *operation, int errno);
+
+void greybus_message_sent(struct gb_host_device *hd,
+ struct gb_message *message, int status);
+
+int gb_operation_sync_timeout(struct gb_connection *connection, int type,
+ void *request, int request_size,
+ void *response, int response_size,
+ unsigned int timeout);
+int gb_operation_unidirectional_timeout(struct gb_connection *connection,
+ int type, void *request, int request_size,
+ unsigned int timeout);
+
+static inline int gb_operation_sync(struct gb_connection *connection, int type,
+ void *request, int request_size,
+ void *response, int response_size)
+{
+ return gb_operation_sync_timeout(connection, type,
+ request, request_size, response, response_size,
+ GB_OPERATION_TIMEOUT_DEFAULT);
+}
+
+static inline int gb_operation_unidirectional(struct gb_connection *connection,
+ int type, void *request, int request_size)
+{
+ return gb_operation_unidirectional_timeout(connection, type,
+ request, request_size, GB_OPERATION_TIMEOUT_DEFAULT);
+}
+
+int gb_operation_init(void);
+void gb_operation_exit(void);
+
+#endif /* !__OPERATION_H */
diff --git a/drivers/staging/greybus/power_supply.c b/drivers/staging/greybus/power_supply.c
new file mode 100644
index 000000000000..e85c988b7034
--- /dev/null
+++ b/drivers/staging/greybus/power_supply.c
@@ -0,0 +1,1141 @@
+/*
+ * Power Supply driver for a Greybus module.
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/power_supply.h>
+#include <linux/slab.h>
+
+#include "greybus.h"
+
+#define PROP_MAX 32
+
+struct gb_power_supply_prop {
+ enum power_supply_property prop;
+ u8 gb_prop;
+ int val;
+ int previous_val;
+ bool is_writeable;
+};
+
+struct gb_power_supply {
+ u8 id;
+ bool registered;
+ struct power_supply *psy;
+ struct power_supply_desc desc;
+ char name[64];
+ struct gb_power_supplies *supplies;
+ struct delayed_work work;
+ char *manufacturer;
+ char *model_name;
+ char *serial_number;
+ u8 type;
+ u8 properties_count;
+ u8 properties_count_str;
+ unsigned long last_update;
+ u8 cache_invalid;
+ unsigned int update_interval;
+ bool changed;
+ struct gb_power_supply_prop *props;
+ enum power_supply_property *props_raw;
+ bool pm_acquired;
+ struct mutex supply_lock;
+};
+
+struct gb_power_supplies {
+ struct gb_connection *connection;
+ u8 supplies_count;
+ struct gb_power_supply *supply;
+ struct mutex supplies_lock;
+};
+
+#define to_gb_power_supply(x) power_supply_get_drvdata(x)
+
+/*
+ * General power supply properties that could be absent from various reasons,
+ * like kernel versions or vendor specific versions
+ */
+#ifndef POWER_SUPPLY_PROP_VOLTAGE_BOOT
+ #define POWER_SUPPLY_PROP_VOLTAGE_BOOT -1
+#endif
+#ifndef POWER_SUPPLY_PROP_CURRENT_BOOT
+ #define POWER_SUPPLY_PROP_CURRENT_BOOT -1
+#endif
+#ifndef POWER_SUPPLY_PROP_CALIBRATE
+ #define POWER_SUPPLY_PROP_CALIBRATE -1
+#endif
+
+/* cache time in milliseconds, if cache_time is set to 0 cache is disable */
+static unsigned int cache_time = 1000;
+/*
+ * update interval initial and maximum value, between the two will
+ * back-off exponential
+ */
+static unsigned int update_interval_init = 1 * HZ;
+static unsigned int update_interval_max = 30 * HZ;
+
+struct gb_power_supply_changes {
+ enum power_supply_property prop;
+ u32 tolerance_change;
+ void (*prop_changed)(struct gb_power_supply *gbpsy,
+ struct gb_power_supply_prop *prop);
+};
+
+static void gb_power_supply_state_change(struct gb_power_supply *gbpsy,
+ struct gb_power_supply_prop *prop);
+
+static const struct gb_power_supply_changes psy_props_changes[] = {
+ { .prop = GB_POWER_SUPPLY_PROP_STATUS,
+ .tolerance_change = 0,
+ .prop_changed = gb_power_supply_state_change,
+ },
+ { .prop = GB_POWER_SUPPLY_PROP_TEMP,
+ .tolerance_change = 500,
+ .prop_changed = NULL,
+ },
+ { .prop = GB_POWER_SUPPLY_PROP_ONLINE,
+ .tolerance_change = 0,
+ .prop_changed = NULL,
+ },
+};
+
+static int get_psp_from_gb_prop(int gb_prop, enum power_supply_property *psp)
+{
+ int prop;
+
+ switch (gb_prop) {
+ case GB_POWER_SUPPLY_PROP_STATUS:
+ prop = POWER_SUPPLY_PROP_STATUS;
+ break;
+ case GB_POWER_SUPPLY_PROP_CHARGE_TYPE:
+ prop = POWER_SUPPLY_PROP_CHARGE_TYPE;
+ break;
+ case GB_POWER_SUPPLY_PROP_HEALTH:
+ prop = POWER_SUPPLY_PROP_HEALTH;
+ break;
+ case GB_POWER_SUPPLY_PROP_PRESENT:
+ prop = POWER_SUPPLY_PROP_PRESENT;
+ break;
+ case GB_POWER_SUPPLY_PROP_ONLINE:
+ prop = POWER_SUPPLY_PROP_ONLINE;
+ break;
+ case GB_POWER_SUPPLY_PROP_AUTHENTIC:
+ prop = POWER_SUPPLY_PROP_AUTHENTIC;
+ break;
+ case GB_POWER_SUPPLY_PROP_TECHNOLOGY:
+ prop = POWER_SUPPLY_PROP_TECHNOLOGY;
+ break;
+ case GB_POWER_SUPPLY_PROP_CYCLE_COUNT:
+ prop = POWER_SUPPLY_PROP_CYCLE_COUNT;
+ break;
+ case GB_POWER_SUPPLY_PROP_VOLTAGE_MAX:
+ prop = POWER_SUPPLY_PROP_VOLTAGE_MAX;
+ break;
+ case GB_POWER_SUPPLY_PROP_VOLTAGE_MIN:
+ prop = POWER_SUPPLY_PROP_VOLTAGE_MIN;
+ break;
+ case GB_POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+ prop = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN;
+ break;
+ case GB_POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+ prop = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN;
+ break;
+ case GB_POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ prop = POWER_SUPPLY_PROP_VOLTAGE_NOW;
+ break;
+ case GB_POWER_SUPPLY_PROP_VOLTAGE_AVG:
+ prop = POWER_SUPPLY_PROP_VOLTAGE_AVG;
+ break;
+ case GB_POWER_SUPPLY_PROP_VOLTAGE_OCV:
+ prop = POWER_SUPPLY_PROP_VOLTAGE_OCV;
+ break;
+ case GB_POWER_SUPPLY_PROP_VOLTAGE_BOOT:
+ prop = POWER_SUPPLY_PROP_VOLTAGE_BOOT;
+ break;
+ case GB_POWER_SUPPLY_PROP_CURRENT_MAX:
+ prop = POWER_SUPPLY_PROP_CURRENT_MAX;
+ break;
+ case GB_POWER_SUPPLY_PROP_CURRENT_NOW:
+ prop = POWER_SUPPLY_PROP_CURRENT_NOW;
+ break;
+ case GB_POWER_SUPPLY_PROP_CURRENT_AVG:
+ prop = POWER_SUPPLY_PROP_CURRENT_AVG;
+ break;
+ case GB_POWER_SUPPLY_PROP_CURRENT_BOOT:
+ prop = POWER_SUPPLY_PROP_CURRENT_BOOT;
+ break;
+ case GB_POWER_SUPPLY_PROP_POWER_NOW:
+ prop = POWER_SUPPLY_PROP_POWER_NOW;
+ break;
+ case GB_POWER_SUPPLY_PROP_POWER_AVG:
+ prop = POWER_SUPPLY_PROP_POWER_AVG;
+ break;
+ case GB_POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+ prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;
+ break;
+ case GB_POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN:
+ prop = POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN;
+ break;
+ case GB_POWER_SUPPLY_PROP_CHARGE_FULL:
+ prop = POWER_SUPPLY_PROP_CHARGE_FULL;
+ break;
+ case GB_POWER_SUPPLY_PROP_CHARGE_EMPTY:
+ prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+ break;
+ case GB_POWER_SUPPLY_PROP_CHARGE_NOW:
+ prop = POWER_SUPPLY_PROP_CHARGE_NOW;
+ break;
+ case GB_POWER_SUPPLY_PROP_CHARGE_AVG:
+ prop = POWER_SUPPLY_PROP_CHARGE_AVG;
+ break;
+ case GB_POWER_SUPPLY_PROP_CHARGE_COUNTER:
+ prop = POWER_SUPPLY_PROP_CHARGE_COUNTER;
+ break;
+ case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+ prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT;
+ break;
+ case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
+ prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
+ break;
+ case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
+ prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE;
+ break;
+ case GB_POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
+ prop = POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX;
+ break;
+ case GB_POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
+ prop = POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT;
+ break;
+ case GB_POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX:
+ prop = POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX;
+ break;
+ case GB_POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
+ prop = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
+ break;
+ case GB_POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+ prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
+ break;
+ case GB_POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN:
+ prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN;
+ break;
+ case GB_POWER_SUPPLY_PROP_ENERGY_FULL:
+ prop = POWER_SUPPLY_PROP_ENERGY_FULL;
+ break;
+ case GB_POWER_SUPPLY_PROP_ENERGY_EMPTY:
+ prop = POWER_SUPPLY_PROP_ENERGY_EMPTY;
+ break;
+ case GB_POWER_SUPPLY_PROP_ENERGY_NOW:
+ prop = POWER_SUPPLY_PROP_ENERGY_NOW;
+ break;
+ case GB_POWER_SUPPLY_PROP_ENERGY_AVG:
+ prop = POWER_SUPPLY_PROP_ENERGY_AVG;
+ break;
+ case GB_POWER_SUPPLY_PROP_CAPACITY:
+ prop = POWER_SUPPLY_PROP_CAPACITY;
+ break;
+ case GB_POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
+ prop = POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN;
+ break;
+ case GB_POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX:
+ prop = POWER_SUPPLY_PROP_CAPACITY_ALERT_MAX;
+ break;
+ case GB_POWER_SUPPLY_PROP_CAPACITY_LEVEL:
+ prop = POWER_SUPPLY_PROP_CAPACITY_LEVEL;
+ break;
+ case GB_POWER_SUPPLY_PROP_TEMP:
+ prop = POWER_SUPPLY_PROP_TEMP;
+ break;
+ case GB_POWER_SUPPLY_PROP_TEMP_MAX:
+ prop = POWER_SUPPLY_PROP_TEMP_MAX;
+ break;
+ case GB_POWER_SUPPLY_PROP_TEMP_MIN:
+ prop = POWER_SUPPLY_PROP_TEMP_MIN;
+ break;
+ case GB_POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
+ prop = POWER_SUPPLY_PROP_TEMP_ALERT_MIN;
+ break;
+ case GB_POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
+ prop = POWER_SUPPLY_PROP_TEMP_ALERT_MAX;
+ break;
+ case GB_POWER_SUPPLY_PROP_TEMP_AMBIENT:
+ prop = POWER_SUPPLY_PROP_TEMP_AMBIENT;
+ break;
+ case GB_POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN:
+ prop = POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN;
+ break;
+ case GB_POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX:
+ prop = POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX;
+ break;
+ case GB_POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
+ prop = POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW;
+ break;
+ case GB_POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
+ prop = POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG;
+ break;
+ case GB_POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
+ prop = POWER_SUPPLY_PROP_TIME_TO_FULL_NOW;
+ break;
+ case GB_POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
+ prop = POWER_SUPPLY_PROP_TIME_TO_FULL_AVG;
+ break;
+ case GB_POWER_SUPPLY_PROP_TYPE:
+ prop = POWER_SUPPLY_PROP_TYPE;
+ break;
+ case GB_POWER_SUPPLY_PROP_SCOPE:
+ prop = POWER_SUPPLY_PROP_SCOPE;
+ break;
+ case GB_POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
+ prop = POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT;
+ break;
+ case GB_POWER_SUPPLY_PROP_CALIBRATE:
+ prop = POWER_SUPPLY_PROP_CALIBRATE;
+ break;
+ default:
+ prop = -1;
+ break;
+ }
+
+ if (prop < 0)
+ return prop;
+
+ *psp = (enum power_supply_property)prop;
+
+ return 0;
+}
+
+static struct gb_connection *get_conn_from_psy(struct gb_power_supply *gbpsy)
+{
+ return gbpsy->supplies->connection;
+}
+
+static struct gb_power_supply_prop *get_psy_prop(struct gb_power_supply *gbpsy,
+ enum power_supply_property psp)
+{
+ int i;
+
+ for (i = 0; i < gbpsy->properties_count; i++)
+ if (gbpsy->props[i].prop == psp)
+ return &gbpsy->props[i];
+ return NULL;
+}
+
+static int is_psy_prop_writeable(struct gb_power_supply *gbpsy,
+ enum power_supply_property psp)
+{
+ struct gb_power_supply_prop *prop;
+
+ prop = get_psy_prop(gbpsy, psp);
+ if (!prop)
+ return -ENOENT;
+ return prop->is_writeable ? 1 : 0;
+}
+
+static int is_prop_valint(enum power_supply_property psp)
+{
+ return ((psp < POWER_SUPPLY_PROP_MODEL_NAME) ? 1 : 0);
+}
+
+static void next_interval(struct gb_power_supply *gbpsy)
+{
+ if (gbpsy->update_interval == update_interval_max)
+ return;
+
+ /* do some exponential back-off in the update interval */
+ gbpsy->update_interval *= 2;
+ if (gbpsy->update_interval > update_interval_max)
+ gbpsy->update_interval = update_interval_max;
+}
+
+static void __gb_power_supply_changed(struct gb_power_supply *gbpsy)
+{
+ power_supply_changed(gbpsy->psy);
+}
+
+static void gb_power_supply_state_change(struct gb_power_supply *gbpsy,
+ struct gb_power_supply_prop *prop)
+{
+ struct gb_connection *connection = get_conn_from_psy(gbpsy);
+ int ret;
+
+ /*
+ * Check gbpsy->pm_acquired to make sure only one pair of 'get_sync'
+ * and 'put_autosuspend' runtime pm call for state property change.
+ */
+ mutex_lock(&gbpsy->supply_lock);
+
+ if ((prop->val == GB_POWER_SUPPLY_STATUS_CHARGING) &&
+ !gbpsy->pm_acquired) {
+ ret = gb_pm_runtime_get_sync(connection->bundle);
+ if (ret)
+ dev_err(&connection->bundle->dev,
+ "Fail to set wake lock for charging state\n");
+ else
+ gbpsy->pm_acquired = true;
+ } else {
+ if (gbpsy->pm_acquired) {
+ ret = gb_pm_runtime_put_autosuspend(connection->bundle);
+ if (ret)
+ dev_err(&connection->bundle->dev,
+ "Fail to set wake unlock for none charging\n");
+ else
+ gbpsy->pm_acquired = false;
+ }
+ }
+
+ mutex_unlock(&gbpsy->supply_lock);
+}
+
+static void check_changed(struct gb_power_supply *gbpsy,
+ struct gb_power_supply_prop *prop)
+{
+ const struct gb_power_supply_changes *psyc;
+ int val = prop->val;
+ int prev_val = prop->previous_val;
+ bool changed = false;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(psy_props_changes); i++) {
+ psyc = &psy_props_changes[i];
+ if (prop->prop == psyc->prop) {
+ if (!psyc->tolerance_change)
+ changed = true;
+ else if (val < prev_val &&
+ prev_val - val > psyc->tolerance_change)
+ changed = true;
+ else if (val > prev_val &&
+ val - prev_val > psyc->tolerance_change)
+ changed = true;
+
+ if (changed && psyc->prop_changed)
+ psyc->prop_changed(gbpsy, prop);
+
+ if (changed)
+ gbpsy->changed = true;
+ break;
+ }
+ }
+}
+
+static int total_props(struct gb_power_supply *gbpsy)
+{
+ /* this return the intval plus the strval properties */
+ return (gbpsy->properties_count + gbpsy->properties_count_str);
+}
+
+static void prop_append(struct gb_power_supply *gbpsy,
+ enum power_supply_property prop)
+{
+ enum power_supply_property *new_props_raw;
+
+ gbpsy->properties_count_str++;
+ new_props_raw = krealloc(gbpsy->props_raw, total_props(gbpsy) *
+ sizeof(enum power_supply_property),
+ GFP_KERNEL);
+ if (!new_props_raw)
+ return;
+ gbpsy->props_raw = new_props_raw;
+ gbpsy->props_raw[total_props(gbpsy) - 1] = prop;
+}
+
+static int __gb_power_supply_set_name(char *init_name, char *name, size_t len)
+{
+ unsigned int i = 0;
+ int ret = 0;
+ struct power_supply *psy;
+
+ if (!strlen(init_name))
+ init_name = "gb_power_supply";
+ strlcpy(name, init_name, len);
+
+ while ((ret < len) && (psy = power_supply_get_by_name(name))) {
+ power_supply_put(psy);
+
+ ret = snprintf(name, len, "%s_%u", init_name, ++i);
+ }
+ if (ret >= len)
+ return -ENOMEM;
+ return i;
+}
+
+static void _gb_power_supply_append_props(struct gb_power_supply *gbpsy)
+{
+ if (strlen(gbpsy->manufacturer))
+ prop_append(gbpsy, POWER_SUPPLY_PROP_MANUFACTURER);
+ if (strlen(gbpsy->model_name))
+ prop_append(gbpsy, POWER_SUPPLY_PROP_MODEL_NAME);
+ if (strlen(gbpsy->serial_number))
+ prop_append(gbpsy, POWER_SUPPLY_PROP_SERIAL_NUMBER);
+}
+
+static int gb_power_supply_description_get(struct gb_power_supply *gbpsy)
+{
+ struct gb_connection *connection = get_conn_from_psy(gbpsy);
+ struct gb_power_supply_get_description_request req;
+ struct gb_power_supply_get_description_response resp;
+ int ret;
+
+ req.psy_id = gbpsy->id;
+
+ ret = gb_operation_sync(connection,
+ GB_POWER_SUPPLY_TYPE_GET_DESCRIPTION,
+ &req, sizeof(req), &resp, sizeof(resp));
+ if (ret < 0)
+ return ret;
+
+ gbpsy->manufacturer = kstrndup(resp.manufacturer, PROP_MAX, GFP_KERNEL);
+ if (!gbpsy->manufacturer)
+ return -ENOMEM;
+ gbpsy->model_name = kstrndup(resp.model, PROP_MAX, GFP_KERNEL);
+ if (!gbpsy->model_name)
+ return -ENOMEM;
+ gbpsy->serial_number = kstrndup(resp.serial_number, PROP_MAX,
+ GFP_KERNEL);
+ if (!gbpsy->serial_number)
+ return -ENOMEM;
+
+ gbpsy->type = le16_to_cpu(resp.type);
+ gbpsy->properties_count = resp.properties_count;
+
+ return 0;
+}
+
+static int gb_power_supply_prop_descriptors_get(struct gb_power_supply *gbpsy)
+{
+ struct gb_connection *connection = get_conn_from_psy(gbpsy);
+ struct gb_power_supply_get_property_descriptors_request *req;
+ struct gb_power_supply_get_property_descriptors_response *resp;
+ struct gb_operation *op;
+ u8 props_count = gbpsy->properties_count;
+ enum power_supply_property psp;
+ int ret;
+ int i, r = 0;
+
+ if (props_count == 0)
+ return 0;
+
+ op = gb_operation_create(connection,
+ GB_POWER_SUPPLY_TYPE_GET_PROP_DESCRIPTORS,
+ sizeof(req), sizeof(*resp) + props_count *
+ sizeof(struct gb_power_supply_props_desc),
+ GFP_KERNEL);
+ if (!op)
+ return -ENOMEM;
+
+ req = op->request->payload;
+ req->psy_id = gbpsy->id;
+
+ ret = gb_operation_request_send_sync(op);
+ if (ret < 0)
+ goto out_put_operation;
+
+ resp = op->response->payload;
+
+ /* validate received properties */
+ for (i = 0; i < props_count; i++) {
+ ret = get_psp_from_gb_prop(resp->props[i].property, &psp);
+ if (ret < 0) {
+ dev_warn(&connection->bundle->dev,
+ "greybus property %u it is not supported by this kernel, dropped\n",
+ resp->props[i].property);
+ gbpsy->properties_count--;
+ }
+ }
+
+ gbpsy->props = kcalloc(gbpsy->properties_count, sizeof(*gbpsy->props),
+ GFP_KERNEL);
+ if (!gbpsy->props) {
+ ret = -ENOMEM;
+ goto out_put_operation;
+ }
+
+ gbpsy->props_raw = kcalloc(gbpsy->properties_count,
+ sizeof(*gbpsy->props_raw), GFP_KERNEL);
+ if (!gbpsy->props_raw) {
+ ret = -ENOMEM;
+ goto out_put_operation;
+ }
+
+ /* Store available properties, skip the ones we do not support */
+ for (i = 0; i < props_count; i++) {
+ ret = get_psp_from_gb_prop(resp->props[i].property, &psp);
+ if (ret < 0) {
+ r++;
+ continue;
+ }
+ gbpsy->props[i - r].prop = psp;
+ gbpsy->props[i - r].gb_prop = resp->props[i].property;
+ gbpsy->props_raw[i - r] = psp;
+ if (resp->props[i].is_writeable)
+ gbpsy->props[i - r].is_writeable = true;
+ }
+
+ /*
+ * now append the properties that we already got information in the
+ * get_description operation. (char * ones)
+ */
+ _gb_power_supply_append_props(gbpsy);
+
+ ret = 0;
+out_put_operation:
+ gb_operation_put(op);
+
+ return ret;
+}
+
+static int __gb_power_supply_property_update(struct gb_power_supply *gbpsy,
+ enum power_supply_property psp)
+{
+ struct gb_connection *connection = get_conn_from_psy(gbpsy);
+ struct gb_power_supply_prop *prop;
+ struct gb_power_supply_get_property_request req;
+ struct gb_power_supply_get_property_response resp;
+ int val;
+ int ret;
+
+ prop = get_psy_prop(gbpsy, psp);
+ if (!prop)
+ return -EINVAL;
+ req.psy_id = gbpsy->id;
+ req.property = prop->gb_prop;
+
+ ret = gb_operation_sync(connection, GB_POWER_SUPPLY_TYPE_GET_PROPERTY,
+ &req, sizeof(req), &resp, sizeof(resp));
+ if (ret < 0)
+ return ret;
+
+ val = le32_to_cpu(resp.prop_val);
+ if (val == prop->val)
+ return 0;
+
+ prop->previous_val = prop->val;
+ prop->val = val;
+
+ check_changed(gbpsy, prop);
+
+ return 0;
+}
+
+static int __gb_power_supply_property_get(struct gb_power_supply *gbpsy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct gb_power_supply_prop *prop;
+
+ prop = get_psy_prop(gbpsy, psp);
+ if (!prop)
+ return -EINVAL;
+
+ val->intval = prop->val;
+ return 0;
+}
+
+static int __gb_power_supply_property_strval_get(struct gb_power_supply *gbpsy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ switch (psp) {
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = gbpsy->model_name;
+ break;
+ case POWER_SUPPLY_PROP_MANUFACTURER:
+ val->strval = gbpsy->manufacturer;
+ break;
+ case POWER_SUPPLY_PROP_SERIAL_NUMBER:
+ val->strval = gbpsy->serial_number;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int _gb_power_supply_property_get(struct gb_power_supply *gbpsy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct gb_connection *connection = get_conn_from_psy(gbpsy);
+ int ret;
+
+ /*
+ * Properties of type const char *, were already fetched on
+ * get_description operation and should be cached in gb
+ */
+ if (is_prop_valint(psp))
+ ret = __gb_power_supply_property_get(gbpsy, psp, val);
+ else
+ ret = __gb_power_supply_property_strval_get(gbpsy, psp, val);
+
+ if (ret < 0)
+ dev_err(&connection->bundle->dev, "get property %u\n", psp);
+
+ return 0;
+}
+
+static int is_cache_valid(struct gb_power_supply *gbpsy)
+{
+ /* check if cache is good enough or it has expired */
+ if (gbpsy->cache_invalid) {
+ gbpsy->cache_invalid = 0;
+ return 0;
+ }
+
+ if (gbpsy->last_update &&
+ time_is_after_jiffies(gbpsy->last_update +
+ msecs_to_jiffies(cache_time)))
+ return 1;
+
+ return 0;
+}
+
+static int gb_power_supply_status_get(struct gb_power_supply *gbpsy)
+{
+ struct gb_connection *connection = get_conn_from_psy(gbpsy);
+ int ret = 0;
+ int i;
+
+ if (is_cache_valid(gbpsy))
+ return 0;
+
+ ret = gb_pm_runtime_get_sync(connection->bundle);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < gbpsy->properties_count; i++) {
+ ret = __gb_power_supply_property_update(gbpsy,
+ gbpsy->props[i].prop);
+ if (ret < 0)
+ break;
+ }
+
+ if (ret == 0)
+ gbpsy->last_update = jiffies;
+
+ gb_pm_runtime_put_autosuspend(connection->bundle);
+ return ret;
+}
+
+static void gb_power_supply_status_update(struct gb_power_supply *gbpsy)
+{
+ /* check if there a change that need to be reported */
+ gb_power_supply_status_get(gbpsy);
+
+ if (!gbpsy->changed)
+ return;
+
+ gbpsy->update_interval = update_interval_init;
+ __gb_power_supply_changed(gbpsy);
+ gbpsy->changed = false;
+}
+
+static void gb_power_supply_work(struct work_struct *work)
+{
+ struct gb_power_supply *gbpsy = container_of(work,
+ struct gb_power_supply,
+ work.work);
+
+ /*
+ * if the poll interval is not set, disable polling, this is helpful
+ * specially at unregister time.
+ */
+ if (!gbpsy->update_interval)
+ return;
+
+ gb_power_supply_status_update(gbpsy);
+ next_interval(gbpsy);
+ schedule_delayed_work(&gbpsy->work, gbpsy->update_interval);
+}
+
+static int get_property(struct power_supply *b,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct gb_power_supply *gbpsy = to_gb_power_supply(b);
+
+ gb_power_supply_status_get(gbpsy);
+
+ return _gb_power_supply_property_get(gbpsy, psp, val);
+}
+
+static int gb_power_supply_property_set(struct gb_power_supply *gbpsy,
+ enum power_supply_property psp,
+ int val)
+{
+ struct gb_connection *connection = get_conn_from_psy(gbpsy);
+ struct gb_power_supply_prop *prop;
+ struct gb_power_supply_set_property_request req;
+ int ret;
+
+ ret = gb_pm_runtime_get_sync(connection->bundle);
+ if (ret)
+ return ret;
+
+ prop = get_psy_prop(gbpsy, psp);
+ if (!prop) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ req.psy_id = gbpsy->id;
+ req.property = prop->gb_prop;
+ req.prop_val = cpu_to_le32((s32)val);
+
+ ret = gb_operation_sync(connection, GB_POWER_SUPPLY_TYPE_SET_PROPERTY,
+ &req, sizeof(req), NULL, 0);
+ if (ret < 0)
+ goto out;
+
+ /* cache immediately the new value */
+ prop->val = val;
+
+out:
+ gb_pm_runtime_put_autosuspend(connection->bundle);
+ return ret;
+}
+
+static int set_property(struct power_supply *b,
+ enum power_supply_property psp,
+ const union power_supply_propval *val)
+{
+ struct gb_power_supply *gbpsy = to_gb_power_supply(b);
+
+ return gb_power_supply_property_set(gbpsy, psp, val->intval);
+}
+
+static int property_is_writeable(struct power_supply *b,
+ enum power_supply_property psp)
+{
+ struct gb_power_supply *gbpsy = to_gb_power_supply(b);
+
+ return is_psy_prop_writeable(gbpsy, psp);
+}
+
+static int gb_power_supply_register(struct gb_power_supply *gbpsy)
+{
+ struct gb_connection *connection = get_conn_from_psy(gbpsy);
+ struct power_supply_config cfg = {};
+
+ cfg.drv_data = gbpsy;
+
+ gbpsy->desc.name = gbpsy->name;
+ gbpsy->desc.type = gbpsy->type;
+ gbpsy->desc.properties = gbpsy->props_raw;
+ gbpsy->desc.num_properties = total_props(gbpsy);
+ gbpsy->desc.get_property = get_property;
+ gbpsy->desc.set_property = set_property;
+ gbpsy->desc.property_is_writeable = property_is_writeable;
+
+ gbpsy->psy = power_supply_register(&connection->bundle->dev,
+ &gbpsy->desc, &cfg);
+ return PTR_ERR_OR_ZERO(gbpsy->psy);
+}
+
+static void _gb_power_supply_free(struct gb_power_supply *gbpsy)
+{
+ kfree(gbpsy->serial_number);
+ kfree(gbpsy->model_name);
+ kfree(gbpsy->manufacturer);
+ kfree(gbpsy->props_raw);
+ kfree(gbpsy->props);
+}
+
+static void _gb_power_supply_release(struct gb_power_supply *gbpsy)
+{
+ gbpsy->update_interval = 0;
+
+ cancel_delayed_work_sync(&gbpsy->work);
+
+ if (gbpsy->registered)
+ power_supply_unregister(gbpsy->psy);
+
+ _gb_power_supply_free(gbpsy);
+}
+
+static void _gb_power_supplies_release(struct gb_power_supplies *supplies)
+{
+ int i;
+
+ if (!supplies->supply)
+ return;
+
+ mutex_lock(&supplies->supplies_lock);
+ for (i = 0; i < supplies->supplies_count; i++)
+ _gb_power_supply_release(&supplies->supply[i]);
+ kfree(supplies->supply);
+ mutex_unlock(&supplies->supplies_lock);
+ kfree(supplies);
+}
+
+static int gb_power_supplies_get_count(struct gb_power_supplies *supplies)
+{
+ struct gb_power_supply_get_supplies_response resp;
+ int ret;
+
+ ret = gb_operation_sync(supplies->connection,
+ GB_POWER_SUPPLY_TYPE_GET_SUPPLIES,
+ NULL, 0, &resp, sizeof(resp));
+ if (ret < 0)
+ return ret;
+
+ if (!resp.supplies_count)
+ return -EINVAL;
+
+ supplies->supplies_count = resp.supplies_count;
+
+ return ret;
+}
+
+static int gb_power_supply_config(struct gb_power_supplies *supplies, int id)
+{
+ struct gb_power_supply *gbpsy = &supplies->supply[id];
+ int ret;
+
+ gbpsy->supplies = supplies;
+ gbpsy->id = id;
+
+ ret = gb_power_supply_description_get(gbpsy);
+ if (ret < 0)
+ return ret;
+
+ return gb_power_supply_prop_descriptors_get(gbpsy);
+}
+
+static int gb_power_supply_enable(struct gb_power_supply *gbpsy)
+{
+ int ret;
+
+ /* guarantee that we have an unique name, before register */
+ ret = __gb_power_supply_set_name(gbpsy->model_name, gbpsy->name,
+ sizeof(gbpsy->name));
+ if (ret < 0)
+ return ret;
+
+ mutex_init(&gbpsy->supply_lock);
+
+ ret = gb_power_supply_register(gbpsy);
+ if (ret < 0)
+ return ret;
+
+ gbpsy->update_interval = update_interval_init;
+ INIT_DELAYED_WORK(&gbpsy->work, gb_power_supply_work);
+ schedule_delayed_work(&gbpsy->work, 0);
+
+ /* everything went fine, mark it for release code to know */
+ gbpsy->registered = true;
+
+ return 0;
+}
+
+static int gb_power_supplies_setup(struct gb_power_supplies *supplies)
+{
+ struct gb_connection *connection = supplies->connection;
+ int ret;
+ int i;
+
+ mutex_lock(&supplies->supplies_lock);
+
+ ret = gb_power_supplies_get_count(supplies);
+ if (ret < 0)
+ goto out;
+
+ supplies->supply = kzalloc(supplies->supplies_count *
+ sizeof(struct gb_power_supply),
+ GFP_KERNEL);
+
+ if (!supplies->supply) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ for (i = 0; i < supplies->supplies_count; i++) {
+ ret = gb_power_supply_config(supplies, i);
+ if (ret < 0) {
+ dev_err(&connection->bundle->dev,
+ "Fail to configure supplies devices\n");
+ goto out;
+ }
+ }
+out:
+ mutex_unlock(&supplies->supplies_lock);
+ return ret;
+}
+
+static int gb_power_supplies_register(struct gb_power_supplies *supplies)
+{
+ struct gb_connection *connection = supplies->connection;
+ int ret = 0;
+ int i;
+
+ mutex_lock(&supplies->supplies_lock);
+
+ for (i = 0; i < supplies->supplies_count; i++) {
+ ret = gb_power_supply_enable(&supplies->supply[i]);
+ if (ret < 0) {
+ dev_err(&connection->bundle->dev,
+ "Fail to enable supplies devices\n");
+ break;
+ }
+ }
+
+ mutex_unlock(&supplies->supplies_lock);
+ return ret;
+}
+
+static int gb_supplies_request_handler(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct gb_power_supplies *supplies = gb_connection_get_data(connection);
+ struct gb_power_supply *gbpsy;
+ struct gb_message *request;
+ struct gb_power_supply_event_request *payload;
+ u8 psy_id;
+ u8 event;
+ int ret = 0;
+
+ if (op->type != GB_POWER_SUPPLY_TYPE_EVENT) {
+ dev_err(&connection->bundle->dev,
+ "Unsupported unsolicited event: %u\n", op->type);
+ return -EINVAL;
+ }
+
+ request = op->request;
+
+ if (request->payload_size < sizeof(*payload)) {
+ dev_err(&connection->bundle->dev,
+ "Wrong event size received (%zu < %zu)\n",
+ request->payload_size, sizeof(*payload));
+ return -EINVAL;
+ }
+
+ payload = request->payload;
+ psy_id = payload->psy_id;
+ mutex_lock(&supplies->supplies_lock);
+ if (psy_id >= supplies->supplies_count ||
+ !supplies->supply[psy_id].registered) {
+ dev_err(&connection->bundle->dev,
+ "Event received for unconfigured power_supply id: %d\n",
+ psy_id);
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ event = payload->event;
+ /*
+ * we will only handle events after setup is done and before release is
+ * running. For that just check update_interval.
+ */
+ gbpsy = &supplies->supply[psy_id];
+ if (!gbpsy->update_interval) {
+ ret = -ESHUTDOWN;
+ goto out_unlock;
+ }
+
+ if (event & GB_POWER_SUPPLY_UPDATE) {
+ /*
+ * we need to make sure we invalidate cache, if not no new
+ * values for the properties will be fetch and the all propose
+ * of this event is missed
+ */
+ gbpsy->cache_invalid = 1;
+ gb_power_supply_status_update(gbpsy);
+ }
+
+out_unlock:
+ mutex_unlock(&supplies->supplies_lock);
+ return ret;
+}
+
+static int gb_power_supply_probe(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id)
+{
+ struct greybus_descriptor_cport *cport_desc;
+ struct gb_connection *connection;
+ struct gb_power_supplies *supplies;
+ int ret;
+
+ if (bundle->num_cports != 1)
+ return -ENODEV;
+
+ cport_desc = &bundle->cport_desc[0];
+ if (cport_desc->protocol_id != GREYBUS_PROTOCOL_POWER_SUPPLY)
+ return -ENODEV;
+
+ supplies = kzalloc(sizeof(*supplies), GFP_KERNEL);
+ if (!supplies)
+ return -ENOMEM;
+
+ connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
+ gb_supplies_request_handler);
+ if (IS_ERR(connection)) {
+ ret = PTR_ERR(connection);
+ goto out;
+ }
+
+ supplies->connection = connection;
+ gb_connection_set_data(connection, supplies);
+
+ mutex_init(&supplies->supplies_lock);
+
+ greybus_set_drvdata(bundle, supplies);
+
+ /* We aren't ready to receive an incoming request yet */
+ ret = gb_connection_enable_tx(connection);
+ if (ret)
+ goto error_connection_destroy;
+
+ ret = gb_power_supplies_setup(supplies);
+ if (ret < 0)
+ goto error_connection_disable;
+
+ /* We are ready to receive an incoming request now, enable RX as well */
+ ret = gb_connection_enable(connection);
+ if (ret)
+ goto error_connection_disable;
+
+ ret = gb_power_supplies_register(supplies);
+ if (ret < 0)
+ goto error_connection_disable;
+
+ gb_pm_runtime_put_autosuspend(bundle);
+ return 0;
+
+error_connection_disable:
+ gb_connection_disable(connection);
+error_connection_destroy:
+ gb_connection_destroy(connection);
+out:
+ _gb_power_supplies_release(supplies);
+ return ret;
+}
+
+static void gb_power_supply_disconnect(struct gb_bundle *bundle)
+{
+ struct gb_power_supplies *supplies = greybus_get_drvdata(bundle);
+
+ gb_connection_disable(supplies->connection);
+ gb_connection_destroy(supplies->connection);
+
+ _gb_power_supplies_release(supplies);
+}
+
+static const struct greybus_bundle_id gb_power_supply_id_table[] = {
+ { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_POWER_SUPPLY) },
+ { }
+};
+MODULE_DEVICE_TABLE(greybus, gb_power_supply_id_table);
+
+static struct greybus_driver gb_power_supply_driver = {
+ .name = "power_supply",
+ .probe = gb_power_supply_probe,
+ .disconnect = gb_power_supply_disconnect,
+ .id_table = gb_power_supply_id_table,
+};
+module_greybus_driver(gb_power_supply_driver);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/pwm.c b/drivers/staging/greybus/pwm.c
new file mode 100644
index 000000000000..c4bf3298ba07
--- /dev/null
+++ b/drivers/staging/greybus/pwm.c
@@ -0,0 +1,338 @@
+/*
+ * PWM Greybus driver.
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pwm.h>
+
+#include "greybus.h"
+#include "gbphy.h"
+
+struct gb_pwm_chip {
+ struct gb_connection *connection;
+ u8 pwm_max; /* max pwm number */
+
+ struct pwm_chip chip;
+ struct pwm_chip *pwm;
+};
+#define pwm_chip_to_gb_pwm_chip(chip) \
+ container_of(chip, struct gb_pwm_chip, chip)
+
+
+static int gb_pwm_count_operation(struct gb_pwm_chip *pwmc)
+{
+ struct gb_pwm_count_response response;
+ int ret;
+
+ ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_PWM_COUNT,
+ NULL, 0, &response, sizeof(response));
+ if (ret)
+ return ret;
+ pwmc->pwm_max = response.count;
+ return 0;
+}
+
+static int gb_pwm_activate_operation(struct gb_pwm_chip *pwmc,
+ u8 which)
+{
+ struct gb_pwm_activate_request request;
+ struct gbphy_device *gbphy_dev;
+ int ret;
+
+ if (which > pwmc->pwm_max)
+ return -EINVAL;
+
+ request.which = which;
+
+ gbphy_dev = to_gbphy_dev(pwmc->chip.dev);
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ return ret;
+
+ ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_ACTIVATE,
+ &request, sizeof(request), NULL, 0);
+
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+
+ return ret;
+}
+
+static int gb_pwm_deactivate_operation(struct gb_pwm_chip *pwmc,
+ u8 which)
+{
+ struct gb_pwm_deactivate_request request;
+ struct gbphy_device *gbphy_dev;
+ int ret;
+
+ if (which > pwmc->pwm_max)
+ return -EINVAL;
+
+ request.which = which;
+
+ gbphy_dev = to_gbphy_dev(pwmc->chip.dev);
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ return ret;
+
+ ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_DEACTIVATE,
+ &request, sizeof(request), NULL, 0);
+
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+
+ return ret;
+}
+
+static int gb_pwm_config_operation(struct gb_pwm_chip *pwmc,
+ u8 which, u32 duty, u32 period)
+{
+ struct gb_pwm_config_request request;
+ struct gbphy_device *gbphy_dev;
+ int ret;
+
+ if (which > pwmc->pwm_max)
+ return -EINVAL;
+
+ request.which = which;
+ request.duty = cpu_to_le32(duty);
+ request.period = cpu_to_le32(period);
+
+ gbphy_dev = to_gbphy_dev(pwmc->chip.dev);
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ return ret;
+
+ ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_CONFIG,
+ &request, sizeof(request), NULL, 0);
+
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+
+ return ret;
+}
+
+static int gb_pwm_set_polarity_operation(struct gb_pwm_chip *pwmc,
+ u8 which, u8 polarity)
+{
+ struct gb_pwm_polarity_request request;
+ struct gbphy_device *gbphy_dev;
+ int ret;
+
+ if (which > pwmc->pwm_max)
+ return -EINVAL;
+
+ request.which = which;
+ request.polarity = polarity;
+
+ gbphy_dev = to_gbphy_dev(pwmc->chip.dev);
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ return ret;
+
+ ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_POLARITY,
+ &request, sizeof(request), NULL, 0);
+
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+
+ return ret;
+}
+
+static int gb_pwm_enable_operation(struct gb_pwm_chip *pwmc,
+ u8 which)
+{
+ struct gb_pwm_enable_request request;
+ struct gbphy_device *gbphy_dev;
+ int ret;
+
+ if (which > pwmc->pwm_max)
+ return -EINVAL;
+
+ request.which = which;
+
+ gbphy_dev = to_gbphy_dev(pwmc->chip.dev);
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ return ret;
+
+ ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_ENABLE,
+ &request, sizeof(request), NULL, 0);
+ if (ret)
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+
+ return ret;
+}
+
+static int gb_pwm_disable_operation(struct gb_pwm_chip *pwmc,
+ u8 which)
+{
+ struct gb_pwm_disable_request request;
+ struct gbphy_device *gbphy_dev;
+ int ret;
+
+ if (which > pwmc->pwm_max)
+ return -EINVAL;
+
+ request.which = which;
+
+ ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_DISABLE,
+ &request, sizeof(request), NULL, 0);
+
+ gbphy_dev = to_gbphy_dev(pwmc->chip.dev);
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+
+ return ret;
+}
+
+static int gb_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
+
+ return gb_pwm_activate_operation(pwmc, pwm->hwpwm);
+};
+
+static void gb_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
+
+ if (pwm_is_enabled(pwm))
+ dev_warn(chip->dev, "freeing PWM device without disabling\n");
+
+ gb_pwm_deactivate_operation(pwmc, pwm->hwpwm);
+}
+
+static int gb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_ns, int period_ns)
+{
+ struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
+
+ return gb_pwm_config_operation(pwmc, pwm->hwpwm, duty_ns, period_ns);
+};
+
+static int gb_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
+ enum pwm_polarity polarity)
+{
+ struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
+
+ return gb_pwm_set_polarity_operation(pwmc, pwm->hwpwm, polarity);
+};
+
+static int gb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
+
+ return gb_pwm_enable_operation(pwmc, pwm->hwpwm);
+};
+
+static void gb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
+
+ gb_pwm_disable_operation(pwmc, pwm->hwpwm);
+};
+
+static const struct pwm_ops gb_pwm_ops = {
+ .request = gb_pwm_request,
+ .free = gb_pwm_free,
+ .config = gb_pwm_config,
+ .set_polarity = gb_pwm_set_polarity,
+ .enable = gb_pwm_enable,
+ .disable = gb_pwm_disable,
+ .owner = THIS_MODULE,
+};
+
+static int gb_pwm_probe(struct gbphy_device *gbphy_dev,
+ const struct gbphy_device_id *id)
+{
+ struct gb_connection *connection;
+ struct gb_pwm_chip *pwmc;
+ struct pwm_chip *pwm;
+ int ret;
+
+ pwmc = kzalloc(sizeof(*pwmc), GFP_KERNEL);
+ if (!pwmc)
+ return -ENOMEM;
+
+ connection = gb_connection_create(gbphy_dev->bundle,
+ le16_to_cpu(gbphy_dev->cport_desc->id),
+ NULL);
+ if (IS_ERR(connection)) {
+ ret = PTR_ERR(connection);
+ goto exit_pwmc_free;
+ }
+
+ pwmc->connection = connection;
+ gb_connection_set_data(connection, pwmc);
+ gb_gbphy_set_data(gbphy_dev, pwmc);
+
+ ret = gb_connection_enable(connection);
+ if (ret)
+ goto exit_connection_destroy;
+
+ /* Query number of pwms present */
+ ret = gb_pwm_count_operation(pwmc);
+ if (ret)
+ goto exit_connection_disable;
+
+ pwm = &pwmc->chip;
+
+ pwm->dev = &gbphy_dev->dev;
+ pwm->ops = &gb_pwm_ops;
+ pwm->base = -1; /* Allocate base dynamically */
+ pwm->npwm = pwmc->pwm_max + 1;
+ pwm->can_sleep = true; /* FIXME */
+
+ ret = pwmchip_add(pwm);
+ if (ret) {
+ dev_err(&gbphy_dev->dev,
+ "failed to register PWM: %d\n", ret);
+ goto exit_connection_disable;
+ }
+
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+ return 0;
+
+exit_connection_disable:
+ gb_connection_disable(connection);
+exit_connection_destroy:
+ gb_connection_destroy(connection);
+exit_pwmc_free:
+ kfree(pwmc);
+ return ret;
+}
+
+static void gb_pwm_remove(struct gbphy_device *gbphy_dev)
+{
+ struct gb_pwm_chip *pwmc = gb_gbphy_get_data(gbphy_dev);
+ struct gb_connection *connection = pwmc->connection;
+ int ret;
+
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ gbphy_runtime_get_noresume(gbphy_dev);
+
+ pwmchip_remove(&pwmc->chip);
+ gb_connection_disable(connection);
+ gb_connection_destroy(connection);
+ kfree(pwmc);
+}
+
+static const struct gbphy_device_id gb_pwm_id_table[] = {
+ { GBPHY_PROTOCOL(GREYBUS_PROTOCOL_PWM) },
+ { },
+};
+MODULE_DEVICE_TABLE(gbphy, gb_pwm_id_table);
+
+static struct gbphy_driver pwm_driver = {
+ .name = "pwm",
+ .probe = gb_pwm_probe,
+ .remove = gb_pwm_remove,
+ .id_table = gb_pwm_id_table,
+};
+
+module_gbphy_driver(pwm_driver);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/raw.c b/drivers/staging/greybus/raw.c
new file mode 100644
index 000000000000..729d25811568
--- /dev/null
+++ b/drivers/staging/greybus/raw.c
@@ -0,0 +1,381 @@
+/*
+ * Greybus driver for the Raw protocol
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright 2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sizes.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/idr.h>
+#include <linux/uaccess.h>
+
+#include "greybus.h"
+
+struct gb_raw {
+ struct gb_connection *connection;
+
+ struct list_head list;
+ int list_data;
+ struct mutex list_lock;
+ dev_t dev;
+ struct cdev cdev;
+ struct device *device;
+};
+
+struct raw_data {
+ struct list_head entry;
+ u32 len;
+ u8 data[0];
+};
+
+static struct class *raw_class;
+static int raw_major;
+static const struct file_operations raw_fops;
+static DEFINE_IDA(minors);
+
+/* Number of minor devices this driver supports */
+#define NUM_MINORS 256
+
+/* Maximum size of any one send data buffer we support */
+#define MAX_PACKET_SIZE (PAGE_SIZE * 2)
+
+/*
+ * Maximum size of the data in the receive buffer we allow before we start to
+ * drop messages on the floor
+ */
+#define MAX_DATA_SIZE (MAX_PACKET_SIZE * 8)
+
+/*
+ * Add the raw data message to the list of received messages.
+ */
+static int receive_data(struct gb_raw *raw, u32 len, u8 *data)
+{
+ struct raw_data *raw_data;
+ struct device *dev = &raw->connection->bundle->dev;
+ int retval = 0;
+
+ if (len > MAX_PACKET_SIZE) {
+ dev_err(dev, "Too big of a data packet, rejected\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&raw->list_lock);
+ if ((raw->list_data + len) > MAX_DATA_SIZE) {
+ dev_err(dev, "Too much data in receive buffer, now dropping packets\n");
+ retval = -EINVAL;
+ goto exit;
+ }
+
+ raw_data = kmalloc(sizeof(*raw_data) + len, GFP_KERNEL);
+ if (!raw_data) {
+ retval = -ENOMEM;
+ goto exit;
+ }
+
+ raw->list_data += len;
+ raw_data->len = len;
+ memcpy(&raw_data->data[0], data, len);
+
+ list_add_tail(&raw_data->entry, &raw->list);
+exit:
+ mutex_unlock(&raw->list_lock);
+ return retval;
+}
+
+static int gb_raw_request_handler(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct device *dev = &connection->bundle->dev;
+ struct gb_raw *raw = greybus_get_drvdata(connection->bundle);
+ struct gb_raw_send_request *receive;
+ u32 len;
+
+ if (op->type != GB_RAW_TYPE_SEND) {
+ dev_err(dev, "unknown request type 0x%02x\n", op->type);
+ return -EINVAL;
+ }
+
+ /* Verify size of payload */
+ if (op->request->payload_size < sizeof(*receive)) {
+ dev_err(dev, "raw receive request too small (%zu < %zu)\n",
+ op->request->payload_size, sizeof(*receive));
+ return -EINVAL;
+ }
+ receive = op->request->payload;
+ len = le32_to_cpu(receive->len);
+ if (len != (int)(op->request->payload_size - sizeof(__le32))) {
+ dev_err(dev, "raw receive request wrong size %d vs %d\n", len,
+ (int)(op->request->payload_size - sizeof(__le32)));
+ return -EINVAL;
+ }
+ if (len == 0) {
+ dev_err(dev, "raw receive request of 0 bytes?\n");
+ return -EINVAL;
+ }
+
+ return receive_data(raw, len, receive->data);
+}
+
+static int gb_raw_send(struct gb_raw *raw, u32 len, const char __user *data)
+{
+ struct gb_connection *connection = raw->connection;
+ struct gb_raw_send_request *request;
+ int retval;
+
+ request = kmalloc(len + sizeof(*request), GFP_KERNEL);
+ if (!request)
+ return -ENOMEM;
+
+ if (copy_from_user(&request->data[0], data, len)) {
+ kfree(request);
+ return -EFAULT;
+ }
+
+ request->len = cpu_to_le32(len);
+
+ retval = gb_operation_sync(connection, GB_RAW_TYPE_SEND,
+ request, len + sizeof(*request),
+ NULL, 0);
+
+ kfree(request);
+ return retval;
+}
+
+static int gb_raw_probe(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id)
+{
+ struct greybus_descriptor_cport *cport_desc;
+ struct gb_connection *connection;
+ struct gb_raw *raw;
+ int retval;
+ int minor;
+
+ if (bundle->num_cports != 1)
+ return -ENODEV;
+
+ cport_desc = &bundle->cport_desc[0];
+ if (cport_desc->protocol_id != GREYBUS_PROTOCOL_RAW)
+ return -ENODEV;
+
+ raw = kzalloc(sizeof(*raw), GFP_KERNEL);
+ if (!raw)
+ return -ENOMEM;
+
+ connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
+ gb_raw_request_handler);
+ if (IS_ERR(connection)) {
+ retval = PTR_ERR(connection);
+ goto error_free;
+ }
+
+ INIT_LIST_HEAD(&raw->list);
+ mutex_init(&raw->list_lock);
+
+ raw->connection = connection;
+ greybus_set_drvdata(bundle, raw);
+
+ minor = ida_simple_get(&minors, 0, 0, GFP_KERNEL);
+ if (minor < 0) {
+ retval = minor;
+ goto error_connection_destroy;
+ }
+
+ raw->dev = MKDEV(raw_major, minor);
+ cdev_init(&raw->cdev, &raw_fops);
+
+ retval = gb_connection_enable(connection);
+ if (retval)
+ goto error_remove_ida;
+
+ retval = cdev_add(&raw->cdev, raw->dev, 1);
+ if (retval)
+ goto error_connection_disable;
+
+ raw->device = device_create(raw_class, &connection->bundle->dev,
+ raw->dev, raw, "gb!raw%d", minor);
+ if (IS_ERR(raw->device)) {
+ retval = PTR_ERR(raw->device);
+ goto error_del_cdev;
+ }
+
+ return 0;
+
+error_del_cdev:
+ cdev_del(&raw->cdev);
+
+error_connection_disable:
+ gb_connection_disable(connection);
+
+error_remove_ida:
+ ida_simple_remove(&minors, minor);
+
+error_connection_destroy:
+ gb_connection_destroy(connection);
+
+error_free:
+ kfree(raw);
+ return retval;
+}
+
+static void gb_raw_disconnect(struct gb_bundle *bundle)
+{
+ struct gb_raw *raw = greybus_get_drvdata(bundle);
+ struct gb_connection *connection = raw->connection;
+ struct raw_data *raw_data;
+ struct raw_data *temp;
+
+ // FIXME - handle removing a connection when the char device node is open.
+ device_destroy(raw_class, raw->dev);
+ cdev_del(&raw->cdev);
+ gb_connection_disable(connection);
+ ida_simple_remove(&minors, MINOR(raw->dev));
+ gb_connection_destroy(connection);
+
+ mutex_lock(&raw->list_lock);
+ list_for_each_entry_safe(raw_data, temp, &raw->list, entry) {
+ list_del(&raw_data->entry);
+ kfree(raw_data);
+ }
+ mutex_unlock(&raw->list_lock);
+
+ kfree(raw);
+}
+
+/*
+ * Character device node interfaces.
+ *
+ * Note, we are using read/write to only allow a single read/write per message.
+ * This means for read(), you have to provide a big enough buffer for the full
+ * message to be copied into. If the buffer isn't big enough, the read() will
+ * fail with -ENOSPC.
+ */
+
+static int raw_open(struct inode *inode, struct file *file)
+{
+ struct cdev *cdev = inode->i_cdev;
+ struct gb_raw *raw = container_of(cdev, struct gb_raw, cdev);
+
+ file->private_data = raw;
+ return 0;
+}
+
+static ssize_t raw_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct gb_raw *raw = file->private_data;
+ int retval;
+
+ if (!count)
+ return 0;
+
+ if (count > MAX_PACKET_SIZE)
+ return -E2BIG;
+
+ retval = gb_raw_send(raw, count, buf);
+ if (retval)
+ return retval;
+
+ return count;
+}
+
+static ssize_t raw_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ struct gb_raw *raw = file->private_data;
+ int retval = 0;
+ struct raw_data *raw_data;
+
+ mutex_lock(&raw->list_lock);
+ if (list_empty(&raw->list))
+ goto exit;
+
+ raw_data = list_first_entry(&raw->list, struct raw_data, entry);
+ if (raw_data->len > count) {
+ retval = -ENOSPC;
+ goto exit;
+ }
+
+ if (copy_to_user(buf, &raw_data->data[0], raw_data->len)) {
+ retval = -EFAULT;
+ goto exit;
+ }
+
+ list_del(&raw_data->entry);
+ raw->list_data -= raw_data->len;
+ retval = raw_data->len;
+ kfree(raw_data);
+
+exit:
+ mutex_unlock(&raw->list_lock);
+ return retval;
+}
+
+static const struct file_operations raw_fops = {
+ .owner = THIS_MODULE,
+ .write = raw_write,
+ .read = raw_read,
+ .open = raw_open,
+ .llseek = noop_llseek,
+};
+
+static const struct greybus_bundle_id gb_raw_id_table[] = {
+ { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_RAW) },
+ { }
+};
+MODULE_DEVICE_TABLE(greybus, gb_raw_id_table);
+
+static struct greybus_driver gb_raw_driver = {
+ .name = "raw",
+ .probe = gb_raw_probe,
+ .disconnect = gb_raw_disconnect,
+ .id_table = gb_raw_id_table,
+};
+
+static int raw_init(void)
+{
+ dev_t dev;
+ int retval;
+
+ raw_class = class_create(THIS_MODULE, "gb_raw");
+ if (IS_ERR(raw_class)) {
+ retval = PTR_ERR(raw_class);
+ goto error_class;
+ }
+
+ retval = alloc_chrdev_region(&dev, 0, NUM_MINORS, "gb_raw");
+ if (retval < 0)
+ goto error_chrdev;
+
+ raw_major = MAJOR(dev);
+
+ retval = greybus_register(&gb_raw_driver);
+ if (retval)
+ goto error_gb;
+
+ return 0;
+
+error_gb:
+ unregister_chrdev_region(dev, NUM_MINORS);
+error_chrdev:
+ class_destroy(raw_class);
+error_class:
+ return retval;
+}
+module_init(raw_init);
+
+static void __exit raw_exit(void)
+{
+ greybus_deregister(&gb_raw_driver);
+ unregister_chrdev_region(MKDEV(raw_major, 0), NUM_MINORS);
+ class_destroy(raw_class);
+ ida_destroy(&minors);
+}
+module_exit(raw_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/sdio.c b/drivers/staging/greybus/sdio.c
new file mode 100644
index 000000000000..5649ef1e379d
--- /dev/null
+++ b/drivers/staging/greybus/sdio.c
@@ -0,0 +1,884 @@
+/*
+ * SD/MMC Greybus driver.
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mmc/core.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/scatterlist.h>
+#include <linux/workqueue.h>
+
+#include "greybus.h"
+#include "gbphy.h"
+
+struct gb_sdio_host {
+ struct gb_connection *connection;
+ struct gbphy_device *gbphy_dev;
+ struct mmc_host *mmc;
+ struct mmc_request *mrq;
+ struct mutex lock; /* lock for this host */
+ size_t data_max;
+ spinlock_t xfer; /* lock to cancel ongoing transfer */
+ bool xfer_stop;
+ struct workqueue_struct *mrq_workqueue;
+ struct work_struct mrqwork;
+ u8 queued_events;
+ bool removed;
+ bool card_present;
+ bool read_only;
+};
+
+
+#define GB_SDIO_RSP_R1_R5_R6_R7 (GB_SDIO_RSP_PRESENT | GB_SDIO_RSP_CRC | \
+ GB_SDIO_RSP_OPCODE)
+#define GB_SDIO_RSP_R3_R4 (GB_SDIO_RSP_PRESENT)
+#define GB_SDIO_RSP_R2 (GB_SDIO_RSP_PRESENT | GB_SDIO_RSP_CRC | \
+ GB_SDIO_RSP_136)
+#define GB_SDIO_RSP_R1B (GB_SDIO_RSP_PRESENT | GB_SDIO_RSP_CRC | \
+ GB_SDIO_RSP_OPCODE | GB_SDIO_RSP_BUSY)
+
+/* kernel vdd starts at 0x80 and we need to translate to greybus ones 0x01 */
+#define GB_SDIO_VDD_SHIFT 8
+
+#ifndef MMC_CAP2_CORE_RUNTIME_PM
+#define MMC_CAP2_CORE_RUNTIME_PM 0
+#endif
+
+static inline bool single_op(struct mmc_command *cmd)
+{
+ uint32_t opcode = cmd->opcode;
+
+ return opcode == MMC_WRITE_BLOCK ||
+ opcode == MMC_READ_SINGLE_BLOCK;
+}
+
+static void _gb_sdio_set_host_caps(struct gb_sdio_host *host, u32 r)
+{
+ u32 caps = 0;
+ u32 caps2 = 0;
+
+ caps = ((r & GB_SDIO_CAP_NONREMOVABLE) ? MMC_CAP_NONREMOVABLE : 0) |
+ ((r & GB_SDIO_CAP_4_BIT_DATA) ? MMC_CAP_4_BIT_DATA : 0) |
+ ((r & GB_SDIO_CAP_8_BIT_DATA) ? MMC_CAP_8_BIT_DATA : 0) |
+ ((r & GB_SDIO_CAP_MMC_HS) ? MMC_CAP_MMC_HIGHSPEED : 0) |
+ ((r & GB_SDIO_CAP_SD_HS) ? MMC_CAP_SD_HIGHSPEED : 0) |
+ ((r & GB_SDIO_CAP_ERASE) ? MMC_CAP_ERASE : 0) |
+ ((r & GB_SDIO_CAP_1_2V_DDR) ? MMC_CAP_1_2V_DDR : 0) |
+ ((r & GB_SDIO_CAP_1_8V_DDR) ? MMC_CAP_1_8V_DDR : 0) |
+ ((r & GB_SDIO_CAP_POWER_OFF_CARD) ? MMC_CAP_POWER_OFF_CARD : 0) |
+ ((r & GB_SDIO_CAP_UHS_SDR12) ? MMC_CAP_UHS_SDR12 : 0) |
+ ((r & GB_SDIO_CAP_UHS_SDR25) ? MMC_CAP_UHS_SDR25 : 0) |
+ ((r & GB_SDIO_CAP_UHS_SDR50) ? MMC_CAP_UHS_SDR50 : 0) |
+ ((r & GB_SDIO_CAP_UHS_SDR104) ? MMC_CAP_UHS_SDR104 : 0) |
+ ((r & GB_SDIO_CAP_UHS_DDR50) ? MMC_CAP_UHS_DDR50 : 0) |
+ ((r & GB_SDIO_CAP_DRIVER_TYPE_A) ? MMC_CAP_DRIVER_TYPE_A : 0) |
+ ((r & GB_SDIO_CAP_DRIVER_TYPE_C) ? MMC_CAP_DRIVER_TYPE_C : 0) |
+ ((r & GB_SDIO_CAP_DRIVER_TYPE_D) ? MMC_CAP_DRIVER_TYPE_D : 0);
+
+ caps2 = ((r & GB_SDIO_CAP_HS200_1_2V) ? MMC_CAP2_HS200_1_2V_SDR : 0) |
+ ((r & GB_SDIO_CAP_HS400_1_2V) ? MMC_CAP2_HS400_1_2V : 0) |
+ ((r & GB_SDIO_CAP_HS400_1_8V) ? MMC_CAP2_HS400_1_8V : 0) |
+ ((r & GB_SDIO_CAP_HS200_1_8V) ? MMC_CAP2_HS200_1_8V_SDR : 0);
+
+ host->mmc->caps = caps;
+ host->mmc->caps2 = caps2 | MMC_CAP2_CORE_RUNTIME_PM;
+
+ if (caps & MMC_CAP_NONREMOVABLE)
+ host->card_present = true;
+}
+
+static u32 _gb_sdio_get_host_ocr(u32 ocr)
+{
+ return (((ocr & GB_SDIO_VDD_165_195) ? MMC_VDD_165_195 : 0) |
+ ((ocr & GB_SDIO_VDD_20_21) ? MMC_VDD_20_21 : 0) |
+ ((ocr & GB_SDIO_VDD_21_22) ? MMC_VDD_21_22 : 0) |
+ ((ocr & GB_SDIO_VDD_22_23) ? MMC_VDD_22_23 : 0) |
+ ((ocr & GB_SDIO_VDD_23_24) ? MMC_VDD_23_24 : 0) |
+ ((ocr & GB_SDIO_VDD_24_25) ? MMC_VDD_24_25 : 0) |
+ ((ocr & GB_SDIO_VDD_25_26) ? MMC_VDD_25_26 : 0) |
+ ((ocr & GB_SDIO_VDD_26_27) ? MMC_VDD_26_27 : 0) |
+ ((ocr & GB_SDIO_VDD_27_28) ? MMC_VDD_27_28 : 0) |
+ ((ocr & GB_SDIO_VDD_28_29) ? MMC_VDD_28_29 : 0) |
+ ((ocr & GB_SDIO_VDD_29_30) ? MMC_VDD_29_30 : 0) |
+ ((ocr & GB_SDIO_VDD_30_31) ? MMC_VDD_30_31 : 0) |
+ ((ocr & GB_SDIO_VDD_31_32) ? MMC_VDD_31_32 : 0) |
+ ((ocr & GB_SDIO_VDD_32_33) ? MMC_VDD_32_33 : 0) |
+ ((ocr & GB_SDIO_VDD_33_34) ? MMC_VDD_33_34 : 0) |
+ ((ocr & GB_SDIO_VDD_34_35) ? MMC_VDD_34_35 : 0) |
+ ((ocr & GB_SDIO_VDD_35_36) ? MMC_VDD_35_36 : 0)
+ );
+}
+
+static int gb_sdio_get_caps(struct gb_sdio_host *host)
+{
+ struct gb_sdio_get_caps_response response;
+ struct mmc_host *mmc = host->mmc;
+ u16 data_max;
+ u32 blksz;
+ u32 ocr;
+ u32 r;
+ int ret;
+
+ ret = gb_operation_sync(host->connection, GB_SDIO_TYPE_GET_CAPABILITIES,
+ NULL, 0, &response, sizeof(response));
+ if (ret < 0)
+ return ret;
+ r = le32_to_cpu(response.caps);
+
+ _gb_sdio_set_host_caps(host, r);
+
+ /* get the max block size that could fit our payload */
+ data_max = gb_operation_get_payload_size_max(host->connection);
+ data_max = min(data_max - sizeof(struct gb_sdio_transfer_request),
+ data_max - sizeof(struct gb_sdio_transfer_response));
+
+ blksz = min_t(u16, le16_to_cpu(response.max_blk_size), data_max);
+ blksz = max_t(u32, 512, blksz);
+
+ mmc->max_blk_size = rounddown_pow_of_two(blksz);
+ mmc->max_blk_count = le16_to_cpu(response.max_blk_count);
+ host->data_max = data_max;
+
+ /* get ocr supported values */
+ ocr = _gb_sdio_get_host_ocr(le32_to_cpu(response.ocr));
+ mmc->ocr_avail = ocr;
+ mmc->ocr_avail_sdio = mmc->ocr_avail;
+ mmc->ocr_avail_sd = mmc->ocr_avail;
+ mmc->ocr_avail_mmc = mmc->ocr_avail;
+
+ /* get frequency range values */
+ mmc->f_min = le32_to_cpu(response.f_min);
+ mmc->f_max = le32_to_cpu(response.f_max);
+
+ return 0;
+}
+
+static void _gb_queue_event(struct gb_sdio_host *host, u8 event)
+{
+ if (event & GB_SDIO_CARD_INSERTED)
+ host->queued_events &= ~GB_SDIO_CARD_REMOVED;
+ else if (event & GB_SDIO_CARD_REMOVED)
+ host->queued_events &= ~GB_SDIO_CARD_INSERTED;
+
+ host->queued_events |= event;
+}
+
+static int _gb_sdio_process_events(struct gb_sdio_host *host, u8 event)
+{
+ u8 state_changed = 0;
+
+ if (event & GB_SDIO_CARD_INSERTED) {
+ if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
+ return 0;
+ if (host->card_present)
+ return 0;
+ host->card_present = true;
+ state_changed = 1;
+ }
+
+ if (event & GB_SDIO_CARD_REMOVED) {
+ if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
+ return 0;
+ if (!(host->card_present))
+ return 0;
+ host->card_present = false;
+ state_changed = 1;
+ }
+
+ if (event & GB_SDIO_WP) {
+ host->read_only = true;
+ }
+
+ if (state_changed) {
+ dev_info(mmc_dev(host->mmc), "card %s now event\n",
+ (host->card_present ? "inserted" : "removed"));
+ mmc_detect_change(host->mmc, 0);
+ }
+
+ return 0;
+}
+
+static int gb_sdio_request_handler(struct gb_operation *op)
+{
+ struct gb_sdio_host *host = gb_connection_get_data(op->connection);
+ struct gb_message *request;
+ struct gb_sdio_event_request *payload;
+ u8 type = op->type;
+ int ret = 0;
+ u8 event;
+
+ if (type != GB_SDIO_TYPE_EVENT) {
+ dev_err(mmc_dev(host->mmc),
+ "unsupported unsolicited event: %u\n", type);
+ return -EINVAL;
+ }
+
+ request = op->request;
+
+ if (request->payload_size < sizeof(*payload)) {
+ dev_err(mmc_dev(host->mmc), "wrong event size received (%zu < %zu)\n",
+ request->payload_size, sizeof(*payload));
+ return -EINVAL;
+ }
+
+ payload = request->payload;
+ event = payload->event;
+
+ if (host->removed)
+ _gb_queue_event(host, event);
+ else
+ ret = _gb_sdio_process_events(host, event);
+
+ return ret;
+}
+
+static int gb_sdio_set_ios(struct gb_sdio_host *host,
+ struct gb_sdio_set_ios_request *request)
+{
+ int ret;
+
+ ret = gbphy_runtime_get_sync(host->gbphy_dev);
+ if (ret)
+ return ret;
+
+ ret = gb_operation_sync(host->connection, GB_SDIO_TYPE_SET_IOS, request,
+ sizeof(*request), NULL, 0);
+
+ gbphy_runtime_put_autosuspend(host->gbphy_dev);
+
+ return ret;
+}
+
+static int _gb_sdio_send(struct gb_sdio_host *host, struct mmc_data *data,
+ size_t len, u16 nblocks, off_t skip)
+{
+ struct gb_sdio_transfer_request *request;
+ struct gb_sdio_transfer_response *response;
+ struct gb_operation *operation;
+ struct scatterlist *sg = data->sg;
+ unsigned int sg_len = data->sg_len;
+ size_t copied;
+ u16 send_blksz;
+ u16 send_blocks;
+ int ret;
+
+ WARN_ON(len > host->data_max);
+
+ operation = gb_operation_create(host->connection, GB_SDIO_TYPE_TRANSFER,
+ len + sizeof(*request),
+ sizeof(*response), GFP_KERNEL);
+ if (!operation)
+ return -ENOMEM;
+
+ request = operation->request->payload;
+ request->data_flags = (data->flags >> 8);
+ request->data_blocks = cpu_to_le16(nblocks);
+ request->data_blksz = cpu_to_le16(data->blksz);
+
+ copied = sg_pcopy_to_buffer(sg, sg_len, &request->data[0], len, skip);
+
+ if (copied != len) {
+ ret = -EINVAL;
+ goto err_put_operation;
+ }
+
+ ret = gb_operation_request_send_sync(operation);
+ if (ret < 0)
+ goto err_put_operation;
+
+ response = operation->response->payload;
+
+ send_blocks = le16_to_cpu(response->data_blocks);
+ send_blksz = le16_to_cpu(response->data_blksz);
+
+ if (len != send_blksz * send_blocks) {
+ dev_err(mmc_dev(host->mmc), "send: size received: %zu != %d\n",
+ len, send_blksz * send_blocks);
+ ret = -EINVAL;
+ }
+
+err_put_operation:
+ gb_operation_put(operation);
+
+ return ret;
+}
+
+static int _gb_sdio_recv(struct gb_sdio_host *host, struct mmc_data *data,
+ size_t len, u16 nblocks, off_t skip)
+{
+ struct gb_sdio_transfer_request *request;
+ struct gb_sdio_transfer_response *response;
+ struct gb_operation *operation;
+ struct scatterlist *sg = data->sg;
+ unsigned int sg_len = data->sg_len;
+ size_t copied;
+ u16 recv_blksz;
+ u16 recv_blocks;
+ int ret;
+
+ WARN_ON(len > host->data_max);
+
+ operation = gb_operation_create(host->connection, GB_SDIO_TYPE_TRANSFER,
+ sizeof(*request),
+ len + sizeof(*response), GFP_KERNEL);
+ if (!operation)
+ return -ENOMEM;
+
+ request = operation->request->payload;
+ request->data_flags = (data->flags >> 8);
+ request->data_blocks = cpu_to_le16(nblocks);
+ request->data_blksz = cpu_to_le16(data->blksz);
+
+ ret = gb_operation_request_send_sync(operation);
+ if (ret < 0)
+ goto err_put_operation;
+
+ response = operation->response->payload;
+ recv_blocks = le16_to_cpu(response->data_blocks);
+ recv_blksz = le16_to_cpu(response->data_blksz);
+
+ if (len != recv_blksz * recv_blocks) {
+ dev_err(mmc_dev(host->mmc), "recv: size received: %d != %zu\n",
+ recv_blksz * recv_blocks, len);
+ ret = -EINVAL;
+ goto err_put_operation;
+ }
+
+ copied = sg_pcopy_from_buffer(sg, sg_len, &response->data[0], len,
+ skip);
+ if (copied != len)
+ ret = -EINVAL;
+
+err_put_operation:
+ gb_operation_put(operation);
+
+ return ret;
+}
+
+static int gb_sdio_transfer(struct gb_sdio_host *host, struct mmc_data *data)
+{
+ size_t left, len;
+ off_t skip = 0;
+ int ret = 0;
+ u16 nblocks;
+
+ if (single_op(data->mrq->cmd) && data->blocks > 1) {
+ ret = -ETIMEDOUT;
+ goto out;
+ }
+
+ left = data->blksz * data->blocks;
+
+ while (left) {
+ /* check is a stop transmission is pending */
+ spin_lock(&host->xfer);
+ if (host->xfer_stop) {
+ host->xfer_stop = false;
+ spin_unlock(&host->xfer);
+ ret = -EINTR;
+ goto out;
+ }
+ spin_unlock(&host->xfer);
+ len = min(left, host->data_max);
+ nblocks = len / data->blksz;
+ len = nblocks * data->blksz;
+
+ if (data->flags & MMC_DATA_READ) {
+ ret = _gb_sdio_recv(host, data, len, nblocks, skip);
+ if (ret < 0)
+ goto out;
+ } else {
+ ret = _gb_sdio_send(host, data, len, nblocks, skip);
+ if (ret < 0)
+ goto out;
+ }
+ data->bytes_xfered += len;
+ left -= len;
+ skip += len;
+ }
+
+out:
+ data->error = ret;
+ return ret;
+}
+
+static int gb_sdio_command(struct gb_sdio_host *host, struct mmc_command *cmd)
+{
+ struct gb_sdio_command_request request = {0};
+ struct gb_sdio_command_response response;
+ struct mmc_data *data = host->mrq->data;
+ u8 cmd_flags;
+ u8 cmd_type;
+ int i;
+ int ret;
+
+ switch (mmc_resp_type(cmd)) {
+ case MMC_RSP_NONE:
+ cmd_flags = GB_SDIO_RSP_NONE;
+ break;
+ case MMC_RSP_R1:
+ cmd_flags = GB_SDIO_RSP_R1_R5_R6_R7;
+ break;
+ case MMC_RSP_R1B:
+ cmd_flags = GB_SDIO_RSP_R1B;
+ break;
+ case MMC_RSP_R2:
+ cmd_flags = GB_SDIO_RSP_R2;
+ break;
+ case MMC_RSP_R3:
+ cmd_flags = GB_SDIO_RSP_R3_R4;
+ break;
+ default:
+ dev_err(mmc_dev(host->mmc), "cmd flag invalid 0x%04x\n",
+ mmc_resp_type(cmd));
+ ret = -EINVAL;
+ goto out;
+ }
+
+ switch (mmc_cmd_type(cmd)) {
+ case MMC_CMD_BC:
+ cmd_type = GB_SDIO_CMD_BC;
+ break;
+ case MMC_CMD_BCR:
+ cmd_type = GB_SDIO_CMD_BCR;
+ break;
+ case MMC_CMD_AC:
+ cmd_type = GB_SDIO_CMD_AC;
+ break;
+ case MMC_CMD_ADTC:
+ cmd_type = GB_SDIO_CMD_ADTC;
+ break;
+ default:
+ dev_err(mmc_dev(host->mmc), "cmd type invalid 0x%04x\n",
+ mmc_cmd_type(cmd));
+ ret = -EINVAL;
+ goto out;
+ }
+
+ request.cmd = cmd->opcode;
+ request.cmd_flags = cmd_flags;
+ request.cmd_type = cmd_type;
+ request.cmd_arg = cpu_to_le32(cmd->arg);
+ /* some controllers need to know at command time data details */
+ if (data) {
+ request.data_blocks = cpu_to_le16(data->blocks);
+ request.data_blksz = cpu_to_le16(data->blksz);
+ }
+
+ ret = gb_operation_sync(host->connection, GB_SDIO_TYPE_COMMAND,
+ &request, sizeof(request), &response,
+ sizeof(response));
+ if (ret < 0)
+ goto out;
+
+ /* no response expected */
+ if (cmd_flags == GB_SDIO_RSP_NONE)
+ goto out;
+
+ /* long response expected */
+ if (cmd_flags & GB_SDIO_RSP_R2)
+ for (i = 0; i < 4; i++)
+ cmd->resp[i] = le32_to_cpu(response.resp[i]);
+ else
+ cmd->resp[0] = le32_to_cpu(response.resp[0]);
+
+out:
+ cmd->error = ret;
+ return ret;
+}
+
+static void gb_sdio_mrq_work(struct work_struct *work)
+{
+ struct gb_sdio_host *host;
+ struct mmc_request *mrq;
+ int ret;
+
+ host = container_of(work, struct gb_sdio_host, mrqwork);
+
+ ret = gbphy_runtime_get_sync(host->gbphy_dev);
+ if (ret)
+ return;
+
+ mutex_lock(&host->lock);
+ mrq = host->mrq;
+ if (!mrq) {
+ mutex_unlock(&host->lock);
+ gbphy_runtime_put_autosuspend(host->gbphy_dev);
+ dev_err(mmc_dev(host->mmc), "mmc request is NULL");
+ return;
+ }
+
+ if (host->removed) {
+ mrq->cmd->error = -ESHUTDOWN;
+ goto done;
+ }
+
+ if (mrq->sbc) {
+ ret = gb_sdio_command(host, mrq->sbc);
+ if (ret < 0)
+ goto done;
+ }
+
+ ret = gb_sdio_command(host, mrq->cmd);
+ if (ret < 0)
+ goto done;
+
+ if (mrq->data) {
+ ret = gb_sdio_transfer(host, mrq->data);
+ if (ret < 0)
+ goto done;
+ }
+
+ if (mrq->stop) {
+ ret = gb_sdio_command(host, mrq->stop);
+ if (ret < 0)
+ goto done;
+ }
+
+done:
+ host->mrq = NULL;
+ mutex_unlock(&host->lock);
+ mmc_request_done(host->mmc, mrq);
+ gbphy_runtime_put_autosuspend(host->gbphy_dev);
+}
+
+static void gb_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ struct gb_sdio_host *host = mmc_priv(mmc);
+ struct mmc_command *cmd = mrq->cmd;
+
+ /* Check if it is a cancel to ongoing transfer */
+ if (cmd->opcode == MMC_STOP_TRANSMISSION) {
+ spin_lock(&host->xfer);
+ host->xfer_stop = true;
+ spin_unlock(&host->xfer);
+ }
+
+ mutex_lock(&host->lock);
+
+ WARN_ON(host->mrq);
+ host->mrq = mrq;
+
+ if (host->removed) {
+ mrq->cmd->error = -ESHUTDOWN;
+ goto out;
+ }
+ if (!host->card_present) {
+ mrq->cmd->error = -ENOMEDIUM;
+ goto out;
+ }
+
+ queue_work(host->mrq_workqueue, &host->mrqwork);
+
+ mutex_unlock(&host->lock);
+ return;
+
+out:
+ host->mrq = NULL;
+ mutex_unlock(&host->lock);
+ mmc_request_done(mmc, mrq);
+}
+
+static void gb_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct gb_sdio_host *host = mmc_priv(mmc);
+ struct gb_sdio_set_ios_request request;
+ int ret;
+ u8 power_mode;
+ u8 bus_width;
+ u8 timing;
+ u8 signal_voltage;
+ u8 drv_type;
+ u32 vdd = 0;
+
+ mutex_lock(&host->lock);
+ request.clock = cpu_to_le32(ios->clock);
+
+ if (ios->vdd)
+ vdd = 1 << (ios->vdd - GB_SDIO_VDD_SHIFT);
+ request.vdd = cpu_to_le32(vdd);
+
+ request.bus_mode = (ios->bus_mode == MMC_BUSMODE_OPENDRAIN ?
+ GB_SDIO_BUSMODE_OPENDRAIN :
+ GB_SDIO_BUSMODE_PUSHPULL);
+
+ switch (ios->power_mode) {
+ case MMC_POWER_OFF:
+ default:
+ power_mode = GB_SDIO_POWER_OFF;
+ break;
+ case MMC_POWER_UP:
+ power_mode = GB_SDIO_POWER_UP;
+ break;
+ case MMC_POWER_ON:
+ power_mode = GB_SDIO_POWER_ON;
+ break;
+ case MMC_POWER_UNDEFINED:
+ power_mode = GB_SDIO_POWER_UNDEFINED;
+ break;
+ }
+ request.power_mode = power_mode;
+
+ switch (ios->bus_width) {
+ case MMC_BUS_WIDTH_1:
+ bus_width = GB_SDIO_BUS_WIDTH_1;
+ break;
+ case MMC_BUS_WIDTH_4:
+ default:
+ bus_width = GB_SDIO_BUS_WIDTH_4;
+ break;
+ case MMC_BUS_WIDTH_8:
+ bus_width = GB_SDIO_BUS_WIDTH_8;
+ break;
+ }
+ request.bus_width = bus_width;
+
+ switch (ios->timing) {
+ case MMC_TIMING_LEGACY:
+ default:
+ timing = GB_SDIO_TIMING_LEGACY;
+ break;
+ case MMC_TIMING_MMC_HS:
+ timing = GB_SDIO_TIMING_MMC_HS;
+ break;
+ case MMC_TIMING_SD_HS:
+ timing = GB_SDIO_TIMING_SD_HS;
+ break;
+ case MMC_TIMING_UHS_SDR12:
+ timing = GB_SDIO_TIMING_UHS_SDR12;
+ break;
+ case MMC_TIMING_UHS_SDR25:
+ timing = GB_SDIO_TIMING_UHS_SDR25;
+ break;
+ case MMC_TIMING_UHS_SDR50:
+ timing = GB_SDIO_TIMING_UHS_SDR50;
+ break;
+ case MMC_TIMING_UHS_SDR104:
+ timing = GB_SDIO_TIMING_UHS_SDR104;
+ break;
+ case MMC_TIMING_UHS_DDR50:
+ timing = GB_SDIO_TIMING_UHS_DDR50;
+ break;
+ case MMC_TIMING_MMC_DDR52:
+ timing = GB_SDIO_TIMING_MMC_DDR52;
+ break;
+ case MMC_TIMING_MMC_HS200:
+ timing = GB_SDIO_TIMING_MMC_HS200;
+ break;
+ case MMC_TIMING_MMC_HS400:
+ timing = GB_SDIO_TIMING_MMC_HS400;
+ break;
+ }
+ request.timing = timing;
+
+ switch (ios->signal_voltage) {
+ case MMC_SIGNAL_VOLTAGE_330:
+ signal_voltage = GB_SDIO_SIGNAL_VOLTAGE_330;
+ break;
+ case MMC_SIGNAL_VOLTAGE_180:
+ default:
+ signal_voltage = GB_SDIO_SIGNAL_VOLTAGE_180;
+ break;
+ case MMC_SIGNAL_VOLTAGE_120:
+ signal_voltage = GB_SDIO_SIGNAL_VOLTAGE_120;
+ break;
+ }
+ request.signal_voltage = signal_voltage;
+
+ switch (ios->drv_type) {
+ case MMC_SET_DRIVER_TYPE_A:
+ drv_type = GB_SDIO_SET_DRIVER_TYPE_A;
+ break;
+ case MMC_SET_DRIVER_TYPE_C:
+ drv_type = GB_SDIO_SET_DRIVER_TYPE_C;
+ break;
+ case MMC_SET_DRIVER_TYPE_D:
+ drv_type = GB_SDIO_SET_DRIVER_TYPE_D;
+ break;
+ case MMC_SET_DRIVER_TYPE_B:
+ default:
+ drv_type = GB_SDIO_SET_DRIVER_TYPE_B;
+ break;
+ }
+ request.drv_type = drv_type;
+
+ ret = gb_sdio_set_ios(host, &request);
+ if (ret < 0)
+ goto out;
+
+ memcpy(&mmc->ios, ios, sizeof(mmc->ios));
+
+out:
+ mutex_unlock(&host->lock);
+}
+
+static int gb_mmc_get_ro(struct mmc_host *mmc)
+{
+ struct gb_sdio_host *host = mmc_priv(mmc);
+
+ mutex_lock(&host->lock);
+ if (host->removed) {
+ mutex_unlock(&host->lock);
+ return -ESHUTDOWN;
+ }
+ mutex_unlock(&host->lock);
+
+ return host->read_only;
+}
+
+static int gb_mmc_get_cd(struct mmc_host *mmc)
+{
+ struct gb_sdio_host *host = mmc_priv(mmc);
+
+ mutex_lock(&host->lock);
+ if (host->removed) {
+ mutex_unlock(&host->lock);
+ return -ESHUTDOWN;
+ }
+ mutex_unlock(&host->lock);
+
+ return host->card_present;
+}
+
+static int gb_mmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ return 0;
+}
+
+static const struct mmc_host_ops gb_sdio_ops = {
+ .request = gb_mmc_request,
+ .set_ios = gb_mmc_set_ios,
+ .get_ro = gb_mmc_get_ro,
+ .get_cd = gb_mmc_get_cd,
+ .start_signal_voltage_switch = gb_mmc_switch_voltage,
+};
+
+static int gb_sdio_probe(struct gbphy_device *gbphy_dev,
+ const struct gbphy_device_id *id)
+{
+ struct gb_connection *connection;
+ struct mmc_host *mmc;
+ struct gb_sdio_host *host;
+ int ret = 0;
+
+ mmc = mmc_alloc_host(sizeof(*host), &gbphy_dev->dev);
+ if (!mmc)
+ return -ENOMEM;
+
+ connection = gb_connection_create(gbphy_dev->bundle,
+ le16_to_cpu(gbphy_dev->cport_desc->id),
+ gb_sdio_request_handler);
+ if (IS_ERR(connection)) {
+ ret = PTR_ERR(connection);
+ goto exit_mmc_free;
+ }
+
+ host = mmc_priv(mmc);
+ host->mmc = mmc;
+ host->removed = true;
+
+ host->connection = connection;
+ gb_connection_set_data(connection, host);
+ host->gbphy_dev = gbphy_dev;
+ gb_gbphy_set_data(gbphy_dev, host);
+
+ ret = gb_connection_enable_tx(connection);
+ if (ret)
+ goto exit_connection_destroy;
+
+ ret = gb_sdio_get_caps(host);
+ if (ret < 0)
+ goto exit_connection_disable;
+
+ mmc->ops = &gb_sdio_ops;
+
+ mmc->max_segs = host->mmc->max_blk_count;
+
+ /* for now we make a map 1:1 between max request and segment size */
+ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+ mmc->max_seg_size = mmc->max_req_size;
+
+ mutex_init(&host->lock);
+ spin_lock_init(&host->xfer);
+ host->mrq_workqueue = alloc_workqueue("mmc-%s", 0, 1,
+ dev_name(&gbphy_dev->dev));
+ if (!host->mrq_workqueue) {
+ ret = -ENOMEM;
+ goto exit_connection_disable;
+ }
+ INIT_WORK(&host->mrqwork, gb_sdio_mrq_work);
+
+ ret = gb_connection_enable(connection);
+ if (ret)
+ goto exit_wq_destroy;
+
+ ret = mmc_add_host(mmc);
+ if (ret < 0)
+ goto exit_wq_destroy;
+ host->removed = false;
+ ret = _gb_sdio_process_events(host, host->queued_events);
+ host->queued_events = 0;
+
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+
+ return ret;
+
+exit_wq_destroy:
+ destroy_workqueue(host->mrq_workqueue);
+exit_connection_disable:
+ gb_connection_disable(connection);
+exit_connection_destroy:
+ gb_connection_destroy(connection);
+exit_mmc_free:
+ mmc_free_host(mmc);
+
+ return ret;
+}
+
+static void gb_sdio_remove(struct gbphy_device *gbphy_dev)
+{
+ struct gb_sdio_host *host = gb_gbphy_get_data(gbphy_dev);
+ struct gb_connection *connection = host->connection;
+ struct mmc_host *mmc;
+ int ret;
+
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ gbphy_runtime_get_noresume(gbphy_dev);
+
+ mutex_lock(&host->lock);
+ host->removed = true;
+ mmc = host->mmc;
+ gb_connection_set_data(connection, NULL);
+ mutex_unlock(&host->lock);
+
+ flush_workqueue(host->mrq_workqueue);
+ destroy_workqueue(host->mrq_workqueue);
+ gb_connection_disable_rx(connection);
+ mmc_remove_host(mmc);
+ gb_connection_disable(connection);
+ gb_connection_destroy(connection);
+ mmc_free_host(mmc);
+}
+
+static const struct gbphy_device_id gb_sdio_id_table[] = {
+ { GBPHY_PROTOCOL(GREYBUS_PROTOCOL_SDIO) },
+ { },
+};
+MODULE_DEVICE_TABLE(gbphy, gb_sdio_id_table);
+
+static struct gbphy_driver sdio_driver = {
+ .name = "sdio",
+ .probe = gb_sdio_probe,
+ .remove = gb_sdio_remove,
+ .id_table = gb_sdio_id_table,
+};
+
+module_gbphy_driver(sdio_driver);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/spi.c b/drivers/staging/greybus/spi.c
new file mode 100644
index 000000000000..c893552b5c0b
--- /dev/null
+++ b/drivers/staging/greybus/spi.c
@@ -0,0 +1,79 @@
+/*
+ * SPI bridge PHY driver.
+ *
+ * Copyright 2014-2016 Google Inc.
+ * Copyright 2014-2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/module.h>
+
+#include "greybus.h"
+#include "gbphy.h"
+#include "spilib.h"
+
+static struct spilib_ops *spilib_ops;
+
+static int gb_spi_probe(struct gbphy_device *gbphy_dev,
+ const struct gbphy_device_id *id)
+{
+ struct gb_connection *connection;
+ int ret;
+
+ connection = gb_connection_create(gbphy_dev->bundle,
+ le16_to_cpu(gbphy_dev->cport_desc->id),
+ NULL);
+ if (IS_ERR(connection))
+ return PTR_ERR(connection);
+
+ ret = gb_connection_enable(connection);
+ if (ret)
+ goto exit_connection_destroy;
+
+ ret = gb_spilib_master_init(connection, &gbphy_dev->dev, spilib_ops);
+ if (ret)
+ goto exit_connection_disable;
+
+ gb_gbphy_set_data(gbphy_dev, connection);
+
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+ return 0;
+
+exit_connection_disable:
+ gb_connection_disable(connection);
+exit_connection_destroy:
+ gb_connection_destroy(connection);
+
+ return ret;
+}
+
+static void gb_spi_remove(struct gbphy_device *gbphy_dev)
+{
+ struct gb_connection *connection = gb_gbphy_get_data(gbphy_dev);
+ int ret;
+
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ gbphy_runtime_get_noresume(gbphy_dev);
+
+ gb_spilib_master_exit(connection);
+ gb_connection_disable(connection);
+ gb_connection_destroy(connection);
+}
+
+static const struct gbphy_device_id gb_spi_id_table[] = {
+ { GBPHY_PROTOCOL(GREYBUS_PROTOCOL_SPI) },
+ { },
+};
+MODULE_DEVICE_TABLE(gbphy, gb_spi_id_table);
+
+static struct gbphy_driver spi_driver = {
+ .name = "spi",
+ .probe = gb_spi_probe,
+ .remove = gb_spi_remove,
+ .id_table = gb_spi_id_table,
+};
+
+module_gbphy_driver(spi_driver);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/spilib.c b/drivers/staging/greybus/spilib.c
new file mode 100644
index 000000000000..e97b19148497
--- /dev/null
+++ b/drivers/staging/greybus/spilib.c
@@ -0,0 +1,565 @@
+/*
+ * Greybus SPI library
+ *
+ * Copyright 2014-2016 Google Inc.
+ * Copyright 2014-2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+
+#include "greybus.h"
+#include "spilib.h"
+
+struct gb_spilib {
+ struct gb_connection *connection;
+ struct device *parent;
+ struct spi_transfer *first_xfer;
+ struct spi_transfer *last_xfer;
+ struct spilib_ops *ops;
+ u32 rx_xfer_offset;
+ u32 tx_xfer_offset;
+ u32 last_xfer_size;
+ unsigned int op_timeout;
+ u16 mode;
+ u16 flags;
+ u32 bits_per_word_mask;
+ u8 num_chipselect;
+ u32 min_speed_hz;
+ u32 max_speed_hz;
+};
+
+#define GB_SPI_STATE_MSG_DONE ((void *)0)
+#define GB_SPI_STATE_MSG_IDLE ((void *)1)
+#define GB_SPI_STATE_MSG_RUNNING ((void *)2)
+#define GB_SPI_STATE_OP_READY ((void *)3)
+#define GB_SPI_STATE_OP_DONE ((void *)4)
+#define GB_SPI_STATE_MSG_ERROR ((void *)-1)
+
+#define XFER_TIMEOUT_TOLERANCE 200
+
+static struct spi_master *get_master_from_spi(struct gb_spilib *spi)
+{
+ return gb_connection_get_data(spi->connection);
+}
+
+static int tx_header_fit_operation(u32 tx_size, u32 count, size_t data_max)
+{
+ size_t headers_size;
+
+ data_max -= sizeof(struct gb_spi_transfer_request);
+ headers_size = (count + 1) * sizeof(struct gb_spi_transfer);
+
+ return tx_size + headers_size > data_max ? 0 : 1;
+}
+
+static size_t calc_rx_xfer_size(u32 rx_size, u32 *tx_xfer_size, u32 len,
+ size_t data_max)
+{
+ size_t rx_xfer_size;
+
+ data_max -= sizeof(struct gb_spi_transfer_response);
+
+ if (rx_size + len > data_max)
+ rx_xfer_size = data_max - rx_size;
+ else
+ rx_xfer_size = len;
+
+ /* if this is a write_read, for symmetry read the same as write */
+ if (*tx_xfer_size && rx_xfer_size > *tx_xfer_size)
+ rx_xfer_size = *tx_xfer_size;
+ if (*tx_xfer_size && rx_xfer_size < *tx_xfer_size)
+ *tx_xfer_size = rx_xfer_size;
+
+ return rx_xfer_size;
+}
+
+static size_t calc_tx_xfer_size(u32 tx_size, u32 count, size_t len,
+ size_t data_max)
+{
+ size_t headers_size;
+
+ data_max -= sizeof(struct gb_spi_transfer_request);
+ headers_size = (count + 1) * sizeof(struct gb_spi_transfer);
+
+ if (tx_size + headers_size + len > data_max)
+ return data_max - (tx_size + sizeof(struct gb_spi_transfer));
+
+ return len;
+}
+
+static void clean_xfer_state(struct gb_spilib *spi)
+{
+ spi->first_xfer = NULL;
+ spi->last_xfer = NULL;
+ spi->rx_xfer_offset = 0;
+ spi->tx_xfer_offset = 0;
+ spi->last_xfer_size = 0;
+ spi->op_timeout = 0;
+}
+
+static bool is_last_xfer_done(struct gb_spilib *spi)
+{
+ struct spi_transfer *last_xfer = spi->last_xfer;
+
+ if ((spi->tx_xfer_offset + spi->last_xfer_size == last_xfer->len) ||
+ (spi->rx_xfer_offset + spi->last_xfer_size == last_xfer->len))
+ return true;
+
+ return false;
+}
+
+static int setup_next_xfer(struct gb_spilib *spi, struct spi_message *msg)
+{
+ struct spi_transfer *last_xfer = spi->last_xfer;
+
+ if (msg->state != GB_SPI_STATE_OP_DONE)
+ return 0;
+
+ /*
+ * if we transferred all content of the last transfer, reset values and
+ * check if this was the last transfer in the message
+ */
+ if (is_last_xfer_done(spi)) {
+ spi->tx_xfer_offset = 0;
+ spi->rx_xfer_offset = 0;
+ spi->op_timeout = 0;
+ if (last_xfer == list_last_entry(&msg->transfers,
+ struct spi_transfer,
+ transfer_list))
+ msg->state = GB_SPI_STATE_MSG_DONE;
+ else
+ spi->first_xfer = list_next_entry(last_xfer,
+ transfer_list);
+ return 0;
+ }
+
+ spi->first_xfer = last_xfer;
+ if (last_xfer->tx_buf)
+ spi->tx_xfer_offset += spi->last_xfer_size;
+
+ if (last_xfer->rx_buf)
+ spi->rx_xfer_offset += spi->last_xfer_size;
+
+ return 0;
+}
+
+static struct spi_transfer *get_next_xfer(struct spi_transfer *xfer,
+ struct spi_message *msg)
+{
+ if (xfer == list_last_entry(&msg->transfers, struct spi_transfer,
+ transfer_list))
+ return NULL;
+
+ return list_next_entry(xfer, transfer_list);
+}
+
+/* Routines to transfer data */
+static struct gb_operation *gb_spi_operation_create(struct gb_spilib *spi,
+ struct gb_connection *connection, struct spi_message *msg)
+{
+ struct gb_spi_transfer_request *request;
+ struct spi_device *dev = msg->spi;
+ struct spi_transfer *xfer;
+ struct gb_spi_transfer *gb_xfer;
+ struct gb_operation *operation;
+ u32 tx_size = 0, rx_size = 0, count = 0, xfer_len = 0, request_size;
+ u32 tx_xfer_size = 0, rx_xfer_size = 0, len;
+ u32 total_len = 0;
+ unsigned int xfer_timeout;
+ size_t data_max;
+ void *tx_data;
+
+ data_max = gb_operation_get_payload_size_max(connection);
+ xfer = spi->first_xfer;
+
+ /* Find number of transfers queued and tx/rx length in the message */
+
+ while (msg->state != GB_SPI_STATE_OP_READY) {
+ msg->state = GB_SPI_STATE_MSG_RUNNING;
+ spi->last_xfer = xfer;
+
+ if (!xfer->tx_buf && !xfer->rx_buf) {
+ dev_err(spi->parent,
+ "bufferless transfer, length %u\n", xfer->len);
+ msg->state = GB_SPI_STATE_MSG_ERROR;
+ return NULL;
+ }
+
+ tx_xfer_size = 0;
+ rx_xfer_size = 0;
+
+ if (xfer->tx_buf) {
+ len = xfer->len - spi->tx_xfer_offset;
+ if (!tx_header_fit_operation(tx_size, count, data_max))
+ break;
+ tx_xfer_size = calc_tx_xfer_size(tx_size, count,
+ len, data_max);
+ spi->last_xfer_size = tx_xfer_size;
+ }
+
+ if (xfer->rx_buf) {
+ len = xfer->len - spi->rx_xfer_offset;
+ rx_xfer_size = calc_rx_xfer_size(rx_size, &tx_xfer_size,
+ len, data_max);
+ spi->last_xfer_size = rx_xfer_size;
+ }
+
+ tx_size += tx_xfer_size;
+ rx_size += rx_xfer_size;
+
+ total_len += spi->last_xfer_size;
+ count++;
+
+ xfer = get_next_xfer(xfer, msg);
+ if (!xfer || total_len >= data_max)
+ msg->state = GB_SPI_STATE_OP_READY;
+ }
+
+ /*
+ * In addition to space for all message descriptors we need
+ * to have enough to hold all tx data.
+ */
+ request_size = sizeof(*request);
+ request_size += count * sizeof(*gb_xfer);
+ request_size += tx_size;
+
+ /* Response consists only of incoming data */
+ operation = gb_operation_create(connection, GB_SPI_TYPE_TRANSFER,
+ request_size, rx_size, GFP_KERNEL);
+ if (!operation)
+ return NULL;
+
+ request = operation->request->payload;
+ request->count = cpu_to_le16(count);
+ request->mode = dev->mode;
+ request->chip_select = dev->chip_select;
+
+ gb_xfer = &request->transfers[0];
+ tx_data = gb_xfer + count; /* place tx data after last gb_xfer */
+
+ /* Fill in the transfers array */
+ xfer = spi->first_xfer;
+ while (msg->state != GB_SPI_STATE_OP_DONE) {
+ if (xfer == spi->last_xfer)
+ xfer_len = spi->last_xfer_size;
+ else
+ xfer_len = xfer->len;
+
+ /* make sure we do not timeout in a slow transfer */
+ xfer_timeout = xfer_len * 8 * MSEC_PER_SEC / xfer->speed_hz;
+ xfer_timeout += GB_OPERATION_TIMEOUT_DEFAULT;
+
+ if (xfer_timeout > spi->op_timeout)
+ spi->op_timeout = xfer_timeout;
+
+ gb_xfer->speed_hz = cpu_to_le32(xfer->speed_hz);
+ gb_xfer->len = cpu_to_le32(xfer_len);
+ gb_xfer->delay_usecs = cpu_to_le16(xfer->delay_usecs);
+ gb_xfer->cs_change = xfer->cs_change;
+ gb_xfer->bits_per_word = xfer->bits_per_word;
+
+ /* Copy tx data */
+ if (xfer->tx_buf) {
+ gb_xfer->xfer_flags |= GB_SPI_XFER_WRITE;
+ memcpy(tx_data, xfer->tx_buf + spi->tx_xfer_offset,
+ xfer_len);
+ tx_data += xfer_len;
+ }
+
+ if (xfer->rx_buf)
+ gb_xfer->xfer_flags |= GB_SPI_XFER_READ;
+
+ if (xfer == spi->last_xfer) {
+ if (!is_last_xfer_done(spi))
+ gb_xfer->xfer_flags |= GB_SPI_XFER_INPROGRESS;
+ msg->state = GB_SPI_STATE_OP_DONE;
+ continue;
+ }
+
+ gb_xfer++;
+ xfer = get_next_xfer(xfer, msg);
+ }
+
+ msg->actual_length += total_len;
+
+ return operation;
+}
+
+static void gb_spi_decode_response(struct gb_spilib *spi,
+ struct spi_message *msg,
+ struct gb_spi_transfer_response *response)
+{
+ struct spi_transfer *xfer = spi->first_xfer;
+ void *rx_data = response->data;
+ u32 xfer_len;
+
+ while (xfer) {
+ /* Copy rx data */
+ if (xfer->rx_buf) {
+ if (xfer == spi->first_xfer)
+ xfer_len = xfer->len - spi->rx_xfer_offset;
+ else if (xfer == spi->last_xfer)
+ xfer_len = spi->last_xfer_size;
+ else
+ xfer_len = xfer->len;
+
+ memcpy(xfer->rx_buf + spi->rx_xfer_offset, rx_data,
+ xfer_len);
+ rx_data += xfer_len;
+ }
+
+ if (xfer == spi->last_xfer)
+ break;
+
+ xfer = list_next_entry(xfer, transfer_list);
+ }
+}
+
+static int gb_spi_transfer_one_message(struct spi_master *master,
+ struct spi_message *msg)
+{
+ struct gb_spilib *spi = spi_master_get_devdata(master);
+ struct gb_connection *connection = spi->connection;
+ struct gb_spi_transfer_response *response;
+ struct gb_operation *operation;
+ int ret = 0;
+
+ spi->first_xfer = list_first_entry_or_null(&msg->transfers,
+ struct spi_transfer,
+ transfer_list);
+ if (!spi->first_xfer) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ msg->state = GB_SPI_STATE_MSG_IDLE;
+
+ while (msg->state != GB_SPI_STATE_MSG_DONE &&
+ msg->state != GB_SPI_STATE_MSG_ERROR) {
+ operation = gb_spi_operation_create(spi, connection, msg);
+ if (!operation) {
+ msg->state = GB_SPI_STATE_MSG_ERROR;
+ ret = -EINVAL;
+ continue;
+ }
+
+ ret = gb_operation_request_send_sync_timeout(operation,
+ spi->op_timeout);
+ if (!ret) {
+ response = operation->response->payload;
+ if (response)
+ gb_spi_decode_response(spi, msg, response);
+ } else {
+ dev_err(spi->parent,
+ "transfer operation failed: %d\n", ret);
+ msg->state = GB_SPI_STATE_MSG_ERROR;
+ }
+
+ gb_operation_put(operation);
+ setup_next_xfer(spi, msg);
+ }
+
+out:
+ msg->status = ret;
+ clean_xfer_state(spi);
+ spi_finalize_current_message(master);
+
+ return ret;
+}
+
+static int gb_spi_prepare_transfer_hardware(struct spi_master *master)
+{
+ struct gb_spilib *spi = spi_master_get_devdata(master);
+
+ return spi->ops->prepare_transfer_hardware(spi->parent);
+}
+
+static int gb_spi_unprepare_transfer_hardware(struct spi_master *master)
+{
+ struct gb_spilib *spi = spi_master_get_devdata(master);
+
+ spi->ops->unprepare_transfer_hardware(spi->parent);
+
+ return 0;
+}
+
+static int gb_spi_setup(struct spi_device *spi)
+{
+ /* Nothing to do for now */
+ return 0;
+}
+
+static void gb_spi_cleanup(struct spi_device *spi)
+{
+ /* Nothing to do for now */
+}
+
+/* Routines to get controller information */
+
+/*
+ * Map Greybus spi mode bits/flags/bpw into Linux ones.
+ * All bits are same for now and so these macro's return same values.
+ */
+#define gb_spi_mode_map(mode) mode
+#define gb_spi_flags_map(flags) flags
+
+static int gb_spi_get_master_config(struct gb_spilib *spi)
+{
+ struct gb_spi_master_config_response response;
+ u16 mode, flags;
+ int ret;
+
+ ret = gb_operation_sync(spi->connection, GB_SPI_TYPE_MASTER_CONFIG,
+ NULL, 0, &response, sizeof(response));
+ if (ret < 0)
+ return ret;
+
+ mode = le16_to_cpu(response.mode);
+ spi->mode = gb_spi_mode_map(mode);
+
+ flags = le16_to_cpu(response.flags);
+ spi->flags = gb_spi_flags_map(flags);
+
+ spi->bits_per_word_mask = le32_to_cpu(response.bits_per_word_mask);
+ spi->num_chipselect = response.num_chipselect;
+
+ spi->min_speed_hz = le32_to_cpu(response.min_speed_hz);
+ spi->max_speed_hz = le32_to_cpu(response.max_speed_hz);
+
+ return 0;
+}
+
+static int gb_spi_setup_device(struct gb_spilib *spi, u8 cs)
+{
+ struct spi_master *master = get_master_from_spi(spi);
+ struct gb_spi_device_config_request request;
+ struct gb_spi_device_config_response response;
+ struct spi_board_info spi_board = { {0} };
+ struct spi_device *spidev;
+ int ret;
+ u8 dev_type;
+
+ request.chip_select = cs;
+
+ ret = gb_operation_sync(spi->connection, GB_SPI_TYPE_DEVICE_CONFIG,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret < 0)
+ return ret;
+
+ dev_type = response.device_type;
+
+ if (dev_type == GB_SPI_SPI_DEV)
+ strlcpy(spi_board.modalias, "spidev",
+ sizeof(spi_board.modalias));
+ else if (dev_type == GB_SPI_SPI_NOR)
+ strlcpy(spi_board.modalias, "spi-nor",
+ sizeof(spi_board.modalias));
+ else if (dev_type == GB_SPI_SPI_MODALIAS)
+ memcpy(spi_board.modalias, response.name,
+ sizeof(spi_board.modalias));
+ else
+ return -EINVAL;
+
+ spi_board.mode = le16_to_cpu(response.mode);
+ spi_board.bus_num = master->bus_num;
+ spi_board.chip_select = cs;
+ spi_board.max_speed_hz = le32_to_cpu(response.max_speed_hz);
+
+ spidev = spi_new_device(master, &spi_board);
+ if (!spidev)
+ return -EINVAL;
+
+ return 0;
+}
+
+int gb_spilib_master_init(struct gb_connection *connection, struct device *dev,
+ struct spilib_ops *ops)
+{
+ struct gb_spilib *spi;
+ struct spi_master *master;
+ int ret;
+ u8 i;
+
+ /* Allocate master with space for data */
+ master = spi_alloc_master(dev, sizeof(*spi));
+ if (!master) {
+ dev_err(dev, "cannot alloc SPI master\n");
+ return -ENOMEM;
+ }
+
+ spi = spi_master_get_devdata(master);
+ spi->connection = connection;
+ gb_connection_set_data(connection, master);
+ spi->parent = dev;
+ spi->ops = ops;
+
+ /* get master configuration */
+ ret = gb_spi_get_master_config(spi);
+ if (ret)
+ goto exit_spi_put;
+
+ master->bus_num = -1; /* Allow spi-core to allocate it dynamically */
+ master->num_chipselect = spi->num_chipselect;
+ master->mode_bits = spi->mode;
+ master->flags = spi->flags;
+ master->bits_per_word_mask = spi->bits_per_word_mask;
+
+ /* Attach methods */
+ master->cleanup = gb_spi_cleanup;
+ master->setup = gb_spi_setup;
+ master->transfer_one_message = gb_spi_transfer_one_message;
+
+ if (ops && ops->prepare_transfer_hardware) {
+ master->prepare_transfer_hardware =
+ gb_spi_prepare_transfer_hardware;
+ }
+
+ if (ops && ops->unprepare_transfer_hardware) {
+ master->unprepare_transfer_hardware =
+ gb_spi_unprepare_transfer_hardware;
+ }
+
+ master->auto_runtime_pm = true;
+
+ ret = spi_register_master(master);
+ if (ret < 0)
+ goto exit_spi_put;
+
+ /* now, fetch the devices configuration */
+ for (i = 0; i < spi->num_chipselect; i++) {
+ ret = gb_spi_setup_device(spi, i);
+ if (ret < 0) {
+ dev_err(dev, "failed to allocate spi device %d: %d\n",
+ i, ret);
+ goto exit_spi_unregister;
+ }
+ }
+
+ return 0;
+
+exit_spi_unregister:
+ spi_unregister_master(master);
+exit_spi_put:
+ spi_master_put(master);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_spilib_master_init);
+
+void gb_spilib_master_exit(struct gb_connection *connection)
+{
+ struct spi_master *master = gb_connection_get_data(connection);
+
+ spi_unregister_master(master);
+ spi_master_put(master);
+}
+EXPORT_SYMBOL_GPL(gb_spilib_master_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/spilib.h b/drivers/staging/greybus/spilib.h
new file mode 100644
index 000000000000..566d0dde7f79
--- /dev/null
+++ b/drivers/staging/greybus/spilib.h
@@ -0,0 +1,24 @@
+/*
+ * Greybus SPI library header
+ *
+ * copyright 2016 google inc.
+ * copyright 2016 linaro ltd.
+ *
+ * released under the gplv2 only.
+ */
+
+#ifndef __SPILIB_H
+#define __SPILIB_H
+
+struct device;
+struct gb_connection;
+
+struct spilib_ops {
+ int (*prepare_transfer_hardware)(struct device *dev);
+ void (*unprepare_transfer_hardware)(struct device *dev);
+};
+
+int gb_spilib_master_init(struct gb_connection *connection, struct device *dev, struct spilib_ops *ops);
+void gb_spilib_master_exit(struct gb_connection *connection);
+
+#endif /* __SPILIB_H */
diff --git a/drivers/staging/greybus/svc.c b/drivers/staging/greybus/svc.c
new file mode 100644
index 000000000000..550055ec27a5
--- /dev/null
+++ b/drivers/staging/greybus/svc.c
@@ -0,0 +1,1486 @@
+/*
+ * SVC Greybus driver.
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright 2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/workqueue.h>
+
+#include "greybus.h"
+
+#define SVC_INTF_EJECT_TIMEOUT 9000
+#define SVC_INTF_ACTIVATE_TIMEOUT 6000
+#define SVC_INTF_RESUME_TIMEOUT 3000
+
+struct gb_svc_deferred_request {
+ struct work_struct work;
+ struct gb_operation *operation;
+};
+
+
+static int gb_svc_queue_deferred_request(struct gb_operation *operation);
+
+static ssize_t endo_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_svc *svc = to_gb_svc(dev);
+
+ return sprintf(buf, "0x%04x\n", svc->endo_id);
+}
+static DEVICE_ATTR_RO(endo_id);
+
+static ssize_t ap_intf_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_svc *svc = to_gb_svc(dev);
+
+ return sprintf(buf, "%u\n", svc->ap_intf_id);
+}
+static DEVICE_ATTR_RO(ap_intf_id);
+
+// FIXME
+// This is a hack, we need to do this "right" and clean the interface up
+// properly, not just forcibly yank the thing out of the system and hope for the
+// best. But for now, people want their modules to come out without having to
+// throw the thing to the ground or get out a screwdriver.
+static ssize_t intf_eject_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t len)
+{
+ struct gb_svc *svc = to_gb_svc(dev);
+ unsigned short intf_id;
+ int ret;
+
+ ret = kstrtou16(buf, 10, &intf_id);
+ if (ret < 0)
+ return ret;
+
+ dev_warn(dev, "Forcibly trying to eject interface %d\n", intf_id);
+
+ ret = gb_svc_intf_eject(svc, intf_id);
+ if (ret < 0)
+ return ret;
+
+ return len;
+}
+static DEVICE_ATTR_WO(intf_eject);
+
+static ssize_t watchdog_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct gb_svc *svc = to_gb_svc(dev);
+
+ return sprintf(buf, "%s\n",
+ gb_svc_watchdog_enabled(svc) ? "enabled" : "disabled");
+}
+
+static ssize_t watchdog_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t len)
+{
+ struct gb_svc *svc = to_gb_svc(dev);
+ int retval;
+ bool user_request;
+
+ retval = strtobool(buf, &user_request);
+ if (retval)
+ return retval;
+
+ if (user_request)
+ retval = gb_svc_watchdog_enable(svc);
+ else
+ retval = gb_svc_watchdog_disable(svc);
+ if (retval)
+ return retval;
+ return len;
+}
+static DEVICE_ATTR_RW(watchdog);
+
+static ssize_t watchdog_action_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gb_svc *svc = to_gb_svc(dev);
+
+ if (svc->action == GB_SVC_WATCHDOG_BITE_PANIC_KERNEL)
+ return sprintf(buf, "panic\n");
+ else if (svc->action == GB_SVC_WATCHDOG_BITE_RESET_UNIPRO)
+ return sprintf(buf, "reset\n");
+
+ return -EINVAL;
+}
+
+static ssize_t watchdog_action_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct gb_svc *svc = to_gb_svc(dev);
+
+ if (sysfs_streq(buf, "panic"))
+ svc->action = GB_SVC_WATCHDOG_BITE_PANIC_KERNEL;
+ else if (sysfs_streq(buf, "reset"))
+ svc->action = GB_SVC_WATCHDOG_BITE_RESET_UNIPRO;
+ else
+ return -EINVAL;
+
+ return len;
+}
+static DEVICE_ATTR_RW(watchdog_action);
+
+static int gb_svc_pwrmon_rail_count_get(struct gb_svc *svc, u8 *value)
+{
+ struct gb_svc_pwrmon_rail_count_get_response response;
+ int ret;
+
+ ret = gb_operation_sync(svc->connection,
+ GB_SVC_TYPE_PWRMON_RAIL_COUNT_GET, NULL, 0,
+ &response, sizeof(response));
+ if (ret) {
+ dev_err(&svc->dev, "failed to get rail count: %d\n", ret);
+ return ret;
+ }
+
+ *value = response.rail_count;
+
+ return 0;
+}
+
+static int gb_svc_pwrmon_rail_names_get(struct gb_svc *svc,
+ struct gb_svc_pwrmon_rail_names_get_response *response,
+ size_t bufsize)
+{
+ int ret;
+
+ ret = gb_operation_sync(svc->connection,
+ GB_SVC_TYPE_PWRMON_RAIL_NAMES_GET, NULL, 0,
+ response, bufsize);
+ if (ret) {
+ dev_err(&svc->dev, "failed to get rail names: %d\n", ret);
+ return ret;
+ }
+
+ if (response->status != GB_SVC_OP_SUCCESS) {
+ dev_err(&svc->dev,
+ "SVC error while getting rail names: %u\n",
+ response->status);
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static int gb_svc_pwrmon_sample_get(struct gb_svc *svc, u8 rail_id,
+ u8 measurement_type, u32 *value)
+{
+ struct gb_svc_pwrmon_sample_get_request request;
+ struct gb_svc_pwrmon_sample_get_response response;
+ int ret;
+
+ request.rail_id = rail_id;
+ request.measurement_type = measurement_type;
+
+ ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_PWRMON_SAMPLE_GET,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret) {
+ dev_err(&svc->dev, "failed to get rail sample: %d\n", ret);
+ return ret;
+ }
+
+ if (response.result) {
+ dev_err(&svc->dev,
+ "UniPro error while getting rail power sample (%d %d): %d\n",
+ rail_id, measurement_type, response.result);
+ switch (response.result) {
+ case GB_SVC_PWRMON_GET_SAMPLE_INVAL:
+ return -EINVAL;
+ case GB_SVC_PWRMON_GET_SAMPLE_NOSUPP:
+ return -ENOMSG;
+ default:
+ return -EREMOTEIO;
+ }
+ }
+
+ *value = le32_to_cpu(response.measurement);
+
+ return 0;
+}
+
+int gb_svc_pwrmon_intf_sample_get(struct gb_svc *svc, u8 intf_id,
+ u8 measurement_type, u32 *value)
+{
+ struct gb_svc_pwrmon_intf_sample_get_request request;
+ struct gb_svc_pwrmon_intf_sample_get_response response;
+ int ret;
+
+ request.intf_id = intf_id;
+ request.measurement_type = measurement_type;
+
+ ret = gb_operation_sync(svc->connection,
+ GB_SVC_TYPE_PWRMON_INTF_SAMPLE_GET,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret) {
+ dev_err(&svc->dev, "failed to get intf sample: %d\n", ret);
+ return ret;
+ }
+
+ if (response.result) {
+ dev_err(&svc->dev,
+ "UniPro error while getting intf power sample (%d %d): %d\n",
+ intf_id, measurement_type, response.result);
+ switch (response.result) {
+ case GB_SVC_PWRMON_GET_SAMPLE_INVAL:
+ return -EINVAL;
+ case GB_SVC_PWRMON_GET_SAMPLE_NOSUPP:
+ return -ENOMSG;
+ default:
+ return -EREMOTEIO;
+ }
+ }
+
+ *value = le32_to_cpu(response.measurement);
+
+ return 0;
+}
+
+static struct attribute *svc_attrs[] = {
+ &dev_attr_endo_id.attr,
+ &dev_attr_ap_intf_id.attr,
+ &dev_attr_intf_eject.attr,
+ &dev_attr_watchdog.attr,
+ &dev_attr_watchdog_action.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(svc);
+
+int gb_svc_intf_device_id(struct gb_svc *svc, u8 intf_id, u8 device_id)
+{
+ struct gb_svc_intf_device_id_request request;
+
+ request.intf_id = intf_id;
+ request.device_id = device_id;
+
+ return gb_operation_sync(svc->connection, GB_SVC_TYPE_INTF_DEVICE_ID,
+ &request, sizeof(request), NULL, 0);
+}
+
+int gb_svc_intf_eject(struct gb_svc *svc, u8 intf_id)
+{
+ struct gb_svc_intf_eject_request request;
+ int ret;
+
+ request.intf_id = intf_id;
+
+ /*
+ * The pulse width for module release in svc is long so we need to
+ * increase the timeout so the operation will not return to soon.
+ */
+ ret = gb_operation_sync_timeout(svc->connection,
+ GB_SVC_TYPE_INTF_EJECT, &request,
+ sizeof(request), NULL, 0,
+ SVC_INTF_EJECT_TIMEOUT);
+ if (ret) {
+ dev_err(&svc->dev, "failed to eject interface %u\n", intf_id);
+ return ret;
+ }
+
+ return 0;
+}
+
+int gb_svc_intf_vsys_set(struct gb_svc *svc, u8 intf_id, bool enable)
+{
+ struct gb_svc_intf_vsys_request request;
+ struct gb_svc_intf_vsys_response response;
+ int type, ret;
+
+ request.intf_id = intf_id;
+
+ if (enable)
+ type = GB_SVC_TYPE_INTF_VSYS_ENABLE;
+ else
+ type = GB_SVC_TYPE_INTF_VSYS_DISABLE;
+
+ ret = gb_operation_sync(svc->connection, type,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret < 0)
+ return ret;
+ if (response.result_code != GB_SVC_INTF_VSYS_OK)
+ return -EREMOTEIO;
+ return 0;
+}
+
+int gb_svc_intf_refclk_set(struct gb_svc *svc, u8 intf_id, bool enable)
+{
+ struct gb_svc_intf_refclk_request request;
+ struct gb_svc_intf_refclk_response response;
+ int type, ret;
+
+ request.intf_id = intf_id;
+
+ if (enable)
+ type = GB_SVC_TYPE_INTF_REFCLK_ENABLE;
+ else
+ type = GB_SVC_TYPE_INTF_REFCLK_DISABLE;
+
+ ret = gb_operation_sync(svc->connection, type,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret < 0)
+ return ret;
+ if (response.result_code != GB_SVC_INTF_REFCLK_OK)
+ return -EREMOTEIO;
+ return 0;
+}
+
+int gb_svc_intf_unipro_set(struct gb_svc *svc, u8 intf_id, bool enable)
+{
+ struct gb_svc_intf_unipro_request request;
+ struct gb_svc_intf_unipro_response response;
+ int type, ret;
+
+ request.intf_id = intf_id;
+
+ if (enable)
+ type = GB_SVC_TYPE_INTF_UNIPRO_ENABLE;
+ else
+ type = GB_SVC_TYPE_INTF_UNIPRO_DISABLE;
+
+ ret = gb_operation_sync(svc->connection, type,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret < 0)
+ return ret;
+ if (response.result_code != GB_SVC_INTF_UNIPRO_OK)
+ return -EREMOTEIO;
+ return 0;
+}
+
+int gb_svc_intf_activate(struct gb_svc *svc, u8 intf_id, u8 *intf_type)
+{
+ struct gb_svc_intf_activate_request request;
+ struct gb_svc_intf_activate_response response;
+ int ret;
+
+ request.intf_id = intf_id;
+
+ ret = gb_operation_sync_timeout(svc->connection,
+ GB_SVC_TYPE_INTF_ACTIVATE,
+ &request, sizeof(request),
+ &response, sizeof(response),
+ SVC_INTF_ACTIVATE_TIMEOUT);
+ if (ret < 0)
+ return ret;
+ if (response.status != GB_SVC_OP_SUCCESS) {
+ dev_err(&svc->dev, "failed to activate interface %u: %u\n",
+ intf_id, response.status);
+ return -EREMOTEIO;
+ }
+
+ *intf_type = response.intf_type;
+
+ return 0;
+}
+
+int gb_svc_intf_resume(struct gb_svc *svc, u8 intf_id)
+{
+ struct gb_svc_intf_resume_request request;
+ struct gb_svc_intf_resume_response response;
+ int ret;
+
+ request.intf_id = intf_id;
+
+ ret = gb_operation_sync_timeout(svc->connection,
+ GB_SVC_TYPE_INTF_RESUME,
+ &request, sizeof(request),
+ &response, sizeof(response),
+ SVC_INTF_RESUME_TIMEOUT);
+ if (ret < 0) {
+ dev_err(&svc->dev, "failed to send interface resume %u: %d\n",
+ intf_id, ret);
+ return ret;
+ }
+
+ if (response.status != GB_SVC_OP_SUCCESS) {
+ dev_err(&svc->dev, "failed to resume interface %u: %u\n",
+ intf_id, response.status);
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+int gb_svc_dme_peer_get(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector,
+ u32 *value)
+{
+ struct gb_svc_dme_peer_get_request request;
+ struct gb_svc_dme_peer_get_response response;
+ u16 result;
+ int ret;
+
+ request.intf_id = intf_id;
+ request.attr = cpu_to_le16(attr);
+ request.selector = cpu_to_le16(selector);
+
+ ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_DME_PEER_GET,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret) {
+ dev_err(&svc->dev, "failed to get DME attribute (%u 0x%04x %u): %d\n",
+ intf_id, attr, selector, ret);
+ return ret;
+ }
+
+ result = le16_to_cpu(response.result_code);
+ if (result) {
+ dev_err(&svc->dev, "UniPro error while getting DME attribute (%u 0x%04x %u): %u\n",
+ intf_id, attr, selector, result);
+ return -EREMOTEIO;
+ }
+
+ if (value)
+ *value = le32_to_cpu(response.attr_value);
+
+ return 0;
+}
+
+int gb_svc_dme_peer_set(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector,
+ u32 value)
+{
+ struct gb_svc_dme_peer_set_request request;
+ struct gb_svc_dme_peer_set_response response;
+ u16 result;
+ int ret;
+
+ request.intf_id = intf_id;
+ request.attr = cpu_to_le16(attr);
+ request.selector = cpu_to_le16(selector);
+ request.value = cpu_to_le32(value);
+
+ ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_DME_PEER_SET,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret) {
+ dev_err(&svc->dev, "failed to set DME attribute (%u 0x%04x %u %u): %d\n",
+ intf_id, attr, selector, value, ret);
+ return ret;
+ }
+
+ result = le16_to_cpu(response.result_code);
+ if (result) {
+ dev_err(&svc->dev, "UniPro error while setting DME attribute (%u 0x%04x %u %u): %u\n",
+ intf_id, attr, selector, value, result);
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+int gb_svc_connection_create(struct gb_svc *svc,
+ u8 intf1_id, u16 cport1_id,
+ u8 intf2_id, u16 cport2_id,
+ u8 cport_flags)
+{
+ struct gb_svc_conn_create_request request;
+
+ request.intf1_id = intf1_id;
+ request.cport1_id = cpu_to_le16(cport1_id);
+ request.intf2_id = intf2_id;
+ request.cport2_id = cpu_to_le16(cport2_id);
+ request.tc = 0; /* TC0 */
+ request.flags = cport_flags;
+
+ return gb_operation_sync(svc->connection, GB_SVC_TYPE_CONN_CREATE,
+ &request, sizeof(request), NULL, 0);
+}
+
+void gb_svc_connection_destroy(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
+ u8 intf2_id, u16 cport2_id)
+{
+ struct gb_svc_conn_destroy_request request;
+ struct gb_connection *connection = svc->connection;
+ int ret;
+
+ request.intf1_id = intf1_id;
+ request.cport1_id = cpu_to_le16(cport1_id);
+ request.intf2_id = intf2_id;
+ request.cport2_id = cpu_to_le16(cport2_id);
+
+ ret = gb_operation_sync(connection, GB_SVC_TYPE_CONN_DESTROY,
+ &request, sizeof(request), NULL, 0);
+ if (ret) {
+ dev_err(&svc->dev, "failed to destroy connection (%u:%u %u:%u): %d\n",
+ intf1_id, cport1_id, intf2_id, cport2_id, ret);
+ }
+}
+
+int gb_svc_timesync_enable(struct gb_svc *svc, u8 count, u64 frame_time,
+ u32 strobe_delay, u32 refclk)
+{
+ struct gb_connection *connection = svc->connection;
+ struct gb_svc_timesync_enable_request request;
+
+ request.count = count;
+ request.frame_time = cpu_to_le64(frame_time);
+ request.strobe_delay = cpu_to_le32(strobe_delay);
+ request.refclk = cpu_to_le32(refclk);
+ return gb_operation_sync(connection,
+ GB_SVC_TYPE_TIMESYNC_ENABLE,
+ &request, sizeof(request), NULL, 0);
+}
+
+int gb_svc_timesync_disable(struct gb_svc *svc)
+{
+ struct gb_connection *connection = svc->connection;
+
+ return gb_operation_sync(connection,
+ GB_SVC_TYPE_TIMESYNC_DISABLE,
+ NULL, 0, NULL, 0);
+}
+
+int gb_svc_timesync_authoritative(struct gb_svc *svc, u64 *frame_time)
+{
+ struct gb_connection *connection = svc->connection;
+ struct gb_svc_timesync_authoritative_response response;
+ int ret, i;
+
+ ret = gb_operation_sync(connection,
+ GB_SVC_TYPE_TIMESYNC_AUTHORITATIVE, NULL, 0,
+ &response, sizeof(response));
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < GB_TIMESYNC_MAX_STROBES; i++)
+ frame_time[i] = le64_to_cpu(response.frame_time[i]);
+ return 0;
+}
+
+int gb_svc_timesync_ping(struct gb_svc *svc, u64 *frame_time)
+{
+ struct gb_connection *connection = svc->connection;
+ struct gb_svc_timesync_ping_response response;
+ int ret;
+
+ ret = gb_operation_sync(connection,
+ GB_SVC_TYPE_TIMESYNC_PING,
+ NULL, 0,
+ &response, sizeof(response));
+ if (ret < 0)
+ return ret;
+
+ *frame_time = le64_to_cpu(response.frame_time);
+ return 0;
+}
+
+int gb_svc_timesync_wake_pins_acquire(struct gb_svc *svc, u32 strobe_mask)
+{
+ struct gb_connection *connection = svc->connection;
+ struct gb_svc_timesync_wake_pins_acquire_request request;
+
+ request.strobe_mask = cpu_to_le32(strobe_mask);
+ return gb_operation_sync(connection,
+ GB_SVC_TYPE_TIMESYNC_WAKE_PINS_ACQUIRE,
+ &request, sizeof(request),
+ NULL, 0);
+}
+
+int gb_svc_timesync_wake_pins_release(struct gb_svc *svc)
+{
+ struct gb_connection *connection = svc->connection;
+
+ return gb_operation_sync(connection,
+ GB_SVC_TYPE_TIMESYNC_WAKE_PINS_RELEASE,
+ NULL, 0, NULL, 0);
+}
+
+/* Creates bi-directional routes between the devices */
+int gb_svc_route_create(struct gb_svc *svc, u8 intf1_id, u8 dev1_id,
+ u8 intf2_id, u8 dev2_id)
+{
+ struct gb_svc_route_create_request request;
+
+ request.intf1_id = intf1_id;
+ request.dev1_id = dev1_id;
+ request.intf2_id = intf2_id;
+ request.dev2_id = dev2_id;
+
+ return gb_operation_sync(svc->connection, GB_SVC_TYPE_ROUTE_CREATE,
+ &request, sizeof(request), NULL, 0);
+}
+
+/* Destroys bi-directional routes between the devices */
+void gb_svc_route_destroy(struct gb_svc *svc, u8 intf1_id, u8 intf2_id)
+{
+ struct gb_svc_route_destroy_request request;
+ int ret;
+
+ request.intf1_id = intf1_id;
+ request.intf2_id = intf2_id;
+
+ ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_ROUTE_DESTROY,
+ &request, sizeof(request), NULL, 0);
+ if (ret) {
+ dev_err(&svc->dev, "failed to destroy route (%u %u): %d\n",
+ intf1_id, intf2_id, ret);
+ }
+}
+
+int gb_svc_intf_set_power_mode(struct gb_svc *svc, u8 intf_id, u8 hs_series,
+ u8 tx_mode, u8 tx_gear, u8 tx_nlanes,
+ u8 tx_amplitude, u8 tx_hs_equalizer,
+ u8 rx_mode, u8 rx_gear, u8 rx_nlanes,
+ u8 flags, u32 quirks,
+ struct gb_svc_l2_timer_cfg *local,
+ struct gb_svc_l2_timer_cfg *remote)
+{
+ struct gb_svc_intf_set_pwrm_request request;
+ struct gb_svc_intf_set_pwrm_response response;
+ int ret;
+ u16 result_code;
+
+ memset(&request, 0, sizeof(request));
+
+ request.intf_id = intf_id;
+ request.hs_series = hs_series;
+ request.tx_mode = tx_mode;
+ request.tx_gear = tx_gear;
+ request.tx_nlanes = tx_nlanes;
+ request.tx_amplitude = tx_amplitude;
+ request.tx_hs_equalizer = tx_hs_equalizer;
+ request.rx_mode = rx_mode;
+ request.rx_gear = rx_gear;
+ request.rx_nlanes = rx_nlanes;
+ request.flags = flags;
+ request.quirks = cpu_to_le32(quirks);
+ if (local)
+ request.local_l2timerdata = *local;
+ if (remote)
+ request.remote_l2timerdata = *remote;
+
+ ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_INTF_SET_PWRM,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret < 0)
+ return ret;
+
+ result_code = response.result_code;
+ if (result_code != GB_SVC_SETPWRM_PWR_LOCAL) {
+ dev_err(&svc->dev, "set power mode = %d\n", result_code);
+ return -EIO;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gb_svc_intf_set_power_mode);
+
+int gb_svc_intf_set_power_mode_hibernate(struct gb_svc *svc, u8 intf_id)
+{
+ struct gb_svc_intf_set_pwrm_request request;
+ struct gb_svc_intf_set_pwrm_response response;
+ int ret;
+ u16 result_code;
+
+ memset(&request, 0, sizeof(request));
+
+ request.intf_id = intf_id;
+ request.hs_series = GB_SVC_UNIPRO_HS_SERIES_A;
+ request.tx_mode = GB_SVC_UNIPRO_HIBERNATE_MODE;
+ request.rx_mode = GB_SVC_UNIPRO_HIBERNATE_MODE;
+
+ ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_INTF_SET_PWRM,
+ &request, sizeof(request),
+ &response, sizeof(response));
+ if (ret < 0) {
+ dev_err(&svc->dev,
+ "failed to send set power mode operation to interface %u: %d\n",
+ intf_id, ret);
+ return ret;
+ }
+
+ result_code = response.result_code;
+ if (result_code != GB_SVC_SETPWRM_PWR_OK) {
+ dev_err(&svc->dev,
+ "failed to hibernate the link for interface %u: %u\n",
+ intf_id, result_code);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int gb_svc_ping(struct gb_svc *svc)
+{
+ return gb_operation_sync_timeout(svc->connection, GB_SVC_TYPE_PING,
+ NULL, 0, NULL, 0,
+ GB_OPERATION_TIMEOUT_DEFAULT * 2);
+}
+
+static int gb_svc_version_request(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct gb_svc *svc = gb_connection_get_data(connection);
+ struct gb_svc_version_request *request;
+ struct gb_svc_version_response *response;
+
+ if (op->request->payload_size < sizeof(*request)) {
+ dev_err(&svc->dev, "short version request (%zu < %zu)\n",
+ op->request->payload_size,
+ sizeof(*request));
+ return -EINVAL;
+ }
+
+ request = op->request->payload;
+
+ if (request->major > GB_SVC_VERSION_MAJOR) {
+ dev_warn(&svc->dev, "unsupported major version (%u > %u)\n",
+ request->major, GB_SVC_VERSION_MAJOR);
+ return -ENOTSUPP;
+ }
+
+ svc->protocol_major = request->major;
+ svc->protocol_minor = request->minor;
+
+ if (!gb_operation_response_alloc(op, sizeof(*response), GFP_KERNEL))
+ return -ENOMEM;
+
+ response = op->response->payload;
+ response->major = svc->protocol_major;
+ response->minor = svc->protocol_minor;
+
+ return 0;
+}
+
+static ssize_t pwr_debugfs_voltage_read(struct file *file, char __user *buf,
+ size_t len, loff_t *offset)
+{
+ struct svc_debugfs_pwrmon_rail *pwrmon_rails = file->f_inode->i_private;
+ struct gb_svc *svc = pwrmon_rails->svc;
+ int ret, desc;
+ u32 value;
+ char buff[16];
+
+ ret = gb_svc_pwrmon_sample_get(svc, pwrmon_rails->id,
+ GB_SVC_PWRMON_TYPE_VOL, &value);
+ if (ret) {
+ dev_err(&svc->dev,
+ "failed to get voltage sample %u: %d\n",
+ pwrmon_rails->id, ret);
+ return ret;
+ }
+
+ desc = scnprintf(buff, sizeof(buff), "%u\n", value);
+
+ return simple_read_from_buffer(buf, len, offset, buff, desc);
+}
+
+static ssize_t pwr_debugfs_current_read(struct file *file, char __user *buf,
+ size_t len, loff_t *offset)
+{
+ struct svc_debugfs_pwrmon_rail *pwrmon_rails = file->f_inode->i_private;
+ struct gb_svc *svc = pwrmon_rails->svc;
+ int ret, desc;
+ u32 value;
+ char buff[16];
+
+ ret = gb_svc_pwrmon_sample_get(svc, pwrmon_rails->id,
+ GB_SVC_PWRMON_TYPE_CURR, &value);
+ if (ret) {
+ dev_err(&svc->dev,
+ "failed to get current sample %u: %d\n",
+ pwrmon_rails->id, ret);
+ return ret;
+ }
+
+ desc = scnprintf(buff, sizeof(buff), "%u\n", value);
+
+ return simple_read_from_buffer(buf, len, offset, buff, desc);
+}
+
+static ssize_t pwr_debugfs_power_read(struct file *file, char __user *buf,
+ size_t len, loff_t *offset)
+{
+ struct svc_debugfs_pwrmon_rail *pwrmon_rails = file->f_inode->i_private;
+ struct gb_svc *svc = pwrmon_rails->svc;
+ int ret, desc;
+ u32 value;
+ char buff[16];
+
+ ret = gb_svc_pwrmon_sample_get(svc, pwrmon_rails->id,
+ GB_SVC_PWRMON_TYPE_PWR, &value);
+ if (ret) {
+ dev_err(&svc->dev, "failed to get power sample %u: %d\n",
+ pwrmon_rails->id, ret);
+ return ret;
+ }
+
+ desc = scnprintf(buff, sizeof(buff), "%u\n", value);
+
+ return simple_read_from_buffer(buf, len, offset, buff, desc);
+}
+
+static const struct file_operations pwrmon_debugfs_voltage_fops = {
+ .read = pwr_debugfs_voltage_read,
+};
+
+static const struct file_operations pwrmon_debugfs_current_fops = {
+ .read = pwr_debugfs_current_read,
+};
+
+static const struct file_operations pwrmon_debugfs_power_fops = {
+ .read = pwr_debugfs_power_read,
+};
+
+static void gb_svc_pwrmon_debugfs_init(struct gb_svc *svc)
+{
+ int i;
+ size_t bufsize;
+ struct dentry *dent;
+ struct gb_svc_pwrmon_rail_names_get_response *rail_names;
+ u8 rail_count;
+
+ dent = debugfs_create_dir("pwrmon", svc->debugfs_dentry);
+ if (IS_ERR_OR_NULL(dent))
+ return;
+
+ if (gb_svc_pwrmon_rail_count_get(svc, &rail_count))
+ goto err_pwrmon_debugfs;
+
+ if (!rail_count || rail_count > GB_SVC_PWRMON_MAX_RAIL_COUNT)
+ goto err_pwrmon_debugfs;
+
+ bufsize = sizeof(*rail_names) +
+ GB_SVC_PWRMON_RAIL_NAME_BUFSIZE * rail_count;
+
+ rail_names = kzalloc(bufsize, GFP_KERNEL);
+ if (!rail_names)
+ goto err_pwrmon_debugfs;
+
+ svc->pwrmon_rails = kcalloc(rail_count, sizeof(*svc->pwrmon_rails),
+ GFP_KERNEL);
+ if (!svc->pwrmon_rails)
+ goto err_pwrmon_debugfs_free;
+
+ if (gb_svc_pwrmon_rail_names_get(svc, rail_names, bufsize))
+ goto err_pwrmon_debugfs_free;
+
+ for (i = 0; i < rail_count; i++) {
+ struct dentry *dir;
+ struct svc_debugfs_pwrmon_rail *rail = &svc->pwrmon_rails[i];
+ char fname[GB_SVC_PWRMON_RAIL_NAME_BUFSIZE];
+
+ snprintf(fname, sizeof(fname), "%s",
+ (char *)&rail_names->name[i]);
+
+ rail->id = i;
+ rail->svc = svc;
+
+ dir = debugfs_create_dir(fname, dent);
+ debugfs_create_file("voltage_now", S_IRUGO, dir, rail,
+ &pwrmon_debugfs_voltage_fops);
+ debugfs_create_file("current_now", S_IRUGO, dir, rail,
+ &pwrmon_debugfs_current_fops);
+ debugfs_create_file("power_now", S_IRUGO, dir, rail,
+ &pwrmon_debugfs_power_fops);
+ }
+
+ kfree(rail_names);
+ return;
+
+err_pwrmon_debugfs_free:
+ kfree(rail_names);
+ kfree(svc->pwrmon_rails);
+ svc->pwrmon_rails = NULL;
+
+err_pwrmon_debugfs:
+ debugfs_remove(dent);
+}
+
+static void gb_svc_debugfs_init(struct gb_svc *svc)
+{
+ svc->debugfs_dentry = debugfs_create_dir(dev_name(&svc->dev),
+ gb_debugfs_get());
+ gb_svc_pwrmon_debugfs_init(svc);
+}
+
+static void gb_svc_debugfs_exit(struct gb_svc *svc)
+{
+ debugfs_remove_recursive(svc->debugfs_dentry);
+ kfree(svc->pwrmon_rails);
+ svc->pwrmon_rails = NULL;
+}
+
+static int gb_svc_hello(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct gb_svc *svc = gb_connection_get_data(connection);
+ struct gb_svc_hello_request *hello_request;
+ int ret;
+
+ if (op->request->payload_size < sizeof(*hello_request)) {
+ dev_warn(&svc->dev, "short hello request (%zu < %zu)\n",
+ op->request->payload_size,
+ sizeof(*hello_request));
+ return -EINVAL;
+ }
+
+ hello_request = op->request->payload;
+ svc->endo_id = le16_to_cpu(hello_request->endo_id);
+ svc->ap_intf_id = hello_request->interface_id;
+
+ ret = device_add(&svc->dev);
+ if (ret) {
+ dev_err(&svc->dev, "failed to register svc device: %d\n", ret);
+ return ret;
+ }
+
+ ret = gb_svc_watchdog_create(svc);
+ if (ret) {
+ dev_err(&svc->dev, "failed to create watchdog: %d\n", ret);
+ goto err_unregister_device;
+ }
+
+ gb_svc_debugfs_init(svc);
+
+ ret = gb_timesync_svc_add(svc);
+ if (ret) {
+ dev_err(&svc->dev, "failed to add SVC to timesync: %d\n", ret);
+ gb_svc_debugfs_exit(svc);
+ goto err_unregister_device;
+ }
+
+ return gb_svc_queue_deferred_request(op);
+
+err_unregister_device:
+ gb_svc_watchdog_destroy(svc);
+ device_del(&svc->dev);
+ return ret;
+}
+
+static struct gb_interface *gb_svc_interface_lookup(struct gb_svc *svc,
+ u8 intf_id)
+{
+ struct gb_host_device *hd = svc->hd;
+ struct gb_module *module;
+ size_t num_interfaces;
+ u8 module_id;
+
+ list_for_each_entry(module, &hd->modules, hd_node) {
+ module_id = module->module_id;
+ num_interfaces = module->num_interfaces;
+
+ if (intf_id >= module_id &&
+ intf_id < module_id + num_interfaces) {
+ return module->interfaces[intf_id - module_id];
+ }
+ }
+
+ return NULL;
+}
+
+static struct gb_module *gb_svc_module_lookup(struct gb_svc *svc, u8 module_id)
+{
+ struct gb_host_device *hd = svc->hd;
+ struct gb_module *module;
+
+ list_for_each_entry(module, &hd->modules, hd_node) {
+ if (module->module_id == module_id)
+ return module;
+ }
+
+ return NULL;
+}
+
+static void gb_svc_process_hello_deferred(struct gb_operation *operation)
+{
+ struct gb_connection *connection = operation->connection;
+ struct gb_svc *svc = gb_connection_get_data(connection);
+ int ret;
+
+ /*
+ * XXX This is a hack/work-around to reconfigure the APBridgeA-Switch
+ * link to PWM G2, 1 Lane, Slow Auto, so that it has sufficient
+ * bandwidth for 3 audio streams plus boot-over-UniPro of a hot-plugged
+ * module.
+ *
+ * The code should be removed once SW-2217, Heuristic for UniPro
+ * Power Mode Changes is resolved.
+ */
+ ret = gb_svc_intf_set_power_mode(svc, svc->ap_intf_id,
+ GB_SVC_UNIPRO_HS_SERIES_A,
+ GB_SVC_UNIPRO_SLOW_AUTO_MODE,
+ 2, 1,
+ GB_SVC_SMALL_AMPLITUDE, GB_SVC_NO_DE_EMPHASIS,
+ GB_SVC_UNIPRO_SLOW_AUTO_MODE,
+ 2, 1,
+ 0, 0,
+ NULL, NULL);
+
+ if (ret)
+ dev_warn(&svc->dev,
+ "power mode change failed on AP to switch link: %d\n",
+ ret);
+}
+
+static void gb_svc_process_module_inserted(struct gb_operation *operation)
+{
+ struct gb_svc_module_inserted_request *request;
+ struct gb_connection *connection = operation->connection;
+ struct gb_svc *svc = gb_connection_get_data(connection);
+ struct gb_host_device *hd = svc->hd;
+ struct gb_module *module;
+ size_t num_interfaces;
+ u8 module_id;
+ u16 flags;
+ int ret;
+
+ /* The request message size has already been verified. */
+ request = operation->request->payload;
+ module_id = request->primary_intf_id;
+ num_interfaces = request->intf_count;
+ flags = le16_to_cpu(request->flags);
+
+ dev_dbg(&svc->dev, "%s - id = %u, num_interfaces = %zu, flags = 0x%04x\n",
+ __func__, module_id, num_interfaces, flags);
+
+ if (flags & GB_SVC_MODULE_INSERTED_FLAG_NO_PRIMARY) {
+ dev_warn(&svc->dev, "no primary interface detected on module %u\n",
+ module_id);
+ }
+
+ module = gb_svc_module_lookup(svc, module_id);
+ if (module) {
+ dev_warn(&svc->dev, "unexpected module-inserted event %u\n",
+ module_id);
+ return;
+ }
+
+ module = gb_module_create(hd, module_id, num_interfaces);
+ if (!module) {
+ dev_err(&svc->dev, "failed to create module\n");
+ return;
+ }
+
+ ret = gb_module_add(module);
+ if (ret) {
+ gb_module_put(module);
+ return;
+ }
+
+ list_add(&module->hd_node, &hd->modules);
+}
+
+static void gb_svc_process_module_removed(struct gb_operation *operation)
+{
+ struct gb_svc_module_removed_request *request;
+ struct gb_connection *connection = operation->connection;
+ struct gb_svc *svc = gb_connection_get_data(connection);
+ struct gb_module *module;
+ u8 module_id;
+
+ /* The request message size has already been verified. */
+ request = operation->request->payload;
+ module_id = request->primary_intf_id;
+
+ dev_dbg(&svc->dev, "%s - id = %u\n", __func__, module_id);
+
+ module = gb_svc_module_lookup(svc, module_id);
+ if (!module) {
+ dev_warn(&svc->dev, "unexpected module-removed event %u\n",
+ module_id);
+ return;
+ }
+
+ module->disconnected = true;
+
+ gb_module_del(module);
+ list_del(&module->hd_node);
+ gb_module_put(module);
+}
+
+static void gb_svc_process_intf_oops(struct gb_operation *operation)
+{
+ struct gb_svc_intf_oops_request *request;
+ struct gb_connection *connection = operation->connection;
+ struct gb_svc *svc = gb_connection_get_data(connection);
+ struct gb_interface *intf;
+ u8 intf_id;
+ u8 reason;
+
+ /* The request message size has already been verified. */
+ request = operation->request->payload;
+ intf_id = request->intf_id;
+ reason = request->reason;
+
+ intf = gb_svc_interface_lookup(svc, intf_id);
+ if (!intf) {
+ dev_warn(&svc->dev, "unexpected interface-oops event %u\n",
+ intf_id);
+ return;
+ }
+
+ dev_info(&svc->dev, "Deactivating interface %u, interface oops reason = %u\n",
+ intf_id, reason);
+
+ mutex_lock(&intf->mutex);
+ intf->disconnected = true;
+ gb_interface_disable(intf);
+ gb_interface_deactivate(intf);
+ mutex_unlock(&intf->mutex);
+}
+
+static void gb_svc_process_intf_mailbox_event(struct gb_operation *operation)
+{
+ struct gb_svc_intf_mailbox_event_request *request;
+ struct gb_connection *connection = operation->connection;
+ struct gb_svc *svc = gb_connection_get_data(connection);
+ struct gb_interface *intf;
+ u8 intf_id;
+ u16 result_code;
+ u32 mailbox;
+
+ /* The request message size has already been verified. */
+ request = operation->request->payload;
+ intf_id = request->intf_id;
+ result_code = le16_to_cpu(request->result_code);
+ mailbox = le32_to_cpu(request->mailbox);
+
+ dev_dbg(&svc->dev, "%s - id = %u, result = 0x%04x, mailbox = 0x%08x\n",
+ __func__, intf_id, result_code, mailbox);
+
+ intf = gb_svc_interface_lookup(svc, intf_id);
+ if (!intf) {
+ dev_warn(&svc->dev, "unexpected mailbox event %u\n", intf_id);
+ return;
+ }
+
+ gb_interface_mailbox_event(intf, result_code, mailbox);
+}
+
+static void gb_svc_process_deferred_request(struct work_struct *work)
+{
+ struct gb_svc_deferred_request *dr;
+ struct gb_operation *operation;
+ struct gb_svc *svc;
+ u8 type;
+
+ dr = container_of(work, struct gb_svc_deferred_request, work);
+ operation = dr->operation;
+ svc = gb_connection_get_data(operation->connection);
+ type = operation->request->header->type;
+
+ switch (type) {
+ case GB_SVC_TYPE_SVC_HELLO:
+ gb_svc_process_hello_deferred(operation);
+ break;
+ case GB_SVC_TYPE_MODULE_INSERTED:
+ gb_svc_process_module_inserted(operation);
+ break;
+ case GB_SVC_TYPE_MODULE_REMOVED:
+ gb_svc_process_module_removed(operation);
+ break;
+ case GB_SVC_TYPE_INTF_MAILBOX_EVENT:
+ gb_svc_process_intf_mailbox_event(operation);
+ break;
+ case GB_SVC_TYPE_INTF_OOPS:
+ gb_svc_process_intf_oops(operation);
+ break;
+ default:
+ dev_err(&svc->dev, "bad deferred request type: 0x%02x\n", type);
+ }
+
+ gb_operation_put(operation);
+ kfree(dr);
+}
+
+static int gb_svc_queue_deferred_request(struct gb_operation *operation)
+{
+ struct gb_svc *svc = gb_connection_get_data(operation->connection);
+ struct gb_svc_deferred_request *dr;
+
+ dr = kmalloc(sizeof(*dr), GFP_KERNEL);
+ if (!dr)
+ return -ENOMEM;
+
+ gb_operation_get(operation);
+
+ dr->operation = operation;
+ INIT_WORK(&dr->work, gb_svc_process_deferred_request);
+
+ queue_work(svc->wq, &dr->work);
+
+ return 0;
+}
+
+static int gb_svc_intf_reset_recv(struct gb_operation *op)
+{
+ struct gb_svc *svc = gb_connection_get_data(op->connection);
+ struct gb_message *request = op->request;
+ struct gb_svc_intf_reset_request *reset;
+ u8 intf_id;
+
+ if (request->payload_size < sizeof(*reset)) {
+ dev_warn(&svc->dev, "short reset request received (%zu < %zu)\n",
+ request->payload_size, sizeof(*reset));
+ return -EINVAL;
+ }
+ reset = request->payload;
+
+ intf_id = reset->intf_id;
+
+ /* FIXME Reset the interface here */
+
+ return 0;
+}
+
+static int gb_svc_module_inserted_recv(struct gb_operation *op)
+{
+ struct gb_svc *svc = gb_connection_get_data(op->connection);
+ struct gb_svc_module_inserted_request *request;
+
+ if (op->request->payload_size < sizeof(*request)) {
+ dev_warn(&svc->dev, "short module-inserted request received (%zu < %zu)\n",
+ op->request->payload_size, sizeof(*request));
+ return -EINVAL;
+ }
+
+ request = op->request->payload;
+
+ dev_dbg(&svc->dev, "%s - id = %u\n", __func__,
+ request->primary_intf_id);
+
+ return gb_svc_queue_deferred_request(op);
+}
+
+static int gb_svc_module_removed_recv(struct gb_operation *op)
+{
+ struct gb_svc *svc = gb_connection_get_data(op->connection);
+ struct gb_svc_module_removed_request *request;
+
+ if (op->request->payload_size < sizeof(*request)) {
+ dev_warn(&svc->dev, "short module-removed request received (%zu < %zu)\n",
+ op->request->payload_size, sizeof(*request));
+ return -EINVAL;
+ }
+
+ request = op->request->payload;
+
+ dev_dbg(&svc->dev, "%s - id = %u\n", __func__,
+ request->primary_intf_id);
+
+ return gb_svc_queue_deferred_request(op);
+}
+
+static int gb_svc_intf_oops_recv(struct gb_operation *op)
+{
+ struct gb_svc *svc = gb_connection_get_data(op->connection);
+ struct gb_svc_intf_oops_request *request;
+
+ if (op->request->payload_size < sizeof(*request)) {
+ dev_warn(&svc->dev, "short intf-oops request received (%zu < %zu)\n",
+ op->request->payload_size, sizeof(*request));
+ return -EINVAL;
+ }
+
+ return gb_svc_queue_deferred_request(op);
+}
+
+static int gb_svc_intf_mailbox_event_recv(struct gb_operation *op)
+{
+ struct gb_svc *svc = gb_connection_get_data(op->connection);
+ struct gb_svc_intf_mailbox_event_request *request;
+
+ if (op->request->payload_size < sizeof(*request)) {
+ dev_warn(&svc->dev, "short mailbox request received (%zu < %zu)\n",
+ op->request->payload_size, sizeof(*request));
+ return -EINVAL;
+ }
+
+ request = op->request->payload;
+
+ dev_dbg(&svc->dev, "%s - id = %u\n", __func__, request->intf_id);
+
+ return gb_svc_queue_deferred_request(op);
+}
+
+static int gb_svc_request_handler(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct gb_svc *svc = gb_connection_get_data(connection);
+ u8 type = op->type;
+ int ret = 0;
+
+ /*
+ * SVC requests need to follow a specific order (at least initially) and
+ * below code takes care of enforcing that. The expected order is:
+ * - PROTOCOL_VERSION
+ * - SVC_HELLO
+ * - Any other request, but the earlier two.
+ *
+ * Incoming requests are guaranteed to be serialized and so we don't
+ * need to protect 'state' for any races.
+ */
+ switch (type) {
+ case GB_SVC_TYPE_PROTOCOL_VERSION:
+ if (svc->state != GB_SVC_STATE_RESET)
+ ret = -EINVAL;
+ break;
+ case GB_SVC_TYPE_SVC_HELLO:
+ if (svc->state != GB_SVC_STATE_PROTOCOL_VERSION)
+ ret = -EINVAL;
+ break;
+ default:
+ if (svc->state != GB_SVC_STATE_SVC_HELLO)
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret) {
+ dev_warn(&svc->dev, "unexpected request 0x%02x received (state %u)\n",
+ type, svc->state);
+ return ret;
+ }
+
+ switch (type) {
+ case GB_SVC_TYPE_PROTOCOL_VERSION:
+ ret = gb_svc_version_request(op);
+ if (!ret)
+ svc->state = GB_SVC_STATE_PROTOCOL_VERSION;
+ return ret;
+ case GB_SVC_TYPE_SVC_HELLO:
+ ret = gb_svc_hello(op);
+ if (!ret)
+ svc->state = GB_SVC_STATE_SVC_HELLO;
+ return ret;
+ case GB_SVC_TYPE_INTF_RESET:
+ return gb_svc_intf_reset_recv(op);
+ case GB_SVC_TYPE_MODULE_INSERTED:
+ return gb_svc_module_inserted_recv(op);
+ case GB_SVC_TYPE_MODULE_REMOVED:
+ return gb_svc_module_removed_recv(op);
+ case GB_SVC_TYPE_INTF_MAILBOX_EVENT:
+ return gb_svc_intf_mailbox_event_recv(op);
+ case GB_SVC_TYPE_INTF_OOPS:
+ return gb_svc_intf_oops_recv(op);
+ default:
+ dev_warn(&svc->dev, "unsupported request 0x%02x\n", type);
+ return -EINVAL;
+ }
+}
+
+static void gb_svc_release(struct device *dev)
+{
+ struct gb_svc *svc = to_gb_svc(dev);
+
+ if (svc->connection)
+ gb_connection_destroy(svc->connection);
+ ida_destroy(&svc->device_id_map);
+ destroy_workqueue(svc->wq);
+ kfree(svc);
+}
+
+struct device_type greybus_svc_type = {
+ .name = "greybus_svc",
+ .release = gb_svc_release,
+};
+
+struct gb_svc *gb_svc_create(struct gb_host_device *hd)
+{
+ struct gb_svc *svc;
+
+ svc = kzalloc(sizeof(*svc), GFP_KERNEL);
+ if (!svc)
+ return NULL;
+
+ svc->wq = alloc_workqueue("%s:svc", WQ_UNBOUND, 1, dev_name(&hd->dev));
+ if (!svc->wq) {
+ kfree(svc);
+ return NULL;
+ }
+
+ svc->dev.parent = &hd->dev;
+ svc->dev.bus = &greybus_bus_type;
+ svc->dev.type = &greybus_svc_type;
+ svc->dev.groups = svc_groups;
+ svc->dev.dma_mask = svc->dev.parent->dma_mask;
+ device_initialize(&svc->dev);
+
+ dev_set_name(&svc->dev, "%d-svc", hd->bus_id);
+
+ ida_init(&svc->device_id_map);
+ svc->state = GB_SVC_STATE_RESET;
+ svc->hd = hd;
+
+ svc->connection = gb_connection_create_static(hd, GB_SVC_CPORT_ID,
+ gb_svc_request_handler);
+ if (IS_ERR(svc->connection)) {
+ dev_err(&svc->dev, "failed to create connection: %ld\n",
+ PTR_ERR(svc->connection));
+ goto err_put_device;
+ }
+
+ gb_connection_set_data(svc->connection, svc);
+
+ return svc;
+
+err_put_device:
+ put_device(&svc->dev);
+ return NULL;
+}
+
+int gb_svc_add(struct gb_svc *svc)
+{
+ int ret;
+
+ /*
+ * The SVC protocol is currently driven by the SVC, so the SVC device
+ * is added from the connection request handler when enough
+ * information has been received.
+ */
+ ret = gb_connection_enable(svc->connection);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void gb_svc_remove_modules(struct gb_svc *svc)
+{
+ struct gb_host_device *hd = svc->hd;
+ struct gb_module *module, *tmp;
+
+ list_for_each_entry_safe(module, tmp, &hd->modules, hd_node) {
+ gb_module_del(module);
+ list_del(&module->hd_node);
+ gb_module_put(module);
+ }
+}
+
+void gb_svc_del(struct gb_svc *svc)
+{
+ gb_connection_disable_rx(svc->connection);
+
+ /*
+ * The SVC device may have been registered from the request handler.
+ */
+ if (device_is_registered(&svc->dev)) {
+ gb_timesync_svc_remove(svc);
+ gb_svc_debugfs_exit(svc);
+ gb_svc_watchdog_destroy(svc);
+ device_del(&svc->dev);
+ }
+
+ flush_workqueue(svc->wq);
+
+ gb_svc_remove_modules(svc);
+
+ gb_connection_disable(svc->connection);
+}
+
+void gb_svc_put(struct gb_svc *svc)
+{
+ put_device(&svc->dev);
+}
diff --git a/drivers/staging/greybus/svc.h b/drivers/staging/greybus/svc.h
new file mode 100644
index 000000000000..d1d7ef967385
--- /dev/null
+++ b/drivers/staging/greybus/svc.h
@@ -0,0 +1,109 @@
+/*
+ * Greybus SVC code
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright 2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __SVC_H
+#define __SVC_H
+
+#define GB_SVC_CPORT_FLAG_E2EFC BIT(0)
+#define GB_SVC_CPORT_FLAG_CSD_N BIT(1)
+#define GB_SVC_CPORT_FLAG_CSV_N BIT(2)
+
+enum gb_svc_state {
+ GB_SVC_STATE_RESET,
+ GB_SVC_STATE_PROTOCOL_VERSION,
+ GB_SVC_STATE_SVC_HELLO,
+};
+
+enum gb_svc_watchdog_bite {
+ GB_SVC_WATCHDOG_BITE_RESET_UNIPRO = 0,
+ GB_SVC_WATCHDOG_BITE_PANIC_KERNEL,
+};
+
+struct gb_svc_watchdog;
+
+struct svc_debugfs_pwrmon_rail {
+ u8 id;
+ struct gb_svc *svc;
+};
+
+struct gb_svc {
+ struct device dev;
+
+ struct gb_host_device *hd;
+ struct gb_connection *connection;
+ enum gb_svc_state state;
+ struct ida device_id_map;
+ struct workqueue_struct *wq;
+
+ u16 endo_id;
+ u8 ap_intf_id;
+
+ u8 protocol_major;
+ u8 protocol_minor;
+
+ struct gb_svc_watchdog *watchdog;
+ enum gb_svc_watchdog_bite action;
+
+ struct dentry *debugfs_dentry;
+ struct svc_debugfs_pwrmon_rail *pwrmon_rails;
+};
+#define to_gb_svc(d) container_of(d, struct gb_svc, dev)
+
+struct gb_svc *gb_svc_create(struct gb_host_device *hd);
+int gb_svc_add(struct gb_svc *svc);
+void gb_svc_del(struct gb_svc *svc);
+void gb_svc_put(struct gb_svc *svc);
+
+int gb_svc_pwrmon_intf_sample_get(struct gb_svc *svc, u8 intf_id,
+ u8 measurement_type, u32 *value);
+int gb_svc_intf_device_id(struct gb_svc *svc, u8 intf_id, u8 device_id);
+int gb_svc_route_create(struct gb_svc *svc, u8 intf1_id, u8 dev1_id,
+ u8 intf2_id, u8 dev2_id);
+void gb_svc_route_destroy(struct gb_svc *svc, u8 intf1_id, u8 intf2_id);
+int gb_svc_connection_create(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
+ u8 intf2_id, u16 cport2_id, u8 cport_flags);
+void gb_svc_connection_destroy(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
+ u8 intf2_id, u16 cport2_id);
+int gb_svc_intf_eject(struct gb_svc *svc, u8 intf_id);
+int gb_svc_intf_vsys_set(struct gb_svc *svc, u8 intf_id, bool enable);
+int gb_svc_intf_refclk_set(struct gb_svc *svc, u8 intf_id, bool enable);
+int gb_svc_intf_unipro_set(struct gb_svc *svc, u8 intf_id, bool enable);
+int gb_svc_intf_activate(struct gb_svc *svc, u8 intf_id, u8 *intf_type);
+int gb_svc_intf_resume(struct gb_svc *svc, u8 intf_id);
+
+int gb_svc_dme_peer_get(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector,
+ u32 *value);
+int gb_svc_dme_peer_set(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector,
+ u32 value);
+int gb_svc_intf_set_power_mode(struct gb_svc *svc, u8 intf_id, u8 hs_series,
+ u8 tx_mode, u8 tx_gear, u8 tx_nlanes,
+ u8 tx_amplitude, u8 tx_hs_equalizer,
+ u8 rx_mode, u8 rx_gear, u8 rx_nlanes,
+ u8 flags, u32 quirks,
+ struct gb_svc_l2_timer_cfg *local,
+ struct gb_svc_l2_timer_cfg *remote);
+int gb_svc_intf_set_power_mode_hibernate(struct gb_svc *svc, u8 intf_id);
+int gb_svc_ping(struct gb_svc *svc);
+int gb_svc_watchdog_create(struct gb_svc *svc);
+void gb_svc_watchdog_destroy(struct gb_svc *svc);
+bool gb_svc_watchdog_enabled(struct gb_svc *svc);
+int gb_svc_watchdog_enable(struct gb_svc *svc);
+int gb_svc_watchdog_disable(struct gb_svc *svc);
+int gb_svc_timesync_enable(struct gb_svc *svc, u8 count, u64 frame_time,
+ u32 strobe_delay, u32 refclk);
+int gb_svc_timesync_disable(struct gb_svc *svc);
+int gb_svc_timesync_authoritative(struct gb_svc *svc, u64 *frame_time);
+int gb_svc_timesync_ping(struct gb_svc *svc, u64 *frame_time);
+int gb_svc_timesync_wake_pins_acquire(struct gb_svc *svc, u32 strobe_mask);
+int gb_svc_timesync_wake_pins_release(struct gb_svc *svc);
+
+int gb_svc_protocol_init(void);
+void gb_svc_protocol_exit(void);
+
+#endif /* __SVC_H */
diff --git a/drivers/staging/greybus/svc_watchdog.c b/drivers/staging/greybus/svc_watchdog.c
new file mode 100644
index 000000000000..3729460fb954
--- /dev/null
+++ b/drivers/staging/greybus/svc_watchdog.c
@@ -0,0 +1,198 @@
+/*
+ * SVC Greybus "watchdog" driver.
+ *
+ * Copyright 2016 Google Inc.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/delay.h>
+#include <linux/suspend.h>
+#include <linux/workqueue.h>
+#include "greybus.h"
+
+#define SVC_WATCHDOG_PERIOD (2*HZ)
+
+struct gb_svc_watchdog {
+ struct delayed_work work;
+ struct gb_svc *svc;
+ bool enabled;
+ struct notifier_block pm_notifier;
+};
+
+static struct delayed_work reset_work;
+
+static int svc_watchdog_pm_notifier(struct notifier_block *notifier,
+ unsigned long pm_event, void *unused)
+{
+ struct gb_svc_watchdog *watchdog =
+ container_of(notifier, struct gb_svc_watchdog, pm_notifier);
+
+ switch (pm_event) {
+ case PM_SUSPEND_PREPARE:
+ gb_svc_watchdog_disable(watchdog->svc);
+ break;
+ case PM_POST_SUSPEND:
+ gb_svc_watchdog_enable(watchdog->svc);
+ break;
+ default:
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static void greybus_reset(struct work_struct *work)
+{
+ static char start_path[256] = "/system/bin/start";
+ static char *envp[] = {
+ "HOME=/",
+ "PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin",
+ NULL,
+ };
+ static char *argv[] = {
+ start_path,
+ "unipro_reset",
+ NULL,
+ };
+
+ printk(KERN_ERR "svc_watchdog: calling \"%s %s\" to reset greybus network!\n",
+ argv[0], argv[1]);
+ call_usermodehelper(start_path, argv, envp, UMH_WAIT_EXEC);
+}
+
+static void do_work(struct work_struct *work)
+{
+ struct gb_svc_watchdog *watchdog;
+ struct gb_svc *svc;
+ int retval;
+
+ watchdog = container_of(work, struct gb_svc_watchdog, work.work);
+ svc = watchdog->svc;
+
+ dev_dbg(&svc->dev, "%s: ping.\n", __func__);
+ retval = gb_svc_ping(svc);
+ if (retval) {
+ /*
+ * Something went really wrong, let's warn userspace and then
+ * pull the plug and reset the whole greybus network.
+ * We need to do this outside of this workqueue as we will be
+ * tearing down the svc device itself. So queue up
+ * yet-another-callback to do that.
+ */
+ dev_err(&svc->dev,
+ "SVC ping has returned %d, something is wrong!!!\n",
+ retval);
+
+ if (svc->action == GB_SVC_WATCHDOG_BITE_PANIC_KERNEL) {
+ panic("SVC is not responding\n");
+ } else if (svc->action == GB_SVC_WATCHDOG_BITE_RESET_UNIPRO) {
+ dev_err(&svc->dev, "Resetting the greybus network, watch out!!!\n");
+
+ INIT_DELAYED_WORK(&reset_work, greybus_reset);
+ schedule_delayed_work(&reset_work, HZ / 2);
+
+ /*
+ * Disable ourselves, we don't want to trip again unless
+ * userspace wants us to.
+ */
+ watchdog->enabled = false;
+ }
+ }
+
+ /* resubmit our work to happen again, if we are still "alive" */
+ if (watchdog->enabled)
+ schedule_delayed_work(&watchdog->work, SVC_WATCHDOG_PERIOD);
+}
+
+int gb_svc_watchdog_create(struct gb_svc *svc)
+{
+ struct gb_svc_watchdog *watchdog;
+ int retval;
+
+ if (svc->watchdog)
+ return 0;
+
+ watchdog = kmalloc(sizeof(*watchdog), GFP_KERNEL);
+ if (!watchdog)
+ return -ENOMEM;
+
+ watchdog->enabled = false;
+ watchdog->svc = svc;
+ INIT_DELAYED_WORK(&watchdog->work, do_work);
+ svc->watchdog = watchdog;
+
+ watchdog->pm_notifier.notifier_call = svc_watchdog_pm_notifier;
+ retval = register_pm_notifier(&watchdog->pm_notifier);
+ if (retval) {
+ dev_err(&svc->dev, "error registering pm notifier(%d)\n",
+ retval);
+ goto svc_watchdog_create_err;
+ }
+
+ retval = gb_svc_watchdog_enable(svc);
+ if (retval) {
+ dev_err(&svc->dev, "error enabling watchdog (%d)\n", retval);
+ unregister_pm_notifier(&watchdog->pm_notifier);
+ goto svc_watchdog_create_err;
+ }
+ return retval;
+
+svc_watchdog_create_err:
+ svc->watchdog = NULL;
+ kfree(watchdog);
+
+ return retval;
+}
+
+void gb_svc_watchdog_destroy(struct gb_svc *svc)
+{
+ struct gb_svc_watchdog *watchdog = svc->watchdog;
+
+ if (!watchdog)
+ return;
+
+ unregister_pm_notifier(&watchdog->pm_notifier);
+ gb_svc_watchdog_disable(svc);
+ svc->watchdog = NULL;
+ kfree(watchdog);
+}
+
+bool gb_svc_watchdog_enabled(struct gb_svc *svc)
+{
+ if (!svc || !svc->watchdog)
+ return false;
+ return svc->watchdog->enabled;
+}
+
+int gb_svc_watchdog_enable(struct gb_svc *svc)
+{
+ struct gb_svc_watchdog *watchdog;
+
+ if (!svc->watchdog)
+ return -ENODEV;
+
+ watchdog = svc->watchdog;
+ if (watchdog->enabled)
+ return 0;
+
+ watchdog->enabled = true;
+ schedule_delayed_work(&watchdog->work, SVC_WATCHDOG_PERIOD);
+ return 0;
+}
+
+int gb_svc_watchdog_disable(struct gb_svc *svc)
+{
+ struct gb_svc_watchdog *watchdog;
+
+ if (!svc->watchdog)
+ return -ENODEV;
+
+ watchdog = svc->watchdog;
+ if (!watchdog->enabled)
+ return 0;
+
+ watchdog->enabled = false;
+ cancel_delayed_work_sync(&watchdog->work);
+ return 0;
+}
diff --git a/drivers/staging/greybus/timesync.c b/drivers/staging/greybus/timesync.c
new file mode 100644
index 000000000000..2e68af7dea6d
--- /dev/null
+++ b/drivers/staging/greybus/timesync.c
@@ -0,0 +1,1357 @@
+/*
+ * TimeSync API driver.
+ *
+ * Copyright 2016 Google Inc.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+#include <linux/debugfs.h>
+#include <linux/hrtimer.h>
+#include "greybus.h"
+#include "timesync.h"
+#include "greybus_trace.h"
+
+/*
+ * Minimum inter-strobe value of one millisecond is chosen because it
+ * just-about fits the common definition of a jiffy.
+ *
+ * Maximum value OTOH is constrained by the number of bits the SVC can fit
+ * into a 16 bit up-counter. The SVC configures the timer in microseconds
+ * so the maximum allowable value is 65535 microseconds. We clip that value
+ * to 10000 microseconds for the sake of using nice round base 10 numbers
+ * and since right-now there's no imaginable use-case requiring anything
+ * other than a one millisecond inter-strobe time, let alone something
+ * higher than ten milliseconds.
+ */
+#define GB_TIMESYNC_STROBE_DELAY_US 1000
+#define GB_TIMESYNC_DEFAULT_OFFSET_US 1000
+
+/* Work queue timers long, short and SVC strobe timeout */
+#define GB_TIMESYNC_DELAYED_WORK_LONG msecs_to_jiffies(10)
+#define GB_TIMESYNC_DELAYED_WORK_SHORT msecs_to_jiffies(1)
+#define GB_TIMESYNC_MAX_WAIT_SVC msecs_to_jiffies(5000)
+#define GB_TIMESYNC_KTIME_UPDATE msecs_to_jiffies(1000)
+#define GB_TIMESYNC_MAX_KTIME_CONVERSION 15
+
+/* Maximum number of times we'll retry a failed synchronous sync */
+#define GB_TIMESYNC_MAX_RETRIES 5
+
+/* Reported nanoseconds/femtoseconds per clock */
+static u64 gb_timesync_ns_per_clock;
+static u64 gb_timesync_fs_per_clock;
+
+/* Maximum difference we will accept converting FrameTime to ktime */
+static u32 gb_timesync_max_ktime_diff;
+
+/* Reported clock rate */
+static unsigned long gb_timesync_clock_rate;
+
+/* Workqueue */
+static void gb_timesync_worker(struct work_struct *work);
+
+/* List of SVCs with one FrameTime per SVC */
+static LIST_HEAD(gb_timesync_svc_list);
+
+/* Synchronize parallel contexts accessing a valid timesync_svc pointer */
+static DEFINE_MUTEX(gb_timesync_svc_list_mutex);
+
+/* Structure to convert from FrameTime to timespec/ktime */
+struct gb_timesync_frame_time_data {
+ u64 frame_time;
+ struct timespec ts;
+};
+
+struct gb_timesync_svc {
+ struct list_head list;
+ struct list_head interface_list;
+ struct gb_svc *svc;
+ struct gb_timesync_host_device *timesync_hd;
+
+ spinlock_t spinlock; /* Per SVC spinlock to sync with ISR */
+ struct mutex mutex; /* Per SVC mutex for regular synchronization */
+
+ struct dentry *frame_time_dentry;
+ struct dentry *frame_ktime_dentry;
+ struct workqueue_struct *work_queue;
+ wait_queue_head_t wait_queue;
+ struct delayed_work delayed_work;
+ struct timer_list ktime_timer;
+
+ /* The current local FrameTime */
+ u64 frame_time_offset;
+ struct gb_timesync_frame_time_data strobe_data[GB_TIMESYNC_MAX_STROBES];
+ struct gb_timesync_frame_time_data ktime_data;
+
+ /* The SVC FrameTime and relative AP FrameTime @ last TIMESYNC_PING */
+ u64 svc_ping_frame_time;
+ u64 ap_ping_frame_time;
+
+ /* Transitory settings */
+ u32 strobe_mask;
+ bool offset_down;
+ bool print_ping;
+ bool capture_ping;
+ int strobe;
+
+ /* Current state */
+ int state;
+};
+
+struct gb_timesync_host_device {
+ struct list_head list;
+ struct gb_host_device *hd;
+ u64 ping_frame_time;
+};
+
+struct gb_timesync_interface {
+ struct list_head list;
+ struct gb_interface *interface;
+ u64 ping_frame_time;
+};
+
+enum gb_timesync_state {
+ GB_TIMESYNC_STATE_INVALID = 0,
+ GB_TIMESYNC_STATE_INACTIVE = 1,
+ GB_TIMESYNC_STATE_INIT = 2,
+ GB_TIMESYNC_STATE_WAIT_SVC = 3,
+ GB_TIMESYNC_STATE_AUTHORITATIVE = 4,
+ GB_TIMESYNC_STATE_PING = 5,
+ GB_TIMESYNC_STATE_ACTIVE = 6,
+};
+
+static void gb_timesync_ktime_timer_fn(unsigned long data);
+
+static u64 gb_timesync_adjust_count(struct gb_timesync_svc *timesync_svc,
+ u64 counts)
+{
+ if (timesync_svc->offset_down)
+ return counts - timesync_svc->frame_time_offset;
+ else
+ return counts + timesync_svc->frame_time_offset;
+}
+
+/*
+ * This function provides the authoritative FrameTime to a calling function. It
+ * is designed to be lockless and should remain that way the caller is assumed
+ * to be state-aware.
+ */
+static u64 __gb_timesync_get_frame_time(struct gb_timesync_svc *timesync_svc)
+{
+ u64 clocks = gb_timesync_platform_get_counter();
+
+ return gb_timesync_adjust_count(timesync_svc, clocks);
+}
+
+static void gb_timesync_schedule_svc_timeout(struct gb_timesync_svc
+ *timesync_svc)
+{
+ queue_delayed_work(timesync_svc->work_queue,
+ &timesync_svc->delayed_work,
+ GB_TIMESYNC_MAX_WAIT_SVC);
+}
+
+static void gb_timesync_set_state(struct gb_timesync_svc *timesync_svc,
+ int state)
+{
+ switch (state) {
+ case GB_TIMESYNC_STATE_INVALID:
+ timesync_svc->state = state;
+ wake_up(&timesync_svc->wait_queue);
+ break;
+ case GB_TIMESYNC_STATE_INACTIVE:
+ timesync_svc->state = state;
+ wake_up(&timesync_svc->wait_queue);
+ break;
+ case GB_TIMESYNC_STATE_INIT:
+ if (timesync_svc->state != GB_TIMESYNC_STATE_INVALID) {
+ timesync_svc->strobe = 0;
+ timesync_svc->frame_time_offset = 0;
+ timesync_svc->state = state;
+ cancel_delayed_work(&timesync_svc->delayed_work);
+ queue_delayed_work(timesync_svc->work_queue,
+ &timesync_svc->delayed_work,
+ GB_TIMESYNC_DELAYED_WORK_LONG);
+ }
+ break;
+ case GB_TIMESYNC_STATE_WAIT_SVC:
+ if (timesync_svc->state == GB_TIMESYNC_STATE_INIT)
+ timesync_svc->state = state;
+ break;
+ case GB_TIMESYNC_STATE_AUTHORITATIVE:
+ if (timesync_svc->state == GB_TIMESYNC_STATE_WAIT_SVC) {
+ timesync_svc->state = state;
+ cancel_delayed_work(&timesync_svc->delayed_work);
+ queue_delayed_work(timesync_svc->work_queue,
+ &timesync_svc->delayed_work, 0);
+ }
+ break;
+ case GB_TIMESYNC_STATE_PING:
+ if (timesync_svc->state == GB_TIMESYNC_STATE_ACTIVE) {
+ timesync_svc->state = state;
+ queue_delayed_work(timesync_svc->work_queue,
+ &timesync_svc->delayed_work,
+ GB_TIMESYNC_DELAYED_WORK_SHORT);
+ }
+ break;
+ case GB_TIMESYNC_STATE_ACTIVE:
+ if (timesync_svc->state == GB_TIMESYNC_STATE_AUTHORITATIVE ||
+ timesync_svc->state == GB_TIMESYNC_STATE_PING) {
+ timesync_svc->state = state;
+ wake_up(&timesync_svc->wait_queue);
+ }
+ break;
+ }
+
+ if (WARN_ON(timesync_svc->state != state)) {
+ pr_err("Invalid state transition %d=>%d\n",
+ timesync_svc->state, state);
+ }
+}
+
+static void gb_timesync_set_state_atomic(struct gb_timesync_svc *timesync_svc,
+ int state)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&timesync_svc->spinlock, flags);
+ gb_timesync_set_state(timesync_svc, state);
+ spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
+}
+
+static u64 gb_timesync_diff(u64 x, u64 y)
+{
+ if (x > y)
+ return x - y;
+ else
+ return y - x;
+}
+
+static void gb_timesync_adjust_to_svc(struct gb_timesync_svc *svc,
+ u64 svc_frame_time, u64 ap_frame_time)
+{
+ if (svc_frame_time > ap_frame_time) {
+ svc->frame_time_offset = svc_frame_time - ap_frame_time;
+ svc->offset_down = false;
+ } else {
+ svc->frame_time_offset = ap_frame_time - svc_frame_time;
+ svc->offset_down = true;
+ }
+}
+
+/*
+ * Associate a FrameTime with a ktime timestamp represented as struct timespec
+ * Requires the calling context to hold timesync_svc->mutex
+ */
+static void gb_timesync_store_ktime(struct gb_timesync_svc *timesync_svc,
+ struct timespec ts, u64 frame_time)
+{
+ timesync_svc->ktime_data.ts = ts;
+ timesync_svc->ktime_data.frame_time = frame_time;
+}
+
+/*
+ * Find the two pulses that best-match our expected inter-strobe gap and
+ * then calculate the difference between the SVC time at the second pulse
+ * to the local time at the second pulse.
+ */
+static void gb_timesync_collate_frame_time(struct gb_timesync_svc *timesync_svc,
+ u64 *frame_time)
+{
+ int i = 0;
+ u64 delta, ap_frame_time;
+ u64 strobe_delay_ns = GB_TIMESYNC_STROBE_DELAY_US * NSEC_PER_USEC;
+ u64 least = 0;
+
+ for (i = 1; i < GB_TIMESYNC_MAX_STROBES; i++) {
+ delta = timesync_svc->strobe_data[i].frame_time -
+ timesync_svc->strobe_data[i - 1].frame_time;
+ delta *= gb_timesync_ns_per_clock;
+ delta = gb_timesync_diff(delta, strobe_delay_ns);
+
+ if (!least || delta < least) {
+ least = delta;
+ gb_timesync_adjust_to_svc(timesync_svc, frame_time[i],
+ timesync_svc->strobe_data[i].frame_time);
+
+ ap_frame_time = timesync_svc->strobe_data[i].frame_time;
+ ap_frame_time = gb_timesync_adjust_count(timesync_svc,
+ ap_frame_time);
+ gb_timesync_store_ktime(timesync_svc,
+ timesync_svc->strobe_data[i].ts,
+ ap_frame_time);
+
+ pr_debug("adjust %s local %llu svc %llu delta %llu\n",
+ timesync_svc->offset_down ? "down" : "up",
+ timesync_svc->strobe_data[i].frame_time,
+ frame_time[i], delta);
+ }
+ }
+}
+
+static void gb_timesync_teardown(struct gb_timesync_svc *timesync_svc)
+{
+ struct gb_timesync_interface *timesync_interface;
+ struct gb_svc *svc = timesync_svc->svc;
+ struct gb_interface *interface;
+ struct gb_host_device *hd;
+ int ret;
+
+ list_for_each_entry(timesync_interface,
+ &timesync_svc->interface_list, list) {
+ interface = timesync_interface->interface;
+ ret = gb_interface_timesync_disable(interface);
+ if (ret) {
+ dev_err(&interface->dev,
+ "interface timesync_disable %d\n", ret);
+ }
+ }
+
+ hd = timesync_svc->timesync_hd->hd;
+ ret = hd->driver->timesync_disable(hd);
+ if (ret < 0) {
+ dev_err(&hd->dev, "host timesync_disable %d\n",
+ ret);
+ }
+
+ gb_svc_timesync_wake_pins_release(svc);
+ gb_svc_timesync_disable(svc);
+ gb_timesync_platform_unlock_bus();
+
+ gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_INACTIVE);
+}
+
+static void gb_timesync_platform_lock_bus_fail(struct gb_timesync_svc
+ *timesync_svc, int ret)
+{
+ if (ret == -EAGAIN) {
+ gb_timesync_set_state(timesync_svc, timesync_svc->state);
+ } else {
+ pr_err("Failed to lock timesync bus %d\n", ret);
+ gb_timesync_set_state(timesync_svc, GB_TIMESYNC_STATE_INACTIVE);
+ }
+}
+
+static void gb_timesync_enable(struct gb_timesync_svc *timesync_svc)
+{
+ struct gb_svc *svc = timesync_svc->svc;
+ struct gb_host_device *hd;
+ struct gb_timesync_interface *timesync_interface;
+ struct gb_interface *interface;
+ u64 init_frame_time;
+ unsigned long clock_rate = gb_timesync_clock_rate;
+ int ret;
+
+ /*
+ * Get access to the wake pins in the AP and SVC
+ * Release these pins either in gb_timesync_teardown() or in
+ * gb_timesync_authoritative()
+ */
+ ret = gb_timesync_platform_lock_bus(timesync_svc);
+ if (ret < 0) {
+ gb_timesync_platform_lock_bus_fail(timesync_svc, ret);
+ return;
+ }
+ ret = gb_svc_timesync_wake_pins_acquire(svc, timesync_svc->strobe_mask);
+ if (ret) {
+ dev_err(&svc->dev,
+ "gb_svc_timesync_wake_pins_acquire %d\n", ret);
+ gb_timesync_teardown(timesync_svc);
+ return;
+ }
+
+ /* Choose an initial time in the future */
+ init_frame_time = __gb_timesync_get_frame_time(timesync_svc) + 100000UL;
+
+ /* Send enable command to all relevant participants */
+ list_for_each_entry(timesync_interface, &timesync_svc->interface_list,
+ list) {
+ interface = timesync_interface->interface;
+ ret = gb_interface_timesync_enable(interface,
+ GB_TIMESYNC_MAX_STROBES,
+ init_frame_time,
+ GB_TIMESYNC_STROBE_DELAY_US,
+ clock_rate);
+ if (ret) {
+ dev_err(&interface->dev,
+ "interface timesync_enable %d\n", ret);
+ }
+ }
+
+ hd = timesync_svc->timesync_hd->hd;
+ ret = hd->driver->timesync_enable(hd, GB_TIMESYNC_MAX_STROBES,
+ init_frame_time,
+ GB_TIMESYNC_STROBE_DELAY_US,
+ clock_rate);
+ if (ret < 0) {
+ dev_err(&hd->dev, "host timesync_enable %d\n",
+ ret);
+ }
+
+ gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_WAIT_SVC);
+ ret = gb_svc_timesync_enable(svc, GB_TIMESYNC_MAX_STROBES,
+ init_frame_time,
+ GB_TIMESYNC_STROBE_DELAY_US,
+ clock_rate);
+ if (ret) {
+ dev_err(&svc->dev,
+ "gb_svc_timesync_enable %d\n", ret);
+ gb_timesync_teardown(timesync_svc);
+ return;
+ }
+
+ /* Schedule a timeout waiting for SVC to complete strobing */
+ gb_timesync_schedule_svc_timeout(timesync_svc);
+}
+
+static void gb_timesync_authoritative(struct gb_timesync_svc *timesync_svc)
+{
+ struct gb_svc *svc = timesync_svc->svc;
+ struct gb_host_device *hd;
+ struct gb_timesync_interface *timesync_interface;
+ struct gb_interface *interface;
+ u64 svc_frame_time[GB_TIMESYNC_MAX_STROBES];
+ int ret;
+
+ /* Get authoritative time from SVC and adjust local clock */
+ ret = gb_svc_timesync_authoritative(svc, svc_frame_time);
+ if (ret) {
+ dev_err(&svc->dev,
+ "gb_svc_timesync_authoritative %d\n", ret);
+ gb_timesync_teardown(timesync_svc);
+ return;
+ }
+ gb_timesync_collate_frame_time(timesync_svc, svc_frame_time);
+
+ /* Transmit authoritative time to downstream slaves */
+ hd = timesync_svc->timesync_hd->hd;
+ ret = hd->driver->timesync_authoritative(hd, svc_frame_time);
+ if (ret < 0)
+ dev_err(&hd->dev, "host timesync_authoritative %d\n", ret);
+
+ list_for_each_entry(timesync_interface,
+ &timesync_svc->interface_list, list) {
+ interface = timesync_interface->interface;
+ ret = gb_interface_timesync_authoritative(
+ interface,
+ svc_frame_time);
+ if (ret) {
+ dev_err(&interface->dev,
+ "interface timesync_authoritative %d\n", ret);
+ }
+ }
+
+ /* Release wake pins */
+ gb_svc_timesync_wake_pins_release(svc);
+ gb_timesync_platform_unlock_bus();
+
+ /* Transition to state ACTIVE */
+ gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_ACTIVE);
+
+ /* Schedule a ping to verify the synchronized system time */
+ timesync_svc->print_ping = true;
+ gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_PING);
+}
+
+static int __gb_timesync_get_status(struct gb_timesync_svc *timesync_svc)
+{
+ int ret = -EINVAL;
+
+ switch (timesync_svc->state) {
+ case GB_TIMESYNC_STATE_INVALID:
+ case GB_TIMESYNC_STATE_INACTIVE:
+ ret = -ENODEV;
+ break;
+ case GB_TIMESYNC_STATE_INIT:
+ case GB_TIMESYNC_STATE_WAIT_SVC:
+ case GB_TIMESYNC_STATE_AUTHORITATIVE:
+ ret = -EAGAIN;
+ break;
+ case GB_TIMESYNC_STATE_PING:
+ case GB_TIMESYNC_STATE_ACTIVE:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+/*
+ * This routine takes a FrameTime and derives the difference with-respect
+ * to a reference FrameTime/ktime pair. It then returns the calculated
+ * ktime based on the difference between the supplied FrameTime and
+ * the reference FrameTime.
+ *
+ * The time difference is calculated to six decimal places. Taking 19.2MHz
+ * as an example this means we have 52.083333~ nanoseconds per clock or
+ * 52083333~ femtoseconds per clock.
+ *
+ * Naively taking the count difference and converting to
+ * seconds/nanoseconds would quickly see the 0.0833 component produce
+ * noticeable errors. For example a time difference of one second would
+ * loose 19200000 * 0.08333x nanoseconds or 1.59 seconds.
+ *
+ * In contrast calculating in femtoseconds the same example of 19200000 *
+ * 0.000000083333x nanoseconds per count of error is just 1.59 nanoseconds!
+ *
+ * Continuing the example of 19.2 MHz we cap the maximum error difference
+ * at a worst-case 0.3 microseconds over a potential calculation window of
+ * abount 15 seconds, meaning you can convert a FrameTime that is <= 15
+ * seconds older/younger than the reference time with a maximum error of
+ * 0.2385 useconds. Note 19.2MHz is an example frequency not a requirement.
+ */
+static int gb_timesync_to_timespec(struct gb_timesync_svc *timesync_svc,
+ u64 frame_time, struct timespec *ts)
+{
+ unsigned long flags;
+ u64 delta_fs, counts, sec, nsec;
+ bool add;
+ int ret = 0;
+
+ memset(ts, 0x00, sizeof(*ts));
+ mutex_lock(&timesync_svc->mutex);
+ spin_lock_irqsave(&timesync_svc->spinlock, flags);
+
+ ret = __gb_timesync_get_status(timesync_svc);
+ if (ret)
+ goto done;
+
+ /* Support calculating ktime upwards or downwards from the reference */
+ if (frame_time < timesync_svc->ktime_data.frame_time) {
+ add = false;
+ counts = timesync_svc->ktime_data.frame_time - frame_time;
+ } else {
+ add = true;
+ counts = frame_time - timesync_svc->ktime_data.frame_time;
+ }
+
+ /* Enforce the .23 of a usecond boundary @ 19.2MHz */
+ if (counts > gb_timesync_max_ktime_diff) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ /* Determine the time difference in femtoseconds */
+ delta_fs = counts * gb_timesync_fs_per_clock;
+
+ /* Convert to seconds */
+ sec = delta_fs;
+ do_div(sec, NSEC_PER_SEC);
+ do_div(sec, 1000000UL);
+
+ /* Get the nanosecond remainder */
+ nsec = do_div(delta_fs, sec);
+ do_div(nsec, 1000000UL);
+
+ if (add) {
+ /* Add the calculated offset - overflow nanoseconds upwards */
+ ts->tv_sec = timesync_svc->ktime_data.ts.tv_sec + sec;
+ ts->tv_nsec = timesync_svc->ktime_data.ts.tv_nsec + nsec;
+ if (ts->tv_nsec >= NSEC_PER_SEC) {
+ ts->tv_sec++;
+ ts->tv_nsec -= NSEC_PER_SEC;
+ }
+ } else {
+ /* Subtract the difference over/underflow as necessary */
+ if (nsec > timesync_svc->ktime_data.ts.tv_nsec) {
+ sec++;
+ nsec = nsec + timesync_svc->ktime_data.ts.tv_nsec;
+ nsec = do_div(nsec, NSEC_PER_SEC);
+ } else {
+ nsec = timesync_svc->ktime_data.ts.tv_nsec - nsec;
+ }
+ /* Cannot return a negative second value */
+ if (sec > timesync_svc->ktime_data.ts.tv_sec) {
+ ret = -EINVAL;
+ goto done;
+ }
+ ts->tv_sec = timesync_svc->ktime_data.ts.tv_sec - sec;
+ ts->tv_nsec = nsec;
+ }
+done:
+ spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
+ mutex_unlock(&timesync_svc->mutex);
+ return ret;
+}
+
+static size_t gb_timesync_log_frame_time(struct gb_timesync_svc *timesync_svc,
+ char *buf, size_t buflen)
+{
+ struct gb_svc *svc = timesync_svc->svc;
+ struct gb_host_device *hd;
+ struct gb_timesync_interface *timesync_interface;
+ struct gb_interface *interface;
+ unsigned int len;
+ size_t off;
+
+ /* AP/SVC */
+ off = snprintf(buf, buflen, "%s frametime: ap=%llu %s=%llu ",
+ greybus_bus_type.name,
+ timesync_svc->ap_ping_frame_time, dev_name(&svc->dev),
+ timesync_svc->svc_ping_frame_time);
+ len = buflen - off;
+
+ /* APB/GPB */
+ if (len < buflen) {
+ hd = timesync_svc->timesync_hd->hd;
+ off += snprintf(&buf[off], len, "%s=%llu ", dev_name(&hd->dev),
+ timesync_svc->timesync_hd->ping_frame_time);
+ len = buflen - off;
+ }
+
+ list_for_each_entry(timesync_interface,
+ &timesync_svc->interface_list, list) {
+ if (len < buflen) {
+ interface = timesync_interface->interface;
+ off += snprintf(&buf[off], len, "%s=%llu ",
+ dev_name(&interface->dev),
+ timesync_interface->ping_frame_time);
+ len = buflen - off;
+ }
+ }
+ if (len < buflen)
+ off += snprintf(&buf[off], len, "\n");
+ return off;
+}
+
+static size_t gb_timesync_log_frame_ktime(struct gb_timesync_svc *timesync_svc,
+ char *buf, size_t buflen)
+{
+ struct gb_svc *svc = timesync_svc->svc;
+ struct gb_host_device *hd;
+ struct gb_timesync_interface *timesync_interface;
+ struct gb_interface *interface;
+ struct timespec ts;
+ unsigned int len;
+ size_t off;
+
+ /* AP */
+ gb_timesync_to_timespec(timesync_svc, timesync_svc->ap_ping_frame_time,
+ &ts);
+ off = snprintf(buf, buflen, "%s frametime: ap=%lu.%lu ",
+ greybus_bus_type.name, ts.tv_sec, ts.tv_nsec);
+ len = buflen - off;
+ if (len >= buflen)
+ goto done;
+
+ /* SVC */
+ gb_timesync_to_timespec(timesync_svc, timesync_svc->svc_ping_frame_time,
+ &ts);
+ off += snprintf(&buf[off], len, "%s=%lu.%lu ", dev_name(&svc->dev),
+ ts.tv_sec, ts.tv_nsec);
+ len = buflen - off;
+ if (len >= buflen)
+ goto done;
+
+ /* APB/GPB */
+ hd = timesync_svc->timesync_hd->hd;
+ gb_timesync_to_timespec(timesync_svc,
+ timesync_svc->timesync_hd->ping_frame_time,
+ &ts);
+ off += snprintf(&buf[off], len, "%s=%lu.%lu ",
+ dev_name(&hd->dev),
+ ts.tv_sec, ts.tv_nsec);
+ len = buflen - off;
+ if (len >= buflen)
+ goto done;
+
+ list_for_each_entry(timesync_interface,
+ &timesync_svc->interface_list, list) {
+ interface = timesync_interface->interface;
+ gb_timesync_to_timespec(timesync_svc,
+ timesync_interface->ping_frame_time,
+ &ts);
+ off += snprintf(&buf[off], len, "%s=%lu.%lu ",
+ dev_name(&interface->dev),
+ ts.tv_sec, ts.tv_nsec);
+ len = buflen - off;
+ if (len >= buflen)
+ goto done;
+ }
+ off += snprintf(&buf[off], len, "\n");
+done:
+ return off;
+}
+
+/*
+ * Send an SVC initiated wake 'ping' to each TimeSync participant.
+ * Get the FrameTime from each participant associated with the wake
+ * ping.
+ */
+static void gb_timesync_ping(struct gb_timesync_svc *timesync_svc)
+{
+ struct gb_svc *svc = timesync_svc->svc;
+ struct gb_host_device *hd;
+ struct gb_timesync_interface *timesync_interface;
+ struct gb_control *control;
+ u64 *ping_frame_time;
+ int ret;
+
+ /* Get access to the wake pins in the AP and SVC */
+ ret = gb_timesync_platform_lock_bus(timesync_svc);
+ if (ret < 0) {
+ gb_timesync_platform_lock_bus_fail(timesync_svc, ret);
+ return;
+ }
+ ret = gb_svc_timesync_wake_pins_acquire(svc, timesync_svc->strobe_mask);
+ if (ret) {
+ dev_err(&svc->dev,
+ "gb_svc_timesync_wake_pins_acquire %d\n", ret);
+ gb_timesync_teardown(timesync_svc);
+ return;
+ }
+
+ /* Have SVC generate a timesync ping */
+ timesync_svc->capture_ping = true;
+ timesync_svc->svc_ping_frame_time = 0;
+ ret = gb_svc_timesync_ping(svc, &timesync_svc->svc_ping_frame_time);
+ timesync_svc->capture_ping = false;
+ if (ret) {
+ dev_err(&svc->dev,
+ "gb_svc_timesync_ping %d\n", ret);
+ gb_timesync_teardown(timesync_svc);
+ return;
+ }
+
+ /* Get the ping FrameTime from each APB/GPB */
+ hd = timesync_svc->timesync_hd->hd;
+ timesync_svc->timesync_hd->ping_frame_time = 0;
+ ret = hd->driver->timesync_get_last_event(hd,
+ &timesync_svc->timesync_hd->ping_frame_time);
+ if (ret)
+ dev_err(&hd->dev, "host timesync_get_last_event %d\n", ret);
+
+ list_for_each_entry(timesync_interface,
+ &timesync_svc->interface_list, list) {
+ control = timesync_interface->interface->control;
+ timesync_interface->ping_frame_time = 0;
+ ping_frame_time = &timesync_interface->ping_frame_time;
+ ret = gb_control_timesync_get_last_event(control,
+ ping_frame_time);
+ if (ret) {
+ dev_err(&timesync_interface->interface->dev,
+ "gb_control_timesync_get_last_event %d\n", ret);
+ }
+ }
+
+ /* Ping success - move to timesync active */
+ gb_svc_timesync_wake_pins_release(svc);
+ gb_timesync_platform_unlock_bus();
+ gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_ACTIVE);
+}
+
+static void gb_timesync_log_ping_time(struct gb_timesync_svc *timesync_svc)
+{
+ char *buf;
+
+ if (!timesync_svc->print_ping)
+ return;
+
+ buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (buf) {
+ gb_timesync_log_frame_time(timesync_svc, buf, PAGE_SIZE);
+ dev_dbg(&timesync_svc->svc->dev, "%s", buf);
+ kfree(buf);
+ }
+}
+
+/*
+ * Perform the actual work of scheduled TimeSync logic.
+ */
+static void gb_timesync_worker(struct work_struct *work)
+{
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ struct gb_timesync_svc *timesync_svc =
+ container_of(delayed_work, struct gb_timesync_svc, delayed_work);
+
+ mutex_lock(&timesync_svc->mutex);
+
+ switch (timesync_svc->state) {
+ case GB_TIMESYNC_STATE_INIT:
+ gb_timesync_enable(timesync_svc);
+ break;
+
+ case GB_TIMESYNC_STATE_WAIT_SVC:
+ dev_err(&timesync_svc->svc->dev,
+ "timeout SVC strobe completion %d/%d\n",
+ timesync_svc->strobe, GB_TIMESYNC_MAX_STROBES);
+ gb_timesync_teardown(timesync_svc);
+ break;
+
+ case GB_TIMESYNC_STATE_AUTHORITATIVE:
+ gb_timesync_authoritative(timesync_svc);
+ break;
+
+ case GB_TIMESYNC_STATE_PING:
+ gb_timesync_ping(timesync_svc);
+ gb_timesync_log_ping_time(timesync_svc);
+ break;
+
+ default:
+ pr_err("Invalid state %d for delayed work\n",
+ timesync_svc->state);
+ break;
+ }
+
+ mutex_unlock(&timesync_svc->mutex);
+}
+
+/*
+ * Schedule a new TimeSync INIT or PING operation serialized w/r to
+ * gb_timesync_worker().
+ */
+static int gb_timesync_schedule(struct gb_timesync_svc *timesync_svc, int state)
+{
+ int ret = 0;
+
+ if (state != GB_TIMESYNC_STATE_INIT && state != GB_TIMESYNC_STATE_PING)
+ return -EINVAL;
+
+ mutex_lock(&timesync_svc->mutex);
+ if (timesync_svc->state != GB_TIMESYNC_STATE_INVALID) {
+ gb_timesync_set_state_atomic(timesync_svc, state);
+ } else {
+ ret = -ENODEV;
+ }
+ mutex_unlock(&timesync_svc->mutex);
+ return ret;
+}
+
+static int __gb_timesync_schedule_synchronous(
+ struct gb_timesync_svc *timesync_svc, int state)
+{
+ unsigned long flags;
+ int ret;
+
+ ret = gb_timesync_schedule(timesync_svc, state);
+ if (ret)
+ return ret;
+
+ ret = wait_event_interruptible(timesync_svc->wait_queue,
+ (timesync_svc->state == GB_TIMESYNC_STATE_ACTIVE ||
+ timesync_svc->state == GB_TIMESYNC_STATE_INACTIVE ||
+ timesync_svc->state == GB_TIMESYNC_STATE_INVALID));
+ if (ret)
+ return ret;
+
+ mutex_lock(&timesync_svc->mutex);
+ spin_lock_irqsave(&timesync_svc->spinlock, flags);
+
+ ret = __gb_timesync_get_status(timesync_svc);
+
+ spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
+ mutex_unlock(&timesync_svc->mutex);
+
+ return ret;
+}
+
+static struct gb_timesync_svc *gb_timesync_find_timesync_svc(
+ struct gb_host_device *hd)
+{
+ struct gb_timesync_svc *timesync_svc;
+
+ list_for_each_entry(timesync_svc, &gb_timesync_svc_list, list) {
+ if (timesync_svc->svc == hd->svc)
+ return timesync_svc;
+ }
+ return NULL;
+}
+
+static struct gb_timesync_interface *gb_timesync_find_timesync_interface(
+ struct gb_timesync_svc *timesync_svc,
+ struct gb_interface *interface)
+{
+ struct gb_timesync_interface *timesync_interface;
+
+ list_for_each_entry(timesync_interface, &timesync_svc->interface_list, list) {
+ if (timesync_interface->interface == interface)
+ return timesync_interface;
+ }
+ return NULL;
+}
+
+int gb_timesync_schedule_synchronous(struct gb_interface *interface)
+{
+ int ret;
+ struct gb_timesync_svc *timesync_svc;
+ int retries;
+
+ if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC))
+ return 0;
+
+ mutex_lock(&gb_timesync_svc_list_mutex);
+ for (retries = 0; retries < GB_TIMESYNC_MAX_RETRIES; retries++) {
+ timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
+ if (!timesync_svc) {
+ ret = -ENODEV;
+ goto done;
+ }
+
+ ret = __gb_timesync_schedule_synchronous(timesync_svc,
+ GB_TIMESYNC_STATE_INIT);
+ if (!ret)
+ break;
+ }
+ if (ret && retries == GB_TIMESYNC_MAX_RETRIES)
+ ret = -ETIMEDOUT;
+done:
+ mutex_unlock(&gb_timesync_svc_list_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_timesync_schedule_synchronous);
+
+void gb_timesync_schedule_asynchronous(struct gb_interface *interface)
+{
+ struct gb_timesync_svc *timesync_svc;
+
+ if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC))
+ return;
+
+ mutex_lock(&gb_timesync_svc_list_mutex);
+ timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
+ if (!timesync_svc)
+ goto done;
+
+ gb_timesync_schedule(timesync_svc, GB_TIMESYNC_STATE_INIT);
+done:
+ mutex_unlock(&gb_timesync_svc_list_mutex);
+ return;
+}
+EXPORT_SYMBOL_GPL(gb_timesync_schedule_asynchronous);
+
+static ssize_t gb_timesync_ping_read(struct file *file, char __user *ubuf,
+ size_t len, loff_t *offset, bool ktime)
+{
+ struct gb_timesync_svc *timesync_svc = file->f_inode->i_private;
+ char *buf;
+ ssize_t ret = 0;
+
+ mutex_lock(&gb_timesync_svc_list_mutex);
+ mutex_lock(&timesync_svc->mutex);
+ if (list_empty(&timesync_svc->interface_list))
+ ret = -ENODEV;
+ timesync_svc->print_ping = false;
+ mutex_unlock(&timesync_svc->mutex);
+ if (ret)
+ goto done;
+
+ ret = __gb_timesync_schedule_synchronous(timesync_svc,
+ GB_TIMESYNC_STATE_PING);
+ if (ret)
+ goto done;
+
+ buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ if (ktime)
+ ret = gb_timesync_log_frame_ktime(timesync_svc, buf, PAGE_SIZE);
+ else
+ ret = gb_timesync_log_frame_time(timesync_svc, buf, PAGE_SIZE);
+ if (ret > 0)
+ ret = simple_read_from_buffer(ubuf, len, offset, buf, ret);
+ kfree(buf);
+done:
+ mutex_unlock(&gb_timesync_svc_list_mutex);
+ return ret;
+}
+
+static ssize_t gb_timesync_ping_read_frame_time(struct file *file,
+ char __user *buf,
+ size_t len, loff_t *offset)
+{
+ return gb_timesync_ping_read(file, buf, len, offset, false);
+}
+
+static ssize_t gb_timesync_ping_read_frame_ktime(struct file *file,
+ char __user *buf,
+ size_t len, loff_t *offset)
+{
+ return gb_timesync_ping_read(file, buf, len, offset, true);
+}
+
+static const struct file_operations gb_timesync_debugfs_frame_time_ops = {
+ .read = gb_timesync_ping_read_frame_time,
+};
+
+static const struct file_operations gb_timesync_debugfs_frame_ktime_ops = {
+ .read = gb_timesync_ping_read_frame_ktime,
+};
+
+static int gb_timesync_hd_add(struct gb_timesync_svc *timesync_svc,
+ struct gb_host_device *hd)
+{
+ struct gb_timesync_host_device *timesync_hd;
+
+ timesync_hd = kzalloc(sizeof(*timesync_hd), GFP_KERNEL);
+ if (!timesync_hd)
+ return -ENOMEM;
+
+ WARN_ON(timesync_svc->timesync_hd);
+ timesync_hd->hd = hd;
+ timesync_svc->timesync_hd = timesync_hd;
+
+ return 0;
+}
+
+static void gb_timesync_hd_remove(struct gb_timesync_svc *timesync_svc,
+ struct gb_host_device *hd)
+{
+ if (timesync_svc->timesync_hd->hd == hd) {
+ kfree(timesync_svc->timesync_hd);
+ timesync_svc->timesync_hd = NULL;
+ return;
+ }
+ WARN_ON(1);
+}
+
+int gb_timesync_svc_add(struct gb_svc *svc)
+{
+ struct gb_timesync_svc *timesync_svc;
+ int ret;
+
+ timesync_svc = kzalloc(sizeof(*timesync_svc), GFP_KERNEL);
+ if (!timesync_svc)
+ return -ENOMEM;
+
+ timesync_svc->work_queue =
+ create_singlethread_workqueue("gb-timesync-work_queue");
+
+ if (!timesync_svc->work_queue) {
+ kfree(timesync_svc);
+ return -ENOMEM;
+ }
+
+ mutex_lock(&gb_timesync_svc_list_mutex);
+ INIT_LIST_HEAD(&timesync_svc->interface_list);
+ INIT_DELAYED_WORK(&timesync_svc->delayed_work, gb_timesync_worker);
+ mutex_init(&timesync_svc->mutex);
+ spin_lock_init(&timesync_svc->spinlock);
+ init_waitqueue_head(&timesync_svc->wait_queue);
+
+ timesync_svc->svc = svc;
+ timesync_svc->frame_time_offset = 0;
+ timesync_svc->capture_ping = false;
+ gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_INACTIVE);
+
+ timesync_svc->frame_time_dentry =
+ debugfs_create_file("frame-time", S_IRUGO, svc->debugfs_dentry,
+ timesync_svc,
+ &gb_timesync_debugfs_frame_time_ops);
+ timesync_svc->frame_ktime_dentry =
+ debugfs_create_file("frame-ktime", S_IRUGO, svc->debugfs_dentry,
+ timesync_svc,
+ &gb_timesync_debugfs_frame_ktime_ops);
+
+ list_add(&timesync_svc->list, &gb_timesync_svc_list);
+ ret = gb_timesync_hd_add(timesync_svc, svc->hd);
+ if (ret) {
+ list_del(&timesync_svc->list);
+ debugfs_remove(timesync_svc->frame_ktime_dentry);
+ debugfs_remove(timesync_svc->frame_time_dentry);
+ destroy_workqueue(timesync_svc->work_queue);
+ kfree(timesync_svc);
+ goto done;
+ }
+
+ init_timer(&timesync_svc->ktime_timer);
+ timesync_svc->ktime_timer.function = gb_timesync_ktime_timer_fn;
+ timesync_svc->ktime_timer.expires = jiffies + GB_TIMESYNC_KTIME_UPDATE;
+ timesync_svc->ktime_timer.data = (unsigned long)timesync_svc;
+ add_timer(&timesync_svc->ktime_timer);
+done:
+ mutex_unlock(&gb_timesync_svc_list_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_timesync_svc_add);
+
+void gb_timesync_svc_remove(struct gb_svc *svc)
+{
+ struct gb_timesync_svc *timesync_svc;
+ struct gb_timesync_interface *timesync_interface;
+ struct gb_timesync_interface *next;
+
+ mutex_lock(&gb_timesync_svc_list_mutex);
+ timesync_svc = gb_timesync_find_timesync_svc(svc->hd);
+ if (!timesync_svc)
+ goto done;
+
+ cancel_delayed_work_sync(&timesync_svc->delayed_work);
+
+ mutex_lock(&timesync_svc->mutex);
+
+ gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_INVALID);
+ del_timer_sync(&timesync_svc->ktime_timer);
+ gb_timesync_teardown(timesync_svc);
+
+ gb_timesync_hd_remove(timesync_svc, svc->hd);
+ list_for_each_entry_safe(timesync_interface, next,
+ &timesync_svc->interface_list, list) {
+ list_del(&timesync_interface->list);
+ kfree(timesync_interface);
+ }
+ debugfs_remove(timesync_svc->frame_ktime_dentry);
+ debugfs_remove(timesync_svc->frame_time_dentry);
+ destroy_workqueue(timesync_svc->work_queue);
+ list_del(&timesync_svc->list);
+
+ mutex_unlock(&timesync_svc->mutex);
+
+ kfree(timesync_svc);
+done:
+ mutex_unlock(&gb_timesync_svc_list_mutex);
+}
+EXPORT_SYMBOL_GPL(gb_timesync_svc_remove);
+
+/*
+ * Add a Greybus Interface to the set of TimeSync Interfaces.
+ */
+int gb_timesync_interface_add(struct gb_interface *interface)
+{
+ struct gb_timesync_svc *timesync_svc;
+ struct gb_timesync_interface *timesync_interface;
+ int ret = 0;
+
+ if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC))
+ return 0;
+
+ mutex_lock(&gb_timesync_svc_list_mutex);
+ timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
+ if (!timesync_svc) {
+ ret = -ENODEV;
+ goto done;
+ }
+
+ timesync_interface = kzalloc(sizeof(*timesync_interface), GFP_KERNEL);
+ if (!timesync_interface) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ mutex_lock(&timesync_svc->mutex);
+ timesync_interface->interface = interface;
+ list_add(&timesync_interface->list, &timesync_svc->interface_list);
+ timesync_svc->strobe_mask |= 1 << interface->interface_id;
+ mutex_unlock(&timesync_svc->mutex);
+
+done:
+ mutex_unlock(&gb_timesync_svc_list_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_timesync_interface_add);
+
+/*
+ * Remove a Greybus Interface from the set of TimeSync Interfaces.
+ */
+void gb_timesync_interface_remove(struct gb_interface *interface)
+{
+ struct gb_timesync_svc *timesync_svc;
+ struct gb_timesync_interface *timesync_interface;
+
+ if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC))
+ return;
+
+ mutex_lock(&gb_timesync_svc_list_mutex);
+ timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
+ if (!timesync_svc)
+ goto done;
+
+ timesync_interface = gb_timesync_find_timesync_interface(timesync_svc,
+ interface);
+ if (!timesync_interface)
+ goto done;
+
+ mutex_lock(&timesync_svc->mutex);
+ timesync_svc->strobe_mask &= ~(1 << interface->interface_id);
+ list_del(&timesync_interface->list);
+ kfree(timesync_interface);
+ mutex_unlock(&timesync_svc->mutex);
+done:
+ mutex_unlock(&gb_timesync_svc_list_mutex);
+}
+EXPORT_SYMBOL_GPL(gb_timesync_interface_remove);
+
+/*
+ * Give the authoritative FrameTime to the calling function. Returns zero if we
+ * are not in GB_TIMESYNC_STATE_ACTIVE.
+ */
+static u64 gb_timesync_get_frame_time(struct gb_timesync_svc *timesync_svc)
+{
+ unsigned long flags;
+ u64 ret;
+
+ spin_lock_irqsave(&timesync_svc->spinlock, flags);
+ if (timesync_svc->state == GB_TIMESYNC_STATE_ACTIVE)
+ ret = __gb_timesync_get_frame_time(timesync_svc);
+ else
+ ret = 0;
+ spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
+ return ret;
+}
+
+u64 gb_timesync_get_frame_time_by_interface(struct gb_interface *interface)
+{
+ struct gb_timesync_svc *timesync_svc;
+ u64 ret = 0;
+
+ mutex_lock(&gb_timesync_svc_list_mutex);
+ timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
+ if (!timesync_svc)
+ goto done;
+
+ ret = gb_timesync_get_frame_time(timesync_svc);
+done:
+ mutex_unlock(&gb_timesync_svc_list_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_timesync_get_frame_time_by_interface);
+
+u64 gb_timesync_get_frame_time_by_svc(struct gb_svc *svc)
+{
+ struct gb_timesync_svc *timesync_svc;
+ u64 ret = 0;
+
+ mutex_lock(&gb_timesync_svc_list_mutex);
+ timesync_svc = gb_timesync_find_timesync_svc(svc->hd);
+ if (!timesync_svc)
+ goto done;
+
+ ret = gb_timesync_get_frame_time(timesync_svc);
+done:
+ mutex_unlock(&gb_timesync_svc_list_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_timesync_get_frame_time_by_svc);
+
+/* Incrementally updates the conversion base from FrameTime to ktime */
+static void gb_timesync_ktime_timer_fn(unsigned long data)
+{
+ struct gb_timesync_svc *timesync_svc =
+ (struct gb_timesync_svc *)data;
+ unsigned long flags;
+ u64 frame_time;
+ struct timespec ts;
+
+ spin_lock_irqsave(&timesync_svc->spinlock, flags);
+
+ if (timesync_svc->state != GB_TIMESYNC_STATE_ACTIVE)
+ goto done;
+
+ ktime_get_ts(&ts);
+ frame_time = __gb_timesync_get_frame_time(timesync_svc);
+ gb_timesync_store_ktime(timesync_svc, ts, frame_time);
+
+done:
+ spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
+ mod_timer(&timesync_svc->ktime_timer,
+ jiffies + GB_TIMESYNC_KTIME_UPDATE);
+}
+
+int gb_timesync_to_timespec_by_svc(struct gb_svc *svc, u64 frame_time,
+ struct timespec *ts)
+{
+ struct gb_timesync_svc *timesync_svc;
+ int ret = 0;
+
+ mutex_lock(&gb_timesync_svc_list_mutex);
+ timesync_svc = gb_timesync_find_timesync_svc(svc->hd);
+ if (!timesync_svc) {
+ ret = -ENODEV;
+ goto done;
+ }
+ ret = gb_timesync_to_timespec(timesync_svc, frame_time, ts);
+done:
+ mutex_unlock(&gb_timesync_svc_list_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_timesync_to_timespec_by_svc);
+
+int gb_timesync_to_timespec_by_interface(struct gb_interface *interface,
+ u64 frame_time, struct timespec *ts)
+{
+ struct gb_timesync_svc *timesync_svc;
+ int ret = 0;
+
+ mutex_lock(&gb_timesync_svc_list_mutex);
+ timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
+ if (!timesync_svc) {
+ ret = -ENODEV;
+ goto done;
+ }
+
+ ret = gb_timesync_to_timespec(timesync_svc, frame_time, ts);
+done:
+ mutex_unlock(&gb_timesync_svc_list_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gb_timesync_to_timespec_by_interface);
+
+void gb_timesync_irq(struct gb_timesync_svc *timesync_svc)
+{
+ unsigned long flags;
+ u64 strobe_time;
+ bool strobe_is_ping = true;
+ struct timespec ts;
+
+ ktime_get_ts(&ts);
+ strobe_time = __gb_timesync_get_frame_time(timesync_svc);
+
+ spin_lock_irqsave(&timesync_svc->spinlock, flags);
+
+ if (timesync_svc->state == GB_TIMESYNC_STATE_PING) {
+ if (!timesync_svc->capture_ping)
+ goto done_nolog;
+ timesync_svc->ap_ping_frame_time = strobe_time;
+ goto done_log;
+ } else if (timesync_svc->state != GB_TIMESYNC_STATE_WAIT_SVC) {
+ goto done_nolog;
+ }
+
+ timesync_svc->strobe_data[timesync_svc->strobe].frame_time = strobe_time;
+ timesync_svc->strobe_data[timesync_svc->strobe].ts = ts;
+
+ if (++timesync_svc->strobe == GB_TIMESYNC_MAX_STROBES) {
+ gb_timesync_set_state(timesync_svc,
+ GB_TIMESYNC_STATE_AUTHORITATIVE);
+ }
+ strobe_is_ping = false;
+done_log:
+ trace_gb_timesync_irq(strobe_is_ping, timesync_svc->strobe,
+ GB_TIMESYNC_MAX_STROBES, strobe_time);
+done_nolog:
+ spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
+}
+EXPORT_SYMBOL(gb_timesync_irq);
+
+int __init gb_timesync_init(void)
+{
+ int ret = 0;
+
+ ret = gb_timesync_platform_init();
+ if (ret) {
+ pr_err("timesync platform init fail!\n");
+ return ret;
+ }
+
+ gb_timesync_clock_rate = gb_timesync_platform_get_clock_rate();
+
+ /* Calculate nanoseconds and femtoseconds per clock */
+ gb_timesync_fs_per_clock = FSEC_PER_SEC;
+ do_div(gb_timesync_fs_per_clock, gb_timesync_clock_rate);
+ gb_timesync_ns_per_clock = NSEC_PER_SEC;
+ do_div(gb_timesync_ns_per_clock, gb_timesync_clock_rate);
+
+ /* Calculate the maximum number of clocks we will convert to ktime */
+ gb_timesync_max_ktime_diff =
+ GB_TIMESYNC_MAX_KTIME_CONVERSION * gb_timesync_clock_rate;
+
+ pr_info("Time-Sync @ %lu Hz max ktime conversion +/- %d seconds\n",
+ gb_timesync_clock_rate, GB_TIMESYNC_MAX_KTIME_CONVERSION);
+ return 0;
+}
+
+void gb_timesync_exit(void)
+{
+ gb_timesync_platform_exit();
+}
diff --git a/drivers/staging/greybus/timesync.h b/drivers/staging/greybus/timesync.h
new file mode 100644
index 000000000000..72fc9a35a002
--- /dev/null
+++ b/drivers/staging/greybus/timesync.h
@@ -0,0 +1,45 @@
+/*
+ * TimeSync API driver.
+ *
+ * Copyright 2016 Google Inc.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#ifndef __TIMESYNC_H
+#define __TIMESYNC_H
+
+struct gb_svc;
+struct gb_interface;
+struct gb_timesync_svc;
+
+/* Platform */
+u64 gb_timesync_platform_get_counter(void);
+u32 gb_timesync_platform_get_clock_rate(void);
+int gb_timesync_platform_lock_bus(struct gb_timesync_svc *pdata);
+void gb_timesync_platform_unlock_bus(void);
+
+int gb_timesync_platform_init(void);
+void gb_timesync_platform_exit(void);
+
+/* Core API */
+int gb_timesync_interface_add(struct gb_interface *interface);
+void gb_timesync_interface_remove(struct gb_interface *interface);
+int gb_timesync_svc_add(struct gb_svc *svc);
+void gb_timesync_svc_remove(struct gb_svc *svc);
+
+u64 gb_timesync_get_frame_time_by_interface(struct gb_interface *interface);
+u64 gb_timesync_get_frame_time_by_svc(struct gb_svc *svc);
+int gb_timesync_to_timespec_by_svc(struct gb_svc *svc, u64 frame_time,
+ struct timespec *ts);
+int gb_timesync_to_timespec_by_interface(struct gb_interface *interface,
+ u64 frame_time, struct timespec *ts);
+
+int gb_timesync_schedule_synchronous(struct gb_interface *intf);
+void gb_timesync_schedule_asynchronous(struct gb_interface *intf);
+void gb_timesync_irq(struct gb_timesync_svc *timesync_svc);
+int gb_timesync_init(void);
+void gb_timesync_exit(void);
+
+#endif /* __TIMESYNC_H */
diff --git a/drivers/staging/greybus/timesync_platform.c b/drivers/staging/greybus/timesync_platform.c
new file mode 100644
index 000000000000..113f3d6c4b3a
--- /dev/null
+++ b/drivers/staging/greybus/timesync_platform.c
@@ -0,0 +1,82 @@
+/*
+ * TimeSync API driver.
+ *
+ * Copyright 2016 Google Inc.
+ * Copyright 2016 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ *
+ * This code reads directly from an ARMv7 memory-mapped timer that lives in
+ * MMIO space. Since this counter lives inside of MMIO space its shared between
+ * cores and that means we don't have to worry about issues like TSC on x86
+ * where each time-stamp-counter (TSC) is local to a particular core.
+ *
+ * Register-level access code is based on
+ * drivers/clocksource/arm_arch_timer.c
+ */
+#include <linux/cpufreq.h>
+#include <linux/of_platform.h>
+
+#include "greybus.h"
+#include "arche_platform.h"
+
+#define DEFAULT_FRAMETIME_CLOCK_HZ 19200000
+
+static u32 gb_timesync_clock_frequency;
+int (*arche_platform_change_state_cb)(enum arche_platform_state state,
+ struct gb_timesync_svc *pdata);
+EXPORT_SYMBOL_GPL(arche_platform_change_state_cb);
+
+u64 gb_timesync_platform_get_counter(void)
+{
+ return (u64)get_cycles();
+}
+
+u32 gb_timesync_platform_get_clock_rate(void)
+{
+ if (unlikely(!gb_timesync_clock_frequency)) {
+ gb_timesync_clock_frequency = cpufreq_get(0);
+ if (!gb_timesync_clock_frequency)
+ gb_timesync_clock_frequency = DEFAULT_FRAMETIME_CLOCK_HZ;
+ }
+
+ return gb_timesync_clock_frequency;
+}
+
+int gb_timesync_platform_lock_bus(struct gb_timesync_svc *pdata)
+{
+ return arche_platform_change_state_cb(ARCHE_PLATFORM_STATE_TIME_SYNC,
+ pdata);
+}
+
+void gb_timesync_platform_unlock_bus(void)
+{
+ arche_platform_change_state_cb(ARCHE_PLATFORM_STATE_ACTIVE, NULL);
+}
+
+static const struct of_device_id arch_timer_of_match[] = {
+ { .compatible = "google,greybus-frame-time-counter", },
+ {},
+};
+
+int __init gb_timesync_platform_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, arch_timer_of_match);
+ if (!np) {
+ /* Tolerate not finding to allow BBB etc to continue */
+ pr_warn("Unable to find a compatible ARMv7 timer\n");
+ return 0;
+ }
+
+ if (of_property_read_u32(np, "clock-frequency",
+ &gb_timesync_clock_frequency)) {
+ pr_err("Unable to find timer clock-frequency\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+void gb_timesync_platform_exit(void) {}
diff --git a/drivers/staging/greybus/tools/.gitignore b/drivers/staging/greybus/tools/.gitignore
new file mode 100644
index 000000000000..023654c83068
--- /dev/null
+++ b/drivers/staging/greybus/tools/.gitignore
@@ -0,0 +1 @@
+loopback_test
diff --git a/drivers/staging/greybus/tools/Android.mk b/drivers/staging/greybus/tools/Android.mk
new file mode 100644
index 000000000000..fdadbf611757
--- /dev/null
+++ b/drivers/staging/greybus/tools/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= loopback_test.c
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := gb_loopback_test
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/drivers/staging/greybus/tools/Makefile b/drivers/staging/greybus/tools/Makefile
new file mode 100644
index 000000000000..852b12b71149
--- /dev/null
+++ b/drivers/staging/greybus/tools/Makefile
@@ -0,0 +1,31 @@
+ifeq ($(strip $(V)), 1)
+ Q =
+else
+ Q = @
+endif
+
+CFLAGS += -std=gnu99 -Wall -Wextra -g \
+ -D_GNU_SOURCE \
+ -Wno-unused-parameter \
+ -Wmaybe-uninitialized \
+ -Wredundant-decls \
+ -Wcast-align \
+ -Wsign-compare \
+ -Wno-missing-field-initializers
+
+CC := $(CROSS_COMPILE)gcc
+
+TOOLS = loopback_test
+
+all: $(TOOLS)
+
+%.o: %.c ../greybus_protocols.h
+ @echo ' TARGET_CC $@'
+ $(Q)$(CC) $(CFLAGS) -c $< -o $@
+
+loopback_%: loopback_%.o
+ @echo ' TARGET_LD $@'
+ $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
+
+clean::
+ rm -f *.o $(TOOLS)
diff --git a/drivers/staging/greybus/tools/README.loopback b/drivers/staging/greybus/tools/README.loopback
new file mode 100644
index 000000000000..845b08dc4696
--- /dev/null
+++ b/drivers/staging/greybus/tools/README.loopback
@@ -0,0 +1,198 @@
+
+
+ 1 - LOOPBACK DRIVER
+
+The driver implements the main logic of the loopback test and provides
+sysfs files to configure the test and retrieve the results.
+A user could run a test without the need of the test application given
+that he understands the sysfs interface of the loopback driver.
+
+The loopback kernel driver needs to be loaded and at least one module
+with the loopback feature enabled must be present for the sysfs files to be
+created and for the loopback test application to be able to run.
+
+To load the module:
+# modprobe gb-loopback
+
+
+When the module is probed, New files are available on the sysfs
+directory of the detected loopback device.
+(typically under "/sys/bus/graybus/devices").
+
+Here is a short summary of the sysfs interface files that should be visible:
+
+* Loopback Configuration Files:
+ async - Use asynchronous operations.
+ iteration_max - Number of tests iterations to perform.
+ size - payload size of the transfer.
+ timeout - The number of microseconds to give an individual
+ asynchronous request before timing out.
+ us_wait - Time to wait between 2 messages
+ type - By writing the test type to this file, the test starts.
+ Valid tests are:
+ 0 stop the test
+ 2 - ping
+ 3 - transfer
+ 4 - sink
+
+* Loopback feedback files:
+ error - number of errors that have occurred.
+ iteration_count - Number of iterations performed.
+ requests_completed - Number of requests successfully completed.
+ requests_timedout - Number of requests that have timed out.
+ timeout_max - Max allowed timeout
+ timeout_min - Min allowed timeout.
+
+* Loopback result files:
+ apbridge_unipro_latency_avg
+ apbridge_unipro_latency_max
+ apbridge_unipro_latency_min
+ gpbridge_firmware_latency_avg
+ gpbridge_firmware_latency_max
+ gpbridge_firmware_latency_min
+ requests_per_second_avg
+ requests_per_second_max
+ requests_per_second_min
+ latency_avg
+ latency_max
+ latency_min
+ throughput_avg
+ throughput_max
+ throughput_min
+
+
+
+ 2 - LOOPBACK TEST APPLICATION
+
+The loopback test application manages and formats the results provided by
+the loopback kernel module. The purpose of this application
+is to:
+ - Start and manage multiple loopback device tests concurrently.
+ - Calculate the aggregate results for multiple devices.
+ - Gather and format test results (csv or human readable).
+
+The best way to get up to date usage information for the application is
+usually to pass the "-h" parameter.
+Here is the summary of the available options:
+
+ Mandatory arguments
+ -t must be one of the test names - sink, transfer or ping
+ -i iteration count - the number of iterations to run the test over
+ Optional arguments
+ -S sysfs location - location for greybus 'endo' entires default /sys/bus/greybus/devices/
+ -D debugfs location - location for loopback debugfs entries default /sys/kernel/debug/gb_loopback/
+ -s size of data packet to send during test - defaults to zero
+ -m mask - a bit mask of connections to include example: -m 8 = 4th connection -m 9 = 1st and 4th connection etc
+ default is zero which means broadcast to all connections
+ -v verbose output
+ -d debug output
+ -r raw data output - when specified the full list of latency values are included in the output CSV
+ -p porcelain - when specified printout is in a user-friendly non-CSV format. This option suppresses writing to CSV file
+ -a aggregate - show aggregation of all enabled devies
+ -l list found loopback devices and exit.
+ -x Async - Enable async transfers.
+ -o Timeout - Timeout in microseconds for async operations.
+
+
+
+ 3 - REAL WORLD EXAMPLE USAGES
+
+ 3.1 - Using the driver sysfs files to run a test on a single device:
+
+* Run a 1000 transfers of a 100 byte packet. Each transfer is started only
+after the previous one finished successfully:
+ echo 0 > /sys/bus/greybus/devices/1-2.17/type
+ echo 0 > /sys/bus/greybus/devices/1-2.17/async
+ echo 2000 > /sys/bus/greybus/devices/1-2.17/us_wait
+ echo 100 > /sys/bus/greybus/devices/1-2.17/size
+ echo 1000 > /sys/bus/greybus/devices/1-2.17/iteration_max
+ echo 0 > /sys/bus/greybus/devices/1-2.17/mask
+ echo 200000 > /sys/bus/greybus/devices/1-2.17/timeout
+ echo 3 > /sys/bus/greybus/devices/1-2.17/type
+
+* Run a 1000 transfers of a 100 byte packet. Transfers are started without
+waiting for the previous one to finish:
+ echo 0 > /sys/bus/greybus/devices/1-2.17/type
+ echo 3 > /sys/bus/greybus/devices/1-2.17/async
+ echo 0 > /sys/bus/greybus/devices/1-2.17/us_wait
+ echo 100 > /sys/bus/greybus/devices/1-2.17/size
+ echo 1000 > /sys/bus/greybus/devices/1-2.17/iteration_max
+ echo 0 > /sys/bus/greybus/devices/1-2.17/mask
+ echo 200000 > /sys/bus/greybus/devices/1-2.17/timeout
+ echo 3 > /sys/bus/greybus/devices/1-2.17/type
+
+* Read the results from sysfs:
+ cat /sys/bus/greybus/devices/1-2.17/requests_per_second_min
+ cat /sys/bus/greybus/devices/1-2.17/requests_per_second_max
+ cat /sys/bus/greybus/devices/1-2.17/requests_per_second_avg
+
+ cat /sys/bus/greybus/devices/1-2.17/latency_min
+ cat /sys/bus/greybus/devices/1-2.17/latency_max
+ cat /sys/bus/greybus/devices/1-2.17/latency_avg
+
+ cat /sys/bus/greybus/devices/1-2.17/apbridge_unipro_latency_min
+ cat /sys/bus/greybus/devices/1-2.17/apbridge_unipro_latency_max
+ cat /sys/bus/greybus/devices/1-2.17/apbridge_unipro_latency_avg
+
+ cat /sys/bus/greybus/devices/1-2.17/gpbridge_firmware_latency_min
+ cat /sys/bus/greybus/devices/1-2.17/gpbridge_firmware_latency_max
+ cat /sys/bus/greybus/devices/1-2.17/gpbridge_firmware_latency_avg
+
+ cat /sys/bus/greybus/devices/1-2.17/error
+ cat /sys/bus/greybus/devices/1-2.17/requests_completed
+ cat /sys/bus/greybus/devices/1-2.17/requests_timedout
+
+
+3.2 - using the test application:
+
+* Run a transfer test 10 iterations of size 100 bytes on all available devices
+ #/loopback_test -t transfer -i 10 -s 100
+ 1970-1-1 0:10:7,transfer,1-4.17,100,10,0,443,509,471.700012,66,1963,2256,2124.600098,293,102776,118088,109318.898438,15312,1620,1998,1894.099976,378,56,57,56.799999,1
+ 1970-1-1 0:10:7,transfer,1-5.17,100,10,0,399,542,463.399994,143,1845,2505,2175.800049,660,92568,125744,107393.296875,33176,1469,2305,1806.500000,836,56,57,56.799999,1
+
+
+* Show the aggregate results of both devices. ("-a")
+ #/loopback_test -t transfer -i 10 -s 100 -a
+ 1970-1-1 0:10:35,transfer,1-4.17,100,10,0,448,580,494.100006,132,1722,2230,2039.400024,508,103936,134560,114515.703125,30624,1513,1980,1806.900024,467,56,57,57.299999,1
+ 1970-1-1 0:10:35,transfer,1-5.17,100,10,0,383,558,478.600006,175,1791,2606,2115.199951,815,88856,129456,110919.703125,40600,1457,2246,1773.599976,789,56,57,57.099998,1
+ 1970-1-1 0:10:35,transfer,aggregate,100,10,0,383,580,486.000000,197,1722,2606,2077.000000,884,88856,134560,112717.000000,45704,1457,2246,1789.000000,789,56,57,57.000000,1
+
+* Example usage of the mask option to select which devices will
+ run the test (1st, 2nd, or both devices):
+ # /loopback_test -t transfer -i 10 -s 100 -m 1
+ 1970-1-1 0:11:56,transfer,1-4.17,100,10,0,514,558,544.900024,44,1791,1943,1836.599976,152,119248,129456,126301.296875,10208,1600,1001609,101613.601562,1000009,56,57,56.900002,1
+ # /loopback_test -t transfer -i 10 -s 100 -m 2
+ 1970-1-1 0:12:0,transfer,1-5.17,100,10,0,468,554,539.000000,86,1804,2134,1859.500000,330,108576,128528,124932.500000,19952,1606,1626,1619.300049,20,56,57,57.400002,1
+ # /loopback_test -t transfer -i 10 -s 100 -m 3
+ 1970-1-1 0:12:3,transfer,1-4.17,100,10,0,432,510,469.399994,78,1959,2313,2135.800049,354,100224,118320,108785.296875,18096,1610,2024,1893.500000,414,56,57,57.200001,1
+ 1970-1-1 0:12:3,transfer,1-5.17,100,10,0,404,542,468.799988,138,1843,2472,2152.500000,629,93728,125744,108646.101562,32016,1504,2247,1853.099976,743,56,57,57.099998,1
+
+* Show output in human readable format ("-p")
+ # /loopback_test -t transfer -i 10 -s 100 -m 3 -p
+
+ 1970-1-1 0:12:37
+ test: transfer
+ path: 1-4.17
+ size: 100
+ iterations: 10
+ errors: 0
+ async: Disabled
+ requests per-sec: min=390, max=547, average=469.299988, jitter=157
+ ap-throughput B/s: min=90480 max=126904 average=108762.101562 jitter=36424
+ ap-latency usec: min=1826 max=2560 average=2146.000000 jitter=734
+ apbridge-latency usec: min=1620 max=1982 average=1882.099976 jitter=362
+ gpbridge-latency usec: min=56 max=57 average=57.099998 jitter=1
+
+
+ 1970-1-1 0:12:37
+ test: transfer
+ path: 1-5.17
+ size: 100
+ iterations: 10
+ errors: 0
+ async: Disabled
+ requests per-sec: min=397, max=538, average=461.700012, jitter=141
+ ap-throughput B/s: min=92104 max=124816 average=106998.898438 jitter=32712
+ ap-latency usec: min=1856 max=2514 average=2185.699951 jitter=658
+ apbridge-latency usec: min=1460 max=2296 average=1828.599976 jitter=836
+ gpbridge-latency usec: min=56 max=57 average=57.099998 jitter=1
diff --git a/drivers/staging/greybus/tools/lbtest b/drivers/staging/greybus/tools/lbtest
new file mode 100755
index 000000000000..d7353f1a2a6f
--- /dev/null
+++ b/drivers/staging/greybus/tools/lbtest
@@ -0,0 +1,168 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2015 Google, Inc.
+# Copyright (c) 2015 Linaro, Ltd.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from __future__ import print_function
+import csv
+import datetime
+import sys
+import time
+
+dict = {'ping': '2', 'transfer': '3', 'sink': '4'}
+verbose = 1
+
+def abort():
+ sys.exit(1)
+
+def usage():
+ print('Usage: looptest TEST SIZE ITERATIONS PATH\n\n'
+ ' Run TEST for a number of ITERATIONS with operation data SIZE bytes\n'
+ ' TEST may be \'ping\' \'transfer\' or \'sink\'\n'
+ ' SIZE indicates the size of transfer <= greybus max payload bytes\n'
+ ' ITERATIONS indicates the number of times to execute TEST at SIZE bytes\n'
+ ' Note if ITERATIONS is set to zero then this utility will\n'
+ ' initiate an infinite (non terminating) test and exit\n'
+ ' without logging any metrics data\n'
+ ' PATH indicates the sysfs path for the loopback greybus entries e.g.\n'
+ ' /sys/bus/greybus/devices/endo0:1:1:1:1/\n'
+ 'Examples:\n'
+ ' looptest transfer 128 10000\n'
+ ' looptest ping 0 128\n'
+ ' looptest sink 2030 32768\n'
+ .format(sys.argv[0]), file=sys.stderr)
+
+ abort()
+
+def read_sysfs_int(path):
+ try:
+ f = open(path, "r");
+ val = f.read();
+ f.close()
+ return int(val)
+ except IOError as e:
+ print("I/O error({0}): {1}".format(e.errno, e.strerror))
+ print("Invalid path %s" % path)
+
+def write_sysfs_val(path, val):
+ try:
+ f = open(path, "r+")
+ f.write(val)
+ f.close()
+ except IOError as e:
+ print("I/O error({0}): {1}".format(e.errno, e.strerror))
+ print("Invalid path %s" % path)
+
+def log_csv(test_name, size, iteration_max, sys_pfx):
+ # file name will test_name_size_iteration_max.csv
+ # every time the same test with the same parameters is run we will then
+ # append to the same CSV with datestamp - representing each test dataset
+ fname = test_name + '_' + size + '_' + str(iteration_max) + '.csv'
+
+ try:
+ # gather data set
+ date = str(datetime.datetime.now())
+ error = read_sysfs_int(sys_pfx + 'error')
+ request_min = read_sysfs_int(sys_pfx + 'requests_per_second_min')
+ request_max = read_sysfs_int(sys_pfx + 'requests_per_second_max')
+ request_avg = read_sysfs_int(sys_pfx + 'requests_per_second_avg')
+ latency_min = read_sysfs_int(sys_pfx + 'latency_min')
+ latency_max = read_sysfs_int(sys_pfx + 'latency_max')
+ latency_avg = read_sysfs_int(sys_pfx + 'latency_avg')
+ throughput_min = read_sysfs_int(sys_pfx + 'throughput_min')
+ throughput_max = read_sysfs_int(sys_pfx + 'throughput_max')
+ throughput_avg = read_sysfs_int(sys_pfx + 'throughput_avg')
+
+ # derive jitter
+ request_jitter = request_max - request_min
+ latency_jitter = latency_max - latency_min
+ throughput_jitter = throughput_max - throughput_min
+
+ # append data set to file
+ with open(fname, 'a') as csvf:
+ row = csv.writer(csvf, delimiter=",", quotechar="'",
+ quoting=csv.QUOTE_MINIMAL)
+ row.writerow([date, test_name, size, iteration_max, error,
+ request_min, request_max, request_avg, request_jitter,
+ latency_min, latency_max, latency_avg, latency_jitter,
+ throughput_min, throughput_max, throughput_avg, throughput_jitter])
+ except IOError as e:
+ print("I/O error({0}): {1}".format(e.errno, e.strerror))
+
+def loopback_run(test_name, size, iteration_max, sys_pfx):
+ test_id = dict[test_name]
+ try:
+ # Terminate any currently running test
+ write_sysfs_val(sys_pfx + 'type', '0')
+ # Set parameter for no wait between messages
+ write_sysfs_val(sys_pfx + 'ms_wait', '0')
+ # Set operation size
+ write_sysfs_val(sys_pfx + 'size', size)
+ # Set iterations
+ write_sysfs_val(sys_pfx + 'iteration_max', str(iteration_max))
+ # Initiate by setting loopback operation type
+ write_sysfs_val(sys_pfx + 'type', test_id)
+ time.sleep(1)
+
+ if iteration_max == 0:
+ print ("Infinite test initiated CSV won't be logged\n")
+ return
+
+ previous = 0
+ err = 0
+ while True:
+ # get current count bail out if it hasn't changed
+ iteration_count = read_sysfs_int(sys_pfx + 'iteration_count')
+ if previous == iteration_count:
+ err = 1
+ break
+ elif iteration_count == iteration_max:
+ break
+ previous = iteration_count
+ if verbose:
+ print('%02d%% complete %d of %d ' %
+ (100 * iteration_count / iteration_max,
+ iteration_count, iteration_max))
+ time.sleep(1)
+ if err:
+ print ('\nError executing test\n')
+ else:
+ log_csv(test_name, size, iteration_max, sys_pfx)
+ except ValueError as ve:
+ print("Error: %s " % format(e.strerror), file=sys.stderr)
+ abort()
+
+def main():
+ if len(sys.argv) < 5:
+ usage()
+
+ if sys.argv[1] in dict.keys():
+ loopback_run(sys.argv[1], sys.argv[2], int(sys.argv[3]), sys.argv[4])
+ else:
+ usage()
+if __name__ == '__main__':
+ main()
diff --git a/drivers/staging/greybus/tools/loopback_test.c b/drivers/staging/greybus/tools/loopback_test.c
new file mode 100644
index 000000000000..f7f4cd6fb55b
--- /dev/null
+++ b/drivers/staging/greybus/tools/loopback_test.c
@@ -0,0 +1,1000 @@
+/*
+ * Loopback test application
+ *
+ * Copyright 2015 Google Inc.
+ * Copyright 2015 Linaro Ltd.
+ *
+ * Provided under the three clause BSD license found in the LICENSE file.
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <poll.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <signal.h>
+
+#define MAX_NUM_DEVICES 10
+#define MAX_SYSFS_PATH 0x200
+#define CSV_MAX_LINE 0x1000
+#define SYSFS_MAX_INT 0x20
+#define MAX_STR_LEN 255
+#define DEFAULT_ASYNC_TIMEOUT 200000
+
+struct dict {
+ char *name;
+ int type;
+};
+
+static struct dict dict[] = {
+ {"ping", 2},
+ {"transfer", 3},
+ {"sink", 4},
+ {NULL,} /* list termination */
+};
+
+struct loopback_results {
+ float latency_avg;
+ uint32_t latency_max;
+ uint32_t latency_min;
+ uint32_t latency_jitter;
+
+ float request_avg;
+ uint32_t request_max;
+ uint32_t request_min;
+ uint32_t request_jitter;
+
+ float throughput_avg;
+ uint32_t throughput_max;
+ uint32_t throughput_min;
+ uint32_t throughput_jitter;
+
+ float apbridge_unipro_latency_avg;
+ uint32_t apbridge_unipro_latency_max;
+ uint32_t apbridge_unipro_latency_min;
+ uint32_t apbridge_unipro_latency_jitter;
+
+ float gbphy_firmware_latency_avg;
+ uint32_t gbphy_firmware_latency_max;
+ uint32_t gbphy_firmware_latency_min;
+ uint32_t gbphy_firmware_latency_jitter;
+
+ uint32_t error;
+};
+
+struct loopback_device {
+ char name[MAX_SYSFS_PATH];
+ char sysfs_entry[MAX_SYSFS_PATH];
+ char debugfs_entry[MAX_SYSFS_PATH];
+ struct loopback_results results;
+};
+
+struct loopback_test {
+ int verbose;
+ int debug;
+ int raw_data_dump;
+ int porcelain;
+ int mask;
+ int size;
+ int iteration_max;
+ int aggregate_output;
+ int test_id;
+ int device_count;
+ int list_devices;
+ int use_async;
+ int async_timeout;
+ int async_outstanding_operations;
+ int us_wait;
+ int file_output;
+ int stop_all;
+ int poll_count;
+ char test_name[MAX_STR_LEN];
+ char sysfs_prefix[MAX_SYSFS_PATH];
+ char debugfs_prefix[MAX_SYSFS_PATH];
+ struct timespec poll_timeout;
+ struct loopback_device devices[MAX_NUM_DEVICES];
+ struct loopback_results aggregate_results;
+ struct pollfd fds[MAX_NUM_DEVICES];
+};
+
+struct loopback_test t;
+
+/* Helper macros to calculate the aggregate results for all devices */
+static inline int device_enabled(struct loopback_test *t, int dev_idx);
+
+#define GET_MAX(field) \
+static int get_##field##_aggregate(struct loopback_test *t) \
+{ \
+ uint32_t max = 0; \
+ int i; \
+ for (i = 0; i < t->device_count; i++) { \
+ if (!device_enabled(t, i)) \
+ continue; \
+ if (t->devices[i].results.field > max) \
+ max = t->devices[i].results.field; \
+ } \
+ return max; \
+} \
+
+#define GET_MIN(field) \
+static int get_##field##_aggregate(struct loopback_test *t) \
+{ \
+ uint32_t min = ~0; \
+ int i; \
+ for (i = 0; i < t->device_count; i++) { \
+ if (!device_enabled(t, i)) \
+ continue; \
+ if (t->devices[i].results.field < min) \
+ min = t->devices[i].results.field; \
+ } \
+ return min; \
+} \
+
+#define GET_AVG(field) \
+static int get_##field##_aggregate(struct loopback_test *t) \
+{ \
+ uint32_t val = 0; \
+ uint32_t count = 0; \
+ int i; \
+ for (i = 0; i < t->device_count; i++) { \
+ if (!device_enabled(t, i)) \
+ continue; \
+ count++; \
+ val += t->devices[i].results.field; \
+ } \
+ if (count) \
+ val /= count; \
+ return val; \
+} \
+
+GET_MAX(throughput_max);
+GET_MAX(request_max);
+GET_MAX(latency_max);
+GET_MAX(apbridge_unipro_latency_max);
+GET_MAX(gbphy_firmware_latency_max);
+GET_MIN(throughput_min);
+GET_MIN(request_min);
+GET_MIN(latency_min);
+GET_MIN(apbridge_unipro_latency_min);
+GET_MIN(gbphy_firmware_latency_min);
+GET_AVG(throughput_avg);
+GET_AVG(request_avg);
+GET_AVG(latency_avg);
+GET_AVG(apbridge_unipro_latency_avg);
+GET_AVG(gbphy_firmware_latency_avg);
+
+void abort()
+{
+ _exit(1);
+}
+
+void usage(void)
+{
+ fprintf(stderr, "Usage: loopback_test TEST [SIZE] ITERATIONS [SYSPATH] [DBGPATH]\n\n"
+ " Run TEST for a number of ITERATIONS with operation data SIZE bytes\n"
+ " TEST may be \'ping\' \'transfer\' or \'sink\'\n"
+ " SIZE indicates the size of transfer <= greybus max payload bytes\n"
+ " ITERATIONS indicates the number of times to execute TEST at SIZE bytes\n"
+ " Note if ITERATIONS is set to zero then this utility will\n"
+ " initiate an infinite (non terminating) test and exit\n"
+ " without logging any metrics data\n"
+ " SYSPATH indicates the sysfs path for the loopback greybus entries e.g.\n"
+ " /sys/bus/greybus/devices\n"
+ " DBGPATH indicates the debugfs path for the loopback greybus entries e.g.\n"
+ " /sys/kernel/debug/gb_loopback/\n"
+ " Mandatory arguments\n"
+ " -t must be one of the test names - sink, transfer or ping\n"
+ " -i iteration count - the number of iterations to run the test over\n"
+ " Optional arguments\n"
+ " -S sysfs location - location for greybus 'endo' entires default /sys/bus/greybus/devices/\n"
+ " -D debugfs location - location for loopback debugfs entries default /sys/kernel/debug/gb_loopback/\n"
+ " -s size of data packet to send during test - defaults to zero\n"
+ " -m mask - a bit mask of connections to include example: -m 8 = 4th connection -m 9 = 1st and 4th connection etc\n"
+ " default is zero which means broadcast to all connections\n"
+ " -v verbose output\n"
+ " -d debug output\n"
+ " -r raw data output - when specified the full list of latency values are included in the output CSV\n"
+ " -p porcelain - when specified printout is in a user-friendly non-CSV format. This option suppresses writing to CSV file\n"
+ " -a aggregate - show aggregation of all enabled devices\n"
+ " -l list found loopback devices and exit\n"
+ " -x Async - Enable async transfers\n"
+ " -o Async Timeout - Timeout in uSec for async operations\n"
+ " -O Poll loop time out in seconds(max time a test is expected to last, default: 30sec)\n"
+ " -c Max number of outstanding operations for async operations\n"
+ " -w Wait in uSec between operations\n"
+ " -z Enable output to a CSV file (incompatible with -p)\n"
+ " -f When starting new loopback test, stop currently running tests on all devices\n"
+ "Examples:\n"
+ " Send 10000 transfers with a packet size of 128 bytes to all active connections\n"
+ " loopback_test -t transfer -s 128 -i 10000 -S /sys/bus/greybus/devices/ -D /sys/kernel/debug/gb_loopback/\n"
+ " loopback_test -t transfer -s 128 -i 10000 -m 0\n"
+ " Send 10000 transfers with a packet size of 128 bytes to connection 1 and 4\n"
+ " loopback_test -t transfer -s 128 -i 10000 -m 9\n"
+ " loopback_test -t ping -s 0 128 -i -S /sys/bus/greybus/devices/ -D /sys/kernel/debug/gb_loopback/\n"
+ " loopback_test -t sink -s 2030 -i 32768 -S /sys/bus/greybus/devices/ -D /sys/kernel/debug/gb_loopback/\n");
+ abort();
+}
+
+static inline int device_enabled(struct loopback_test *t, int dev_idx)
+{
+ if (!t->mask || (t->mask & (1 << dev_idx)))
+ return 1;
+
+ return 0;
+}
+
+static void show_loopback_devices(struct loopback_test *t)
+{
+ int i;
+
+ if (t->device_count == 0) {
+ printf("No loopback devices.\n");
+ return;
+ }
+
+ for (i = 0; i < t->device_count; i++)
+ printf("device[%d] = %s\n", i, t->devices[i].name);
+
+}
+
+int open_sysfs(const char *sys_pfx, const char *node, int flags)
+{
+ int fd;
+ char path[MAX_SYSFS_PATH];
+
+ snprintf(path, sizeof(path), "%s%s", sys_pfx, node);
+ fd = open(path, flags);
+ if (fd < 0) {
+ fprintf(stderr, "unable to open %s\n", path);
+ abort();
+ }
+ return fd;
+}
+
+int read_sysfs_int_fd(int fd, const char *sys_pfx, const char *node)
+{
+ char buf[SYSFS_MAX_INT];
+
+ if (read(fd, buf, sizeof(buf)) < 0) {
+ fprintf(stderr, "unable to read from %s%s %s\n", sys_pfx, node,
+ strerror(errno));
+ close(fd);
+ abort();
+ }
+ return atoi(buf);
+}
+
+float read_sysfs_float_fd(int fd, const char *sys_pfx, const char *node)
+{
+ char buf[SYSFS_MAX_INT];
+
+ if (read(fd, buf, sizeof(buf)) < 0) {
+
+ fprintf(stderr, "unable to read from %s%s %s\n", sys_pfx, node,
+ strerror(errno));
+ close(fd);
+ abort();
+ }
+ return atof(buf);
+}
+
+int read_sysfs_int(const char *sys_pfx, const char *node)
+{
+ int fd, val;
+
+ fd = open_sysfs(sys_pfx, node, O_RDONLY);
+ val = read_sysfs_int_fd(fd, sys_pfx, node);
+ close(fd);
+ return val;
+}
+
+float read_sysfs_float(const char *sys_pfx, const char *node)
+{
+ int fd;
+ float val;
+
+ fd = open_sysfs(sys_pfx, node, O_RDONLY);
+ val = read_sysfs_float_fd(fd, sys_pfx, node);
+ close(fd);
+ return val;
+}
+
+void write_sysfs_val(const char *sys_pfx, const char *node, int val)
+{
+ int fd, len;
+ char buf[SYSFS_MAX_INT];
+
+ fd = open_sysfs(sys_pfx, node, O_RDWR);
+ len = snprintf(buf, sizeof(buf), "%d", val);
+ if (write(fd, buf, len) < 0) {
+ fprintf(stderr, "unable to write to %s%s %s\n", sys_pfx, node,
+ strerror(errno));
+ close(fd);
+ abort();
+ }
+ close(fd);
+}
+
+static int get_results(struct loopback_test *t)
+{
+ struct loopback_device *d;
+ struct loopback_results *r;
+ int i;
+
+ for (i = 0; i < t->device_count; i++) {
+ if (!device_enabled(t, i))
+ continue;
+
+ d = &t->devices[i];
+ r = &d->results;
+
+ r->error = read_sysfs_int(d->sysfs_entry, "error");
+ r->request_min = read_sysfs_int(d->sysfs_entry, "requests_per_second_min");
+ r->request_max = read_sysfs_int(d->sysfs_entry, "requests_per_second_max");
+ r->request_avg = read_sysfs_float(d->sysfs_entry, "requests_per_second_avg");
+
+ r->latency_min = read_sysfs_int(d->sysfs_entry, "latency_min");
+ r->latency_max = read_sysfs_int(d->sysfs_entry, "latency_max");
+ r->latency_avg = read_sysfs_float(d->sysfs_entry, "latency_avg");
+
+ r->throughput_min = read_sysfs_int(d->sysfs_entry, "throughput_min");
+ r->throughput_max = read_sysfs_int(d->sysfs_entry, "throughput_max");
+ r->throughput_avg = read_sysfs_float(d->sysfs_entry, "throughput_avg");
+
+ r->apbridge_unipro_latency_min =
+ read_sysfs_int(d->sysfs_entry, "apbridge_unipro_latency_min");
+ r->apbridge_unipro_latency_max =
+ read_sysfs_int(d->sysfs_entry, "apbridge_unipro_latency_max");
+ r->apbridge_unipro_latency_avg =
+ read_sysfs_float(d->sysfs_entry, "apbridge_unipro_latency_avg");
+
+ r->gbphy_firmware_latency_min =
+ read_sysfs_int(d->sysfs_entry, "gbphy_firmware_latency_min");
+ r->gbphy_firmware_latency_max =
+ read_sysfs_int(d->sysfs_entry, "gbphy_firmware_latency_max");
+ r->gbphy_firmware_latency_avg =
+ read_sysfs_float(d->sysfs_entry, "gbphy_firmware_latency_avg");
+
+ r->request_jitter = r->request_max - r->request_min;
+ r->latency_jitter = r->latency_max - r->latency_min;
+ r->throughput_jitter = r->throughput_max - r->throughput_min;
+ r->apbridge_unipro_latency_jitter =
+ r->apbridge_unipro_latency_max - r->apbridge_unipro_latency_min;
+ r->gbphy_firmware_latency_jitter =
+ r->gbphy_firmware_latency_max - r->gbphy_firmware_latency_min;
+
+ }
+
+ /*calculate the aggregate results of all enabled devices */
+ if (t->aggregate_output) {
+ r = &t->aggregate_results;
+
+ r->request_min = get_request_min_aggregate(t);
+ r->request_max = get_request_max_aggregate(t);
+ r->request_avg = get_request_avg_aggregate(t);
+
+ r->latency_min = get_latency_min_aggregate(t);
+ r->latency_max = get_latency_max_aggregate(t);
+ r->latency_avg = get_latency_avg_aggregate(t);
+
+ r->throughput_min = get_throughput_min_aggregate(t);
+ r->throughput_max = get_throughput_max_aggregate(t);
+ r->throughput_avg = get_throughput_avg_aggregate(t);
+
+ r->apbridge_unipro_latency_min =
+ get_apbridge_unipro_latency_min_aggregate(t);
+ r->apbridge_unipro_latency_max =
+ get_apbridge_unipro_latency_max_aggregate(t);
+ r->apbridge_unipro_latency_avg =
+ get_apbridge_unipro_latency_avg_aggregate(t);
+
+ r->gbphy_firmware_latency_min =
+ get_gbphy_firmware_latency_min_aggregate(t);
+ r->gbphy_firmware_latency_max =
+ get_gbphy_firmware_latency_max_aggregate(t);
+ r->gbphy_firmware_latency_avg =
+ get_gbphy_firmware_latency_avg_aggregate(t);
+
+ r->request_jitter = r->request_max - r->request_min;
+ r->latency_jitter = r->latency_max - r->latency_min;
+ r->throughput_jitter = r->throughput_max - r->throughput_min;
+ r->apbridge_unipro_latency_jitter =
+ r->apbridge_unipro_latency_max - r->apbridge_unipro_latency_min;
+ r->gbphy_firmware_latency_jitter =
+ r->gbphy_firmware_latency_max - r->gbphy_firmware_latency_min;
+
+ }
+
+ return 0;
+}
+
+void log_csv_error(int len, int err)
+{
+ fprintf(stderr, "unable to write %d bytes to csv %s\n", len,
+ strerror(err));
+}
+
+int format_output(struct loopback_test *t,
+ struct loopback_results *r,
+ const char *dev_name,
+ char *buf, int buf_len,
+ struct tm *tm)
+{
+ int len = 0;
+
+ memset(buf, 0x00, buf_len);
+ len = snprintf(buf, buf_len, "%u-%u-%u %u:%u:%u",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+ if (t->porcelain) {
+ len += snprintf(&buf[len], buf_len - len,
+ "\n test:\t\t\t%s\n path:\t\t\t%s\n size:\t\t\t%u\n iterations:\t\t%u\n errors:\t\t%u\n async:\t\t\t%s\n",
+ t->test_name,
+ dev_name,
+ t->size,
+ t->iteration_max,
+ r->error,
+ t->use_async ? "Enabled" : "Disabled");
+
+ len += snprintf(&buf[len], buf_len - len,
+ " requests per-sec:\tmin=%u, max=%u, average=%f, jitter=%u\n",
+ r->request_min,
+ r->request_max,
+ r->request_avg,
+ r->request_jitter);
+
+ len += snprintf(&buf[len], buf_len - len,
+ " ap-throughput B/s:\tmin=%u max=%u average=%f jitter=%u\n",
+ r->throughput_min,
+ r->throughput_max,
+ r->throughput_avg,
+ r->throughput_jitter);
+ len += snprintf(&buf[len], buf_len - len,
+ " ap-latency usec:\tmin=%u max=%u average=%f jitter=%u\n",
+ r->latency_min,
+ r->latency_max,
+ r->latency_avg,
+ r->latency_jitter);
+ len += snprintf(&buf[len], buf_len - len,
+ " apbridge-latency usec:\tmin=%u max=%u average=%f jitter=%u\n",
+ r->apbridge_unipro_latency_min,
+ r->apbridge_unipro_latency_max,
+ r->apbridge_unipro_latency_avg,
+ r->apbridge_unipro_latency_jitter);
+
+ len += snprintf(&buf[len], buf_len - len,
+ " gbphy-latency usec:\tmin=%u max=%u average=%f jitter=%u\n",
+ r->gbphy_firmware_latency_min,
+ r->gbphy_firmware_latency_max,
+ r->gbphy_firmware_latency_avg,
+ r->gbphy_firmware_latency_jitter);
+
+ } else {
+ len += snprintf(&buf[len], buf_len- len, ",%s,%s,%u,%u,%u",
+ t->test_name, dev_name, t->size, t->iteration_max,
+ r->error);
+
+ len += snprintf(&buf[len], buf_len - len, ",%u,%u,%f,%u",
+ r->request_min,
+ r->request_max,
+ r->request_avg,
+ r->request_jitter);
+
+ len += snprintf(&buf[len], buf_len - len, ",%u,%u,%f,%u",
+ r->latency_min,
+ r->latency_max,
+ r->latency_avg,
+ r->latency_jitter);
+
+ len += snprintf(&buf[len], buf_len - len, ",%u,%u,%f,%u",
+ r->throughput_min,
+ r->throughput_max,
+ r->throughput_avg,
+ r->throughput_jitter);
+
+ len += snprintf(&buf[len], buf_len - len, ",%u,%u,%f,%u",
+ r->apbridge_unipro_latency_min,
+ r->apbridge_unipro_latency_max,
+ r->apbridge_unipro_latency_avg,
+ r->apbridge_unipro_latency_jitter);
+
+ len += snprintf(&buf[len], buf_len - len, ",%u,%u,%f,%u",
+ r->gbphy_firmware_latency_min,
+ r->gbphy_firmware_latency_max,
+ r->gbphy_firmware_latency_avg,
+ r->gbphy_firmware_latency_jitter);
+ }
+
+ printf("\n%s\n", buf);
+
+ return len;
+}
+
+static int log_results(struct loopback_test *t)
+{
+ int fd, i, len, ret;
+ struct tm tm;
+ time_t local_time;
+ mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+ char file_name[MAX_SYSFS_PATH];
+ char data[CSV_MAX_LINE];
+
+ local_time = time(NULL);
+ tm = *localtime(&local_time);
+
+ /*
+ * file name will test_name_size_iteration_max.csv
+ * every time the same test with the same parameters is run we will then
+ * append to the same CSV with datestamp - representing each test
+ * dataset.
+ */
+ if (t->file_output && !t->porcelain) {
+ snprintf(file_name, sizeof(file_name), "%s_%d_%d.csv",
+ t->test_name, t->size, t->iteration_max);
+
+ fd = open(file_name, O_WRONLY | O_CREAT | O_APPEND, mode);
+ if (fd < 0) {
+ fprintf(stderr, "unable to open %s for appendation\n", file_name);
+ abort();
+ }
+
+ }
+ for (i = 0; i < t->device_count; i++) {
+ if (!device_enabled(t, i))
+ continue;
+
+ len = format_output(t, &t->devices[i].results,
+ t->devices[i].name,
+ data, sizeof(data), &tm);
+ if (t->file_output && !t->porcelain) {
+ ret = write(fd, data, len);
+ if (ret == -1)
+ fprintf(stderr, "unable to write %d bytes to csv.\n", len);
+ }
+
+ }
+
+
+ if (t->aggregate_output) {
+ len = format_output(t, &t->aggregate_results, "aggregate",
+ data, sizeof(data), &tm);
+ if (t->file_output && !t->porcelain) {
+ ret = write(fd, data, len);
+ if (ret == -1)
+ fprintf(stderr, "unable to write %d bytes to csv.\n", len);
+ }
+ }
+
+ if (t->file_output && !t->porcelain)
+ close(fd);
+
+ return 0;
+}
+
+int is_loopback_device(const char *path, const char *node)
+{
+ char file[MAX_SYSFS_PATH];
+
+ snprintf(file, MAX_SYSFS_PATH, "%s%s/iteration_count", path, node);
+ if (access(file, F_OK) == 0)
+ return 1;
+ return 0;
+}
+
+int find_loopback_devices(struct loopback_test *t)
+{
+ struct dirent **namelist;
+ int i, n, ret;
+ unsigned int dev_id;
+ struct loopback_device *d;
+
+ n = scandir(t->sysfs_prefix, &namelist, NULL, alphasort);
+ if (n < 0) {
+ perror("scandir");
+ ret = -ENODEV;
+ goto baddir;
+ }
+
+ /* Don't include '.' and '..' */
+ if (n <= 2) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ for (i = 0; i < n; i++) {
+ ret = sscanf(namelist[i]->d_name, "gb_loopback%u", &dev_id);
+ if (ret != 1)
+ continue;
+
+ if (!is_loopback_device(t->sysfs_prefix, namelist[i]->d_name))
+ continue;
+
+ if (t->device_count == MAX_NUM_DEVICES) {
+ fprintf(stderr, "max number of devices reached!\n");
+ break;
+ }
+
+ d = &t->devices[t->device_count++];
+ snprintf(d->name, MAX_STR_LEN, "gb_loopback%u", dev_id);
+
+ snprintf(d->sysfs_entry, MAX_SYSFS_PATH, "%s%s/",
+ t->sysfs_prefix, d->name);
+
+ snprintf(d->debugfs_entry, MAX_SYSFS_PATH, "%sraw_latency_%s",
+ t->debugfs_prefix, d->name);
+
+ if (t->debug)
+ printf("add %s %s\n", d->sysfs_entry,
+ d->debugfs_entry);
+ }
+
+ ret = 0;
+done:
+ for (i = 0; i < n; i++)
+ free(namelist[n]);
+ free(namelist);
+baddir:
+ return ret;
+}
+
+static int open_poll_files(struct loopback_test *t)
+{
+ struct loopback_device *dev;
+ char buf[MAX_STR_LEN];
+ char dummy;
+ int fds_idx = 0;
+ int i;
+
+ for (i = 0; i < t->device_count; i++) {
+ dev = &t->devices[i];
+
+ if (!device_enabled(t, i))
+ continue;
+
+ snprintf(buf, sizeof(buf), "%s%s", dev->sysfs_entry, "iteration_count");
+ t->fds[fds_idx].fd = open(buf, O_RDONLY);
+ if (t->fds[fds_idx].fd < 0) {
+ fprintf(stderr, "Error opening poll file!\n");
+ goto err;
+ }
+ read(t->fds[fds_idx].fd, &dummy, 1);
+ t->fds[fds_idx].events = POLLERR|POLLPRI;
+ t->fds[fds_idx].revents = 0;
+ fds_idx++;
+ }
+
+ t->poll_count = fds_idx;
+
+ return 0;
+
+err:
+ for (i = 0; i < fds_idx; i++)
+ close(t->fds[fds_idx].fd);
+
+ return -1;
+}
+
+static int close_poll_files(struct loopback_test *t)
+{
+ int i;
+ for (i = 0; i < t->poll_count; i++)
+ close(t->fds[i].fd);
+
+ return 0;
+}
+static int is_complete(struct loopback_test *t)
+{
+ int iteration_count;
+ int i;
+
+ for (i = 0; i < t->device_count; i++) {
+ if (!device_enabled(t, i))
+ continue;
+
+ iteration_count = read_sysfs_int(t->devices[i].sysfs_entry,
+ "iteration_count");
+
+ /* at least one device did not finish yet */
+ if (iteration_count != t->iteration_max)
+ return 0;
+ }
+
+ return 1;
+}
+
+static void stop_tests(struct loopback_test *t)
+{
+ int i;
+
+ for (i = 0; i < t->device_count; i++) {
+ if (!device_enabled(t, i))
+ continue;
+ write_sysfs_val(t->devices[i].sysfs_entry, "type", 0);
+ }
+}
+
+static void handler(int sig) { /* do nothing */ }
+
+static int wait_for_complete(struct loopback_test *t)
+{
+ int number_of_events = 0;
+ char dummy;
+ int ret;
+ int i;
+ struct timespec *ts = NULL;
+ struct sigaction sa;
+ sigset_t mask_old, mask;
+
+ sigemptyset(&mask);
+ sigemptyset(&mask_old);
+ sigaddset(&mask, SIGINT);
+ sigprocmask(SIG_BLOCK, &mask, &mask_old);
+
+ sa.sa_handler = handler;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ if (sigaction(SIGINT, &sa, NULL) == -1) {
+ fprintf(stderr, "sigaction error\n");
+ return -1;
+ }
+
+ if (t->poll_timeout.tv_sec != 0)
+ ts = &t->poll_timeout;
+
+ while (1) {
+
+ ret = ppoll(t->fds, t->poll_count, ts, &mask_old);
+ if (ret <= 0) {
+ stop_tests(t);
+ fprintf(stderr, "Poll exit with errno %d\n", errno);
+ return -1;
+ }
+
+ for (i = 0; i < t->poll_count; i++) {
+ if (t->fds[i].revents & POLLPRI) {
+ /* Dummy read to clear the event */
+ read(t->fds[i].fd, &dummy, 1);
+ number_of_events++;
+ }
+ }
+
+ if (number_of_events == t->poll_count)
+ break;
+ }
+
+ if (!is_complete(t)) {
+ fprintf(stderr, "Iteration count did not finish!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void prepare_devices(struct loopback_test *t)
+{
+ int i;
+
+ /* Cancel any running tests on enabled devices. If
+ * stop_all option is given, stop test on all devices.
+ */
+ for (i = 0; i < t->device_count; i++)
+ if (t->stop_all || device_enabled(t, i))
+ write_sysfs_val(t->devices[i].sysfs_entry, "type", 0);
+
+
+ for (i = 0; i < t->device_count; i++) {
+ if (!device_enabled(t, i))
+ continue;
+
+ write_sysfs_val(t->devices[i].sysfs_entry, "us_wait",
+ t->us_wait);
+
+ /* Set operation size */
+ write_sysfs_val(t->devices[i].sysfs_entry, "size", t->size);
+
+ /* Set iterations */
+ write_sysfs_val(t->devices[i].sysfs_entry, "iteration_max",
+ t->iteration_max);
+
+ if (t->use_async) {
+ write_sysfs_val(t->devices[i].sysfs_entry,
+ "async", 1);
+ write_sysfs_val(t->devices[i].sysfs_entry,
+ "timeout", t->async_timeout);
+ write_sysfs_val(t->devices[i].sysfs_entry,
+ "outstanding_operations_max",
+ t->async_outstanding_operations);
+ } else
+ write_sysfs_val(t->devices[i].sysfs_entry,
+ "async", 0);
+ }
+}
+
+static int start(struct loopback_test *t)
+{
+ int i;
+
+ /* the test starts by writing test_id to the type file. */
+ for (i = 0; i < t->device_count; i++) {
+ if (!device_enabled(t, i))
+ continue;
+
+ write_sysfs_val(t->devices[i].sysfs_entry, "type", t->test_id);
+ }
+
+ return 0;
+}
+
+
+void loopback_run(struct loopback_test *t)
+{
+ int i;
+ int ret;
+
+ for (i = 0; dict[i].name != NULL; i++) {
+ if (strstr(dict[i].name, t->test_name))
+ t->test_id = dict[i].type;
+ }
+ if (!t->test_id) {
+ fprintf(stderr, "invalid test %s\n", t->test_name);
+ usage();
+ return;
+ }
+
+ prepare_devices(t);
+
+ ret = open_poll_files(t);
+ if (ret)
+ goto err;
+
+ start(t);
+
+ ret = wait_for_complete(t);
+ close_poll_files(t);
+ if (ret)
+ goto err;
+
+
+ get_results(t);
+
+ log_results(t);
+
+ return;
+
+err:
+ printf("Error running test\n");
+ return;
+}
+
+static int sanity_check(struct loopback_test *t)
+{
+ int i;
+
+ if (t->device_count == 0) {
+ fprintf(stderr, "No loopback devices found\n");
+ return -1;
+ }
+
+ for (i = 0; i < MAX_NUM_DEVICES; i++) {
+ if (!device_enabled(t, i))
+ continue;
+
+ if (t->mask && !strcmp(t->devices[i].name, "")) {
+ fprintf(stderr, "Bad device mask %x\n", (1 << i));
+ return -1;
+ }
+
+ }
+
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int o, ret;
+ char *sysfs_prefix = "/sys/class/gb_loopback/";
+ char *debugfs_prefix = "/sys/kernel/debug/gb_loopback/";
+
+ memset(&t, 0, sizeof(t));
+
+ while ((o = getopt(argc, argv,
+ "t:s:i:S:D:m:v::d::r::p::a::l::x::o:O:c:w:z::f::")) != -1) {
+ switch (o) {
+ case 't':
+ snprintf(t.test_name, MAX_STR_LEN, "%s", optarg);
+ break;
+ case 's':
+ t.size = atoi(optarg);
+ break;
+ case 'i':
+ t.iteration_max = atoi(optarg);
+ break;
+ case 'S':
+ snprintf(t.sysfs_prefix, MAX_SYSFS_PATH, "%s", optarg);
+ break;
+ case 'D':
+ snprintf(t.debugfs_prefix, MAX_SYSFS_PATH, "%s", optarg);
+ break;
+ case 'm':
+ t.mask = atol(optarg);
+ break;
+ case 'v':
+ t.verbose = 1;
+ break;
+ case 'd':
+ t.debug = 1;
+ break;
+ case 'r':
+ t.raw_data_dump = 1;
+ break;
+ case 'p':
+ t.porcelain = 1;
+ break;
+ case 'a':
+ t.aggregate_output = 1;
+ break;
+ case 'l':
+ t.list_devices = 1;
+ break;
+ case 'x':
+ t.use_async = 1;
+ break;
+ case 'o':
+ t.async_timeout = atoi(optarg);
+ break;
+ case 'O':
+ t.poll_timeout.tv_sec = atoi(optarg);
+ break;
+ case 'c':
+ t.async_outstanding_operations = atoi(optarg);
+ break;
+ case 'w':
+ t.us_wait = atoi(optarg);
+ break;
+ case 'z':
+ t.file_output = 1;
+ break;
+ case 'f':
+ t.stop_all = 1;
+ break;
+ default:
+ usage();
+ return -EINVAL;
+ }
+ }
+
+ if (!strcmp(t.sysfs_prefix, ""))
+ snprintf(t.sysfs_prefix, MAX_SYSFS_PATH, "%s", sysfs_prefix);
+
+ if (!strcmp(t.debugfs_prefix, ""))
+ snprintf(t.debugfs_prefix, MAX_SYSFS_PATH, "%s", debugfs_prefix);
+
+ ret = find_loopback_devices(&t);
+ if (ret)
+ return ret;
+ ret = sanity_check(&t);
+ if (ret)
+ return ret;
+
+ if (t.list_devices) {
+ show_loopback_devices(&t);
+ return 0;
+ }
+
+ if (t.test_name[0] == '\0' || t.iteration_max == 0)
+ usage();
+
+ if (t.async_timeout == 0)
+ t.async_timeout = DEFAULT_ASYNC_TIMEOUT;
+
+ loopback_run(&t);
+
+ return 0;
+}
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
new file mode 100644
index 000000000000..5ee7954bd9f9
--- /dev/null
+++ b/drivers/staging/greybus/uart.c
@@ -0,0 +1,1075 @@
+/*
+ * UART driver for the Greybus "generic" UART module.
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ *
+ * Heavily based on drivers/usb/class/cdc-acm.c and
+ * drivers/usb/serial/usb-serial.c.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/mutex.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/idr.h>
+#include <linux/fs.h>
+#include <linux/kdev_t.h>
+#include <linux/kfifo.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+
+#include "greybus.h"
+#include "gbphy.h"
+
+#define GB_NUM_MINORS 16 /* 16 is is more than enough */
+#define GB_NAME "ttyGB"
+
+#define GB_UART_WRITE_FIFO_SIZE PAGE_SIZE
+#define GB_UART_WRITE_ROOM_MARGIN 1 /* leave some space in fifo */
+#define GB_UART_FIRMWARE_CREDITS 4096
+#define GB_UART_CREDIT_WAIT_TIMEOUT_MSEC 10000
+
+struct gb_tty_line_coding {
+ __le32 rate;
+ __u8 format;
+ __u8 parity;
+ __u8 data_bits;
+ __u8 flow_control;
+};
+
+struct gb_tty {
+ struct gbphy_device *gbphy_dev;
+ struct tty_port port;
+ void *buffer;
+ size_t buffer_payload_max;
+ struct gb_connection *connection;
+ u16 cport_id;
+ unsigned int minor;
+ unsigned char clocal;
+ bool disconnected;
+ spinlock_t read_lock;
+ spinlock_t write_lock;
+ struct async_icount iocount;
+ struct async_icount oldcount;
+ wait_queue_head_t wioctl;
+ struct mutex mutex;
+ u8 ctrlin; /* input control lines */
+ u8 ctrlout; /* output control lines */
+ struct gb_tty_line_coding line_coding;
+ struct work_struct tx_work;
+ struct kfifo write_fifo;
+ bool close_pending;
+ unsigned int credits;
+ struct completion credits_complete;
+};
+
+static struct tty_driver *gb_tty_driver;
+static DEFINE_IDR(tty_minors);
+static DEFINE_MUTEX(table_lock);
+
+static int gb_uart_receive_data_handler(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct gb_tty *gb_tty = gb_connection_get_data(connection);
+ struct tty_port *port = &gb_tty->port;
+ struct gb_message *request = op->request;
+ struct gb_uart_recv_data_request *receive_data;
+ u16 recv_data_size;
+ int count;
+ unsigned long tty_flags = TTY_NORMAL;
+
+ if (request->payload_size < sizeof(*receive_data)) {
+ dev_err(&gb_tty->gbphy_dev->dev,
+ "short receive-data request received (%zu < %zu)\n",
+ request->payload_size, sizeof(*receive_data));
+ return -EINVAL;
+ }
+
+ receive_data = op->request->payload;
+ recv_data_size = le16_to_cpu(receive_data->size);
+
+ if (recv_data_size != request->payload_size - sizeof(*receive_data)) {
+ dev_err(&gb_tty->gbphy_dev->dev,
+ "malformed receive-data request received (%u != %zu)\n",
+ recv_data_size,
+ request->payload_size - sizeof(*receive_data));
+ return -EINVAL;
+ }
+
+ if (!recv_data_size)
+ return -EINVAL;
+
+ if (receive_data->flags) {
+ if (receive_data->flags & GB_UART_RECV_FLAG_BREAK)
+ tty_flags = TTY_BREAK;
+ else if (receive_data->flags & GB_UART_RECV_FLAG_PARITY)
+ tty_flags = TTY_PARITY;
+ else if (receive_data->flags & GB_UART_RECV_FLAG_FRAMING)
+ tty_flags = TTY_FRAME;
+
+ /* overrun is special, not associated with a char */
+ if (receive_data->flags & GB_UART_RECV_FLAG_OVERRUN)
+ tty_insert_flip_char(port, 0, TTY_OVERRUN);
+ }
+ count = tty_insert_flip_string_fixed_flag(port, receive_data->data,
+ tty_flags, recv_data_size);
+ if (count != recv_data_size) {
+ dev_err(&gb_tty->gbphy_dev->dev,
+ "UART: RX 0x%08x bytes only wrote 0x%08x\n",
+ recv_data_size, count);
+ }
+ if (count)
+ tty_flip_buffer_push(port);
+ return 0;
+}
+
+static int gb_uart_serial_state_handler(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct gb_tty *gb_tty = gb_connection_get_data(connection);
+ struct gb_message *request = op->request;
+ struct gb_uart_serial_state_request *serial_state;
+
+ if (request->payload_size < sizeof(*serial_state)) {
+ dev_err(&gb_tty->gbphy_dev->dev,
+ "short serial-state event received (%zu < %zu)\n",
+ request->payload_size, sizeof(*serial_state));
+ return -EINVAL;
+ }
+
+ serial_state = request->payload;
+ gb_tty->ctrlin = serial_state->control;
+
+ return 0;
+}
+
+static int gb_uart_receive_credits_handler(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct gb_tty *gb_tty = gb_connection_get_data(connection);
+ struct gb_message *request = op->request;
+ struct gb_uart_receive_credits_request *credit_request;
+ unsigned long flags;
+ unsigned int incoming_credits;
+ int ret = 0;
+
+ if (request->payload_size < sizeof(*credit_request)) {
+ dev_err(&gb_tty->gbphy_dev->dev,
+ "short receive_credits event received (%zu < %zu)\n",
+ request->payload_size,
+ sizeof(*credit_request));
+ return -EINVAL;
+ }
+
+ credit_request = request->payload;
+ incoming_credits = le16_to_cpu(credit_request->count);
+
+ spin_lock_irqsave(&gb_tty->write_lock, flags);
+ gb_tty->credits += incoming_credits;
+ if (gb_tty->credits > GB_UART_FIRMWARE_CREDITS) {
+ gb_tty->credits -= incoming_credits;
+ ret = -EINVAL;
+ }
+ spin_unlock_irqrestore(&gb_tty->write_lock, flags);
+
+ if (ret) {
+ dev_err(&gb_tty->gbphy_dev->dev,
+ "invalid number of incoming credits: %d\n",
+ incoming_credits);
+ return ret;
+ }
+
+ if (!gb_tty->close_pending)
+ schedule_work(&gb_tty->tx_work);
+
+ /*
+ * the port the tty layer may be waiting for credits
+ */
+ tty_port_tty_wakeup(&gb_tty->port);
+
+ if (gb_tty->credits == GB_UART_FIRMWARE_CREDITS)
+ complete(&gb_tty->credits_complete);
+
+ return ret;
+}
+
+static int gb_uart_request_handler(struct gb_operation *op)
+{
+ struct gb_connection *connection = op->connection;
+ struct gb_tty *gb_tty = gb_connection_get_data(connection);
+ int type = op->type;
+ int ret;
+
+ switch (type) {
+ case GB_UART_TYPE_RECEIVE_DATA:
+ ret = gb_uart_receive_data_handler(op);
+ break;
+ case GB_UART_TYPE_SERIAL_STATE:
+ ret = gb_uart_serial_state_handler(op);
+ break;
+ case GB_UART_TYPE_RECEIVE_CREDITS:
+ ret = gb_uart_receive_credits_handler(op);
+ break;
+ default:
+ dev_err(&gb_tty->gbphy_dev->dev,
+ "unsupported unsolicited request: 0x%02x\n", type);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static void gb_uart_tx_write_work(struct work_struct *work)
+{
+ struct gb_uart_send_data_request *request;
+ struct gb_tty *gb_tty;
+ unsigned long flags;
+ unsigned int send_size;
+ int ret;
+
+ gb_tty = container_of(work, struct gb_tty, tx_work);
+ request = gb_tty->buffer;
+
+ while (1) {
+ if (gb_tty->close_pending)
+ break;
+
+ spin_lock_irqsave(&gb_tty->write_lock, flags);
+ send_size = gb_tty->buffer_payload_max;
+ if (send_size > gb_tty->credits)
+ send_size = gb_tty->credits;
+
+ send_size = kfifo_out_peek(&gb_tty->write_fifo,
+ &request->data[0],
+ send_size);
+ if (!send_size) {
+ spin_unlock_irqrestore(&gb_tty->write_lock, flags);
+ break;
+ }
+
+ gb_tty->credits -= send_size;
+ spin_unlock_irqrestore(&gb_tty->write_lock, flags);
+
+ request->size = cpu_to_le16(send_size);
+ ret = gb_operation_sync(gb_tty->connection,
+ GB_UART_TYPE_SEND_DATA,
+ request, sizeof(*request) + send_size,
+ NULL, 0);
+ if (ret) {
+ dev_err(&gb_tty->gbphy_dev->dev,
+ "send data error: %d\n", ret);
+ spin_lock_irqsave(&gb_tty->write_lock, flags);
+ gb_tty->credits += send_size;
+ spin_unlock_irqrestore(&gb_tty->write_lock, flags);
+ if (!gb_tty->close_pending)
+ schedule_work(work);
+ return;
+ }
+
+ spin_lock_irqsave(&gb_tty->write_lock, flags);
+ ret = kfifo_out(&gb_tty->write_fifo, &request->data[0],
+ send_size);
+ spin_unlock_irqrestore(&gb_tty->write_lock, flags);
+
+ tty_port_tty_wakeup(&gb_tty->port);
+ }
+}
+
+static int send_line_coding(struct gb_tty *tty)
+{
+ struct gb_uart_set_line_coding_request request;
+
+ memcpy(&request, &tty->line_coding,
+ sizeof(tty->line_coding));
+ return gb_operation_sync(tty->connection, GB_UART_TYPE_SET_LINE_CODING,
+ &request, sizeof(request), NULL, 0);
+}
+
+static int send_control(struct gb_tty *gb_tty, u8 control)
+{
+ struct gb_uart_set_control_line_state_request request;
+
+ request.control = control;
+ return gb_operation_sync(gb_tty->connection,
+ GB_UART_TYPE_SET_CONTROL_LINE_STATE,
+ &request, sizeof(request), NULL, 0);
+}
+
+static int send_break(struct gb_tty *gb_tty, u8 state)
+{
+ struct gb_uart_set_break_request request;
+
+ if ((state != 0) && (state != 1)) {
+ dev_err(&gb_tty->gbphy_dev->dev,
+ "invalid break state of %d\n", state);
+ return -EINVAL;
+ }
+
+ request.state = state;
+ return gb_operation_sync(gb_tty->connection, GB_UART_TYPE_SEND_BREAK,
+ &request, sizeof(request), NULL, 0);
+}
+
+static int gb_uart_wait_for_all_credits(struct gb_tty *gb_tty)
+{
+ int ret;
+
+ if (gb_tty->credits == GB_UART_FIRMWARE_CREDITS)
+ return 0;
+
+ ret = wait_for_completion_timeout(&gb_tty->credits_complete,
+ msecs_to_jiffies(GB_UART_CREDIT_WAIT_TIMEOUT_MSEC));
+ if (!ret) {
+ dev_err(&gb_tty->gbphy_dev->dev,
+ "time out waiting for credits\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int gb_uart_flush(struct gb_tty *gb_tty, u8 flags)
+{
+ struct gb_uart_serial_flush_request request;
+
+ request.flags = flags;
+ return gb_operation_sync(gb_tty->connection, GB_UART_TYPE_FLUSH_FIFOS,
+ &request, sizeof(request), NULL, 0);
+}
+
+static struct gb_tty *get_gb_by_minor(unsigned int minor)
+{
+ struct gb_tty *gb_tty;
+
+ mutex_lock(&table_lock);
+ gb_tty = idr_find(&tty_minors, minor);
+ if (gb_tty) {
+ mutex_lock(&gb_tty->mutex);
+ if (gb_tty->disconnected) {
+ mutex_unlock(&gb_tty->mutex);
+ gb_tty = NULL;
+ } else {
+ tty_port_get(&gb_tty->port);
+ mutex_unlock(&gb_tty->mutex);
+ }
+ }
+ mutex_unlock(&table_lock);
+ return gb_tty;
+}
+
+static int alloc_minor(struct gb_tty *gb_tty)
+{
+ int minor;
+
+ mutex_lock(&table_lock);
+ minor = idr_alloc(&tty_minors, gb_tty, 0, GB_NUM_MINORS, GFP_KERNEL);
+ mutex_unlock(&table_lock);
+ if (minor >= 0)
+ gb_tty->minor = minor;
+ return minor;
+}
+
+static void release_minor(struct gb_tty *gb_tty)
+{
+ int minor = gb_tty->minor;
+
+ gb_tty->minor = 0; /* Maybe should use an invalid value instead */
+ mutex_lock(&table_lock);
+ idr_remove(&tty_minors, minor);
+ mutex_unlock(&table_lock);
+}
+
+static int gb_tty_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+ struct gb_tty *gb_tty;
+ int retval;
+
+ gb_tty = get_gb_by_minor(tty->index);
+ if (!gb_tty)
+ return -ENODEV;
+
+ retval = tty_standard_install(driver, tty);
+ if (retval)
+ goto error;
+
+ tty->driver_data = gb_tty;
+ return 0;
+error:
+ tty_port_put(&gb_tty->port);
+ return retval;
+}
+
+static int gb_tty_open(struct tty_struct *tty, struct file *file)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+
+ return tty_port_open(&gb_tty->port, tty, file);
+}
+
+static void gb_tty_close(struct tty_struct *tty, struct file *file)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+
+ tty_port_close(&gb_tty->port, tty, file);
+}
+
+static void gb_tty_cleanup(struct tty_struct *tty)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+
+ tty_port_put(&gb_tty->port);
+}
+
+static void gb_tty_hangup(struct tty_struct *tty)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+
+ tty_port_hangup(&gb_tty->port);
+}
+
+static int gb_tty_write(struct tty_struct *tty, const unsigned char *buf,
+ int count)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+
+ count = kfifo_in_spinlocked(&gb_tty->write_fifo, buf, count,
+ &gb_tty->write_lock);
+ if (count && !gb_tty->close_pending)
+ schedule_work(&gb_tty->tx_work);
+
+ return count;
+}
+
+static int gb_tty_write_room(struct tty_struct *tty)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+ unsigned long flags;
+ int room;
+
+ spin_lock_irqsave(&gb_tty->write_lock, flags);
+ room = kfifo_avail(&gb_tty->write_fifo);
+ spin_unlock_irqrestore(&gb_tty->write_lock, flags);
+
+ room -= GB_UART_WRITE_ROOM_MARGIN;
+ if (room < 0)
+ return 0;
+
+ return room;
+}
+
+static int gb_tty_chars_in_buffer(struct tty_struct *tty)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+ unsigned long flags;
+ int chars;
+
+ spin_lock_irqsave(&gb_tty->write_lock, flags);
+ chars = kfifo_len(&gb_tty->write_fifo);
+ if (gb_tty->credits < GB_UART_FIRMWARE_CREDITS)
+ chars += GB_UART_FIRMWARE_CREDITS - gb_tty->credits;
+ spin_unlock_irqrestore(&gb_tty->write_lock, flags);
+
+ return chars;
+}
+
+static int gb_tty_break_ctl(struct tty_struct *tty, int state)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+
+ return send_break(gb_tty, state ? 1 : 0);
+}
+
+static void gb_tty_set_termios(struct tty_struct *tty,
+ struct ktermios *termios_old)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+ struct ktermios *termios = &tty->termios;
+ struct gb_tty_line_coding newline;
+ u8 newctrl = gb_tty->ctrlout;
+
+ newline.rate = cpu_to_le32(tty_get_baud_rate(tty));
+ newline.format = termios->c_cflag & CSTOPB ?
+ GB_SERIAL_2_STOP_BITS : GB_SERIAL_1_STOP_BITS;
+ newline.parity = termios->c_cflag & PARENB ?
+ (termios->c_cflag & PARODD ? 1 : 2) +
+ (termios->c_cflag & CMSPAR ? 2 : 0) : 0;
+
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ newline.data_bits = 5;
+ break;
+ case CS6:
+ newline.data_bits = 6;
+ break;
+ case CS7:
+ newline.data_bits = 7;
+ break;
+ case CS8:
+ default:
+ newline.data_bits = 8;
+ break;
+ }
+
+ /* FIXME: needs to clear unsupported bits in the termios */
+ gb_tty->clocal = ((termios->c_cflag & CLOCAL) != 0);
+
+ if (C_BAUD(tty) == B0) {
+ newline.rate = gb_tty->line_coding.rate;
+ newctrl &= ~(GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);
+ } else if (termios_old && (termios_old->c_cflag & CBAUD) == B0) {
+ newctrl |= (GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);
+ }
+
+ if (newctrl != gb_tty->ctrlout) {
+ gb_tty->ctrlout = newctrl;
+ send_control(gb_tty, newctrl);
+ }
+
+ if (C_CRTSCTS(tty) && C_BAUD(tty) != B0)
+ newline.flow_control |= GB_SERIAL_AUTO_RTSCTS_EN;
+ else
+ newline.flow_control &= ~GB_SERIAL_AUTO_RTSCTS_EN;
+
+ if (memcmp(&gb_tty->line_coding, &newline, sizeof(newline))) {
+ memcpy(&gb_tty->line_coding, &newline, sizeof(newline));
+ send_line_coding(gb_tty);
+ }
+}
+
+static int gb_tty_tiocmget(struct tty_struct *tty)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+
+ return (gb_tty->ctrlout & GB_UART_CTRL_DTR ? TIOCM_DTR : 0) |
+ (gb_tty->ctrlout & GB_UART_CTRL_RTS ? TIOCM_RTS : 0) |
+ (gb_tty->ctrlin & GB_UART_CTRL_DSR ? TIOCM_DSR : 0) |
+ (gb_tty->ctrlin & GB_UART_CTRL_RI ? TIOCM_RI : 0) |
+ (gb_tty->ctrlin & GB_UART_CTRL_DCD ? TIOCM_CD : 0) |
+ TIOCM_CTS;
+}
+
+static int gb_tty_tiocmset(struct tty_struct *tty, unsigned int set,
+ unsigned int clear)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+ u8 newctrl = gb_tty->ctrlout;
+
+ set = (set & TIOCM_DTR ? GB_UART_CTRL_DTR : 0) |
+ (set & TIOCM_RTS ? GB_UART_CTRL_RTS : 0);
+ clear = (clear & TIOCM_DTR ? GB_UART_CTRL_DTR : 0) |
+ (clear & TIOCM_RTS ? GB_UART_CTRL_RTS : 0);
+
+ newctrl = (newctrl & ~clear) | set;
+ if (gb_tty->ctrlout == newctrl)
+ return 0;
+
+ gb_tty->ctrlout = newctrl;
+ return send_control(gb_tty, newctrl);
+}
+
+static void gb_tty_throttle(struct tty_struct *tty)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+ unsigned char stop_char;
+ int retval;
+
+ if (I_IXOFF(tty)) {
+ stop_char = STOP_CHAR(tty);
+ retval = gb_tty_write(tty, &stop_char, 1);
+ if (retval <= 0)
+ return;
+ }
+
+ if (tty->termios.c_cflag & CRTSCTS) {
+ gb_tty->ctrlout &= ~GB_UART_CTRL_RTS;
+ retval = send_control(gb_tty, gb_tty->ctrlout);
+ }
+}
+
+static void gb_tty_unthrottle(struct tty_struct *tty)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+ unsigned char start_char;
+ int retval;
+
+ if (I_IXOFF(tty)) {
+ start_char = START_CHAR(tty);
+ retval = gb_tty_write(tty, &start_char, 1);
+ if (retval <= 0)
+ return;
+ }
+
+ if (tty->termios.c_cflag & CRTSCTS) {
+ gb_tty->ctrlout |= GB_UART_CTRL_RTS;
+ retval = send_control(gb_tty, gb_tty->ctrlout);
+ }
+}
+
+static int get_serial_info(struct gb_tty *gb_tty,
+ struct serial_struct __user *info)
+{
+ struct serial_struct tmp;
+
+ if (!info)
+ return -EINVAL;
+
+ memset(&tmp, 0, sizeof(tmp));
+ tmp.flags = ASYNC_LOW_LATENCY | ASYNC_SKIP_TEST;
+ tmp.type = PORT_16550A;
+ tmp.line = gb_tty->minor;
+ tmp.xmit_fifo_size = 16;
+ tmp.baud_base = 9600;
+ tmp.close_delay = gb_tty->port.close_delay / 10;
+ tmp.closing_wait = gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
+ ASYNC_CLOSING_WAIT_NONE : gb_tty->port.closing_wait / 10;
+
+ if (copy_to_user(info, &tmp, sizeof(tmp)))
+ return -EFAULT;
+ return 0;
+}
+
+static int set_serial_info(struct gb_tty *gb_tty,
+ struct serial_struct __user *newinfo)
+{
+ struct serial_struct new_serial;
+ unsigned int closing_wait;
+ unsigned int close_delay;
+ int retval = 0;
+
+ if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
+ return -EFAULT;
+
+ close_delay = new_serial.close_delay * 10;
+ closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
+ ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;
+
+ mutex_lock(&gb_tty->port.mutex);
+ if (!capable(CAP_SYS_ADMIN)) {
+ if ((close_delay != gb_tty->port.close_delay) ||
+ (closing_wait != gb_tty->port.closing_wait))
+ retval = -EPERM;
+ else
+ retval = -EOPNOTSUPP;
+ } else {
+ gb_tty->port.close_delay = close_delay;
+ gb_tty->port.closing_wait = closing_wait;
+ }
+ mutex_unlock(&gb_tty->port.mutex);
+ return retval;
+}
+
+static int wait_serial_change(struct gb_tty *gb_tty, unsigned long arg)
+{
+ int retval = 0;
+ DECLARE_WAITQUEUE(wait, current);
+ struct async_icount old;
+ struct async_icount new;
+
+ if (!(arg & (TIOCM_DSR | TIOCM_RI | TIOCM_CD)))
+ return -EINVAL;
+
+ do {
+ spin_lock_irq(&gb_tty->read_lock);
+ old = gb_tty->oldcount;
+ new = gb_tty->iocount;
+ gb_tty->oldcount = new;
+ spin_unlock_irq(&gb_tty->read_lock);
+
+ if ((arg & TIOCM_DSR) && (old.dsr != new.dsr))
+ break;
+ if ((arg & TIOCM_CD) && (old.dcd != new.dcd))
+ break;
+ if ((arg & TIOCM_RI) && (old.rng != new.rng))
+ break;
+
+ add_wait_queue(&gb_tty->wioctl, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ remove_wait_queue(&gb_tty->wioctl, &wait);
+ if (gb_tty->disconnected) {
+ if (arg & TIOCM_CD)
+ break;
+ retval = -ENODEV;
+ } else if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ }
+ } while (!retval);
+
+ return retval;
+}
+
+static int get_serial_usage(struct gb_tty *gb_tty,
+ struct serial_icounter_struct __user *count)
+{
+ struct serial_icounter_struct icount;
+ int retval = 0;
+
+ memset(&icount, 0, sizeof(icount));
+ icount.dsr = gb_tty->iocount.dsr;
+ icount.rng = gb_tty->iocount.rng;
+ icount.dcd = gb_tty->iocount.dcd;
+ icount.frame = gb_tty->iocount.frame;
+ icount.overrun = gb_tty->iocount.overrun;
+ icount.parity = gb_tty->iocount.parity;
+ icount.brk = gb_tty->iocount.brk;
+
+ if (copy_to_user(count, &icount, sizeof(icount)) > 0)
+ retval = -EFAULT;
+
+ return retval;
+}
+
+static int gb_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
+ unsigned long arg)
+{
+ struct gb_tty *gb_tty = tty->driver_data;
+
+ switch (cmd) {
+ case TIOCGSERIAL:
+ return get_serial_info(gb_tty,
+ (struct serial_struct __user *)arg);
+ case TIOCSSERIAL:
+ return set_serial_info(gb_tty,
+ (struct serial_struct __user *)arg);
+ case TIOCMIWAIT:
+ return wait_serial_change(gb_tty, arg);
+ case TIOCGICOUNT:
+ return get_serial_usage(gb_tty,
+ (struct serial_icounter_struct __user *)arg);
+ }
+
+ return -ENOIOCTLCMD;
+}
+
+static void gb_tty_dtr_rts(struct tty_port *port, int on)
+{
+ struct gb_tty *gb_tty;
+ u8 newctrl;
+
+ gb_tty = container_of(port, struct gb_tty, port);
+ newctrl = gb_tty->ctrlout;
+
+ if (on)
+ newctrl |= (GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);
+ else
+ newctrl &= ~(GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);
+
+ gb_tty->ctrlout = newctrl;
+ send_control(gb_tty, newctrl);
+}
+
+static int gb_tty_port_activate(struct tty_port *port,
+ struct tty_struct *tty)
+{
+ struct gb_tty *gb_tty;
+
+ gb_tty = container_of(port, struct gb_tty, port);
+
+ return gbphy_runtime_get_sync(gb_tty->gbphy_dev);
+}
+
+static void gb_tty_port_shutdown(struct tty_port *port)
+{
+ struct gb_tty *gb_tty;
+ unsigned long flags;
+ int ret;
+
+ gb_tty = container_of(port, struct gb_tty, port);
+
+ gb_tty->close_pending = true;
+
+ cancel_work_sync(&gb_tty->tx_work);
+
+ spin_lock_irqsave(&gb_tty->write_lock, flags);
+ kfifo_reset_out(&gb_tty->write_fifo);
+ spin_unlock_irqrestore(&gb_tty->write_lock, flags);
+
+ if (gb_tty->credits == GB_UART_FIRMWARE_CREDITS)
+ goto out;
+
+ ret = gb_uart_flush(gb_tty, GB_SERIAL_FLAG_FLUSH_TRANSMITTER);
+ if (ret) {
+ dev_err(&gb_tty->gbphy_dev->dev,
+ "error flushing transmitter: %d\n", ret);
+ }
+
+ gb_uart_wait_for_all_credits(gb_tty);
+
+out:
+ gb_tty->close_pending = false;
+
+ gbphy_runtime_put_autosuspend(gb_tty->gbphy_dev);
+}
+
+static const struct tty_operations gb_ops = {
+ .install = gb_tty_install,
+ .open = gb_tty_open,
+ .close = gb_tty_close,
+ .cleanup = gb_tty_cleanup,
+ .hangup = gb_tty_hangup,
+ .write = gb_tty_write,
+ .write_room = gb_tty_write_room,
+ .ioctl = gb_tty_ioctl,
+ .throttle = gb_tty_throttle,
+ .unthrottle = gb_tty_unthrottle,
+ .chars_in_buffer = gb_tty_chars_in_buffer,
+ .break_ctl = gb_tty_break_ctl,
+ .set_termios = gb_tty_set_termios,
+ .tiocmget = gb_tty_tiocmget,
+ .tiocmset = gb_tty_tiocmset,
+};
+
+static struct tty_port_operations gb_port_ops = {
+ .dtr_rts = gb_tty_dtr_rts,
+ .activate = gb_tty_port_activate,
+ .shutdown = gb_tty_port_shutdown,
+};
+
+static int gb_uart_probe(struct gbphy_device *gbphy_dev,
+ const struct gbphy_device_id *id)
+{
+ struct gb_connection *connection;
+ size_t max_payload;
+ struct gb_tty *gb_tty;
+ struct device *tty_dev;
+ int retval;
+ int minor;
+
+ gb_tty = kzalloc(sizeof(*gb_tty), GFP_KERNEL);
+ if (!gb_tty)
+ return -ENOMEM;
+
+ connection = gb_connection_create(gbphy_dev->bundle,
+ le16_to_cpu(gbphy_dev->cport_desc->id),
+ gb_uart_request_handler);
+ if (IS_ERR(connection)) {
+ retval = PTR_ERR(connection);
+ goto exit_tty_free;
+ }
+
+ max_payload = gb_operation_get_payload_size_max(connection);
+ if (max_payload < sizeof(struct gb_uart_send_data_request)) {
+ retval = -EINVAL;
+ goto exit_connection_destroy;
+ }
+
+ gb_tty->buffer_payload_max = max_payload -
+ sizeof(struct gb_uart_send_data_request);
+
+ gb_tty->buffer = kzalloc(gb_tty->buffer_payload_max, GFP_KERNEL);
+ if (!gb_tty->buffer) {
+ retval = -ENOMEM;
+ goto exit_connection_destroy;
+ }
+
+ INIT_WORK(&gb_tty->tx_work, gb_uart_tx_write_work);
+
+ retval = kfifo_alloc(&gb_tty->write_fifo, GB_UART_WRITE_FIFO_SIZE,
+ GFP_KERNEL);
+ if (retval)
+ goto exit_buf_free;
+
+ gb_tty->credits = GB_UART_FIRMWARE_CREDITS;
+ init_completion(&gb_tty->credits_complete);
+
+ minor = alloc_minor(gb_tty);
+ if (minor < 0) {
+ if (minor == -ENOSPC) {
+ dev_err(&connection->bundle->dev,
+ "no more free minor numbers\n");
+ retval = -ENODEV;
+ } else {
+ retval = minor;
+ }
+ goto exit_kfifo_free;
+ }
+
+ gb_tty->minor = minor;
+ spin_lock_init(&gb_tty->write_lock);
+ spin_lock_init(&gb_tty->read_lock);
+ init_waitqueue_head(&gb_tty->wioctl);
+ mutex_init(&gb_tty->mutex);
+
+ tty_port_init(&gb_tty->port);
+ gb_tty->port.ops = &gb_port_ops;
+
+ gb_tty->connection = connection;
+ gb_tty->gbphy_dev = gbphy_dev;
+ gb_connection_set_data(connection, gb_tty);
+ gb_gbphy_set_data(gbphy_dev, gb_tty);
+
+ retval = gb_connection_enable_tx(connection);
+ if (retval)
+ goto exit_release_minor;
+
+ send_control(gb_tty, gb_tty->ctrlout);
+
+ /* initialize the uart to be 9600n81 */
+ gb_tty->line_coding.rate = cpu_to_le32(9600);
+ gb_tty->line_coding.format = GB_SERIAL_1_STOP_BITS;
+ gb_tty->line_coding.parity = GB_SERIAL_NO_PARITY;
+ gb_tty->line_coding.data_bits = 8;
+ send_line_coding(gb_tty);
+
+ retval = gb_connection_enable(connection);
+ if (retval)
+ goto exit_connection_disable;
+
+ tty_dev = tty_port_register_device(&gb_tty->port, gb_tty_driver, minor,
+ &gbphy_dev->dev);
+ if (IS_ERR(tty_dev)) {
+ retval = PTR_ERR(tty_dev);
+ goto exit_connection_disable;
+ }
+
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+ return 0;
+
+exit_connection_disable:
+ gb_connection_disable(connection);
+exit_release_minor:
+ release_minor(gb_tty);
+exit_kfifo_free:
+ kfifo_free(&gb_tty->write_fifo);
+exit_buf_free:
+ kfree(gb_tty->buffer);
+exit_connection_destroy:
+ gb_connection_destroy(connection);
+exit_tty_free:
+ kfree(gb_tty);
+
+ return retval;
+}
+
+static void gb_uart_remove(struct gbphy_device *gbphy_dev)
+{
+ struct gb_tty *gb_tty = gb_gbphy_get_data(gbphy_dev);
+ struct gb_connection *connection = gb_tty->connection;
+ struct tty_struct *tty;
+ int ret;
+
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ gbphy_runtime_get_noresume(gbphy_dev);
+
+ mutex_lock(&gb_tty->mutex);
+ gb_tty->disconnected = true;
+
+ wake_up_all(&gb_tty->wioctl);
+ mutex_unlock(&gb_tty->mutex);
+
+ tty = tty_port_tty_get(&gb_tty->port);
+ if (tty) {
+ tty_vhangup(tty);
+ tty_kref_put(tty);
+ }
+
+ gb_connection_disable_rx(connection);
+ tty_unregister_device(gb_tty_driver, gb_tty->minor);
+
+ /* FIXME - free transmit / receive buffers */
+
+ gb_connection_disable(connection);
+ tty_port_destroy(&gb_tty->port);
+ gb_connection_destroy(connection);
+ release_minor(gb_tty);
+ kfifo_free(&gb_tty->write_fifo);
+ kfree(gb_tty->buffer);
+ kfree(gb_tty);
+}
+
+static int gb_tty_init(void)
+{
+ int retval = 0;
+
+ gb_tty_driver = tty_alloc_driver(GB_NUM_MINORS, 0);
+ if (IS_ERR(gb_tty_driver)) {
+ pr_err("Can not allocate tty driver\n");
+ retval = -ENOMEM;
+ goto fail_unregister_dev;
+ }
+
+ gb_tty_driver->driver_name = "gb";
+ gb_tty_driver->name = GB_NAME;
+ gb_tty_driver->major = 0;
+ gb_tty_driver->minor_start = 0;
+ gb_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
+ gb_tty_driver->subtype = SERIAL_TYPE_NORMAL;
+ gb_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+ gb_tty_driver->init_termios = tty_std_termios;
+ gb_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ tty_set_operations(gb_tty_driver, &gb_ops);
+
+ retval = tty_register_driver(gb_tty_driver);
+ if (retval) {
+ pr_err("Can not register tty driver: %d\n", retval);
+ goto fail_put_gb_tty;
+ }
+
+ return 0;
+
+fail_put_gb_tty:
+ put_tty_driver(gb_tty_driver);
+fail_unregister_dev:
+ return retval;
+}
+
+static void gb_tty_exit(void)
+{
+ tty_unregister_driver(gb_tty_driver);
+ put_tty_driver(gb_tty_driver);
+ idr_destroy(&tty_minors);
+}
+
+static const struct gbphy_device_id gb_uart_id_table[] = {
+ { GBPHY_PROTOCOL(GREYBUS_PROTOCOL_UART) },
+ { },
+};
+MODULE_DEVICE_TABLE(gbphy, gb_uart_id_table);
+
+static struct gbphy_driver uart_driver = {
+ .name = "uart",
+ .probe = gb_uart_probe,
+ .remove = gb_uart_remove,
+ .id_table = gb_uart_id_table,
+};
+
+static int gb_uart_driver_init(void)
+{
+ int ret;
+
+ ret = gb_tty_init();
+ if (ret)
+ return ret;
+
+ ret = gb_gbphy_register(&uart_driver);
+ if (ret) {
+ gb_tty_exit();
+ return ret;
+ }
+
+ return 0;
+}
+module_init(gb_uart_driver_init);
+
+static void gb_uart_driver_exit(void)
+{
+ gb_gbphy_deregister(&uart_driver);
+ gb_tty_exit();
+}
+
+module_exit(gb_uart_driver_exit);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/usb.c b/drivers/staging/greybus/usb.c
new file mode 100644
index 000000000000..ccadda084b76
--- /dev/null
+++ b/drivers/staging/greybus/usb.c
@@ -0,0 +1,247 @@
+/*
+ * USB host driver for the Greybus "generic" USB module.
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "greybus.h"
+#include "gbphy.h"
+
+/* Greybus USB request types */
+#define GB_USB_TYPE_HCD_START 0x02
+#define GB_USB_TYPE_HCD_STOP 0x03
+#define GB_USB_TYPE_HUB_CONTROL 0x04
+
+struct gb_usb_hub_control_request {
+ __le16 typeReq;
+ __le16 wValue;
+ __le16 wIndex;
+ __le16 wLength;
+};
+
+struct gb_usb_hub_control_response {
+ u8 buf[0];
+};
+
+struct gb_usb_device {
+ struct gb_connection *connection;
+ struct gbphy_device *gbphy_dev;
+};
+
+static inline struct gb_usb_device *to_gb_usb_device(struct usb_hcd *hcd)
+{
+ return (struct gb_usb_device *)hcd->hcd_priv;
+}
+
+static inline struct usb_hcd *gb_usb_device_to_hcd(struct gb_usb_device *dev)
+{
+ return container_of((void *)dev, struct usb_hcd, hcd_priv);
+}
+
+static void hcd_stop(struct usb_hcd *hcd)
+{
+ struct gb_usb_device *dev = to_gb_usb_device(hcd);
+ int ret;
+
+ ret = gb_operation_sync(dev->connection, GB_USB_TYPE_HCD_STOP,
+ NULL, 0, NULL, 0);
+ if (ret)
+ dev_err(&dev->gbphy_dev->dev, "HCD stop failed '%d'\n", ret);
+}
+
+static int hcd_start(struct usb_hcd *hcd)
+{
+ struct usb_bus *bus = hcd_to_bus(hcd);
+ struct gb_usb_device *dev = to_gb_usb_device(hcd);
+ int ret;
+
+ ret = gb_operation_sync(dev->connection, GB_USB_TYPE_HCD_START,
+ NULL, 0, NULL, 0);
+ if (ret) {
+ dev_err(&dev->gbphy_dev->dev, "HCD start failed '%d'\n", ret);
+ return ret;
+ }
+
+ hcd->state = HC_STATE_RUNNING;
+ if (bus->root_hub)
+ usb_hcd_resume_root_hub(hcd);
+ return 0;
+}
+
+static int urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
+{
+ return -ENXIO;
+}
+
+static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+{
+ return -ENXIO;
+}
+
+static int get_frame_number(struct usb_hcd *hcd)
+{
+ return 0;
+}
+
+static int hub_status_data(struct usb_hcd *hcd, char *buf)
+{
+ return 0;
+}
+
+static int hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
+ char *buf, u16 wLength)
+{
+ struct gb_usb_device *dev = to_gb_usb_device(hcd);
+ struct gb_operation *operation;
+ struct gb_usb_hub_control_request *request;
+ struct gb_usb_hub_control_response *response;
+ size_t response_size;
+ int ret;
+
+ /* FIXME: handle unspecified lengths */
+ response_size = sizeof(*response) + wLength;
+
+ operation = gb_operation_create(dev->connection,
+ GB_USB_TYPE_HUB_CONTROL,
+ sizeof(*request),
+ response_size,
+ GFP_KERNEL);
+ if (!operation)
+ return -ENOMEM;
+
+ request = operation->request->payload;
+ request->typeReq = cpu_to_le16(typeReq);
+ request->wValue = cpu_to_le16(wValue);
+ request->wIndex = cpu_to_le16(wIndex);
+ request->wLength = cpu_to_le16(wLength);
+
+ ret = gb_operation_request_send_sync(operation);
+ if (ret)
+ goto out;
+
+ if (wLength) {
+ /* Greybus core has verified response size */
+ response = operation->response->payload;
+ memcpy(buf, response->buf, wLength);
+ }
+out:
+ gb_operation_put(operation);
+
+ return ret;
+}
+
+static struct hc_driver usb_gb_hc_driver = {
+ .description = "greybus-hcd",
+ .product_desc = "Greybus USB Host Controller",
+ .hcd_priv_size = sizeof(struct gb_usb_device),
+
+ .flags = HCD_USB2,
+
+ .start = hcd_start,
+ .stop = hcd_stop,
+
+ .urb_enqueue = urb_enqueue,
+ .urb_dequeue = urb_dequeue,
+
+ .get_frame_number = get_frame_number,
+ .hub_status_data = hub_status_data,
+ .hub_control = hub_control,
+};
+
+static int gb_usb_probe(struct gbphy_device *gbphy_dev,
+ const struct gbphy_device_id *id)
+{
+ struct gb_connection *connection;
+ struct device *dev = &gbphy_dev->dev;
+ struct gb_usb_device *gb_usb_dev;
+ struct usb_hcd *hcd;
+ int retval;
+
+ hcd = usb_create_hcd(&usb_gb_hc_driver, dev, dev_name(dev));
+ if (!hcd)
+ return -ENOMEM;
+
+ connection = gb_connection_create(gbphy_dev->bundle,
+ le16_to_cpu(gbphy_dev->cport_desc->id),
+ NULL);
+ if (IS_ERR(connection)) {
+ retval = PTR_ERR(connection);
+ goto exit_usb_put;
+ }
+
+ gb_usb_dev = to_gb_usb_device(hcd);
+ gb_usb_dev->connection = connection;
+ gb_connection_set_data(connection, gb_usb_dev);
+ gb_usb_dev->gbphy_dev = gbphy_dev;
+ gb_gbphy_set_data(gbphy_dev, gb_usb_dev);
+
+ hcd->has_tt = 1;
+
+ retval = gb_connection_enable(connection);
+ if (retval)
+ goto exit_connection_destroy;
+
+ /*
+ * FIXME: The USB bridged-PHY protocol driver depends on changes to
+ * USB core which are not yet upstream.
+ *
+ * Disable for now.
+ */
+ if (1) {
+ dev_warn(dev, "USB protocol disabled\n");
+ retval = -EPROTONOSUPPORT;
+ goto exit_connection_disable;
+ }
+
+ retval = usb_add_hcd(hcd, 0, 0);
+ if (retval)
+ goto exit_connection_disable;
+
+ return 0;
+
+exit_connection_disable:
+ gb_connection_disable(connection);
+exit_connection_destroy:
+ gb_connection_destroy(connection);
+exit_usb_put:
+ usb_put_hcd(hcd);
+
+ return retval;
+}
+
+static void gb_usb_remove(struct gbphy_device *gbphy_dev)
+{
+ struct gb_usb_device *gb_usb_dev = gb_gbphy_get_data(gbphy_dev);
+ struct gb_connection *connection = gb_usb_dev->connection;
+ struct usb_hcd *hcd = gb_usb_device_to_hcd(gb_usb_dev);
+
+ usb_remove_hcd(hcd);
+ gb_connection_disable(connection);
+ gb_connection_destroy(connection);
+ usb_put_hcd(hcd);
+}
+
+static const struct gbphy_device_id gb_usb_id_table[] = {
+ { GBPHY_PROTOCOL(GREYBUS_PROTOCOL_USB) },
+ { },
+};
+MODULE_DEVICE_TABLE(gbphy, gb_usb_id_table);
+
+static struct gbphy_driver usb_driver = {
+ .name = "usb",
+ .probe = gb_usb_probe,
+ .remove = gb_usb_remove,
+ .id_table = gb_usb_id_table,
+};
+
+module_gbphy_driver(usb_driver);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/greybus/vibrator.c b/drivers/staging/greybus/vibrator.c
new file mode 100644
index 000000000000..4ba0e168930f
--- /dev/null
+++ b/drivers/staging/greybus/vibrator.c
@@ -0,0 +1,249 @@
+/*
+ * Greybus Vibrator protocol driver.
+ *
+ * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
+ *
+ * Released under the GPLv2 only.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/kdev_t.h>
+#include <linux/idr.h>
+#include <linux/pm_runtime.h>
+
+#include "greybus.h"
+
+struct gb_vibrator_device {
+ struct gb_connection *connection;
+ struct device *dev;
+ int minor; /* vibrator minor number */
+ struct delayed_work delayed_work;
+};
+
+/* Greybus Vibrator operation types */
+#define GB_VIBRATOR_TYPE_ON 0x02
+#define GB_VIBRATOR_TYPE_OFF 0x03
+
+static int turn_off(struct gb_vibrator_device *vib)
+{
+ struct gb_bundle *bundle = vib->connection->bundle;
+ int ret;
+
+ ret = gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_OFF,
+ NULL, 0, NULL, 0);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return ret;
+}
+
+static int turn_on(struct gb_vibrator_device *vib, u16 timeout_ms)
+{
+ struct gb_bundle *bundle = vib->connection->bundle;
+ int ret;
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ return ret;
+
+ /* Vibrator was switched ON earlier */
+ if (cancel_delayed_work_sync(&vib->delayed_work))
+ turn_off(vib);
+
+ ret = gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_ON,
+ NULL, 0, NULL, 0);
+ if (ret) {
+ gb_pm_runtime_put_autosuspend(bundle);
+ return ret;
+ }
+
+ schedule_delayed_work(&vib->delayed_work, msecs_to_jiffies(timeout_ms));
+
+ return 0;
+}
+
+static void gb_vibrator_worker(struct work_struct *work)
+{
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ struct gb_vibrator_device *vib =
+ container_of(delayed_work, struct gb_vibrator_device, delayed_work);
+
+ turn_off(vib);
+}
+
+static ssize_t timeout_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct gb_vibrator_device *vib = dev_get_drvdata(dev);
+ unsigned long val;
+ int retval;
+
+ retval = kstrtoul(buf, 10, &val);
+ if (retval < 0) {
+ dev_err(dev, "could not parse timeout value %d\n", retval);
+ return retval;
+ }
+
+ if (val)
+ retval = turn_on(vib, (u16)val);
+ else
+ retval = turn_off(vib);
+ if (retval)
+ return retval;
+
+ return count;
+}
+static DEVICE_ATTR_WO(timeout);
+
+static struct attribute *vibrator_attrs[] = {
+ &dev_attr_timeout.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(vibrator);
+
+static struct class vibrator_class = {
+ .name = "vibrator",
+ .owner = THIS_MODULE,
+ .dev_groups = vibrator_groups,
+};
+
+static DEFINE_IDA(minors);
+
+static int gb_vibrator_probe(struct gb_bundle *bundle,
+ const struct greybus_bundle_id *id)
+{
+ struct greybus_descriptor_cport *cport_desc;
+ struct gb_connection *connection;
+ struct gb_vibrator_device *vib;
+ struct device *dev;
+ int retval;
+
+ if (bundle->num_cports != 1)
+ return -ENODEV;
+
+ cport_desc = &bundle->cport_desc[0];
+ if (cport_desc->protocol_id != GREYBUS_PROTOCOL_VIBRATOR)
+ return -ENODEV;
+
+ vib = kzalloc(sizeof(*vib), GFP_KERNEL);
+ if (!vib)
+ return -ENOMEM;
+
+ connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
+ NULL);
+ if (IS_ERR(connection)) {
+ retval = PTR_ERR(connection);
+ goto err_free_vib;
+ }
+ gb_connection_set_data(connection, vib);
+
+ vib->connection = connection;
+
+ greybus_set_drvdata(bundle, vib);
+
+ retval = gb_connection_enable(connection);
+ if (retval)
+ goto err_connection_destroy;
+
+ /*
+ * For now we create a device in sysfs for the vibrator, but odds are
+ * there is a "real" device somewhere in the kernel for this, but I
+ * can't find it at the moment...
+ */
+ vib->minor = ida_simple_get(&minors, 0, 0, GFP_KERNEL);
+ if (vib->minor < 0) {
+ retval = vib->minor;
+ goto err_connection_disable;
+ }
+ dev = device_create(&vibrator_class, &bundle->dev,
+ MKDEV(0, 0), vib, "vibrator%d", vib->minor);
+ if (IS_ERR(dev)) {
+ retval = -EINVAL;
+ goto err_ida_remove;
+ }
+ vib->dev = dev;
+
+ INIT_DELAYED_WORK(&vib->delayed_work, gb_vibrator_worker);
+
+ gb_pm_runtime_put_autosuspend(bundle);
+
+ return 0;
+
+err_ida_remove:
+ ida_simple_remove(&minors, vib->minor);
+err_connection_disable:
+ gb_connection_disable(connection);
+err_connection_destroy:
+ gb_connection_destroy(connection);
+err_free_vib:
+ kfree(vib);
+
+ return retval;
+}
+
+static void gb_vibrator_disconnect(struct gb_bundle *bundle)
+{
+ struct gb_vibrator_device *vib = greybus_get_drvdata(bundle);
+ int ret;
+
+ ret = gb_pm_runtime_get_sync(bundle);
+ if (ret)
+ gb_pm_runtime_get_noresume(bundle);
+
+ if (cancel_delayed_work_sync(&vib->delayed_work))
+ turn_off(vib);
+
+ device_unregister(vib->dev);
+ ida_simple_remove(&minors, vib->minor);
+ gb_connection_disable(vib->connection);
+ gb_connection_destroy(vib->connection);
+ kfree(vib);
+}
+
+static const struct greybus_bundle_id gb_vibrator_id_table[] = {
+ { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_VIBRATOR) },
+ { }
+};
+MODULE_DEVICE_TABLE(greybus, gb_vibrator_id_table);
+
+static struct greybus_driver gb_vibrator_driver = {
+ .name = "vibrator",
+ .probe = gb_vibrator_probe,
+ .disconnect = gb_vibrator_disconnect,
+ .id_table = gb_vibrator_id_table,
+};
+
+static __init int gb_vibrator_init(void)
+{
+ int retval;
+
+ retval = class_register(&vibrator_class);
+ if (retval)
+ return retval;
+
+ retval = greybus_register(&gb_vibrator_driver);
+ if (retval)
+ goto err_class_unregister;
+
+ return 0;
+
+err_class_unregister:
+ class_unregister(&vibrator_class);
+
+ return retval;
+}
+module_init(gb_vibrator_init);
+
+static __exit void gb_vibrator_exit(void)
+{
+ greybus_deregister(&gb_vibrator_driver);
+ class_unregister(&vibrator_class);
+ ida_destroy(&minors);
+}
+module_exit(gb_vibrator_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c
index a221f261c3d3..8ed4d395be58 100644
--- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c
+++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c
@@ -8,10 +8,6 @@
* 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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.h b/drivers/staging/gs_fpgaboot/gs_fpgaboot.h
index 8cc32555dbf3..7b8cc3a25214 100644
--- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.h
+++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.h
@@ -7,12 +7,7 @@
* 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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/firmware.h>
diff --git a/drivers/staging/gs_fpgaboot/io.h b/drivers/staging/gs_fpgaboot/io.h
index 7b46ac24b74e..5e839b1fc884 100644
--- a/drivers/staging/gs_fpgaboot/io.h
+++ b/drivers/staging/gs_fpgaboot/io.h
@@ -66,10 +66,8 @@ enum wbus {
bus_2byte = 2,
};
-
#define MAX_WAIT_DONE 10000
-
struct gpiobus {
int ngpio;
void __iomem *r[4];
diff --git a/drivers/staging/i4l/act2000/act2000_isa.c b/drivers/staging/i4l/act2000/act2000_isa.c
index f0eb8441deed..ad7a0391369f 100644
--- a/drivers/staging/i4l/act2000/act2000_isa.c
+++ b/drivers/staging/i4l/act2000/act2000_isa.c
@@ -134,9 +134,9 @@ act2000_isa_config_irq(act2000_card *card, short irq)
{
int old_irq;
- if (card->flags & ACT2000_FLAGS_IVALID) {
+ if (card->flags & ACT2000_FLAGS_IVALID)
free_irq(card->irq, card);
- }
+
card->flags &= ~ACT2000_FLAGS_IVALID;
outb(ISA_COR_IRQOFF, ISA_PORT_COR);
if (!irq)
@@ -166,7 +166,7 @@ act2000_isa_config_port(act2000_card *card, unsigned short portbase)
release_region(card->port, ISA_REGION);
card->flags &= ~ACT2000_FLAGS_PVALID;
}
- if (request_region(portbase, ACT2000_PORTLEN, card->regname) == NULL)
+ if (!request_region(portbase, ACT2000_PORTLEN, card->regname))
return -EBUSY;
else {
card->port = portbase;
@@ -176,7 +176,7 @@ act2000_isa_config_port(act2000_card *card, unsigned short portbase)
}
/*
- * Release ressources, used by an adaptor.
+ * Release resources, used by an adaptor.
*/
void
act2000_isa_release(act2000_card *card)
@@ -244,7 +244,7 @@ act2000_isa_receive(act2000_card *card)
if (valid) {
card->idat.isa.rcvlen = ((actcapi_msghdr *)&card->idat.isa.rcvhdr)->len;
card->idat.isa.rcvskb = dev_alloc_skb(card->idat.isa.rcvlen);
- if (card->idat.isa.rcvskb == NULL) {
+ if (!card->idat.isa.rcvskb) {
card->idat.isa.rcvignore = 1;
printk(KERN_WARNING
"act2000_isa_receive: no memory\n");
@@ -399,7 +399,6 @@ act2000_isa_download(act2000_card *card, act2000_ddef __user *cb)
unsigned int length;
int l;
int c;
- long timeout;
u_char *b;
u_char __user *p;
u_char *buf;
@@ -417,7 +416,6 @@ act2000_isa_download(act2000_card *card, act2000_ddef __user *cb)
buf = kmalloc(1024, GFP_KERNEL);
if (!buf)
return -ENOMEM;
- timeout = 0;
while (length) {
l = (length > 1024) ? 1024 : length;
c = 0;
diff --git a/drivers/staging/i4l/act2000/capi.c b/drivers/staging/i4l/act2000/capi.c
index 3f66ca20b5e5..62f56294853c 100644
--- a/drivers/staging/i4l/act2000/capi.c
+++ b/drivers/staging/i4l/act2000/capi.c
@@ -113,7 +113,9 @@ actcapi_chkhdr(act2000_card *card, actcapi_msghdr *hdr)
m->hdr.cmd.cmd = c; \
m->hdr.cmd.subcmd = s; \
m->hdr.msgnum = actcapi_nextsmsg(card); \
- } else m = NULL; \
+ } else { \
+ m = NULL; \
+ } \
}
#define ACTCAPI_CHKSKB if (!skb) { \
@@ -547,12 +549,11 @@ static int
actcapi_data_b3_ind(act2000_card *card, struct sk_buff *skb) {
__u16 plci;
__u16 ncci;
- __u16 controller;
__u8 blocknr;
int chan;
actcapi_msg *msg = (actcapi_msg *)skb->data;
- EVAL_NCCI(msg->msg.data_b3_ind.fakencci, plci, controller, ncci);
+ EVAL_NCCI(msg->msg.data_b3_ind.fakencci, plci, ncci);
chan = find_ncci(card, ncci);
if (chan < 0)
return 0;
@@ -617,7 +618,7 @@ handle_ack(act2000_card *card, act2000_chan *chan, __u8 blocknr) {
spin_lock_irqsave(&card->lock, flags);
tmp = skb_peek((struct sk_buff_head *)tmp);
spin_unlock_irqrestore(&card->lock, flags);
- if ((tmp == skb) || (tmp == NULL)) {
+ if ((tmp == skb) || !tmp) {
/* reached end of queue */
printk(KERN_WARNING "act2000: handle_ack nothing found!\n");
return 0;
@@ -990,7 +991,8 @@ actcapi_debug_dlpd(actcapi_dlpd *dlpd)
}
#ifdef DEBUG_DUMP_SKB
-static void dump_skb(struct sk_buff *skb) {
+static void dump_skb(struct sk_buff *skb)
+{
char tmp[80];
char *p = skb->data;
char *t = tmp;
diff --git a/drivers/staging/i4l/act2000/capi.h b/drivers/staging/i4l/act2000/capi.h
index 01ccdecd43f7..34884a5efee5 100644
--- a/drivers/staging/i4l/act2000/capi.h
+++ b/drivers/staging/i4l/act2000/capi.h
@@ -114,9 +114,8 @@ typedef struct actcapi_ncpd {
#define MAKE_NCCI(plci, contr, ncci) \
((plci & 0x1f) | ((contr & 0x7) << 5) | ((ncci & 0xff) << 8))
-#define EVAL_NCCI(fakencci, plci, contr, ncci) { \
+#define EVAL_NCCI(fakencci, plci, ncci) { \
plci = fakencci & 0x1f; \
- contr = (fakencci >> 5) & 0x7; \
ncci = (fakencci >> 8) & 0xff; \
}
@@ -128,13 +127,6 @@ typedef struct actcapi_ncpd {
* Bit 5-7 = Controller
* Bit 8-15 = reserved (must be 0)
*/
-#define MAKE_PLCI(plci, contr) \
- ((plci & 0x1f) | ((contr & 0x7) << 5))
-
-#define EVAL_PLCI(fakeplci, plci, contr) { \
- plci = fakeplci & 0x1f; \
- contr = (fakeplci >> 5) & 0x7; \
- }
typedef struct actcapi_msg {
actcapi_msghdr hdr;
diff --git a/drivers/staging/i4l/act2000/module.c b/drivers/staging/i4l/act2000/module.c
index 68073d0da0e3..99c9c0a1c63e 100644
--- a/drivers/staging/i4l/act2000/module.c
+++ b/drivers/staging/i4l/act2000/module.c
@@ -28,7 +28,7 @@ static unsigned short act2000_isa_ports[] =
static act2000_card *cards = (act2000_card *) NULL;
/* Parameters to be set by insmod */
-static int act_bus = 0;
+static int act_bus;
static int act_port = -1; /* -1 = Autoprobe */
static int act_irq = -1;
static char *act_id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
@@ -289,7 +289,8 @@ act2000_command(act2000_card *card, isdn_ctrl *c)
if (copy_from_user(tmp, arg,
sizeof(tmp)))
return -EFAULT;
- if ((ret = act2000_set_msn(card, tmp)))
+ ret = act2000_set_msn(card, tmp);
+ if (ret)
return ret;
if (card->flags & ACT2000_FLAGS_RUNNING)
return (actcapi_manufacturer_req_msn(card));
diff --git a/drivers/staging/i4l/icn/icn.c b/drivers/staging/i4l/icn/icn.c
index 46d957c34be1..514bfc2c5b53 100644
--- a/drivers/staging/i4l/icn/icn.c
+++ b/drivers/staging/i4l/icn/icn.c
@@ -62,7 +62,8 @@ icn_free_queue(icn_card *card, int channel)
skb_queue_purge(queue);
card->xlen[channel] = 0;
card->sndcount[channel] = 0;
- if ((skb = card->xskb[channel])) {
+ skb = card->xskb[channel];
+ if (skb) {
card->xskb[channel] = NULL;
dev_kfree_skb(skb);
}
@@ -81,12 +82,11 @@ icn_shiftout(unsigned short port,
int firstbit,
int bitcount)
{
-
register u_char s;
register u_char c;
for (s = firstbit, c = bitcount; c > 0; s--, c--)
- OUTB_P((u_char) ((val >> s) & 1) ? 0xff : 0, port);
+ OUTB_P((u_char)((val >> s) & 1) ? 0xff : 0, port);
}
/*
@@ -272,8 +272,10 @@ icn_pollbchan_receive(int channel, icn_card *card)
rbnext;
icn_maprelease_channel(card, mch & 2);
if (!eflag) {
- if ((cnt = card->rcvidx[channel])) {
- if (!(skb = dev_alloc_skb(cnt))) {
+ cnt = card->rcvidx[channel];
+ if (cnt) {
+ skb = dev_alloc_skb(cnt);
+ if (!skb) {
printk(KERN_WARNING "icn: receive out of memory\n");
break;
}
@@ -382,7 +384,7 @@ icn_pollbchan_send(int channel, icn_card *card)
static void
icn_pollbchan(unsigned long data)
{
- icn_card *card = (icn_card *) data;
+ icn_card *card = (icn_card *)data;
unsigned long flags;
if (card->flags & ICN_FLAGS_B1ACTIVE) {
@@ -472,7 +474,6 @@ icn_parse_status(u_char *status, int channel, icn_card *card)
if (card->flags &
((channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE)) {
-
isdn_ctrl ncmd;
card->flags &= ~((channel) ?
@@ -544,7 +545,7 @@ icn_parse_status(u_char *status, int channel, icn_card *card)
break;
case 6:
snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%d",
- (int) simple_strtoul(status + 7, NULL, 16));
+ (int)simple_strtoul(status + 7, NULL, 16));
break;
case 7:
status += 3;
@@ -604,7 +605,7 @@ icn_putmsg(icn_card *card, unsigned char c)
static void
icn_polldchan(unsigned long data)
{
- icn_card *card = (icn_card *) data;
+ icn_card *card = (icn_card *)data;
int mch = card->secondhalf ? 2 : 0;
int avail = 0;
int left;
@@ -656,9 +657,8 @@ icn_polldchan(unsigned long data)
*q = '\0';
strcat(vstr, "000");
vstr[3] = '\0';
- card->fw_rev = (int) simple_strtoul(vstr, NULL, 10);
+ card->fw_rev = (int)simple_strtoul(vstr, NULL, 10);
continue;
-
}
}
} else {
@@ -683,7 +683,7 @@ icn_polldchan(unsigned long data)
card->flags |= ICN_FLAGS_RBTIMER;
del_timer(&card->rb_timer);
card->rb_timer.function = icn_pollbchan;
- card->rb_timer.data = (unsigned long) card;
+ card->rb_timer.data = (unsigned long)card;
card->rb_timer.expires = jiffies + ICN_TIMER_BCREAD;
add_timer(&card->rb_timer);
}
@@ -805,17 +805,12 @@ icn_loadboot(u_char __user *buffer, icn_card *card)
unsigned long flags;
#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong) buffer);
+ printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong)buffer);
#endif
- if (!(codebuf = kmalloc(ICN_CODE_STAGE1, GFP_KERNEL))) {
- printk(KERN_WARNING "icn: Could not allocate code buffer\n");
- ret = -ENOMEM;
- goto out;
- }
- if (copy_from_user(codebuf, buffer, ICN_CODE_STAGE1)) {
- ret = -EFAULT;
- goto out_kfree;
- }
+ codebuf = memdup_user(buffer, ICN_CODE_STAGE1);
+ if (IS_ERR(codebuf))
+ return PTR_ERR(codebuf);
+
if (!card->rvalid) {
if (!request_region(card->port, ICN_PORTLEN, card->regname)) {
printk(KERN_WARNING
@@ -878,9 +873,9 @@ icn_loadboot(u_char __user *buffer, icn_card *card)
}
SLEEP(1);
OUTB_P(0xff, ICN_RUN); /* Start Boot-Code */
- if ((ret = icn_check_loader(card->doubleS0 ? 2 : 1))) {
+ ret = icn_check_loader(card->doubleS0 ? 2 : 1);
+ if (ret)
goto out_kfree;
- }
if (!card->doubleS0) {
ret = 0;
goto out_kfree;
@@ -898,7 +893,6 @@ icn_loadboot(u_char __user *buffer, icn_card *card)
out_kfree:
kfree(codebuf);
-out:
return ret;
}
@@ -980,18 +974,17 @@ icn_loadproto(u_char __user *buffer, icn_card *card)
card->secondhalf);
#endif
spin_lock_irqsave(&card->lock, flags);
- init_timer(&card->st_timer);
- card->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
- card->st_timer.function = icn_polldchan;
- card->st_timer.data = (unsigned long) card;
- add_timer(&card->st_timer);
+ setup_timer(&card->st_timer, icn_polldchan,
+ (unsigned long)card);
+ mod_timer(&card->st_timer,
+ jiffies + ICN_TIMER_DCREAD);
card->flags |= ICN_FLAGS_RUNNING;
if (card->doubleS0) {
- init_timer(&card->other->st_timer);
- card->other->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
- card->other->st_timer.function = icn_polldchan;
- card->other->st_timer.data = (unsigned long) card->other;
- add_timer(&card->other->st_timer);
+ setup_timer(&card->other->st_timer,
+ icn_polldchan,
+ (unsigned long)card->other);
+ mod_timer(&card->other->st_timer,
+ jiffies + ICN_TIMER_DCREAD);
card->other->flags |= ICN_FLAGS_RUNNING;
}
spin_unlock_irqrestore(&card->lock, flags);
@@ -1022,7 +1015,8 @@ icn_readstatus(u_char __user *buf, int len, icn_card *card)
/* Put command-strings into the command-queue of the Interface */
static int
-icn_writecmd(const u_char *buf, int len, int user, icn_card *card)
+icn_writecmd(const u_char __user *ubuf, const u_char *kbuf, int len,
+ int user, icn_card *card)
{
int mch = card->secondhalf ? 2 : 0;
int pp;
@@ -1045,10 +1039,10 @@ icn_writecmd(const u_char *buf, int len, int user, icn_card *card)
if (count > len)
count = len;
if (user) {
- if (copy_from_user(msg, buf, count))
+ if (copy_from_user(msg, ubuf, count))
return -EFAULT;
} else
- memcpy(msg, buf, count);
+ memcpy(msg, kbuf, count);
spin_lock_irqsave(&dev.devlock, flags);
lastmap_card = dev.mcard;
@@ -1190,28 +1184,28 @@ icn_command(isdn_ctrl *c, icn_card *card)
}
break;
case ICN_IOCTL_GETMMIO:
- return (long) dev.memaddr;
+ return (long)dev.memaddr;
case ICN_IOCTL_SETPORT:
if (a == 0x300 || a == 0x310 || a == 0x320 || a == 0x330
|| a == 0x340 || a == 0x350 || a == 0x360 ||
a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338
|| a == 0x348 || a == 0x358 || a == 0x368) {
- if (card->port != (unsigned short) a) {
- if (!request_region((unsigned short) a, ICN_PORTLEN, "icn-isdn")) {
+ if (card->port != (unsigned short)a) {
+ if (!request_region((unsigned short)a, ICN_PORTLEN, "icn-isdn")) {
printk(KERN_WARNING
"icn: (%s) ports 0x%03x-0x%03x in use.\n",
- CID, (int) a, (int) a + ICN_PORTLEN);
+ CID, (int)a, (int)a + ICN_PORTLEN);
return -EINVAL;
}
- release_region((unsigned short) a, ICN_PORTLEN);
+ release_region((unsigned short)a, ICN_PORTLEN);
icn_stopcard(card);
spin_lock_irqsave(&card->lock, flags);
if (card->rvalid)
release_region(card->port, ICN_PORTLEN);
- card->port = (unsigned short) a;
+ card->port = (unsigned short)a;
card->rvalid = 0;
if (card->doubleS0) {
- card->other->port = (unsigned short) a;
+ card->other->port = (unsigned short)a;
card->other->rvalid = 0;
}
spin_unlock_irqrestore(&card->lock, flags);
@@ -1223,9 +1217,9 @@ icn_command(isdn_ctrl *c, icn_card *card)
return -EINVAL;
break;
case ICN_IOCTL_GETPORT:
- return (int) card->port;
+ return (int)card->port;
case ICN_IOCTL_GETDOUBLE:
- return (int) card->doubleS0;
+ return (int)card->doubleS0;
case ICN_IOCTL_DEBUGVAR:
if (copy_to_user(arg,
&card,
@@ -1246,10 +1240,11 @@ icn_command(isdn_ctrl *c, icn_card *card)
dev.firstload = 0;
}
icn_stopcard(card);
- return (icn_loadboot(arg, card));
+ return icn_loadboot(arg, card);
case ICN_IOCTL_LOADPROTO:
icn_stopcard(card);
- if ((i = (icn_loadproto(arg, card))))
+ i = (icn_loadproto(arg, card));
+ if (i)
return i;
if (card->doubleS0)
i = icn_loadproto(arg + ICN_CODE_STAGE2, card->other);
@@ -1262,19 +1257,20 @@ icn_command(isdn_ctrl *c, icn_card *card)
arg,
sizeof(cdef)))
return -EFAULT;
- return (icn_addcard(cdef.port, cdef.id1, cdef.id2));
+ return icn_addcard(cdef.port, cdef.id1, cdef.id2);
break;
case ICN_IOCTL_LEASEDCFG:
if (a) {
if (!card->leased) {
card->leased = 1;
- while (card->ptype == ISDN_PTYPE_UNKNOWN) {
+ while (card->ptype == ISDN_PTYPE_UNKNOWN)
msleep_interruptible(ICN_BOOT_TIMEOUT1);
- }
msleep_interruptible(ICN_BOOT_TIMEOUT1);
sprintf(cbuf, "00;FV2ON\n01;EAZ%c\n02;EAZ%c\n",
(a & 1) ? '1' : 'C', (a & 2) ? '2' : 'C');
- i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+ i = icn_writecmd(NULL, cbuf,
+ strlen(cbuf),
+ 0, card);
printk(KERN_INFO
"icn: (%s) Leased-line mode enabled\n",
CID);
@@ -1287,7 +1283,9 @@ icn_command(isdn_ctrl *c, icn_card *card)
if (card->leased) {
card->leased = 0;
sprintf(cbuf, "00;FV2OFF\n");
- i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+ i = icn_writecmd(NULL, cbuf,
+ strlen(cbuf),
+ 0, card);
printk(KERN_INFO
"icn: (%s) Leased-line mode disabled\n",
CID);
@@ -1321,10 +1319,10 @@ icn_command(isdn_ctrl *c, icn_card *card)
/* Normal Dial */
strcpy(dcode, "CAL");
snprintf(cbuf, sizeof(cbuf),
- "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
+ "%02d;D%s_R%s,%02d,%02d,%s\n", (int)(a + 1),
dcode, p, c->parm.setup.si1,
c->parm.setup.si2, c->parm.setup.eazmsn);
- i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+ i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
}
break;
case ISDN_CMD_ACCEPTD:
@@ -1335,16 +1333,18 @@ icn_command(isdn_ctrl *c, icn_card *card)
if (card->fw_rev >= 300) {
switch (card->l2_proto[a - 1]) {
case ISDN_PROTO_L2_X75I:
- sprintf(cbuf, "%02d;BX75\n", (int) a);
+ sprintf(cbuf, "%02d;BX75\n", (int)a);
break;
case ISDN_PROTO_L2_HDLC:
- sprintf(cbuf, "%02d;BTRA\n", (int) a);
+ sprintf(cbuf, "%02d;BTRA\n", (int)a);
break;
}
- i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+ i = icn_writecmd(NULL, cbuf,
+ strlen(cbuf), 0,
+ card);
}
- sprintf(cbuf, "%02d;DCON_R\n", (int) a);
- i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+ sprintf(cbuf, "%02d;DCON_R\n", (int)a);
+ i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
}
break;
case ISDN_CMD_ACCEPTB:
@@ -1355,14 +1355,14 @@ icn_command(isdn_ctrl *c, icn_card *card)
if (card->fw_rev >= 300)
switch (card->l2_proto[a - 1]) {
case ISDN_PROTO_L2_X75I:
- sprintf(cbuf, "%02d;BCON_R,BX75\n", (int) a);
+ sprintf(cbuf, "%02d;BCON_R,BX75\n", (int)a);
break;
case ISDN_PROTO_L2_HDLC:
- sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int) a);
+ sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int)a);
break;
} else
- sprintf(cbuf, "%02d;BCON_R\n", (int) a);
- i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+ sprintf(cbuf, "%02d;BCON_R\n", (int)a);
+ i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
}
break;
case ISDN_CMD_HANGUP:
@@ -1370,8 +1370,8 @@ icn_command(isdn_ctrl *c, icn_card *card)
return -ENODEV;
if (c->arg < ICN_BCH) {
a = c->arg + 1;
- sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a, (int) a);
- i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+ sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int)a, (int)a);
+ i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
}
break;
case ISDN_CMD_SETEAZ:
@@ -1382,12 +1382,12 @@ icn_command(isdn_ctrl *c, icn_card *card)
if (c->arg < ICN_BCH) {
a = c->arg + 1;
if (card->ptype == ISDN_PTYPE_EURO) {
- sprintf(cbuf, "%02d;MS%s%s\n", (int) a,
+ sprintf(cbuf, "%02d;MS%s%s\n", (int)a,
c->parm.num[0] ? "N" : "ALL", c->parm.num);
} else
- sprintf(cbuf, "%02d;EAZ%s\n", (int) a,
+ sprintf(cbuf, "%02d;EAZ%s\n", (int)a,
c->parm.num[0] ? (char *)(c->parm.num) : "0123456789");
- i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+ i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
}
break;
case ISDN_CMD_CLREAZ:
@@ -1398,10 +1398,10 @@ icn_command(isdn_ctrl *c, icn_card *card)
if (c->arg < ICN_BCH) {
a = c->arg + 1;
if (card->ptype == ISDN_PTYPE_EURO)
- sprintf(cbuf, "%02d;MSNC\n", (int) a);
+ sprintf(cbuf, "%02d;MSNC\n", (int)a);
else
- sprintf(cbuf, "%02d;EAZC\n", (int) a);
- i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+ sprintf(cbuf, "%02d;EAZC\n", (int)a);
+ i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
}
break;
case ISDN_CMD_SETL2:
@@ -1411,15 +1411,15 @@ icn_command(isdn_ctrl *c, icn_card *card)
a = c->arg;
switch (a >> 8) {
case ISDN_PROTO_L2_X75I:
- sprintf(cbuf, "%02d;BX75\n", (int) (a & 255) + 1);
+ sprintf(cbuf, "%02d;BX75\n", (int)(a & 255) + 1);
break;
case ISDN_PROTO_L2_HDLC:
- sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
+ sprintf(cbuf, "%02d;BTRA\n", (int)(a & 255) + 1);
break;
default:
return -EINVAL;
}
- i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+ i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
card->l2_proto[a & 255] = (a >> 8);
}
break;
@@ -1446,7 +1446,7 @@ icn_findcard(int driverid)
return p;
p = p->next;
}
- return (icn_card *) 0;
+ return (icn_card *)0;
}
/*
@@ -1458,7 +1458,7 @@ if_command(isdn_ctrl *c)
icn_card *card = icn_findcard(c->driver);
if (card)
- return (icn_command(c, card));
+ return icn_command(c, card);
printk(KERN_ERR
"icn: if_command %d called with invalid driverId %d!\n",
c->command, c->driver);
@@ -1473,7 +1473,7 @@ if_writecmd(const u_char __user *buf, int len, int id, int channel)
if (card) {
if (!(card->flags & ICN_FLAGS_RUNNING))
return -ENODEV;
- return (icn_writecmd(buf, len, 1, card));
+ return icn_writecmd(buf, NULL, len, 1, card);
}
printk(KERN_ERR
"icn: if_writecmd called with invalid driverId!\n");
@@ -1488,7 +1488,7 @@ if_readstatus(u_char __user *buf, int len, int id, int channel)
if (card) {
if (!(card->flags & ICN_FLAGS_RUNNING))
return -ENODEV;
- return (icn_readstatus(buf, len, card));
+ return icn_readstatus(buf, len, card);
}
printk(KERN_ERR
"icn: if_readstatus called with invalid driverId!\n");
@@ -1503,7 +1503,7 @@ if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
if (card) {
if (!(card->flags & ICN_FLAGS_RUNNING))
return -ENODEV;
- return (icn_sendbuf(channel, ack, skb, card));
+ return icn_sendbuf(channel, ack, skb, card);
}
printk(KERN_ERR
"icn: if_sendbuf called with invalid driverId!\n");
@@ -1520,10 +1520,11 @@ icn_initcard(int port, char *id)
icn_card *card;
int i;
- if (!(card = kzalloc(sizeof(icn_card), GFP_KERNEL))) {
+ card = kzalloc(sizeof(icn_card), GFP_KERNEL);
+ if (!card) {
printk(KERN_WARNING
"icn: (%s) Could not allocate card-struct.\n", id);
- return (icn_card *) 0;
+ return (icn_card *)0;
}
spin_lock_init(&card->lock);
card->port = port;
@@ -1555,7 +1556,7 @@ icn_initcard(int port, char *id)
printk(KERN_WARNING
"icn: Unable to register %s\n", id);
kfree(card);
- return (icn_card *) 0;
+ return (icn_card *)0;
}
card->myid = card->interface.channels;
sprintf(card->regname, "icn-isdn (%s)", card->interface.id);
@@ -1568,16 +1569,17 @@ icn_addcard(int port, char *id1, char *id2)
icn_card *card;
icn_card *card2;
- if (!(card = icn_initcard(port, id1))) {
+ card = icn_initcard(port, id1);
+ if (!card)
return -EIO;
- }
if (!strlen(id2)) {
printk(KERN_INFO
"icn: (%s) ICN-2B, port 0x%x added\n",
card->interface.id, port);
return 0;
}
- if (!(card2 = icn_initcard(port, id2))) {
+ card2 = icn_initcard(port, id2);
+ if (!card2) {
printk(KERN_INFO
"icn: (%s) half ICN-4B, port 0x%x added\n", id2, port);
return 0;
@@ -1611,13 +1613,14 @@ icn_setup(char *line)
if (str && *str) {
strlcpy(sid, str, sizeof(sid));
icn_id = sid;
- if ((p = strchr(sid, ','))) {
+ p = strchr(sid, ',');
+ if (p) {
*p++ = 0;
strcpy(sid2, p);
icn_id2 = sid2;
}
}
- return (1);
+ return 1;
}
__setup("icn=", icn_setup);
#endif /* MODULE */
@@ -1634,7 +1637,8 @@ static int __init icn_init(void)
dev.firstload = 1;
spin_lock_init(&dev.devlock);
- if ((p = strchr(revision, ':'))) {
+ p = strchr(revision, ':');
+ if (p) {
strncpy(rev, p + 1, 20);
rev[20] = '\0';
p = strchr(rev, '$');
@@ -1644,7 +1648,7 @@ static int __init icn_init(void)
strcpy(rev, " ??? ");
printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev,
dev.memaddr);
- return (icn_addcard(portbase, icn_id, icn_id2));
+ return icn_addcard(portbase, icn_id, icn_id2);
}
static void __exit icn_exit(void)
diff --git a/drivers/staging/i4l/pcbit/capi.c b/drivers/staging/i4l/pcbit/capi.c
index 4e3cbf857d60..373f90feda5a 100644
--- a/drivers/staging/i4l/pcbit/capi.c
+++ b/drivers/staging/i4l/pcbit/capi.c
@@ -92,9 +92,7 @@ int capi_conn_req(const char *calledPN, struct sk_buff **skb, int proto)
*(skb_put(*skb, 1)) = 0x80; /* Speech */
*(skb_put(*skb, 1)) = 0x10; /* Circuit Mode */
*(skb_put(*skb, 1)) = 0x23; /* A-law */
- }
- else
- {
+ } else {
/* Bearer Capability - Mandatory*/
*(skb_put(*skb, 1)) = 2; /* BC0.Length */
*(skb_put(*skb, 1)) = 0x88; /* Digital Information */
diff --git a/drivers/staging/i4l/pcbit/drv.c b/drivers/staging/i4l/pcbit/drv.c
index c5270e229efb..d417df5efb5f 100644
--- a/drivers/staging/i4l/pcbit/drv.c
+++ b/drivers/staging/i4l/pcbit/drv.c
@@ -359,11 +359,9 @@ static int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
*/
#ifdef BLOCK_TIMER
if (chan->block_timer.function == NULL) {
- init_timer(&chan->block_timer);
- chan->block_timer.function = &pcbit_block_timer;
- chan->block_timer.data = (long) chan;
- chan->block_timer.expires = jiffies + 1 * HZ;
- add_timer(&chan->block_timer);
+ setup_timer(&chan->block_timer, &pcbit_block_timer,
+ (long)chan);
+ mod_timer(&chan->block_timer, jiffies + 1 * HZ);
}
#endif
return 0;
@@ -804,11 +802,7 @@ static int set_protocol_running(struct pcbit_dev *dev)
{
isdn_ctrl ctl;
- init_timer(&dev->set_running_timer);
-
- dev->set_running_timer.function = &set_running_timeout;
- dev->set_running_timer.data = (ulong) dev;
- dev->set_running_timer.expires = jiffies + SET_RUN_TIMEOUT;
+ setup_timer(&dev->set_running_timer, &set_running_timeout, (ulong)dev);
/* kick it */
@@ -817,7 +811,7 @@ static int set_protocol_running(struct pcbit_dev *dev)
writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)),
dev->sh_mem + BANK4);
- add_timer(&dev->set_running_timer);
+ mod_timer(&dev->set_running_timer, jiffies + SET_RUN_TIMEOUT);
wait_event(dev->set_running_wq, dev->l2_state == L2_RUNNING ||
dev->l2_state == L2_DOWN);
diff --git a/drivers/staging/i4l/pcbit/edss1.c b/drivers/staging/i4l/pcbit/edss1.c
index e72c16420712..6d291d548423 100644
--- a/drivers/staging/i4l/pcbit/edss1.c
+++ b/drivers/staging/i4l/pcbit/edss1.c
@@ -298,11 +298,8 @@ void pcbit_fsm_event(struct pcbit_dev *dev, struct pcbit_chan *chan,
break;
if (tentry->init != 0xff) {
- init_timer(&chan->fsm_timer);
- chan->fsm_timer.function = &pcbit_fsm_timer;
- chan->fsm_timer.data = (ulong) chan;
- chan->fsm_timer.expires = jiffies + tentry->timeout * HZ;
- add_timer(&chan->fsm_timer);
+ setup_timer(&chan->fsm_timer, &pcbit_fsm_timer, (ulong)chan);
+ mod_timer(&chan->fsm_timer, jiffies + tentry->timeout * HZ);
}
spin_unlock_irqrestore(&dev->lock, flags);
diff --git a/drivers/staging/i4l/pcbit/layer2.c b/drivers/staging/i4l/pcbit/layer2.c
index 46e1240ae074..a136c72547e5 100644
--- a/drivers/staging/i4l/pcbit/layer2.c
+++ b/drivers/staging/i4l/pcbit/layer2.c
@@ -645,11 +645,9 @@ pcbit_l2_error(struct pcbit_dev *dev)
dev->l2_state = L2_DOWN;
- init_timer(&dev->error_recover_timer);
- dev->error_recover_timer.function = &pcbit_l2_err_recover;
- dev->error_recover_timer.data = (ulong) dev;
- dev->error_recover_timer.expires = jiffies + ERRTIME;
- add_timer(&dev->error_recover_timer);
+ setup_timer(&dev->error_recover_timer, &pcbit_l2_err_recover,
+ (ulong)dev);
+ mod_timer(&dev->error_recover_timer, jiffies + ERRTIME);
}
}
diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h
index 9c8a9587df7d..4dcc8575cbe3 100644
--- a/drivers/staging/iio/accel/sca3000.h
+++ b/drivers/staging/iio/accel/sca3000.h
@@ -113,6 +113,7 @@
#define SCA3000_OUT_CTRL_BUF_X_EN 0x10
#define SCA3000_OUT_CTRL_BUF_Y_EN 0x08
#define SCA3000_OUT_CTRL_BUF_Z_EN 0x04
+#define SCA3000_OUT_CTRL_BUF_DIV_MASK 0x03
#define SCA3000_OUT_CTRL_BUF_DIV_4 0x02
#define SCA3000_OUT_CTRL_BUF_DIV_2 0x01
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index b5625f5d5e0e..d626125d7af9 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -402,6 +402,7 @@ static const struct iio_event_spec sca3000_event = {
.channel2 = mod, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
.address = index, \
.scan_index = index, \
.scan_type = { \
@@ -412,7 +413,7 @@ static const struct iio_event_spec sca3000_event = {
}, \
.event_spec = &sca3000_event, \
.num_event_specs = 1, \
- }
+ }
static const struct iio_chan_spec sca3000_channels[] = {
SCA3000_CHAN(0, IIO_MOD_X),
@@ -443,6 +444,97 @@ static u8 sca3000_addresses[3][3] = {
SCA3000_MD_CTRL_OR_Z},
};
+/**
+ * __sca3000_get_base_freq() obtain mode specific base frequency
+ *
+ * lock must be held
+ **/
+static inline int __sca3000_get_base_freq(struct sca3000_state *st,
+ const struct sca3000_chip_info *info,
+ int *base_freq)
+{
+ int ret;
+
+ ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
+ if (ret)
+ goto error_ret;
+ switch (0x03 & st->rx[0]) {
+ case SCA3000_MEAS_MODE_NORMAL:
+ *base_freq = info->measurement_mode_freq;
+ break;
+ case SCA3000_MEAS_MODE_OP_1:
+ *base_freq = info->option_mode_1_freq;
+ break;
+ case SCA3000_MEAS_MODE_OP_2:
+ *base_freq = info->option_mode_2_freq;
+ break;
+ }
+error_ret:
+ return ret;
+}
+
+/**
+ * read_raw handler for IIO_CHAN_INFO_SAMP_FREQ
+ *
+ * lock must be held
+ **/
+static int read_raw_samp_freq(struct sca3000_state *st, int *val)
+{
+ int ret;
+
+ ret = __sca3000_get_base_freq(st, st->info, val);
+ if (ret)
+ return ret;
+
+ ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
+ if (ret < 0)
+ return ret;
+
+ if (*val > 0) {
+ ret &= SCA3000_OUT_CTRL_BUF_DIV_MASK;
+ switch (ret) {
+ case SCA3000_OUT_CTRL_BUF_DIV_2:
+ *val /= 2;
+ break;
+ case SCA3000_OUT_CTRL_BUF_DIV_4:
+ *val /= 4;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * write_raw handler for IIO_CHAN_INFO_SAMP_FREQ
+ *
+ * lock must be held
+ **/
+static int write_raw_samp_freq(struct sca3000_state *st, int val)
+{
+ int ret, base_freq, ctrlval;
+
+ ret = __sca3000_get_base_freq(st, st->info, &base_freq);
+ if (ret)
+ return ret;
+
+ ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
+ if (ret < 0)
+ return ret;
+
+ ctrlval = ret & ~SCA3000_OUT_CTRL_BUF_DIV_MASK;
+
+ if (val == base_freq / 2)
+ ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_2;
+ if (val == base_freq / 4)
+ ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_4;
+ else if (val != base_freq)
+ return -EINVAL;
+
+ return sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL,
+ ctrlval);
+}
+
static int sca3000_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
@@ -495,9 +587,36 @@ static int sca3000_read_raw(struct iio_dev *indio_dev,
*val = -214;
*val2 = 600000;
return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ mutex_lock(&st->lock);
+ ret = read_raw_samp_freq(st, val);
+ mutex_unlock(&st->lock);
+ return ret ? ret : IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int sca3000_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct sca3000_state *st = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (val2)
+ return -EINVAL;
+ mutex_lock(&st->lock);
+ ret = write_raw_samp_freq(st, val);
+ mutex_unlock(&st->lock);
+ return ret;
default:
return -EINVAL;
}
+
+ return ret;
}
/**
@@ -548,133 +667,12 @@ error_ret:
return ret;
}
-/**
- * __sca3000_get_base_freq() obtain mode specific base frequency
- *
- * lock must be held
- **/
-static inline int __sca3000_get_base_freq(struct sca3000_state *st,
- const struct sca3000_chip_info *info,
- int *base_freq)
-{
- int ret;
-
- ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
- if (ret)
- goto error_ret;
- switch (0x03 & st->rx[0]) {
- case SCA3000_MEAS_MODE_NORMAL:
- *base_freq = info->measurement_mode_freq;
- break;
- case SCA3000_MEAS_MODE_OP_1:
- *base_freq = info->option_mode_1_freq;
- break;
- case SCA3000_MEAS_MODE_OP_2:
- *base_freq = info->option_mode_2_freq;
- break;
- }
-error_ret:
- return ret;
-}
-
-/**
- * sca3000_read_frequency() sysfs interface to get the current frequency
- **/
-static ssize_t sca3000_read_frequency(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct sca3000_state *st = iio_priv(indio_dev);
- int ret, len = 0, base_freq = 0, val;
-
- mutex_lock(&st->lock);
- ret = __sca3000_get_base_freq(st, st->info, &base_freq);
- if (ret)
- goto error_ret_mut;
- ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
- mutex_unlock(&st->lock);
- if (ret < 0)
- goto error_ret;
- val = ret;
- if (base_freq > 0)
- switch (val & 0x03) {
- case 0x00:
- case 0x03:
- len = sprintf(buf, "%d\n", base_freq);
- break;
- case 0x01:
- len = sprintf(buf, "%d\n", base_freq / 2);
- break;
- case 0x02:
- len = sprintf(buf, "%d\n", base_freq / 4);
- break;
- }
-
- return len;
-error_ret_mut:
- mutex_unlock(&st->lock);
-error_ret:
- return ret;
-}
-
-/**
- * sca3000_set_frequency() sysfs interface to set the current frequency
- **/
-static ssize_t sca3000_set_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct sca3000_state *st = iio_priv(indio_dev);
- int ret, base_freq = 0;
- int ctrlval;
- int val;
-
- ret = kstrtoint(buf, 10, &val);
- if (ret)
- return ret;
-
- mutex_lock(&st->lock);
- /* What mode are we in? */
- ret = __sca3000_get_base_freq(st, st->info, &base_freq);
- if (ret)
- goto error_free_lock;
-
- ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
- if (ret < 0)
- goto error_free_lock;
- ctrlval = ret;
- /* clear the bits */
- ctrlval &= ~0x03;
-
- if (val == base_freq / 2) {
- ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_2;
- } else if (val == base_freq / 4) {
- ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_4;
- } else if (val != base_freq) {
- ret = -EINVAL;
- goto error_free_lock;
- }
- ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL,
- ctrlval);
-error_free_lock:
- mutex_unlock(&st->lock);
-
- return ret ? ret : len;
-}
-
/*
* Should only really be registered if ring buffer support is compiled in.
* Does no harm however and doing it right would add a fair bit of complexity
*/
static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(sca3000_read_av_freq);
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
- sca3000_read_frequency,
- sca3000_set_frequency);
-
/**
* sca3000_read_thresh() - query of a threshold
**/
@@ -751,7 +749,6 @@ static struct attribute *sca3000_attributes[] = {
&iio_dev_attr_measurement_mode_available.dev_attr.attr,
&iio_dev_attr_measurement_mode.dev_attr.attr,
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
NULL,
};
@@ -1086,6 +1083,7 @@ error_ret:
static const struct iio_info sca3000_info = {
.attrs = &sca3000_attribute_group,
.read_raw = &sca3000_read_raw,
+ .write_raw = &sca3000_write_raw,
.event_attrs = &sca3000_event_attribute_group,
.read_event_value = &sca3000_read_thresh,
.write_event_value = &sca3000_write_thresh,
diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c
index 2177f1dd2b5d..b460dda7eb65 100644
--- a/drivers/staging/iio/adc/ad7280a.c
+++ b/drivers/staging/iio/adc/ad7280a.c
@@ -478,7 +478,7 @@ static ssize_t ad7280_store_balance_timer(struct device *dev,
static struct attribute *ad7280_attributes[AD7280A_MAX_CHAIN *
AD7280A_CELLS_PER_DEV * 2 + 1];
-static struct attribute_group ad7280_attrs_group = {
+static const struct attribute_group ad7280_attrs_group = {
.attrs = ad7280_attributes,
};
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index 24c348d2f5bb..5eecf1cb1028 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -156,8 +156,7 @@ static const struct iio_chan_spec ad5933_channels[] = {
},
};
-static int ad5933_i2c_write(struct i2c_client *client,
- u8 reg, u8 len, u8 *data)
+static int ad5933_i2c_write(struct i2c_client *client, u8 reg, u8 len, u8 *data)
{
int ret;
@@ -171,8 +170,7 @@ static int ad5933_i2c_write(struct i2c_client *client,
return 0;
}
-static int ad5933_i2c_read(struct i2c_client *client,
- u8 reg, u8 len, u8 *data)
+static int ad5933_i2c_read(struct i2c_client *client, u8 reg, u8 len, u8 *data)
{
int ret;
@@ -269,7 +267,8 @@ static int ad5933_setup(struct ad5933_state *st)
dat = cpu_to_be16(st->settling_cycles);
ret = ad5933_i2c_write(st->client,
- AD5933_REG_SETTLING_CYCLES, 2, (u8 *)&dat);
+ AD5933_REG_SETTLING_CYCLES,
+ 2, (u8 *)&dat);
if (ret < 0)
return ret;
@@ -294,8 +293,8 @@ static void ad5933_calc_out_ranges(struct ad5933_state *st)
*/
static ssize_t ad5933_show_frequency(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad5933_state *st = iio_priv(indio_dev);
@@ -322,9 +321,9 @@ static ssize_t ad5933_show_frequency(struct device *dev,
}
static ssize_t ad5933_store_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad5933_state *st = iio_priv(indio_dev);
@@ -357,8 +356,8 @@ static IIO_DEVICE_ATTR(out_voltage0_freq_increment, S_IRUGO | S_IWUSR,
AD5933_REG_FREQ_INC);
static ssize_t ad5933_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad5933_state *st = iio_priv(indio_dev);
@@ -399,9 +398,9 @@ static ssize_t ad5933_show(struct device *dev,
}
static ssize_t ad5933_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad5933_state *st = iio_priv(indio_dev);
@@ -451,7 +450,8 @@ static ssize_t ad5933_store(struct device *dev,
dat = cpu_to_be16(val);
ret = ad5933_i2c_write(st->client,
- AD5933_REG_SETTLING_CYCLES, 2, (u8 *)&dat);
+ AD5933_REG_SETTLING_CYCLES,
+ 2, (u8 *)&dat);
break;
case AD5933_FREQ_POINTS:
val = clamp(val, (u16)0, (u16)511);
@@ -545,8 +545,8 @@ static int ad5933_read_raw(struct iio_dev *indio_dev,
goto out;
ret = ad5933_i2c_read(st->client,
- AD5933_REG_TEMP_DATA, 2,
- (u8 *)&dat);
+ AD5933_REG_TEMP_DATA,
+ 2, (u8 *)&dat);
if (ret < 0)
goto out;
mutex_unlock(&indio_dev->mlock);
@@ -705,7 +705,7 @@ static void ad5933_work(struct work_struct *work)
}
static int ad5933_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
int ret, voltage_uv = 0;
struct ad5933_platform_data *pdata = dev_get_platdata(&client->dev);
diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c
index 76d9f74e7dcb..a767a43c995c 100644
--- a/drivers/staging/iio/light/isl29018.c
+++ b/drivers/staging/iio/light/isl29018.c
@@ -15,10 +15,6 @@
* 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <linux/module.h>
@@ -32,25 +28,25 @@
#include <linux/iio/sysfs.h>
#include <linux/acpi.h>
-#define CONVERSION_TIME_MS 100
+#define ISL29018_CONV_TIME_MS 100
#define ISL29018_REG_ADD_COMMAND1 0x00
-#define COMMMAND1_OPMODE_SHIFT 5
-#define COMMMAND1_OPMODE_MASK (7 << COMMMAND1_OPMODE_SHIFT)
-#define COMMMAND1_OPMODE_POWER_DOWN 0
-#define COMMMAND1_OPMODE_ALS_ONCE 1
-#define COMMMAND1_OPMODE_IR_ONCE 2
-#define COMMMAND1_OPMODE_PROX_ONCE 3
+#define ISL29018_CMD1_OPMODE_SHIFT 5
+#define ISL29018_CMD1_OPMODE_MASK (7 << ISL29018_CMD1_OPMODE_SHIFT)
+#define ISL29018_CMD1_OPMODE_POWER_DOWN 0
+#define ISL29018_CMD1_OPMODE_ALS_ONCE 1
+#define ISL29018_CMD1_OPMODE_IR_ONCE 2
+#define ISL29018_CMD1_OPMODE_PROX_ONCE 3
-#define ISL29018_REG_ADD_COMMANDII 0x01
-#define COMMANDII_RESOLUTION_SHIFT 2
-#define COMMANDII_RESOLUTION_MASK (0x3 << COMMANDII_RESOLUTION_SHIFT)
+#define ISL29018_REG_ADD_COMMAND2 0x01
+#define ISL29018_CMD2_RESOLUTION_SHIFT 2
+#define ISL29018_CMD2_RESOLUTION_MASK (0x3 << ISL29018_CMD2_RESOLUTION_SHIFT)
-#define COMMANDII_RANGE_SHIFT 0
-#define COMMANDII_RANGE_MASK (0x3 << COMMANDII_RANGE_SHIFT)
+#define ISL29018_CMD2_RANGE_SHIFT 0
+#define ISL29018_CMD2_RANGE_MASK (0x3 << ISL29018_CMD2_RANGE_SHIFT)
-#define COMMANDII_SCHEME_SHIFT 7
-#define COMMANDII_SCHEME_MASK (0x1 << COMMANDII_SCHEME_SHIFT)
+#define ISL29018_CMD2_SCHEME_SHIFT 7
+#define ISL29018_CMD2_SCHEME_MASK (0x1 << ISL29018_CMD2_SCHEME_SHIFT)
#define ISL29018_REG_ADD_DATA_LSB 0x02
#define ISL29018_REG_ADD_DATA_MSB 0x03
@@ -127,13 +123,13 @@ static int isl29018_set_integration_time(struct isl29018_chip *chip,
if (i >= ARRAY_SIZE(isl29018_int_utimes[chip->type]))
return -EINVAL;
- ret = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII,
- COMMANDII_RESOLUTION_MASK,
- i << COMMANDII_RESOLUTION_SHIFT);
+ ret = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMAND2,
+ ISL29018_CMD2_RESOLUTION_MASK,
+ i << ISL29018_CMD2_RESOLUTION_SHIFT);
if (ret < 0)
return ret;
- /* keep the same range when integration time changes */
+ /* Keep the same range when integration time changes */
int_time = chip->int_time;
for (i = 0; i < ARRAY_SIZE(isl29018_scales[int_time]); ++i) {
if (chip->scale.scale == isl29018_scales[int_time][i].scale &&
@@ -163,9 +159,9 @@ static int isl29018_set_scale(struct isl29018_chip *chip, int scale, int uscale)
if (i >= ARRAY_SIZE(isl29018_scales[chip->int_time]))
return -EINVAL;
- ret = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII,
- COMMANDII_RANGE_MASK,
- i << COMMANDII_RANGE_SHIFT);
+ ret = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMAND2,
+ ISL29018_CMD2_RANGE_MASK,
+ i << ISL29018_CMD2_RANGE_SHIFT);
if (ret < 0)
return ret;
@@ -183,13 +179,13 @@ static int isl29018_read_sensor_input(struct isl29018_chip *chip, int mode)
/* Set mode */
status = regmap_write(chip->regmap, ISL29018_REG_ADD_COMMAND1,
- mode << COMMMAND1_OPMODE_SHIFT);
+ mode << ISL29018_CMD1_OPMODE_SHIFT);
if (status) {
dev_err(dev,
"Error in setting operating mode err %d\n", status);
return status;
}
- msleep(CONVERSION_TIME_MS);
+ msleep(ISL29018_CONV_TIME_MS);
status = regmap_read(chip->regmap, ISL29018_REG_ADD_DATA_LSB, &lsb);
if (status < 0) {
dev_err(dev,
@@ -213,8 +209,8 @@ static int isl29018_read_lux(struct isl29018_chip *chip, int *lux)
int lux_data;
unsigned int data_x_range;
- lux_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_ALS_ONCE);
-
+ lux_data = isl29018_read_sensor_input(chip,
+ ISL29018_CMD1_OPMODE_ALS_ONCE);
if (lux_data < 0)
return lux_data;
@@ -230,8 +226,8 @@ static int isl29018_read_ir(struct isl29018_chip *chip, int *ir)
{
int ir_data;
- ir_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_IR_ONCE);
-
+ ir_data = isl29018_read_sensor_input(chip,
+ ISL29018_CMD1_OPMODE_IR_ONCE);
if (ir_data < 0)
return ir_data;
@@ -249,16 +245,16 @@ static int isl29018_read_proximity_ir(struct isl29018_chip *chip, int scheme,
struct device *dev = regmap_get_device(chip->regmap);
/* Do proximity sensing with required scheme */
- status = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII,
- COMMANDII_SCHEME_MASK,
- scheme << COMMANDII_SCHEME_SHIFT);
+ status = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMAND2,
+ ISL29018_CMD2_SCHEME_MASK,
+ scheme << ISL29018_CMD2_SCHEME_SHIFT);
if (status) {
dev_err(dev, "Error in setting operating mode\n");
return status;
}
prox_data = isl29018_read_sensor_input(chip,
- COMMMAND1_OPMODE_PROX_ONCE);
+ ISL29018_CMD1_OPMODE_PROX_ONCE);
if (prox_data < 0)
return prox_data;
@@ -267,8 +263,8 @@ static int isl29018_read_proximity_ir(struct isl29018_chip *chip, int scheme,
return 0;
}
- ir_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_IR_ONCE);
-
+ ir_data = isl29018_read_sensor_input(chip,
+ ISL29018_CMD1_OPMODE_IR_ONCE);
if (ir_data < 0)
return ir_data;
@@ -280,7 +276,7 @@ static int isl29018_read_proximity_ir(struct isl29018_chip *chip, int scheme,
return 0;
}
-static ssize_t show_scale_available(struct device *dev,
+static ssize_t isl29018_show_scale_available(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -297,7 +293,7 @@ static ssize_t show_scale_available(struct device *dev,
return len;
}
-static ssize_t show_int_time_available(struct device *dev,
+static ssize_t isl29018_show_int_time_available(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -313,8 +309,7 @@ static ssize_t show_int_time_available(struct device *dev,
return len;
}
-/* proximity scheme */
-static ssize_t show_prox_infrared_suppression(struct device *dev,
+static ssize_t isl29018_show_prox_infrared_suppression(struct device *dev,
struct device_attribute *attr,
char *buf)
{
@@ -322,13 +317,13 @@ static ssize_t show_prox_infrared_suppression(struct device *dev,
struct isl29018_chip *chip = iio_priv(indio_dev);
/*
- * return the "proximity scheme" i.e. if the chip does on chip
+ * Return the "proximity scheme" i.e. if the chip does on chip
* infrared suppression (1 means perform on chip suppression)
*/
return sprintf(buf, "%d\n", chip->prox_scheme);
}
-static ssize_t store_prox_infrared_suppression(struct device *dev,
+static ssize_t isl29018_store_prox_infrared_suppression(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
@@ -338,13 +333,11 @@ static ssize_t store_prox_infrared_suppression(struct device *dev,
if (kstrtoint(buf, 10, &val))
return -EINVAL;
- if (!(val == 0 || val == 1)) {
- dev_err(dev, "The mode is not supported\n");
+ if (!(val == 0 || val == 1))
return -EINVAL;
- }
/*
- * get the "proximity scheme" i.e. if the chip does on chip
+ * Get the "proximity scheme" i.e. if the chip does on chip
* infrared suppression (1 means perform on chip suppression)
*/
mutex_lock(&chip->lock);
@@ -354,7 +347,6 @@ static ssize_t store_prox_infrared_suppression(struct device *dev,
return count;
}
-/* Channel IO */
static int isl29018_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val,
@@ -491,13 +483,13 @@ static const struct iio_chan_spec isl29023_channels[] = {
};
static IIO_DEVICE_ATTR(in_illuminance_integration_time_available, S_IRUGO,
- show_int_time_available, NULL, 0);
+ isl29018_show_int_time_available, NULL, 0);
static IIO_DEVICE_ATTR(in_illuminance_scale_available, S_IRUGO,
- show_scale_available, NULL, 0);
+ isl29018_show_scale_available, NULL, 0);
static IIO_DEVICE_ATTR(proximity_on_chip_ambient_infrared_suppression,
S_IRUGO | S_IWUSR,
- show_prox_infrared_suppression,
- store_prox_infrared_suppression, 0);
+ isl29018_show_prox_infrared_suppression,
+ isl29018_store_prox_infrared_suppression, 0);
#define ISL29018_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr)
@@ -541,7 +533,7 @@ static int isl29035_detect(struct isl29018_chip *chip)
if (id != ISL29035_DEVICE_ID)
return -ENODEV;
- /* clear out brownout bit */
+ /* Clear brownout bit */
return regmap_update_bits(chip->regmap, ISL29035_REG_DEVICE_ID,
ISL29035_BOUT_MASK, 0);
}
@@ -574,7 +566,7 @@ static int isl29018_chip_init(struct isl29018_chip *chip)
* conversions, clear the test registers, and then rewrite all
* registers to the desired values.
* ...
- * FOR ISL29011, ISL29018, ISL29021, ISL29023
+ * For ISL29011, ISL29018, ISL29021, ISL29023
* 1. Write 0x00 to register 0x08 (TEST)
* 2. Write 0x00 to register 0x00 (CMD1)
* 3. Rewrite all registers to the desired values
@@ -603,7 +595,7 @@ static int isl29018_chip_init(struct isl29018_chip *chip)
usleep_range(1000, 2000); /* per data sheet, page 10 */
- /* set defaults */
+ /* Set defaults */
status = isl29018_set_scale(chip, chip->scale.scale,
chip->scale.uscale);
if (status < 0) {
@@ -635,7 +627,7 @@ static const struct iio_info isl29023_info = {
.write_raw = isl29018_write_raw,
};
-static bool is_volatile_reg(struct device *dev, unsigned int reg)
+static bool isl29018_is_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case ISL29018_REG_ADD_DATA_LSB:
@@ -649,37 +641,32 @@ static bool is_volatile_reg(struct device *dev, unsigned int reg)
}
}
-/*
- * isl29018_regmap_config: regmap configuration.
- * Use RBTREE mechanism for caching.
- */
static const struct regmap_config isl29018_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
- .volatile_reg = is_volatile_reg,
+ .volatile_reg = isl29018_is_volatile_reg,
.max_register = ISL29018_REG_TEST,
.num_reg_defaults_raw = ISL29018_REG_TEST + 1,
.cache_type = REGCACHE_RBTREE,
};
-/* isl29035_regmap_config: regmap configuration for ISL29035 */
static const struct regmap_config isl29035_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
- .volatile_reg = is_volatile_reg,
+ .volatile_reg = isl29018_is_volatile_reg,
.max_register = ISL29035_REG_DEVICE_ID,
.num_reg_defaults_raw = ISL29035_REG_DEVICE_ID + 1,
.cache_type = REGCACHE_RBTREE,
};
-struct chip_info {
+struct isl29018_chip_info {
const struct iio_chan_spec *channels;
int num_channels;
const struct iio_info *indio_info;
const struct regmap_config *regmap_cfg;
};
-static const struct chip_info chip_info_tbl[] = {
+static const struct isl29018_chip_info isl29018_chip_info_tbl[] = {
[isl29018] = {
.channels = isl29018_channels,
.num_channels = ARRAY_SIZE(isl29018_channels),
@@ -724,10 +711,8 @@ static int isl29018_probe(struct i2c_client *client,
int dev_id = 0;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
- if (!indio_dev) {
- dev_err(&client->dev, "iio allocation fails\n");
+ if (!indio_dev)
return -ENOMEM;
- }
chip = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
@@ -750,7 +735,7 @@ static int isl29018_probe(struct i2c_client *client,
chip->suspended = false;
chip->regmap = devm_regmap_init_i2c(client,
- chip_info_tbl[dev_id].regmap_cfg);
+ isl29018_chip_info_tbl[dev_id].regmap_cfg);
if (IS_ERR(chip->regmap)) {
err = PTR_ERR(chip->regmap);
dev_err(&client->dev, "regmap initialization fails: %d\n", err);
@@ -761,19 +746,13 @@ static int isl29018_probe(struct i2c_client *client,
if (err)
return err;
- indio_dev->info = chip_info_tbl[dev_id].indio_info;
- indio_dev->channels = chip_info_tbl[dev_id].channels;
- indio_dev->num_channels = chip_info_tbl[dev_id].num_channels;
+ indio_dev->info = isl29018_chip_info_tbl[dev_id].indio_info;
+ indio_dev->channels = isl29018_chip_info_tbl[dev_id].channels;
+ indio_dev->num_channels = isl29018_chip_info_tbl[dev_id].num_channels;
indio_dev->name = name;
indio_dev->dev.parent = &client->dev;
indio_dev->modes = INDIO_DIRECT_MODE;
- err = devm_iio_device_register(&client->dev, indio_dev);
- if (err) {
- dev_err(&client->dev, "iio registration fails\n");
- return err;
- }
-
- return 0;
+ return devm_iio_device_register(&client->dev, indio_dev);
}
#ifdef CONFIG_PM_SLEEP
@@ -840,7 +819,6 @@ static const struct of_device_id isl29018_of_match[] = {
MODULE_DEVICE_TABLE(of, isl29018_of_match);
static struct i2c_driver isl29018_driver = {
- .class = I2C_CLASS_HWMON,
.driver = {
.name = "isl29018",
.acpi_match_table = ACPI_PTR(isl29018_acpi_match),
diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c
index 2e3b1d64e32a..aa413e5878b9 100644
--- a/drivers/staging/iio/light/isl29028.c
+++ b/drivers/staging/iio/light/isl29028.c
@@ -27,29 +27,27 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
-#define CONVERSION_TIME_MS 100
+#define ISL29028_CONV_TIME_MS 100
#define ISL29028_REG_CONFIGURE 0x01
-#define CONFIGURE_ALS_IR_MODE_ALS 0
-#define CONFIGURE_ALS_IR_MODE_IR BIT(0)
-#define CONFIGURE_ALS_IR_MODE_MASK BIT(0)
+#define ISL29028_CONF_ALS_IR_MODE_ALS 0
+#define ISL29028_CONF_ALS_IR_MODE_IR BIT(0)
+#define ISL29028_CONF_ALS_IR_MODE_MASK BIT(0)
-#define CONFIGURE_ALS_RANGE_LOW_LUX 0
-#define CONFIGURE_ALS_RANGE_HIGH_LUX BIT(1)
-#define CONFIGURE_ALS_RANGE_MASK BIT(1)
+#define ISL29028_CONF_ALS_RANGE_LOW_LUX 0
+#define ISL29028_CONF_ALS_RANGE_HIGH_LUX BIT(1)
+#define ISL29028_CONF_ALS_RANGE_MASK BIT(1)
-#define CONFIGURE_ALS_DIS 0
-#define CONFIGURE_ALS_EN BIT(2)
-#define CONFIGURE_ALS_EN_MASK BIT(2)
+#define ISL29028_CONF_ALS_DIS 0
+#define ISL29028_CONF_ALS_EN BIT(2)
+#define ISL29028_CONF_ALS_EN_MASK BIT(2)
-#define CONFIGURE_PROX_DRIVE BIT(3)
+#define ISL29028_CONF_PROX_SLP_SH 4
+#define ISL29028_CONF_PROX_SLP_MASK (7 << ISL29028_CONF_PROX_SLP_SH)
-#define CONFIGURE_PROX_SLP_SH 4
-#define CONFIGURE_PROX_SLP_MASK (7 << CONFIGURE_PROX_SLP_SH)
-
-#define CONFIGURE_PROX_EN BIT(7)
-#define CONFIGURE_PROX_EN_MASK BIT(7)
+#define ISL29028_CONF_PROX_EN BIT(7)
+#define ISL29028_CONF_PROX_EN_MASK BIT(7)
#define ISL29028_REG_INTERRUPT 0x02
@@ -62,10 +60,10 @@
#define ISL29028_NUM_REGS (ISL29028_REG_TEST2_MODE + 1)
-enum als_ir_mode {
- MODE_NONE = 0,
- MODE_ALS,
- MODE_IR
+enum isl29028_als_ir_mode {
+ ISL29028_MODE_NONE = 0,
+ ISL29028_MODE_ALS,
+ ISL29028_MODE_IR,
};
struct isl29028_chip {
@@ -76,7 +74,7 @@ struct isl29028_chip {
bool enable_prox;
int lux_scale;
- int als_ir_mode;
+ enum isl29028_als_ir_mode als_ir_mode;
};
static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
@@ -91,7 +89,8 @@ static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
break;
}
return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- CONFIGURE_PROX_SLP_MASK, sel << CONFIGURE_PROX_SLP_SH);
+ ISL29028_CONF_PROX_SLP_MASK,
+ sel << ISL29028_CONF_PROX_SLP_SH);
}
static int isl29028_enable_proximity(struct isl29028_chip *chip, bool enable)
@@ -100,9 +99,9 @@ static int isl29028_enable_proximity(struct isl29028_chip *chip, bool enable)
int val = 0;
if (enable)
- val = CONFIGURE_PROX_EN;
+ val = ISL29028_CONF_PROX_EN;
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- CONFIGURE_PROX_EN_MASK, val);
+ ISL29028_CONF_PROX_EN_MASK, val);
if (ret < 0)
return ret;
@@ -113,40 +112,40 @@ static int isl29028_enable_proximity(struct isl29028_chip *chip, bool enable)
static int isl29028_set_als_scale(struct isl29028_chip *chip, int lux_scale)
{
- int val = (lux_scale == 2000) ? CONFIGURE_ALS_RANGE_HIGH_LUX :
- CONFIGURE_ALS_RANGE_LOW_LUX;
+ int val = (lux_scale == 2000) ? ISL29028_CONF_ALS_RANGE_HIGH_LUX :
+ ISL29028_CONF_ALS_RANGE_LOW_LUX;
return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- CONFIGURE_ALS_RANGE_MASK, val);
+ ISL29028_CONF_ALS_RANGE_MASK, val);
}
static int isl29028_set_als_ir_mode(struct isl29028_chip *chip,
- enum als_ir_mode mode)
+ enum isl29028_als_ir_mode mode)
{
int ret = 0;
switch (mode) {
- case MODE_ALS:
+ case ISL29028_MODE_ALS:
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- CONFIGURE_ALS_IR_MODE_MASK,
- CONFIGURE_ALS_IR_MODE_ALS);
+ ISL29028_CONF_ALS_IR_MODE_MASK,
+ ISL29028_CONF_ALS_IR_MODE_ALS);
if (ret < 0)
return ret;
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- CONFIGURE_ALS_RANGE_MASK,
- CONFIGURE_ALS_RANGE_HIGH_LUX);
+ ISL29028_CONF_ALS_RANGE_MASK,
+ ISL29028_CONF_ALS_RANGE_HIGH_LUX);
break;
- case MODE_IR:
+ case ISL29028_MODE_IR:
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- CONFIGURE_ALS_IR_MODE_MASK,
- CONFIGURE_ALS_IR_MODE_IR);
+ ISL29028_CONF_ALS_IR_MODE_MASK,
+ ISL29028_CONF_ALS_IR_MODE_IR);
break;
- case MODE_NONE:
+ case ISL29028_MODE_NONE:
return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- CONFIGURE_ALS_EN_MASK, CONFIGURE_ALS_DIS);
+ ISL29028_CONF_ALS_EN_MASK, ISL29028_CONF_ALS_DIS);
}
if (ret < 0)
@@ -154,12 +153,13 @@ static int isl29028_set_als_ir_mode(struct isl29028_chip *chip,
/* Enable the ALS/IR */
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- CONFIGURE_ALS_EN_MASK, CONFIGURE_ALS_EN);
+ ISL29028_CONF_ALS_EN_MASK,
+ ISL29028_CONF_ALS_EN);
if (ret < 0)
return ret;
/* Need to wait for conversion time if ALS/IR mode enabled */
- mdelay(CONVERSION_TIME_MS);
+ mdelay(ISL29028_CONV_TIME_MS);
return 0;
}
@@ -223,14 +223,14 @@ static int isl29028_als_get(struct isl29028_chip *chip, int *als_data)
int ret;
int als_ir_data;
- if (chip->als_ir_mode != MODE_ALS) {
- ret = isl29028_set_als_ir_mode(chip, MODE_ALS);
+ if (chip->als_ir_mode != ISL29028_MODE_ALS) {
+ ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_ALS);
if (ret < 0) {
dev_err(dev,
"Error in enabling ALS mode err %d\n", ret);
return ret;
}
- chip->als_ir_mode = MODE_ALS;
+ chip->als_ir_mode = ISL29028_MODE_ALS;
}
ret = isl29028_read_als_ir(chip, &als_ir_data);
@@ -256,14 +256,14 @@ static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data)
struct device *dev = regmap_get_device(chip->regmap);
int ret;
- if (chip->als_ir_mode != MODE_IR) {
- ret = isl29028_set_als_ir_mode(chip, MODE_IR);
+ if (chip->als_ir_mode != ISL29028_MODE_IR) {
+ ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_IR);
if (ret < 0) {
dev_err(dev,
"Error in enabling IR mode err %d\n", ret);
return ret;
}
- chip->als_ir_mode = MODE_IR;
+ chip->als_ir_mode = ISL29028_MODE_IR;
}
return isl29028_read_als_ir(chip, ir_data);
}
@@ -383,8 +383,8 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
}
static IIO_CONST_ATTR(in_proximity_sampling_frequency_available,
- "1, 3, 5, 10, 13, 20, 83, 100");
-static IIO_CONST_ATTR(in_illuminance_scale_available, "125, 2000");
+ "1 3 5 10 13 20 83 100");
+static IIO_CONST_ATTR(in_illuminance_scale_available, "125 2000");
#define ISL29028_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr)
#define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr)
@@ -428,7 +428,7 @@ static int isl29028_chip_init(struct isl29028_chip *chip)
chip->enable_prox = false;
chip->prox_sampling = 20;
chip->lux_scale = 2000;
- chip->als_ir_mode = MODE_NONE;
+ chip->als_ir_mode = ISL29028_MODE_NONE;
ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0);
if (ret < 0) {
@@ -462,7 +462,7 @@ static int isl29028_chip_init(struct isl29028_chip *chip)
return ret;
}
-static bool is_volatile_reg(struct device *dev, unsigned int reg)
+static bool isl29028_is_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case ISL29028_REG_INTERRUPT:
@@ -478,7 +478,7 @@ static bool is_volatile_reg(struct device *dev, unsigned int reg)
static const struct regmap_config isl29028_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
- .volatile_reg = is_volatile_reg,
+ .volatile_reg = isl29028_is_volatile_reg,
.max_register = ISL29028_NUM_REGS - 1,
.num_reg_defaults_raw = ISL29028_NUM_REGS,
.cache_type = REGCACHE_RBTREE,
@@ -546,7 +546,6 @@ static const struct of_device_id isl29028_of_match[] = {
MODULE_DEVICE_TABLE(of, isl29028_of_match);
static struct i2c_driver isl29028_driver = {
- .class = I2C_CLASS_HWMON,
.driver = {
.name = "isl29028",
.of_match_table = isl29028_of_match,
diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c
index 05b4ad4e941c..08f1583ee34e 100644
--- a/drivers/staging/iio/light/tsl2583.c
+++ b/drivers/staging/iio/light/tsl2583.c
@@ -803,7 +803,7 @@ static struct attribute *sysfs_attrs_ctrl[] = {
NULL
};
-static struct attribute_group tsl2583_attribute_group = {
+static const struct attribute_group tsl2583_attribute_group = {
.attrs = sysfs_attrs_ctrl,
};
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index c46bef641613..17309591ca57 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -23,9 +23,7 @@
#include "meter.h"
#include "ade7754.h"
-static int ade7754_spi_write_reg_8(struct device *dev,
- u8 reg_address,
- u8 val)
+static int ade7754_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val)
{
int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -42,8 +40,7 @@ static int ade7754_spi_write_reg_8(struct device *dev,
}
static int ade7754_spi_write_reg_16(struct device *dev,
- u8 reg_address,
- u16 value)
+ u8 reg_address, u16 value)
{
int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -59,9 +56,7 @@ static int ade7754_spi_write_reg_16(struct device *dev,
return ret;
}
-static int ade7754_spi_read_reg_8(struct device *dev,
- u8 reg_address,
- u8 *val)
+static int ade7754_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7754_state *st = iio_priv(indio_dev);
@@ -70,7 +65,7 @@ static int ade7754_spi_read_reg_8(struct device *dev,
ret = spi_w8r8(st->us, ADE7754_READ_REG(reg_address));
if (ret < 0) {
dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X",
- reg_address);
+ reg_address);
return ret;
}
*val = ret;
@@ -79,8 +74,7 @@ static int ade7754_spi_read_reg_8(struct device *dev,
}
static int ade7754_spi_read_reg_16(struct device *dev,
- u8 reg_address,
- u16 *val)
+ u8 reg_address, u16 *val)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7754_state *st = iio_priv(indio_dev);
@@ -99,8 +93,7 @@ static int ade7754_spi_read_reg_16(struct device *dev,
}
static int ade7754_spi_read_reg_24(struct device *dev,
- u8 reg_address,
- u32 *val)
+ u8 reg_address, u32 *val)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7754_state *st = iio_priv(indio_dev);
@@ -123,7 +116,7 @@ static int ade7754_spi_read_reg_24(struct device *dev,
ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
if (ret) {
dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
- reg_address);
+ reg_address);
goto error_ret;
}
*val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3];
@@ -134,8 +127,8 @@ error_ret:
}
static ssize_t ade7754_read_8bit(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
int ret;
u8 val = 0;
@@ -149,8 +142,8 @@ static ssize_t ade7754_read_8bit(struct device *dev,
}
static ssize_t ade7754_read_16bit(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
int ret;
u16 val = 0;
@@ -164,8 +157,8 @@ static ssize_t ade7754_read_16bit(struct device *dev,
}
static ssize_t ade7754_read_24bit(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
int ret;
u32 val = 0;
@@ -179,9 +172,9 @@ static ssize_t ade7754_read_24bit(struct device *dev,
}
static ssize_t ade7754_write_8bit(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
@@ -197,9 +190,9 @@ error_ret:
}
static ssize_t ade7754_write_16bit(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int ret;
@@ -403,16 +396,14 @@ err_ret:
}
static ssize_t ade7754_read_frequency(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
int ret;
u8 t;
int sps;
- ret = ade7754_spi_read_reg_8(dev,
- ADE7754_WAVMODE,
- &t);
+ ret = ade7754_spi_read_reg_8(dev, ADE7754_WAVMODE, &t);
if (ret)
return ret;
@@ -423,9 +414,9 @@ static ssize_t ade7754_read_frequency(struct device *dev,
}
static ssize_t ade7754_write_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7754_state *st = iio_priv(indio_dev);
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index a6b76d4b1c80..57c213dfadcc 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -38,18 +38,14 @@ static int ade7758_write_waveform_type(struct device *dev, unsigned int type)
int ret;
u8 reg;
- ret = ade7758_spi_read_reg_8(dev,
- ADE7758_WAVMODE,
- &reg);
+ ret = ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, &reg);
if (ret)
goto out;
reg &= ~0x1F;
reg |= type & 0x1F;
- ret = ade7758_spi_write_reg_8(dev,
- ADE7758_WAVMODE,
- reg);
+ ret = ade7758_spi_write_reg_8(dev, ADE7758_WAVMODE, reg);
out:
return ret;
}
@@ -94,7 +90,7 @@ static int ade7758_ring_preenable(struct iio_dev *indio_dev)
indio_dev->masklength);
ade7758_write_waveform_type(&indio_dev->dev,
- indio_dev->channels[channel].address);
+ indio_dev->channels[channel].address);
return 0;
}
diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c
index 75e8685e6df2..24edbc39ab4e 100644
--- a/drivers/staging/iio/meter/ade7854.c
+++ b/drivers/staging/iio/meter/ade7854.c
@@ -23,8 +23,8 @@
#include "ade7854.h"
static ssize_t ade7854_read_8bit(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
int ret;
u8 val = 0;
@@ -40,8 +40,8 @@ static ssize_t ade7854_read_8bit(struct device *dev,
}
static ssize_t ade7854_read_16bit(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
int ret;
u16 val = 0;
@@ -57,8 +57,8 @@ static ssize_t ade7854_read_16bit(struct device *dev,
}
static ssize_t ade7854_read_24bit(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
int ret;
u32 val;
@@ -74,8 +74,8 @@ static ssize_t ade7854_read_24bit(struct device *dev,
}
static ssize_t ade7854_read_32bit(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
int ret;
u32 val = 0;
@@ -91,9 +91,9 @@ static ssize_t ade7854_read_32bit(struct device *dev,
}
static ssize_t ade7854_write_8bit(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -112,9 +112,9 @@ error_ret:
}
static ssize_t ade7854_write_16bit(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -133,9 +133,9 @@ error_ret:
}
static ssize_t ade7854_write_24bit(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
@@ -154,9 +154,9 @@ error_ret:
}
static ssize_t ade7854_write_32bit(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
diff --git a/drivers/staging/ks7010/eap_packet.h b/drivers/staging/ks7010/eap_packet.h
index 16a392abdaec..df7f760e4110 100644
--- a/drivers/staging/ks7010/eap_packet.h
+++ b/drivers/staging/ks7010/eap_packet.h
@@ -1,6 +1,8 @@
#ifndef EAP_PACKET_H
#define EAP_PACKET_H
+#include <linux/compiler.h>
+
#define WBIT(n) (1 << (n))
#ifndef ETH_ALEN
@@ -19,14 +21,14 @@ struct ether_hdr {
#define ETHER_PROTOCOL_TYPE_IP 0x0800
#define ETHER_PROTOCOL_TYPE_ARP 0x0806
/* followed by length octets of data */
-} __attribute__ ((packed));
+} __packed;
struct ieee802_1x_hdr {
unsigned char version;
unsigned char type;
unsigned short length;
/* followed by length octets of data */
-} __attribute__ ((packed));
+} __packed;
#define EAPOL_VERSION 2
@@ -51,25 +53,33 @@ enum { EAPOL_KEY_TYPE_RC4 = 1, EAPOL_KEY_TYPE_RSN = 2,
struct ieee802_1x_eapol_key {
unsigned char type;
unsigned short key_length;
- /* does not repeat within the life of the keying material used to
- * encrypt the Key field; 64-bit NTP timestamp MAY be used here */
+ /*
+ * does not repeat within the life of the keying material used to
+ * encrypt the Key field; 64-bit NTP timestamp MAY be used here
+ */
unsigned char replay_counter[IEEE8021X_REPLAY_COUNTER_LEN];
unsigned char key_iv[IEEE8021X_KEY_IV_LEN]; /* cryptographically random number */
- unsigned char key_index; /* key flag in the most significant bit:
+ unsigned char key_index; /*
+ * key flag in the most significant bit:
* 0 = broadcast (default key),
* 1 = unicast (key mapping key); key index is in the
- * 7 least significant bits */
- /* HMAC-MD5 message integrity check computed with MS-MPPE-Send-Key as
- * the key */
+ * 7 least significant bits
+ */
+ /*
+ * HMAC-MD5 message integrity check computed with MS-MPPE-Send-Key as
+ * the key
+ */
unsigned char key_signature[IEEE8021X_KEY_SIGN_LEN];
- /* followed by key: if packet body length = 44 + key length, then the
+ /*
+ * followed by key: if packet body length = 44 + key length, then the
* key field (of key_length bytes) contains the key in encrypted form;
* if packet body length = 44, key field is absent and key_length
* represents the number of least significant octets from
* MS-MPPE-Send-Key attribute to be used as the keying material;
- * RC4 key used in encryption = Key-IV + MS-MPPE-Recv-Key */
-} __attribute__ ((packed));
+ * RC4 key used in encryption = Key-IV + MS-MPPE-Recv-Key
+ */
+} __packed;
#define WPA_NONCE_LEN 32
#define WPA_REPLAY_COUNTER_LEN 8
@@ -86,7 +96,7 @@ struct wpa_eapol_key {
unsigned char key_mic[16];
unsigned short key_data_length;
/* followed by key_data_length bytes of key_data */
-} __attribute__ ((packed));
+} __packed;
#define WPA_KEY_INFO_TYPE_MASK (WBIT(0) | WBIT(1) | WBIT(2))
#define WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 WBIT(0)
diff --git a/drivers/staging/ks7010/ks7010_sdio.c b/drivers/staging/ks7010/ks7010_sdio.c
index b7337fd813d5..81c46f4d0935 100644
--- a/drivers/staging/ks7010/ks7010_sdio.c
+++ b/drivers/staging/ks7010/ks7010_sdio.c
@@ -14,7 +14,7 @@
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_func.h>
#include <linux/workqueue.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include "ks_wlan.h"
#include "ks_wlan_ioctl.h"
@@ -35,18 +35,18 @@ MODULE_DEVICE_TABLE(sdio, ks7010_sdio_ids);
/* macro */
#define inc_txqhead(priv) \
- ( priv->tx_dev.qhead = (priv->tx_dev.qhead + 1) % TX_DEVICE_BUFF_SIZE )
+ (priv->tx_dev.qhead = (priv->tx_dev.qhead + 1) % TX_DEVICE_BUFF_SIZE)
#define inc_txqtail(priv) \
- ( priv->tx_dev.qtail = (priv->tx_dev.qtail + 1) % TX_DEVICE_BUFF_SIZE )
+ (priv->tx_dev.qtail = (priv->tx_dev.qtail + 1) % TX_DEVICE_BUFF_SIZE)
#define cnt_txqbody(priv) \
- (((priv->tx_dev.qtail + TX_DEVICE_BUFF_SIZE) - (priv->tx_dev.qhead)) % TX_DEVICE_BUFF_SIZE )
+ (((priv->tx_dev.qtail + TX_DEVICE_BUFF_SIZE) - (priv->tx_dev.qhead)) % TX_DEVICE_BUFF_SIZE)
#define inc_rxqhead(priv) \
- ( priv->rx_dev.qhead = (priv->rx_dev.qhead + 1) % RX_DEVICE_BUFF_SIZE )
+ (priv->rx_dev.qhead = (priv->rx_dev.qhead + 1) % RX_DEVICE_BUFF_SIZE)
#define inc_rxqtail(priv) \
- ( priv->rx_dev.qtail = (priv->rx_dev.qtail + 1) % RX_DEVICE_BUFF_SIZE )
+ (priv->rx_dev.qtail = (priv->rx_dev.qtail + 1) % RX_DEVICE_BUFF_SIZE)
#define cnt_rxqbody(priv) \
- (((priv->rx_dev.qtail + RX_DEVICE_BUFF_SIZE) - (priv->rx_dev.qhead)) % RX_DEVICE_BUFF_SIZE )
+ (((priv->rx_dev.qtail + RX_DEVICE_BUFF_SIZE) - (priv->rx_dev.qhead)) % RX_DEVICE_BUFF_SIZE)
static int ks7010_sdio_read(struct ks_wlan_private *priv, unsigned int address,
unsigned char *buffer, int length)
@@ -87,7 +87,7 @@ static int ks7010_sdio_write(struct ks_wlan_private *priv, unsigned int address,
return rc;
}
-void ks_wlan_hw_sleep_doze_request(struct ks_wlan_private *priv)
+static void ks_wlan_hw_sleep_doze_request(struct ks_wlan_private *priv)
{
unsigned char rw_data;
int retval;
@@ -115,10 +115,9 @@ void ks_wlan_hw_sleep_doze_request(struct ks_wlan_private *priv)
out:
priv->sleep_mode = atomic_read(&priv->sleepstatus.status);
- return;
}
-void ks_wlan_hw_sleep_wakeup_request(struct ks_wlan_private *priv)
+static void ks_wlan_hw_sleep_wakeup_request(struct ks_wlan_private *priv)
{
unsigned char rw_data;
int retval;
@@ -146,7 +145,6 @@ void ks_wlan_hw_sleep_wakeup_request(struct ks_wlan_private *priv)
out:
priv->sleep_mode = atomic_read(&priv->sleepstatus.status);
- return;
}
void ks_wlan_hw_wakeup_request(struct ks_wlan_private *priv)
@@ -159,9 +157,9 @@ void ks_wlan_hw_wakeup_request(struct ks_wlan_private *priv)
rw_data = WAKEUP_REQ;
retval =
ks7010_sdio_write(priv, WAKEUP, &rw_data, sizeof(rw_data));
- if (retval) {
+ if (retval)
DPRINTK(1, " error : WAKEUP=%02X\n", rw_data);
- }
+
DPRINTK(4, "wake up : WAKEUP=%02X\n", rw_data);
priv->last_wakeup = jiffies;
++priv->wakeup_count;
@@ -171,19 +169,16 @@ void ks_wlan_hw_wakeup_request(struct ks_wlan_private *priv)
}
}
-int _ks_wlan_hw_power_save(struct ks_wlan_private *priv)
+static int _ks_wlan_hw_power_save(struct ks_wlan_private *priv)
{
- int rc = 0;
unsigned char rw_data;
int retval;
if (priv->reg.powermgt == POWMGT_ACTIVE_MODE)
- return rc;
+ return 0;
if (priv->reg.operation_mode == MODE_INFRASTRUCTURE &&
(priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {
-
- //DPRINTK(1,"psstatus.status=%d\n",atomic_read(&priv->psstatus.status));
if (priv->dev_state == DEVICE_STATE_SLEEP) {
switch (atomic_read(&priv->psstatus.status)) {
case PS_SNOOZE: /* 4 */
@@ -246,10 +241,9 @@ int _ks_wlan_hw_power_save(struct ks_wlan_private *priv)
break;
}
}
-
}
- return rc;
+ return 0;
}
int ks_wlan_hw_power_save(struct ks_wlan_private *priv)
@@ -268,7 +262,7 @@ static int enqueue_txdev(struct ks_wlan_private *priv, unsigned char *p,
if (priv->dev_state < DEVICE_STATE_BOOT) {
kfree(p);
- if (complete_handler != NULL)
+ if (complete_handler)
(*complete_handler) (arg1, arg2);
return 1;
}
@@ -277,7 +271,7 @@ static int enqueue_txdev(struct ks_wlan_private *priv, unsigned char *p,
/* in case of buffer overflow */
DPRINTK(1, "tx buffer overflow\n");
kfree(p);
- if (complete_handler != NULL)
+ if (complete_handler)
(*complete_handler) (arg1, arg2);
return 1;
}
@@ -297,11 +291,10 @@ static int enqueue_txdev(struct ks_wlan_private *priv, unsigned char *p,
static int write_to_device(struct ks_wlan_private *priv, unsigned char *buffer,
unsigned long size)
{
- int rc, retval;
+ int retval;
unsigned char rw_data;
struct hostif_hdr *hdr;
hdr = (struct hostif_hdr *)buffer;
- rc = 0;
DPRINTK(4, "size=%d\n", hdr->size);
if (hdr->event < HIF_DATA_REQ || HIF_REQ_MAX < hdr->event) {
@@ -346,10 +339,9 @@ static void tx_device_task(void *dev)
&priv->ks_wlan_hw.rw_wq, 1);
return;
}
-
}
kfree(sp->sendp); /* allocated memory free */
- if (sp->complete_handler != NULL) /* TX Complete */
+ if (sp->complete_handler) /* TX Complete */
(*sp->complete_handler) (sp->arg1, sp->arg2);
inc_txqhead(priv);
@@ -358,7 +350,6 @@ static void tx_device_task(void *dev)
&priv->ks_wlan_hw.rw_wq, 0);
}
}
- return;
}
int ks_wlan_hw_tx(struct ks_wlan_private *priv, void *p, unsigned long size,
@@ -402,12 +393,9 @@ static void rx_event_task(unsigned long dev)
hostif_receive(priv, rp->data, rp->size);
inc_rxqhead(priv);
- if (cnt_rxqbody(priv) > 0) {
+ if (cnt_rxqbody(priv) > 0)
tasklet_schedule(&priv->ks_wlan_hw.rx_bh_task);
- }
}
-
- return;
}
static void ks_wlan_hw_rx(void *dev, uint16_t size)
@@ -432,9 +420,8 @@ static void ks_wlan_hw_rx(void *dev, uint16_t size)
retval =
ks7010_sdio_read(priv, DATA_WINDOW, &rx_buffer->data[0],
hif_align_size(size));
- if (retval) {
+ if (retval)
goto error_out;
- }
/* length check */
if (size > 2046 || size == 0) {
@@ -449,9 +436,9 @@ static void ks_wlan_hw_rx(void *dev, uint16_t size)
retval =
ks7010_sdio_write(priv, READ_STATUS, &read_status,
sizeof(read_status));
- if (retval) {
+ if (retval)
DPRINTK(1, " error : READ_STATUS=%02X\n", read_status);
- }
+
goto error_out;
}
@@ -465,9 +452,9 @@ static void ks_wlan_hw_rx(void *dev, uint16_t size)
retval =
ks7010_sdio_write(priv, READ_STATUS, &read_status,
sizeof(read_status));
- if (retval) {
+ if (retval)
DPRINTK(1, " error : READ_STATUS=%02X\n", read_status);
- }
+
DPRINTK(4, "READ_STATUS=%02X\n", read_status);
if (atomic_read(&priv->psstatus.confirm_wait)) {
@@ -498,7 +485,7 @@ static void ks7010_rw_function(struct work_struct *work)
/* wiat after DOZE */
if (time_after(priv->last_doze + ((30 * HZ) / 1000), jiffies)) {
- DPRINTK(4, "wait after DOZE \n");
+ DPRINTK(4, "wait after DOZE\n");
queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
&priv->ks_wlan_hw.rw_wq, 1);
return;
@@ -506,11 +493,13 @@ static void ks7010_rw_function(struct work_struct *work)
/* wiat after WAKEUP */
while (time_after(priv->last_wakeup + ((30 * HZ) / 1000), jiffies)) {
- DPRINTK(4, "wait after WAKEUP \n");
+ DPRINTK(4, "wait after WAKEUP\n");
/* queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,&priv->ks_wlan_hw.rw_wq,
(priv->last_wakeup + ((30*HZ)/1000) - jiffies));*/
- printk("wake: %lu %lu\n", priv->last_wakeup + (30 * HZ) / 1000,
- jiffies);
+ dev_info(&priv->ks_wlan_hw.sdio_card->func->dev,
+ "wake: %lu %lu\n",
+ priv->last_wakeup + (30 * HZ) / 1000,
+ jiffies);
msleep(30);
}
@@ -549,17 +538,15 @@ static void ks7010_rw_function(struct work_struct *work)
if (rw_data & RSIZE_MASK) { /* Read schedule */
ks_wlan_hw_rx((void *)priv,
- (uint16_t) (((rw_data & RSIZE_MASK) << 4)));
+ (uint16_t)((rw_data & RSIZE_MASK) << 4));
}
- if ((rw_data & WSTATUS_MASK)) {
+ if ((rw_data & WSTATUS_MASK))
tx_device_task((void *)priv);
- }
+
_ks_wlan_hw_power_save(priv);
err_out:
sdio_release_host(priv->ks_wlan_hw.sdio_card->func);
-
- return;
}
static void ks_sdio_interrupt(struct sdio_func *func)
@@ -607,7 +594,6 @@ static void ks_sdio_interrupt(struct sdio_func *func)
}
complete(&priv->psstatus.wakeup_wait);
}
-
}
do {
@@ -624,7 +610,7 @@ static void ks_sdio_interrupt(struct sdio_func *func)
rsize = rw_data & RSIZE_MASK;
if (rsize) { /* Read schedule */
ks_wlan_hw_rx((void *)priv,
- (uint16_t) (((rsize) << 4)));
+ (uint16_t)(rsize << 4));
}
if (rw_data & WSTATUS_MASK) {
#if 0
@@ -667,7 +653,6 @@ static void ks_sdio_interrupt(struct sdio_func *func)
intr_out:
queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
&priv->ks_wlan_hw.rw_wq, 0);
- return;
}
static int trx_device_init(struct ks_wlan_private *priv)
@@ -696,14 +681,12 @@ static void trx_device_exit(struct ks_wlan_private *priv)
while (cnt_txqbody(priv) > 0) {
sp = &priv->tx_dev.tx_dev_buff[priv->tx_dev.qhead];
kfree(sp->sendp); /* allocated memory free */
- if (sp->complete_handler != NULL) /* TX Complete */
+ if (sp->complete_handler) /* TX Complete */
(*sp->complete_handler) (sp->arg1, sp->arg2);
inc_txqhead(priv);
}
tasklet_kill(&priv->ks_wlan_hw.rx_bh_task);
-
- return;
}
static int ks7010_sdio_update_index(struct ks_wlan_private *priv, u32 index)
@@ -711,7 +694,6 @@ static int ks7010_sdio_update_index(struct ks_wlan_private *priv, u32 index)
int rc = 0;
int retval;
unsigned char *data_buf;
- data_buf = NULL;
data_buf = kmalloc(sizeof(u32), GFP_KERNEL);
if (!data_buf) {
@@ -732,8 +714,7 @@ static int ks7010_sdio_update_index(struct ks_wlan_private *priv, u32 index)
goto error_out;
}
error_out:
- if (data_buf)
- kfree(data_buf);
+ kfree(data_buf);
return rc;
}
@@ -744,7 +725,7 @@ static int ks7010_sdio_data_compare(struct ks_wlan_private *priv, u32 address,
int rc = 0;
int retval;
unsigned char *read_buf;
- read_buf = NULL;
+
read_buf = kmalloc(ROM_BUFF_SIZE, GFP_KERNEL);
if (!read_buf) {
rc = 1;
@@ -758,13 +739,12 @@ static int ks7010_sdio_data_compare(struct ks_wlan_private *priv, u32 address,
retval = memcmp(data, read_buf, size);
if (retval) {
- DPRINTK(0, "data compare error (%d) \n", retval);
+ DPRINTK(0, "data compare error (%d)\n", retval);
rc = 3;
goto error_out;
}
error_out:
- if (read_buf)
- kfree(read_buf);
+ kfree(read_buf);
return rc;
}
@@ -778,14 +758,10 @@ static int ks7010_upload_firmware(struct ks_wlan_private *priv,
int length;
const struct firmware *fw_entry = NULL;
- rom_buf = NULL;
-
/* buffer allocate */
rom_buf = kmalloc(ROM_BUFF_SIZE, GFP_KERNEL);
- if (!rom_buf) {
- rc = 3;
- goto error_out0;
- }
+ if (!rom_buf)
+ return 3;
sdio_claim_host(card->func);
@@ -799,7 +775,7 @@ static int ks7010_upload_firmware(struct ks_wlan_private *priv,
retval = request_firmware(&fw_entry, ROM_FILE, &priv->ks_wlan_hw.sdio_card->func->dev);
if (retval)
- return retval;
+ goto error_out0;
length = fw_entry->size;
@@ -879,8 +855,7 @@ static int ks7010_upload_firmware(struct ks_wlan_private *priv,
release_firmware(fw_entry);
error_out0:
sdio_release_host(card->func);
- if (rom_buf)
- kfree(rom_buf);
+ kfree(rom_buf);
return rc;
}
@@ -903,9 +878,9 @@ static void ks7010_card_init(struct ks_wlan_private *priv)
DPRINTK(1, "wait time out!! SME_START\n");
}
- if (priv->mac_address_valid && priv->version_size) {
+ if (priv->mac_address_valid && priv->version_size)
priv->dev_state = DEVICE_STATE_PREINIT;
- }
+
hostif_sme_enqueue(priv, SME_GET_EEPROM_CKSUM);
@@ -981,7 +956,7 @@ static int ks7010_sdio_probe(struct sdio_func *func,
netdev = NULL;
/* initilize ks_sdio_card */
- card = kzalloc(sizeof(struct ks_sdio_card), GFP_KERNEL);
+ card = kzalloc(sizeof(*card), GFP_KERNEL);
if (!card)
return -ENOMEM;
@@ -1029,12 +1004,13 @@ static int ks7010_sdio_probe(struct sdio_func *func,
/* private memory allocate */
netdev = alloc_etherdev(sizeof(*priv));
- if (netdev == NULL) {
- printk(KERN_ERR "ks7010 : Unable to alloc new net device\n");
+ if (!netdev) {
+ dev_err(&card->func->dev, "ks7010 : Unable to alloc new net device\n");
goto error_release_irq;
}
if (dev_alloc_name(netdev, "wlan%d") < 0) {
- printk(KERN_ERR "ks7010 : Couldn't get name!\n");
+ dev_err(&card->func->dev,
+ "ks7010 : Couldn't get name!\n");
goto error_free_netdev;
}
@@ -1048,9 +1024,9 @@ static int ks7010_sdio_probe(struct sdio_func *func,
init_completion(&priv->ks_wlan_hw.ks7010_sdio_wait);
priv->ks_wlan_hw.read_buf = NULL;
priv->ks_wlan_hw.read_buf = kmalloc(RX_DATA_SIZE, GFP_KERNEL);
- if (!priv->ks_wlan_hw.read_buf) {
+ if (!priv->ks_wlan_hw.read_buf)
goto error_free_netdev;
- }
+
priv->dev_state = DEVICE_STATE_PREBOOT;
priv->net_dev = netdev;
priv->firmware_version[0] = '\0';
@@ -1074,9 +1050,9 @@ static int ks7010_sdio_probe(struct sdio_func *func,
/* Upload firmware */
ret = ks7010_upload_firmware(priv, card); /* firmware load */
if (ret) {
- printk(KERN_ERR
- "ks7010: firmware load failed !! retern code = %d\n",
- ret);
+ dev_err(&card->func->dev,
+ "ks7010: firmware load failed !! return code = %d\n",
+ ret);
goto error_free_read_buf;
}
@@ -1086,9 +1062,9 @@ static int ks7010_sdio_probe(struct sdio_func *func,
sdio_claim_host(func);
ret = ks7010_sdio_write(priv, INT_PENDING, &rw_data, sizeof(rw_data));
sdio_release_host(func);
- if (ret) {
+ if (ret)
DPRINTK(1, " error : INT_PENDING=%02X\n", rw_data);
- }
+
DPRINTK(4, " clear Interrupt : INT_PENDING=%02X\n", rw_data);
/* enable ks7010sdio interrupt (INT_GCR_B|INT_READ_STATUS|INT_WRITE_STATUS) */
@@ -1096,9 +1072,9 @@ static int ks7010_sdio_probe(struct sdio_func *func,
sdio_claim_host(func);
ret = ks7010_sdio_write(priv, INT_ENABLE, &rw_data, sizeof(rw_data));
sdio_release_host(func);
- if (ret) {
+ if (ret)
DPRINTK(1, " error : INT_ENABLE=%02X\n", rw_data);
- }
+
DPRINTK(4, " enable Interrupt : INT_ENABLE=%02X\n", rw_data);
priv->dev_state = DEVICE_STATE_BOOT;
@@ -1141,18 +1117,18 @@ static void ks7010_sdio_remove(struct sdio_func *func)
int ret;
struct ks_sdio_card *card;
struct ks_wlan_private *priv;
- struct net_device *netdev;
DPRINTK(1, "ks7010_sdio_remove()\n");
card = sdio_get_drvdata(func);
- if (card == NULL)
+ if (!card)
return;
DPRINTK(1, "priv = card->priv\n");
priv = card->priv;
- netdev = priv->net_dev;
if (priv) {
+ struct net_device *netdev = priv->net_dev;
+
ks_wlan_net_stop(netdev);
DPRINTK(1, "ks_wlan_net_stop\n");
@@ -1166,9 +1142,8 @@ static void ks7010_sdio_remove(struct sdio_func *func)
/* send stop request to MAC */
{
struct hostif_stop_request_t *pp;
- pp = (struct hostif_stop_request_t *)
- kzalloc(hif_align_size(sizeof(*pp)), GFP_KERNEL);
- if (pp == NULL) {
+ pp = kzalloc(hif_align_size(sizeof(*pp)), GFP_KERNEL);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return; /* to do goto ni suru */
}
@@ -1176,7 +1151,7 @@ static void ks7010_sdio_remove(struct sdio_func *func)
cpu_to_le16((uint16_t)
(sizeof(*pp) -
sizeof(pp->header.size)));
- pp->header.event = cpu_to_le16((uint16_t) HIF_STOP_REQ);
+ pp->header.event = cpu_to_le16((uint16_t)HIF_STOP_REQ);
sdio_claim_host(func);
write_to_device(priv, (unsigned char *)pp,
@@ -1199,9 +1174,7 @@ static void ks7010_sdio_remove(struct sdio_func *func)
unregister_netdev(netdev);
trx_device_exit(priv);
- if (priv->ks_wlan_hw.read_buf) {
- kfree(priv->ks_wlan_hw.read_buf);
- }
+ kfree(priv->ks_wlan_hw.read_buf);
free_netdev(priv->net_dev);
card->priv = NULL;
}
@@ -1219,7 +1192,6 @@ static void ks7010_sdio_remove(struct sdio_func *func)
DPRINTK(1, "kfree()\n");
DPRINTK(5, " Bye !!\n");
- return;
}
static struct sdio_driver ks7010_sdio_driver = {
diff --git a/drivers/staging/ks7010/ks_hostif.c b/drivers/staging/ks7010/ks_hostif.c
index a8822fe2bd60..c57ca581550a 100644
--- a/drivers/staging/ks7010/ks_hostif.c
+++ b/drivers/staging/ks7010/ks_hostif.c
@@ -14,21 +14,13 @@
#include "eap_packet.h"
#include "michael_mic.h"
+#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
/* Include Wireless Extension definition and check version */
#include <net/iw_handler.h> /* New driver API */
-extern int ks_wlan_hw_tx(struct ks_wlan_private *priv, void *p,
- unsigned long size,
- void (*complete_handler) (void *arg1, void *arg2),
- void *arg1, void *arg2);
-extern void send_packet_complete(void *, void *);
-
-extern void ks_wlan_hw_wakeup_request(struct ks_wlan_private *priv);
-extern int ks_wlan_hw_power_save(struct ks_wlan_private *priv);
-
/* macro */
#define inc_smeqhead(priv) \
( priv->sme_i.qhead = (priv->sme_i.qhead + 1) % SME_EVENT_BUFF_SIZE )
@@ -43,6 +35,7 @@ static
inline u8 get_BYTE(struct ks_wlan_private *priv)
{
u8 data;
+
data = *(priv->rxp)++;
/* length check in advance ! */
--(priv->rx_size);
@@ -53,6 +46,7 @@ static
inline u16 get_WORD(struct ks_wlan_private *priv)
{
u16 data;
+
data = (get_BYTE(priv) & 0xff);
data |= ((get_BYTE(priv) << 8) & 0xff00);
return data;
@@ -62,6 +56,7 @@ static
inline u32 get_DWORD(struct ks_wlan_private *priv)
{
u32 data;
+
data = (get_BYTE(priv) & 0xff);
data |= ((get_BYTE(priv) << 8) & 0x0000ff00);
data |= ((get_BYTE(priv) << 16) & 0x00ff0000);
@@ -69,16 +64,20 @@ inline u32 get_DWORD(struct ks_wlan_private *priv)
return data;
}
-void ks_wlan_hw_wakeup_task(struct work_struct *work)
+static void ks_wlan_hw_wakeup_task(struct work_struct *work)
{
struct ks_wlan_private *priv =
container_of(work, struct ks_wlan_private, ks_wlan_wakeup_task);
int ps_status = atomic_read(&priv->psstatus.status);
+ long time_left;
if (ps_status == PS_SNOOZE) {
ks_wlan_hw_wakeup_request(priv);
- if (!wait_for_completion_interruptible_timeout(&priv->psstatus.wakeup_wait, HZ / 50)) { /* 20ms timeout */
- DPRINTK(1, "wake up timeout !!!\n");
+ time_left = wait_for_completion_interruptible_timeout(
+ &priv->psstatus.wakeup_wait,
+ msecs_to_jiffies(20));
+ if (time_left <= 0) {
+ DPRINTK(1, "wake up timeout or interrupted !!!\n");
schedule_work(&priv->ks_wlan_wakeup_task);
return;
}
@@ -96,8 +95,6 @@ void ks_wlan_hw_wakeup_task(struct work_struct *work)
static
int ks_wlan_do_power_save(struct ks_wlan_private *priv)
{
- int rc = 0;
-
DPRINTK(4, "psstatus.status=%d\n", atomic_read(&priv->psstatus.status));
if ((priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {
@@ -105,7 +102,7 @@ int ks_wlan_do_power_save(struct ks_wlan_private *priv)
} else {
priv->dev_state = DEVICE_STATE_READY;
}
- return rc;
+ return 0;
}
static
@@ -217,7 +214,6 @@ int get_ap_information(struct ks_wlan_private *priv, struct ap_info_t *ap_info,
{
unsigned char *bp;
int bsize, offset;
- int rc = 0;
DPRINTK(3, "\n");
memset(ap, 0, sizeof(struct local_ap_t));
@@ -240,13 +236,13 @@ int get_ap_information(struct ks_wlan_private *priv, struct ap_info_t *ap_info,
offset = 0;
while (bsize > offset) {
- /* DPRINTK(4, "Element ID=%d \n",*bp); */
+ /* DPRINTK(4, "Element ID=%d\n",*bp); */
switch (*bp) {
case 0: /* ssid */
if (*(bp + 1) <= SSID_MAX_SIZE) {
ap->ssid.size = *(bp + 1);
} else {
- DPRINTK(1, "size over :: ssid size=%d \n",
+ DPRINTK(1, "size over :: ssid size=%d\n",
*(bp + 1));
ap->ssid.size = SSID_MAX_SIZE;
}
@@ -260,7 +256,7 @@ int get_ap_information(struct ks_wlan_private *priv, struct ap_info_t *ap_info,
bp + 2, *(bp + 1));
ap->rate_set.size += *(bp + 1);
} else {
- DPRINTK(1, "size over :: rate size=%d \n",
+ DPRINTK(1, "size over :: rate size=%d\n",
(*(bp + 1) + ap->rate_set.size));
memcpy(&(ap->rate_set.body[ap->rate_set.size]),
bp + 2,
@@ -276,7 +272,7 @@ int get_ap_information(struct ks_wlan_private *priv, struct ap_info_t *ap_info,
if (*(bp + 1) <= RSN_IE_BODY_MAX) {
ap->rsn_ie.size = *(bp + 1);
} else {
- DPRINTK(1, "size over :: rsn size=%d \n",
+ DPRINTK(1, "size over :: rsn size=%d\n",
*(bp + 1));
ap->rsn_ie.size = RSN_IE_BODY_MAX;
}
@@ -289,7 +285,7 @@ int get_ap_information(struct ks_wlan_private *priv, struct ap_info_t *ap_info,
ap->wpa_ie.size = *(bp + 1);
} else {
DPRINTK(1,
- "size over :: wpa size=%d \n",
+ "size over :: wpa size=%d\n",
*(bp + 1));
ap->wpa_ie.size = RSN_IE_BODY_MAX;
}
@@ -307,7 +303,7 @@ int get_ap_information(struct ks_wlan_private *priv, struct ap_info_t *ap_info,
case 47: /* Reserve ID 47 Broadcom AP */
break;
default:
- DPRINTK(4, "unknown Element ID=%d \n", *bp);
+ DPRINTK(4, "unknown Element ID=%d\n", *bp);
break;
}
offset += 2; /* id & size field */
@@ -315,7 +311,7 @@ int get_ap_information(struct ks_wlan_private *priv, struct ap_info_t *ap_info,
bp += (*(bp + 1) + 2); /* pointer update */
}
- return rc;
+ return 0;
}
static
@@ -404,7 +400,7 @@ void hostif_data_indication(struct ks_wlan_private *priv)
HZ >= 60) {
mic_failure->failure = 0;
}
- DPRINTK(4, "MIC FAILURE \n");
+ DPRINTK(4, "MIC FAILURE\n");
if (mic_failure->failure == 0) {
mic_failure->failure = 1;
mic_failure->counter = 0;
@@ -481,8 +477,7 @@ void hostif_data_indication(struct ks_wlan_private *priv)
netif_rx(skb);
} else {
printk(KERN_WARNING
- "%s: Memory squeeze, dropping packet.\n",
- skb->dev->name);
+ "ks_wlan: Memory squeeze, dropping packet.\n");
priv->nstats.rx_dropped++;
}
break;
@@ -517,8 +512,7 @@ void hostif_data_indication(struct ks_wlan_private *priv)
netif_rx(skb);
} else {
printk(KERN_WARNING
- "%s: Memory squeeze, dropping packet.\n",
- skb->dev->name);
+ "ks_wlan: Memory squeeze, dropping packet.\n");
priv->nstats.rx_dropped++;
}
break;
@@ -778,7 +772,7 @@ void hostif_start_confirm(struct ks_wlan_private *priv)
wrqu.data.flags = 0;
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
if ((priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {
- memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
+ eth_zero_addr(wrqu.ap_addr.sa_data);
DPRINTK(3, "IWEVENT: disconnect\n");
wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
}
@@ -836,7 +830,7 @@ void hostif_connect_indication(struct ks_wlan_private *priv)
wrqu0.ap_addr.sa_family = ARPHRD_ETHER;
if ((priv->connect_status & CONNECT_STATUS_MASK) == DISCONNECT_STATUS &&
(old_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {
- memset(wrqu0.ap_addr.sa_data, '\0', ETH_ALEN);
+ eth_zero_addr(wrqu0.ap_addr.sa_data);
DPRINTK(3, "IWEVENT: disconnect\n");
DPRINTK(3, "disconnect :: scan_ind_count=%d\n",
priv->scan_ind_count);
@@ -908,7 +902,7 @@ void hostif_stop_confirm(struct ks_wlan_private *priv)
if ((priv->connect_status & CONNECT_STATUS_MASK) ==
DISCONNECT_STATUS
&& (old_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {
- memset(wrqu0.ap_addr.sa_data, '\0', ETH_ALEN);
+ eth_zero_addr(wrqu0.ap_addr.sa_data);
DPRINTK(3, "IWEVENT: disconnect\n");
printk("IWEVENT: disconnect\n");
DPRINTK(3, "disconnect :: scan_ind_count=%d\n",
@@ -1148,7 +1142,7 @@ int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *packet)
packet_len = packet->len;
if (packet_len > ETH_FRAME_LEN) {
- DPRINTK(1, "bad length packet_len=%d \n", packet_len);
+ DPRINTK(1, "bad length packet_len=%d\n", packet_len);
dev_kfree_skb(packet);
return -1;
}
@@ -1172,11 +1166,10 @@ int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *packet)
}
DPRINTK(4, "skb_buff length=%d\n", packet_len);
- pp = (struct hostif_data_request_t *)
- kmalloc(hif_align_size(sizeof(*pp) + 6 + packet_len + 8),
- KS_WLAN_MEM_FLAG);
+ pp = kmalloc(hif_align_size(sizeof(*pp) + 6 + packet_len + 8),
+ KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
dev_kfree_skb(packet);
return -2;
@@ -1194,6 +1187,8 @@ int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *packet)
DPRINTK(1, "ethernet->h_source=%02X:%02X:%02X:%02X:%02X:%02X\n",
eth->h_source[0], eth->h_source[1], eth->h_source[2],
eth->h_source[3], eth->h_source[4], eth->h_source[5]);
+ dev_kfree_skb(packet);
+ kfree(pp);
return -3;
}
@@ -1231,7 +1226,7 @@ int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *packet)
eth_hdr = (struct ether_hdr *)&pp->data[0];
eth_proto = ntohs(eth_hdr->h_proto);
- /* for MIC FAILUER REPORT check */
+ /* for MIC FAILURE REPORT check */
if (eth_proto == ETHER_PROTOCOL_TYPE_EAP
&& priv->wpa.mic_failure.failure > 0) {
aa1x_hdr = (struct ieee802_1x_hdr *)(eth_hdr + 1);
@@ -1284,7 +1279,7 @@ int hostif_data_request(struct ks_wlan_private *priv, struct sk_buff *packet)
(void *)send_packet_complete, (void *)priv,
(void *)packet);
- /* MIC FAILUER REPORT check */
+ /* MIC FAILURE REPORT check */
if (eth_proto == ETHER_PROTOCOL_TYPE_EAP
&& priv->wpa.mic_failure.failure > 0) {
if (keyinfo & WPA_KEY_INFO_ERROR
@@ -1313,9 +1308,8 @@ void hostif_mib_get_request(struct ks_wlan_private *priv,
DPRINTK(3, "\n");
/* make primitive */
- pp = (struct hostif_mib_get_request_t *)
- kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1344,9 +1338,8 @@ void hostif_mib_set_request(struct ks_wlan_private *priv,
}
/* make primitive */
- pp = (struct hostif_mib_set_request_t *)
- kmalloc(hif_align_size(sizeof(*pp) + size), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp) + size), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1374,9 +1367,8 @@ void hostif_start_request(struct ks_wlan_private *priv, unsigned char mode)
DPRINTK(3, "\n");
/* make primitive */
- pp = (struct hostif_start_request_t *)
- kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1402,9 +1394,8 @@ void hostif_ps_adhoc_set_request(struct ks_wlan_private *priv)
DPRINTK(3, "\n");
/* make primitive */
- pp = (struct hostif_ps_adhoc_set_request_t *)
- kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1443,12 +1434,11 @@ void hostif_infrastructure_set_request(struct ks_wlan_private *priv)
struct hostif_infrastructure_set_request_t *pp;
uint16_t capability;
- DPRINTK(3, "ssid.size=%d \n", priv->reg.ssid.size);
+ DPRINTK(3, "ssid.size=%d\n", priv->reg.ssid.size);
/* make primitive */
- pp = (struct hostif_infrastructure_set_request_t *)
- kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1505,17 +1495,16 @@ void hostif_infrastructure_set_request(struct ks_wlan_private *priv)
ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
}
-void hostif_infrastructure_set2_request(struct ks_wlan_private *priv)
+static void hostif_infrastructure_set2_request(struct ks_wlan_private *priv)
{
struct hostif_infrastructure_set2_request_t *pp;
uint16_t capability;
- DPRINTK(2, "ssid.size=%d \n", priv->reg.ssid.size);
+ DPRINTK(2, "ssid.size=%d\n", priv->reg.ssid.size);
/* make primitive */
- pp = (struct hostif_infrastructure_set2_request_t *)
- kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1583,9 +1572,8 @@ void hostif_adhoc_set_request(struct ks_wlan_private *priv)
DPRINTK(3, "\n");
/* make primitive */
- pp = (struct hostif_adhoc_set_request_t *)
- kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1629,9 +1617,8 @@ void hostif_adhoc_set2_request(struct ks_wlan_private *priv)
DPRINTK(3, "\n");
/* make primitive */
- pp = (struct hostif_adhoc_set2_request_t *)
- kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1677,9 +1664,8 @@ void hostif_stop_request(struct ks_wlan_private *priv)
DPRINTK(3, "\n");
/* make primitive */
- pp = (struct hostif_stop_request_t *)
- kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1700,9 +1686,8 @@ void hostif_phy_information_request(struct ks_wlan_private *priv)
DPRINTK(3, "\n");
/* make primitive */
- pp = (struct hostif_phy_information_request_t *)
- kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1732,9 +1717,8 @@ void hostif_power_mngmt_request(struct ks_wlan_private *priv,
DPRINTK(3, "mode=%lu wake_up=%lu receiveDTIMs=%lu\n", mode, wake_up,
receiveDTIMs);
/* make primitive */
- pp = (struct hostif_power_mngmt_request_t *)
- kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1755,13 +1739,12 @@ void hostif_sleep_request(struct ks_wlan_private *priv, unsigned long mode)
{
struct hostif_sleep_request_t *pp;
- DPRINTK(3, "mode=%lu \n", mode);
+ DPRINTK(3, "mode=%lu\n", mode);
if (mode == SLP_SLEEP) {
/* make primitive */
- pp = (struct hostif_sleep_request_t *)
- kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1779,23 +1762,22 @@ void hostif_sleep_request(struct ks_wlan_private *priv, unsigned long mode)
queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
&priv->ks_wlan_hw.rw_wq, 1);
} else {
- DPRINTK(3, "invalid mode %ld \n", mode);
+ DPRINTK(3, "invalid mode %ld\n", mode);
return;
}
}
static
void hostif_bss_scan_request(struct ks_wlan_private *priv,
- unsigned long scan_type, uint8_t * scan_ssid,
+ unsigned long scan_type, uint8_t *scan_ssid,
uint8_t scan_ssid_len)
{
struct hostif_bss_scan_request_t *pp;
DPRINTK(2, "\n");
/* make primitive */
- pp = (struct hostif_bss_scan_request_t *)
- kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1850,9 +1832,8 @@ void hostif_mic_failure_request(struct ks_wlan_private *priv,
DPRINTK(3, "count=%d :: timer=%d\n", failure_count, timer);
/* make primitive */
- pp = (struct hostif_mic_failure_request_t *)
- kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
- if (pp == NULL) {
+ pp = kmalloc(hif_align_size(sizeof(*pp)), KS_WLAN_MEM_FLAG);
+ if (!pp) {
DPRINTK(3, "allocate memory failed..\n");
return;
}
@@ -1867,7 +1848,7 @@ void hostif_mic_failure_request(struct ks_wlan_private *priv,
ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
}
-/* Device I/O Recieve indicate */
+/* Device I/O Receive indicate */
static void devio_rec_ind(struct ks_wlan_private *priv, unsigned char *p,
unsigned int size)
{
@@ -2700,7 +2681,6 @@ void hostif_sme_enqueue(struct ks_wlan_private *priv, unsigned short event)
int hostif_init(struct ks_wlan_private *priv)
{
- int rc = 0;
int i;
DPRINTK(3, "\n");
@@ -2750,7 +2730,7 @@ int hostif_init(struct ks_wlan_private *priv)
tasklet_init(&priv->sme_task, hostif_sme_task, (unsigned long)priv);
- return rc;
+ return 0;
}
void hostif_exit(struct ks_wlan_private *priv)
diff --git a/drivers/staging/ks7010/ks_hostif.h b/drivers/staging/ks7010/ks_hostif.h
index dc806b5b47be..743f31ead56e 100644
--- a/drivers/staging/ks7010/ks_hostif.h
+++ b/drivers/staging/ks7010/ks_hostif.h
@@ -11,6 +11,9 @@
#ifndef _KS_HOSTIF_H_
#define _KS_HOSTIF_H_
+
+#include <linux/compiler.h>
+
/*
* HOST-MAC I/F events
*/
@@ -61,7 +64,7 @@
struct hostif_hdr {
uint16_t size;
uint16_t event;
-} __attribute__ ((packed));
+} __packed;
struct hostif_data_request_t {
struct hostif_hdr header;
@@ -70,7 +73,7 @@ struct hostif_data_request_t {
#define TYPE_AUTH 0x0001
uint16_t reserved;
uint8_t data[0];
-} __attribute__ ((packed));
+} __packed;
struct hostif_data_indication_t {
struct hostif_hdr header;
@@ -81,14 +84,14 @@ struct hostif_data_indication_t {
#define TYPE_GMK2 0x0003
uint16_t reserved;
uint8_t data[0];
-} __attribute__ ((packed));
+} __packed;
#define CHANNEL_LIST_MAX_SIZE 14
struct channel_list_t {
uint8_t size;
uint8_t body[CHANNEL_LIST_MAX_SIZE];
uint8_t pad;
-} __attribute__ ((packed));
+} __packed;
/* MIB Attribute */
#define DOT11_MAC_ADDRESS 0x21010100 /* MAC Address (R) */
@@ -141,7 +144,7 @@ struct channel_list_t {
struct hostif_mib_get_request_t {
struct hostif_hdr header;
uint32_t mib_attribute;
-} __attribute__ ((packed));
+} __packed;
struct hostif_mib_value_t {
uint16_t size;
@@ -152,7 +155,7 @@ struct hostif_mib_value_t {
#define MIB_VALUE_TYPE_COUNT32 3
#define MIB_VALUE_TYPE_OSTRING 4
uint8_t body[0];
-} __attribute__ ((packed));
+} __packed;
struct hostif_mib_get_confirm_t {
struct hostif_hdr header;
@@ -163,19 +166,19 @@ struct hostif_mib_get_confirm_t {
#define MIB_WRITE_ONLY 3
uint32_t mib_attribute;
struct hostif_mib_value_t mib_value;
-} __attribute__ ((packed));
+} __packed;
struct hostif_mib_set_request_t {
struct hostif_hdr header;
uint32_t mib_attribute;
struct hostif_mib_value_t mib_value;
-} __attribute__ ((packed));
+} __packed;
struct hostif_mib_set_confirm_t {
struct hostif_hdr header;
uint32_t mib_status;
uint32_t mib_attribute;
-} __attribute__ ((packed));
+} __packed;
struct hostif_power_mngmt_request_t {
struct hostif_hdr header;
@@ -188,7 +191,7 @@ struct hostif_power_mngmt_request_t {
uint32_t receiveDTIMs;
#define DTIM_FALSE 0
#define DTIM_TRUE 1
-} __attribute__ ((packed));
+} __packed;
/* power management mode */
enum {
@@ -206,7 +209,7 @@ enum {
struct hostif_power_mngmt_confirm_t {
struct hostif_hdr header;
uint16_t result_code;
-} __attribute__ ((packed));
+} __packed;
struct hostif_start_request_t {
struct hostif_hdr header;
@@ -215,64 +218,64 @@ struct hostif_start_request_t {
#define MODE_INFRASTRUCTURE 1
#define MODE_AP 2 /* not used */
#define MODE_ADHOC 3
-} __attribute__ ((packed));
+} __packed;
struct hostif_start_confirm_t {
struct hostif_hdr header;
uint16_t result_code;
-} __attribute__ ((packed));
+} __packed;
#define SSID_MAX_SIZE 32
struct ssid_t {
uint8_t size;
uint8_t body[SSID_MAX_SIZE];
uint8_t ssid_pad;
-} __attribute__ ((packed));
+} __packed;
#define RATE_SET_MAX_SIZE 16
struct rate_set8_t {
uint8_t size;
uint8_t body[8];
uint8_t rate_pad;
-} __attribute__ ((packed));
+} __packed;
struct FhParms_t {
uint16_t dwellTime;
uint8_t hopSet;
uint8_t hopPattern;
uint8_t hopIndex;
-} __attribute__ ((packed));
+} __packed;
struct DsParms_t {
uint8_t channel;
-} __attribute__ ((packed));
+} __packed;
struct CfParms_t {
uint8_t count;
uint8_t period;
uint16_t maxDuration;
uint16_t durRemaining;
-} __attribute__ ((packed));
+} __packed;
struct IbssParms_t {
uint16_t atimWindow;
-} __attribute__ ((packed));
+} __packed;
struct rsn_t {
uint8_t size;
#define RSN_BODY_SIZE 64
uint8_t body[RSN_BODY_SIZE];
-} __attribute__ ((packed));
+} __packed;
struct ErpParams_t {
uint8_t erp_info;
-} __attribute__ ((packed));
+} __packed;
struct rate_set16_t {
uint8_t size;
uint8_t body[16];
uint8_t rate_pad;
-} __attribute__ ((packed));
+} __packed;
struct ap_info_t {
uint8_t bssid[6]; /* +00 */
@@ -299,7 +302,7 @@ struct ap_info_t {
uint16_t body_size; /* +16 */
uint8_t body[1024]; /* +18 */
/* +1032 */
-} __attribute__ ((packed));
+} __packed;
struct link_ap_info_t {
uint8_t bssid[6]; /* +00 */
@@ -325,8 +328,8 @@ struct link_ap_info_t {
struct {
uint8_t size; /* +52 */
uint8_t body[128]; /* +53 */
- } __attribute__ ((packed)) rsn;
-} __attribute__ ((packed));
+ } __packed rsn;
+} __packed;
struct hostif_connect_indication_t {
struct hostif_hdr header;
@@ -334,16 +337,16 @@ struct hostif_connect_indication_t {
#define RESULT_CONNECT 0
#define RESULT_DISCONNECT 1
struct link_ap_info_t link_ap_info;
-} __attribute__ ((packed));
+} __packed;
struct hostif_stop_request_t {
struct hostif_hdr header;
-} __attribute__ ((packed));
+} __packed;
struct hostif_stop_confirm_t {
struct hostif_hdr header;
uint16_t result_code;
-} __attribute__ ((packed));
+} __packed;
struct hostif_ps_adhoc_set_request_t {
struct hostif_hdr header;
@@ -360,12 +363,12 @@ struct hostif_ps_adhoc_set_request_t {
uint16_t capability; /* bit5:preamble bit6:pbcc pbcc not supported always 0
* bit10:ShortSlotTime bit13:DSSS-OFDM DSSS-OFDM not supported always 0 */
uint16_t scan_type;
-} __attribute__ ((packed));
+} __packed;
struct hostif_ps_adhoc_set_confirm_t {
struct hostif_hdr header;
uint16_t result_code;
-} __attribute__ ((packed));
+} __packed;
struct hostif_infrastructure_set_request_t {
struct hostif_hdr header;
@@ -381,7 +384,7 @@ struct hostif_infrastructure_set_request_t {
#define AUTH_TYPE_SHARED_KEY 1
struct channel_list_t channel_list;
uint16_t scan_type;
-} __attribute__ ((packed));
+} __packed;
struct hostif_infrastructure_set2_request_t {
struct hostif_hdr header;
@@ -398,12 +401,12 @@ struct hostif_infrastructure_set2_request_t {
struct channel_list_t channel_list;
uint16_t scan_type;
uint8_t bssid[ETH_ALEN];
-} __attribute__ ((packed));
+} __packed;
struct hostif_infrastructure_set_confirm_t {
struct hostif_hdr header;
uint16_t result_code;
-} __attribute__ ((packed));
+} __packed;
struct hostif_adhoc_set_request_t {
struct hostif_hdr header;
@@ -415,7 +418,7 @@ struct hostif_adhoc_set_request_t {
uint16_t capability; /* bit5:preamble bit6:pbcc pbcc not supported always 0
* bit10:ShortSlotTime bit13:DSSS-OFDM DSSS-OFDM not supported always 0 */
uint16_t scan_type;
-} __attribute__ ((packed));
+} __packed;
struct hostif_adhoc_set2_request_t {
struct hostif_hdr header;
@@ -429,17 +432,17 @@ struct hostif_adhoc_set2_request_t {
uint16_t scan_type;
struct channel_list_t channel_list;
uint8_t bssid[ETH_ALEN];
-} __attribute__ ((packed));
+} __packed;
struct hostif_adhoc_set_confirm_t {
struct hostif_hdr header;
uint16_t result_code;
-} __attribute__ ((packed));
+} __packed;
struct last_associate_t {
uint8_t type;
uint8_t status;
-} __attribute__ ((packed));
+} __packed;
struct association_request_t {
uint8_t type;
@@ -450,7 +453,7 @@ struct association_request_t {
uint16_t listen_interval;
uint8_t ap_address[6];
uint16_t reqIEs_size;
-} __attribute__ ((packed));
+} __packed;
struct association_response_t {
uint8_t type;
@@ -461,7 +464,7 @@ struct association_response_t {
uint16_t status;
uint16_t association_id;
uint16_t respIEs_size;
-} __attribute__ ((packed));
+} __packed;
struct hostif_associate_indication_t {
struct hostif_hdr header;
@@ -469,7 +472,7 @@ struct hostif_associate_indication_t {
struct association_response_t assoc_resp;
/* followed by (reqIEs_size + respIEs_size) octets of data */
/* reqIEs data *//* respIEs data */
-} __attribute__ ((packed));
+} __packed;
struct hostif_bss_scan_request_t {
struct hostif_hdr header;
@@ -481,13 +484,13 @@ struct hostif_bss_scan_request_t {
uint32_t ch_time_max;
struct channel_list_t channel_list;
struct ssid_t ssid;
-} __attribute__ ((packed));
+} __packed;
struct hostif_bss_scan_confirm_t {
struct hostif_hdr header;
uint16_t result_code;
uint16_t reserved;
-} __attribute__ ((packed));
+} __packed;
struct hostif_phy_information_request_t {
struct hostif_hdr header;
@@ -495,7 +498,7 @@ struct hostif_phy_information_request_t {
#define NORMAL_TYPE 0
#define TIME_TYPE 1
uint16_t time; /* unit 100ms */
-} __attribute__ ((packed));
+} __packed;
struct hostif_phy_information_confirm_t {
struct hostif_hdr header;
@@ -507,30 +510,30 @@ struct hostif_phy_information_confirm_t {
uint32_t rx_frame;
uint32_t tx_error;
uint32_t rx_error;
-} __attribute__ ((packed));
+} __packed;
/* sleep mode */
#define SLP_ACTIVE 0
#define SLP_SLEEP 1
struct hostif_sleep_request_t {
struct hostif_hdr header;
-} __attribute__ ((packed));
+} __packed;
struct hostif_sleep_confirm_t {
struct hostif_hdr header;
uint16_t result_code;
-} __attribute__ ((packed));
+} __packed;
struct hostif_mic_failure_request_t {
struct hostif_hdr header;
uint16_t failure_count;
uint16_t timer;
-} __attribute__ ((packed));
+} __packed;
struct hostif_mic_failure_confirm_t {
struct hostif_hdr header;
uint16_t result_code;
-} __attribute__ ((packed));
+} __packed;
#define BASIC_RATE 0x80
#define RATE_MASK 0x7F
@@ -616,13 +619,21 @@ enum {
#include "ks_wlan.h"
/* function prototype */
-extern int hostif_data_request(struct ks_wlan_private *priv,
- struct sk_buff *packet);
-extern void hostif_receive(struct ks_wlan_private *priv, unsigned char *p,
- unsigned int size);
-extern void hostif_sme_enqueue(struct ks_wlan_private *priv, uint16_t event);
-extern int hostif_init(struct ks_wlan_private *priv);
-extern void hostif_exit(struct ks_wlan_private *priv);
+int hostif_data_request(struct ks_wlan_private *priv,
+ struct sk_buff *packet);
+void hostif_receive(struct ks_wlan_private *priv, unsigned char *p,
+ unsigned int size);
+void hostif_sme_enqueue(struct ks_wlan_private *priv, uint16_t event);
+int hostif_init(struct ks_wlan_private *priv);
+void hostif_exit(struct ks_wlan_private *priv);
+int ks_wlan_hw_tx(struct ks_wlan_private *priv, void *p,
+ unsigned long size,
+ void (*complete_handler) (void *arg1, void *arg2),
+ void *arg1, void *arg2);
+void send_packet_complete(void *, void *);
+
+void ks_wlan_hw_wakeup_request(struct ks_wlan_private *priv);
+int ks_wlan_hw_power_save(struct ks_wlan_private *priv);
static
inline int hif_align_size(int size)
diff --git a/drivers/staging/ks7010/ks_wlan.h b/drivers/staging/ks7010/ks_wlan.h
index f05dc0122fcb..c2cc288ae899 100644
--- a/drivers/staging/ks7010/ks_wlan.h
+++ b/drivers/staging/ks7010/ks_wlan.h
@@ -219,7 +219,7 @@ struct rsn_ie_t {
uint8_t id; /* 0xdd = WPA or 0x30 = RSN */
uint8_t size; /* max ? 255 ? */
uint8_t body[RSN_IE_BODY_MAX];
-} __attribute__ ((packed));
+} __packed;
#ifdef WPS
#define WPS_IE_BODY_MAX 255
@@ -227,7 +227,7 @@ struct wps_ie_t {
uint8_t id; /* 221 'dd <len> 00 50 F2 04' */
uint8_t size; /* max ? 255 ? */
uint8_t body[WPS_IE_BODY_MAX];
-} __attribute__ ((packed));
+} __packed;
#endif /* WPS */
struct local_ap_t {
@@ -499,7 +499,7 @@ struct ks_wlan_private {
uint wakeup_count; /* for detect wakeup loop */
};
-extern int ks_wlan_net_start(struct net_device *dev);
-extern int ks_wlan_net_stop(struct net_device *dev);
+int ks_wlan_net_start(struct net_device *dev);
+int ks_wlan_net_stop(struct net_device *dev);
#endif /* _KS_WLAN_H */
diff --git a/drivers/staging/ks7010/ks_wlan_ioctl.h b/drivers/staging/ks7010/ks_wlan_ioctl.h
index 49369e497808..84554b6bb239 100644
--- a/drivers/staging/ks7010/ks_wlan_ioctl.h
+++ b/drivers/staging/ks7010/ks_wlan_ioctl.h
@@ -58,9 +58,9 @@
#include "ks_wlan.h"
#include <linux/netdevice.h>
-extern int ks_wlan_read_config_file(struct ks_wlan_private *priv);
-extern int ks_wlan_setup_parameter(struct ks_wlan_private *priv,
- unsigned int commit_flag);
+int ks_wlan_read_config_file(struct ks_wlan_private *priv);
+int ks_wlan_setup_parameter(struct ks_wlan_private *priv,
+ unsigned int commit_flag);
#endif /* __KERNEL__ */
diff --git a/drivers/staging/ks7010/ks_wlan_net.c b/drivers/staging/ks7010/ks_wlan_net.c
index 1e21eb1c4667..b2b4fa4c3834 100644
--- a/drivers/staging/ks7010/ks_wlan_net.c
+++ b/drivers/staging/ks7010/ks_wlan_net.c
@@ -9,7 +9,6 @@
* published by the Free Software Foundation.
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/compiler.h>
@@ -70,10 +69,6 @@ static const struct iw_handler_def ks_wlan_handler_def;
/*
* function prototypes
*/
-extern int ks_wlan_hw_tx(struct ks_wlan_private *priv, void *p,
- unsigned long size,
- void (*complete_handler) (void *arg1, void *arg2),
- void *arg1, void *arg2);
static int ks_wlan_open(struct net_device *dev);
static void ks_wlan_tx_timeout(struct net_device *dev);
static int ks_wlan_start_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -238,9 +233,9 @@ static int ks_wlan_set_freq(struct net_device *dev,
/* We should do a better check than that,
* based on the card capability !!! */
if ((channel < 1) || (channel > 14)) {
- printk(KERN_DEBUG
- "%s: New channel value of %d is invalid!\n",
- dev->name, fwrq->m);
+ netdev_dbg(dev,
+ "%s: New channel value of %d is invalid!\n",
+ dev->name, fwrq->m);
rc = -EINVAL;
} else {
/* Yes ! We can set it !!! */
@@ -402,7 +397,7 @@ static int ks_wlan_set_wap(struct net_device *dev, struct iw_request_info *info,
priv->need_commit |= SME_MODE_SET;
}
} else {
- memset(priv->reg.bssid, 0x0, ETH_ALEN);
+ eth_zero_addr(priv->reg.bssid);
return -EOPNOTSUPP;
}
@@ -433,7 +428,7 @@ static int ks_wlan_get_wap(struct net_device *dev, struct iw_request_info *info,
if ((priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {
memcpy(awrq->sa_data, &(priv->current_ap.bssid[0]), ETH_ALEN);
} else {
- memset(awrq->sa_data, 0, ETH_ALEN);
+ eth_zero_addr(awrq->sa_data);
}
awrq->sa_family = ARPHRD_ETHER;
@@ -2092,7 +2087,7 @@ static int ks_wlan_set_pmksa(struct net_device *dev,
list_for_each(ptr, &priv->pmklist.head) {
pmk = list_entry(ptr, struct pmk_t, list);
if (!memcmp(pmksa->bssid.sa_data, pmk->bssid, ETH_ALEN)) { /* match address! list del. */
- memset(pmk->bssid, 0, ETH_ALEN);
+ eth_zero_addr(pmk->bssid);
memset(pmk->pmkid, 0, IW_PMKID_LEN);
list_del_init(&pmk->list);
break;
@@ -2676,17 +2671,17 @@ static int ks_wlan_set_sleep_mode(struct net_device *dev,
if (*uwrq == SLP_SLEEP) {
priv->sleep_mode = *uwrq;
- printk("SET_SLEEP_MODE %d\n", priv->sleep_mode);
+ netdev_info(dev, "SET_SLEEP_MODE %d\n", priv->sleep_mode);
hostif_sme_enqueue(priv, SME_STOP_REQUEST);
hostif_sme_enqueue(priv, SME_SLEEP_REQUEST);
} else if (*uwrq == SLP_ACTIVE) {
priv->sleep_mode = *uwrq;
- printk("SET_SLEEP_MODE %d\n", priv->sleep_mode);
+ netdev_info(dev, "SET_SLEEP_MODE %d\n", priv->sleep_mode);
hostif_sme_enqueue(priv, SME_SLEEP_REQUEST);
} else {
- printk("SET_SLEEP_MODE %d errror\n", *uwrq);
+ netdev_err(dev, "SET_SLEEP_MODE %d errror\n", *uwrq);
return -EINVAL;
}
@@ -2788,7 +2783,7 @@ static int ks_wlan_get_wps_enable(struct net_device *dev,
}
/* for SLEEP MODE */
*uwrq = priv->wps.wps_enabled;
- printk("return=%d\n", *uwrq);
+ netdev_info(dev, "return=%d\n", *uwrq);
return 0;
}
@@ -2978,117 +2973,117 @@ static int ks_wlan_get_eeprom_cksum(struct net_device *dev,
return 0;
}
-static void print_hif_event(int event)
+static void print_hif_event(struct net_device *dev, int event)
{
switch (event) {
case HIF_DATA_REQ:
- printk("HIF_DATA_REQ\n");
+ netdev_info(dev, "HIF_DATA_REQ\n");
break;
case HIF_DATA_IND:
- printk("HIF_DATA_IND\n");
+ netdev_info(dev, "HIF_DATA_IND\n");
break;
case HIF_MIB_GET_REQ:
- printk("HIF_MIB_GET_REQ\n");
+ netdev_info(dev, "HIF_MIB_GET_REQ\n");
break;
case HIF_MIB_GET_CONF:
- printk("HIF_MIB_GET_CONF\n");
+ netdev_info(dev, "HIF_MIB_GET_CONF\n");
break;
case HIF_MIB_SET_REQ:
- printk("HIF_MIB_SET_REQ\n");
+ netdev_info(dev, "HIF_MIB_SET_REQ\n");
break;
case HIF_MIB_SET_CONF:
- printk("HIF_MIB_SET_CONF\n");
+ netdev_info(dev, "HIF_MIB_SET_CONF\n");
break;
case HIF_POWERMGT_REQ:
- printk("HIF_POWERMGT_REQ\n");
+ netdev_info(dev, "HIF_POWERMGT_REQ\n");
break;
case HIF_POWERMGT_CONF:
- printk("HIF_POWERMGT_CONF\n");
+ netdev_info(dev, "HIF_POWERMGT_CONF\n");
break;
case HIF_START_REQ:
- printk("HIF_START_REQ\n");
+ netdev_info(dev, "HIF_START_REQ\n");
break;
case HIF_START_CONF:
- printk("HIF_START_CONF\n");
+ netdev_info(dev, "HIF_START_CONF\n");
break;
case HIF_CONNECT_IND:
- printk("HIF_CONNECT_IND\n");
+ netdev_info(dev, "HIF_CONNECT_IND\n");
break;
case HIF_STOP_REQ:
- printk("HIF_STOP_REQ\n");
+ netdev_info(dev, "HIF_STOP_REQ\n");
break;
case HIF_STOP_CONF:
- printk("HIF_STOP_CONF\n");
+ netdev_info(dev, "HIF_STOP_CONF\n");
break;
case HIF_PS_ADH_SET_REQ:
- printk("HIF_PS_ADH_SET_REQ\n");
+ netdev_info(dev, "HIF_PS_ADH_SET_REQ\n");
break;
case HIF_PS_ADH_SET_CONF:
- printk("HIF_PS_ADH_SET_CONF\n");
+ netdev_info(dev, "HIF_PS_ADH_SET_CONF\n");
break;
case HIF_INFRA_SET_REQ:
- printk("HIF_INFRA_SET_REQ\n");
+ netdev_info(dev, "HIF_INFRA_SET_REQ\n");
break;
case HIF_INFRA_SET_CONF:
- printk("HIF_INFRA_SET_CONF\n");
+ netdev_info(dev, "HIF_INFRA_SET_CONF\n");
break;
case HIF_ADH_SET_REQ:
- printk("HIF_ADH_SET_REQ\n");
+ netdev_info(dev, "HIF_ADH_SET_REQ\n");
break;
case HIF_ADH_SET_CONF:
- printk("HIF_ADH_SET_CONF\n");
+ netdev_info(dev, "HIF_ADH_SET_CONF\n");
break;
case HIF_AP_SET_REQ:
- printk("HIF_AP_SET_REQ\n");
+ netdev_info(dev, "HIF_AP_SET_REQ\n");
break;
case HIF_AP_SET_CONF:
- printk("HIF_AP_SET_CONF\n");
+ netdev_info(dev, "HIF_AP_SET_CONF\n");
break;
case HIF_ASSOC_INFO_IND:
- printk("HIF_ASSOC_INFO_IND\n");
+ netdev_info(dev, "HIF_ASSOC_INFO_IND\n");
break;
case HIF_MIC_FAILURE_REQ:
- printk("HIF_MIC_FAILURE_REQ\n");
+ netdev_info(dev, "HIF_MIC_FAILURE_REQ\n");
break;
case HIF_MIC_FAILURE_CONF:
- printk("HIF_MIC_FAILURE_CONF\n");
+ netdev_info(dev, "HIF_MIC_FAILURE_CONF\n");
break;
case HIF_SCAN_REQ:
- printk("HIF_SCAN_REQ\n");
+ netdev_info(dev, "HIF_SCAN_REQ\n");
break;
case HIF_SCAN_CONF:
- printk("HIF_SCAN_CONF\n");
+ netdev_info(dev, "HIF_SCAN_CONF\n");
break;
case HIF_PHY_INFO_REQ:
- printk("HIF_PHY_INFO_REQ\n");
+ netdev_info(dev, "HIF_PHY_INFO_REQ\n");
break;
case HIF_PHY_INFO_CONF:
- printk("HIF_PHY_INFO_CONF\n");
+ netdev_info(dev, "HIF_PHY_INFO_CONF\n");
break;
case HIF_SLEEP_REQ:
- printk("HIF_SLEEP_REQ\n");
+ netdev_info(dev, "HIF_SLEEP_REQ\n");
break;
case HIF_SLEEP_CONF:
- printk("HIF_SLEEP_CONF\n");
+ netdev_info(dev, "HIF_SLEEP_CONF\n");
break;
case HIF_PHY_INFO_IND:
- printk("HIF_PHY_INFO_IND\n");
+ netdev_info(dev, "HIF_PHY_INFO_IND\n");
break;
case HIF_SCAN_IND:
- printk("HIF_SCAN_IND\n");
+ netdev_info(dev, "HIF_SCAN_IND\n");
break;
case HIF_INFRA_SET2_REQ:
- printk("HIF_INFRA_SET2_REQ\n");
+ netdev_info(dev, "HIF_INFRA_SET2_REQ\n");
break;
case HIF_INFRA_SET2_CONF:
- printk("HIF_INFRA_SET2_CONF\n");
+ netdev_info(dev, "HIF_INFRA_SET2_CONF\n");
break;
case HIF_ADH_SET2_REQ:
- printk("HIF_ADH_SET2_REQ\n");
+ netdev_info(dev, "HIF_ADH_SET2_REQ\n");
break;
case HIF_ADH_SET2_CONF:
- printk("HIF_ADH_SET2_CONF\n");
+ netdev_info(dev, "HIF_ADH_SET2_CONF\n");
}
}
@@ -3105,7 +3100,7 @@ static int ks_wlan_hostt(struct net_device *dev, struct iw_request_info *info,
event =
priv->hostt.buff[(priv->hostt.qtail - 1 - i) %
SME_EVENT_BUFF_SIZE];
- print_hif_event(event);
+ print_hif_event(dev, event);
}
return 0;
}
@@ -3335,7 +3330,7 @@ int ks_wlan_set_mac_address(struct net_device *dev, void *addr)
priv->mac_address_valid = 0;
hostif_sme_enqueue(priv, SME_MACADDRESS_SET_REQUEST);
- printk(KERN_INFO
+ netdev_info(dev,
"ks_wlan: MAC ADDRESS = %02x:%02x:%02x:%02x:%02x:%02x\n",
priv->eth_addr[0], priv->eth_addr[1], priv->eth_addr[2],
priv->eth_addr[3], priv->eth_addr[4], priv->eth_addr[5]);
@@ -3354,8 +3349,6 @@ void ks_wlan_tx_timeout(struct net_device *dev)
}
priv->nstats.tx_errors++;
netif_wake_queue(dev);
-
- return;
}
static
@@ -3366,8 +3359,8 @@ int ks_wlan_start_xmit(struct sk_buff *skb, struct net_device *dev)
DPRINTK(3, "in_interrupt()=%ld\n", in_interrupt());
- if (skb == NULL) {
- printk(KERN_ERR "ks_wlan: skb == NULL!!!\n");
+ if (!skb) {
+ netdev_err(dev, "ks_wlan: skb == NULL!!!\n");
return 0;
}
if (priv->dev_state < DEVICE_STATE_READY) {
@@ -3396,13 +3389,13 @@ void send_packet_complete(void *arg1, void *arg2)
DPRINTK(3, "\n");
- priv->nstats.tx_bytes += packet->len;
priv->nstats.tx_packets++;
if (netif_queue_stopped(priv->net_dev))
netif_wake_queue(priv->net_dev);
if (packet) {
+ priv->nstats.tx_bytes += packet->len;
dev_kfree_skb(packet);
packet = NULL;
}
@@ -3421,8 +3414,6 @@ void ks_wlan_set_multicast_list(struct net_device *dev)
return; /* not finished initialize */
}
hostif_sme_enqueue(priv, SME_MULTICAST_REQUEST);
-
- return;
}
static
@@ -3433,7 +3424,7 @@ int ks_wlan_open(struct net_device *dev)
priv->cur_rx = 0;
if (!priv->mac_address_valid) {
- printk(KERN_ERR "ks_wlan : %s Not READY !!\n", dev->name);
+ netdev_err(dev, "ks_wlan : %s Not READY !!\n", dev->name);
return -EBUSY;
} else
netif_start_queue(dev);
@@ -3512,17 +3503,11 @@ int ks_wlan_net_stop(struct net_device *dev)
{
struct ks_wlan_private *priv = netdev_priv(dev);
- int ret = 0;
priv->device_open_status = 0;
del_timer_sync(&update_phyinfo_timer);
if (netif_running(dev))
netif_stop_queue(dev);
- return ret;
-}
-
-int ks_wlan_reset(struct net_device *dev)
-{
return 0;
}
diff --git a/drivers/staging/ks7010/michael_mic.c b/drivers/staging/ks7010/michael_mic.c
index e14c109b3cab..78ae2b8fb7f3 100644
--- a/drivers/staging/ks7010/michael_mic.c
+++ b/drivers/staging/ks7010/michael_mic.c
@@ -20,18 +20,24 @@
#define getUInt32( A, B ) (uint32_t)(A[B+0] << 0) + (A[B+1] << 8) + (A[B+2] << 16) + (A[B+3] << 24)
// Convert from UInt32 to Byte[] in a portable way
-#define putUInt32( A, B, C ) A[B+0] = (uint8_t) (C & 0xff); \
- A[B+1] = (uint8_t) ((C>>8) & 0xff); \
- A[B+2] = (uint8_t) ((C>>16) & 0xff); \
- A[B+3] = (uint8_t) ((C>>24) & 0xff)
+#define putUInt32(A, B, C) \
+do { \
+ A[B + 0] = (uint8_t)(C & 0xff); \
+ A[B + 1] = (uint8_t)((C >> 8) & 0xff); \
+ A[B + 2] = (uint8_t)((C >> 16) & 0xff); \
+ A[B + 3] = (uint8_t)((C >> 24) & 0xff); \
+} while (0)
// Reset the state to the empty message.
-#define MichaelClear( A ) A->L = A->K0; \
- A->R = A->K1; \
- A->nBytesInM = 0;
+#define MichaelClear(A) \
+do { \
+ A->L = A->K0; \
+ A->R = A->K1; \
+ A->nBytesInM = 0; \
+} while (0)
static
-void MichaelInitializeFunction(struct michel_mic_t *Mic, uint8_t * key)
+void MichaelInitializeFunction(struct michel_mic_t *Mic, uint8_t *key)
{
// Set the key
Mic->K0 = getUInt32(key, 0);
@@ -54,7 +60,7 @@ do{ \
}while(0)
static
-void MichaelAppend(struct michel_mic_t *Mic, uint8_t * src, int nBytes)
+void MichaelAppend(struct michel_mic_t *Mic, uint8_t *src, int nBytes)
{
int addlen;
if (Mic->nBytesInM) {
@@ -88,7 +94,7 @@ void MichaelAppend(struct michel_mic_t *Mic, uint8_t * src, int nBytes)
}
static
-void MichaelGetMIC(struct michel_mic_t *Mic, uint8_t * dst)
+void MichaelGetMIC(struct michel_mic_t *Mic, uint8_t *dst)
{
uint8_t *data = Mic->M;
switch (Mic->nBytesInM) {
@@ -116,9 +122,9 @@ void MichaelGetMIC(struct michel_mic_t *Mic, uint8_t * dst)
MichaelClear(Mic);
}
-void MichaelMICFunction(struct michel_mic_t *Mic, uint8_t * Key,
- uint8_t * Data, int Len, uint8_t priority,
- uint8_t * Result)
+void MichaelMICFunction(struct michel_mic_t *Mic, uint8_t *Key,
+ uint8_t *Data, int Len, uint8_t priority,
+ uint8_t *Result)
{
uint8_t pad_data[4] = { priority, 0, 0, 0 };
// Compute the MIC value
diff --git a/drivers/staging/ks7010/michael_mic.h b/drivers/staging/ks7010/michael_mic.h
index c7e4eb280961..efaa21788fc7 100644
--- a/drivers/staging/ks7010/michael_mic.h
+++ b/drivers/staging/ks7010/michael_mic.h
@@ -20,7 +20,6 @@ struct michel_mic_t {
uint8_t Result[8];
};
-extern
-void MichaelMICFunction(struct michel_mic_t *Mic, uint8_t * Key,
- uint8_t * Data, int Len, uint8_t priority,
- uint8_t * Result);
+void MichaelMICFunction(struct michel_mic_t *Mic, uint8_t *Key,
+ uint8_t *Data, int Len, uint8_t priority,
+ uint8_t *Result);
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h
index 3f6447c65042..3b92d38d37e2 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h
@@ -138,8 +138,8 @@ struct lnet_debugfs_symlink_def {
void lustre_insert_debugfs(struct ctl_table *table,
const struct lnet_debugfs_symlink_def *symlinks);
int lprocfs_call_handler(void *data, int write, loff_t *ppos,
- void __user *buffer, size_t *lenp,
- int (*handler)(void *data, int write,
- loff_t pos, void __user *buffer, int len));
+ void __user *buffer, size_t *lenp,
+ int (*handler)(void *data, int write, loff_t pos,
+ void __user *buffer, int len));
#endif /* _LIBCFS_H */
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
index 25adab19fd86..b7bd6e8ab33f 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
@@ -247,19 +247,19 @@ do { \
#define LCONSOLE_EMERG(format, ...) CDEBUG(D_CONSOLE | D_EMERG, format, ## __VA_ARGS__)
int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata,
- const char *format1, ...)
+ const char *format1, ...)
__printf(2, 3);
int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
- const char *format1,
- va_list args, const char *format2, ...)
+ const char *format1,
+ va_list args, const char *format2, ...)
__printf(4, 5);
/* other external symbols that tracefile provides: */
int cfs_trace_copyin_string(char *knl_buffer, int knl_buffer_nob,
- const char __user *usr_buffer, int usr_buffer_nob);
+ const char __user *usr_buffer, int usr_buffer_nob);
int cfs_trace_copyout_string(char __user *usr_buffer, int usr_buffer_nob,
- const char *knl_buffer, char *append);
+ const char *knl_buffer, char *append);
#define LIBCFS_DEBUG_FILE_PATH_DEFAULT "/tmp/lustre-log"
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h
index d3f9a6020ee3..bdbbe934584c 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h
@@ -143,6 +143,9 @@ static inline int cfs_fail_timeout_set(__u32 id, __u32 value, int ms, int set)
#define CFS_FAIL_TIMEOUT_ORSET(id, value, secs) \
cfs_fail_timeout_set(id, value, secs * 1000, CFS_FAIL_LOC_ORSET)
+#define CFS_FAIL_TIMEOUT_RESET(id, value, secs) \
+ cfs_fail_timeout_set(id, value, secs * 1000, CFS_FAIL_LOC_RESET)
+
#define CFS_FAIL_TIMEOUT_MS_ORSET(id, value, ms) \
cfs_fail_timeout_set(id, value, ms, CFS_FAIL_LOC_ORSET)
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
index 4daa3823f60a..e0e1a5d0949d 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
@@ -310,13 +310,13 @@ do { \
#define MKSTR(ptr) ((ptr)) ? (ptr) : ""
-static inline int cfs_size_round4(int val)
+static inline size_t cfs_size_round4(int val)
{
return (val + 3) & (~0x3);
}
#ifndef HAVE_CFS_SIZE_ROUND
-static inline int cfs_size_round(int val)
+static inline size_t cfs_size_round(int val)
{
return (val + 7) & (~0x7);
}
@@ -324,17 +324,17 @@ static inline int cfs_size_round(int val)
#define HAVE_CFS_SIZE_ROUND
#endif
-static inline int cfs_size_round16(int val)
+static inline size_t cfs_size_round16(int val)
{
return (val + 0xf) & (~0xf);
}
-static inline int cfs_size_round32(int val)
+static inline size_t cfs_size_round32(int val)
{
return (val + 0x1f) & (~0x1f);
}
-static inline int cfs_size_round0(int val)
+static inline size_t cfs_size_round0(int val)
{
if (!val)
return 0;
@@ -343,7 +343,7 @@ static inline int cfs_size_round0(int val)
static inline size_t cfs_round_strlen(char *fset)
{
- return (size_t)cfs_size_round((int)strlen(fset) + 1);
+ return cfs_size_round((int)strlen(fset) + 1);
}
#define LOGL(var, len, ptr) \
@@ -360,13 +360,4 @@ do { \
ptr += cfs_size_round(len); \
} while (0)
-#define LOGL0(var, len, ptr) \
-do { \
- if (!len) \
- break; \
- memcpy((char *)ptr, (const char *)var, len); \
- *((char *)(ptr) + len) = 0; \
- ptr += cfs_size_round(len + 1); \
-} while (0)
-
#endif
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
index 513a8225f888..a59c5e99cbd3 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
@@ -605,73 +605,20 @@ void lnet_counters_reset(void);
unsigned int lnet_iov_nob(unsigned int niov, struct kvec *iov);
int lnet_extract_iov(int dst_niov, struct kvec *dst,
- int src_niov, struct kvec *src,
+ int src_niov, const struct kvec *src,
unsigned int offset, unsigned int len);
unsigned int lnet_kiov_nob(unsigned int niov, lnet_kiov_t *iov);
int lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst,
- int src_niov, lnet_kiov_t *src,
+ int src_niov, const lnet_kiov_t *src,
unsigned int offset, unsigned int len);
-void lnet_copy_iov2iov(unsigned int ndiov, struct kvec *diov,
- unsigned int doffset,
- unsigned int nsiov, struct kvec *siov,
+void lnet_copy_iov2iter(struct iov_iter *to,
+ unsigned int nsiov, const struct kvec *siov,
unsigned int soffset, unsigned int nob);
-void lnet_copy_kiov2iov(unsigned int niov, struct kvec *iov,
- unsigned int iovoffset,
- unsigned int nkiov, lnet_kiov_t *kiov,
+void lnet_copy_kiov2iter(struct iov_iter *to,
+ unsigned int nkiov, const lnet_kiov_t *kiov,
unsigned int kiovoffset, unsigned int nob);
-void lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov,
- unsigned int kiovoffset,
- unsigned int niov, struct kvec *iov,
- unsigned int iovoffset, unsigned int nob);
-void lnet_copy_kiov2kiov(unsigned int ndkiov, lnet_kiov_t *dkiov,
- unsigned int doffset,
- unsigned int nskiov, lnet_kiov_t *skiov,
- unsigned int soffset, unsigned int nob);
-
-static inline void
-lnet_copy_iov2flat(int dlen, void *dest, unsigned int doffset,
- unsigned int nsiov, struct kvec *siov, unsigned int soffset,
- unsigned int nob)
-{
- struct kvec diov = {/*.iov_base = */ dest, /*.iov_len = */ dlen};
-
- lnet_copy_iov2iov(1, &diov, doffset,
- nsiov, siov, soffset, nob);
-}
-
-static inline void
-lnet_copy_kiov2flat(int dlen, void *dest, unsigned int doffset,
- unsigned int nsiov, lnet_kiov_t *skiov,
- unsigned int soffset, unsigned int nob)
-{
- struct kvec diov = {/* .iov_base = */ dest, /* .iov_len = */ dlen};
-
- lnet_copy_kiov2iov(1, &diov, doffset,
- nsiov, skiov, soffset, nob);
-}
-
-static inline void
-lnet_copy_flat2iov(unsigned int ndiov, struct kvec *diov, unsigned int doffset,
- int slen, void *src, unsigned int soffset, unsigned int nob)
-{
- struct kvec siov = {/*.iov_base = */ src, /*.iov_len = */slen};
-
- lnet_copy_iov2iov(ndiov, diov, doffset,
- 1, &siov, soffset, nob);
-}
-
-static inline void
-lnet_copy_flat2kiov(unsigned int ndiov, lnet_kiov_t *dkiov,
- unsigned int doffset, int slen, void *src,
- unsigned int soffset, unsigned int nob)
-{
- struct kvec siov = {/* .iov_base = */ src, /* .iov_len = */ slen};
-
- lnet_copy_iov2kiov(ndiov, dkiov, doffset,
- 1, &siov, soffset, nob);
-}
void lnet_me_unlink(lnet_me_t *me);
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h
index 7967b013cbae..b84a5bb9186c 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-types.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h
@@ -220,10 +220,7 @@ typedef struct lnet_lnd {
* credit if the LND does flow control.
*/
int (*lnd_recv)(struct lnet_ni *ni, void *private, lnet_msg_t *msg,
- int delayed, unsigned int niov,
- struct kvec *iov, lnet_kiov_t *kiov,
- unsigned int offset, unsigned int mlen,
- unsigned int rlen);
+ int delayed, struct iov_iter *to, unsigned int rlen);
/*
* lnet_parse() has had to delay processing of this message
@@ -278,6 +275,8 @@ typedef struct lnet_ni {
struct lnet_ioctl_config_lnd_tunables *ni_lnd_tunables;
/* equivalent interfaces to use */
char *ni_interfaces[LNET_MAX_INTERFACES];
+ /* original net namespace */
+ struct net *ni_net_ns;
} lnet_ni_t;
#define LNET_PROTO_PING_MATCHBITS 0x8000000000000000LL
diff --git a/drivers/staging/lustre/include/linux/lnet/types.h b/drivers/staging/lustre/include/linux/lnet/types.h
index e098b6c086e1..f8be0e2f7bf7 100644
--- a/drivers/staging/lustre/include/linux/lnet/types.h
+++ b/drivers/staging/lustre/include/linux/lnet/types.h
@@ -503,21 +503,7 @@ typedef struct {
/* NB lustre portals uses struct iovec internally! */
typedef struct iovec lnet_md_iovec_t;
-/**
- * A page-based fragment of a MD.
- */
-typedef struct {
- /** Pointer to the page where the fragment resides */
- struct page *kiov_page;
- /** Length in bytes of the fragment */
- unsigned int kiov_len;
- /**
- * Starting offset of the fragment within the page. Note that the
- * end of the fragment must not pass the end of the page; i.e.,
- * kiov_len + kiov_offset <= PAGE_SIZE.
- */
- unsigned int kiov_offset;
-} lnet_kiov_t;
+typedef struct bio_vec lnet_kiov_t;
/** @} lnet_md */
/** \addtogroup lnet_eq
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
index 4f5978b3767b..c7a5d49e487f 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
@@ -128,6 +128,7 @@ static int kiblnd_msgtype2size(int type)
static int kiblnd_unpack_rd(struct kib_msg *msg, int flip)
{
struct kib_rdma_desc *rd;
+ int msg_size;
int nob;
int n;
int i;
@@ -146,12 +147,6 @@ static int kiblnd_unpack_rd(struct kib_msg *msg, int flip)
n = rd->rd_nfrags;
- if (n <= 0 || n > IBLND_MAX_RDMA_FRAGS) {
- CERROR("Bad nfrags: %d, should be 0 < n <= %d\n",
- n, IBLND_MAX_RDMA_FRAGS);
- return 1;
- }
-
nob = offsetof(struct kib_msg, ibm_u) +
kiblnd_rd_msg_size(rd, msg->ibm_type, n);
@@ -161,6 +156,13 @@ static int kiblnd_unpack_rd(struct kib_msg *msg, int flip)
return 1;
}
+ msg_size = kiblnd_rd_size(rd);
+ if (msg_size <= 0 || msg_size > LNET_MAX_PAYLOAD) {
+ CERROR("Bad msg_size: %d, should be 0 < n <= %d\n",
+ msg_size, LNET_MAX_PAYLOAD);
+ return 1;
+ }
+
if (!flip)
return 0;
@@ -618,7 +620,7 @@ static int kiblnd_get_completion_vector(struct kib_conn *conn, int cpt)
}
struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cmid,
- int state, int version)
+ int state, int version)
{
/*
* CAVEAT EMPTOR:
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
index 078a0c3e8845..14576977200f 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
@@ -113,8 +113,9 @@ extern struct kib_tunables kiblnd_tunables;
#define IBLND_OOB_CAPABLE(v) ((v) != IBLND_MSG_VERSION_1)
#define IBLND_OOB_MSGS(v) (IBLND_OOB_CAPABLE(v) ? 2 : 0)
-#define IBLND_MSG_SIZE (4 << 10) /* max size of queued messages (inc hdr) */
-#define IBLND_MAX_RDMA_FRAGS LNET_MAX_IOV /* max # of fragments supported */
+#define IBLND_FRAG_SHIFT (PAGE_SHIFT - 12) /* frag size on wire is in 4K units */
+#define IBLND_MSG_SIZE (4 << 10) /* max size of queued messages (inc hdr) */
+#define IBLND_MAX_RDMA_FRAGS (LNET_MAX_PAYLOAD >> 12)/* max # of fragments supported in 4K size */
/************************/
/* derived constants... */
@@ -133,8 +134,8 @@ extern struct kib_tunables kiblnd_tunables;
/* WRs and CQEs (per connection) */
#define IBLND_RECV_WRS(c) IBLND_RX_MSGS(c)
#define IBLND_SEND_WRS(c) \
- ((c->ibc_max_frags + 1) * kiblnd_concurrent_sends(c->ibc_version, \
- c->ibc_peer->ibp_ni))
+ (((c->ibc_max_frags + 1) << IBLND_FRAG_SHIFT) * \
+ kiblnd_concurrent_sends(c->ibc_version, c->ibc_peer->ibp_ni))
#define IBLND_CQ_ENTRIES(c) (IBLND_RECV_WRS(c) + IBLND_SEND_WRS(c))
struct kib_hca_dev;
@@ -582,6 +583,8 @@ struct kib_peer {
unsigned short ibp_connecting;
/* reconnect this peer later */
unsigned short ibp_reconnecting:1;
+ /* counter of how many times we triggered a conn race */
+ unsigned char ibp_races;
/* # consecutive reconnection attempts to this peer */
unsigned int ibp_reconnected;
/* errno on closing this peer */
@@ -607,14 +610,14 @@ kiblnd_cfg_rdma_frags(struct lnet_ni *ni)
tunables = &ni->ni_lnd_tunables->lt_tun_u.lt_o2ib;
mod = tunables->lnd_map_on_demand;
- return mod ? mod : IBLND_MAX_RDMA_FRAGS;
+ return mod ? mod : IBLND_MAX_RDMA_FRAGS >> IBLND_FRAG_SHIFT;
}
static inline int
kiblnd_rdma_frags(int version, struct lnet_ni *ni)
{
return version == IBLND_MSG_VERSION_1 ?
- IBLND_MAX_RDMA_FRAGS :
+ (IBLND_MAX_RDMA_FRAGS >> IBLND_FRAG_SHIFT) :
kiblnd_cfg_rdma_frags(ni);
}
@@ -1034,5 +1037,4 @@ int kiblnd_post_rx(struct kib_rx *rx, int credit);
int kiblnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg);
int kiblnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed,
- unsigned int niov, struct kvec *iov, lnet_kiov_t *kiov,
- unsigned int offset, unsigned int mlen, unsigned int rlen);
+ struct iov_iter *to, unsigned int rlen);
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
index 596a697b9d39..b27de8888149 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
@@ -36,16 +36,19 @@
#include "o2iblnd.h"
+#define MAX_CONN_RACES_BEFORE_ABORT 20
+
static void kiblnd_peer_alive(struct kib_peer *peer);
static void kiblnd_peer_connect_failed(struct kib_peer *peer, int active, int error);
-static void kiblnd_check_sends(struct kib_conn *conn);
static void kiblnd_init_tx_msg(lnet_ni_t *ni, struct kib_tx *tx,
- int type, int body_nob);
+ int type, int body_nob);
static int kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type,
- int resid, struct kib_rdma_desc *dstrd, __u64 dstcookie);
+ int resid, struct kib_rdma_desc *dstrd,
+ __u64 dstcookie);
static void kiblnd_queue_tx_locked(struct kib_tx *tx, struct kib_conn *conn);
static void kiblnd_queue_tx(struct kib_tx *tx, struct kib_conn *conn);
static void kiblnd_unmap_tx(lnet_ni_t *ni, struct kib_tx *tx);
+static void kiblnd_check_sends_locked(struct kib_conn *conn);
static void
kiblnd_tx_done(lnet_ni_t *ni, struct kib_tx *tx)
@@ -211,9 +214,9 @@ kiblnd_post_rx(struct kib_rx *rx, int credit)
conn->ibc_outstanding_credits++;
else
conn->ibc_reserved_credits++;
+ kiblnd_check_sends_locked(conn);
spin_unlock(&conn->ibc_lock);
- kiblnd_check_sends(conn);
out:
kiblnd_conn_decref(conn);
return rc;
@@ -344,8 +347,8 @@ kiblnd_handle_rx(struct kib_rx *rx)
!IBLND_OOB_CAPABLE(conn->ibc_version)) /* v1 only */
conn->ibc_outstanding_credits++;
+ kiblnd_check_sends_locked(conn);
spin_unlock(&conn->ibc_lock);
- kiblnd_check_sends(conn);
}
switch (msg->ibm_type) {
@@ -648,7 +651,7 @@ static int kiblnd_map_tx(lnet_ni_t *ni, struct kib_tx *tx, struct kib_rdma_desc
static int
kiblnd_setup_rd_iov(lnet_ni_t *ni, struct kib_tx *tx, struct kib_rdma_desc *rd,
- unsigned int niov, struct kvec *iov, int offset, int nob)
+ unsigned int niov, const struct kvec *iov, int offset, int nob)
{
struct kib_net *net = ni->ni_data;
struct page *page;
@@ -705,7 +708,7 @@ kiblnd_setup_rd_iov(lnet_ni_t *ni, struct kib_tx *tx, struct kib_rdma_desc *rd,
static int
kiblnd_setup_rd_kiov(lnet_ni_t *ni, struct kib_tx *tx, struct kib_rdma_desc *rd,
- int nkiov, lnet_kiov_t *kiov, int offset, int nob)
+ int nkiov, const lnet_kiov_t *kiov, int offset, int nob)
{
struct kib_net *net = ni->ni_data;
struct scatterlist *sg;
@@ -717,8 +720,8 @@ kiblnd_setup_rd_kiov(lnet_ni_t *ni, struct kib_tx *tx, struct kib_rdma_desc *rd,
LASSERT(nkiov > 0);
LASSERT(net);
- while (offset >= kiov->kiov_len) {
- offset -= kiov->kiov_len;
+ while (offset >= kiov->bv_len) {
+ offset -= kiov->bv_len;
nkiov--;
kiov++;
LASSERT(nkiov > 0);
@@ -728,10 +731,10 @@ kiblnd_setup_rd_kiov(lnet_ni_t *ni, struct kib_tx *tx, struct kib_rdma_desc *rd,
do {
LASSERT(nkiov > 0);
- fragnob = min((int)(kiov->kiov_len - offset), nob);
+ fragnob = min((int)(kiov->bv_len - offset), nob);
- sg_set_page(sg, kiov->kiov_page, fragnob,
- kiov->kiov_offset + offset);
+ sg_set_page(sg, kiov->bv_page, fragnob,
+ kiov->bv_offset + offset);
sg = sg_next(sg);
if (!sg) {
CERROR("lacking enough sg entries to map tx\n");
@@ -761,7 +764,6 @@ kiblnd_post_tx_locked(struct kib_conn *conn, struct kib_tx *tx, int credit)
LASSERT(tx->tx_queued);
/* We rely on this for QP sizing */
LASSERT(tx->tx_nwrq > 0);
- LASSERT(tx->tx_nwrq <= 1 + conn->ibc_max_frags);
LASSERT(!credit || credit == 1);
LASSERT(conn->ibc_outstanding_credits >= 0);
@@ -800,7 +802,7 @@ kiblnd_post_tx_locked(struct kib_conn *conn, struct kib_tx *tx, int credit)
conn->ibc_noops_posted == IBLND_OOB_MSGS(ver)))) {
/*
* OK to drop when posted enough NOOPs, since
- * kiblnd_check_sends will queue NOOP again when
+ * kiblnd_check_sends_locked will queue NOOP again when
* posted NOOPs complete
*/
spin_unlock(&conn->ibc_lock);
@@ -905,7 +907,7 @@ kiblnd_post_tx_locked(struct kib_conn *conn, struct kib_tx *tx, int credit)
}
static void
-kiblnd_check_sends(struct kib_conn *conn)
+kiblnd_check_sends_locked(struct kib_conn *conn)
{
int ver = conn->ibc_version;
lnet_ni_t *ni = conn->ibc_peer->ibp_ni;
@@ -918,8 +920,6 @@ kiblnd_check_sends(struct kib_conn *conn)
return;
}
- spin_lock(&conn->ibc_lock);
-
LASSERT(conn->ibc_nsends_posted <= kiblnd_concurrent_sends(ver, ni));
LASSERT(!IBLND_OOB_CAPABLE(ver) ||
conn->ibc_noops_posted <= IBLND_OOB_MSGS(ver));
@@ -969,8 +969,6 @@ kiblnd_check_sends(struct kib_conn *conn)
if (kiblnd_post_tx_locked(conn, tx, credit))
break;
}
-
- spin_unlock(&conn->ibc_lock);
}
static void
@@ -1016,16 +1014,11 @@ kiblnd_tx_complete(struct kib_tx *tx, int status)
if (idle)
list_del(&tx->tx_list);
- kiblnd_conn_addref(conn); /* 1 ref for me.... */
-
+ kiblnd_check_sends_locked(conn);
spin_unlock(&conn->ibc_lock);
if (idle)
kiblnd_tx_done(conn->ibc_peer->ibp_ni, tx);
-
- kiblnd_check_sends(conn);
-
- kiblnd_conn_decref(conn); /* ...until here */
}
static void
@@ -1078,6 +1071,15 @@ kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type,
LASSERT(type == IBLND_MSG_GET_DONE ||
type == IBLND_MSG_PUT_DONE);
+ if (kiblnd_rd_size(srcrd) > conn->ibc_max_frags << PAGE_SHIFT) {
+ CERROR("RDMA is too large for peer %s (%d), src size: %d dst size: %d\n",
+ libcfs_nid2str(conn->ibc_peer->ibp_nid),
+ conn->ibc_max_frags << PAGE_SHIFT,
+ kiblnd_rd_size(srcrd), kiblnd_rd_size(dstrd));
+ rc = -EMSGSIZE;
+ goto too_big;
+ }
+
while (resid > 0) {
if (srcidx >= srcrd->rd_nfrags) {
CERROR("Src buffer exhausted: %d frags\n", srcidx);
@@ -1091,10 +1093,10 @@ kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type,
break;
}
- if (tx->tx_nwrq >= conn->ibc_max_frags) {
+ if (tx->tx_nwrq >= IBLND_MAX_RDMA_FRAGS) {
CERROR("RDMA has too many fragments for peer %s (%d), src idx/frags: %d/%d dst idx/frags: %d/%d\n",
libcfs_nid2str(conn->ibc_peer->ibp_nid),
- conn->ibc_max_frags,
+ IBLND_MAX_RDMA_FRAGS,
srcidx, srcrd->rd_nfrags,
dstidx, dstrd->rd_nfrags);
rc = -EMSGSIZE;
@@ -1132,7 +1134,7 @@ kiblnd_init_rdma(struct kib_conn *conn, struct kib_tx *tx, int type,
wrq++;
sge++;
}
-
+too_big:
if (rc < 0) /* no RDMA if completing with failure */
tx->tx_nwrq = 0;
@@ -1204,9 +1206,8 @@ kiblnd_queue_tx(struct kib_tx *tx, struct kib_conn *conn)
{
spin_lock(&conn->ibc_lock);
kiblnd_queue_tx_locked(tx, conn);
+ kiblnd_check_sends_locked(conn);
spin_unlock(&conn->ibc_lock);
-
- kiblnd_check_sends(conn);
}
static int kiblnd_resolve_addr(struct rdma_cm_id *cmid,
@@ -1499,6 +1500,7 @@ kiblnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
lnet_kiov_t *payload_kiov = lntmsg->msg_kiov;
unsigned int payload_offset = lntmsg->msg_offset;
unsigned int payload_nob = lntmsg->msg_len;
+ struct iov_iter from;
struct kib_msg *ibmsg;
struct kib_rdma_desc *rd;
struct kib_tx *tx;
@@ -1518,6 +1520,17 @@ kiblnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
/* payload is either all vaddrs or all pages */
LASSERT(!(payload_kiov && payload_iov));
+ if (payload_kiov)
+ iov_iter_bvec(&from, ITER_BVEC | WRITE,
+ payload_kiov, payload_niov,
+ payload_nob + payload_offset);
+ else
+ iov_iter_kvec(&from, ITER_KVEC | WRITE,
+ payload_iov, payload_niov,
+ payload_nob + payload_offset);
+
+ iov_iter_advance(&from, payload_offset);
+
switch (type) {
default:
LBUG();
@@ -1637,17 +1650,8 @@ kiblnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
ibmsg = tx->tx_msg;
ibmsg->ibm_u.immediate.ibim_hdr = *hdr;
- if (payload_kiov)
- lnet_copy_kiov2flat(IBLND_MSG_SIZE, ibmsg,
- offsetof(struct kib_msg, ibm_u.immediate.ibim_payload),
- payload_niov, payload_kiov,
- payload_offset, payload_nob);
- else
- lnet_copy_iov2flat(IBLND_MSG_SIZE, ibmsg,
- offsetof(struct kib_msg, ibm_u.immediate.ibim_payload),
- payload_niov, payload_iov,
- payload_offset, payload_nob);
-
+ copy_from_iter(&ibmsg->ibm_u.immediate.ibim_payload, IBLND_MSG_SIZE,
+ &from);
nob = offsetof(struct kib_immediate_msg, ibim_payload[payload_nob]);
kiblnd_init_tx_msg(ni, tx, IBLND_MSG_IMMEDIATE, nob);
@@ -1719,8 +1723,7 @@ kiblnd_reply(lnet_ni_t *ni, struct kib_rx *rx, lnet_msg_t *lntmsg)
int
kiblnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed,
- unsigned int niov, struct kvec *iov, lnet_kiov_t *kiov,
- unsigned int offset, unsigned int mlen, unsigned int rlen)
+ struct iov_iter *to, unsigned int rlen)
{
struct kib_rx *rx = private;
struct kib_msg *rxmsg = rx->rx_msg;
@@ -1730,10 +1733,9 @@ kiblnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed,
int post_credit = IBLND_POSTRX_PEER_CREDIT;
int rc = 0;
- LASSERT(mlen <= rlen);
+ LASSERT(iov_iter_count(to) <= rlen);
LASSERT(!in_interrupt());
/* Either all pages or all vaddrs */
- LASSERT(!(kiov && iov));
switch (rxmsg->ibm_type) {
default:
@@ -1749,16 +1751,8 @@ kiblnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed,
break;
}
- if (kiov)
- lnet_copy_flat2kiov(niov, kiov, offset,
- IBLND_MSG_SIZE, rxmsg,
- offsetof(struct kib_msg, ibm_u.immediate.ibim_payload),
- mlen);
- else
- lnet_copy_flat2iov(niov, iov, offset,
- IBLND_MSG_SIZE, rxmsg,
- offsetof(struct kib_msg, ibm_u.immediate.ibim_payload),
- mlen);
+ copy_to_iter(&rxmsg->ibm_u.immediate.ibim_payload,
+ IBLND_MSG_SIZE, to);
lnet_finalize(ni, lntmsg, 0);
break;
@@ -1766,7 +1760,7 @@ kiblnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed,
struct kib_msg *txmsg;
struct kib_rdma_desc *rd;
- if (!mlen) {
+ if (!iov_iter_count(to)) {
lnet_finalize(ni, lntmsg, 0);
kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, 0,
rxmsg->ibm_u.putreq.ibprm_cookie);
@@ -1784,12 +1778,16 @@ kiblnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed,
txmsg = tx->tx_msg;
rd = &txmsg->ibm_u.putack.ibpam_rd;
- if (!kiov)
+ if (!(to->type & ITER_BVEC))
rc = kiblnd_setup_rd_iov(ni, tx, rd,
- niov, iov, offset, mlen);
+ to->nr_segs, to->kvec,
+ to->iov_offset,
+ iov_iter_count(to));
else
rc = kiblnd_setup_rd_kiov(ni, tx, rd,
- niov, kiov, offset, mlen);
+ to->nr_segs, to->bvec,
+ to->iov_offset,
+ iov_iter_count(to));
if (rc) {
CERROR("Can't setup PUT sink for %s: %d\n",
libcfs_nid2str(conn->ibc_peer->ibp_nid), rc);
@@ -2183,14 +2181,11 @@ kiblnd_connreq_done(struct kib_conn *conn, int status)
return;
}
- /**
- * refcount taken by cmid is not reliable after I released the glock
- * because this connection is visible to other threads now, another
- * thread can find and close this connection right after I released
- * the glock, if kiblnd_cm_callback for RDMA_CM_EVENT_DISCONNECTED is
- * called, it can release the connection refcount taken by cmid.
- * It means the connection could be destroyed before I finish my
- * operations on it.
+ /*
+ * +1 ref for myself, this connection is visible to other threads
+ * now, refcount of peer:ibp_conns can be released by connection
+ * close from either a different thread, or the calling of
+ * kiblnd_check_sends_locked() below. See bz21911 for details.
*/
kiblnd_conn_addref(conn);
write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
@@ -2202,10 +2197,9 @@ kiblnd_connreq_done(struct kib_conn *conn, int status)
kiblnd_queue_tx_locked(tx, conn);
}
+ kiblnd_check_sends_locked(conn);
spin_unlock(&conn->ibc_lock);
- kiblnd_check_sends(conn);
-
/* schedule blocked rxs */
kiblnd_handle_early_rxs(conn);
@@ -2240,6 +2234,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob)
struct kib_rej rej;
int version = IBLND_MSG_VERSION;
unsigned long flags;
+ int max_frags;
int rc;
struct sockaddr_in *peer_addr;
@@ -2346,22 +2341,20 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob)
goto failed;
}
- if (reqmsg->ibm_u.connparams.ibcp_max_frags >
- kiblnd_rdma_frags(version, ni)) {
- CWARN("Can't accept conn from %s (version %x): max_frags %d too large (%d wanted)\n",
- libcfs_nid2str(nid), version,
- reqmsg->ibm_u.connparams.ibcp_max_frags,
+ max_frags = reqmsg->ibm_u.connparams.ibcp_max_frags >> IBLND_FRAG_SHIFT;
+ if (max_frags > kiblnd_rdma_frags(version, ni)) {
+ CWARN("Can't accept conn from %s (version %x): max message size %d is too large (%d wanted)\n",
+ libcfs_nid2str(nid), version, max_frags,
kiblnd_rdma_frags(version, ni));
if (version >= IBLND_MSG_VERSION)
rej.ibr_why = IBLND_REJECT_RDMA_FRAGS;
goto failed;
- } else if (reqmsg->ibm_u.connparams.ibcp_max_frags <
- kiblnd_rdma_frags(version, ni) && !net->ibn_fmr_ps) {
- CWARN("Can't accept conn from %s (version %x): max_frags %d incompatible without FMR pool (%d wanted)\n",
- libcfs_nid2str(nid), version,
- reqmsg->ibm_u.connparams.ibcp_max_frags,
+ } else if (max_frags < kiblnd_rdma_frags(version, ni) &&
+ !net->ibn_fmr_ps) {
+ CWARN("Can't accept conn from %s (version %x): max message size %d incompatible without FMR pool (%d wanted)\n",
+ libcfs_nid2str(nid), version, max_frags,
kiblnd_rdma_frags(version, ni));
if (version == IBLND_MSG_VERSION)
@@ -2387,7 +2380,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob)
}
/* We have validated the peer's parameters so use those */
- peer->ibp_max_frags = reqmsg->ibm_u.connparams.ibcp_max_frags;
+ peer->ibp_max_frags = max_frags;
peer->ibp_queue_depth = reqmsg->ibm_u.connparams.ibcp_queue_depth;
write_lock_irqsave(g_lock, flags);
@@ -2419,23 +2412,37 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob)
goto failed;
}
- /* tie-break connection race in favour of the higher NID */
+ /*
+ * Tie-break connection race in favour of the higher NID.
+ * If we keep running into a race condition multiple times,
+ * we have to assume that the connection attempt with the
+ * higher NID is stuck in a connecting state and will never
+ * recover. As such, we pass through this if-block and let
+ * the lower NID connection win so we can move forward.
+ */
if (peer2->ibp_connecting &&
- nid < ni->ni_nid) {
+ nid < ni->ni_nid && peer2->ibp_races <
+ MAX_CONN_RACES_BEFORE_ABORT) {
+ peer2->ibp_races++;
write_unlock_irqrestore(g_lock, flags);
- CWARN("Conn race %s\n", libcfs_nid2str(peer2->ibp_nid));
+ CDEBUG(D_NET, "Conn race %s\n",
+ libcfs_nid2str(peer2->ibp_nid));
kiblnd_peer_decref(peer);
rej.ibr_why = IBLND_REJECT_CONN_RACE;
goto failed;
}
-
+ if (peer2->ibp_races >= MAX_CONN_RACES_BEFORE_ABORT)
+ CNETERR("Conn race %s: unresolved after %d attempts, letting lower NID win\n",
+ libcfs_nid2str(peer2->ibp_nid),
+ MAX_CONN_RACES_BEFORE_ABORT);
/**
* passive connection is allowed even this peer is waiting for
* reconnection.
*/
peer2->ibp_reconnecting = 0;
+ peer2->ibp_races = 0;
peer2->ibp_accepting++;
kiblnd_peer_addref(peer2);
@@ -2494,7 +2501,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob)
kiblnd_init_msg(ackmsg, IBLND_MSG_CONNACK,
sizeof(ackmsg->ibm_u.connparams));
ackmsg->ibm_u.connparams.ibcp_queue_depth = conn->ibc_queue_depth;
- ackmsg->ibm_u.connparams.ibcp_max_frags = conn->ibc_max_frags;
+ ackmsg->ibm_u.connparams.ibcp_max_frags = conn->ibc_max_frags << IBLND_FRAG_SHIFT;
ackmsg->ibm_u.connparams.ibcp_max_msg_size = IBLND_MSG_SIZE;
kiblnd_pack_msg(ni, ackmsg, version, 0, nid, reqmsg->ibm_srcstamp);
@@ -2526,9 +2533,9 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob)
failed:
if (ni) {
- lnet_ni_decref(ni);
rej.ibr_cp.ibcp_queue_depth = kiblnd_msg_queue_size(version, ni);
rej.ibr_cp.ibcp_max_frags = kiblnd_rdma_frags(version, ni);
+ lnet_ni_decref(ni);
}
rej.ibr_version = version;
@@ -2556,7 +2563,7 @@ kiblnd_check_reconnect(struct kib_conn *conn, int version,
if (cp) {
msg_size = cp->ibcp_max_msg_size;
- frag_num = cp->ibcp_max_frags;
+ frag_num = cp->ibcp_max_frags << IBLND_FRAG_SHIFT;
queue_dep = cp->ibcp_queue_depth;
}
@@ -2821,11 +2828,11 @@ kiblnd_check_connreply(struct kib_conn *conn, void *priv, int priv_nob)
goto failed;
}
- if (msg->ibm_u.connparams.ibcp_max_frags >
+ if ((msg->ibm_u.connparams.ibcp_max_frags >> IBLND_FRAG_SHIFT) >
conn->ibc_max_frags) {
CERROR("%s has incompatible max_frags %d (<=%d wanted)\n",
libcfs_nid2str(peer->ibp_nid),
- msg->ibm_u.connparams.ibcp_max_frags,
+ msg->ibm_u.connparams.ibcp_max_frags >> IBLND_FRAG_SHIFT,
conn->ibc_max_frags);
rc = -EPROTO;
goto failed;
@@ -2859,7 +2866,7 @@ kiblnd_check_connreply(struct kib_conn *conn, void *priv, int priv_nob)
conn->ibc_credits = msg->ibm_u.connparams.ibcp_queue_depth;
conn->ibc_reserved_credits = msg->ibm_u.connparams.ibcp_queue_depth;
conn->ibc_queue_depth = msg->ibm_u.connparams.ibcp_queue_depth;
- conn->ibc_max_frags = msg->ibm_u.connparams.ibcp_max_frags;
+ conn->ibc_max_frags = msg->ibm_u.connparams.ibcp_max_frags >> IBLND_FRAG_SHIFT;
LASSERT(conn->ibc_credits + conn->ibc_reserved_credits +
IBLND_OOB_MSGS(ver) <= IBLND_RX_MSGS(conn));
@@ -2916,7 +2923,7 @@ kiblnd_active_connect(struct rdma_cm_id *cmid)
memset(msg, 0, sizeof(*msg));
kiblnd_init_msg(msg, IBLND_MSG_CONNREQ, sizeof(msg->ibm_u.connparams));
msg->ibm_u.connparams.ibcp_queue_depth = conn->ibc_queue_depth;
- msg->ibm_u.connparams.ibcp_max_frags = conn->ibc_max_frags;
+ msg->ibm_u.connparams.ibcp_max_frags = conn->ibc_max_frags << IBLND_FRAG_SHIFT;
msg->ibm_u.connparams.ibcp_max_msg_size = IBLND_MSG_SIZE;
kiblnd_pack_msg(peer->ibp_ni, msg, version,
@@ -3233,7 +3240,11 @@ kiblnd_check_conns(int idx)
*/
list_for_each_entry_safe(conn, temp, &checksends, ibc_connd_list) {
list_del(&conn->ibc_connd_list);
- kiblnd_check_sends(conn);
+
+ spin_lock(&conn->ibc_lock);
+ kiblnd_check_sends_locked(conn);
+ spin_unlock(&conn->ibc_lock);
+
kiblnd_conn_decref(conn);
}
}
@@ -3419,6 +3430,12 @@ kiblnd_qp_event(struct ib_event *event, void *arg)
case IB_EVENT_COMM_EST:
CDEBUG(D_NET, "%s established\n",
libcfs_nid2str(conn->ibc_peer->ibp_nid));
+ /*
+ * We received a packet but connection isn't established
+ * probably handshake packet was lost, so free to
+ * force make connection established
+ */
+ rdma_notify(conn->ibc_cmid, IB_EVENT_COMM_EST);
return;
default:
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
index 07ec540946cd..cbc9a9c5385f 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
@@ -1468,11 +1468,6 @@ ksocknal_close_conn_locked(struct ksock_conn *conn, int error)
conn->ksnc_route = NULL;
-#if 0 /* irrelevant with only eager routes */
- /* make route least favourite */
- list_del(&route->ksnr_list);
- list_add_tail(&route->ksnr_list, &peer->ksnp_routes);
-#endif
ksocknal_route_decref(route); /* drop conn's ref on route */
}
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
index a56632b4ee37..e6ca0cf52691 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
@@ -86,8 +86,6 @@ struct ksock_sched { /* per scheduler state */
int kss_nconns; /* # connections assigned to
* this scheduler */
struct ksock_sched_info *kss_info; /* owner of it */
- struct page *kss_rx_scratch_pgs[LNET_MAX_IOV];
- struct kvec kss_scratch_iov[LNET_MAX_IOV];
};
struct ksock_sched_info {
@@ -616,9 +614,7 @@ void ksocknal_shutdown(lnet_ni_t *ni);
int ksocknal_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg);
int ksocknal_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg);
int ksocknal_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg,
- int delayed, unsigned int niov,
- struct kvec *iov, lnet_kiov_t *kiov,
- unsigned int offset, unsigned int mlen, unsigned int rlen);
+ int delayed, struct iov_iter *to, unsigned int rlen);
int ksocknal_accept(lnet_ni_t *ni, struct socket *sock);
int ksocknal_add_peer(lnet_ni_t *ni, lnet_process_id_t id, __u32 ip, int port);
@@ -635,7 +631,7 @@ int ksocknal_close_peer_conns_locked(struct ksock_peer *peer,
int ksocknal_close_conn_and_siblings(struct ksock_conn *conn, int why);
int ksocknal_close_matching_conns(lnet_process_id_t id, __u32 ipaddr);
struct ksock_conn *ksocknal_find_conn_locked(struct ksock_peer *peer,
- struct ksock_tx *tx, int nonblk);
+ struct ksock_tx *tx, int nonblk);
int ksocknal_launch_packet(lnet_ni_t *ni, struct ksock_tx *tx,
lnet_process_id_t id);
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
index 303576d815c6..c1c6f604e6ad 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
@@ -35,8 +35,8 @@ ksocknal_alloc_tx(int type, int size)
spin_lock(&ksocknal_data.ksnd_tx_lock);
if (!list_empty(&ksocknal_data.ksnd_idle_noop_txs)) {
- tx = list_entry(ksocknal_data.ksnd_idle_noop_txs. \
- next, struct ksock_tx, tx_list);
+ tx = list_entry(ksocknal_data.ksnd_idle_noop_txs.next,
+ struct ksock_tx, tx_list);
LASSERT(tx->tx_desc_size == size);
list_del(&tx->tx_list);
}
@@ -164,13 +164,13 @@ ksocknal_send_kiov(struct ksock_conn *conn, struct ksock_tx *tx)
do {
LASSERT(tx->tx_nkiov > 0);
- if (nob < (int)kiov->kiov_len) {
- kiov->kiov_offset += nob;
- kiov->kiov_len -= nob;
+ if (nob < (int)kiov->bv_len) {
+ kiov->bv_offset += nob;
+ kiov->bv_len -= nob;
return rc;
}
- nob -= (int)kiov->kiov_len;
+ nob -= (int)kiov->bv_len;
tx->tx_kiov = ++kiov;
tx->tx_nkiov--;
} while (nob);
@@ -326,13 +326,13 @@ ksocknal_recv_kiov(struct ksock_conn *conn)
do {
LASSERT(conn->ksnc_rx_nkiov > 0);
- if (nob < (int)kiov->kiov_len) {
- kiov->kiov_offset += nob;
- kiov->kiov_len -= nob;
+ if (nob < (int)kiov->bv_len) {
+ kiov->bv_offset += nob;
+ kiov->bv_len -= nob;
return -EAGAIN;
}
- nob -= kiov->kiov_len;
+ nob -= kiov->bv_len;
conn->ksnc_rx_kiov = ++kiov;
conn->ksnc_rx_nkiov--;
} while (nob);
@@ -1325,39 +1325,36 @@ ksocknal_process_receive(struct ksock_conn *conn)
int
ksocknal_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
- unsigned int niov, struct kvec *iov, lnet_kiov_t *kiov,
- unsigned int offset, unsigned int mlen, unsigned int rlen)
+ struct iov_iter *to, unsigned int rlen)
{
struct ksock_conn *conn = private;
struct ksock_sched *sched = conn->ksnc_scheduler;
- LASSERT(mlen <= rlen);
- LASSERT(niov <= LNET_MAX_IOV);
+ LASSERT(iov_iter_count(to) <= rlen);
+ LASSERT(to->nr_segs <= LNET_MAX_IOV);
conn->ksnc_cookie = msg;
- conn->ksnc_rx_nob_wanted = mlen;
+ conn->ksnc_rx_nob_wanted = iov_iter_count(to);
conn->ksnc_rx_nob_left = rlen;
- if (!mlen || iov) {
+ if (to->type & ITER_KVEC) {
conn->ksnc_rx_nkiov = 0;
conn->ksnc_rx_kiov = NULL;
conn->ksnc_rx_iov = conn->ksnc_rx_iov_space.iov;
conn->ksnc_rx_niov =
lnet_extract_iov(LNET_MAX_IOV, conn->ksnc_rx_iov,
- niov, iov, offset, mlen);
+ to->nr_segs, to->kvec,
+ to->iov_offset, iov_iter_count(to));
} else {
conn->ksnc_rx_niov = 0;
conn->ksnc_rx_iov = NULL;
conn->ksnc_rx_kiov = conn->ksnc_rx_iov_space.kiov;
conn->ksnc_rx_nkiov =
lnet_extract_kiov(LNET_MAX_IOV, conn->ksnc_rx_kiov,
- niov, kiov, offset, mlen);
+ to->nr_segs, to->bvec,
+ to->iov_offset, iov_iter_count(to));
}
- LASSERT(mlen ==
- lnet_iov_nob(conn->ksnc_rx_niov, conn->ksnc_rx_iov) +
- lnet_kiov_nob(conn->ksnc_rx_nkiov, conn->ksnc_rx_kiov));
-
LASSERT(conn->ksnc_rx_scheduled);
spin_lock_bh(&sched->kss_lock);
@@ -2008,13 +2005,6 @@ ksocknal_connect(struct ksock_route *route)
list_splice_init(&peer->ksnp_tx_queue, &zombies);
}
-#if 0 /* irrelevant with only eager routes */
- if (!route->ksnr_deleted) {
- /* make this route least-favourite for re-selection */
- list_del(&route->ksnr_list);
- list_add_tail(&route->ksnr_list, &peer->ksnp_routes);
- }
-#endif
write_unlock_bh(&ksocknal_data.ksnd_global_lock);
ksocknal_peer_failed(peer);
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
index 6a17757fce1e..6c95e989ca12 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib.c
@@ -73,9 +73,9 @@ ksocknal_lib_zc_capable(struct ksock_conn *conn)
int
ksocknal_lib_send_iov(struct ksock_conn *conn, struct ksock_tx *tx)
{
+ struct msghdr msg = {.msg_flags = MSG_DONTWAIT};
struct socket *sock = conn->ksnc_sock;
- int nob;
- int rc;
+ int nob, i;
if (*ksocknal_tunables.ksnd_enable_csum && /* checksum enabled */
conn->ksnc_proto == &ksocknal_protocol_v2x && /* V2.x connection */
@@ -83,34 +83,16 @@ ksocknal_lib_send_iov(struct ksock_conn *conn, struct ksock_tx *tx)
!tx->tx_msg.ksm_csum) /* not checksummed */
ksocknal_lib_csum_tx(tx);
- /*
- * NB we can't trust socket ops to either consume our iovs
- * or leave them alone.
- */
- {
-#if SOCKNAL_SINGLE_FRAG_TX
- struct kvec scratch;
- struct kvec *scratchiov = &scratch;
- unsigned int niov = 1;
-#else
- struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
- unsigned int niov = tx->tx_niov;
-#endif
- struct msghdr msg = {.msg_flags = MSG_DONTWAIT};
- int i;
+ for (nob = i = 0; i < tx->tx_niov; i++)
+ nob += tx->tx_iov[i].iov_len;
- for (nob = i = 0; i < niov; i++) {
- scratchiov[i] = tx->tx_iov[i];
- nob += scratchiov[i].iov_len;
- }
+ if (!list_empty(&conn->ksnc_tx_queue) ||
+ nob < tx->tx_resid)
+ msg.msg_flags |= MSG_MORE;
- if (!list_empty(&conn->ksnc_tx_queue) ||
- nob < tx->tx_resid)
- msg.msg_flags |= MSG_MORE;
-
- rc = kernel_sendmsg(sock, &msg, scratchiov, niov, nob);
- }
- return rc;
+ iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC,
+ tx->tx_iov, tx->tx_niov, nob);
+ return sock_sendmsg(sock, &msg);
}
int
@@ -124,20 +106,16 @@ ksocknal_lib_send_kiov(struct ksock_conn *conn, struct ksock_tx *tx)
/* Not NOOP message */
LASSERT(tx->tx_lnetmsg);
- /*
- * NB we can't trust socket ops to either consume our iovs
- * or leave them alone.
- */
if (tx->tx_msg.ksm_zc_cookies[0]) {
/* Zero copy is enabled */
struct sock *sk = sock->sk;
- struct page *page = kiov->kiov_page;
- int offset = kiov->kiov_offset;
- int fragsize = kiov->kiov_len;
+ struct page *page = kiov->bv_page;
+ int offset = kiov->bv_offset;
+ int fragsize = kiov->bv_len;
int msgflg = MSG_DONTWAIT;
CDEBUG(D_NET, "page %p + offset %x for %d\n",
- page, offset, kiov->kiov_len);
+ page, offset, kiov->bv_len);
if (!list_empty(&conn->ksnc_tx_queue) ||
fragsize < tx->tx_resid)
@@ -150,34 +128,19 @@ ksocknal_lib_send_kiov(struct ksock_conn *conn, struct ksock_tx *tx)
rc = tcp_sendpage(sk, page, offset, fragsize, msgflg);
}
} else {
-#if SOCKNAL_SINGLE_FRAG_TX || !SOCKNAL_RISK_KMAP_DEADLOCK
- struct kvec scratch;
- struct kvec *scratchiov = &scratch;
- unsigned int niov = 1;
-#else
-#ifdef CONFIG_HIGHMEM
-#warning "XXX risk of kmap deadlock on multiple frags..."
-#endif
- struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
- unsigned int niov = tx->tx_nkiov;
-#endif
struct msghdr msg = {.msg_flags = MSG_DONTWAIT};
int i;
- for (nob = i = 0; i < niov; i++) {
- scratchiov[i].iov_base = kmap(kiov[i].kiov_page) +
- kiov[i].kiov_offset;
- nob += scratchiov[i].iov_len = kiov[i].kiov_len;
- }
+ for (nob = i = 0; i < tx->tx_nkiov; i++)
+ nob += kiov[i].bv_len;
if (!list_empty(&conn->ksnc_tx_queue) ||
nob < tx->tx_resid)
msg.msg_flags |= MSG_MORE;
- rc = kernel_sendmsg(sock, &msg, (struct kvec *)scratchiov, niov, nob);
-
- for (i = 0; i < niov; i++)
- kunmap(kiov[i].kiov_page);
+ iov_iter_bvec(&msg.msg_iter, WRITE | ITER_BVEC,
+ kiov, tx->tx_nkiov, nob);
+ rc = sock_sendmsg(sock, &msg);
}
return rc;
}
@@ -201,14 +164,7 @@ ksocknal_lib_eager_ack(struct ksock_conn *conn)
int
ksocknal_lib_recv_iov(struct ksock_conn *conn)
{
-#if SOCKNAL_SINGLE_FRAG_RX
- struct kvec scratch;
- struct kvec *scratchiov = &scratch;
- unsigned int niov = 1;
-#else
- struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
unsigned int niov = conn->ksnc_rx_niov;
-#endif
struct kvec *iov = conn->ksnc_rx_iov;
struct msghdr msg = {
.msg_flags = 0
@@ -220,20 +176,15 @@ ksocknal_lib_recv_iov(struct ksock_conn *conn)
int sum;
__u32 saved_csum;
- /*
- * NB we can't trust socket ops to either consume our iovs
- * or leave them alone.
- */
LASSERT(niov > 0);
- for (nob = i = 0; i < niov; i++) {
- scratchiov[i] = iov[i];
- nob += scratchiov[i].iov_len;
- }
+ for (nob = i = 0; i < niov; i++)
+ nob += iov[i].iov_len;
+
LASSERT(nob <= conn->ksnc_rx_nob_wanted);
- rc = kernel_recvmsg(conn->ksnc_sock, &msg, scratchiov, niov, nob,
- MSG_DONTWAIT);
+ iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, iov, niov, nob);
+ rc = sock_recvmsg(conn->ksnc_sock, &msg, MSG_DONTWAIT);
saved_csum = 0;
if (conn->ksnc_proto == &ksocknal_protocol_v2x) {
@@ -259,67 +210,10 @@ ksocknal_lib_recv_iov(struct ksock_conn *conn)
return rc;
}
-static void
-ksocknal_lib_kiov_vunmap(void *addr)
-{
- if (!addr)
- return;
-
- vunmap(addr);
-}
-
-static void *
-ksocknal_lib_kiov_vmap(lnet_kiov_t *kiov, int niov,
- struct kvec *iov, struct page **pages)
-{
- void *addr;
- int nob;
- int i;
-
- if (!*ksocknal_tunables.ksnd_zc_recv || !pages)
- return NULL;
-
- LASSERT(niov <= LNET_MAX_IOV);
-
- if (niov < 2 ||
- niov < *ksocknal_tunables.ksnd_zc_recv_min_nfrags)
- return NULL;
-
- for (nob = i = 0; i < niov; i++) {
- if ((kiov[i].kiov_offset && i > 0) ||
- (kiov[i].kiov_offset + kiov[i].kiov_len != PAGE_SIZE && i < niov - 1))
- return NULL;
-
- pages[i] = kiov[i].kiov_page;
- nob += kiov[i].kiov_len;
- }
-
- addr = vmap(pages, niov, VM_MAP, PAGE_KERNEL);
- if (!addr)
- return NULL;
-
- iov->iov_base = addr + kiov[0].kiov_offset;
- iov->iov_len = nob;
-
- return addr;
-}
-
int
ksocknal_lib_recv_kiov(struct ksock_conn *conn)
{
-#if SOCKNAL_SINGLE_FRAG_RX || !SOCKNAL_RISK_KMAP_DEADLOCK
- struct kvec scratch;
- struct kvec *scratchiov = &scratch;
- struct page **pages = NULL;
- unsigned int niov = 1;
-#else
-#ifdef CONFIG_HIGHMEM
-#warning "XXX risk of kmap deadlock on multiple frags..."
-#endif
- struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
- struct page **pages = conn->ksnc_scheduler->kss_rx_scratch_pgs;
unsigned int niov = conn->ksnc_rx_nkiov;
-#endif
lnet_kiov_t *kiov = conn->ksnc_rx_kiov;
struct msghdr msg = {
.msg_flags = 0
@@ -328,63 +222,32 @@ ksocknal_lib_recv_kiov(struct ksock_conn *conn)
int i;
int rc;
void *base;
- void *addr;
int sum;
int fragnob;
- int n;
-
- /*
- * NB we can't trust socket ops to either consume our iovs
- * or leave them alone.
- */
- addr = ksocknal_lib_kiov_vmap(kiov, niov, scratchiov, pages);
- if (addr) {
- nob = scratchiov[0].iov_len;
- n = 1;
- } else {
- for (nob = i = 0; i < niov; i++) {
- nob += scratchiov[i].iov_len = kiov[i].kiov_len;
- scratchiov[i].iov_base = kmap(kiov[i].kiov_page) +
- kiov[i].kiov_offset;
- }
- n = niov;
- }
+ for (nob = i = 0; i < niov; i++)
+ nob += kiov[i].bv_len;
LASSERT(nob <= conn->ksnc_rx_nob_wanted);
- rc = kernel_recvmsg(conn->ksnc_sock, &msg, (struct kvec *)scratchiov,
- n, nob, MSG_DONTWAIT);
+ iov_iter_bvec(&msg.msg_iter, READ | ITER_BVEC, kiov, niov, nob);
+ rc = sock_recvmsg(conn->ksnc_sock, &msg, MSG_DONTWAIT);
if (conn->ksnc_msg.ksm_csum) {
for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
LASSERT(i < niov);
- /*
- * Dang! have to kmap again because I have nowhere to
- * stash the mapped address. But by doing it while the
- * page is still mapped, the kernel just bumps the map
- * count and returns me the address it stashed.
- */
- base = kmap(kiov[i].kiov_page) + kiov[i].kiov_offset;
- fragnob = kiov[i].kiov_len;
+ base = kmap(kiov[i].bv_page) + kiov[i].bv_offset;
+ fragnob = kiov[i].bv_len;
if (fragnob > sum)
fragnob = sum;
conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
base, fragnob);
- kunmap(kiov[i].kiov_page);
+ kunmap(kiov[i].bv_page);
}
}
-
- if (addr) {
- ksocknal_lib_kiov_vunmap(addr);
- } else {
- for (i = 0; i < niov; i++)
- kunmap(kiov[i].kiov_page);
- }
-
return rc;
}
@@ -406,12 +269,12 @@ ksocknal_lib_csum_tx(struct ksock_tx *tx)
if (tx->tx_kiov) {
for (i = 0; i < tx->tx_nkiov; i++) {
- base = kmap(tx->tx_kiov[i].kiov_page) +
- tx->tx_kiov[i].kiov_offset;
+ base = kmap(tx->tx_kiov[i].bv_page) +
+ tx->tx_kiov[i].bv_offset;
- csum = ksocknal_csum(csum, base, tx->tx_kiov[i].kiov_len);
+ csum = ksocknal_csum(csum, base, tx->tx_kiov[i].bv_len);
- kunmap(tx->tx_kiov[i].kiov_page);
+ kunmap(tx->tx_kiov[i].bv_page);
}
} else {
for (i = 1; i < tx->tx_niov; i++)
diff --git a/drivers/staging/lustre/lnet/libcfs/debug.c b/drivers/staging/lustre/lnet/libcfs/debug.c
index 42b15a769183..23b36b890964 100644
--- a/drivers/staging/lustre/lnet/libcfs/debug.c
+++ b/drivers/staging/lustre/lnet/libcfs/debug.c
@@ -328,15 +328,20 @@ libcfs_debug_str2mask(int *mask, const char *str, int is_subsys)
*/
void libcfs_debug_dumplog_internal(void *arg)
{
+ static time64_t last_dump_time;
+ time64_t current_time;
void *journal_info;
journal_info = current->journal_info;
current->journal_info = NULL;
+ current_time = ktime_get_real_seconds();
- if (strncmp(libcfs_debug_file_path_arr, "NONE", 4) != 0) {
+ if (strncmp(libcfs_debug_file_path_arr, "NONE", 4) &&
+ current_time > last_dump_time) {
+ last_dump_time = current_time;
snprintf(debug_file_name, sizeof(debug_file_name) - 1,
"%s.%lld.%ld", libcfs_debug_file_path_arr,
- (s64)ktime_get_real_seconds(), (long_ptr_t)arg);
+ (s64)current_time, (long_ptr_t)arg);
pr_alert("LustreError: dumping log to %s\n", debug_file_name);
cfs_tracefile_dump_all_pages(debug_file_name);
libcfs_run_debug_log_upcall(debug_file_name);
diff --git a/drivers/staging/lustre/lnet/libcfs/fail.c b/drivers/staging/lustre/lnet/libcfs/fail.c
index 9288ee08d1f7..e4b1a0a86eae 100644
--- a/drivers/staging/lustre/lnet/libcfs/fail.c
+++ b/drivers/staging/lustre/lnet/libcfs/fail.c
@@ -90,8 +90,10 @@ int __cfs_fail_check_set(__u32 id, __u32 value, int set)
}
}
- if ((set == CFS_FAIL_LOC_ORSET || set == CFS_FAIL_LOC_RESET) &&
- (value & CFS_FAIL_ONCE))
+ /* Take into account the current call for FAIL_ONCE for ORSET only,
+ * as RESET is a new fail_loc, it does not change the current call
+ */
+ if ((set == CFS_FAIL_LOC_ORSET) && (value & CFS_FAIL_ONCE))
set_bit(CFS_FAIL_ONCE_BIT, &cfs_fail_loc);
/* Lost race to set CFS_FAILED_BIT. */
if (test_and_set_bit(CFS_FAILED_BIT, &cfs_fail_loc)) {
diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_string.c b/drivers/staging/lustre/lnet/libcfs/libcfs_string.c
index fc697cdfcdaf..56a614d7713b 100644
--- a/drivers/staging/lustre/lnet/libcfs/libcfs_string.c
+++ b/drivers/staging/lustre/lnet/libcfs/libcfs_string.c
@@ -229,8 +229,6 @@ cfs_str2num_check(char *str, int nob, unsigned *num,
char *endp, cache;
int rc;
- str = cfs_trimwhite(str);
-
/**
* kstrouint can only handle strings composed
* of only numbers. We need to scan the string
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c
index b52518c54efe..e8b1a61420de 100644
--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c
+++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c
@@ -74,6 +74,17 @@ struct cfs_cpt_data {
static struct cfs_cpt_data cpt_data;
+static void
+cfs_node_to_cpumask(int node, cpumask_t *mask)
+{
+ const cpumask_t *tmp = cpumask_of_node(node);
+
+ if (tmp)
+ cpumask_copy(mask, tmp);
+ else
+ cpumask_clear(mask);
+}
+
void
cfs_cpt_table_free(struct cfs_cpt_table *cptab)
{
@@ -403,7 +414,7 @@ cfs_cpt_set_node(struct cfs_cpt_table *cptab, int cpt, int node)
mutex_lock(&cpt_data.cpt_mutex);
mask = cpt_data.cpt_cpumask;
- cpumask_copy(mask, cpumask_of_node(node));
+ cfs_node_to_cpumask(node, mask);
rc = cfs_cpt_set_cpumask(cptab, cpt, mask);
@@ -427,7 +438,7 @@ cfs_cpt_unset_node(struct cfs_cpt_table *cptab, int cpt, int node)
mutex_lock(&cpt_data.cpt_mutex);
mask = cpt_data.cpt_cpumask;
- cpumask_copy(mask, cpumask_of_node(node));
+ cfs_node_to_cpumask(node, mask);
cfs_cpt_unset_cpumask(cptab, cpt, mask);
@@ -749,7 +760,7 @@ cfs_cpt_table_create(int ncpt)
}
for_each_online_node(i) {
- cpumask_copy(mask, cpumask_of_node(i));
+ cfs_node_to_cpumask(i, mask);
while (!cpumask_empty(mask)) {
struct cfs_cpu_partition *part;
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c
index 5c0116ade909..7f56d2c9dd00 100644
--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c
+++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c
@@ -95,8 +95,8 @@ static int cfs_crypto_hash_alloc(enum cfs_crypto_hash_alg hash_alg,
err = crypto_ahash_setkey(tfm, key, key_len);
else if ((*type)->cht_key != 0)
err = crypto_ahash_setkey(tfm,
- (unsigned char *)&((*type)->cht_key),
- (*type)->cht_size);
+ (unsigned char *)&((*type)->cht_key),
+ (*type)->cht_size);
if (err != 0) {
ahash_request_free(*req);
diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c
index 346db892f275..4daf828198c3 100644
--- a/drivers/staging/lustre/lnet/lnet/api-ni.c
+++ b/drivers/staging/lustre/lnet/lnet/api-ni.c
@@ -1286,6 +1286,25 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf)
sizeof(*ni->ni_lnd_tunables));
}
+ /*
+ * If given some LND tunable parameters, parse those now to
+ * override the values in the NI structure.
+ */
+ if (conf) {
+ if (conf->cfg_config_u.cfg_net.net_peer_rtr_credits >= 0)
+ ni->ni_peerrtrcredits =
+ conf->cfg_config_u.cfg_net.net_peer_rtr_credits;
+ if (conf->cfg_config_u.cfg_net.net_peer_timeout >= 0)
+ ni->ni_peertimeout =
+ conf->cfg_config_u.cfg_net.net_peer_timeout;
+ if (conf->cfg_config_u.cfg_net.net_peer_tx_credits != -1)
+ ni->ni_peertxcredits =
+ conf->cfg_config_u.cfg_net.net_peer_tx_credits;
+ if (conf->cfg_config_u.cfg_net.net_max_tx_credits >= 0)
+ ni->ni_maxtxcredits =
+ conf->cfg_config_u.cfg_net.net_max_tx_credits;
+ }
+
rc = lnd->lnd_startup(ni);
mutex_unlock(&the_lnet.ln_lnd_mutex);
@@ -1299,33 +1318,6 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf)
goto failed0;
}
- /*
- * If given some LND tunable parameters, parse those now to
- * override the values in the NI structure.
- */
- if (conf && conf->cfg_config_u.cfg_net.net_peer_rtr_credits >= 0) {
- ni->ni_peerrtrcredits =
- conf->cfg_config_u.cfg_net.net_peer_rtr_credits;
- }
- if (conf && conf->cfg_config_u.cfg_net.net_peer_timeout >= 0) {
- ni->ni_peertimeout =
- conf->cfg_config_u.cfg_net.net_peer_timeout;
- }
- /*
- * TODO
- * Note: For now, don't allow the user to change
- * peertxcredits as this number is used in the
- * IB LND to control queue depth.
- *
- * if (conf && conf->cfg_config_u.cfg_net.net_peer_tx_credits != -1)
- * ni->ni_peertxcredits =
- * conf->cfg_config_u.cfg_net.net_peer_tx_credits;
- */
- if (conf && conf->cfg_config_u.cfg_net.net_max_tx_credits >= 0) {
- ni->ni_maxtxcredits =
- conf->cfg_config_u.cfg_net.net_max_tx_credits;
- }
-
LASSERT(ni->ni_peertimeout <= 0 || lnd->lnd_query);
lnet_net_lock(LNET_LOCK_EX);
diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c
index a72afdf68bb2..9e2183ff847e 100644
--- a/drivers/staging/lustre/lnet/lnet/config.c
+++ b/drivers/staging/lustre/lnet/lnet/config.c
@@ -31,6 +31,8 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
+#include <linux/nsproxy.h>
+#include <net/net_namespace.h>
#include "../../include/linux/lnet/lib-lnet.h"
struct lnet_text_buf { /* tmp struct for parsing routes */
@@ -110,6 +112,11 @@ lnet_ni_free(struct lnet_ni *ni)
LIBCFS_FREE(ni->ni_interfaces[i],
strlen(ni->ni_interfaces[i]) + 1);
}
+
+ /* release reference to net namespace */
+ if (ni->ni_net_ns)
+ put_net(ni->ni_net_ns);
+
LIBCFS_FREE(ni, sizeof(*ni));
}
@@ -171,6 +178,13 @@ lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist)
/* LND will fill in the address part of the NID */
ni->ni_nid = LNET_MKNID(net, 0);
+
+ /* Store net namespace in which current ni is being created */
+ if (current->nsproxy->net_ns)
+ ni->ni_net_ns = get_net(current->nsproxy->net_ns);
+ else
+ ni->ni_net_ns = NULL;
+
ni->ni_last_alive = ktime_get_real_seconds();
list_add_tail(&ni->ni_list, nilist);
return ni;
diff --git a/drivers/staging/lustre/lnet/lnet/lib-md.c b/drivers/staging/lustre/lnet/lnet/lib-md.c
index 1834bf7a27ef..eab53cd57296 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-md.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-md.c
@@ -134,11 +134,11 @@ lnet_md_build(lnet_libmd_t *lmd, lnet_md_t *umd, int unlink)
for (i = 0; i < (int)niov; i++) {
/* We take the page pointer on trust */
- if (lmd->md_iov.kiov[i].kiov_offset +
- lmd->md_iov.kiov[i].kiov_len > PAGE_SIZE)
+ if (lmd->md_iov.kiov[i].bv_offset +
+ lmd->md_iov.kiov[i].bv_len > PAGE_SIZE)
return -EINVAL; /* invalid length */
- total_length += lmd->md_iov.kiov[i].kiov_len;
+ total_length += lmd->md_iov.kiov[i].bv_len;
}
lmd->md_length = total_length;
@@ -292,11 +292,12 @@ LNetMDAttach(lnet_handle_me_t meh, lnet_md_t umd,
return -ENOMEM;
rc = lnet_md_build(md, &umd, unlink);
+ if (rc)
+ goto out_free;
+
cpt = lnet_cpt_of_cookie(meh.cookie);
lnet_res_lock(cpt);
- if (rc)
- goto failed;
me = lnet_handle2me(&meh);
if (!me)
@@ -307,7 +308,7 @@ LNetMDAttach(lnet_handle_me_t meh, lnet_md_t umd,
rc = lnet_md_link(md, umd.eq_handle, cpt);
if (rc)
- goto failed;
+ goto out_unlock;
/*
* attach this MD to portal of ME and check if it matches any
@@ -324,10 +325,10 @@ LNetMDAttach(lnet_handle_me_t meh, lnet_md_t umd,
return 0;
- failed:
- lnet_md_free(md);
-
+out_unlock:
lnet_res_unlock(cpt);
+out_free:
+ lnet_md_free(md);
return rc;
}
EXPORT_SYMBOL(LNetMDAttach);
@@ -370,24 +371,25 @@ LNetMDBind(lnet_md_t umd, lnet_unlink_t unlink, lnet_handle_md_t *handle)
return -ENOMEM;
rc = lnet_md_build(md, &umd, unlink);
+ if (rc)
+ goto out_free;
cpt = lnet_res_lock_current();
- if (rc)
- goto failed;
rc = lnet_md_link(md, umd.eq_handle, cpt);
if (rc)
- goto failed;
+ goto out_unlock;
lnet_md2handle(handle, md);
lnet_res_unlock(cpt);
return 0;
- failed:
+out_unlock:
+ lnet_res_unlock(cpt);
+out_free:
lnet_md_free(md);
- lnet_res_unlock(cpt);
return rc;
}
EXPORT_SYMBOL(LNetMDBind);
diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c
index e6d3b801d87d..48e6f8f2392f 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-move.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-move.c
@@ -37,6 +37,8 @@
#define DEBUG_SUBSYSTEM S_LNET
#include "../../include/linux/lnet/lib-lnet.h"
+#include <linux/nsproxy.h>
+#include <net/net_namespace.h>
static int local_nid_dist_zero = 1;
module_param(local_nid_dist_zero, int, 0444);
@@ -166,25 +168,17 @@ lnet_iov_nob(unsigned int niov, struct kvec *iov)
EXPORT_SYMBOL(lnet_iov_nob);
void
-lnet_copy_iov2iov(unsigned int ndiov, struct kvec *diov, unsigned int doffset,
- unsigned int nsiov, struct kvec *siov, unsigned int soffset,
- unsigned int nob)
+lnet_copy_iov2iter(struct iov_iter *to,
+ unsigned int nsiov, const struct kvec *siov,
+ unsigned int soffset, unsigned int nob)
{
/* NB diov, siov are READ-ONLY */
- unsigned int this_nob;
+ const char *s;
+ size_t left;
if (!nob)
return;
- /* skip complete frags before 'doffset' */
- LASSERT(ndiov > 0);
- while (doffset >= diov->iov_len) {
- doffset -= diov->iov_len;
- diov++;
- ndiov--;
- LASSERT(ndiov > 0);
- }
-
/* skip complete frags before 'soffset' */
LASSERT(nsiov > 0);
while (soffset >= siov->iov_len) {
@@ -194,39 +188,68 @@ lnet_copy_iov2iov(unsigned int ndiov, struct kvec *diov, unsigned int doffset,
LASSERT(nsiov > 0);
}
+ s = (char *)siov->iov_base + soffset;
+ left = siov->iov_len - soffset;
do {
- LASSERT(ndiov > 0);
+ size_t n, copy = left;
LASSERT(nsiov > 0);
- this_nob = min(diov->iov_len - doffset,
- siov->iov_len - soffset);
- this_nob = min(this_nob, nob);
- memcpy((char *)diov->iov_base + doffset,
- (char *)siov->iov_base + soffset, this_nob);
- nob -= this_nob;
+ if (copy > nob)
+ copy = nob;
+ n = copy_to_iter(s, copy, to);
+ if (n != copy)
+ return;
+ nob -= n;
- if (diov->iov_len > doffset + this_nob) {
- doffset += this_nob;
- } else {
- diov++;
- ndiov--;
- doffset = 0;
- }
+ siov++;
+ s = (char *)siov->iov_base;
+ left = siov->iov_len;
+ nsiov--;
+ } while (nob > 0);
+}
+EXPORT_SYMBOL(lnet_copy_iov2iter);
- if (siov->iov_len > soffset + this_nob) {
- soffset += this_nob;
- } else {
- siov++;
- nsiov--;
- soffset = 0;
- }
+void
+lnet_copy_kiov2iter(struct iov_iter *to,
+ unsigned int nsiov, const lnet_kiov_t *siov,
+ unsigned int soffset, unsigned int nob)
+{
+ if (!nob)
+ return;
+
+ LASSERT(!in_interrupt());
+
+ LASSERT(nsiov > 0);
+ while (soffset >= siov->bv_len) {
+ soffset -= siov->bv_len;
+ siov++;
+ nsiov--;
+ LASSERT(nsiov > 0);
+ }
+
+ do {
+ size_t copy = siov->bv_len - soffset, n;
+
+ LASSERT(nsiov > 0);
+
+ if (copy > nob)
+ copy = nob;
+ n = copy_page_to_iter(siov->bv_page,
+ siov->bv_offset + soffset,
+ copy, to);
+ if (n != copy)
+ return;
+ nob -= n;
+ siov++;
+ nsiov--;
+ soffset = 0;
} while (nob > 0);
}
-EXPORT_SYMBOL(lnet_copy_iov2iov);
+EXPORT_SYMBOL(lnet_copy_kiov2iter);
int
lnet_extract_iov(int dst_niov, struct kvec *dst,
- int src_niov, struct kvec *src,
+ int src_niov, const struct kvec *src,
unsigned int offset, unsigned int len)
{
/*
@@ -280,238 +303,15 @@ lnet_kiov_nob(unsigned int niov, lnet_kiov_t *kiov)
LASSERT(!niov || kiov);
while (niov-- > 0)
- nob += (kiov++)->kiov_len;
+ nob += (kiov++)->bv_len;
return nob;
}
EXPORT_SYMBOL(lnet_kiov_nob);
-void
-lnet_copy_kiov2kiov(unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset,
- unsigned int nsiov, lnet_kiov_t *siov, unsigned int soffset,
- unsigned int nob)
-{
- /* NB diov, siov are READ-ONLY */
- unsigned int this_nob;
- char *daddr = NULL;
- char *saddr = NULL;
-
- if (!nob)
- return;
-
- LASSERT(!in_interrupt());
-
- LASSERT(ndiov > 0);
- while (doffset >= diov->kiov_len) {
- doffset -= diov->kiov_len;
- diov++;
- ndiov--;
- LASSERT(ndiov > 0);
- }
-
- LASSERT(nsiov > 0);
- while (soffset >= siov->kiov_len) {
- soffset -= siov->kiov_len;
- siov++;
- nsiov--;
- LASSERT(nsiov > 0);
- }
-
- do {
- LASSERT(ndiov > 0);
- LASSERT(nsiov > 0);
- this_nob = min(diov->kiov_len - doffset,
- siov->kiov_len - soffset);
- this_nob = min(this_nob, nob);
-
- if (!daddr)
- daddr = ((char *)kmap(diov->kiov_page)) +
- diov->kiov_offset + doffset;
- if (!saddr)
- saddr = ((char *)kmap(siov->kiov_page)) +
- siov->kiov_offset + soffset;
-
- /*
- * Vanishing risk of kmap deadlock when mapping 2 pages.
- * However in practice at least one of the kiovs will be mapped
- * kernel pages and the map/unmap will be NOOPs
- */
- memcpy(daddr, saddr, this_nob);
- nob -= this_nob;
-
- if (diov->kiov_len > doffset + this_nob) {
- daddr += this_nob;
- doffset += this_nob;
- } else {
- kunmap(diov->kiov_page);
- daddr = NULL;
- diov++;
- ndiov--;
- doffset = 0;
- }
-
- if (siov->kiov_len > soffset + this_nob) {
- saddr += this_nob;
- soffset += this_nob;
- } else {
- kunmap(siov->kiov_page);
- saddr = NULL;
- siov++;
- nsiov--;
- soffset = 0;
- }
- } while (nob > 0);
-
- if (daddr)
- kunmap(diov->kiov_page);
- if (saddr)
- kunmap(siov->kiov_page);
-}
-EXPORT_SYMBOL(lnet_copy_kiov2kiov);
-
-void
-lnet_copy_kiov2iov(unsigned int niov, struct kvec *iov, unsigned int iovoffset,
- unsigned int nkiov, lnet_kiov_t *kiov,
- unsigned int kiovoffset, unsigned int nob)
-{
- /* NB iov, kiov are READ-ONLY */
- unsigned int this_nob;
- char *addr = NULL;
-
- if (!nob)
- return;
-
- LASSERT(!in_interrupt());
-
- LASSERT(niov > 0);
- while (iovoffset >= iov->iov_len) {
- iovoffset -= iov->iov_len;
- iov++;
- niov--;
- LASSERT(niov > 0);
- }
-
- LASSERT(nkiov > 0);
- while (kiovoffset >= kiov->kiov_len) {
- kiovoffset -= kiov->kiov_len;
- kiov++;
- nkiov--;
- LASSERT(nkiov > 0);
- }
-
- do {
- LASSERT(niov > 0);
- LASSERT(nkiov > 0);
- this_nob = min(iov->iov_len - iovoffset,
- (__kernel_size_t)kiov->kiov_len - kiovoffset);
- this_nob = min(this_nob, nob);
-
- if (!addr)
- addr = ((char *)kmap(kiov->kiov_page)) +
- kiov->kiov_offset + kiovoffset;
-
- memcpy((char *)iov->iov_base + iovoffset, addr, this_nob);
- nob -= this_nob;
-
- if (iov->iov_len > iovoffset + this_nob) {
- iovoffset += this_nob;
- } else {
- iov++;
- niov--;
- iovoffset = 0;
- }
-
- if (kiov->kiov_len > kiovoffset + this_nob) {
- addr += this_nob;
- kiovoffset += this_nob;
- } else {
- kunmap(kiov->kiov_page);
- addr = NULL;
- kiov++;
- nkiov--;
- kiovoffset = 0;
- }
-
- } while (nob > 0);
-
- if (addr)
- kunmap(kiov->kiov_page);
-}
-EXPORT_SYMBOL(lnet_copy_kiov2iov);
-
-void
-lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov,
- unsigned int kiovoffset, unsigned int niov,
- struct kvec *iov, unsigned int iovoffset,
- unsigned int nob)
-{
- /* NB kiov, iov are READ-ONLY */
- unsigned int this_nob;
- char *addr = NULL;
-
- if (!nob)
- return;
-
- LASSERT(!in_interrupt());
-
- LASSERT(nkiov > 0);
- while (kiovoffset >= kiov->kiov_len) {
- kiovoffset -= kiov->kiov_len;
- kiov++;
- nkiov--;
- LASSERT(nkiov > 0);
- }
-
- LASSERT(niov > 0);
- while (iovoffset >= iov->iov_len) {
- iovoffset -= iov->iov_len;
- iov++;
- niov--;
- LASSERT(niov > 0);
- }
-
- do {
- LASSERT(nkiov > 0);
- LASSERT(niov > 0);
- this_nob = min((__kernel_size_t)kiov->kiov_len - kiovoffset,
- iov->iov_len - iovoffset);
- this_nob = min(this_nob, nob);
-
- if (!addr)
- addr = ((char *)kmap(kiov->kiov_page)) +
- kiov->kiov_offset + kiovoffset;
-
- memcpy(addr, (char *)iov->iov_base + iovoffset, this_nob);
- nob -= this_nob;
-
- if (kiov->kiov_len > kiovoffset + this_nob) {
- addr += this_nob;
- kiovoffset += this_nob;
- } else {
- kunmap(kiov->kiov_page);
- addr = NULL;
- kiov++;
- nkiov--;
- kiovoffset = 0;
- }
-
- if (iov->iov_len > iovoffset + this_nob) {
- iovoffset += this_nob;
- } else {
- iov++;
- niov--;
- iovoffset = 0;
- }
- } while (nob > 0);
-
- if (addr)
- kunmap(kiov->kiov_page);
-}
-EXPORT_SYMBOL(lnet_copy_iov2kiov);
-
int
lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst,
- int src_niov, lnet_kiov_t *src,
+ int src_niov, const lnet_kiov_t *src,
unsigned int offset, unsigned int len)
{
/*
@@ -526,8 +326,8 @@ lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst,
return 0; /* no frags */
LASSERT(src_niov > 0);
- while (offset >= src->kiov_len) { /* skip initial frags */
- offset -= src->kiov_len;
+ while (offset >= src->bv_len) { /* skip initial frags */
+ offset -= src->bv_len;
src_niov--;
src++;
LASSERT(src_niov > 0);
@@ -538,19 +338,19 @@ lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst,
LASSERT(src_niov > 0);
LASSERT((int)niov <= dst_niov);
- frag_len = src->kiov_len - offset;
- dst->kiov_page = src->kiov_page;
- dst->kiov_offset = src->kiov_offset + offset;
+ frag_len = src->bv_len - offset;
+ dst->bv_page = src->bv_page;
+ dst->bv_offset = src->bv_offset + offset;
if (len <= frag_len) {
- dst->kiov_len = len;
- LASSERT(dst->kiov_offset + dst->kiov_len
+ dst->bv_len = len;
+ LASSERT(dst->bv_offset + dst->bv_len
<= PAGE_SIZE);
return niov;
}
- dst->kiov_len = frag_len;
- LASSERT(dst->kiov_offset + dst->kiov_len <= PAGE_SIZE);
+ dst->bv_len = frag_len;
+ LASSERT(dst->bv_offset + dst->bv_len <= PAGE_SIZE);
len -= frag_len;
dst++;
@@ -569,6 +369,7 @@ lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
unsigned int niov = 0;
struct kvec *iov = NULL;
lnet_kiov_t *kiov = NULL;
+ struct iov_iter to;
int rc;
LASSERT(!in_interrupt());
@@ -594,8 +395,14 @@ lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
}
}
- rc = ni->ni_lnd->lnd_recv(ni, private, msg, delayed,
- niov, iov, kiov, offset, mlen, rlen);
+ if (iov) {
+ iov_iter_kvec(&to, ITER_KVEC | READ, iov, niov, mlen + offset);
+ iov_iter_advance(&to, offset);
+ } else {
+ iov_iter_bvec(&to, ITER_BVEC | READ, kiov, niov, mlen + offset);
+ iov_iter_advance(&to, offset);
+ }
+ rc = ni->ni_lnd->lnd_recv(ni, private, msg, delayed, &to, rlen);
if (rc < 0)
lnet_finalize(ni, msg, rc);
}
@@ -2002,6 +1809,9 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
libcfs_nid2str(from_nid), libcfs_nid2str(src_nid),
lnet_msgtyp2str(type), rc);
lnet_msg_free(msg);
+ if (rc == -ESHUTDOWN)
+ /* We are shutting down. Don't do anything more */
+ return 0;
goto drop;
}
@@ -2512,6 +2322,15 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp)
}
if (LNET_NIDNET(ni->ni_nid) == dstnet) {
+ /*
+ * Check if ni was originally created in
+ * current net namespace.
+ * If not, assign order above 0xffff0000,
+ * to make this ni not a priority.
+ */
+ if (!net_eq(ni->ni_net_ns, current->nsproxy->net_ns))
+ order += 0xffff0000;
+
if (srcnidp)
*srcnidp = ni->ni_nid;
if (orderp)
diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c
index 910e106e221d..0897e588bd54 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-msg.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c
@@ -449,23 +449,7 @@ lnet_finalize(lnet_ni_t *ni, lnet_msg_t *msg, int status)
if (!msg)
return;
-#if 0
- CDEBUG(D_WARNING, "%s msg->%s Flags:%s%s%s%s%s%s%s%s%s%s%s txp %s rxp %s\n",
- lnet_msgtyp2str(msg->msg_type), libcfs_id2str(msg->msg_target),
- msg->msg_target_is_router ? "t" : "",
- msg->msg_routing ? "X" : "",
- msg->msg_ack ? "A" : "",
- msg->msg_sending ? "S" : "",
- msg->msg_receiving ? "R" : "",
- msg->msg_delayed ? "d" : "",
- msg->msg_txcredit ? "C" : "",
- msg->msg_peertxcredit ? "c" : "",
- msg->msg_rtrcredit ? "F" : "",
- msg->msg_peerrtrcredit ? "f" : "",
- msg->msg_onactivelist ? "!" : "",
- !msg->msg_txpeer ? "<none>" : libcfs_nid2str(msg->msg_txpeer->lp_nid),
- !msg->msg_rxpeer ? "<none>" : libcfs_nid2str(msg->msg_rxpeer->lp_nid));
-#endif
+
msg->msg_ev.status = status;
if (msg->msg_md) {
diff --git a/drivers/staging/lustre/lnet/lnet/lib-socket.c b/drivers/staging/lustre/lnet/lnet/lib-socket.c
index 891fd59401d7..4e6dd5149b4f 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-socket.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-socket.c
@@ -265,21 +265,17 @@ lnet_sock_write(struct socket *sock, void *buffer, int nob, int timeout)
long jiffies_left = timeout * msecs_to_jiffies(MSEC_PER_SEC);
unsigned long then;
struct timeval tv;
+ struct kvec iov = { .iov_base = buffer, .iov_len = nob };
+ struct msghdr msg = {NULL,};
LASSERT(nob > 0);
/*
* Caller may pass a zero timeout if she thinks the socket buffer is
* empty enough to take the whole message immediately
*/
+ iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &iov, 1, nob);
for (;;) {
- struct kvec iov = {
- .iov_base = buffer,
- .iov_len = nob
- };
- struct msghdr msg = {
- .msg_flags = !timeout ? MSG_DONTWAIT : 0
- };
-
+ msg.msg_flags = !timeout ? MSG_DONTWAIT : 0;
if (timeout) {
/* Set send timeout to remaining time */
jiffies_to_timeval(jiffies_left, &tv);
@@ -296,9 +292,6 @@ lnet_sock_write(struct socket *sock, void *buffer, int nob, int timeout)
rc = kernel_sendmsg(sock, &msg, &iov, 1, nob);
jiffies_left -= jiffies - then;
- if (rc == nob)
- return 0;
-
if (rc < 0)
return rc;
@@ -307,11 +300,11 @@ lnet_sock_write(struct socket *sock, void *buffer, int nob, int timeout)
return -ECONNABORTED;
}
+ if (!msg_data_left(&msg))
+ break;
+
if (jiffies_left <= 0)
return -EAGAIN;
-
- buffer = ((char *)buffer) + rc;
- nob -= rc;
}
return 0;
}
diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c
index 08402712a452..cb213b8f51cf 100644
--- a/drivers/staging/lustre/lnet/lnet/lo.c
+++ b/drivers/staging/lustre/lnet/lnet/lo.c
@@ -42,36 +42,23 @@ lolnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
static int
lolnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg,
- int delayed, unsigned int niov,
- struct kvec *iov, lnet_kiov_t *kiov,
- unsigned int offset, unsigned int mlen, unsigned int rlen)
+ int delayed, struct iov_iter *to, unsigned int rlen)
{
lnet_msg_t *sendmsg = private;
if (lntmsg) { /* not discarding */
- if (sendmsg->msg_iov) {
- if (iov)
- lnet_copy_iov2iov(niov, iov, offset,
- sendmsg->msg_niov,
- sendmsg->msg_iov,
- sendmsg->msg_offset, mlen);
- else
- lnet_copy_iov2kiov(niov, kiov, offset,
- sendmsg->msg_niov,
- sendmsg->msg_iov,
- sendmsg->msg_offset, mlen);
- } else {
- if (iov)
- lnet_copy_kiov2iov(niov, iov, offset,
- sendmsg->msg_niov,
- sendmsg->msg_kiov,
- sendmsg->msg_offset, mlen);
- else
- lnet_copy_kiov2kiov(niov, kiov, offset,
- sendmsg->msg_niov,
- sendmsg->msg_kiov,
- sendmsg->msg_offset, mlen);
- }
+ if (sendmsg->msg_iov)
+ lnet_copy_iov2iter(to,
+ sendmsg->msg_niov,
+ sendmsg->msg_iov,
+ sendmsg->msg_offset,
+ iov_iter_count(to));
+ else
+ lnet_copy_kiov2iter(to,
+ sendmsg->msg_niov,
+ sendmsg->msg_kiov,
+ sendmsg->msg_offset,
+ iov_iter_count(to));
lnet_finalize(ni, lntmsg, 0);
}
diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c
index 063543233035..063ad55ec950 100644
--- a/drivers/staging/lustre/lnet/lnet/router.c
+++ b/drivers/staging/lustre/lnet/lnet/router.c
@@ -1307,7 +1307,7 @@ lnet_destroy_rtrbuf(lnet_rtrbuf_t *rb, int npages)
int sz = offsetof(lnet_rtrbuf_t, rb_kiov[npages]);
while (--npages >= 0)
- __free_page(rb->rb_kiov[npages].kiov_page);
+ __free_page(rb->rb_kiov[npages].bv_page);
LIBCFS_FREE(rb, sz);
}
@@ -1333,15 +1333,15 @@ lnet_new_rtrbuf(lnet_rtrbufpool_t *rbp, int cpt)
GFP_KERNEL | __GFP_ZERO, 0);
if (!page) {
while (--i >= 0)
- __free_page(rb->rb_kiov[i].kiov_page);
+ __free_page(rb->rb_kiov[i].bv_page);
LIBCFS_FREE(rb, sz);
return NULL;
}
- rb->rb_kiov[i].kiov_len = PAGE_SIZE;
- rb->rb_kiov[i].kiov_offset = 0;
- rb->rb_kiov[i].kiov_page = page;
+ rb->rb_kiov[i].bv_len = PAGE_SIZE;
+ rb->rb_kiov[i].bv_offset = 0;
+ rb->rb_kiov[i].bv_page = page;
}
return rb;
@@ -1693,7 +1693,7 @@ lnet_rtrpools_adjust(int tiny, int small, int large)
int
lnet_rtrpools_enable(void)
{
- int rc;
+ int rc = 0;
if (the_lnet.ln_routing)
return 0;
@@ -1706,9 +1706,9 @@ lnet_rtrpools_enable(void)
* if we are just configuring this for the first
* time.
*/
- return lnet_rtrpools_alloc(1);
-
- rc = lnet_rtrpools_adjust_helper(0, 0, 0);
+ rc = lnet_rtrpools_alloc(1);
+ else
+ rc = lnet_rtrpools_adjust_helper(0, 0, 0);
if (rc)
return rc;
@@ -1718,7 +1718,7 @@ lnet_rtrpools_enable(void)
the_lnet.ln_ping_info->pi_features &= ~LNET_PING_FEAT_RTE_DISABLED;
lnet_net_unlock(LNET_LOCK_EX);
- return 0;
+ return rc;
}
void
diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c
index 13d0454e7fcb..b20c5d394e3b 100644
--- a/drivers/staging/lustre/lnet/selftest/brw_test.c
+++ b/drivers/staging/lustre/lnet/selftest/brw_test.c
@@ -226,7 +226,7 @@ brw_fill_bulk(struct srpc_bulk *bk, int pattern, __u64 magic)
struct page *pg;
for (i = 0; i < bk->bk_niov; i++) {
- pg = bk->bk_iovs[i].kiov_page;
+ pg = bk->bk_iovs[i].bv_page;
brw_fill_page(pg, pattern, magic);
}
}
@@ -238,7 +238,7 @@ brw_check_bulk(struct srpc_bulk *bk, int pattern, __u64 magic)
struct page *pg;
for (i = 0; i < bk->bk_niov; i++) {
- pg = bk->bk_iovs[i].kiov_page;
+ pg = bk->bk_iovs[i].bv_page;
if (brw_check_page(pg, pattern, magic)) {
CERROR("Bulk page %p (%d/%d) is corrupted!\n",
pg, i, bk->bk_niov);
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c
index 1be3cad727ae..55afb53b0743 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.c
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.c
@@ -152,10 +152,10 @@ lstcon_rpc_put(struct lstcon_rpc *crpc)
LASSERT(list_empty(&crpc->crp_link));
for (i = 0; i < bulk->bk_niov; i++) {
- if (!bulk->bk_iovs[i].kiov_page)
+ if (!bulk->bk_iovs[i].bv_page)
continue;
- __free_page(bulk->bk_iovs[i].kiov_page);
+ __free_page(bulk->bk_iovs[i].bv_page);
}
srpc_client_rpc_decref(crpc->crp_rpc);
@@ -705,7 +705,7 @@ lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov)
LASSERT(i < nkiov);
- pid = (lnet_process_id_packed_t *)page_address(kiov[i].kiov_page);
+ pid = (lnet_process_id_packed_t *)page_address(kiov[i].bv_page);
return &pid[idx % SFW_ID_PER_PAGE];
}
@@ -849,12 +849,11 @@ lstcon_testrpc_prep(struct lstcon_node *nd, int transop, unsigned feats,
min_t(int, nob, PAGE_SIZE);
nob -= len;
- bulk->bk_iovs[i].kiov_offset = 0;
- bulk->bk_iovs[i].kiov_len = len;
- bulk->bk_iovs[i].kiov_page =
- alloc_page(GFP_KERNEL);
+ bulk->bk_iovs[i].bv_offset = 0;
+ bulk->bk_iovs[i].bv_len = len;
+ bulk->bk_iovs[i].bv_page = alloc_page(GFP_KERNEL);
- if (!bulk->bk_iovs[i].kiov_page) {
+ if (!bulk->bk_iovs[i].bv_page) {
lstcon_rpc_put(*crpc);
return -ENOMEM;
}
diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c
index 4c33621f06da..a0fcbf3bcc95 100644
--- a/drivers/staging/lustre/lnet/selftest/console.c
+++ b/drivers/staging/lustre/lnet/selftest/console.c
@@ -1993,8 +1993,6 @@ static void lstcon_init_acceptor_service(void)
lstcon_acceptor_service.sv_wi_total = SFW_FRWK_WI_MAX;
}
-extern int lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr);
-
static DECLARE_IOCTL_HANDLER(lstcon_ioctl_handler, lstcon_ioctl_entry);
/* initialize console */
diff --git a/drivers/staging/lustre/lnet/selftest/console.h b/drivers/staging/lustre/lnet/selftest/console.h
index 78b147732615..78388a611c22 100644
--- a/drivers/staging/lustre/lnet/selftest/console.h
+++ b/drivers/staging/lustre/lnet/selftest/console.h
@@ -184,6 +184,7 @@ lstcon_id2hash(lnet_process_id_t id, struct list_head *hash)
return &hash[idx];
}
+int lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr);
int lstcon_console_init(void);
int lstcon_console_fini(void);
int lstcon_session_match(lst_sid_t sid);
diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c
index c2f121f44d33..abbd6287b4bd 100644
--- a/drivers/staging/lustre/lnet/selftest/framework.c
+++ b/drivers/staging/lustre/lnet/selftest/framework.c
@@ -784,8 +784,8 @@ sfw_add_test_instance(struct sfw_batch *tsb, struct srpc_server_rpc *rpc)
lnet_process_id_packed_t id;
int j;
- dests = page_address(bk->bk_iovs[i / SFW_ID_PER_PAGE].kiov_page);
- LASSERT(dests); /* my pages are within KVM always */
+ dests = page_address(bk->bk_iovs[i / SFW_ID_PER_PAGE].bv_page);
+ LASSERT(dests); /* my pages are within KVM always */
id = dests[i % SFW_ID_PER_PAGE];
if (msg->msg_magic != SRPC_MSG_MAGIC)
sfw_unpack_id(id);
diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c
index 3b26d6eb4240..f5619d8744ef 100644
--- a/drivers/staging/lustre/lnet/selftest/rpc.c
+++ b/drivers/staging/lustre/lnet/selftest/rpc.c
@@ -91,9 +91,9 @@ srpc_add_bulk_page(struct srpc_bulk *bk, struct page *pg, int i, int nob)
LASSERT(nob > 0);
LASSERT(i >= 0 && i < bk->bk_niov);
- bk->bk_iovs[i].kiov_offset = 0;
- bk->bk_iovs[i].kiov_page = pg;
- bk->bk_iovs[i].kiov_len = nob;
+ bk->bk_iovs[i].bv_offset = 0;
+ bk->bk_iovs[i].bv_page = pg;
+ bk->bk_iovs[i].bv_len = nob;
return nob;
}
@@ -106,7 +106,7 @@ srpc_free_bulk(struct srpc_bulk *bk)
LASSERT(bk);
for (i = 0; i < bk->bk_niov; i++) {
- pg = bk->bk_iovs[i].kiov_page;
+ pg = bk->bk_iovs[i].bv_page;
if (!pg)
break;
diff --git a/drivers/staging/lustre/lustre/fid/fid_lib.c b/drivers/staging/lustre/lustre/fid/fid_lib.c
index 99ae7eb6720e..4e49cb356d64 100644
--- a/drivers/staging/lustre/lustre/fid/fid_lib.c
+++ b/drivers/staging/lustre/lustre/fid/fid_lib.c
@@ -63,14 +63,12 @@ const struct lu_seq_range LUSTRE_SEQ_SPACE_RANGE = {
FID_SEQ_NORMAL,
(__u64)~0ULL
};
-EXPORT_SYMBOL(LUSTRE_SEQ_SPACE_RANGE);
/* Zero range, used for init and other purposes. */
const struct lu_seq_range LUSTRE_SEQ_ZERO_RANGE = {
0,
0
};
-EXPORT_SYMBOL(LUSTRE_SEQ_ZERO_RANGE);
/* Lustre Big Fs Lock fid. */
const struct lu_fid LUSTRE_BFL_FID = { .f_seq = FID_SEQ_SPECIAL,
diff --git a/drivers/staging/lustre/lustre/fid/fid_request.c b/drivers/staging/lustre/lustre/fid/fid_request.c
index 454744d25956..edd72b926f81 100644
--- a/drivers/staging/lustre/lustre/fid/fid_request.c
+++ b/drivers/staging/lustre/lustre/fid/fid_request.c
@@ -125,19 +125,19 @@ static int seq_client_rpc(struct lu_client_seq *seq,
if (!range_is_sane(output)) {
CERROR("%s: Invalid range received from server: "
- DRANGE"\n", seq->lcs_name, PRANGE(output));
+ DRANGE "\n", seq->lcs_name, PRANGE(output));
rc = -EINVAL;
goto out_req;
}
if (range_is_exhausted(output)) {
CERROR("%s: Range received from server is exhausted: "
- DRANGE"]\n", seq->lcs_name, PRANGE(output));
+ DRANGE "]\n", seq->lcs_name, PRANGE(output));
rc = -EINVAL;
goto out_req;
}
- CDEBUG_LIMIT(debug_mask, "%s: Allocated %s-sequence "DRANGE"]\n",
+ CDEBUG_LIMIT(debug_mask, "%s: Allocated %s-sequence " DRANGE "]\n",
seq->lcs_name, opcname, PRANGE(output));
out_req:
@@ -179,7 +179,7 @@ static int seq_client_alloc_seq(const struct lu_env *env,
seq->lcs_name, rc);
return rc;
}
- CDEBUG(D_INFO, "%s: New range - "DRANGE"\n",
+ CDEBUG(D_INFO, "%s: New range - " DRANGE "\n",
seq->lcs_name, PRANGE(&seq->lcs_space));
} else {
rc = 0;
diff --git a/drivers/staging/lustre/lustre/fid/lproc_fid.c b/drivers/staging/lustre/lustre/fid/lproc_fid.c
index 81b7ca9ea2fd..3ed32d77f38b 100644
--- a/drivers/staging/lustre/lustre/fid/lproc_fid.c
+++ b/drivers/staging/lustre/lustre/fid/lproc_fid.c
@@ -105,7 +105,7 @@ ldebugfs_fid_space_seq_write(struct file *file,
rc = ldebugfs_fid_write_common(buffer, count, &seq->lcs_space);
if (rc == 0) {
- CDEBUG(D_INFO, "%s: Space: "DRANGE"\n",
+ CDEBUG(D_INFO, "%s: Space: " DRANGE "\n",
seq->lcs_name, PRANGE(&seq->lcs_space));
}
diff --git a/drivers/staging/lustre/lustre/fld/fld_internal.h b/drivers/staging/lustre/lustre/fld/fld_internal.h
index f0efe5b9fbec..08eaec735d6f 100644
--- a/drivers/staging/lustre/lustre/fld/fld_internal.h
+++ b/drivers/staging/lustre/lustre/fld/fld_internal.h
@@ -31,6 +31,25 @@
*
* lustre/fld/fld_internal.h
*
+ * Subsystem Description:
+ * FLD is FID Location Database, which stores where (IE, on which MDT)
+ * FIDs are located.
+ * The database is basically a record file, each record consists of a FID
+ * sequence range, MDT/OST index, and flags. The FLD for the whole FS
+ * is only stored on the sequence controller(MDT0) right now, but each target
+ * also has its local FLD, which only stores the local sequence.
+ *
+ * The FLD subsystem usually has two tasks:
+ * 1. maintain the database, i.e. when the sequence controller allocates
+ * new sequence ranges to some nodes, it will call the FLD API to insert the
+ * location information <sequence_range, node_index> in FLDB.
+ *
+ * 2. Handle requests from other nodes, i.e. if client needs to know where
+ * the FID is located, if it can not find the information in the local cache,
+ * it will send a FLD lookup RPC to the FLD service, and the FLD service will
+ * look up the FLDB entry and return the location information to client.
+ *
+ *
* Author: Yury Umanets <umka@clusterfs.com>
* Author: Tom WangDi <wangdi@clusterfs.com>
*/
diff --git a/drivers/staging/lustre/lustre/fld/fld_request.c b/drivers/staging/lustre/lustre/fld/fld_request.c
index e59d626a1548..0de72b717ce5 100644
--- a/drivers/staging/lustre/lustre/fld/fld_request.c
+++ b/drivers/staging/lustre/lustre/fld/fld_request.c
@@ -53,57 +53,6 @@
#include "../include/lustre_mdc.h"
#include "fld_internal.h"
-/* TODO: these 3 functions are copies of flow-control code from mdc_lib.c
- * It should be common thing. The same about mdc RPC lock
- */
-static int fld_req_avail(struct client_obd *cli, struct mdc_cache_waiter *mcw)
-{
- int rc;
-
- spin_lock(&cli->cl_loi_list_lock);
- rc = list_empty(&mcw->mcw_entry);
- spin_unlock(&cli->cl_loi_list_lock);
- return rc;
-};
-
-static void fld_enter_request(struct client_obd *cli)
-{
- struct mdc_cache_waiter mcw;
- struct l_wait_info lwi = { 0 };
-
- spin_lock(&cli->cl_loi_list_lock);
- if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) {
- list_add_tail(&mcw.mcw_entry, &cli->cl_cache_waiters);
- init_waitqueue_head(&mcw.mcw_waitq);
- spin_unlock(&cli->cl_loi_list_lock);
- l_wait_event(mcw.mcw_waitq, fld_req_avail(cli, &mcw), &lwi);
- } else {
- cli->cl_r_in_flight++;
- spin_unlock(&cli->cl_loi_list_lock);
- }
-}
-
-static void fld_exit_request(struct client_obd *cli)
-{
- struct list_head *l, *tmp;
- struct mdc_cache_waiter *mcw;
-
- spin_lock(&cli->cl_loi_list_lock);
- cli->cl_r_in_flight--;
- list_for_each_safe(l, tmp, &cli->cl_cache_waiters) {
- if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) {
- /* No free request slots anymore */
- break;
- }
-
- mcw = list_entry(l, struct mdc_cache_waiter, mcw_entry);
- list_del_init(&mcw->mcw_entry);
- cli->cl_r_in_flight++;
- wake_up(&mcw->mcw_waitq);
- }
- spin_unlock(&cli->cl_loi_list_lock);
-}
-
static int fld_rrb_hash(struct lu_client_fld *fld, u64 seq)
{
LASSERT(fld->lcf_count > 0);
@@ -270,7 +219,6 @@ int fld_client_del_target(struct lu_client_fld *fld, __u64 idx)
spin_unlock(&fld->lcf_lock);
return -ENOENT;
}
-EXPORT_SYMBOL(fld_client_del_target);
static struct dentry *fld_debugfs_dir;
@@ -439,9 +387,9 @@ int fld_client_rpc(struct obd_export *exp,
req->rq_reply_portal = MDC_REPLY_PORTAL;
ptlrpc_at_set_req_timeout(req);
- fld_enter_request(&exp->exp_obd->u.cli);
+ obd_get_request_slot(&exp->exp_obd->u.cli);
rc = ptlrpc_queue_wait(req);
- fld_exit_request(&exp->exp_obd->u.cli);
+ obd_put_request_slot(&exp->exp_obd->u.cli);
if (rc)
goto out_req;
@@ -505,7 +453,6 @@ void fld_client_flush(struct lu_client_fld *fld)
{
fld_cache_flush(fld->lcf_cache);
}
-EXPORT_SYMBOL(fld_client_flush);
static int __init fld_init(void)
{
diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
index 3cd4a2577d90..89292c93dcd5 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -93,8 +93,8 @@
* super-class definitions.
*/
#include "lu_object.h"
+#include "lustre_compat.h"
#include <linux/atomic.h>
-#include "linux/lustre_compat25.h"
#include <linux/mutex.h>
#include <linux/radix-tree.h>
#include <linux/spinlock.h>
@@ -191,6 +191,9 @@ struct cl_attr {
* Group identifier for quota purposes.
*/
gid_t cat_gid;
+
+ /* nlink of the directory */
+ __u64 cat_nlink;
};
/**
@@ -320,7 +323,7 @@ struct cl_object_operations {
* to be used instead of newly created.
*/
int (*coo_page_init)(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, pgoff_t index);
+ struct cl_page *page, pgoff_t index);
/**
* Initialize lock slice for this layer. Called top-to-bottom through
* every object layer when a new cl_lock is instantiated. Layer
@@ -366,8 +369,8 @@ struct cl_object_operations {
* \return the same convention as for
* cl_object_operations::coo_attr_get() is used.
*/
- int (*coo_attr_set)(const struct lu_env *env, struct cl_object *obj,
- const struct cl_attr *attr, unsigned valid);
+ int (*coo_attr_update)(const struct lu_env *env, struct cl_object *obj,
+ const struct cl_attr *attr, unsigned int valid);
/**
* Update object configuration. Called top-to-bottom to modify object
* configuration.
@@ -392,6 +395,11 @@ struct cl_object_operations {
* mainly pages and locks.
*/
int (*coo_prune)(const struct lu_env *env, struct cl_object *obj);
+ /**
+ * Object getstripe method.
+ */
+ int (*coo_getstripe)(const struct lu_env *env, struct cl_object *obj,
+ struct lov_user_md __user *lum);
};
/**
@@ -687,17 +695,6 @@ enum cl_page_type {
};
/**
- * Flags maintained for every cl_page.
- */
-enum cl_page_flags {
- /**
- * Set when pagein completes. Used for debugging (read completes at
- * most once for a page).
- */
- CPF_READ_COMPLETED = 1 << 0
-};
-
-/**
* Fields are protected by the lock on struct page, except for atomics and
* immutables.
*
@@ -711,24 +708,19 @@ struct cl_page {
atomic_t cp_ref;
/** An object this page is a part of. Immutable after creation. */
struct cl_object *cp_obj;
- /** List of slices. Immutable after creation. */
- struct list_head cp_layers;
/** vmpage */
struct page *cp_vmpage;
+ /** Linkage of pages within group. Pages must be owned */
+ struct list_head cp_batch;
+ /** List of slices. Immutable after creation. */
+ struct list_head cp_layers;
+ /** Linkage of pages within cl_req. */
+ struct list_head cp_flight;
/**
* Page state. This field is const to avoid accidental update, it is
* modified only internally within cl_page.c. Protected by a VM lock.
*/
const enum cl_page_state cp_state;
- /** Linkage of pages within group. Protected by cl_page::cp_mutex. */
- struct list_head cp_batch;
- /** Mutex serializing membership of a page in a batch. */
- struct mutex cp_mutex;
- /** Linkage of pages within cl_req. */
- struct list_head cp_flight;
- /** Transfer error. */
- int cp_error;
-
/**
* Page type. Only CPT_TRANSIENT is used so far. Immutable after
* creation.
@@ -741,10 +733,6 @@ struct cl_page {
*/
struct cl_io *cp_owner;
/**
- * Debug information, the task is owning the page.
- */
- struct task_struct *cp_task;
- /**
* Owning IO request in cl_page_state::CPS_PAGEOUT and
* cl_page_state::CPS_PAGEIN states. This field is maintained only in
* the top-level pages. Protected by a VM lock.
@@ -756,8 +744,6 @@ struct cl_page {
struct lu_ref_link cp_obj_ref;
/** Link to a queue, for debugging. */
struct lu_ref_link cp_queue_ref;
- /** Per-page flags from enum cl_page_flags. Protected by a VM lock. */
- unsigned cp_flags;
/** Assigned if doing a sync_io */
struct cl_sync_io *cp_sync_io;
};
@@ -1056,23 +1042,32 @@ do { \
} \
} while (0)
-static inline int __page_in_use(const struct cl_page *page, int refc)
-{
- if (page->cp_type == CPT_CACHEABLE)
- ++refc;
- LASSERT(atomic_read(&page->cp_ref) > 0);
- return (atomic_read(&page->cp_ref) > refc);
-}
-
-#define cl_page_in_use(pg) __page_in_use(pg, 1)
-#define cl_page_in_use_noref(pg) __page_in_use(pg, 0)
-
static inline struct page *cl_page_vmpage(struct cl_page *page)
{
LASSERT(page->cp_vmpage);
return page->cp_vmpage;
}
+/**
+ * Check if a cl_page is in use.
+ *
+ * Client cache holds a refcount, this refcount will be dropped when
+ * the page is taken out of cache, see vvp_page_delete().
+ */
+static inline bool __page_in_use(const struct cl_page *page, int refc)
+{
+ return (atomic_read(&page->cp_ref) > refc + 1);
+}
+
+/**
+ * Caller itself holds a refcount of cl_page.
+ */
+#define cl_page_in_use(pg) __page_in_use(pg, 1)
+/**
+ * Caller doesn't hold a refcount.
+ */
+#define cl_page_in_use_noref(pg) __page_in_use(pg, 0)
+
/** @} cl_page */
/** \addtogroup cl_lock cl_lock
@@ -1771,12 +1766,14 @@ struct cl_io {
struct cl_setattr_io {
struct ost_lvb sa_attr;
unsigned int sa_valid;
+ int sa_stripe_index;
+ struct lu_fid *sa_parent_fid;
} ci_setattr;
struct cl_fault_io {
/** page index within file. */
pgoff_t ft_index;
/** bytes valid byte on a faulted page. */
- int ft_nob;
+ size_t ft_nob;
/** writable page? for nopage() only */
int ft_writable;
/** page of an executable? */
@@ -1909,7 +1906,7 @@ struct cl_req_attr {
/** Generic attributes for the server consumption. */
struct obdo *cra_oa;
/** Jobid */
- char cra_jobid[JOBSTATS_JOBID_SIZE];
+ char cra_jobid[LUSTRE_JOBID_SIZE];
};
/**
@@ -2176,14 +2173,16 @@ void cl_object_attr_lock(struct cl_object *o);
void cl_object_attr_unlock(struct cl_object *o);
int cl_object_attr_get(const struct lu_env *env, struct cl_object *obj,
struct cl_attr *attr);
-int cl_object_attr_set(const struct lu_env *env, struct cl_object *obj,
- const struct cl_attr *attr, unsigned valid);
+int cl_object_attr_update(const struct lu_env *env, struct cl_object *obj,
+ const struct cl_attr *attr, unsigned int valid);
int cl_object_glimpse(const struct lu_env *env, struct cl_object *obj,
struct ost_lvb *lvb);
int cl_conf_set(const struct lu_env *env, struct cl_object *obj,
const struct cl_object_conf *conf);
int cl_object_prune(const struct lu_env *env, struct cl_object *obj);
void cl_object_kill(const struct lu_env *env, struct cl_object *obj);
+int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
+ struct lov_user_md __user *lum);
/**
* Returns true, iff \a o0 and \a o1 are slices of the same object.
@@ -2197,6 +2196,7 @@ static inline void cl_object_page_init(struct cl_object *clob, int size)
{
clob->co_slice_off = cl_object_header(clob)->coh_page_bufsize;
cl_object_header(clob)->coh_page_bufsize += cfs_size_round(size);
+ WARN_ON(cl_object_header(clob)->coh_page_bufsize > 512);
}
static inline void *cl_object_page_slice(struct cl_object *clob,
@@ -2263,6 +2263,8 @@ void cl_page_unassume(const struct lu_env *env,
struct cl_io *io, struct cl_page *pg);
void cl_page_disown(const struct lu_env *env,
struct cl_io *io, struct cl_page *page);
+void cl_page_disown0(const struct lu_env *env,
+ struct cl_io *io, struct cl_page *pg);
int cl_page_is_owned(const struct cl_page *pg, const struct cl_io *io);
/** @} ownership */
@@ -2304,7 +2306,7 @@ int cl_page_is_under_lock(const struct lu_env *env, struct cl_io *io,
struct cl_page *page, pgoff_t *max_index);
loff_t cl_offset(const struct cl_object *obj, pgoff_t idx);
pgoff_t cl_index(const struct cl_object *obj, loff_t offset);
-int cl_page_size(const struct cl_object *obj);
+size_t cl_page_size(const struct cl_object *obj);
int cl_pages_prune(const struct lu_env *env, struct cl_object *obj);
void cl_lock_print(const struct lu_env *env, void *cookie,
@@ -2333,7 +2335,7 @@ struct cl_client_cache {
/**
* # of LRU entries available
*/
- atomic_t ccc_lru_left;
+ atomic_long_t ccc_lru_left;
/**
* List of entities(OSCs) for this LRU cache
*/
@@ -2347,14 +2349,18 @@ struct cl_client_cache {
*/
spinlock_t ccc_lru_lock;
/**
+ * Set if unstable check is enabled
+ */
+ unsigned int ccc_unstable_check:1;
+ /**
* # of unstable pages for this mount point
*/
- atomic_t ccc_unstable_nr;
+ atomic_long_t ccc_unstable_nr;
/**
* Waitq for awaiting unstable pages to reach zero.
* Used at umounting time and signaled on BRW commit
*/
- wait_queue_head_t ccc_unstable_waitq;
+ wait_queue_head_t ccc_unstable_waitq;
};
diff --git a/drivers/staging/lustre/lustre/include/interval_tree.h b/drivers/staging/lustre/lustre/include/interval_tree.h
index 4a15228b5570..5d387d372547 100644
--- a/drivers/staging/lustre/lustre/include/interval_tree.h
+++ b/drivers/staging/lustre/lustre/include/interval_tree.h
@@ -63,6 +63,11 @@ static inline int interval_is_intree(struct interval_node *node)
return node->in_intree == 1;
}
+static inline __u64 interval_low(struct interval_node *node)
+{
+ return node->in_extent.start;
+}
+
static inline __u64 interval_high(struct interval_node *node)
{
return node->in_extent.end;
@@ -77,8 +82,29 @@ static inline void interval_set(struct interval_node *node,
node->in_max_high = end;
}
+/*
+ * Rules to write an interval callback.
+ * - the callback returns INTERVAL_ITER_STOP when it thinks the iteration
+ * should be stopped. It will then cause the iteration function to return
+ * immediately with return value INTERVAL_ITER_STOP.
+ * - callbacks for interval_iterate and interval_iterate_reverse: Every
+ * nodes in the tree will be set to @node before the callback being called
+ * - callback for interval_search: Only overlapped node will be set to @node
+ * before the callback being called.
+ */
+typedef enum interval_iter (*interval_callback_t)(struct interval_node *node,
+ void *args);
+
struct interval_node *interval_insert(struct interval_node *node,
struct interval_node **root);
void interval_erase(struct interval_node *node, struct interval_node **root);
+/*
+ * Search the extents in the tree and call @func for each overlapped
+ * extents.
+ */
+enum interval_iter interval_search(struct interval_node *root,
+ struct interval_node_extent *ex,
+ interval_callback_t func, void *data);
+
#endif
diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_lite.h b/drivers/staging/lustre/lustre/include/linux/lustre_lite.h
deleted file mode 100644
index d18e8a76bb25..000000000000
--- a/drivers/staging/lustre/lustre/include/linux/lustre_lite.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef _LINUX_LL_H
-#define _LINUX_LL_H
-
-#ifndef _LL_H
-#error Do not #include this file directly. #include <lustre_lite.h> instead
-#endif
-
-#include <linux/statfs.h>
-
-#include <linux/fs.h>
-#include <linux/dcache.h>
-
-#include "../obd_class.h"
-#include "../lustre_net.h"
-#include "../lustre_ha.h"
-
-#include <linux/rbtree.h>
-#include "../../include/linux/lustre_compat25.h"
-#include <linux/pagemap.h>
-
-/* lprocfs.c */
-enum {
- LPROC_LL_DIRTY_HITS = 0,
- LPROC_LL_DIRTY_MISSES,
- LPROC_LL_READ_BYTES,
- LPROC_LL_WRITE_BYTES,
- LPROC_LL_BRW_READ,
- LPROC_LL_BRW_WRITE,
- LPROC_LL_OSC_READ,
- LPROC_LL_OSC_WRITE,
- LPROC_LL_IOCTL,
- LPROC_LL_OPEN,
- LPROC_LL_RELEASE,
- LPROC_LL_MAP,
- LPROC_LL_LLSEEK,
- LPROC_LL_FSYNC,
- LPROC_LL_READDIR,
- LPROC_LL_SETATTR,
- LPROC_LL_TRUNC,
- LPROC_LL_FLOCK,
- LPROC_LL_GETATTR,
- LPROC_LL_CREATE,
- LPROC_LL_LINK,
- LPROC_LL_UNLINK,
- LPROC_LL_SYMLINK,
- LPROC_LL_MKDIR,
- LPROC_LL_RMDIR,
- LPROC_LL_MKNOD,
- LPROC_LL_RENAME,
- LPROC_LL_STAFS,
- LPROC_LL_ALLOC_INODE,
- LPROC_LL_SETXATTR,
- LPROC_LL_GETXATTR,
- LPROC_LL_GETXATTR_HITS,
- LPROC_LL_LISTXATTR,
- LPROC_LL_REMOVEXATTR,
- LPROC_LL_INODE_PERM,
- LPROC_LL_FILE_OPCODES
-};
-
-#endif
diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_user.h b/drivers/staging/lustre/lustre/include/linux/lustre_user.h
deleted file mode 100644
index e967950e8536..000000000000
--- a/drivers/staging/lustre/lustre/include/linux/lustre_user.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * lustre/include/linux/lustre_user.h
- *
- * Lustre public user-space interface definitions.
- */
-
-#ifndef _LINUX_LUSTRE_USER_H
-#define _LINUX_LUSTRE_USER_H
-
-# include <linux/quota.h>
-
-/*
- * asm-x86_64/processor.h on some SLES 9 distros seems to use
- * kernel-only typedefs. fortunately skipping it altogether is ok
- * (for now).
- */
-#define __ASM_X86_64_PROCESSOR_H
-
-#include <linux/string.h>
-
-/*
- * We need to always use 64bit version because the structure
- * is shared across entire cluster where 32bit and 64bit machines
- * are co-existing.
- */
-#if __BITS_PER_LONG != 64 || defined(__ARCH_WANT_STAT64)
-typedef struct stat64 lstat_t;
-#define lstat_f lstat64
-#else
-typedef struct stat lstat_t;
-#define lstat_f lstat
-#endif
-
-#define HAVE_LOV_USER_MDS_DATA
-
-#endif /* _LUSTRE_USER_H */
diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h
index d68e60e7fef7..cc0713ef8ae5 100644
--- a/drivers/staging/lustre/lustre/include/lprocfs_status.h
+++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h
@@ -165,8 +165,10 @@ struct lprocfs_percpu {
struct lprocfs_counter lp_cntr[0];
};
-#define LPROCFS_GET_NUM_CPU 0x0001
-#define LPROCFS_GET_SMP_ID 0x0002
+enum lprocfs_stats_lock_ops {
+ LPROCFS_GET_NUM_CPU = 0x0001, /* number allocated per-CPU stats */
+ LPROCFS_GET_SMP_ID = 0x0002, /* current stat to be updated */
+};
enum lprocfs_stats_flags {
LPROCFS_STATS_FLAG_NONE = 0x0000, /* per cpu counter */
@@ -363,82 +365,99 @@ static inline void s2dhms(struct dhms *ts, time64_t secs64)
#define JOBSTATS_PROCNAME_UID "procname_uid"
#define JOBSTATS_NODELOCAL "nodelocal"
+/* obd_config.c */
+void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg));
+
int lprocfs_write_frac_helper(const char __user *buffer,
unsigned long count, int *val, int mult);
int lprocfs_read_frac_helper(char *buffer, unsigned long count,
long val, int mult);
int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, unsigned int cpuid);
-/*
- * \return value
- * < 0 : on error (only possible for opc as LPROCFS_GET_SMP_ID)
+
+/**
+ * Lock statistics structure for access, possibly only on this CPU.
+ *
+ * The statistics struct may be allocated with per-CPU structures for
+ * efficient concurrent update (usually only on server-wide stats), or
+ * as a single global struct (e.g. for per-client or per-job statistics),
+ * so the required locking depends on the type of structure allocated.
+ *
+ * For per-CPU statistics, pin the thread to the current cpuid so that
+ * will only access the statistics for that CPU. If the stats structure
+ * for the current CPU has not been allocated (or previously freed),
+ * allocate it now. The per-CPU statistics do not need locking since
+ * the thread is pinned to the CPU during update.
+ *
+ * For global statistics, lock the stats structure to prevent concurrent update.
+ *
+ * \param[in] stats statistics structure to lock
+ * \param[in] opc type of operation:
+ * LPROCFS_GET_SMP_ID: "lock" and return current CPU index
+ * for incrementing statistics for that CPU
+ * LPROCFS_GET_NUM_CPU: "lock" and return number of used
+ * CPU indices to iterate over all indices
+ * \param[out] flags CPU interrupt saved state for IRQ-safe locking
+ *
+ * \retval cpuid of current thread or number of allocated structs
+ * \retval negative on error (only for opc LPROCFS_GET_SMP_ID + per-CPU stats)
*/
-static inline int lprocfs_stats_lock(struct lprocfs_stats *stats, int opc,
+static inline int lprocfs_stats_lock(struct lprocfs_stats *stats,
+ enum lprocfs_stats_lock_ops opc,
unsigned long *flags)
{
- int rc = 0;
+ if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
+ if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
+ spin_lock_irqsave(&stats->ls_lock, *flags);
+ else
+ spin_lock(&stats->ls_lock);
+ return opc == LPROCFS_GET_NUM_CPU ? 1 : 0;
+ }
switch (opc) {
- default:
- LBUG();
+ case LPROCFS_GET_SMP_ID: {
+ unsigned int cpuid = get_cpu();
- case LPROCFS_GET_SMP_ID:
- if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
- if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
- spin_lock_irqsave(&stats->ls_lock, *flags);
- else
- spin_lock(&stats->ls_lock);
- return 0;
- } else {
- unsigned int cpuid = get_cpu();
-
- if (unlikely(!stats->ls_percpu[cpuid])) {
- rc = lprocfs_stats_alloc_one(stats, cpuid);
- if (rc < 0) {
- put_cpu();
- return rc;
- }
+ if (unlikely(!stats->ls_percpu[cpuid])) {
+ int rc = lprocfs_stats_alloc_one(stats, cpuid);
+
+ if (rc < 0) {
+ put_cpu();
+ return rc;
}
- return cpuid;
}
-
+ return cpuid;
+ }
case LPROCFS_GET_NUM_CPU:
- if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
- if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
- spin_lock_irqsave(&stats->ls_lock, *flags);
- else
- spin_lock(&stats->ls_lock);
- return 1;
- }
return stats->ls_biggest_alloc_num;
+ default:
+ LBUG();
}
}
-static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats, int opc,
+/**
+ * Unlock statistics structure after access.
+ *
+ * Unlock the lock acquired via lprocfs_stats_lock() for global statistics,
+ * or unpin this thread from the current cpuid for per-CPU statistics.
+ *
+ * This function must be called using the same arguments as used when calling
+ * lprocfs_stats_lock() so that the correct operation can be performed.
+ *
+ * \param[in] stats statistics structure to unlock
+ * \param[in] opc type of operation (current cpuid or number of structs)
+ * \param[in] flags CPU interrupt saved state for IRQ-safe locking
+ */
+static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats,
+ enum lprocfs_stats_lock_ops opc,
unsigned long *flags)
{
- switch (opc) {
- default:
- LBUG();
-
- case LPROCFS_GET_SMP_ID:
- if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
- if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
- spin_unlock_irqrestore(&stats->ls_lock, *flags);
- else
- spin_unlock(&stats->ls_lock);
- } else {
- put_cpu();
- }
- return;
-
- case LPROCFS_GET_NUM_CPU:
- if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
- if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
- spin_unlock_irqrestore(&stats->ls_lock, *flags);
- else
- spin_unlock(&stats->ls_lock);
- }
- return;
+ if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
+ if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
+ spin_unlock_irqrestore(&stats->ls_lock, *flags);
+ else
+ spin_unlock(&stats->ls_lock);
+ } else if (opc == LPROCFS_GET_SMP_ID) {
+ put_cpu();
}
}
@@ -496,7 +515,7 @@ static inline __u64 lprocfs_stats_collector(struct lprocfs_stats *stats,
int idx,
enum lprocfs_fields_flags field)
{
- int i;
+ unsigned int i;
unsigned int num_cpu;
unsigned long flags = 0;
__u64 ret = 0;
@@ -681,6 +700,12 @@ static struct lustre_attr lustre_attr_##name = __ATTR(name, mode, show, store)
extern const struct sysfs_ops lustre_sysfs_ops;
+struct root_squash_info;
+int lprocfs_wr_root_squash(const char *buffer, unsigned long count,
+ struct root_squash_info *squash, char *name);
+int lprocfs_wr_nosquash_nids(const char *buffer, unsigned long count,
+ struct root_squash_info *squash, char *name);
+
/* all quota proc functions */
int lprocfs_quota_rd_bunit(char *page, char **start,
loff_t off, int count,
diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h
index 6e25c1bb6aa3..260643ee0d48 100644
--- a/drivers/staging/lustre/lustre/include/lu_object.h
+++ b/drivers/staging/lustre/lustre/include/lu_object.h
@@ -327,7 +327,7 @@ struct lu_device_type {
/**
* Number of existing device type instances.
*/
- unsigned ldt_device_nr;
+ atomic_t ldt_device_nr;
/**
* Linkage into a global list of all device types.
*
@@ -602,7 +602,7 @@ struct lu_site {
/**
* index of bucket on hash table while purging
*/
- int ls_purge_start;
+ unsigned int ls_purge_start;
/**
* Top-level device for this stack.
*/
@@ -623,6 +623,11 @@ struct lu_site {
spinlock_t ls_ld_lock;
/**
+ * Lock to serialize site purge.
+ */
+ struct mutex ls_purge_mutex;
+
+ /**
* lu_site stats
*/
struct lprocfs_stats *ls_stats;
@@ -673,7 +678,6 @@ void lu_object_add(struct lu_object *before, struct lu_object *o);
int lu_device_type_init(struct lu_device_type *ldt);
void lu_device_type_fini(struct lu_device_type *ldt);
-void lu_types_stop(void);
/** @} ctors */
@@ -1025,7 +1029,8 @@ enum lu_context_tag {
/**
* Contexts usable in cache shrinker thread.
*/
- LCT_SHRINKER = LCT_MD_THREAD|LCT_DT_THREAD|LCT_CL_THREAD|LCT_NOREF
+ LCT_SHRINKER = LCT_MD_THREAD | LCT_DT_THREAD | LCT_CL_THREAD |
+ LCT_NOREF
};
/**
@@ -1264,12 +1269,28 @@ struct lu_name {
};
/**
+ * Validate names (path components)
+ *
+ * To be valid \a name must be non-empty, '\0' terminated of length \a
+ * name_len, and not contain '/'. The maximum length of a name (before
+ * say -ENAMETOOLONG will be returned) is really controlled by llite
+ * and the server. We only check for something insane coming from bad
+ * integer handling here.
+ */
+static inline bool lu_name_is_valid_2(const char *name, size_t name_len)
+{
+ return name && name_len > 0 && name_len < INT_MAX &&
+ name[name_len] == '\0' && strlen(name) == name_len &&
+ !memchr(name, '/', name_len);
+}
+
+/**
* Common buffer structure to be passed around for various xattr_{s,g}et()
* methods.
*/
struct lu_buf {
void *lb_buf;
- ssize_t lb_len;
+ size_t lb_len;
};
#define DLUBUF "(%p %zu)"
@@ -1298,5 +1319,12 @@ struct lu_kmem_descr {
int lu_kmem_init(struct lu_kmem_descr *caches);
void lu_kmem_fini(struct lu_kmem_descr *caches);
+void lu_buf_free(struct lu_buf *buf);
+void lu_buf_alloc(struct lu_buf *buf, size_t size);
+void lu_buf_realloc(struct lu_buf *buf, size_t size);
+
+int lu_buf_check_and_grow(struct lu_buf *buf, size_t len);
+struct lu_buf *lu_buf_check_and_alloc(struct lu_buf *buf, size_t len);
+
/** @} lu */
#endif /* __LUSTRE_LU_OBJECT_H */
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
index 051864c23b5b..72eaee95c6b8 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
+++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
@@ -93,6 +93,7 @@
/* Defn's shared with user-space. */
#include "lustre_user.h"
#include "lustre_errno.h"
+#include "../lustre_ver.h"
/*
* GENERAL STUFF
@@ -196,12 +197,12 @@ static inline unsigned fld_range_type(const struct lu_seq_range *range)
return range->lsr_flags & LU_SEQ_RANGE_MASK;
}
-static inline int fld_range_is_ost(const struct lu_seq_range *range)
+static inline bool fld_range_is_ost(const struct lu_seq_range *range)
{
return fld_range_type(range) == LU_SEQ_RANGE_OST;
}
-static inline int fld_range_is_mdt(const struct lu_seq_range *range)
+static inline bool fld_range_is_mdt(const struct lu_seq_range *range)
{
return fld_range_type(range) == LU_SEQ_RANGE_MDT;
}
@@ -260,23 +261,23 @@ static inline void range_init(struct lu_seq_range *range)
* check if given seq id \a s is within given range \a r
*/
-static inline int range_within(const struct lu_seq_range *range,
- __u64 s)
+static inline bool range_within(const struct lu_seq_range *range,
+ __u64 s)
{
return s >= range->lsr_start && s < range->lsr_end;
}
-static inline int range_is_sane(const struct lu_seq_range *range)
+static inline bool range_is_sane(const struct lu_seq_range *range)
{
return (range->lsr_end >= range->lsr_start);
}
-static inline int range_is_zero(const struct lu_seq_range *range)
+static inline bool range_is_zero(const struct lu_seq_range *range)
{
return (range->lsr_start == 0 && range->lsr_end == 0);
}
-static inline int range_is_exhausted(const struct lu_seq_range *range)
+static inline bool range_is_exhausted(const struct lu_seq_range *range)
{
return range_space(range) == 0;
@@ -437,69 +438,69 @@ enum dot_lustre_oid {
FID_OID_DOT_LUSTRE_OBF = 2UL,
};
-static inline int fid_seq_is_mdt0(__u64 seq)
+static inline bool fid_seq_is_mdt0(__u64 seq)
{
return (seq == FID_SEQ_OST_MDT0);
}
-static inline int fid_seq_is_mdt(const __u64 seq)
+static inline bool fid_seq_is_mdt(__u64 seq)
{
return seq == FID_SEQ_OST_MDT0 || seq >= FID_SEQ_NORMAL;
};
-static inline int fid_seq_is_echo(__u64 seq)
+static inline bool fid_seq_is_echo(__u64 seq)
{
return (seq == FID_SEQ_ECHO);
}
-static inline int fid_is_echo(const struct lu_fid *fid)
+static inline bool fid_is_echo(const struct lu_fid *fid)
{
return fid_seq_is_echo(fid_seq(fid));
}
-static inline int fid_seq_is_llog(__u64 seq)
+static inline bool fid_seq_is_llog(__u64 seq)
{
return (seq == FID_SEQ_LLOG);
}
-static inline int fid_is_llog(const struct lu_fid *fid)
+static inline bool fid_is_llog(const struct lu_fid *fid)
{
/* file with OID == 0 is not llog but contains last oid */
return fid_seq_is_llog(fid_seq(fid)) && fid_oid(fid) > 0;
}
-static inline int fid_seq_is_rsvd(const __u64 seq)
+static inline bool fid_seq_is_rsvd(__u64 seq)
{
return (seq > FID_SEQ_OST_MDT0 && seq <= FID_SEQ_RSVD);
};
-static inline int fid_seq_is_special(const __u64 seq)
+static inline bool fid_seq_is_special(__u64 seq)
{
return seq == FID_SEQ_SPECIAL;
};
-static inline int fid_seq_is_local_file(const __u64 seq)
+static inline bool fid_seq_is_local_file(__u64 seq)
{
return seq == FID_SEQ_LOCAL_FILE ||
seq == FID_SEQ_LOCAL_NAME;
};
-static inline int fid_seq_is_root(const __u64 seq)
+static inline bool fid_seq_is_root(__u64 seq)
{
return seq == FID_SEQ_ROOT;
}
-static inline int fid_seq_is_dot(const __u64 seq)
+static inline bool fid_seq_is_dot(__u64 seq)
{
return seq == FID_SEQ_DOT_LUSTRE;
}
-static inline int fid_seq_is_default(const __u64 seq)
+static inline bool fid_seq_is_default(__u64 seq)
{
return seq == FID_SEQ_LOV_DEFAULT;
}
-static inline int fid_is_mdt0(const struct lu_fid *fid)
+static inline bool fid_is_mdt0(const struct lu_fid *fid)
{
return fid_seq_is_mdt0(fid_seq(fid));
}
@@ -516,12 +517,12 @@ static inline void lu_root_fid(struct lu_fid *fid)
* \param fid the fid to be tested.
* \return true if the fid is a igif; otherwise false.
*/
-static inline int fid_seq_is_igif(const __u64 seq)
+static inline bool fid_seq_is_igif(__u64 seq)
{
return seq >= FID_SEQ_IGIF && seq <= FID_SEQ_IGIF_MAX;
}
-static inline int fid_is_igif(const struct lu_fid *fid)
+static inline bool fid_is_igif(const struct lu_fid *fid)
{
return fid_seq_is_igif(fid_seq(fid));
}
@@ -531,27 +532,27 @@ static inline int fid_is_igif(const struct lu_fid *fid)
* \param fid the fid to be tested.
* \return true if the fid is a idif; otherwise false.
*/
-static inline int fid_seq_is_idif(const __u64 seq)
+static inline bool fid_seq_is_idif(__u64 seq)
{
return seq >= FID_SEQ_IDIF && seq <= FID_SEQ_IDIF_MAX;
}
-static inline int fid_is_idif(const struct lu_fid *fid)
+static inline bool fid_is_idif(const struct lu_fid *fid)
{
return fid_seq_is_idif(fid_seq(fid));
}
-static inline int fid_is_local_file(const struct lu_fid *fid)
+static inline bool fid_is_local_file(const struct lu_fid *fid)
{
return fid_seq_is_local_file(fid_seq(fid));
}
-static inline int fid_seq_is_norm(const __u64 seq)
+static inline bool fid_seq_is_norm(__u64 seq)
{
return (seq >= FID_SEQ_NORMAL);
}
-static inline int fid_is_norm(const struct lu_fid *fid)
+static inline bool fid_is_norm(const struct lu_fid *fid)
{
return fid_seq_is_norm(fid_seq(fid));
}
@@ -658,7 +659,7 @@ static inline void ostid_set_id(struct ost_id *oi, __u64 oid)
oi->oi_fid.f_oid = oid;
oi->oi_fid.f_ver = oid >> 48;
} else {
- if (oid > OBIF_MAX_OID) {
+ if (oid >= OBIF_MAX_OID) {
CERROR("Bad %llu to set " DOSTID "\n", oid, POSTID(oi));
return;
}
@@ -683,7 +684,7 @@ static inline int fid_set_id(struct lu_fid *fid, __u64 oid)
fid->f_oid = oid;
fid->f_ver = oid >> 48;
} else {
- if (oid > OBIF_MAX_OID) {
+ if (oid >= OBIF_MAX_OID) {
CERROR("Too large OID %#llx to set REG "DFID"\n",
(unsigned long long)oid, PFID(fid));
return -EBADF;
@@ -769,7 +770,7 @@ static inline int fid_to_ostid(const struct lu_fid *fid, struct ost_id *ostid)
}
/* Check whether the fid is for LAST_ID */
-static inline int fid_is_last_id(const struct lu_fid *fid)
+static inline bool fid_is_last_id(const struct lu_fid *fid)
{
return (fid_oid(fid) == 0);
}
@@ -838,7 +839,7 @@ static inline void fid_be_to_cpu(struct lu_fid *dst, const struct lu_fid *src)
dst->f_ver = be32_to_cpu(fid_ver(src));
}
-static inline int fid_is_sane(const struct lu_fid *fid)
+static inline bool fid_is_sane(const struct lu_fid *fid)
{
return fid &&
((fid_seq(fid) >= FID_SEQ_START && fid_ver(fid) == 0) ||
@@ -846,15 +847,10 @@ static inline int fid_is_sane(const struct lu_fid *fid)
fid_seq_is_rsvd(fid_seq(fid)));
}
-static inline int fid_is_zero(const struct lu_fid *fid)
-{
- return fid_seq(fid) == 0 && fid_oid(fid) == 0;
-}
-
void lustre_swab_lu_fid(struct lu_fid *fid);
void lustre_swab_lu_seq_range(struct lu_seq_range *range);
-static inline int lu_fid_eq(const struct lu_fid *f0, const struct lu_fid *f1)
+static inline bool lu_fid_eq(const struct lu_fid *f0, const struct lu_fid *f1)
{
return memcmp(f0, f1, sizeof(*f0)) == 0;
}
@@ -1017,12 +1013,12 @@ static inline struct lu_dirent *lu_dirent_next(struct lu_dirent *ent)
return next;
}
-static inline int lu_dirent_calc_size(int namelen, __u16 attr)
+static inline size_t lu_dirent_calc_size(size_t namelen, __u16 attr)
{
- int size;
+ size_t size;
if (attr & LUDA_TYPE) {
- const unsigned align = sizeof(struct luda_type) - 1;
+ const size_t align = sizeof(struct luda_type) - 1;
size = (sizeof(struct lu_dirent) + namelen + align) & ~align;
size += sizeof(struct luda_type);
@@ -1033,15 +1029,6 @@ static inline int lu_dirent_calc_size(int namelen, __u16 attr)
return (size + 7) & ~7;
}
-static inline int lu_dirent_size(struct lu_dirent *ent)
-{
- if (le16_to_cpu(ent->lde_reclen) == 0) {
- return lu_dirent_calc_size(le16_to_cpu(ent->lde_namelen),
- le32_to_cpu(ent->lde_attrs));
- }
- return le16_to_cpu(ent->lde_reclen);
-}
-
#define MDS_DIR_END_OFF 0xfffffffffffffffeULL
/**
@@ -1067,19 +1054,19 @@ struct lustre_handle {
#define DEAD_HANDLE_MAGIC 0xdeadbeefcafebabeULL
-static inline int lustre_handle_is_used(struct lustre_handle *lh)
+static inline bool lustre_handle_is_used(const struct lustre_handle *lh)
{
return lh->cookie != 0ull;
}
-static inline int lustre_handle_equal(const struct lustre_handle *lh1,
- const struct lustre_handle *lh2)
+static inline bool lustre_handle_equal(const struct lustre_handle *lh1,
+ const struct lustre_handle *lh2)
{
return lh1->cookie == lh2->cookie;
}
static inline void lustre_handle_copy(struct lustre_handle *tgt,
- struct lustre_handle *src)
+ const struct lustre_handle *src)
{
tgt->cookie = src->cookie;
}
@@ -1105,7 +1092,7 @@ struct lustre_msg_v2 {
/* without gss, ptlrpc_body is put at the first buffer. */
#define PTLRPC_NUM_VERSIONS 4
-#define JOBSTATS_JOBID_SIZE 32 /* 32 bytes string */
+
struct ptlrpc_body_v3 {
struct lustre_handle pb_handle;
__u32 pb_type;
@@ -1127,7 +1114,7 @@ struct ptlrpc_body_v3 {
__u64 pb_pre_versions[PTLRPC_NUM_VERSIONS];
/* padding for future needs */
__u64 pb_padding[4];
- char pb_jobid[JOBSTATS_JOBID_SIZE];
+ char pb_jobid[LUSTRE_JOBID_SIZE];
};
#define ptlrpc_body ptlrpc_body_v3
@@ -1293,6 +1280,9 @@ void lustre_swab_ptlrpc_body(struct ptlrpc_body *pb);
#define OBD_CONNECT_OPEN_BY_FID 0x20000000000000ULL /* open by fid won't pack
* name in request
*/
+#define OBD_CONNECT_LFSCK 0x40000000000000ULL/* support online LFSCK */
+#define OBD_CONNECT_UNLINK_CLOSE 0x100000000000000ULL/* close file in unlink */
+#define OBD_CONNECT_DIR_STRIPE 0x400000000000000ULL/* striped DNE dir */
/* XXX README XXX:
* Please DO NOT add flag values here before first ensuring that this same
@@ -1318,14 +1308,6 @@ void lustre_swab_ptlrpc_body(struct ptlrpc_body *pb);
#define CLIENT_CONNECT_MDT_REQD (OBD_CONNECT_IBITS | OBD_CONNECT_FID | \
OBD_CONNECT_FULL20)
-#define OBD_OCD_VERSION(major, minor, patch, fix) (((major)<<24) + \
- ((minor)<<16) + \
- ((patch)<<8) + (fix))
-#define OBD_OCD_VERSION_MAJOR(version) ((int)((version)>>24)&255)
-#define OBD_OCD_VERSION_MINOR(version) ((int)((version)>>16)&255)
-#define OBD_OCD_VERSION_PATCH(version) ((int)((version)>>8)&255)
-#define OBD_OCD_VERSION_FIX(version) ((int)(version)&255)
-
/* This structure is used for both request and reply.
*
* If we eventually have separate connect data for different types, which we
@@ -1478,10 +1460,23 @@ enum obdo_flags {
OBD_FL_LOCAL_MASK = 0xF0000000,
};
-#define LOV_MAGIC_V1 0x0BD10BD0
-#define LOV_MAGIC LOV_MAGIC_V1
-#define LOV_MAGIC_JOIN_V1 0x0BD20BD0
-#define LOV_MAGIC_V3 0x0BD30BD0
+/*
+ * All LOV EA magics should have the same postfix, if some new version
+ * Lustre instroduces new LOV EA magic, then when down-grade to an old
+ * Lustre, even though the old version system does not recognizes such
+ * new magic, it still can distinguish the corrupted cases by checking
+ * the magic's postfix.
+ */
+#define LOV_MAGIC_MAGIC 0x0BD0
+#define LOV_MAGIC_MASK 0xFFFF
+
+#define LOV_MAGIC_V1 (0x0BD10000 | LOV_MAGIC_MAGIC)
+#define LOV_MAGIC_JOIN_V1 (0x0BD20000 | LOV_MAGIC_MAGIC)
+#define LOV_MAGIC_V3 (0x0BD30000 | LOV_MAGIC_MAGIC)
+#define LOV_MAGIC_MIGRATE (0x0BD40000 | LOV_MAGIC_MAGIC)
+/* reserved for specifying OSTs */
+#define LOV_MAGIC_SPECIFIC (0x0BD50000 | LOV_MAGIC_MAGIC)
+#define LOV_MAGIC LOV_MAGIC_V1
/*
* magic for fully defined striping
@@ -1498,14 +1493,6 @@ enum obdo_flags {
#define LOV_MAGIC_V1_DEF 0x0CD10BD0
#define LOV_MAGIC_V3_DEF 0x0CD30BD0
-#define LOV_PATTERN_RAID0 0x001 /* stripes are used round-robin */
-#define LOV_PATTERN_RAID1 0x002 /* stripes are mirrors of each other */
-#define LOV_PATTERN_FIRST 0x100 /* first stripe is not in round-robin */
-#define LOV_PATTERN_CMOBD 0x200
-
-#define LOV_PATTERN_F_MASK 0xffff0000
-#define LOV_PATTERN_F_RELEASED 0x80000000 /* HSM released file */
-
#define lov_pattern(pattern) (pattern & ~LOV_PATTERN_F_MASK)
#define lov_pattern_flags(pattern) (pattern & LOV_PATTERN_F_MASK)
@@ -1569,25 +1556,25 @@ static inline void lmm_oi_set_id(struct ost_id *oi, __u64 oid)
oi->oi.oi_id = oid;
}
-static inline __u64 lmm_oi_id(struct ost_id *oi)
+static inline __u64 lmm_oi_id(const struct ost_id *oi)
{
return oi->oi.oi_id;
}
-static inline __u64 lmm_oi_seq(struct ost_id *oi)
+static inline __u64 lmm_oi_seq(const struct ost_id *oi)
{
return oi->oi.oi_seq;
}
static inline void lmm_oi_le_to_cpu(struct ost_id *dst_oi,
- struct ost_id *src_oi)
+ const struct ost_id *src_oi)
{
dst_oi->oi.oi_id = le64_to_cpu(src_oi->oi.oi_id);
dst_oi->oi.oi_seq = le64_to_cpu(src_oi->oi.oi_seq);
}
static inline void lmm_oi_cpu_to_le(struct ost_id *dst_oi,
- struct ost_id *src_oi)
+ const struct ost_id *src_oi)
{
dst_oi->oi.oi_id = cpu_to_le64(src_oi->oi.oi_id);
dst_oi->oi.oi_seq = cpu_to_le64(src_oi->oi.oi_seq);
@@ -1610,6 +1597,7 @@ static inline void lmm_oi_cpu_to_le(struct ost_id *dst_oi,
#define XATTR_NAME_LOV "trusted.lov"
#define XATTR_NAME_LMA "trusted.lma"
#define XATTR_NAME_LMV "trusted.lmv"
+#define XATTR_NAME_DEFAULT_LMV "trusted.dmv"
#define XATTR_NAME_LINK "trusted.link"
#define XATTR_NAME_FID "trusted.fid"
#define XATTR_NAME_VERSION "trusted.version"
@@ -1625,7 +1613,7 @@ struct lov_mds_md_v3 { /* LOV EA mds/wire data (little-endian) */
/* lmm_stripe_count used to be __u32 */
__u16 lmm_stripe_count; /* num stripes in use for this object */
__u16 lmm_layout_gen; /* layout generation number */
- char lmm_pool_name[LOV_MAXPOOLNAME]; /* must be 32bit aligned */
+ char lmm_pool_name[LOV_MAXPOOLNAME + 1]; /* must be 32bit aligned */
struct lov_ost_data_v1 lmm_objects[0]; /* per-stripe data */
};
@@ -1727,6 +1715,8 @@ lov_mds_md_max_stripe_count(size_t buf_size, __u32 lmm_magic)
#define OBD_MD_FLDATAVERSION (0x0010000000000000ULL) /* iversion sum */
#define OBD_MD_FLRELEASED (0x0020000000000000ULL) /* file released */
+#define OBD_MD_DEFAULT_MEA (0x0040000000000000ULL) /* default MEA */
+
#define OBD_MD_FLGETATTR (OBD_MD_FLID | OBD_MD_FLATIME | OBD_MD_FLMTIME | \
OBD_MD_FLCTIME | OBD_MD_FLSIZE | OBD_MD_FLBLKSZ | \
OBD_MD_FLMODE | OBD_MD_FLTYPE | OBD_MD_FLUID | \
@@ -1782,7 +1772,7 @@ void lustre_swab_obd_statfs(struct obd_statfs *os);
* it to sync quickly
*/
-#define OBD_OBJECT_EOF 0xffffffffffffffffULL
+#define OBD_OBJECT_EOF LUSTRE_EOF
#define OST_MIN_PRECREATE 32
#define OST_MAX_PRECREATE 20000
@@ -1806,9 +1796,9 @@ void lustre_swab_obd_ioobj(struct obd_ioobj *ioo);
/* multiple of 8 bytes => can array */
struct niobuf_remote {
- __u64 offset;
- __u32 len;
- __u32 flags;
+ __u64 rnb_offset;
+ __u32 rnb_len;
+ __u32 rnb_flags;
};
void lustre_swab_niobuf_remote(struct niobuf_remote *nbr);
@@ -1878,12 +1868,6 @@ struct obd_quotactl {
void lustre_swab_obd_quotactl(struct obd_quotactl *q);
-#define Q_QUOTACHECK 0x800100 /* deprecated as of 2.4 */
-#define Q_INITQUOTA 0x800101 /* deprecated as of 2.4 */
-#define Q_GETOINFO 0x800102 /* get obd quota info */
-#define Q_GETOQUOTA 0x800103 /* get obd quotas */
-#define Q_FINVALIDATE 0x800104 /* deprecated as of 2.4 */
-
#define Q_COPY(out, in, member) (out)->member = (in)->member
#define QCTL_COPY(out, in) \
@@ -1946,8 +1930,8 @@ enum mds_cmd {
MDS_DISCONNECT = 39,
MDS_GETSTATUS = 40,
MDS_STATFS = 41,
- MDS_PIN = 42,
- MDS_UNPIN = 43,
+ MDS_PIN = 42, /* obsolete, never used in a release */
+ MDS_UNPIN = 43, /* obsolete, never used in a release */
MDS_SYNC = 44,
MDS_DONE_WRITING = 45,
MDS_SET_INFO = 46,
@@ -1956,7 +1940,7 @@ enum mds_cmd {
MDS_GETXATTR = 49,
MDS_SETXATTR = 50, /* obsolete, now it's MDS_REINT op */
MDS_WRITEPAGE = 51,
- MDS_IS_SUBDIR = 52,
+ MDS_IS_SUBDIR = 52, /* obsolete, never used in a release */
MDS_GET_INFO = 53,
MDS_HSM_STATE_GET = 54,
MDS_HSM_STATE_SET = 55,
@@ -1984,7 +1968,7 @@ enum mdt_reint_cmd {
REINT_OPEN = 6,
REINT_SETXATTR = 7,
REINT_RMENTRY = 8,
-/* REINT_WRITE = 9, */
+ REINT_MIGRATE = 9,
REINT_MAX
};
@@ -2003,6 +1987,7 @@ void lustre_swab_generic_32s(__u32 *val);
#define DISP_OPEN_LOCK 0x02000000
#define DISP_OPEN_LEASE 0x04000000
#define DISP_OPEN_STRIPE 0x08000000
+#define DISP_OPEN_DENY 0x10000000
/* INODE LOCK PARTS */
#define MDS_INODELOCK_LOOKUP 0x000001 /* For namespace, dentry etc, and also
@@ -2028,7 +2013,7 @@ void lustre_swab_generic_32s(__u32 *val);
#define MDS_INODELOCK_MAXSHIFT 5
/* This FULL lock is useful to take on unlink sort of operations */
-#define MDS_INODELOCK_FULL ((1<<(MDS_INODELOCK_MAXSHIFT+1))-1)
+#define MDS_INODELOCK_FULL ((1 << (MDS_INODELOCK_MAXSHIFT + 1)) - 1)
/* NOTE: until Lustre 1.8.7/2.1.1 the fid_ver() was packed into name[2],
* but was moved into name[1] along with the OID to avoid consuming the
@@ -2108,43 +2093,43 @@ enum md_transient_state {
};
struct mdt_body {
- struct lu_fid fid1;
- struct lu_fid fid2;
- struct lustre_handle handle;
- __u64 valid;
- __u64 size; /* Offset, in the case of MDS_READPAGE */
- __s64 mtime;
- __s64 atime;
- __s64 ctime;
- __u64 blocks; /* XID, in the case of MDS_READPAGE */
- __u64 ioepoch;
- __u64 t_state; /* transient file state defined in
- * enum md_transient_state
- * was "ino" until 2.4.0
- */
- __u32 fsuid;
- __u32 fsgid;
- __u32 capability;
- __u32 mode;
- __u32 uid;
- __u32 gid;
- __u32 flags; /* from vfs for pin/unpin, LUSTRE_BFLAG close */
- __u32 rdev;
- __u32 nlink; /* #bytes to read in the case of MDS_READPAGE */
- __u32 unused2; /* was "generation" until 2.4.0 */
- __u32 suppgid;
- __u32 eadatasize;
- __u32 aclsize;
- __u32 max_mdsize;
- __u32 max_cookiesize;
- __u32 uid_h; /* high 32-bits of uid, for FUID */
- __u32 gid_h; /* high 32-bits of gid, for FUID */
- __u32 padding_5; /* also fix lustre_swab_mdt_body */
- __u64 padding_6;
- __u64 padding_7;
- __u64 padding_8;
- __u64 padding_9;
- __u64 padding_10;
+ struct lu_fid mbo_fid1;
+ struct lu_fid mbo_fid2;
+ struct lustre_handle mbo_handle;
+ __u64 mbo_valid;
+ __u64 mbo_size; /* Offset, in the case of MDS_READPAGE */
+ __s64 mbo_mtime;
+ __s64 mbo_atime;
+ __s64 mbo_ctime;
+ __u64 mbo_blocks; /* XID, in the case of MDS_READPAGE */
+ __u64 mbo_ioepoch;
+ __u64 mbo_t_state; /* transient file state defined in
+ * enum md_transient_state
+ * was "ino" until 2.4.0
+ */
+ __u32 mbo_fsuid;
+ __u32 mbo_fsgid;
+ __u32 mbo_capability;
+ __u32 mbo_mode;
+ __u32 mbo_uid;
+ __u32 mbo_gid;
+ __u32 mbo_flags;
+ __u32 mbo_rdev;
+ __u32 mbo_nlink; /* #bytes to read in the case of MDS_READPAGE */
+ __u32 mbo_unused2; /* was "generation" until 2.4.0 */
+ __u32 mbo_suppgid;
+ __u32 mbo_eadatasize;
+ __u32 mbo_aclsize;
+ __u32 mbo_max_mdsize;
+ __u32 mbo_max_cookiesize;
+ __u32 mbo_uid_h; /* high 32-bits of uid, for FUID */
+ __u32 mbo_gid_h; /* high 32-bits of gid, for FUID */
+ __u32 mbo_padding_5; /* also fix lustre_swab_mdt_body */
+ __u64 mbo_padding_6;
+ __u64 mbo_padding_7;
+ __u64 mbo_padding_8;
+ __u64 mbo_padding_9;
+ __u64 mbo_padding_10;
}; /* 216 */
void lustre_swab_mdt_body(struct mdt_body *b);
@@ -2263,6 +2248,11 @@ void lustre_swab_mdt_rec_setattr(struct mdt_rec_setattr *sa);
*/
#define MDS_OPEN_RELEASE 02000000000000ULL /* Open the file for HSM release */
+#define MDS_OPEN_FL_INTERNAL (MDS_OPEN_HAS_EA | MDS_OPEN_HAS_OBJS | \
+ MDS_OPEN_OWNEROVERRIDE | MDS_OPEN_LOCK | \
+ MDS_OPEN_BY_FID | MDS_OPEN_LEASE | \
+ MDS_OPEN_RELEASE)
+
enum mds_op_bias {
MDS_CHECK_SPLIT = 1 << 0,
MDS_CROSS_REF = 1 << 1,
@@ -2277,6 +2267,7 @@ enum mds_op_bias {
MDS_CREATE_VOLATILE = 1 << 10,
MDS_OWNEROVERRIDE = 1 << 11,
MDS_HSM_RELEASE = 1 << 12,
+ MDS_RENAME_MIGRATE = BIT(13),
};
/* instance of mdt_reint_rec */
@@ -2472,7 +2463,7 @@ struct lmv_desc {
__u32 ld_tgt_count; /* how many MDS's */
__u32 ld_active_tgt_count; /* how many active */
__u32 ld_default_stripe_count; /* how many objects are used */
- __u32 ld_pattern; /* default MEA_MAGIC_* */
+ __u32 ld_pattern; /* default hash pattern */
__u64 ld_default_hash_size;
__u64 ld_padding_1; /* also fix lustre_swab_lmv_desc */
__u32 ld_padding_2; /* also fix lustre_swab_lmv_desc */
@@ -2482,23 +2473,129 @@ struct lmv_desc {
struct obd_uuid ld_uuid;
};
-/* TODO: lmv_stripe_md should contain mds capabilities for all slave fids */
-struct lmv_stripe_md {
- __u32 mea_magic;
- __u32 mea_count;
- __u32 mea_master;
- __u32 mea_padding;
- char mea_pool_name[LOV_MAXPOOLNAME];
- struct lu_fid mea_ids[0];
+/* LMV layout EA, and it will be stored both in master and slave object */
+struct lmv_mds_md_v1 {
+ __u32 lmv_magic;
+ __u32 lmv_stripe_count;
+ __u32 lmv_master_mdt_index; /* On master object, it is master
+ * MDT index, on slave object, it
+ * is stripe index of the slave obj
+ */
+ __u32 lmv_hash_type; /* dir stripe policy, i.e. indicate
+ * which hash function to be used,
+ * Note: only lower 16 bits is being
+ * used for now. Higher 16 bits will
+ * be used to mark the object status,
+ * for example migrating or dead.
+ */
+ __u32 lmv_layout_version; /* Used for directory restriping */
+ __u32 lmv_padding1;
+ __u64 lmv_padding2;
+ __u64 lmv_padding3;
+ char lmv_pool_name[LOV_MAXPOOLNAME + 1];/* pool name */
+ struct lu_fid lmv_stripe_fids[0]; /* FIDs for each stripe */
};
-#define MEA_MAGIC_LAST_CHAR 0xb2221ca1
-#define MEA_MAGIC_ALL_CHARS 0xb222a11c
-#define MEA_MAGIC_HASH_SEGMENT 0xb222a11b
+#define LMV_MAGIC_V1 0x0CD20CD0 /* normal stripe lmv magic */
+#define LMV_MAGIC LMV_MAGIC_V1
+
+/* #define LMV_USER_MAGIC 0x0CD30CD0 */
+#define LMV_MAGIC_STRIPE 0x0CD40CD0 /* magic for dir sub_stripe */
+
+/*
+ *Right now only the lower part(0-16bits) of lmv_hash_type is being used,
+ * and the higher part will be the flag to indicate the status of object,
+ * for example the object is being migrated. And the hash function
+ * might be interpreted differently with different flags.
+ */
+#define LMV_HASH_TYPE_MASK 0x0000ffff
+
+#define LMV_HASH_FLAG_MIGRATION 0x80000000
+#define LMV_HASH_FLAG_DEAD 0x40000000
-#define MAX_HASH_SIZE_32 0x7fffffffUL
-#define MAX_HASH_SIZE 0x7fffffffffffffffULL
-#define MAX_HASH_HIGHEST_BIT 0x1000000000000000ULL
+/**
+ * The FNV-1a hash algorithm is as follows:
+ * hash = FNV_offset_basis
+ * for each octet_of_data to be hashed
+ * hash = hash XOR octet_of_data
+ * hash = hash × FNV_prime
+ * return hash
+ * http://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function#FNV-1a_hash
+ *
+ * http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-reference-source
+ * FNV_prime is 2^40 + 2^8 + 0xb3 = 0x100000001b3ULL
+ **/
+#define LUSTRE_FNV_1A_64_PRIME 0x100000001b3ULL
+#define LUSTRE_FNV_1A_64_OFFSET_BIAS 0xcbf29ce484222325ULL
+static inline __u64 lustre_hash_fnv_1a_64(const void *buf, size_t size)
+{
+ __u64 hash = LUSTRE_FNV_1A_64_OFFSET_BIAS;
+ const unsigned char *p = buf;
+ size_t i;
+
+ for (i = 0; i < size; i++) {
+ hash ^= p[i];
+ hash *= LUSTRE_FNV_1A_64_PRIME;
+ }
+
+ return hash;
+}
+
+union lmv_mds_md {
+ __u32 lmv_magic;
+ struct lmv_mds_md_v1 lmv_md_v1;
+ struct lmv_user_md lmv_user_md;
+};
+
+void lustre_swab_lmv_mds_md(union lmv_mds_md *lmm);
+
+static inline ssize_t lmv_mds_md_size(int stripe_count, unsigned int lmm_magic)
+{
+ ssize_t len = -EINVAL;
+
+ switch (lmm_magic) {
+ case LMV_MAGIC_V1: {
+ struct lmv_mds_md_v1 *lmm1;
+
+ len = sizeof(*lmm1);
+ len += stripe_count * sizeof(lmm1->lmv_stripe_fids[0]);
+ break; }
+ default:
+ break;
+ }
+ return len;
+}
+
+static inline int lmv_mds_md_stripe_count_get(const union lmv_mds_md *lmm)
+{
+ switch (le32_to_cpu(lmm->lmv_magic)) {
+ case LMV_MAGIC_V1:
+ return le32_to_cpu(lmm->lmv_md_v1.lmv_stripe_count);
+ case LMV_USER_MAGIC:
+ return le32_to_cpu(lmm->lmv_user_md.lum_stripe_count);
+ default:
+ return -EINVAL;
+ }
+}
+
+static inline int lmv_mds_md_stripe_count_set(union lmv_mds_md *lmm,
+ unsigned int stripe_count)
+{
+ int rc = 0;
+
+ switch (le32_to_cpu(lmm->lmv_magic)) {
+ case LMV_MAGIC_V1:
+ lmm->lmv_md_v1.lmv_stripe_count = cpu_to_le32(stripe_count);
+ break;
+ case LMV_USER_MAGIC:
+ lmm->lmv_user_md.lum_stripe_count = cpu_to_le32(stripe_count);
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+ }
+ return rc;
+}
enum fld_rpc_opc {
FLD_QUERY = 900,
@@ -2582,8 +2679,8 @@ struct ldlm_res_id {
#define PLDLMRES(res) (res)->lr_name.name[0], (res)->lr_name.name[1], \
(res)->lr_name.name[2], (res)->lr_name.name[3]
-static inline int ldlm_res_eq(const struct ldlm_res_id *res0,
- const struct ldlm_res_id *res1)
+static inline bool ldlm_res_eq(const struct ldlm_res_id *res0,
+ const struct ldlm_res_id *res1)
{
return !memcmp(res0, res1, sizeof(*res0));
}
@@ -2620,17 +2717,15 @@ struct ldlm_extent {
__u64 gid;
};
-#define LDLM_GID_ANY ((__u64)-1)
-
-static inline int ldlm_extent_overlap(struct ldlm_extent *ex1,
- struct ldlm_extent *ex2)
+static inline int ldlm_extent_overlap(const struct ldlm_extent *ex1,
+ const struct ldlm_extent *ex2)
{
return (ex1->start <= ex2->end) && (ex2->start <= ex1->end);
}
/* check if @ex1 contains @ex2 */
-static inline int ldlm_extent_contain(struct ldlm_extent *ex1,
- struct ldlm_extent *ex2)
+static inline int ldlm_extent_contain(const struct ldlm_extent *ex1,
+ const struct ldlm_extent *ex2)
{
return (ex1->start <= ex2->start) && (ex1->end >= ex2->end);
}
@@ -2833,7 +2928,29 @@ enum obd_cmd {
};
#define OBD_FIRST_OPC OBD_PING
-/* catalog of log objects */
+/**
+ * llog contexts indices.
+ *
+ * There is compatibility problem with indexes below, they are not
+ * continuous and must keep their numbers for compatibility needs.
+ * See LU-5218 for details.
+ */
+enum llog_ctxt_id {
+ LLOG_CONFIG_ORIG_CTXT = 0,
+ LLOG_CONFIG_REPL_CTXT = 1,
+ LLOG_MDS_OST_ORIG_CTXT = 2,
+ LLOG_MDS_OST_REPL_CTXT = 3, /* kept just to avoid re-assignment */
+ LLOG_SIZE_ORIG_CTXT = 4,
+ LLOG_SIZE_REPL_CTXT = 5,
+ LLOG_TEST_ORIG_CTXT = 8,
+ LLOG_TEST_REPL_CTXT = 9, /* kept just to avoid re-assignment */
+ LLOG_CHANGELOG_ORIG_CTXT = 12, /**< changelog generation on mdd */
+ LLOG_CHANGELOG_REPL_CTXT = 13, /**< changelog access on clients */
+ /* for multiple changelog consumers */
+ LLOG_CHANGELOG_USER_ORIG_CTXT = 14,
+ LLOG_AGENT_ORIG_CTXT = 15, /**< agent requests generation on cdt */
+ LLOG_MAX_CTXTS
+};
/** Identifier for a single log object */
struct llog_logid {
@@ -2939,7 +3056,7 @@ struct llog_setattr64_rec {
__u32 lsr_uid_h;
__u32 lsr_gid;
__u32 lsr_gid_h;
- __u64 lsr_padding;
+ __u64 lsr_valid;
struct llog_rec_tail lsr_tail;
} __packed;
@@ -2963,15 +3080,9 @@ struct changelog_setinfo {
/** changelog record */
struct llog_changelog_rec {
- struct llog_rec_hdr cr_hdr;
- struct changelog_rec cr;
- struct llog_rec_tail cr_tail; /**< for_sizezof_only */
-} __packed;
-
-struct llog_changelog_ext_rec {
- struct llog_rec_hdr cr_hdr;
- struct changelog_ext_rec cr;
- struct llog_rec_tail cr_tail; /**< for_sizezof_only */
+ struct llog_rec_hdr cr_hdr;
+ struct changelog_rec cr; /**< Variable length field */
+ struct llog_rec_tail cr_do_not_use; /**< for_sizezof_only */
} __packed;
struct llog_changelog_user_rec {
@@ -2990,7 +3101,7 @@ enum agent_req_status {
ARS_SUCCEED,
};
-static inline char *agent_req_status2name(enum agent_req_status ars)
+static inline const char *agent_req_status2name(const enum agent_req_status ars)
{
switch (ars) {
case ARS_WAITING:
@@ -3056,6 +3167,9 @@ enum llog_flag {
LLOG_F_ZAP_WHEN_EMPTY = 0x1,
LLOG_F_IS_CAT = 0x2,
LLOG_F_IS_PLAIN = 0x4,
+ LLOG_F_EXT_JOBID = BIT(3),
+
+ LLOG_F_EXT_MASK = LLOG_F_EXT_JOBID,
};
struct llog_log_hdr {
@@ -3068,8 +3182,8 @@ struct llog_log_hdr {
__u32 llh_cat_idx;
/* for a catalog the first plain slot is next to it */
struct obd_uuid llh_tgtuuid;
- __u32 llh_reserved[LLOG_HEADER_SIZE/sizeof(__u32) - 23];
- __u32 llh_bitmap[LLOG_BITMAP_BYTES/sizeof(__u32)];
+ __u32 llh_reserved[LLOG_HEADER_SIZE / sizeof(__u32) - 23];
+ __u32 llh_bitmap[LLOG_BITMAP_BYTES / sizeof(__u32)];
struct llog_rec_tail llh_tail;
} __packed;
@@ -3166,7 +3280,7 @@ struct obdo {
#define o_cksum o_nlink
#define o_grant_used o_data_version
-static inline void lustre_set_wire_obdo(struct obd_connect_data *ocd,
+static inline void lustre_set_wire_obdo(const struct obd_connect_data *ocd,
struct obdo *wobdo,
const struct obdo *lobdo)
{
@@ -3185,7 +3299,7 @@ static inline void lustre_set_wire_obdo(struct obd_connect_data *ocd,
}
}
-static inline void lustre_get_wire_obdo(struct obd_connect_data *ocd,
+static inline void lustre_get_wire_obdo(const struct obd_connect_data *ocd,
struct obdo *lobdo,
const struct obdo *wobdo)
{
@@ -3284,17 +3398,17 @@ void lustre_swab_lustre_capa(struct lustre_capa *c);
/** lustre_capa::lc_opc */
enum {
- CAPA_OPC_BODY_WRITE = 1<<0, /**< write object data */
- CAPA_OPC_BODY_READ = 1<<1, /**< read object data */
- CAPA_OPC_INDEX_LOOKUP = 1<<2, /**< lookup object fid */
- CAPA_OPC_INDEX_INSERT = 1<<3, /**< insert object fid */
- CAPA_OPC_INDEX_DELETE = 1<<4, /**< delete object fid */
- CAPA_OPC_OSS_WRITE = 1<<5, /**< write oss object data */
- CAPA_OPC_OSS_READ = 1<<6, /**< read oss object data */
- CAPA_OPC_OSS_TRUNC = 1<<7, /**< truncate oss object */
- CAPA_OPC_OSS_DESTROY = 1<<8, /**< destroy oss object */
- CAPA_OPC_META_WRITE = 1<<9, /**< write object meta data */
- CAPA_OPC_META_READ = 1<<10, /**< read object meta data */
+ CAPA_OPC_BODY_WRITE = 1 << 0, /**< write object data */
+ CAPA_OPC_BODY_READ = 1 << 1, /**< read object data */
+ CAPA_OPC_INDEX_LOOKUP = 1 << 2, /**< lookup object fid */
+ CAPA_OPC_INDEX_INSERT = 1 << 3, /**< insert object fid */
+ CAPA_OPC_INDEX_DELETE = 1 << 4, /**< delete object fid */
+ CAPA_OPC_OSS_WRITE = 1 << 5, /**< write oss object data */
+ CAPA_OPC_OSS_READ = 1 << 6, /**< read oss object data */
+ CAPA_OPC_OSS_TRUNC = 1 << 7, /**< truncate oss object */
+ CAPA_OPC_OSS_DESTROY = 1 << 8, /**< destroy oss object */
+ CAPA_OPC_META_WRITE = 1 << 9, /**< write object meta data */
+ CAPA_OPC_META_READ = 1 << 10, /**< read object meta data */
};
#define CAPA_OPC_OSS_RW (CAPA_OPC_OSS_READ | CAPA_OPC_OSS_WRITE)
@@ -3346,6 +3460,14 @@ struct getinfo_fid2path {
void lustre_swab_fid2path(struct getinfo_fid2path *gf);
+/** path2parent request/reply structures */
+struct getparent {
+ struct lu_fid gp_fid; /**< parent FID */
+ __u32 gp_linkno; /**< hardlink number */
+ __u32 gp_name_size; /**< size of the name field */
+ char gp_name[0]; /**< zero-terminated link name */
+} __packed;
+
enum {
LAYOUT_INTENT_ACCESS = 0,
LAYOUT_INTENT_READ = 1,
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_ioctl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_ioctl.h
new file mode 100644
index 000000000000..f3d7c94c3b50
--- /dev/null
+++ b/drivers/staging/lustre/lustre/include/lustre/lustre_ioctl.h
@@ -0,0 +1,412 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * 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 version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2015, Intel Corporation.
+ */
+#ifndef LUSTRE_IOCTL_H_
+#define LUSTRE_IOCTL_H_
+
+#include <linux/types.h>
+#include "../../../include/linux/libcfs/libcfs.h"
+#include "lustre_idl.h"
+
+#ifdef __KERNEL__
+# include <linux/ioctl.h>
+# include <linux/string.h>
+# include "../obd_support.h"
+#else /* __KERNEL__ */
+# include <malloc.h>
+# include <string.h>
+#include <libcfs/util/ioctl.h>
+#endif /* !__KERNEL__ */
+
+#if !defined(__KERNEL__) && !defined(LUSTRE_UTILS)
+# error This file is for Lustre internal use only.
+#endif
+
+enum md_echo_cmd {
+ ECHO_MD_CREATE = 1, /* Open/Create file on MDT */
+ ECHO_MD_MKDIR = 2, /* Mkdir on MDT */
+ ECHO_MD_DESTROY = 3, /* Unlink file on MDT */
+ ECHO_MD_RMDIR = 4, /* Rmdir on MDT */
+ ECHO_MD_LOOKUP = 5, /* Lookup on MDT */
+ ECHO_MD_GETATTR = 6, /* Getattr on MDT */
+ ECHO_MD_SETATTR = 7, /* Setattr on MDT */
+ ECHO_MD_ALLOC_FID = 8, /* Get FIDs from MDT */
+};
+
+#define OBD_DEV_ID 1
+#define OBD_DEV_NAME "obd"
+#define OBD_DEV_PATH "/dev/" OBD_DEV_NAME
+#define OBD_DEV_MAJOR 10
+#define OBD_DEV_MINOR 241
+
+#define OBD_IOCTL_VERSION 0x00010004
+#define OBD_DEV_BY_DEVNAME 0xffffd0de
+#define OBD_MAX_IOCTL_BUFFER CONFIG_LUSTRE_OBD_MAX_IOCTL_BUFFER
+
+struct obd_ioctl_data {
+ __u32 ioc_len;
+ __u32 ioc_version;
+
+ union {
+ __u64 ioc_cookie;
+ __u64 ioc_u64_1;
+ };
+ union {
+ __u32 ioc_conn1;
+ __u32 ioc_u32_1;
+ };
+ union {
+ __u32 ioc_conn2;
+ __u32 ioc_u32_2;
+ };
+
+ struct obdo ioc_obdo1;
+ struct obdo ioc_obdo2;
+
+ __u64 ioc_count;
+ __u64 ioc_offset;
+ __u32 ioc_dev;
+ __u32 ioc_command;
+
+ __u64 ioc_nid;
+ __u32 ioc_nal;
+ __u32 ioc_type;
+
+ /* buffers the kernel will treat as user pointers */
+ __u32 ioc_plen1;
+ char __user *ioc_pbuf1;
+ __u32 ioc_plen2;
+ char __user *ioc_pbuf2;
+
+ /* inline buffers for various arguments */
+ __u32 ioc_inllen1;
+ char *ioc_inlbuf1;
+ __u32 ioc_inllen2;
+ char *ioc_inlbuf2;
+ __u32 ioc_inllen3;
+ char *ioc_inlbuf3;
+ __u32 ioc_inllen4;
+ char *ioc_inlbuf4;
+
+ char ioc_bulk[0];
+};
+
+struct obd_ioctl_hdr {
+ __u32 ioc_len;
+ __u32 ioc_version;
+};
+
+static inline __u32 obd_ioctl_packlen(struct obd_ioctl_data *data)
+{
+ __u32 len = cfs_size_round(sizeof(*data));
+
+ len += cfs_size_round(data->ioc_inllen1);
+ len += cfs_size_round(data->ioc_inllen2);
+ len += cfs_size_round(data->ioc_inllen3);
+ len += cfs_size_round(data->ioc_inllen4);
+
+ return len;
+}
+
+static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
+{
+ if (data->ioc_len > (1 << 30)) {
+ CERROR("OBD ioctl: ioc_len larger than 1<<30\n");
+ return 1;
+ }
+
+ if (data->ioc_inllen1 > (1 << 30)) {
+ CERROR("OBD ioctl: ioc_inllen1 larger than 1<<30\n");
+ return 1;
+ }
+
+ if (data->ioc_inllen2 > (1 << 30)) {
+ CERROR("OBD ioctl: ioc_inllen2 larger than 1<<30\n");
+ return 1;
+ }
+
+ if (data->ioc_inllen3 > (1 << 30)) {
+ CERROR("OBD ioctl: ioc_inllen3 larger than 1<<30\n");
+ return 1;
+ }
+
+ if (data->ioc_inllen4 > (1 << 30)) {
+ CERROR("OBD ioctl: ioc_inllen4 larger than 1<<30\n");
+ return 1;
+ }
+
+ if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
+ CERROR("OBD ioctl: inlbuf1 pointer but 0 length\n");
+ return 1;
+ }
+
+ if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
+ CERROR("OBD ioctl: inlbuf2 pointer but 0 length\n");
+ return 1;
+ }
+
+ if (data->ioc_inlbuf3 && !data->ioc_inllen3) {
+ CERROR("OBD ioctl: inlbuf3 pointer but 0 length\n");
+ return 1;
+ }
+
+ if (data->ioc_inlbuf4 && !data->ioc_inllen4) {
+ CERROR("OBD ioctl: inlbuf4 pointer but 0 length\n");
+ return 1;
+ }
+
+ if (data->ioc_pbuf1 && !data->ioc_plen1) {
+ CERROR("OBD ioctl: pbuf1 pointer but 0 length\n");
+ return 1;
+ }
+
+ if (data->ioc_pbuf2 && !data->ioc_plen2) {
+ CERROR("OBD ioctl: pbuf2 pointer but 0 length\n");
+ return 1;
+ }
+
+ if (!data->ioc_pbuf1 && data->ioc_plen1) {
+ CERROR("OBD ioctl: plen1 set but NULL pointer\n");
+ return 1;
+ }
+
+ if (!data->ioc_pbuf2 && data->ioc_plen2) {
+ CERROR("OBD ioctl: plen2 set but NULL pointer\n");
+ return 1;
+ }
+
+ if (obd_ioctl_packlen(data) > data->ioc_len) {
+ CERROR("OBD ioctl: packlen exceeds ioc_len (%d > %d)\n",
+ obd_ioctl_packlen(data), data->ioc_len);
+ return 1;
+ }
+
+ return 0;
+}
+
+#ifdef __KERNEL__
+
+int obd_ioctl_getdata(char **buf, int *len, void __user *arg);
+int obd_ioctl_popdata(void __user *arg, void *data, int len);
+
+static inline void obd_ioctl_freedata(char *buf, size_t len)
+{
+ kvfree(buf);
+}
+
+#else /* __KERNEL__ */
+
+static inline int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf,
+ int max_len)
+{
+ char *ptr;
+ struct obd_ioctl_data *overlay;
+
+ data->ioc_len = obd_ioctl_packlen(data);
+ data->ioc_version = OBD_IOCTL_VERSION;
+
+ if (*pbuf && data->ioc_len > max_len) {
+ fprintf(stderr, "pbuf = %p, ioc_len = %u, max_len = %d\n",
+ *pbuf, data->ioc_len, max_len);
+ return -EINVAL;
+ }
+
+ if (!*pbuf)
+ *pbuf = malloc(data->ioc_len);
+
+ if (!*pbuf)
+ return -ENOMEM;
+
+ overlay = (struct obd_ioctl_data *)*pbuf;
+ memcpy(*pbuf, data, sizeof(*data));
+
+ ptr = overlay->ioc_bulk;
+ if (data->ioc_inlbuf1)
+ LOGL(data->ioc_inlbuf1, data->ioc_inllen1, ptr);
+
+ if (data->ioc_inlbuf2)
+ LOGL(data->ioc_inlbuf2, data->ioc_inllen2, ptr);
+
+ if (data->ioc_inlbuf3)
+ LOGL(data->ioc_inlbuf3, data->ioc_inllen3, ptr);
+
+ if (data->ioc_inlbuf4)
+ LOGL(data->ioc_inlbuf4, data->ioc_inllen4, ptr);
+
+ if (obd_ioctl_is_invalid(overlay)) {
+ fprintf(stderr, "invalid ioctl data: ioc_len = %u, max_len = %d\n",
+ data->ioc_len, max_len);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline int
+obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len)
+{
+ char *ptr;
+ struct obd_ioctl_data *overlay;
+
+ if (!pbuf)
+ return 1;
+
+ overlay = (struct obd_ioctl_data *)pbuf;
+
+ /* Preserve the caller's buffer pointers */
+ overlay->ioc_inlbuf1 = data->ioc_inlbuf1;
+ overlay->ioc_inlbuf2 = data->ioc_inlbuf2;
+ overlay->ioc_inlbuf3 = data->ioc_inlbuf3;
+ overlay->ioc_inlbuf4 = data->ioc_inlbuf4;
+
+ memcpy(data, pbuf, sizeof(*data));
+
+ ptr = overlay->ioc_bulk;
+ if (data->ioc_inlbuf1)
+ LOGU(data->ioc_inlbuf1, data->ioc_inllen1, ptr);
+
+ if (data->ioc_inlbuf2)
+ LOGU(data->ioc_inlbuf2, data->ioc_inllen2, ptr);
+
+ if (data->ioc_inlbuf3)
+ LOGU(data->ioc_inlbuf3, data->ioc_inllen3, ptr);
+
+ if (data->ioc_inlbuf4)
+ LOGU(data->ioc_inlbuf4, data->ioc_inllen4, ptr);
+
+ return 0;
+}
+
+#endif /* !__KERNEL__ */
+
+/*
+ * OBD_IOC_DATA_TYPE is only for compatibility reasons with older
+ * Linux Lustre user tools. New ioctls should NOT use this macro as
+ * the ioctl "size". Instead the ioctl should get a "size" argument
+ * which is the actual data type used by the ioctl, to ensure the
+ * ioctl interface is versioned correctly.
+ */
+#define OBD_IOC_DATA_TYPE long
+
+/* IOC_LDLM_TEST _IOWR('f', 40, long) */
+/* IOC_LDLM_DUMP _IOWR('f', 41, long) */
+/* IOC_LDLM_REGRESS_START _IOWR('f', 42, long) */
+/* IOC_LDLM_REGRESS_STOP _IOWR('f', 43, long) */
+
+#define OBD_IOC_CREATE _IOWR('f', 101, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_DESTROY _IOW('f', 104, OBD_IOC_DATA_TYPE)
+/* OBD_IOC_PREALLOCATE _IOWR('f', 105, OBD_IOC_DATA_TYPE) */
+
+#define OBD_IOC_SETATTR _IOW('f', 107, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_GETATTR _IOWR('f', 108, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_READ _IOWR('f', 109, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_WRITE _IOWR('f', 110, OBD_IOC_DATA_TYPE)
+
+#define OBD_IOC_STATFS _IOWR('f', 113, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_SYNC _IOW('f', 114, OBD_IOC_DATA_TYPE)
+/* OBD_IOC_READ2 _IOWR('f', 115, OBD_IOC_DATA_TYPE) */
+/* OBD_IOC_FORMAT _IOWR('f', 116, OBD_IOC_DATA_TYPE) */
+/* OBD_IOC_PARTITION _IOWR('f', 117, OBD_IOC_DATA_TYPE) */
+/* OBD_IOC_COPY _IOWR('f', 120, OBD_IOC_DATA_TYPE) */
+/* OBD_IOC_MIGR _IOWR('f', 121, OBD_IOC_DATA_TYPE) */
+/* OBD_IOC_PUNCH _IOWR('f', 122, OBD_IOC_DATA_TYPE) */
+
+/* OBD_IOC_MODULE_DEBUG _IOWR('f', 124, OBD_IOC_DATA_TYPE) */
+#define OBD_IOC_BRW_READ _IOWR('f', 125, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_BRW_WRITE _IOWR('f', 126, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_NAME2DEV _IOWR('f', 127, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_UUID2DEV _IOWR('f', 130, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_GETNAME _IOWR('f', 131, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_GETMDNAME _IOR('f', 131, char[MAX_OBD_NAME])
+#define OBD_IOC_GETDTNAME OBD_IOC_GETNAME
+#define OBD_IOC_LOV_GET_CONFIG _IOWR('f', 132, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_CLIENT_RECOVER _IOW('f', 133, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_PING_TARGET _IOW('f', 136, OBD_IOC_DATA_TYPE)
+
+/* OBD_IOC_DEC_FS_USE_COUNT _IO('f', 139) */
+#define OBD_IOC_NO_TRANSNO _IOW('f', 140, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_SET_READONLY _IOW('f', 141, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_ABORT_RECOVERY _IOR('f', 142, OBD_IOC_DATA_TYPE)
+/* OBD_IOC_ROOT_SQUASH _IOWR('f', 143, OBD_IOC_DATA_TYPE) */
+#define OBD_GET_VERSION _IOWR('f', 144, OBD_IOC_DATA_TYPE)
+/* OBD_IOC_GSS_SUPPORT _IOWR('f', 145, OBD_IOC_DATA_TYPE) */
+/* OBD_IOC_CLOSE_UUID _IOWR('f', 147, OBD_IOC_DATA_TYPE) */
+#define OBD_IOC_CHANGELOG_SEND _IOW('f', 148, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_GETDEVICE _IOWR('f', 149, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_FID2PATH _IOWR('f', 150, OBD_IOC_DATA_TYPE)
+/* lustre/lustre_user.h 151-153 */
+/* OBD_IOC_LOV_SETSTRIPE 154 LL_IOC_LOV_SETSTRIPE */
+/* OBD_IOC_LOV_GETSTRIPE 155 LL_IOC_LOV_GETSTRIPE */
+/* OBD_IOC_LOV_SETEA 156 LL_IOC_LOV_SETEA */
+/* lustre/lustre_user.h 157-159 */
+#define OBD_IOC_QUOTACHECK _IOW('f', 160, int)
+#define OBD_IOC_POLL_QUOTACHECK _IOR('f', 161, struct if_quotacheck *)
+#define OBD_IOC_QUOTACTL _IOWR('f', 162, struct if_quotactl)
+/* lustre/lustre_user.h 163-176 */
+#define OBD_IOC_CHANGELOG_REG _IOW('f', 177, struct obd_ioctl_data)
+#define OBD_IOC_CHANGELOG_DEREG _IOW('f', 178, struct obd_ioctl_data)
+#define OBD_IOC_CHANGELOG_CLEAR _IOW('f', 179, struct obd_ioctl_data)
+/* OBD_IOC_RECORD _IOWR('f', 180, OBD_IOC_DATA_TYPE) */
+/* OBD_IOC_ENDRECORD _IOWR('f', 181, OBD_IOC_DATA_TYPE) */
+/* OBD_IOC_PARSE _IOWR('f', 182, OBD_IOC_DATA_TYPE) */
+/* OBD_IOC_DORECORD _IOWR('f', 183, OBD_IOC_DATA_TYPE) */
+#define OBD_IOC_PROCESS_CFG _IOWR('f', 184, OBD_IOC_DATA_TYPE)
+/* OBD_IOC_DUMP_LOG _IOWR('f', 185, OBD_IOC_DATA_TYPE) */
+/* OBD_IOC_CLEAR_LOG _IOWR('f', 186, OBD_IOC_DATA_TYPE) */
+#define OBD_IOC_PARAM _IOW('f', 187, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_POOL _IOWR('f', 188, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_REPLACE_NIDS _IOWR('f', 189, OBD_IOC_DATA_TYPE)
+
+#define OBD_IOC_CATLOGLIST _IOWR('f', 190, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_LLOG_INFO _IOWR('f', 191, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_LLOG_PRINT _IOWR('f', 192, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_LLOG_CANCEL _IOWR('f', 193, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_LLOG_REMOVE _IOWR('f', 194, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_LLOG_CHECK _IOWR('f', 195, OBD_IOC_DATA_TYPE)
+/* OBD_IOC_LLOG_CATINFO _IOWR('f', 196, OBD_IOC_DATA_TYPE) */
+#define OBD_IOC_NODEMAP _IOWR('f', 197, OBD_IOC_DATA_TYPE)
+
+/* ECHO_IOC_GET_STRIPE _IOWR('f', 200, OBD_IOC_DATA_TYPE) */
+/* ECHO_IOC_SET_STRIPE _IOWR('f', 201, OBD_IOC_DATA_TYPE) */
+/* ECHO_IOC_ENQUEUE _IOWR('f', 202, OBD_IOC_DATA_TYPE) */
+/* ECHO_IOC_CANCEL _IOWR('f', 203, OBD_IOC_DATA_TYPE) */
+
+#define OBD_IOC_GET_OBJ_VERSION _IOR('f', 210, OBD_IOC_DATA_TYPE)
+
+/* lustre/lustre_user.h 212-217 */
+#define OBD_IOC_GET_MNTOPT _IOW('f', 220, mntopt_t)
+#define OBD_IOC_ECHO_MD _IOR('f', 221, struct obd_ioctl_data)
+#define OBD_IOC_ECHO_ALLOC_SEQ _IOWR('f', 222, struct obd_ioctl_data)
+#define OBD_IOC_START_LFSCK _IOWR('f', 230, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_STOP_LFSCK _IOW('f', 231, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_QUERY_LFSCK _IOR('f', 232, struct obd_ioctl_data)
+/* lustre/lustre_user.h 240-249 */
+/* LIBCFS_IOC_DEBUG_MASK 250 */
+
+#define IOC_OSC_SET_ACTIVE _IOWR('h', 21, void *)
+
+#endif /* LUSTRE_IOCTL_H_ */
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h
index ef6f38ff359e..6fc985571cba 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h
+++ b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h
@@ -42,8 +42,35 @@
* @{
*/
+#ifdef __KERNEL__
+# include <linux/quota.h>
+# include <linux/string.h> /* snprintf() */
+# include <linux/version.h>
+#else /* !__KERNEL__ */
+# define NEED_QUOTA_DEFS
+# include <stdio.h> /* snprintf() */
+# include <string.h>
+# include <sys/quota.h>
+# include <sys/stat.h>
+#endif /* __KERNEL__ */
#include "ll_fiemap.h"
-#include "../linux/lustre_user.h"
+
+/*
+ * We need to always use 64bit version because the structure
+ * is shared across entire cluster where 32bit and 64bit machines
+ * are co-existing.
+ */
+#if __BITS_PER_LONG != 64 || defined(__ARCH_WANT_STAT64)
+typedef struct stat64 lstat_t;
+#define lstat_f lstat64
+#else
+typedef struct stat lstat_t;
+#define lstat_f lstat
+#endif
+
+#define HAVE_LOV_USER_MDS_DATA
+
+#define LUSTRE_EOF 0xffffffffffffffffULL
/* for statfs() */
#define LL_SUPER_MAGIC 0x0BD00BD0
@@ -117,6 +144,11 @@ struct lu_fid {
__u32 f_ver;
};
+static inline bool fid_is_zero(const struct lu_fid *fid)
+{
+ return !fid->f_seq && !fid->f_oid;
+}
+
struct filter_fid {
struct lu_fid ff_parent; /* ff_parent.f_ver == file stripe number */
};
@@ -167,7 +199,7 @@ struct lustre_mdt_attrs {
*/
struct ost_id {
union {
- struct ostid {
+ struct {
__u64 oi_id;
__u64 oi_seq;
} oi;
@@ -188,26 +220,20 @@ struct ost_id {
* *STRIPE* - set/get lov_user_md
* *INFO - set/get lov_user_mds_data
*/
-/* see <lustre_lib.h> for ioctl numberss 101-150 */
+/* lustre_ioctl.h 101-150 */
#define LL_IOC_GETFLAGS _IOR('f', 151, long)
#define LL_IOC_SETFLAGS _IOW('f', 152, long)
#define LL_IOC_CLRFLAGS _IOW('f', 153, long)
-/* LL_IOC_LOV_SETSTRIPE: See also OBD_IOC_LOV_SETSTRIPE */
#define LL_IOC_LOV_SETSTRIPE _IOW('f', 154, long)
-/* LL_IOC_LOV_GETSTRIPE: See also OBD_IOC_LOV_GETSTRIPE */
#define LL_IOC_LOV_GETSTRIPE _IOW('f', 155, long)
-/* LL_IOC_LOV_SETEA: See also OBD_IOC_LOV_SETEA */
#define LL_IOC_LOV_SETEA _IOW('f', 156, long)
-#define LL_IOC_RECREATE_OBJ _IOW('f', 157, long)
-#define LL_IOC_RECREATE_FID _IOW('f', 157, struct lu_fid)
+/* LL_IOC_RECREATE_OBJ 157 obsolete */
+/* LL_IOC_RECREATE_FID 158 obsolete */
#define LL_IOC_GROUP_LOCK _IOW('f', 158, long)
#define LL_IOC_GROUP_UNLOCK _IOW('f', 159, long)
-/* LL_IOC_QUOTACHECK: See also OBD_IOC_QUOTACHECK */
-#define LL_IOC_QUOTACHECK _IOW('f', 160, int)
-/* LL_IOC_POLL_QUOTACHECK: See also OBD_IOC_POLL_QUOTACHECK */
-#define LL_IOC_POLL_QUOTACHECK _IOR('f', 161, struct if_quotacheck *)
-/* LL_IOC_QUOTACTL: See also OBD_IOC_QUOTACTL */
-#define LL_IOC_QUOTACTL _IOWR('f', 162, struct if_quotactl)
+/* #define LL_IOC_QUOTACHECK 160 OBD_IOC_QUOTACHECK */
+/* #define LL_IOC_POLL_QUOTACHECK 161 OBD_IOC_POLL_QUOTACHECK */
+/* #define LL_IOC_QUOTACTL 162 OBD_IOC_QUOTACTL */
#define IOC_OBD_STATFS _IOWR('f', 164, struct obd_statfs *)
#define IOC_LOV_GETINFO _IOWR('f', 165, struct lov_user_mds_data *)
#define LL_IOC_FLUSHCTX _IOW('f', 166, long)
@@ -221,8 +247,7 @@ struct ost_id {
#define LL_IOC_GET_CONNECT_FLAGS _IOWR('f', 174, __u64 *)
#define LL_IOC_GET_MDTIDX _IOR('f', 175, int)
-/* see <lustre_lib.h> for ioctl numbers 177-210 */
-
+/* lustre_ioctl.h 177-210 */
#define LL_IOC_HSM_STATE_GET _IOR('f', 211, struct hsm_user_state)
#define LL_IOC_HSM_STATE_SET _IOW('f', 212, struct hsm_state_set)
#define LL_IOC_HSM_CT_START _IOW('f', 213, struct lustre_kernelcomm)
@@ -242,6 +267,17 @@ struct ost_id {
#define LL_IOC_SET_LEASE _IOWR('f', 243, long)
#define LL_IOC_GET_LEASE _IO('f', 244)
#define LL_IOC_HSM_IMPORT _IOWR('f', 245, struct hsm_user_import)
+#define LL_IOC_LMV_SET_DEFAULT_STRIPE _IOWR('f', 246, struct lmv_user_md)
+#define LL_IOC_MIGRATE _IOR('f', 247, int)
+#define LL_IOC_FID2MDTIDX _IOWR('f', 248, struct lu_fid)
+#define LL_IOC_GETPARENT _IOWR('f', 249, struct getparent)
+
+/* Lease types for use as arg and return of LL_IOC_{GET,SET}_LEASE ioctl. */
+enum ll_lease_type {
+ LL_LEASE_RDLCK = 0x1,
+ LL_LEASE_WRLCK = 0x2,
+ LL_LEASE_UNLCK = 0x4,
+};
#define LL_STATFS_LMV 1
#define LL_STATFS_LOV 2
@@ -253,10 +289,6 @@ struct ost_id {
#define IOC_MDC_GETFILEINFO _IOWR(IOC_MDC_TYPE, 22, struct lov_user_mds_data *)
#define LL_IOC_MDC_GETINFO _IOWR(IOC_MDC_TYPE, 23, struct lov_user_mds_data *)
-/* Keep these for backward compartability. */
-#define LL_IOC_OBD_STATFS IOC_OBD_STATFS
-#define IOC_MDC_GETSTRIPE IOC_MDC_GETFILESTRIPE
-
#define MAX_OBD_NAME 128 /* If this changes, a NEW ioctl must be added */
/* Define O_LOV_DELAY_CREATE to be a mask that is not useful for regular
@@ -273,20 +305,26 @@ struct ost_id {
#define LL_FILE_LOCKLESS_IO 0x00000010 /* server-side locks with cio */
#define LL_FILE_RMTACL 0x00000020
-#define LOV_USER_MAGIC_V1 0x0BD10BD0
-#define LOV_USER_MAGIC LOV_USER_MAGIC_V1
-#define LOV_USER_MAGIC_JOIN_V1 0x0BD20BD0
-#define LOV_USER_MAGIC_V3 0x0BD30BD0
+#define LOV_USER_MAGIC_V1 0x0BD10BD0
+#define LOV_USER_MAGIC LOV_USER_MAGIC_V1
+#define LOV_USER_MAGIC_JOIN_V1 0x0BD20BD0
+#define LOV_USER_MAGIC_V3 0x0BD30BD0
+/* 0x0BD40BD0 is occupied by LOV_MAGIC_MIGRATE */
+#define LOV_USER_MAGIC_SPECIFIC 0x0BD50BD0 /* for specific OSTs */
+
+#define LMV_USER_MAGIC 0x0CD30CD0 /*default lmv magic*/
-#define LMV_MAGIC_V1 0x0CD10CD0 /*normal stripe lmv magic */
-#define LMV_USER_MAGIC 0x0CD20CD0 /*default lmv magic*/
+#define LOV_PATTERN_RAID0 0x001
+#define LOV_PATTERN_RAID1 0x002
+#define LOV_PATTERN_FIRST 0x100
+#define LOV_PATTERN_CMOBD 0x200
-#define LOV_PATTERN_RAID0 0x001
-#define LOV_PATTERN_RAID1 0x002
-#define LOV_PATTERN_FIRST 0x100
+#define LOV_PATTERN_F_MASK 0xffff0000
+#define LOV_PATTERN_F_HOLE 0x40000000 /* there is hole in LOV EA */
+#define LOV_PATTERN_F_RELEASED 0x80000000 /* HSM released file */
-#define LOV_MAXPOOLNAME 16
-#define LOV_POOLNAMEF "%.16s"
+#define LOV_MAXPOOLNAME 15
+#define LOV_POOLNAMEF "%.15s"
#define LOV_MIN_STRIPE_BITS 16 /* maximum PAGE_SIZE (ia64), power of 2 */
#define LOV_MIN_STRIPE_SIZE (1 << LOV_MIN_STRIPE_BITS)
@@ -344,18 +382,17 @@ struct lov_user_md_v3 { /* LOV EA user data (host-endian) */
* used when reading
*/
};
- char lmm_pool_name[LOV_MAXPOOLNAME]; /* pool name */
+ char lmm_pool_name[LOV_MAXPOOLNAME + 1]; /* pool name */
struct lov_user_ost_data_v1 lmm_objects[0]; /* per-stripe data */
} __packed;
static inline __u32 lov_user_md_size(__u16 stripes, __u32 lmm_magic)
{
- if (lmm_magic == LOV_USER_MAGIC_V3)
- return sizeof(struct lov_user_md_v3) +
- stripes * sizeof(struct lov_user_ost_data_v1);
- else
+ if (lmm_magic == LOV_USER_MAGIC_V1)
return sizeof(struct lov_user_md_v1) +
stripes * sizeof(struct lov_user_ost_data_v1);
+ return sizeof(struct lov_user_md_v3) +
+ stripes * sizeof(struct lov_user_ost_data_v1);
}
/* Compile with -D_LARGEFILE64_SOURCE or -D_GNU_SOURCE (or #define) to
@@ -374,19 +411,26 @@ struct lov_user_mds_data_v3 {
} __packed;
#endif
-/* keep this to be the same size as lov_user_ost_data_v1 */
struct lmv_user_mds_data {
struct lu_fid lum_fid;
__u32 lum_padding;
__u32 lum_mds;
};
-/* lum_type */
-enum {
- LMV_STRIPE_TYPE = 0,
- LMV_DEFAULT_TYPE = 1,
+enum lmv_hash_type {
+ LMV_HASH_TYPE_UNKNOWN = 0, /* 0 is reserved for testing purpose */
+ LMV_HASH_TYPE_ALL_CHARS = 1,
+ LMV_HASH_TYPE_FNV_1A_64 = 2,
};
+#define LMV_HASH_NAME_ALL_CHARS "all_char"
+#define LMV_HASH_NAME_FNV_1A_64 "fnv_1a_64"
+
+/*
+ * Got this according to how get LOV_MAX_STRIPE_COUNT, see above,
+ * (max buffer size - lmv+rpc header) / sizeof(struct lmv_user_mds_data)
+ */
+#define LMV_MAX_STRIPE_COUNT 2000 /* ((12 * 4096 - 256) / 24) */
#define lmv_user_md lmv_user_md_v1
struct lmv_user_md_v1 {
__u32 lum_magic; /* must be the first field */
@@ -397,9 +441,9 @@ struct lmv_user_md_v1 {
__u32 lum_padding1;
__u32 lum_padding2;
__u32 lum_padding3;
- char lum_pool_name[LOV_MAXPOOLNAME];
+ char lum_pool_name[LOV_MAXPOOLNAME + 1];
struct lmv_user_mds_data lum_objects[0];
-};
+} __packed;
static inline int lmv_user_md_size(int stripes, int lmm_magic)
{
@@ -407,6 +451,8 @@ static inline int lmv_user_md_size(int stripes, int lmm_magic)
stripes * sizeof(struct lmv_user_mds_data);
}
+void lustre_swab_lmv_user_md(struct lmv_user_md *lum);
+
struct ll_recreate_obj {
__u64 lrc_id;
__u32 lrc_ost_idx;
@@ -498,6 +544,12 @@ static inline void obd_uuid2fsname(char *buf, char *uuid, int buflen)
/********* Quotas **********/
+#define Q_QUOTACHECK 0x800100 /* deprecated as of 2.4 */
+#define Q_INITQUOTA 0x800101 /* deprecated as of 2.4 */
+#define Q_GETOINFO 0x800102 /* get obd quota info */
+#define Q_GETOQUOTA 0x800103 /* get obd quotas */
+#define Q_FINVALIDATE 0x800104 /* deprecated as of 2.4 */
+
/* these must be explicitly translated into linux Q_* in ll_dir_ioctl */
#define LUSTRE_Q_QUOTAON 0x800002 /* turn quotas on */
#define LUSTRE_Q_QUOTAOFF 0x800003 /* turn quotas off */
@@ -648,11 +700,16 @@ static inline const char *changelog_type2str(int type)
}
/* per-record flags */
-#define CLF_VERSION 0x1000
-#define CLF_EXT_VERSION 0x2000
#define CLF_FLAGSHIFT 12
#define CLF_FLAGMASK ((1U << CLF_FLAGSHIFT) - 1)
#define CLF_VERMASK (~CLF_FLAGMASK)
+enum changelog_rec_flags {
+ CLF_VERSION = 0x1000,
+ CLF_RENAME = 0x2000,
+ CLF_JOBID = 0x4000,
+ CLF_SUPPORTED = CLF_VERSION | CLF_RENAME | CLF_JOBID
+};
+
/* Anything under the flagmask may be per-type (if desired) */
/* Flags for unlink */
#define CLF_UNLINK_LAST 0x0001 /* Unlink of last hardlink */
@@ -736,12 +793,35 @@ static inline void hsm_set_cl_error(int *flags, int error)
*flags |= (error << CLF_HSM_ERR_L);
}
-#define CR_MAXSIZE cfs_size_round(2*NAME_MAX + 1 + \
- sizeof(struct changelog_ext_rec))
+enum changelog_send_flag {
+ /* Not yet implemented */
+ CHANGELOG_FLAG_FOLLOW = BIT(0),
+ /*
+ * Blocking IO makes sense in case of slow user parsing of the records,
+ * but it also prevents us from cleaning up if the records are not
+ * consumed.
+ */
+ CHANGELOG_FLAG_BLOCK = BIT(1),
+ /* Pack jobid into the changelog records if available. */
+ CHANGELOG_FLAG_JOBID = BIT(2),
+};
+
+#define CR_MAXSIZE cfs_size_round(2 * NAME_MAX + 2 + \
+ changelog_rec_offset(CLF_SUPPORTED))
+
+/* 31 usable bytes string + null terminator. */
+#define LUSTRE_JOBID_SIZE 32
+/*
+ * This is the minimal changelog record. It can contain extensions
+ * such as rename fields or process jobid. Its exact content is described
+ * by the cr_flags.
+ *
+ * Extensions are packed in the same order as their corresponding flags.
+ */
struct changelog_rec {
__u16 cr_namelen;
- __u16 cr_flags; /**< (flags&CLF_FLAGMASK)|CLF_VERSION */
+ __u16 cr_flags; /**< \a changelog_rec_flags */
__u32 cr_type; /**< \a changelog_rec_type */
__u64 cr_index; /**< changelog record number */
__u64 cr_prev; /**< last index for this target fid */
@@ -751,55 +831,138 @@ struct changelog_rec {
__u32 cr_markerflags; /**< CL_MARK flags */
};
struct lu_fid cr_pfid; /**< parent fid */
- char cr_name[0]; /**< last element */
} __packed;
-/* changelog_ext_rec is 2*sizeof(lu_fid) bigger than changelog_rec, to save
- * space, only rename uses changelog_ext_rec, while others use changelog_rec to
- * store records.
- */
-struct changelog_ext_rec {
- __u16 cr_namelen;
- __u16 cr_flags; /**< (flags & CLF_FLAGMASK) |
- * CLF_EXT_VERSION
- */
- __u32 cr_type; /**< \a changelog_rec_type */
- __u64 cr_index; /**< changelog record number */
- __u64 cr_prev; /**< last index for this target fid */
- __u64 cr_time;
- union {
- struct lu_fid cr_tfid; /**< target fid */
- __u32 cr_markerflags; /**< CL_MARK flags */
- };
- struct lu_fid cr_pfid; /**< target parent fid */
- struct lu_fid cr_sfid; /**< source fid, or zero */
- struct lu_fid cr_spfid; /**< source parent fid, or zero */
- char cr_name[0]; /**< last element */
-} __packed;
+/* Changelog extension for RENAME. */
+struct changelog_ext_rename {
+ struct lu_fid cr_sfid; /**< source fid, or zero */
+ struct lu_fid cr_spfid; /**< source parent fid, or zero */
+};
-#define CHANGELOG_REC_EXTENDED(rec) \
- (((rec)->cr_flags & CLF_VERMASK) == CLF_EXT_VERSION)
+/* Changelog extension to include JOBID. */
+struct changelog_ext_jobid {
+ char cr_jobid[LUSTRE_JOBID_SIZE]; /**< zero-terminated string. */
+};
+
+static inline size_t changelog_rec_offset(enum changelog_rec_flags crf)
+{
+ size_t size = sizeof(struct changelog_rec);
+
+ if (crf & CLF_RENAME)
+ size += sizeof(struct changelog_ext_rename);
+
+ if (crf & CLF_JOBID)
+ size += sizeof(struct changelog_ext_jobid);
-static inline int changelog_rec_size(struct changelog_rec *rec)
+ return size;
+}
+
+static inline size_t changelog_rec_size(struct changelog_rec *rec)
{
- return CHANGELOG_REC_EXTENDED(rec) ? sizeof(struct changelog_ext_rec) :
- sizeof(*rec);
+ return changelog_rec_offset(rec->cr_flags);
+}
+
+static inline size_t changelog_rec_varsize(struct changelog_rec *rec)
+{
+ return changelog_rec_size(rec) - sizeof(*rec) + rec->cr_namelen;
+}
+
+static inline
+struct changelog_ext_rename *changelog_rec_rename(struct changelog_rec *rec)
+{
+ enum changelog_rec_flags crf = rec->cr_flags & CLF_VERSION;
+
+ return (struct changelog_ext_rename *)((char *)rec +
+ changelog_rec_offset(crf));
+}
+
+/* The jobid follows the rename extension, if present */
+static inline
+struct changelog_ext_jobid *changelog_rec_jobid(struct changelog_rec *rec)
+{
+ enum changelog_rec_flags crf = rec->cr_flags &
+ (CLF_VERSION | CLF_RENAME);
+
+ return (struct changelog_ext_jobid *)((char *)rec +
+ changelog_rec_offset(crf));
}
+/* The name follows the rename and jobid extensions, if present */
static inline char *changelog_rec_name(struct changelog_rec *rec)
{
- return CHANGELOG_REC_EXTENDED(rec) ?
- ((struct changelog_ext_rec *)rec)->cr_name : rec->cr_name;
+ return (char *)rec + changelog_rec_offset(rec->cr_flags &
+ CLF_SUPPORTED);
}
-static inline int changelog_rec_snamelen(struct changelog_ext_rec *rec)
+static inline size_t changelog_rec_snamelen(struct changelog_rec *rec)
{
- return rec->cr_namelen - strlen(rec->cr_name) - 1;
+ return rec->cr_namelen - strlen(changelog_rec_name(rec)) - 1;
}
-static inline char *changelog_rec_sname(struct changelog_ext_rec *rec)
+static inline char *changelog_rec_sname(struct changelog_rec *rec)
{
- return rec->cr_name + strlen(rec->cr_name) + 1;
+ char *cr_name = changelog_rec_name(rec);
+
+ return cr_name + strlen(cr_name) + 1;
+}
+
+/**
+ * Remap a record to the desired format as specified by the crf flags.
+ * The record must be big enough to contain the final remapped version.
+ * Superfluous extension fields are removed and missing ones are added
+ * and zeroed. The flags of the record are updated accordingly.
+ *
+ * The jobid and rename extensions can be added to a record, to match the
+ * format an application expects, typically. In this case, the newly added
+ * fields will be zeroed.
+ * The Jobid field can be removed, to guarantee compatibility with older
+ * clients that don't expect this field in the records they process.
+ *
+ * The following assumptions are being made:
+ * - CLF_RENAME will not be removed
+ * - CLF_JOBID will not be added without CLF_RENAME being added too
+ *
+ * @param[in,out] rec The record to remap.
+ * @param[in] crf_wanted Flags describing the desired extensions.
+ */
+static inline void changelog_remap_rec(struct changelog_rec *rec,
+ enum changelog_rec_flags crf_wanted)
+{
+ char *jid_mov, *rnm_mov;
+
+ crf_wanted &= CLF_SUPPORTED;
+
+ if ((rec->cr_flags & CLF_SUPPORTED) == crf_wanted)
+ return;
+
+ /* First move the variable-length name field */
+ memmove((char *)rec + changelog_rec_offset(crf_wanted),
+ changelog_rec_name(rec), rec->cr_namelen);
+
+ /* Locations of jobid and rename extensions in the remapped record */
+ jid_mov = (char *)rec +
+ changelog_rec_offset(crf_wanted & ~CLF_JOBID);
+ rnm_mov = (char *)rec +
+ changelog_rec_offset(crf_wanted & ~(CLF_JOBID | CLF_RENAME));
+
+ /* Move the extension fields to the desired positions */
+ if ((crf_wanted & CLF_JOBID) && (rec->cr_flags & CLF_JOBID))
+ memmove(jid_mov, changelog_rec_jobid(rec),
+ sizeof(struct changelog_ext_jobid));
+
+ if ((crf_wanted & CLF_RENAME) && (rec->cr_flags & CLF_RENAME))
+ memmove(rnm_mov, changelog_rec_rename(rec),
+ sizeof(struct changelog_ext_rename));
+
+ /* Clear newly added fields */
+ if ((crf_wanted & CLF_JOBID) && !(rec->cr_flags & CLF_JOBID))
+ memset(jid_mov, 0, sizeof(struct changelog_ext_jobid));
+
+ if ((crf_wanted & CLF_RENAME) && !(rec->cr_flags & CLF_RENAME))
+ memset(rnm_mov, 0, sizeof(struct changelog_ext_rename));
+
+ /* Update the record's flags accordingly */
+ rec->cr_flags = (rec->cr_flags & CLF_FLAGMASK) | crf_wanted;
}
struct ioc_changelog {
@@ -978,7 +1141,7 @@ struct hsm_user_request {
/** Return pointer to data field in a hsm user request */
static inline void *hur_data(struct hsm_user_request *hur)
{
- return &(hur->hur_user_item[hur->hur_request.hr_itemcount]);
+ return &hur->hur_user_item[hur->hur_request.hr_itemcount];
}
/**
diff --git a/drivers/staging/lustre/lustre/include/lustre_cfg.h b/drivers/staging/lustre/lustre/include/lustre_cfg.h
index 95a0be13c0fb..8eb394e64b25 100644
--- a/drivers/staging/lustre/lustre/include/lustre_cfg.h
+++ b/drivers/staging/lustre/lustre/include/lustre_cfg.h
@@ -151,13 +151,11 @@ static inline void lustre_cfg_bufs_reset(struct lustre_cfg_bufs *bufs, char *nam
lustre_cfg_bufs_set_string(bufs, 0, name);
}
-static inline void *lustre_cfg_buf(struct lustre_cfg *lcfg, int index)
+static inline void *lustre_cfg_buf(struct lustre_cfg *lcfg, __u32 index)
{
- int i;
- int offset;
- int bufcount;
-
- LASSERT(index >= 0);
+ __u32 i;
+ size_t offset;
+ __u32 bufcount;
bufcount = lcfg->lcfg_bufcount;
if (index >= bufcount)
@@ -172,7 +170,7 @@ static inline void *lustre_cfg_buf(struct lustre_cfg *lcfg, int index)
static inline void lustre_cfg_bufs_init(struct lustre_cfg_bufs *bufs,
struct lustre_cfg *lcfg)
{
- int i;
+ __u32 i;
bufs->lcfg_bufcount = lcfg->lcfg_bufcount;
for (i = 0; i < bufs->lcfg_bufcount; i++) {
@@ -181,7 +179,7 @@ static inline void lustre_cfg_bufs_init(struct lustre_cfg_bufs *bufs,
}
}
-static inline char *lustre_cfg_string(struct lustre_cfg *lcfg, int index)
+static inline char *lustre_cfg_string(struct lustre_cfg *lcfg, __u32 index)
{
char *s;
@@ -197,8 +195,8 @@ static inline char *lustre_cfg_string(struct lustre_cfg *lcfg, int index)
* of data. Try to use the padding first though.
*/
if (s[lcfg->lcfg_buflens[index] - 1] != '\0') {
- int last = min((int)lcfg->lcfg_buflens[index],
- cfs_size_round(lcfg->lcfg_buflens[index]) - 1);
+ size_t last = min((size_t)lcfg->lcfg_buflens[index],
+ cfs_size_round(lcfg->lcfg_buflens[index]) - 1);
char lost = s[last];
s[last] = '\0';
@@ -210,10 +208,10 @@ static inline char *lustre_cfg_string(struct lustre_cfg *lcfg, int index)
return s;
}
-static inline int lustre_cfg_len(__u32 bufcount, __u32 *buflens)
+static inline __u32 lustre_cfg_len(__u32 bufcount, __u32 *buflens)
{
- int i;
- int len;
+ __u32 i;
+ __u32 len;
len = LCFG_HDR_SIZE(bufcount);
for (i = 0; i < bufcount; i++)
@@ -254,7 +252,7 @@ static inline void lustre_cfg_free(struct lustre_cfg *lcfg)
return;
}
-static inline int lustre_cfg_sanity_check(void *buf, int len)
+static inline int lustre_cfg_sanity_check(void *buf, size_t len)
{
struct lustre_cfg *lcfg = (struct lustre_cfg *)buf;
diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h b/drivers/staging/lustre/lustre/include/lustre_compat.h
index 1eb64ec4bed4..567c438e93cb 100644
--- a/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h
+++ b/drivers/staging/lustre/lustre/include/lustre_compat.h
@@ -30,8 +30,8 @@
* Lustre is a trademark of Sun Microsystems, Inc.
*/
-#ifndef _LINUX_COMPAT25_H
-#define _LINUX_COMPAT25_H
+#ifndef _LUSTRE_COMPAT_H
+#define _LUSTRE_COMPAT_H
#include <linux/fs_struct.h>
#include <linux/namei.h>
@@ -74,4 +74,4 @@
# define ext2_find_next_zero_bit find_next_zero_bit_le
#endif
-#endif /* _COMPAT25_H */
+#endif /* _LUSTRE_COMPAT_H */
diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h
index 60051a5cfe20..d03534432624 100644
--- a/drivers/staging/lustre/lustre/include/lustre_dlm.h
+++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h
@@ -573,6 +573,11 @@ enum lvb_type {
};
/**
+ * LDLM_GID_ANY is used to match any group id in ldlm_lock_match().
+ */
+#define LDLM_GID_ANY ((__u64)-1)
+
+/**
* LDLM lock structure
*
* Represents a single LDLM lock and its state in memory. Each lock is
@@ -968,6 +973,7 @@ struct ldlm_enqueue_info {
void *ei_cb_cp; /** lock completion callback */
void *ei_cb_gl; /** lock glimpse callback */
void *ei_cbdata; /** Data to be passed into callbacks. */
+ unsigned int ei_enq_slave:1; /* whether enqueue slave stripes */
};
extern struct obd_ops ldlm_obd_ops;
@@ -1281,16 +1287,6 @@ int ldlm_cli_cancel_list(struct list_head *head, int count,
int intent_disposition(struct ldlm_reply *rep, int flag);
void intent_set_disposition(struct ldlm_reply *rep, int flag);
-/* ioctls for trying requests */
-#define IOC_LDLM_TYPE 'f'
-#define IOC_LDLM_MIN_NR 40
-
-#define IOC_LDLM_TEST _IOWR('f', 40, long)
-#define IOC_LDLM_DUMP _IOWR('f', 41, long)
-#define IOC_LDLM_REGRESS_START _IOWR('f', 42, long)
-#define IOC_LDLM_REGRESS_STOP _IOWR('f', 43, long)
-#define IOC_LDLM_MAX_NR 43
-
/**
* "Modes" of acquiring lock_res, necessary to tell lockdep that taking more
* than one lock_res is dead-lock safe.
diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h b/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h
index e7e0c21a9b40..a0f064d237c9 100644
--- a/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h
+++ b/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h
@@ -28,21 +28,6 @@
/** l_flags bits marked as "all_flags" bits */
#define LDLM_FL_ALL_FLAGS_MASK 0x00FFFFFFC08F932FULL
-/** l_flags bits marked as "ast" bits */
-#define LDLM_FL_AST_MASK 0x0000000080008000ULL
-
-/** l_flags bits marked as "blocked" bits */
-#define LDLM_FL_BLOCKED_MASK 0x000000000000000EULL
-
-/** l_flags bits marked as "gone" bits */
-#define LDLM_FL_GONE_MASK 0x0006004000000000ULL
-
-/** l_flags bits marked as "inherit" bits */
-#define LDLM_FL_INHERIT_MASK 0x0000000000800000ULL
-
-/** l_flags bits marked as "off_wire" bits */
-#define LDLM_FL_OFF_WIRE_MASK 0x00FFFFFF00000000ULL
-
/** extent, mode, or resource changed */
#define LDLM_FL_LOCK_CHANGED 0x0000000000000001ULL /* bit 0 */
#define ldlm_is_lock_changed(_l) LDLM_TEST_FLAG((_l), 1ULL << 0)
@@ -372,6 +357,27 @@
#define ldlm_set_excl(_l) LDLM_SET_FLAG((_l), 1ULL << 55)
#define ldlm_clear_excl(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 55)
+/** l_flags bits marked as "ast" bits */
+#define LDLM_FL_AST_MASK (LDLM_FL_FLOCK_DEADLOCK |\
+ LDLM_FL_AST_DISCARD_DATA)
+
+/** l_flags bits marked as "blocked" bits */
+#define LDLM_FL_BLOCKED_MASK (LDLM_FL_BLOCK_GRANTED |\
+ LDLM_FL_BLOCK_CONV |\
+ LDLM_FL_BLOCK_WAIT)
+
+/** l_flags bits marked as "gone" bits */
+#define LDLM_FL_GONE_MASK (LDLM_FL_DESTROYED |\
+ LDLM_FL_FAILED)
+
+/** l_flags bits marked as "inherit" bits */
+/* Flags inherited from wire on enqueue/reply between client/server. */
+/* NO_TIMEOUT flag to force ldlm_lock_match() to wait with no timeout. */
+/* TEST_LOCK flag to not let TEST lock to be granted. */
+#define LDLM_FL_INHERIT_MASK (LDLM_FL_CANCEL_ON_BLOCK |\
+ LDLM_FL_NO_TIMEOUT |\
+ LDLM_FL_TEST_LOCK)
+
/** test for ldlm_lock flag bit set */
#define LDLM_TEST_FLAG(_l, _b) (((_l)->l_flags & (_b)) != 0)
diff --git a/drivers/staging/lustre/lustre/include/lustre_eacl.h b/drivers/staging/lustre/lustre/include/lustre_eacl.h
index d1039e1ff70d..1e71a8638186 100644
--- a/drivers/staging/lustre/lustre/include/lustre_eacl.h
+++ b/drivers/staging/lustre/lustre/include/lustre_eacl.h
@@ -46,6 +46,7 @@
#ifdef CONFIG_FS_POSIX_ACL
+#include <linux/fs.h>
#include <linux/posix_acl_xattr.h>
typedef struct {
diff --git a/drivers/staging/lustre/lustre/include/lustre_fid.h b/drivers/staging/lustre/lustre/include/lustre_fid.h
index 743671a547ef..316780693193 100644
--- a/drivers/staging/lustre/lustre/include/lustre_fid.h
+++ b/drivers/staging/lustre/lustre/include/lustre_fid.h
@@ -229,6 +229,7 @@ enum local_oid {
MDD_LOV_OBJ_OSEQ = 4121UL,
LFSCK_NAMESPACE_OID = 4122UL,
REMOTE_PARENT_DIR_OID = 4123UL,
+ SLAVE_LLOG_CATALOGS_OID = 4124UL,
};
static inline void lu_local_obj_fid(struct lu_fid *fid, __u32 oid)
@@ -392,21 +393,19 @@ struct ldlm_namespace;
* but was moved into name[1] along with the OID to avoid consuming the
* renaming name[2,3] fields that need to be used for the quota identifier.
*/
-static inline struct ldlm_res_id *
+static inline void
fid_build_reg_res_name(const struct lu_fid *fid, struct ldlm_res_id *res)
{
memset(res, 0, sizeof(*res));
res->name[LUSTRE_RES_ID_SEQ_OFF] = fid_seq(fid);
res->name[LUSTRE_RES_ID_VER_OID_OFF] = fid_ver_oid(fid);
-
- return res;
}
/*
* Return true if resource is for object identified by FID.
*/
-static inline int fid_res_name_eq(const struct lu_fid *fid,
- const struct ldlm_res_id *res)
+static inline bool fid_res_name_eq(const struct lu_fid *fid,
+ const struct ldlm_res_id *res)
{
return res->name[LUSTRE_RES_ID_SEQ_OFF] == fid_seq(fid) &&
res->name[LUSTRE_RES_ID_VER_OID_OFF] == fid_ver_oid(fid);
@@ -415,29 +414,25 @@ static inline int fid_res_name_eq(const struct lu_fid *fid,
/*
* Extract FID from LDLM resource. Reverse of fid_build_reg_res_name().
*/
-static inline struct lu_fid *
+static inline void
fid_extract_from_res_name(struct lu_fid *fid, const struct ldlm_res_id *res)
{
fid->f_seq = res->name[LUSTRE_RES_ID_SEQ_OFF];
fid->f_oid = (__u32)(res->name[LUSTRE_RES_ID_VER_OID_OFF]);
fid->f_ver = (__u32)(res->name[LUSTRE_RES_ID_VER_OID_OFF] >> 32);
LASSERT(fid_res_name_eq(fid, res));
-
- return fid;
}
/*
* Build (DLM) resource identifier from global quota FID and quota ID.
*/
-static inline struct ldlm_res_id *
+static inline void
fid_build_quota_res_name(const struct lu_fid *glb_fid, union lquota_id *qid,
struct ldlm_res_id *res)
{
fid_build_reg_res_name(glb_fid, res);
res->name[LUSTRE_RES_ID_QUOTA_SEQ_OFF] = fid_seq(&qid->qid_fid);
res->name[LUSTRE_RES_ID_QUOTA_VER_OID_OFF] = fid_ver_oid(&qid->qid_fid);
-
- return res;
}
/*
@@ -454,14 +449,12 @@ static inline void fid_extract_from_quota_res(struct lu_fid *glb_fid,
(__u32)(res->name[LUSTRE_RES_ID_QUOTA_VER_OID_OFF] >> 32);
}
-static inline struct ldlm_res_id *
+static inline void
fid_build_pdo_res_name(const struct lu_fid *fid, unsigned int hash,
struct ldlm_res_id *res)
{
fid_build_reg_res_name(fid, res);
res->name[LUSTRE_RES_ID_HSH_OFF] = hash;
-
- return res;
}
/**
@@ -482,7 +475,7 @@ fid_build_pdo_res_name(const struct lu_fid *fid, unsigned int hash,
* res will be built from normal FID directly, i.e. res[0] = f_seq,
* res[1] = f_oid + f_ver.
*/
-static inline void ostid_build_res_name(struct ost_id *oi,
+static inline void ostid_build_res_name(const struct ost_id *oi,
struct ldlm_res_id *name)
{
memset(name, 0, sizeof(*name));
@@ -497,8 +490,8 @@ static inline void ostid_build_res_name(struct ost_id *oi,
/**
* Return true if the resource is for the object identified by this id & group.
*/
-static inline int ostid_res_name_eq(struct ost_id *oi,
- struct ldlm_res_id *name)
+static inline int ostid_res_name_eq(const struct ost_id *oi,
+ const struct ldlm_res_id *name)
{
/* Note: it is just a trick here to save some effort, probably the
* correct way would be turn them into the FID and compare
@@ -603,13 +596,14 @@ static inline __u32 fid_flatten32(const struct lu_fid *fid)
* (from OID), or up to 128M inodes without collisions for new files.
*/
ino = ((seq & 0x000fffffULL) << 12) + ((seq >> 8) & 0xfffff000) +
- (seq >> (64 - (40-8)) & 0xffffff00) +
+ (seq >> (64 - (40 - 8)) & 0xffffff00) +
(fid_oid(fid) & 0xff000fff) + ((fid_oid(fid) & 0x00fff000) << 8);
return ino ? ino : fid_oid(fid);
}
-static inline int lu_fid_diff(struct lu_fid *fid1, struct lu_fid *fid2)
+static inline int lu_fid_diff(const struct lu_fid *fid1,
+ const struct lu_fid *fid2)
{
LASSERTF(fid_seq(fid1) == fid_seq(fid2), "fid1:"DFID", fid2:"DFID"\n",
PFID(fid1), PFID(fid2));
diff --git a/drivers/staging/lustre/lustre/include/lustre_handles.h b/drivers/staging/lustre/lustre/include/lustre_handles.h
index 1a63a6b9e116..e071bac9df57 100644
--- a/drivers/staging/lustre/lustre/include/lustre_handles.h
+++ b/drivers/staging/lustre/lustre/include/lustre_handles.h
@@ -66,6 +66,7 @@ struct portals_handle_ops {
struct portals_handle {
struct list_head h_link;
__u64 h_cookie;
+ const void *h_owner;
struct portals_handle_ops *h_ops;
/* newly added fields to handle the RCU issue. -jxiong */
@@ -75,15 +76,13 @@ struct portals_handle {
unsigned int h_in:1;
};
-#define RCU2HANDLE(rcu) container_of(rcu, struct portals_handle, h_rcu)
-
/* handles.c */
/* Add a handle to the hash table */
void class_handle_hash(struct portals_handle *,
struct portals_handle_ops *ops);
void class_handle_unhash(struct portals_handle *);
-void *class_handle2object(__u64 cookie);
+void *class_handle2object(__u64 cookie, const void *owner);
void class_handle_free_cb(struct rcu_head *rcu);
int class_handle_init(void);
void class_handle_cleanup(void);
diff --git a/drivers/staging/lustre/lustre/include/lustre_import.h b/drivers/staging/lustre/lustre/include/lustre_import.h
index 4445be7a59dd..5461ba33d90c 100644
--- a/drivers/staging/lustre/lustre/include/lustre_import.h
+++ b/drivers/staging/lustre/lustre/include/lustre_import.h
@@ -285,8 +285,10 @@ struct obd_import {
imp_resend_replay:1,
/* disable normal recovery, for test only. */
imp_no_pinger_recover:1,
+#if OBD_OCD_VERSION(3, 0, 53, 0) > LUSTRE_VERSION_CODE
/* need IR MNE swab */
imp_need_mne_swab:1,
+#endif
/* import must be reconnected instead of
* chosing new connection
*/
@@ -305,28 +307,6 @@ struct obd_import {
time64_t imp_last_reply_time; /* for health check */
};
-typedef void (*obd_import_callback)(struct obd_import *imp, void *closure,
- int event, void *event_arg, void *cb_data);
-
-/**
- * Structure for import observer.
- * It is possible to register "observer" on an import and every time
- * something happens to an import (like connect/evict/disconnect)
- * obderver will get its callback called with event type
- */
-struct obd_import_observer {
- struct list_head oio_chain;
- obd_import_callback oio_cb;
- void *oio_cb_data;
-};
-
-void class_observe_import(struct obd_import *imp, obd_import_callback cb,
- void *cb_data);
-void class_unobserve_import(struct obd_import *imp, obd_import_callback cb,
- void *cb_data);
-void class_notify_import_observers(struct obd_import *imp, int event,
- void *event_arg);
-
/* import.c */
static inline unsigned int at_est2timeout(unsigned int val)
{
diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index 06958f217fc8..6b231913ba2e 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -51,7 +51,6 @@
#include "lustre_cfg.h"
/* target.c */
-struct kstatfs;
struct ptlrpc_request;
struct obd_export;
struct lu_target;
@@ -74,325 +73,8 @@ int do_set_info_async(struct obd_import *imp,
u32 vallen, void *val,
struct ptlrpc_request_set *set);
-#define OBD_RECOVERY_MAX_TIME (obd_timeout * 18) /* b13079 */
-#define OBD_MAX_IOCTL_BUFFER CONFIG_LUSTRE_OBD_MAX_IOCTL_BUFFER
-
void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id);
-/* client.c */
-
-int client_sanobd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg);
-struct client_obd *client_conn2cli(struct lustre_handle *conn);
-
-struct md_open_data;
-struct obd_client_handle {
- struct lustre_handle och_fh;
- struct lu_fid och_fid;
- struct md_open_data *och_mod;
- struct lustre_handle och_lease_handle; /* open lock for lease */
- __u32 och_magic;
- fmode_t och_flags;
-};
-
-#define OBD_CLIENT_HANDLE_MAGIC 0xd15ea5ed
-
-/* statfs_pack.c */
-void statfs_unpack(struct kstatfs *sfs, struct obd_statfs *osfs);
-
-/*
- * For md echo client
- */
-enum md_echo_cmd {
- ECHO_MD_CREATE = 1, /* Open/Create file on MDT */
- ECHO_MD_MKDIR = 2, /* Mkdir on MDT */
- ECHO_MD_DESTROY = 3, /* Unlink file on MDT */
- ECHO_MD_RMDIR = 4, /* Rmdir on MDT */
- ECHO_MD_LOOKUP = 5, /* Lookup on MDT */
- ECHO_MD_GETATTR = 6, /* Getattr on MDT */
- ECHO_MD_SETATTR = 7, /* Setattr on MDT */
- ECHO_MD_ALLOC_FID = 8, /* Get FIDs from MDT */
-};
-
-/*
- * OBD IOCTLS
- */
-#define OBD_IOCTL_VERSION 0x00010004
-
-struct obd_ioctl_data {
- __u32 ioc_len;
- __u32 ioc_version;
-
- union {
- __u64 ioc_cookie;
- __u64 ioc_u64_1;
- };
- union {
- __u32 ioc_conn1;
- __u32 ioc_u32_1;
- };
- union {
- __u32 ioc_conn2;
- __u32 ioc_u32_2;
- };
-
- struct obdo ioc_obdo1;
- struct obdo ioc_obdo2;
-
- u64 ioc_count;
- u64 ioc_offset;
- __u32 ioc_dev;
- __u32 ioc_command;
-
- __u64 ioc_nid;
- __u32 ioc_nal;
- __u32 ioc_type;
-
- /* buffers the kernel will treat as user pointers */
- __u32 ioc_plen1;
- void __user *ioc_pbuf1;
- __u32 ioc_plen2;
- void __user *ioc_pbuf2;
-
- /* inline buffers for various arguments */
- __u32 ioc_inllen1;
- char *ioc_inlbuf1;
- __u32 ioc_inllen2;
- char *ioc_inlbuf2;
- __u32 ioc_inllen3;
- char *ioc_inlbuf3;
- __u32 ioc_inllen4;
- char *ioc_inlbuf4;
-
- char ioc_bulk[0];
-};
-
-struct obd_ioctl_hdr {
- __u32 ioc_len;
- __u32 ioc_version;
-};
-
-static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)
-{
- int len = cfs_size_round(sizeof(struct obd_ioctl_data));
-
- len += cfs_size_round(data->ioc_inllen1);
- len += cfs_size_round(data->ioc_inllen2);
- len += cfs_size_round(data->ioc_inllen3);
- len += cfs_size_round(data->ioc_inllen4);
- return len;
-}
-
-static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
-{
- if (data->ioc_len > OBD_MAX_IOCTL_BUFFER) {
- CERROR("OBD ioctl: ioc_len larger than %d\n",
- OBD_MAX_IOCTL_BUFFER);
- return 1;
- }
- if (data->ioc_inllen1 > OBD_MAX_IOCTL_BUFFER) {
- CERROR("OBD ioctl: ioc_inllen1 larger than ioc_len\n");
- return 1;
- }
- if (data->ioc_inllen2 > OBD_MAX_IOCTL_BUFFER) {
- CERROR("OBD ioctl: ioc_inllen2 larger than ioc_len\n");
- return 1;
- }
- if (data->ioc_inllen3 > OBD_MAX_IOCTL_BUFFER) {
- CERROR("OBD ioctl: ioc_inllen3 larger than ioc_len\n");
- return 1;
- }
- if (data->ioc_inllen4 > OBD_MAX_IOCTL_BUFFER) {
- CERROR("OBD ioctl: ioc_inllen4 larger than ioc_len\n");
- return 1;
- }
- if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
- CERROR("OBD ioctl: inlbuf1 pointer but 0 length\n");
- return 1;
- }
- if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
- CERROR("OBD ioctl: inlbuf2 pointer but 0 length\n");
- return 1;
- }
- if (data->ioc_inlbuf3 && !data->ioc_inllen3) {
- CERROR("OBD ioctl: inlbuf3 pointer but 0 length\n");
- return 1;
- }
- if (data->ioc_inlbuf4 && !data->ioc_inllen4) {
- CERROR("OBD ioctl: inlbuf4 pointer but 0 length\n");
- return 1;
- }
- if (data->ioc_pbuf1 && !data->ioc_plen1) {
- CERROR("OBD ioctl: pbuf1 pointer but 0 length\n");
- return 1;
- }
- if (data->ioc_pbuf2 && !data->ioc_plen2) {
- CERROR("OBD ioctl: pbuf2 pointer but 0 length\n");
- return 1;
- }
- if (data->ioc_plen1 && !data->ioc_pbuf1) {
- CERROR("OBD ioctl: plen1 set but NULL pointer\n");
- return 1;
- }
- if (data->ioc_plen2 && !data->ioc_pbuf2) {
- CERROR("OBD ioctl: plen2 set but NULL pointer\n");
- return 1;
- }
- if (obd_ioctl_packlen(data) > data->ioc_len) {
- CERROR("OBD ioctl: packlen exceeds ioc_len (%d > %d)\n",
- obd_ioctl_packlen(data), data->ioc_len);
- return 1;
- }
- return 0;
-}
-
-#include "obd_support.h"
-
-/* function defined in lustre/obdclass/<platform>/<platform>-module.c */
-int obd_ioctl_getdata(char **buf, int *len, void __user *arg);
-int obd_ioctl_popdata(void __user *arg, void *data, int len);
-
-static inline void obd_ioctl_freedata(char *buf, int len)
-{
- kvfree(buf);
- return;
-}
-
-/*
- * BSD ioctl description:
- * #define IOC_V1 _IOR(g, n1, long)
- * #define IOC_V2 _IOW(g, n2, long)
- *
- * ioctl(f, IOC_V1, arg);
- * arg will be treated as a long value,
- *
- * ioctl(f, IOC_V2, arg)
- * arg will be treated as a pointer, bsd will call
- * copyin(buf, arg, sizeof(long))
- *
- * To make BSD ioctl handles argument correctly and simplely,
- * we change _IOR to _IOWR so BSD will copyin obd_ioctl_data
- * for us. Does this change affect Linux? (XXX Liang)
- */
-#define OBD_IOC_DATA_TYPE long
-
-#define OBD_IOC_CREATE _IOWR('f', 101, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_DESTROY _IOW('f', 104, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_PREALLOCATE _IOWR('f', 105, OBD_IOC_DATA_TYPE)
-
-#define OBD_IOC_SETATTR _IOW('f', 107, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_GETATTR _IOWR ('f', 108, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_READ _IOWR('f', 109, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_WRITE _IOWR('f', 110, OBD_IOC_DATA_TYPE)
-
-#define OBD_IOC_STATFS _IOWR('f', 113, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_SYNC _IOW('f', 114, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_READ2 _IOWR('f', 115, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_FORMAT _IOWR('f', 116, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_PARTITION _IOWR('f', 117, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_COPY _IOWR('f', 120, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_MIGR _IOWR('f', 121, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_PUNCH _IOWR('f', 122, OBD_IOC_DATA_TYPE)
-
-#define OBD_IOC_MODULE_DEBUG _IOWR('f', 124, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_BRW_READ _IOWR('f', 125, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_BRW_WRITE _IOWR('f', 126, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_NAME2DEV _IOWR('f', 127, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_UUID2DEV _IOWR('f', 130, OBD_IOC_DATA_TYPE)
-
-#define OBD_IOC_GETNAME _IOWR('f', 131, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_GETMDNAME _IOR('f', 131, char[MAX_OBD_NAME])
-#define OBD_IOC_GETDTNAME OBD_IOC_GETNAME
-
-#define OBD_IOC_LOV_GET_CONFIG _IOWR('f', 132, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_CLIENT_RECOVER _IOW('f', 133, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_PING_TARGET _IOW('f', 136, OBD_IOC_DATA_TYPE)
-
-#define OBD_IOC_DEC_FS_USE_COUNT _IO ('f', 139)
-#define OBD_IOC_NO_TRANSNO _IOW('f', 140, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_SET_READONLY _IOW('f', 141, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_ABORT_RECOVERY _IOR('f', 142, OBD_IOC_DATA_TYPE)
-
-#define OBD_IOC_ROOT_SQUASH _IOWR('f', 143, OBD_IOC_DATA_TYPE)
-
-#define OBD_GET_VERSION _IOWR ('f', 144, OBD_IOC_DATA_TYPE)
-
-#define OBD_IOC_GSS_SUPPORT _IOWR('f', 145, OBD_IOC_DATA_TYPE)
-
-#define OBD_IOC_CLOSE_UUID _IOWR ('f', 147, OBD_IOC_DATA_TYPE)
-
-#define OBD_IOC_CHANGELOG_SEND _IOW('f', 148, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_GETDEVICE _IOWR ('f', 149, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_FID2PATH _IOWR ('f', 150, OBD_IOC_DATA_TYPE)
-/* see also <lustre/lustre_user.h> for ioctls 151-153 */
-/* OBD_IOC_LOV_SETSTRIPE: See also LL_IOC_LOV_SETSTRIPE */
-#define OBD_IOC_LOV_SETSTRIPE _IOW('f', 154, OBD_IOC_DATA_TYPE)
-/* OBD_IOC_LOV_GETSTRIPE: See also LL_IOC_LOV_GETSTRIPE */
-#define OBD_IOC_LOV_GETSTRIPE _IOW('f', 155, OBD_IOC_DATA_TYPE)
-/* OBD_IOC_LOV_SETEA: See also LL_IOC_LOV_SETEA */
-#define OBD_IOC_LOV_SETEA _IOW('f', 156, OBD_IOC_DATA_TYPE)
-/* see <lustre/lustre_user.h> for ioctls 157-159 */
-/* OBD_IOC_QUOTACHECK: See also LL_IOC_QUOTACHECK */
-#define OBD_IOC_QUOTACHECK _IOW('f', 160, int)
-/* OBD_IOC_POLL_QUOTACHECK: See also LL_IOC_POLL_QUOTACHECK */
-#define OBD_IOC_POLL_QUOTACHECK _IOR('f', 161, struct if_quotacheck *)
-/* OBD_IOC_QUOTACTL: See also LL_IOC_QUOTACTL */
-#define OBD_IOC_QUOTACTL _IOWR('f', 162, struct if_quotactl)
-/* see also <lustre/lustre_user.h> for ioctls 163-176 */
-#define OBD_IOC_CHANGELOG_REG _IOW('f', 177, struct obd_ioctl_data)
-#define OBD_IOC_CHANGELOG_DEREG _IOW('f', 178, struct obd_ioctl_data)
-#define OBD_IOC_CHANGELOG_CLEAR _IOW('f', 179, struct obd_ioctl_data)
-#define OBD_IOC_RECORD _IOWR('f', 180, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_ENDRECORD _IOWR('f', 181, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_PARSE _IOWR('f', 182, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_DORECORD _IOWR('f', 183, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_PROCESS_CFG _IOWR('f', 184, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_DUMP_LOG _IOWR('f', 185, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_CLEAR_LOG _IOWR('f', 186, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_PARAM _IOW('f', 187, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_POOL _IOWR('f', 188, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_REPLACE_NIDS _IOWR('f', 189, OBD_IOC_DATA_TYPE)
-
-#define OBD_IOC_CATLOGLIST _IOWR('f', 190, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_LLOG_INFO _IOWR('f', 191, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_LLOG_PRINT _IOWR('f', 192, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_LLOG_CANCEL _IOWR('f', 193, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_LLOG_REMOVE _IOWR('f', 194, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_LLOG_CHECK _IOWR('f', 195, OBD_IOC_DATA_TYPE)
-/* OBD_IOC_LLOG_CATINFO is deprecated */
-#define OBD_IOC_LLOG_CATINFO _IOWR('f', 196, OBD_IOC_DATA_TYPE)
-
-/* #define ECHO_IOC_GET_STRIPE _IOWR('f', 200, OBD_IOC_DATA_TYPE) */
-/* #define ECHO_IOC_SET_STRIPE _IOWR('f', 201, OBD_IOC_DATA_TYPE) */
-/* #define ECHO_IOC_ENQUEUE _IOWR('f', 202, OBD_IOC_DATA_TYPE) */
-/* #define ECHO_IOC_CANCEL _IOWR('f', 203, OBD_IOC_DATA_TYPE) */
-
-#define OBD_IOC_GET_OBJ_VERSION _IOR('f', 210, OBD_IOC_DATA_TYPE)
-
-/* <lustre/lustre_user.h> defines ioctl number 218-219 */
-#define OBD_IOC_GET_MNTOPT _IOW('f', 220, mntopt_t)
-
-#define OBD_IOC_ECHO_MD _IOR('f', 221, struct obd_ioctl_data)
-#define OBD_IOC_ECHO_ALLOC_SEQ _IOWR('f', 222, struct obd_ioctl_data)
-
-#define OBD_IOC_START_LFSCK _IOWR('f', 230, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_STOP_LFSCK _IOW('f', 231, OBD_IOC_DATA_TYPE)
-#define OBD_IOC_PAUSE_LFSCK _IOW('f', 232, OBD_IOC_DATA_TYPE)
-
-/* XXX _IOWR('f', 250, long) has been defined in
- * libcfs/include/libcfs/libcfs_private.h for debug, don't use it
- */
-
-/* Until such time as we get_info the per-stripe maximum from the OST,
- * we define this to be 2T - 4k, which is the ext3 maxbytes.
- */
-#define LUSTRE_STRIPE_MAXBYTES 0x1fffffff000ULL
-
-/* Special values for remove LOV EA from disk */
-#define LOVEA_DELETE_VALUES(size, count, offset) (size == 0 && count == 0 && \
- offset == (typeof(offset))(-1))
-
-/* #define POISON_BULK 0 */
-
/*
* l_wait_event is a flexible sleeping function, permitting simple caller
* configuration of interrupt and timeout sensitivity along with actions to
diff --git a/drivers/staging/lustre/lustre/include/lustre_linkea.h b/drivers/staging/lustre/lustre/include/lustre_linkea.h
new file mode 100644
index 000000000000..249e8bf4fa22
--- /dev/null
+++ b/drivers/staging/lustre/lustre/include/lustre_linkea.h
@@ -0,0 +1,79 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * 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 version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2013, 2014, Intel Corporation.
+ * Use is subject to license terms.
+ *
+ * Author: di wang <di.wang@intel.com>
+ */
+
+#define DEFAULT_LINKEA_SIZE 4096
+
+struct linkea_data {
+ /**
+ * Buffer to keep link EA body.
+ */
+ struct lu_buf *ld_buf;
+ /**
+ * The matched header, entry and its length in the EA
+ */
+ struct link_ea_header *ld_leh;
+ struct link_ea_entry *ld_lee;
+ int ld_reclen;
+};
+
+int linkea_data_new(struct linkea_data *ldata, struct lu_buf *buf);
+int linkea_init(struct linkea_data *ldata);
+void linkea_entry_unpack(const struct link_ea_entry *lee, int *reclen,
+ struct lu_name *lname, struct lu_fid *pfid);
+int linkea_entry_pack(struct link_ea_entry *lee, const struct lu_name *lname,
+ const struct lu_fid *pfid);
+int linkea_add_buf(struct linkea_data *ldata, const struct lu_name *lname,
+ const struct lu_fid *pfid);
+void linkea_del_buf(struct linkea_data *ldata, const struct lu_name *lname);
+int linkea_links_find(struct linkea_data *ldata, const struct lu_name *lname,
+ const struct lu_fid *pfid);
+
+static inline void linkea_first_entry(struct linkea_data *ldata)
+{
+ LASSERT(ldata);
+ LASSERT(ldata->ld_leh);
+
+ if (ldata->ld_leh->leh_reccount == 0)
+ ldata->ld_lee = NULL;
+ else
+ ldata->ld_lee = (struct link_ea_entry *)(ldata->ld_leh + 1);
+}
+
+static inline void linkea_next_entry(struct linkea_data *ldata)
+{
+ LASSERT(ldata);
+ LASSERT(ldata->ld_leh);
+
+ if (ldata->ld_lee) {
+ ldata->ld_lee = (struct link_ea_entry *)((char *)ldata->ld_lee +
+ ldata->ld_reclen);
+ if ((char *)ldata->ld_lee >= ((char *)ldata->ld_leh +
+ ldata->ld_leh->leh_len))
+ ldata->ld_lee = NULL;
+ }
+}
diff --git a/drivers/staging/lustre/lustre/include/lustre_lite.h b/drivers/staging/lustre/lustre/include/lustre_lite.h
deleted file mode 100644
index b16897702559..000000000000
--- a/drivers/staging/lustre/lustre/include/lustre_lite.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef _LL_H
-#define _LL_H
-
-/** \defgroup lite lite
- *
- * @{
- */
-
-#include "linux/lustre_lite.h"
-
-#include "obd_class.h"
-#include "lustre_net.h"
-#include "lustre_mds.h"
-#include "lustre_ha.h"
-
-/* 4UL * 1024 * 1024 */
-#define LL_MAX_BLKSIZE_BITS (22)
-#define LL_MAX_BLKSIZE (1UL<<LL_MAX_BLKSIZE_BITS)
-
-/*
- * This is embedded into llite super-blocks to keep track of
- * connect flags (capabilities) supported by all imports given mount is
- * connected to.
- */
-struct lustre_client_ocd {
- /*
- * This is conjunction of connect_flags across all imports (LOVs) this
- * mount is connected to. This field is updated by cl_ocd_update()
- * under ->lco_lock.
- */
- __u64 lco_flags;
- struct mutex lco_lock;
- struct obd_export *lco_md_exp;
- struct obd_export *lco_dt_exp;
-};
-
-/*
- * Chain of hash overflow pages.
- */
-struct ll_dir_chain {
- /* XXX something. Later */
-};
-
-static inline void ll_dir_chain_init(struct ll_dir_chain *chain)
-{
-}
-
-static inline void ll_dir_chain_fini(struct ll_dir_chain *chain)
-{
-}
-
-static inline unsigned long hash_x_index(__u64 hash, int hash64)
-{
- if (BITS_PER_LONG == 32 && hash64)
- hash >>= 32;
- /* save hash 0 as index 0 because otherwise we'll save it at
- * page index end (~0UL) and it causes truncate_inode_pages_range()
- * to loop forever.
- */
- return ~0UL - (hash + !hash);
-}
-
-/** @} lite */
-
-#endif
diff --git a/drivers/staging/lustre/lustre/include/lustre_lmv.h b/drivers/staging/lustre/lustre/include/lustre_lmv.h
new file mode 100644
index 000000000000..d7f7afa8dfa7
--- /dev/null
+++ b/drivers/staging/lustre/lustre/include/lustre_lmv.h
@@ -0,0 +1,184 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * 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 version 2 for more details. A copy is
+ * included in the COPYING file that accompanied this code.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2013, Intel Corporation.
+ */
+/*
+ * lustre/include/lustre_lmv.h
+ *
+ * Lustre LMV structures and functions.
+ *
+ * Author: Di Wang <di.wang@intel.com>
+ */
+
+#ifndef _LUSTRE_LMV_H
+#define _LUSTRE_LMV_H
+#include "lustre/lustre_idl.h"
+
+struct lmv_oinfo {
+ struct lu_fid lmo_fid;
+ u32 lmo_mds;
+ struct inode *lmo_root;
+};
+
+struct lmv_stripe_md {
+ __u32 lsm_md_magic;
+ __u32 lsm_md_stripe_count;
+ __u32 lsm_md_master_mdt_index;
+ __u32 lsm_md_hash_type;
+ __u32 lsm_md_layout_version;
+ __u32 lsm_md_default_count;
+ __u32 lsm_md_default_index;
+ char lsm_md_pool_name[LOV_MAXPOOLNAME + 1];
+ struct lmv_oinfo lsm_md_oinfo[0];
+};
+
+static inline bool
+lsm_md_eq(const struct lmv_stripe_md *lsm1, const struct lmv_stripe_md *lsm2)
+{
+ __u32 idx;
+
+ if (lsm1->lsm_md_magic != lsm2->lsm_md_magic ||
+ lsm1->lsm_md_stripe_count != lsm2->lsm_md_stripe_count ||
+ lsm1->lsm_md_master_mdt_index != lsm2->lsm_md_master_mdt_index ||
+ lsm1->lsm_md_hash_type != lsm2->lsm_md_hash_type ||
+ lsm1->lsm_md_layout_version != lsm2->lsm_md_layout_version ||
+ !strcmp(lsm1->lsm_md_pool_name, lsm2->lsm_md_pool_name))
+ return false;
+
+ for (idx = 0; idx < lsm1->lsm_md_stripe_count; idx++) {
+ if (!lu_fid_eq(&lsm1->lsm_md_oinfo[idx].lmo_fid,
+ &lsm2->lsm_md_oinfo[idx].lmo_fid))
+ return false;
+ }
+
+ return true;
+}
+
+union lmv_mds_md;
+
+int lmv_unpack_md(struct obd_export *exp, struct lmv_stripe_md **lsmp,
+ const union lmv_mds_md *lmm, int stripe_count);
+
+static inline int lmv_alloc_memmd(struct lmv_stripe_md **lsmp, int stripe_count)
+{
+ return lmv_unpack_md(NULL, lsmp, NULL, stripe_count);
+}
+
+static inline void lmv_free_memmd(struct lmv_stripe_md *lsm)
+{
+ lmv_unpack_md(NULL, &lsm, NULL, 0);
+}
+
+static inline void lmv1_le_to_cpu(struct lmv_mds_md_v1 *lmv_dst,
+ const struct lmv_mds_md_v1 *lmv_src)
+{
+ __u32 i;
+
+ lmv_dst->lmv_magic = le32_to_cpu(lmv_src->lmv_magic);
+ lmv_dst->lmv_stripe_count = le32_to_cpu(lmv_src->lmv_stripe_count);
+ lmv_dst->lmv_master_mdt_index =
+ le32_to_cpu(lmv_src->lmv_master_mdt_index);
+ lmv_dst->lmv_hash_type = le32_to_cpu(lmv_src->lmv_hash_type);
+ lmv_dst->lmv_layout_version = le32_to_cpu(lmv_src->lmv_layout_version);
+
+ for (i = 0; i < lmv_src->lmv_stripe_count; i++)
+ fid_le_to_cpu(&lmv_dst->lmv_stripe_fids[i],
+ &lmv_src->lmv_stripe_fids[i]);
+}
+
+static inline void lmv_le_to_cpu(union lmv_mds_md *lmv_dst,
+ const union lmv_mds_md *lmv_src)
+{
+ switch (le32_to_cpu(lmv_src->lmv_magic)) {
+ case LMV_MAGIC_V1:
+ lmv1_le_to_cpu(&lmv_dst->lmv_md_v1, &lmv_src->lmv_md_v1);
+ break;
+ default:
+ break;
+ }
+}
+
+/* This hash is only for testing purpose */
+static inline unsigned int
+lmv_hash_all_chars(unsigned int count, const char *name, int namelen)
+{
+ const unsigned char *p = (const unsigned char *)name;
+ unsigned int c = 0;
+
+ while (--namelen >= 0)
+ c += p[namelen];
+
+ c = c % count;
+
+ return c;
+}
+
+static inline unsigned int
+lmv_hash_fnv1a(unsigned int count, const char *name, int namelen)
+{
+ __u64 hash;
+
+ hash = lustre_hash_fnv_1a_64(name, namelen);
+
+ return do_div(hash, count);
+}
+
+static inline int lmv_name_to_stripe_index(__u32 lmv_hash_type,
+ unsigned int stripe_count,
+ const char *name, int namelen)
+{
+ __u32 hash_type = lmv_hash_type & LMV_HASH_TYPE_MASK;
+ int idx;
+
+ LASSERT(namelen > 0);
+ if (stripe_count <= 1)
+ return 0;
+
+ /* for migrating object, always start from 0 stripe */
+ if (lmv_hash_type & LMV_HASH_FLAG_MIGRATION)
+ return 0;
+
+ switch (hash_type) {
+ case LMV_HASH_TYPE_ALL_CHARS:
+ idx = lmv_hash_all_chars(stripe_count, name, namelen);
+ break;
+ case LMV_HASH_TYPE_FNV_1A_64:
+ idx = lmv_hash_fnv1a(stripe_count, name, namelen);
+ break;
+ default:
+ idx = -EBADFD;
+ break;
+ }
+ CDEBUG(D_INFO, "name %.*s hash_type %d idx %d\n", namelen, name,
+ hash_type, idx);
+
+ return idx;
+}
+
+static inline bool lmv_is_known_hash_type(__u32 type)
+{
+ return (type & LMV_HASH_TYPE_MASK) == LMV_HASH_TYPE_FNV_1A_64 ||
+ (type & LMV_HASH_TYPE_MASK) == LMV_HASH_TYPE_ALL_CHARS;
+}
+
+#endif
diff --git a/drivers/staging/lustre/lustre/include/lustre_log.h b/drivers/staging/lustre/lustre/include/lustre_log.h
index b96e02317bfc..995b266932e3 100644
--- a/drivers/staging/lustre/lustre/include/lustre_log.h
+++ b/drivers/staging/lustre/lustre/include/lustre_log.h
@@ -277,12 +277,11 @@ static inline void llog_ctxt_put(struct llog_ctxt *ctxt)
__llog_ctxt_put(NULL, ctxt);
}
-static inline void llog_group_init(struct obd_llog_group *olg, int group)
+static inline void llog_group_init(struct obd_llog_group *olg)
{
init_waitqueue_head(&olg->olg_waitq);
spin_lock_init(&olg->olg_lock);
mutex_init(&olg->olg_cat_processing);
- olg->olg_seq = group;
}
static inline int llog_group_set_ctxt(struct obd_llog_group *olg,
diff --git a/drivers/staging/lustre/lustre/include/lustre_mdc.h b/drivers/staging/lustre/lustre/include/lustre_mdc.h
index fa62b95d351f..8fc2d3f2dfd6 100644
--- a/drivers/staging/lustre/lustre/include/lustre_mdc.h
+++ b/drivers/staging/lustre/lustre/include/lustre_mdc.h
@@ -96,7 +96,7 @@ static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck,
struct lookup_intent *it)
{
if (it && (it->it_op == IT_GETATTR || it->it_op == IT_LOOKUP ||
- it->it_op == IT_LAYOUT))
+ it->it_op == IT_LAYOUT || it->it_op == IT_READDIR))
return;
/* This would normally block until the existing request finishes.
@@ -136,7 +136,7 @@ static inline void mdc_put_rpc_lock(struct mdc_rpc_lock *lck,
struct lookup_intent *it)
{
if (it && (it->it_op == IT_GETATTR || it->it_op == IT_LOOKUP ||
- it->it_op == IT_LAYOUT))
+ it->it_op == IT_LAYOUT || it->it_op == IT_READDIR))
return;
if (lck->rpcl_it == MDC_FAKE_RPCL_IT) { /* OBD_FAIL_MDC_RPCS_SEM */
@@ -156,34 +156,44 @@ static inline void mdc_put_rpc_lock(struct mdc_rpc_lock *lck,
mutex_unlock(&lck->rpcl_mutex);
}
-/* Update the maximum observed easize and cookiesize. The default easize
- * and cookiesize is initialized to the minimum value but allowed to grow
- * up to a single page in size if required to handle the common case.
+/**
+ * Update the maximum possible easize and cookiesize.
+ *
+ * The values are learned from ptlrpc replies sent by the MDT. The
+ * default easize and cookiesize is initialized to the minimum value but
+ * allowed to grow up to a single page in size if required to handle the
+ * common case.
+ *
+ * \see client_obd::cl_default_mds_easize and
+ * client_obd::cl_default_mds_cookiesize
+ *
+ * \param[in] exp export for MDC device
+ * \param[in] body body of ptlrpc reply from MDT
+ *
*/
static inline void mdc_update_max_ea_from_body(struct obd_export *exp,
struct mdt_body *body)
{
- if (body->valid & OBD_MD_FLMODEASIZE) {
+ if (body->mbo_valid & OBD_MD_FLMODEASIZE) {
struct client_obd *cli = &exp->exp_obd->u.cli;
+ u32 def_cookiesize, def_easize;
- if (cli->cl_max_mds_easize < body->max_mdsize) {
- cli->cl_max_mds_easize = body->max_mdsize;
- cli->cl_default_mds_easize =
- min_t(__u32, body->max_mdsize, PAGE_SIZE);
- }
- if (cli->cl_max_mds_cookiesize < body->max_cookiesize) {
- cli->cl_max_mds_cookiesize = body->max_cookiesize;
- cli->cl_default_mds_cookiesize =
- min_t(__u32, body->max_cookiesize, PAGE_SIZE);
- }
+ if (cli->cl_max_mds_easize < body->mbo_max_mdsize)
+ cli->cl_max_mds_easize = body->mbo_max_mdsize;
+
+ def_easize = min_t(__u32, body->mbo_max_mdsize,
+ OBD_MAX_DEFAULT_EA_SIZE);
+ cli->cl_default_mds_easize = def_easize;
+
+ if (cli->cl_max_mds_cookiesize < body->mbo_max_cookiesize)
+ cli->cl_max_mds_cookiesize = body->mbo_max_cookiesize;
+
+ def_cookiesize = min_t(__u32, body->mbo_max_cookiesize,
+ OBD_MAX_DEFAULT_COOKIE_SIZE);
+ cli->cl_default_mds_cookiesize = def_cookiesize;
}
}
-struct mdc_cache_waiter {
- struct list_head mcw_entry;
- wait_queue_head_t mcw_waitq;
-};
-
/* mdc/mdc_locks.c */
int it_open_error(int phase, struct lookup_intent *it);
diff --git a/drivers/staging/lustre/lustre/include/lustre_mds.h b/drivers/staging/lustre/lustre/include/lustre_mds.h
index 4104bd9bd5c4..23a7e4f78e9a 100644
--- a/drivers/staging/lustre/lustre/include/lustre_mds.h
+++ b/drivers/staging/lustre/lustre/include/lustre_mds.h
@@ -58,9 +58,6 @@ struct mds_group_info {
#define MDD_OBD_NAME "mdd_obd"
#define MDD_OBD_UUID "mdd_obd_uuid"
-/* these are local flags, used only on the client, private */
-#define M_CHECK_STALE 0200000000
-
/** @} mds */
#endif
diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h
index d5debd615fdf..e9aba99ee52a 100644
--- a/drivers/staging/lustre/lustre/include/lustre_net.h
+++ b/drivers/staging/lustre/lustre/include/lustre_net.h
@@ -261,7 +261,10 @@
#define MDS_MAXREQSIZE (5 * 1024) /* >= 4736 */
-#define OST_MAXREQSIZE (5 * 1024)
+/**
+ * FIEMAP request can be 4K+ for now
+ */
+#define OST_MAXREQSIZE (16 * 1024)
/* Macro to hide a typecast. */
#define ptlrpc_req_async_args(req) ((void *)&req->rq_async_args)
@@ -570,13 +573,13 @@ struct ptlrpc_nrs_pol_ops {
*
* \param[in,out] policy The policy being initialized
*/
- int (*op_policy_init) (struct ptlrpc_nrs_policy *policy);
+ int (*op_policy_init)(struct ptlrpc_nrs_policy *policy);
/**
* Called during policy unregistration; this operation is optional.
*
* \param[in,out] policy The policy being unregistered/finalized
*/
- void (*op_policy_fini) (struct ptlrpc_nrs_policy *policy);
+ void (*op_policy_fini)(struct ptlrpc_nrs_policy *policy);
/**
* Called when activating a policy via lprocfs; policies allocate and
* initialize their resources here; this operation is optional.
@@ -585,7 +588,7 @@ struct ptlrpc_nrs_pol_ops {
*
* \see nrs_policy_start_locked()
*/
- int (*op_policy_start) (struct ptlrpc_nrs_policy *policy);
+ int (*op_policy_start)(struct ptlrpc_nrs_policy *policy);
/**
* Called when deactivating a policy via lprocfs; policies deallocate
* their resources here; this operation is optional
@@ -594,7 +597,7 @@ struct ptlrpc_nrs_pol_ops {
*
* \see nrs_policy_stop0()
*/
- void (*op_policy_stop) (struct ptlrpc_nrs_policy *policy);
+ void (*op_policy_stop)(struct ptlrpc_nrs_policy *policy);
/**
* Used for policy-specific operations; i.e. not generic ones like
* \e PTLRPC_NRS_CTL_START and \e PTLRPC_NRS_CTL_GET_INFO; analogous
@@ -610,8 +613,8 @@ struct ptlrpc_nrs_pol_ops {
*
* \see ptlrpc_nrs_policy_control()
*/
- int (*op_policy_ctl) (struct ptlrpc_nrs_policy *policy,
- enum ptlrpc_nrs_ctl opc, void *arg);
+ int (*op_policy_ctl)(struct ptlrpc_nrs_policy *policy,
+ enum ptlrpc_nrs_ctl opc, void *arg);
/**
* Called when obtaining references to the resources of the resource
@@ -648,11 +651,11 @@ struct ptlrpc_nrs_pol_ops {
* \see ptlrpc_nrs_req_initialize()
* \see ptlrpc_nrs_hpreq_add_nolock()
*/
- int (*op_res_get) (struct ptlrpc_nrs_policy *policy,
- struct ptlrpc_nrs_request *nrq,
- const struct ptlrpc_nrs_resource *parent,
- struct ptlrpc_nrs_resource **resp,
- bool moving_req);
+ int (*op_res_get)(struct ptlrpc_nrs_policy *policy,
+ struct ptlrpc_nrs_request *nrq,
+ const struct ptlrpc_nrs_resource *parent,
+ struct ptlrpc_nrs_resource **resp,
+ bool moving_req);
/**
* Called when releasing references taken for resources in the resource
* hierarchy for the request; this operation is optional.
@@ -663,8 +666,8 @@ struct ptlrpc_nrs_pol_ops {
* \see ptlrpc_nrs_req_finalize()
* \see ptlrpc_nrs_hpreq_add_nolock()
*/
- void (*op_res_put) (struct ptlrpc_nrs_policy *policy,
- const struct ptlrpc_nrs_resource *res);
+ void (*op_res_put)(struct ptlrpc_nrs_policy *policy,
+ const struct ptlrpc_nrs_resource *res);
/**
* Obtains a request for handling from the policy, and optionally
@@ -683,8 +686,8 @@ struct ptlrpc_nrs_pol_ops {
* \see ptlrpc_nrs_req_get_nolock()
*/
struct ptlrpc_nrs_request *
- (*op_req_get) (struct ptlrpc_nrs_policy *policy, bool peek,
- bool force);
+ (*op_req_get)(struct ptlrpc_nrs_policy *policy, bool peek,
+ bool force);
/**
* Called when attempting to add a request to a policy for later
* handling; this operation is mandatory.
@@ -697,8 +700,8 @@ struct ptlrpc_nrs_pol_ops {
*
* \see ptlrpc_nrs_req_add_nolock()
*/
- int (*op_req_enqueue) (struct ptlrpc_nrs_policy *policy,
- struct ptlrpc_nrs_request *nrq);
+ int (*op_req_enqueue)(struct ptlrpc_nrs_policy *policy,
+ struct ptlrpc_nrs_request *nrq);
/**
* Removes a request from the policy's set of pending requests. Normally
* called after a request has been polled successfully from the policy
@@ -707,8 +710,8 @@ struct ptlrpc_nrs_pol_ops {
* \param[in,out] policy The policy the request \a nrq belongs to
* \param[in,out] nrq The request to dequeue
*/
- void (*op_req_dequeue) (struct ptlrpc_nrs_policy *policy,
- struct ptlrpc_nrs_request *nrq);
+ void (*op_req_dequeue)(struct ptlrpc_nrs_policy *policy,
+ struct ptlrpc_nrs_request *nrq);
/**
* Called after the request being carried out. Could be used for
* job/resource control; this operation is optional.
@@ -721,8 +724,8 @@ struct ptlrpc_nrs_pol_ops {
*
* \see ptlrpc_nrs_req_stop_nolock()
*/
- void (*op_req_stop) (struct ptlrpc_nrs_policy *policy,
- struct ptlrpc_nrs_request *nrq);
+ void (*op_req_stop)(struct ptlrpc_nrs_policy *policy,
+ struct ptlrpc_nrs_request *nrq);
/**
* Registers the policy's lprocfs interface with a PTLRPC service.
*
@@ -731,7 +734,7 @@ struct ptlrpc_nrs_pol_ops {
* \retval 0 success
* \retval != 0 error
*/
- int (*op_lprocfs_init) (struct ptlrpc_service *svc);
+ int (*op_lprocfs_init)(struct ptlrpc_service *svc);
/**
* Unegisters the policy's lprocfs interface with a PTLRPC service.
*
@@ -743,7 +746,7 @@ struct ptlrpc_nrs_pol_ops {
*
* \param[in] svc The service
*/
- void (*op_lprocfs_fini) (struct ptlrpc_service *svc);
+ void (*op_lprocfs_fini)(struct ptlrpc_service *svc);
};
/**
@@ -1628,7 +1631,7 @@ static inline bool ptlrpc_nrs_req_can_move(struct ptlrpc_request *req)
/**
* Returns 1 if request buffer at offset \a index was already swabbed
*/
-static inline int lustre_req_swabbed(struct ptlrpc_request *req, int index)
+static inline int lustre_req_swabbed(struct ptlrpc_request *req, size_t index)
{
LASSERT(index < sizeof(req->rq_req_swab_mask) * 8);
return req->rq_req_swab_mask & (1 << index);
@@ -1637,7 +1640,7 @@ static inline int lustre_req_swabbed(struct ptlrpc_request *req, int index)
/**
* Returns 1 if request reply buffer at offset \a index was already swabbed
*/
-static inline int lustre_rep_swabbed(struct ptlrpc_request *req, int index)
+static inline int lustre_rep_swabbed(struct ptlrpc_request *req, size_t index)
{
LASSERT(index < sizeof(req->rq_rep_swab_mask) * 8);
return req->rq_rep_swab_mask & (1 << index);
@@ -1662,7 +1665,8 @@ static inline int ptlrpc_rep_need_swab(struct ptlrpc_request *req)
/**
* Mark request buffer at offset \a index that it was already swabbed
*/
-static inline void lustre_set_req_swabbed(struct ptlrpc_request *req, int index)
+static inline void lustre_set_req_swabbed(struct ptlrpc_request *req,
+ size_t index)
{
LASSERT(index < sizeof(req->rq_req_swab_mask) * 8);
LASSERT((req->rq_req_swab_mask & (1 << index)) == 0);
@@ -1672,7 +1676,8 @@ static inline void lustre_set_req_swabbed(struct ptlrpc_request *req, int index)
/**
* Mark request reply buffer at offset \a index that it was already swabbed
*/
-static inline void lustre_set_rep_swabbed(struct ptlrpc_request *req, int index)
+static inline void lustre_set_rep_swabbed(struct ptlrpc_request *req,
+ size_t index)
{
LASSERT(index < sizeof(req->rq_rep_swab_mask) * 8);
LASSERT((req->rq_rep_swab_mask & (1 << index)) == 0);
@@ -2403,7 +2408,6 @@ int ptlrpc_send_reply(struct ptlrpc_request *req, int flags);
int ptlrpc_reply(struct ptlrpc_request *req);
int ptlrpc_send_error(struct ptlrpc_request *req, int difficult);
int ptlrpc_error(struct ptlrpc_request *req);
-void ptlrpc_resend_req(struct ptlrpc_request *request);
int ptlrpc_at_get_net_latency(struct ptlrpc_request *req);
int ptl_send_rpc(struct ptlrpc_request *request, int noreply);
int ptlrpc_register_rqbd(struct ptlrpc_request_buffer_desc *rqbd);
@@ -2423,23 +2427,17 @@ struct ptlrpc_connection *ptlrpc_uuid_to_connection(struct obd_uuid *uuid);
int ptlrpc_queue_wait(struct ptlrpc_request *req);
int ptlrpc_replay_req(struct ptlrpc_request *req);
-int ptlrpc_unregister_reply(struct ptlrpc_request *req, int async);
void ptlrpc_abort_inflight(struct obd_import *imp);
void ptlrpc_abort_set(struct ptlrpc_request_set *set);
struct ptlrpc_request_set *ptlrpc_prep_set(void);
struct ptlrpc_request_set *ptlrpc_prep_fcset(int max, set_producer_func func,
void *arg);
-int ptlrpc_set_next_timeout(struct ptlrpc_request_set *);
int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set);
int ptlrpc_set_wait(struct ptlrpc_request_set *);
-int ptlrpc_expired_set(void *data);
-void ptlrpc_interrupted_set(void *data);
void ptlrpc_mark_interrupted(struct ptlrpc_request *req);
void ptlrpc_set_destroy(struct ptlrpc_request_set *);
void ptlrpc_set_add_req(struct ptlrpc_request_set *, struct ptlrpc_request *);
-void ptlrpc_set_add_new_req(struct ptlrpcd_ctl *pc,
- struct ptlrpc_request *req);
void ptlrpc_free_rq_pool(struct ptlrpc_request_pool *pool);
int ptlrpc_add_rqs_to_pool(struct ptlrpc_request_pool *pool, int num_rq);
@@ -2611,9 +2609,9 @@ int ptlrpc_reconnect_import(struct obd_import *imp);
* @{
*/
int ptlrpc_buf_need_swab(struct ptlrpc_request *req, const int inout,
- int index);
+ u32 index);
void ptlrpc_buf_set_swabbed(struct ptlrpc_request *req, const int inout,
- int index);
+ u32 index);
int ptlrpc_unpack_rep_msg(struct ptlrpc_request *req, int len);
int ptlrpc_unpack_req_msg(struct ptlrpc_request *req, int len);
@@ -2632,27 +2630,27 @@ int lustre_shrink_msg(struct lustre_msg *msg, int segment,
unsigned int newlen, int move_data);
void lustre_free_reply_state(struct ptlrpc_reply_state *rs);
int __lustre_unpack_msg(struct lustre_msg *m, int len);
-int lustre_msg_hdr_size(__u32 magic, int count);
-int lustre_msg_size(__u32 magic, int count, __u32 *lengths);
-int lustre_msg_size_v2(int count, __u32 *lengths);
-int lustre_packed_msg_size(struct lustre_msg *msg);
-int lustre_msg_early_size(void);
-void *lustre_msg_buf_v2(struct lustre_msg_v2 *m, int n, int min_size);
-void *lustre_msg_buf(struct lustre_msg *m, int n, int minlen);
-int lustre_msg_buflen(struct lustre_msg *m, int n);
-int lustre_msg_bufcount(struct lustre_msg *m);
-char *lustre_msg_string(struct lustre_msg *m, int n, int max_len);
+u32 lustre_msg_hdr_size(__u32 magic, u32 count);
+u32 lustre_msg_size(__u32 magic, int count, __u32 *lengths);
+u32 lustre_msg_size_v2(int count, __u32 *lengths);
+u32 lustre_packed_msg_size(struct lustre_msg *msg);
+u32 lustre_msg_early_size(void);
+void *lustre_msg_buf_v2(struct lustre_msg_v2 *m, u32 n, u32 min_size);
+void *lustre_msg_buf(struct lustre_msg *m, u32 n, u32 minlen);
+u32 lustre_msg_buflen(struct lustre_msg *m, u32 n);
+u32 lustre_msg_bufcount(struct lustre_msg *m);
+char *lustre_msg_string(struct lustre_msg *m, u32 n, u32 max_len);
__u32 lustre_msghdr_get_flags(struct lustre_msg *msg);
void lustre_msghdr_set_flags(struct lustre_msg *msg, __u32 flags);
__u32 lustre_msg_get_flags(struct lustre_msg *msg);
-void lustre_msg_add_flags(struct lustre_msg *msg, int flags);
-void lustre_msg_set_flags(struct lustre_msg *msg, int flags);
-void lustre_msg_clear_flags(struct lustre_msg *msg, int flags);
+void lustre_msg_add_flags(struct lustre_msg *msg, u32 flags);
+void lustre_msg_set_flags(struct lustre_msg *msg, u32 flags);
+void lustre_msg_clear_flags(struct lustre_msg *msg, u32 flags);
__u32 lustre_msg_get_op_flags(struct lustre_msg *msg);
-void lustre_msg_add_op_flags(struct lustre_msg *msg, int flags);
+void lustre_msg_add_op_flags(struct lustre_msg *msg, u32 flags);
struct lustre_handle *lustre_msg_get_handle(struct lustre_msg *msg);
__u32 lustre_msg_get_type(struct lustre_msg *msg);
-void lustre_msg_add_version(struct lustre_msg *msg, int version);
+void lustre_msg_add_version(struct lustre_msg *msg, u32 version);
__u32 lustre_msg_get_opc(struct lustre_msg *msg);
__u64 lustre_msg_get_last_committed(struct lustre_msg *msg);
__u64 *lustre_msg_get_versions(struct lustre_msg *msg);
diff --git a/drivers/staging/lustre/lustre/include/lustre_param.h b/drivers/staging/lustre/lustre/include/lustre_param.h
index 82aadd32c2b8..8061a04ee806 100644
--- a/drivers/staging/lustre/lustre/include/lustre_param.h
+++ b/drivers/staging/lustre/lustre/include/lustre_param.h
@@ -39,6 +39,9 @@
#ifndef _LUSTRE_PARAM_H
#define _LUSTRE_PARAM_H
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../../include/linux/lnet/types.h"
+
/** \defgroup param param
*
* @{
diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_patchless_compat.h b/drivers/staging/lustre/lustre/include/lustre_patchless_compat.h
index 5842cb18b49e..5842cb18b49e 100644
--- a/drivers/staging/lustre/lustre/include/linux/lustre_patchless_compat.h
+++ b/drivers/staging/lustre/lustre/include/lustre_patchless_compat.h
diff --git a/drivers/staging/lustre/lustre/include/lustre_req_layout.h b/drivers/staging/lustre/lustre/include/lustre_req_layout.h
index 544a43c862b9..a13558e53274 100644
--- a/drivers/staging/lustre/lustre/include/lustre_req_layout.h
+++ b/drivers/staging/lustre/lustre/include/lustre_req_layout.h
@@ -76,7 +76,8 @@ void req_capsule_init(struct req_capsule *pill, struct ptlrpc_request *req,
void req_capsule_fini(struct req_capsule *pill);
void req_capsule_set(struct req_capsule *pill, const struct req_format *fmt);
-int req_capsule_filled_sizes(struct req_capsule *pill, enum req_location loc);
+size_t req_capsule_filled_sizes(struct req_capsule *pill,
+ enum req_location loc);
int req_capsule_server_pack(struct req_capsule *pill);
void *req_capsule_client_get(struct req_capsule *pill,
@@ -86,27 +87,27 @@ void *req_capsule_client_swab_get(struct req_capsule *pill,
void *swabber);
void *req_capsule_client_sized_get(struct req_capsule *pill,
const struct req_msg_field *field,
- int len);
+ u32 len);
void *req_capsule_server_get(struct req_capsule *pill,
const struct req_msg_field *field);
void *req_capsule_server_sized_get(struct req_capsule *pill,
const struct req_msg_field *field,
- int len);
+ u32 len);
void *req_capsule_server_swab_get(struct req_capsule *pill,
const struct req_msg_field *field,
void *swabber);
void *req_capsule_server_sized_swab_get(struct req_capsule *pill,
const struct req_msg_field *field,
- int len, void *swabber);
+ u32 len, void *swabber);
void req_capsule_set_size(struct req_capsule *pill,
const struct req_msg_field *field,
- enum req_location loc, int size);
-int req_capsule_get_size(const struct req_capsule *pill,
+ enum req_location loc, u32 size);
+u32 req_capsule_get_size(const struct req_capsule *pill,
const struct req_msg_field *field,
enum req_location loc);
-int req_capsule_msg_size(struct req_capsule *pill, enum req_location loc);
-int req_capsule_fmt_size(__u32 magic, const struct req_format *fmt,
+u32 req_capsule_msg_size(struct req_capsule *pill, enum req_location loc);
+u32 req_capsule_fmt_size(__u32 magic, const struct req_format *fmt,
enum req_location loc);
void req_capsule_extend(struct req_capsule *pill, const struct req_format *fmt);
@@ -115,8 +116,7 @@ int req_capsule_has_field(const struct req_capsule *pill,
enum req_location loc);
void req_capsule_shrink(struct req_capsule *pill,
const struct req_msg_field *field,
- unsigned int newlen,
- enum req_location loc);
+ u32 newlen, enum req_location loc);
int req_layout_init(void);
void req_layout_fini(void);
@@ -149,14 +149,11 @@ extern struct req_format RQF_MDS_GETATTR;
extern struct req_format RQF_MDS_GETATTR_NAME;
extern struct req_format RQF_MDS_CLOSE;
extern struct req_format RQF_MDS_RELEASE_CLOSE;
-extern struct req_format RQF_MDS_PIN;
-extern struct req_format RQF_MDS_UNPIN;
extern struct req_format RQF_MDS_CONNECT;
extern struct req_format RQF_MDS_DISCONNECT;
extern struct req_format RQF_MDS_GET_INFO;
extern struct req_format RQF_MDS_READPAGE;
extern struct req_format RQF_MDS_WRITEPAGE;
-extern struct req_format RQF_MDS_IS_SUBDIR;
extern struct req_format RQF_MDS_DONE_WRITING;
extern struct req_format RQF_MDS_REINT;
extern struct req_format RQF_MDS_REINT_CREATE;
diff --git a/drivers/staging/lustre/lustre/include/lustre_ver.h b/drivers/staging/lustre/lustre/include/lustre_ver.h
index 64559a16f4de..19c9135e2273 100644
--- a/drivers/staging/lustre/lustre/include/lustre_ver.h
+++ b/drivers/staging/lustre/lustre/include/lustre_ver.h
@@ -2,14 +2,21 @@
#define _LUSTRE_VER_H_
#define LUSTRE_MAJOR 2
-#define LUSTRE_MINOR 4
-#define LUSTRE_PATCH 60
+#define LUSTRE_MINOR 6
+#define LUSTRE_PATCH 99
#define LUSTRE_FIX 0
-#define LUSTRE_VERSION_STRING "2.4.60"
+#define LUSTRE_VERSION_STRING "2.6.99"
-#define LUSTRE_VERSION_CODE OBD_OCD_VERSION(LUSTRE_MAJOR, \
- LUSTRE_MINOR, LUSTRE_PATCH, \
- LUSTRE_FIX)
+#define OBD_OCD_VERSION(major, minor, patch, fix) \
+ (((major) << 24) + ((minor) << 16) + ((patch) << 8) + (fix))
+
+#define OBD_OCD_VERSION_MAJOR(version) ((int)((version) >> 24) & 255)
+#define OBD_OCD_VERSION_MINOR(version) ((int)((version) >> 16) & 255)
+#define OBD_OCD_VERSION_PATCH(version) ((int)((version) >> 8) & 255)
+#define OBD_OCD_VERSION_FIX(version) ((int)((version) >> 0) & 255)
+
+#define LUSTRE_VERSION_CODE \
+ OBD_OCD_VERSION(LUSTRE_MAJOR, LUSTRE_MINOR, LUSTRE_PATCH, LUSTRE_FIX)
/*
* If lustre version of client and servers it connects to differs by more
diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h
index a1bc2c478ff9..f6fc4dd05bd6 100644
--- a/drivers/staging/lustre/lustre/include/obd.h
+++ b/drivers/staging/lustre/lustre/include/obd.h
@@ -35,21 +35,13 @@
#include <linux/spinlock.h>
-#define IOC_OSC_TYPE 'h'
-#define IOC_OSC_MIN_NR 20
-#define IOC_OSC_SET_ACTIVE _IOWR(IOC_OSC_TYPE, 21, struct obd_device *)
-#define IOC_OSC_MAX_NR 50
-
-#define IOC_MDC_TYPE 'i'
-#define IOC_MDC_MIN_NR 20
-#define IOC_MDC_MAX_NR 50
-
#include "lustre/lustre_idl.h"
#include "lustre_lib.h"
#include "lu_ref.h"
#include "lustre_export.h"
#include "lustre_fid.h"
#include "lustre_fld.h"
+#include "lustre_handles.h"
#include "lustre_intent.h"
#define MAX_OBD_DEVICES 8192
@@ -81,6 +73,13 @@ static inline void loi_init(struct lov_oinfo *loi)
{
}
+/*
+ * If we are unable to get the maximum object size from the OST in
+ * ocd_maxbytes using OBD_CONNECT_MAXBYTES, then we fall back to using
+ * the old maximum object size from ext3.
+ */
+#define LUSTRE_EXT3_STRIPE_MAXBYTES 0x1fffffff000ULL
+
struct lov_stripe_md {
atomic_t lsm_refc;
spinlock_t lsm_lock;
@@ -89,31 +88,17 @@ struct lov_stripe_md {
/* maximum possible file size, might change as OSTs status changes,
* e.g. disconnected, deactivated
*/
- __u64 lsm_maxbytes;
- struct {
- /* Public members. */
- struct ost_id lw_object_oi; /* lov object id/seq */
-
- /* LOV-private members start here -- only for use in lov/. */
- __u32 lw_magic;
- __u32 lw_stripe_size; /* size of the stripe */
- __u32 lw_pattern; /* striping pattern (RAID0, RAID1) */
- __u16 lw_stripe_count; /* number of objects being striped over */
- __u16 lw_layout_gen; /* generation of the layout */
- char lw_pool_name[LOV_MAXPOOLNAME]; /* pool name */
- } lsm_wire;
-
+ __u64 lsm_maxbytes;
+ struct ost_id lsm_oi;
+ __u32 lsm_magic;
+ __u32 lsm_stripe_size;
+ __u32 lsm_pattern; /* striping pattern (RAID0, RAID1) */
+ __u16 lsm_stripe_count;
+ __u16 lsm_layout_gen;
+ char lsm_pool_name[LOV_MAXPOOLNAME + 1];
struct lov_oinfo *lsm_oinfo[0];
};
-#define lsm_oi lsm_wire.lw_object_oi
-#define lsm_magic lsm_wire.lw_magic
-#define lsm_layout_gen lsm_wire.lw_layout_gen
-#define lsm_stripe_size lsm_wire.lw_stripe_size
-#define lsm_pattern lsm_wire.lw_pattern
-#define lsm_stripe_count lsm_wire.lw_stripe_count
-#define lsm_pool_name lsm_wire.lw_pool_name
-
static inline bool lsm_is_released(struct lov_stripe_md *lsm)
{
return !!(lsm->lsm_pattern & LOV_PATTERN_F_RELEASED);
@@ -177,31 +162,10 @@ struct obd_type {
struct brw_page {
u64 off;
struct page *pg;
- int count;
+ unsigned int count;
u32 flag;
};
-/* llog contexts */
-enum llog_ctxt_id {
- LLOG_CONFIG_ORIG_CTXT = 0,
- LLOG_CONFIG_REPL_CTXT,
- LLOG_MDS_OST_ORIG_CTXT,
- LLOG_MDS_OST_REPL_CTXT,
- LLOG_SIZE_ORIG_CTXT,
- LLOG_SIZE_REPL_CTXT,
- LLOG_RD1_ORIG_CTXT,
- LLOG_RD1_REPL_CTXT,
- LLOG_TEST_ORIG_CTXT,
- LLOG_TEST_REPL_CTXT,
- LLOG_LOVEA_ORIG_CTXT,
- LLOG_LOVEA_REPL_CTXT,
- LLOG_CHANGELOG_ORIG_CTXT, /**< changelog generation on mdd */
- LLOG_CHANGELOG_REPL_CTXT, /**< changelog access on clients */
- LLOG_CHANGELOG_USER_ORIG_CTXT, /**< for multiple changelog consumers */
- LLOG_AGENT_ORIG_CTXT, /**< agent requests generation on cdt */
- LLOG_MAX_CTXTS
-};
-
struct timeout_item {
enum timeout_event ti_event;
unsigned long ti_timeout;
@@ -211,11 +175,12 @@ struct timeout_item {
struct list_head ti_chain;
};
-#define OSC_MAX_RIF_DEFAULT 8
-#define OSC_MAX_RIF_MAX 256
-#define OSC_MAX_DIRTY_DEFAULT (OSC_MAX_RIF_DEFAULT * 4)
-#define OSC_MAX_DIRTY_MB_MAX 2048 /* arbitrary, but < MAX_LONG bytes */
-#define OSC_DEFAULT_RESENDS 10
+#define OBD_MAX_RIF_DEFAULT 8
+#define OBD_MAX_RIF_MAX 512
+#define OSC_MAX_RIF_MAX 256
+#define OSC_MAX_DIRTY_DEFAULT (OBD_MAX_RIF_DEFAULT * 4)
+#define OSC_MAX_DIRTY_MB_MAX 2048 /* arbitrary, but < MAX_LONG bytes */
+#define OSC_DEFAULT_RESENDS 10
/* possible values for fo_sync_lock_cancel */
enum {
@@ -225,40 +190,74 @@ enum {
NUM_SYNC_ON_CANCEL_STATES
};
-#define MDC_MAX_RIF_DEFAULT 8
-#define MDC_MAX_RIF_MAX 512
-
enum obd_cl_sem_lock_class {
OBD_CLI_SEM_NORMAL,
OBD_CLI_SEM_MGC,
OBD_CLI_SEM_MDCOSC,
};
+/*
+ * Limit reply buffer size for striping data to one x86_64 page. This
+ * value is chosen to fit the striping data for common use cases while
+ * staying well below the limit at which the buffer must be backed by
+ * vmalloc(). Excessive use of vmalloc() may cause spinlock contention
+ * on the MDS.
+ */
+#define OBD_MAX_DEFAULT_EA_SIZE 4096
+#define OBD_MAX_DEFAULT_COOKIE_SIZE 4096
+
struct mdc_rpc_lock;
struct obd_import;
struct client_obd {
struct rw_semaphore cl_sem;
struct obd_uuid cl_target_uuid;
struct obd_import *cl_import; /* ptlrpc connection state */
- int cl_conn_count;
- /* max_mds_easize is purely a performance thing so we don't have to
- * call obd_size_diskmd() all the time.
+ size_t cl_conn_count;
+ /*
+ * Cache maximum and default values for easize and cookiesize. This is
+ * strictly a performance optimization to minimize calls to
+ * obd_size_diskmd(). The default values are used to calculate the
+ * initial size of a request buffer. The ptlrpc layer will resize the
+ * buffer as needed to accommodate a larger reply from the
+ * server. The default values should be small enough to avoid wasted
+ * memory and excessive use of vmalloc(), yet large enough to avoid
+ * reallocating the buffer in the common use case.
*/
- int cl_default_mds_easize;
- int cl_max_mds_easize;
- int cl_default_mds_cookiesize;
- int cl_max_mds_cookiesize;
+ /*
+ * Default EA size for striping attributes. It is initialized at
+ * mount-time based on the default stripe width of the filesystem,
+ * then it tracks the largest observed EA size advertised by
+ * the MDT, up to a maximum value of OBD_MAX_DEFAULT_EA_SIZE.
+ */
+ u32 cl_default_mds_easize;
+ /* Maximum possible EA size computed at mount-time based on
+ * the number of OSTs in the filesystem. May be increased at
+ * run-time if a larger observed size is advertised by the MDT.
+ */
+ u32 cl_max_mds_easize;
+ /* Default cookie size for llog cookies (see struct llog_cookie). It is
+ * initialized to zero at mount-time, then it tracks the largest
+ * observed cookie size advertised by the MDT, up to a maximum value of
+ * OBD_MAX_DEFAULT_COOKIE_SIZE. Note that llog_cookies are not
+ * used by clients communicating with MDS versions 2.4.0 and later.
+ */
+ u32 cl_default_mds_cookiesize;
+ /* Maximum possible cookie size computed at mount-time based on
+ * the number of OSTs in the filesystem. May be increased at
+ * run-time if a larger observed size is advertised by the MDT.
+ */
+ u32 cl_max_mds_cookiesize;
enum lustre_sec_part cl_sp_me;
enum lustre_sec_part cl_sp_to;
struct sptlrpc_flavor cl_flvr_mgc; /* fixed flavor of mgc->mgs */
/* the grant values are protected by loi_list_lock below */
- long cl_dirty; /* all _dirty_ in bytes */
- long cl_dirty_max; /* allowed w/o rpc */
- long cl_dirty_transit; /* dirty synchronous */
- long cl_avail_grant; /* bytes of credit for ost */
- long cl_lost_grant; /* lost credits (trunc) */
+ unsigned long cl_dirty_pages; /* all _dirty_ in pahges */
+ unsigned long cl_dirty_max_pages; /* allowed w/o rpc */
+ unsigned long cl_dirty_transit; /* dirty synchronous */
+ unsigned long cl_avail_grant; /* bytes of credit for ost */
+ unsigned long cl_lost_grant; /* lost credits (trunc) */
/* since we allocate grant by blocks, we don't know how many grant will
* be used to add a page into cache. As a solution, we reserve maximum
@@ -275,8 +274,7 @@ struct client_obd {
* the extent size. A chunk is max(PAGE_SIZE, OST block size)
*/
int cl_chunkbits;
- int cl_chunk;
- int cl_extent_tax; /* extent overhead, by bytes */
+ unsigned int cl_extent_tax; /* extent overhead, by bytes */
/* keep track of objects that have lois that contain pages which
* have been queued for async brw. this lock also protects the
@@ -301,13 +299,13 @@ struct client_obd {
struct list_head cl_loi_hp_ready_list;
struct list_head cl_loi_write_list;
struct list_head cl_loi_read_list;
- int cl_r_in_flight;
- int cl_w_in_flight;
+ __u32 cl_r_in_flight;
+ __u32 cl_w_in_flight;
/* just a sum of the loi/lop pending numbers to be exported by sysfs */
atomic_t cl_pending_w_pages;
atomic_t cl_pending_r_pages;
__u32 cl_max_pages_per_rpc;
- int cl_max_rpcs_in_flight;
+ __u32 cl_max_rpcs_in_flight;
struct obd_histogram cl_read_rpc_hist;
struct obd_histogram cl_write_rpc_hist;
struct obd_histogram cl_read_page_hist;
@@ -318,13 +316,13 @@ struct client_obd {
/* lru for osc caching pages */
struct cl_client_cache *cl_cache;
struct list_head cl_lru_osc; /* member of cl_cache->ccc_lru */
- atomic_t *cl_lru_left;
- atomic_t cl_lru_busy;
+ atomic_long_t *cl_lru_left;
+ atomic_long_t cl_lru_busy;
+ atomic_long_t cl_lru_in_list;
atomic_t cl_lru_shrinkers;
- atomic_t cl_lru_in_list;
struct list_head cl_lru_list; /* lru page list */
spinlock_t cl_lru_list_lock; /* page list protector */
- atomic_t cl_unstable_count;
+ atomic_long_t cl_unstable_count;
/* number of in flight destroy rpcs is limited to max_rpcs_in_flight */
atomic_t cl_destroy_in_flight;
@@ -350,7 +348,7 @@ struct client_obd {
/* used by quotacheck when the servers are older than 2.4 */
int cl_qchk_stat; /* quotacheck stat of the peer */
#define CL_NOT_QUOTACHECKED 1 /* client->cl_qchk_stat init value */
-#if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 7, 50, 0)
+#if OBD_OCD_VERSION(2, 7, 53, 0) < LUSTRE_VERSION_CODE
#warning "please consider removing quotacheck compatibility code"
#endif
@@ -431,7 +429,7 @@ struct lov_obd {
struct lmv_tgt_desc {
struct obd_uuid ltd_uuid;
struct obd_export *ltd_exp;
- int ltd_idx;
+ u32 ltd_idx;
struct mutex ltd_fid_mutex;
unsigned long ltd_active:1; /* target up for requests */
};
@@ -458,9 +456,8 @@ struct lmv_obd {
int max_def_easize;
int max_cookiesize;
int max_def_cookiesize;
- int server_timeout;
- int tgts_size; /* size of tgts array */
+ u32 tgts_size; /* size of tgts array */
struct lmv_tgt_desc **tgts;
struct obd_connect_data conn_data;
@@ -470,12 +467,11 @@ struct lmv_obd {
struct niobuf_local {
__u64 lnb_file_offset;
__u32 lnb_page_offset;
- __u32 len;
- __u32 flags;
- struct page *page;
- struct dentry *dentry;
- int lnb_grant_used;
- int rc;
+ __u32 lnb_len;
+ __u32 lnb_flags;
+ struct page *lnb_page;
+ void *lnb_data;
+ int lnb_rc;
};
#define LUSTRE_FLD_NAME "fld"
@@ -517,7 +513,6 @@ struct niobuf_local {
#define N_LOCAL_TEMP_PAGE 0x10000000
struct obd_trans_info {
- __u64 oti_transno;
__u64 oti_xid;
/* Only used on the server side for tracking acks. */
struct oti_req_ack_lock {
@@ -527,50 +522,11 @@ struct obd_trans_info {
void *oti_handle;
struct llog_cookie oti_onecookie;
struct llog_cookie *oti_logcookies;
- int oti_numcookies;
- /** synchronous write is needed */
- unsigned long oti_sync_write:1;
- /* initial thread handling transaction */
- struct ptlrpc_thread *oti_thread;
- __u32 oti_conn_cnt;
/** VBR: versions */
__u64 oti_pre_version;
- /** JobID */
- char *oti_jobid;
-
- struct obd_uuid *oti_ost_uuid;
};
-static inline void oti_alloc_cookies(struct obd_trans_info *oti,
- int num_cookies)
-{
- if (!oti)
- return;
-
- if (num_cookies == 1)
- oti->oti_logcookies = &oti->oti_onecookie;
- else
- oti->oti_logcookies = libcfs_kvzalloc(num_cookies * sizeof(oti->oti_onecookie),
- GFP_NOFS);
-
- oti->oti_numcookies = num_cookies;
-}
-
-static inline void oti_free_cookies(struct obd_trans_info *oti)
-{
- if (!oti || !oti->oti_logcookies)
- return;
-
- if (oti->oti_logcookies == &oti->oti_onecookie)
- LASSERT(oti->oti_numcookies == 1);
- else
- kvfree(oti->oti_logcookies);
-
- oti->oti_logcookies = NULL;
- oti->oti_numcookies = 0;
-}
-
/*
* Events signalled through obd_notify() upcall-chain.
*/
@@ -616,7 +572,6 @@ struct target_recovery_data {
};
struct obd_llog_group {
- int olg_seq;
struct llog_ctxt *olg_ctxts[LLOG_MAX_CTXTS];
wait_queue_head_t olg_waitq;
spinlock_t olg_lock;
@@ -625,7 +580,6 @@ struct obd_llog_group {
/* corresponds to one of the obd's */
#define OBD_DEVICE_MAGIC 0XAB5CD6EF
-#define OBD_DEV_BY_DEVNAME 0xffffd0de
struct lvfs_run_ctxt {
struct dt_device *dt;
@@ -653,7 +607,6 @@ struct obd_device {
obd_starting:1, /* started setup */
obd_force:1, /* cleanup with > 0 obd refcount */
obd_fail:1, /* cleanup with failover */
- obd_async_recov:1, /* allow asynchronous orphan cleanup */
obd_no_conn:1, /* deny new connections */
obd_inactive:1, /* device active/inactive
* (for sysfs status only!!)
@@ -728,9 +681,6 @@ struct obd_device {
struct completion obd_kobj_unregister;
};
-#define OBD_LLOG_FL_SENDNOW 0x0001
-#define OBD_LLOG_FL_EXIT 0x0002
-
enum obd_cleanup_stage {
/* Special case hack for MDS LOVs */
OBD_CLEANUP_EARLY,
@@ -740,8 +690,6 @@ enum obd_cleanup_stage {
/* get/set_info keys */
#define KEY_ASYNC "async"
-#define KEY_BLOCKSIZE_BITS "blocksize_bits"
-#define KEY_BLOCKSIZE "blocksize"
#define KEY_CHANGELOG_CLEAR "changelog_clear"
#define KEY_FID2PATH "fid2path"
#define KEY_CHECKSUM "checksum"
@@ -753,30 +701,22 @@ enum obd_cleanup_stage {
#define KEY_GRANT_SHRINK "grant_shrink"
#define KEY_HSM_COPYTOOL_SEND "hsm_send"
#define KEY_INIT_RECOV_BACKUP "init_recov_bk"
-#define KEY_INIT_RECOV "initial_recov"
#define KEY_INTERMDS "inter_mds"
#define KEY_LAST_ID "last_id"
#define KEY_LAST_FID "last_fid"
-#define KEY_LOCK_TO_STRIPE "lock_to_stripe"
#define KEY_LOVDESC "lovdesc"
-#define KEY_LOV_IDX "lov_idx"
#define KEY_MAX_EASIZE "max_easize"
#define KEY_DEFAULT_EASIZE "default_easize"
-#define KEY_MDS_CONN "mds_conn"
#define KEY_MGSSEC "mgssec"
-#define KEY_NEXT_ID "next_id"
#define KEY_READ_ONLY "read-only"
#define KEY_REGISTER_TARGET "register_target"
#define KEY_SET_FS "set_fs"
#define KEY_TGT_COUNT "tgt_count"
/* KEY_SET_INFO in lustre_idl.h */
#define KEY_SPTLRPC_CONF "sptlrpc_conf"
-#define KEY_CONNECT_FLAG "connect_flags"
-#define KEY_SYNC_LOCK_CANCEL "sync_lock_cancel"
#define KEY_CACHE_SET "cache_set"
#define KEY_CACHE_LRU_SHRINK "cache_lru_shrink"
-#define KEY_CHANGELOG_INDEX "changelog_index"
struct lu_context;
@@ -801,9 +741,11 @@ static inline int it_to_lock_mode(struct lookup_intent *it)
/* CREAT needs to be tested before open (both could be set) */
if (it->it_op & IT_CREAT)
return LCK_CW;
- else if (it->it_op & (IT_READDIR | IT_GETATTR | IT_OPEN | IT_LOOKUP |
+ else if (it->it_op & (IT_GETATTR | IT_OPEN | IT_LOOKUP |
IT_LAYOUT))
return LCK_CR;
+ else if (it->it_op & IT_READDIR)
+ return LCK_PR;
else if (it->it_op & IT_GETXATTR)
return LCK_PR;
else if (it->it_op & IT_SETXATTR)
@@ -813,6 +755,14 @@ static inline int it_to_lock_mode(struct lookup_intent *it)
return -EINVAL;
}
+enum md_cli_flags {
+ CLI_SET_MEA = BIT(0),
+ CLI_RM_ENTRY = BIT(1),
+ CLI_HASH64 = BIT(2),
+ CLI_API32 = BIT(3),
+ CLI_MIGRATE = BIT(4),
+};
+
struct md_op_data {
struct lu_fid op_fid1; /* operation fid1 (usually parent) */
struct lu_fid op_fid2; /* operation fid2 (usually child) */
@@ -822,7 +772,7 @@ struct md_op_data {
struct lustre_handle op_handle;
s64 op_mod_time;
const char *op_name;
- int op_namelen;
+ size_t op_namelen;
__u32 op_mode;
struct lmv_stripe_md *op_mea1;
struct lmv_stripe_md *op_mea2;
@@ -831,6 +781,7 @@ struct md_op_data {
__u32 op_fsgid;
cfs_cap_t op_cap;
void *op_data;
+ size_t op_data_size;
/* iattr fields and blocks. */
struct iattr op_attr;
@@ -845,28 +796,29 @@ struct md_op_data {
/* Various operation flags. */
enum mds_op_bias op_bias;
- /* Operation type */
- __u32 op_opc;
-
/* Used by readdir */
__u64 op_offset;
/* Used by readdir */
- __u32 op_npages;
+ __u32 op_max_pages;
/* used to transfer info between the stacks of MD client
* see enum op_cli_flags
*/
- __u32 op_cli_flags;
+ enum md_cli_flags op_cli_flags;
/* File object data version for HSM release, on client */
__u64 op_data_version;
struct lustre_handle op_lease_handle;
+
+ /* default stripe offset */
+ __u32 op_default_stripe_offset;
};
-enum op_cli_flags {
- CLI_SET_MEA = 1 << 0,
- CLI_RM_ENTRY = 1 << 1,
+struct md_callback {
+ int (*md_blocking_ast)(struct ldlm_lock *lock,
+ struct ldlm_lock_desc *desc,
+ void *data, int flag);
};
struct md_enqueue_info;
@@ -879,8 +831,7 @@ struct md_enqueue_info {
struct inode *mi_dir;
int (*mi_cb)(struct ptlrpc_request *req,
struct md_enqueue_info *minfo, int rc);
- __u64 mi_cbdata;
- unsigned int mi_generation;
+ void *mi_cbdata;
};
struct obd_ops {
@@ -894,8 +845,6 @@ struct obd_ops {
__u32 keylen, void *key,
__u32 vallen, void *val,
struct ptlrpc_request_set *set);
- int (*attach)(struct obd_device *dev, u32 len, void *data);
- int (*detach)(struct obd_device *dev);
int (*setup)(struct obd_device *dev, struct lustre_cfg *cfg);
int (*precleanup)(struct obd_device *dev,
enum obd_cleanup_stage cleanup_stage);
@@ -927,8 +876,8 @@ struct obd_ops {
int (*fid_fini)(struct obd_device *obd);
/* Allocate new fid according to passed @hint. */
- int (*fid_alloc)(struct obd_export *exp, struct lu_fid *fid,
- struct md_op_data *op_data);
+ int (*fid_alloc)(const struct lu_env *env, struct obd_export *exp,
+ struct lu_fid *fid, struct md_op_data *op_data);
/*
* Object with @fid is getting deleted, we may want to do something
@@ -943,13 +892,10 @@ struct obd_ops {
int (*unpackmd)(struct obd_export *exp,
struct lov_stripe_md **mem_tgt,
struct lov_mds_md *disk_src, int disk_len);
- int (*preallocate)(struct lustre_handle *, u32 *req, u64 *ids);
int (*create)(const struct lu_env *env, struct obd_export *exp,
- struct obdo *oa, struct lov_stripe_md **ea,
- struct obd_trans_info *oti);
+ struct obdo *oa, struct obd_trans_info *oti);
int (*destroy)(const struct lu_env *env, struct obd_export *exp,
- struct obdo *oa, struct lov_stripe_md *ea,
- struct obd_trans_info *oti, struct obd_export *md_exp);
+ struct obdo *oa, struct obd_trans_info *oti);
int (*setattr)(const struct lu_env *, struct obd_export *exp,
struct obd_info *oinfo, struct obd_trans_info *oti);
int (*setattr_async)(struct obd_export *exp, struct obd_info *oinfo,
@@ -959,8 +905,6 @@ struct obd_ops {
struct obd_info *oinfo);
int (*getattr_async)(struct obd_export *exp, struct obd_info *oinfo,
struct ptlrpc_request_set *set);
- int (*adjust_kms)(struct obd_export *exp, struct lov_stripe_md *lsm,
- u64 size, int shrink);
int (*preprw)(const struct lu_env *env, int cmd,
struct obd_export *exp, struct obdo *oa, int objcount,
struct obd_ioobj *obj, struct niobuf_remote *remote,
@@ -972,8 +916,6 @@ struct obd_ops {
struct niobuf_remote *remote, int pages,
struct niobuf_local *local,
struct obd_trans_info *oti, int rc);
- int (*find_cbdata)(struct obd_export *, struct lov_stripe_md *,
- ldlm_iterator_t it, void *data);
int (*init_export)(struct obd_export *exp);
int (*destroy_export)(struct obd_export *exp);
@@ -1009,27 +951,11 @@ struct obd_ops {
*/
};
-enum {
- LUSTRE_OPC_MKDIR = (1 << 0),
- LUSTRE_OPC_SYMLINK = (1 << 1),
- LUSTRE_OPC_MKNOD = (1 << 2),
- LUSTRE_OPC_CREATE = (1 << 3),
- LUSTRE_OPC_ANY = (1 << 4)
-};
-
/* lmv structures */
-#define MEA_MAGIC_LAST_CHAR 0xb2221ca1
-#define MEA_MAGIC_ALL_CHARS 0xb222a11c
-#define MEA_MAGIC_HASH_SEGMENT 0xb222a11b
-
-#define MAX_HASH_SIZE_32 0x7fffffffUL
-#define MAX_HASH_SIZE 0x7fffffffffffffffULL
-#define MAX_HASH_HIGHEST_BIT 0x1000000000000000ULL
-
struct lustre_md {
struct mdt_body *body;
struct lov_stripe_md *lsm;
- struct lmv_stripe_md *mea;
+ struct lmv_stripe_md *lmv;
#ifdef CONFIG_FS_POSIX_ACL
struct posix_acl *posix_acl;
#endif
@@ -1044,48 +970,55 @@ struct md_open_data {
bool mod_is_create;
};
+struct obd_client_handle {
+ struct lustre_handle och_fh;
+ struct lu_fid och_fid;
+ struct md_open_data *och_mod;
+ struct lustre_handle och_lease_handle; /* open lock for lease */
+ __u32 och_magic;
+ int och_flags;
+};
+
+#define OBD_CLIENT_HANDLE_MAGIC 0xd15ea5ed
+
struct lookup_intent;
+struct cl_attr;
struct md_ops {
int (*getstatus)(struct obd_export *, struct lu_fid *);
int (*null_inode)(struct obd_export *, const struct lu_fid *);
- int (*find_cbdata)(struct obd_export *, const struct lu_fid *,
- ldlm_iterator_t, void *);
int (*close)(struct obd_export *, struct md_op_data *,
struct md_open_data *, struct ptlrpc_request **);
int (*create)(struct obd_export *, struct md_op_data *,
- const void *, int, int, __u32, __u32, cfs_cap_t,
- __u64, struct ptlrpc_request **);
+ const void *, size_t, umode_t, uid_t, gid_t,
+ cfs_cap_t, __u64, struct ptlrpc_request **);
int (*done_writing)(struct obd_export *, struct md_op_data *,
struct md_open_data *);
int (*enqueue)(struct obd_export *, struct ldlm_enqueue_info *,
+ const ldlm_policy_data_t *,
struct lookup_intent *, struct md_op_data *,
- struct lustre_handle *, void *, int,
- struct ptlrpc_request **, __u64);
+ struct lustre_handle *, __u64);
int (*getattr)(struct obd_export *, struct md_op_data *,
struct ptlrpc_request **);
int (*getattr_name)(struct obd_export *, struct md_op_data *,
struct ptlrpc_request **);
int (*intent_lock)(struct obd_export *, struct md_op_data *,
- void *, int, struct lookup_intent *, int,
+ struct lookup_intent *,
struct ptlrpc_request **,
ldlm_blocking_callback, __u64);
int (*link)(struct obd_export *, struct md_op_data *,
struct ptlrpc_request **);
int (*rename)(struct obd_export *, struct md_op_data *,
- const char *, int, const char *, int,
+ const char *, size_t, const char *, size_t,
struct ptlrpc_request **);
- int (*is_subdir)(struct obd_export *, const struct lu_fid *,
- const struct lu_fid *,
- struct ptlrpc_request **);
int (*setattr)(struct obd_export *, struct md_op_data *, void *,
- int, void *, int, struct ptlrpc_request **,
+ size_t, void *, size_t, struct ptlrpc_request **,
struct md_open_data **mod);
int (*sync)(struct obd_export *, const struct lu_fid *,
struct ptlrpc_request **);
- int (*readpage)(struct obd_export *, struct md_op_data *,
- struct page **, struct ptlrpc_request **);
-
+ int (*read_page)(struct obd_export *, struct md_op_data *,
+ struct md_callback *cb_op, __u64 hash_offset,
+ struct page **ppage);
int (*unlink)(struct obd_export *, struct md_op_data *,
struct ptlrpc_request **);
@@ -1097,7 +1030,7 @@ struct md_ops {
u64, const char *, const char *, int, int, int,
struct ptlrpc_request **);
- int (*init_ea_size)(struct obd_export *, int, int, int, int);
+ int (*init_ea_size)(struct obd_export *, u32, u32, u32, u32);
int (*get_lustre_md)(struct obd_export *, struct ptlrpc_request *,
struct obd_export *, struct obd_export *,
@@ -1105,12 +1038,17 @@ struct md_ops {
int (*free_lustre_md)(struct obd_export *, struct lustre_md *);
+ int (*merge_attr)(struct obd_export *,
+ const struct lmv_stripe_md *lsm,
+ struct cl_attr *attr, ldlm_blocking_callback);
+
int (*set_open_replay_data)(struct obd_export *,
struct obd_client_handle *,
struct lookup_intent *);
int (*clear_open_replay_data)(struct obd_export *,
struct obd_client_handle *);
- int (*set_lock_data)(struct obd_export *, __u64 *, void *, __u64 *);
+ int (*set_lock_data)(struct obd_export *, const struct lustre_handle *,
+ void *, __u64 *);
enum ldlm_mode (*lock_match)(struct obd_export *, __u64,
const struct lu_fid *, enum ldlm_type,
@@ -1121,6 +1059,11 @@ struct md_ops {
ldlm_policy_data_t *, enum ldlm_mode,
enum ldlm_cancel_flags flags, void *opaque);
+ int (*get_fid_from_lsm)(struct obd_export *,
+ const struct lmv_stripe_md *,
+ const char *name, int namelen,
+ struct lu_fid *fid);
+
int (*intent_getattr_async)(struct obd_export *,
struct md_enqueue_info *,
struct ldlm_enqueue_info *);
@@ -1137,8 +1080,6 @@ struct md_ops {
struct lsm_operations {
void (*lsm_free)(struct lov_stripe_md *);
- int (*lsm_destroy)(struct lov_stripe_md *, struct obdo *oa,
- struct obd_export *md_exp);
void (*lsm_stripe_by_index)(struct lov_stripe_md *, int *, u64 *,
u64 *);
void (*lsm_stripe_by_offset)(struct lov_stripe_md *, int *, u64 *,
@@ -1164,10 +1105,6 @@ static inline const struct lsm_operations *lsm_op_find(int magic)
}
}
-/* Requests for obd_extent_calc() */
-#define OBD_CALC_STRIPE_START 1
-#define OBD_CALC_STRIPE_END 2
-
static inline struct md_open_data *obd_mod_alloc(void)
{
struct md_open_data *mod;
@@ -1211,7 +1148,8 @@ static inline const char *lu_dev_name(const struct lu_device *lu_dev)
return lu_dev->ld_obd->obd_name;
}
-static inline bool filename_is_volatile(const char *name, int namelen, int *idx)
+static inline bool filename_is_volatile(const char *name, size_t namelen,
+ int *idx)
{
const char *start;
char *end;
@@ -1259,4 +1197,28 @@ static inline int cli_brw_size(struct obd_device *obd)
return obd->u.cli.cl_max_pages_per_rpc << PAGE_SHIFT;
}
+/*
+ * when RPC size or the max RPCs in flight is increased, the max dirty pages
+ * of the client should be increased accordingly to avoid sending fragmented
+ * RPCs over the network when the client runs out of the maximum dirty space
+ * when so many RPCs are being generated.
+ */
+static inline void client_adjust_max_dirty(struct client_obd *cli)
+{
+ /* initializing */
+ if (cli->cl_dirty_max_pages <= 0)
+ cli->cl_dirty_max_pages =
+ (OSC_MAX_DIRTY_DEFAULT * 1024 * 1024) >> PAGE_SHIFT;
+ else {
+ unsigned long dirty_max = cli->cl_max_rpcs_in_flight *
+ cli->cl_max_pages_per_rpc;
+
+ if (dirty_max > cli->cl_dirty_max_pages)
+ cli->cl_dirty_max_pages = dirty_max;
+ }
+
+ if (cli->cl_dirty_max_pages > totalram_pages / 8)
+ cli->cl_dirty_max_pages = totalram_pages / 8;
+}
+
#endif /* __OBD_H */
diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h
index 6482a937000b..16094dbec08b 100644
--- a/drivers/staging/lustre/lustre/include/obd_class.h
+++ b/drivers/staging/lustre/lustre/include/obd_class.h
@@ -56,7 +56,6 @@
#define OBD_STATFS_FOR_MDT0 0x0008 /* The statfs is only for retrieving
* information from MDT0.
*/
-#define OBD_FL_PUNCH 0x00000001 /* To indicate it is punch operation */
/* OBD Device Declarations */
extern struct obd_device *obd_devs[MAX_OBD_DEVICES];
@@ -97,6 +96,11 @@ int obd_zombie_impexp_init(void);
void obd_zombie_impexp_stop(void);
void obd_zombie_barrier(void);
+int obd_get_request_slot(struct client_obd *cli);
+void obd_put_request_slot(struct client_obd *cli);
+__u32 obd_get_max_rpcs_in_flight(struct client_obd *cli);
+int obd_set_max_rpcs_in_flight(struct client_obd *cli, __u32 max);
+
struct llog_handle;
struct llog_rec_hdr;
typedef int (*llog_cb_t)(const struct lu_env *, struct llog_handle *,
@@ -265,10 +269,10 @@ static inline int lprocfs_climp_check(struct obd_device *obd)
struct inode;
struct lu_attr;
struct obdo;
-void obdo_refresh_inode(struct inode *dst, struct obdo *src, u32 valid);
+void obdo_refresh_inode(struct inode *dst, const struct obdo *src, u32 valid);
-void obdo_to_ioobj(struct obdo *oa, struct obd_ioobj *ioobj);
-void md_from_obdo(struct md_op_data *op_data, struct obdo *oa, u32 valid);
+void obdo_to_ioobj(const struct obdo *oa, struct obd_ioobj *ioobj);
+void md_from_obdo(struct md_op_data *op_data, const struct obdo *oa, u32 valid);
#define OBT(dev) (dev)->obd_type
#define OBP(dev, op) (dev)->obd_type->typ_dt_ops->op
@@ -673,15 +677,6 @@ static inline int obd_unpackmd(struct obd_export *exp,
return rc;
}
-/* helper functions */
-static inline int obd_alloc_memmd(struct obd_export *exp,
- struct lov_stripe_md **mem_tgt)
-{
- LASSERT(mem_tgt);
- LASSERT(!*mem_tgt);
- return obd_unpackmd(exp, mem_tgt, NULL, 0);
-}
-
static inline int obd_free_memmd(struct obd_export *exp,
struct lov_stripe_md **mem_tgt)
{
@@ -695,29 +690,26 @@ static inline int obd_free_memmd(struct obd_export *exp,
}
static inline int obd_create(const struct lu_env *env, struct obd_export *exp,
- struct obdo *obdo, struct lov_stripe_md **ea,
- struct obd_trans_info *oti)
+ struct obdo *obdo, struct obd_trans_info *oti)
{
int rc;
EXP_CHECK_DT_OP(exp, create);
EXP_COUNTER_INCREMENT(exp, create);
- rc = OBP(exp->exp_obd, create)(env, exp, obdo, ea, oti);
+ rc = OBP(exp->exp_obd, create)(env, exp, obdo, oti);
return rc;
}
static inline int obd_destroy(const struct lu_env *env, struct obd_export *exp,
- struct obdo *obdo, struct lov_stripe_md *ea,
- struct obd_trans_info *oti,
- struct obd_export *md_exp)
+ struct obdo *obdo, struct obd_trans_info *oti)
{
int rc;
EXP_CHECK_DT_OP(exp, destroy);
EXP_COUNTER_INCREMENT(exp, destroy);
- rc = OBP(exp->exp_obd, destroy)(env, exp, obdo, ea, oti, md_exp);
+ rc = OBP(exp->exp_obd, destroy)(env, exp, obdo, oti);
return rc;
}
@@ -925,7 +917,8 @@ static inline int obd_fid_fini(struct obd_device *obd)
return rc;
}
-static inline int obd_fid_alloc(struct obd_export *exp,
+static inline int obd_fid_alloc(const struct lu_env *env,
+ struct obd_export *exp,
struct lu_fid *fid,
struct md_op_data *op_data)
{
@@ -934,7 +927,7 @@ static inline int obd_fid_alloc(struct obd_export *exp,
EXP_CHECK_DT_OP(exp, fid_alloc);
EXP_COUNTER_INCREMENT(exp, fid_alloc);
- rc = OBP(exp->exp_obd, fid_alloc)(exp, fid, op_data);
+ rc = OBP(exp->exp_obd, fid_alloc)(env, exp, fid, op_data);
return rc;
}
@@ -1147,19 +1140,6 @@ static inline int obd_commitrw(const struct lu_env *env, int cmd,
return rc;
}
-static inline int obd_adjust_kms(struct obd_export *exp,
- struct lov_stripe_md *lsm, u64 size,
- int shrink)
-{
- int rc;
-
- EXP_CHECK_DT_OP(exp, adjust_kms);
- EXP_COUNTER_INCREMENT(exp, adjust_kms);
-
- rc = OBP(exp->exp_obd, adjust_kms)(exp, lsm, size, shrink);
- return rc;
-}
-
static inline int obd_iocontrol(unsigned int cmd, struct obd_export *exp,
int len, void *karg, void __user *uarg)
{
@@ -1172,19 +1152,6 @@ static inline int obd_iocontrol(unsigned int cmd, struct obd_export *exp,
return rc;
}
-static inline int obd_find_cbdata(struct obd_export *exp,
- struct lov_stripe_md *lsm,
- ldlm_iterator_t it, void *data)
-{
- int rc;
-
- EXP_CHECK_DT_OP(exp, find_cbdata);
- EXP_COUNTER_INCREMENT(exp, find_cbdata);
-
- rc = OBP(exp->exp_obd, find_cbdata)(exp, lsm, it, data);
- return rc;
-}
-
static inline void obd_import_event(struct obd_device *obd,
struct obd_import *imp,
enum obd_import_event event)
@@ -1210,12 +1177,7 @@ static inline int obd_notify(struct obd_device *obd,
if (rc)
return rc;
- /* the check for async_recov is a complete hack - I'm hereby
- * overloading the meaning to also mean "this was called from
- * mds_postsetup". I know that my mds is able to handle notifies
- * by this point, and it needs to get them to execute mds_postrecov.
- */
- if (!obd->obd_set_up && !obd->obd_async_recov) {
+ if (!obd->obd_set_up) {
CDEBUG(D_HA, "obd %s not set up\n", obd->obd_name);
return -EINVAL;
}
@@ -1358,18 +1320,6 @@ static inline int md_null_inode(struct obd_export *exp,
return rc;
}
-static inline int md_find_cbdata(struct obd_export *exp,
- const struct lu_fid *fid,
- ldlm_iterator_t it, void *data)
-{
- int rc;
-
- EXP_CHECK_MD_OP(exp, find_cbdata);
- EXP_MD_COUNTER_INCREMENT(exp, find_cbdata);
- rc = MDP(exp->exp_obd, find_cbdata)(exp, fid, it, data);
- return rc;
-}
-
static inline int md_close(struct obd_export *exp, struct md_op_data *op_data,
struct md_open_data *mod,
struct ptlrpc_request **request)
@@ -1383,9 +1333,9 @@ static inline int md_close(struct obd_export *exp, struct md_op_data *op_data,
}
static inline int md_create(struct obd_export *exp, struct md_op_data *op_data,
- const void *data, int datalen, int mode, __u32 uid,
- __u32 gid, cfs_cap_t cap_effective, __u64 rdev,
- struct ptlrpc_request **request)
+ const void *data, size_t datalen, umode_t mode,
+ uid_t uid, gid_t gid, cfs_cap_t cap_effective,
+ __u64 rdev, struct ptlrpc_request **request)
{
int rc;
@@ -1410,19 +1360,18 @@ static inline int md_done_writing(struct obd_export *exp,
static inline int md_enqueue(struct obd_export *exp,
struct ldlm_enqueue_info *einfo,
+ const ldlm_policy_data_t *policy,
struct lookup_intent *it,
struct md_op_data *op_data,
struct lustre_handle *lockh,
- void *lmm, int lmmsize,
- struct ptlrpc_request **req,
__u64 extra_lock_flags)
{
int rc;
EXP_CHECK_MD_OP(exp, enqueue);
EXP_MD_COUNTER_INCREMENT(exp, enqueue);
- rc = MDP(exp->exp_obd, enqueue)(exp, einfo, it, op_data, lockh,
- lmm, lmmsize, req, extra_lock_flags);
+ rc = MDP(exp->exp_obd, enqueue)(exp, einfo, policy, it, op_data, lockh,
+ extra_lock_flags);
return rc;
}
@@ -1439,9 +1388,9 @@ static inline int md_getattr_name(struct obd_export *exp,
}
static inline int md_intent_lock(struct obd_export *exp,
- struct md_op_data *op_data, void *lmm,
- int lmmsize, struct lookup_intent *it,
- int lookup_flags, struct ptlrpc_request **reqp,
+ struct md_op_data *op_data,
+ struct lookup_intent *it,
+ struct ptlrpc_request **reqp,
ldlm_blocking_callback cb_blocking,
__u64 extra_lock_flags)
{
@@ -1449,9 +1398,8 @@ static inline int md_intent_lock(struct obd_export *exp,
EXP_CHECK_MD_OP(exp, intent_lock);
EXP_MD_COUNTER_INCREMENT(exp, intent_lock);
- rc = MDP(exp->exp_obd, intent_lock)(exp, op_data, lmm, lmmsize,
- it, lookup_flags, reqp, cb_blocking,
- extra_lock_flags);
+ rc = MDP(exp->exp_obd, intent_lock)(exp, op_data, it, reqp,
+ cb_blocking, extra_lock_flags);
return rc;
}
@@ -1467,8 +1415,8 @@ static inline int md_link(struct obd_export *exp, struct md_op_data *op_data,
}
static inline int md_rename(struct obd_export *exp, struct md_op_data *op_data,
- const char *old, int oldlen, const char *new,
- int newlen, struct ptlrpc_request **request)
+ const char *old, size_t oldlen, const char *new,
+ size_t newlen, struct ptlrpc_request **request)
{
int rc;
@@ -1479,21 +1427,8 @@ static inline int md_rename(struct obd_export *exp, struct md_op_data *op_data,
return rc;
}
-static inline int md_is_subdir(struct obd_export *exp,
- const struct lu_fid *pfid,
- const struct lu_fid *cfid,
- struct ptlrpc_request **request)
-{
- int rc;
-
- EXP_CHECK_MD_OP(exp, is_subdir);
- EXP_MD_COUNTER_INCREMENT(exp, is_subdir);
- rc = MDP(exp->exp_obd, is_subdir)(exp, pfid, cfid, request);
- return rc;
-}
-
static inline int md_setattr(struct obd_export *exp, struct md_op_data *op_data,
- void *ea, int ealen, void *ea2, int ea2len,
+ void *ea, size_t ealen, void *ea2, size_t ea2len,
struct ptlrpc_request **request,
struct md_open_data **mod)
{
@@ -1517,15 +1452,18 @@ static inline int md_sync(struct obd_export *exp, const struct lu_fid *fid,
return rc;
}
-static inline int md_readpage(struct obd_export *exp, struct md_op_data *opdata,
- struct page **pages,
- struct ptlrpc_request **request)
+static inline int md_read_page(struct obd_export *exp,
+ struct md_op_data *op_data,
+ struct md_callback *cb_op,
+ __u64 hash_offset,
+ struct page **ppage)
{
int rc;
- EXP_CHECK_MD_OP(exp, readpage);
- EXP_MD_COUNTER_INCREMENT(exp, readpage);
- rc = MDP(exp->exp_obd, readpage)(exp, opdata, pages, request);
+ EXP_CHECK_MD_OP(exp, read_page);
+ EXP_MD_COUNTER_INCREMENT(exp, read_page);
+ rc = MDP(exp->exp_obd, read_page)(exp, op_data, cb_op, hash_offset,
+ ppage);
return rc;
}
@@ -1559,6 +1497,16 @@ static inline int md_free_lustre_md(struct obd_export *exp,
return MDP(exp->exp_obd, free_lustre_md)(exp, md);
}
+static inline int md_merge_attr(struct obd_export *exp,
+ const struct lmv_stripe_md *lsm,
+ struct cl_attr *attr,
+ ldlm_blocking_callback cb)
+{
+ EXP_CHECK_MD_OP(exp, merge_attr);
+ EXP_MD_COUNTER_INCREMENT(exp, merge_attr);
+ return MDP(exp->exp_obd, merge_attr)(exp, lsm, attr, cb);
+}
+
static inline int md_setxattr(struct obd_export *exp, const struct lu_fid *fid,
u64 valid, const char *name,
const char *input, int input_size,
@@ -1603,7 +1551,8 @@ static inline int md_clear_open_replay_data(struct obd_export *exp,
}
static inline int md_set_lock_data(struct obd_export *exp,
- __u64 *lockh, void *data, __u64 *bits)
+ const struct lustre_handle *lockh,
+ void *data, __u64 *bits)
{
EXP_CHECK_MD_OP(exp, set_lock_data);
EXP_MD_COUNTER_INCREMENT(exp, set_lock_data);
@@ -1674,6 +1623,19 @@ static inline int md_revalidate_lock(struct obd_export *exp,
return rc;
}
+static inline int md_get_fid_from_lsm(struct obd_export *exp,
+ const struct lmv_stripe_md *lsm,
+ const char *name, int namelen,
+ struct lu_fid *fid)
+{
+ int rc;
+
+ EXP_CHECK_MD_OP(exp, get_fid_from_lsm);
+ EXP_MD_COUNTER_INCREMENT(exp, get_fid_from_lsm);
+ rc = MDP(exp->exp_obd, get_fid_from_lsm)(exp, lsm, name, namelen, fid);
+ return rc;
+}
+
/* OBD Metadata Support */
int obd_init_caches(void);
@@ -1682,16 +1644,6 @@ void obd_cleanup_caches(void);
/* support routines */
extern struct kmem_cache *obdo_cachep;
-static inline void obdo2fid(struct obdo *oa, struct lu_fid *fid)
-{
- /* something here */
-}
-
-static inline void fid2obdo(struct lu_fid *fid, struct obdo *oa)
-{
- /* something here */
-}
-
typedef int (*register_lwp_cb)(void *data);
struct lwp_register_item {
@@ -1710,6 +1662,9 @@ struct lwp_register_item {
extern int (*ptlrpc_put_connection_superhack)(struct ptlrpc_connection *c);
/* obd_mount.c */
+int lustre_unregister_fs(void);
+int lustre_register_fs(void);
+int lustre_check_exclusion(struct super_block *sb, char *svname);
/* sysctl.c */
int obd_sysctl_init(void);
@@ -1730,8 +1685,24 @@ void class_exit_uuidlist(void);
extern char obd_jobid_node[];
extern struct miscdevice obd_psdev;
extern spinlock_t obd_types_lock;
+int class_procfs_init(void);
+int class_procfs_clean(void);
/* prng.c */
#define ll_generate_random_uuid(uuid_out) cfs_get_random_bytes(uuid_out, sizeof(class_uuid_t))
+/* statfs_pack.c */
+struct kstatfs;
+void statfs_pack(struct obd_statfs *osfs, struct kstatfs *sfs);
+void statfs_unpack(struct kstatfs *sfs, struct obd_statfs *osfs);
+
+/* root squash info */
+struct rw_semaphore;
+struct root_squash_info {
+ uid_t rsi_uid;
+ gid_t rsi_gid;
+ struct list_head rsi_nosquash_nids;
+ struct rw_semaphore rsi_sem;
+};
+
#endif /* __LINUX_OBD_CLASS_H */
diff --git a/drivers/staging/lustre/lustre/include/obd_support.h b/drivers/staging/lustre/lustre/include/obd_support.h
index 845e64a56c21..b346a7f10aa4 100644
--- a/drivers/staging/lustre/lustre/include/obd_support.h
+++ b/drivers/staging/lustre/lustre/include/obd_support.h
@@ -35,7 +35,7 @@
#include <linux/slab.h>
#include "../../include/linux/libcfs/libcfs.h"
-#include "linux/lustre_compat25.h"
+#include "lustre_compat.h"
#include "lprocfs_status.h"
/* global variables */
@@ -52,11 +52,9 @@ extern unsigned int at_max;
extern unsigned int at_history;
extern int at_early_margin;
extern int at_extra;
-extern unsigned int obd_sync_filter;
-extern unsigned int obd_max_dirty_pages;
-extern atomic_t obd_unstable_pages;
-extern atomic_t obd_dirty_pages;
-extern atomic_t obd_dirty_transit_pages;
+extern unsigned long obd_max_dirty_pages;
+extern atomic_long_t obd_dirty_pages;
+extern atomic_long_t obd_dirty_transit_pages;
extern char obd_jobid_var[];
/* Some hash init argument constants */
@@ -117,17 +115,17 @@ extern char obd_jobid_var[];
* running on a backup server. (If it's too low, import_select_connection
* will increase the timeout anyhow.)
*/
-#define INITIAL_CONNECT_TIMEOUT max(CONNECTION_SWITCH_MIN, obd_timeout/20)
+#define INITIAL_CONNECT_TIMEOUT max(CONNECTION_SWITCH_MIN, obd_timeout / 20)
/* The max delay between connects is SWITCH_MAX + SWITCH_INC + INITIAL */
#define RECONNECT_DELAY_MAX (CONNECTION_SWITCH_MAX + CONNECTION_SWITCH_INC + \
INITIAL_CONNECT_TIMEOUT)
/* The min time a target should wait for clients to reconnect in recovery */
-#define OBD_RECOVERY_TIME_MIN (2*RECONNECT_DELAY_MAX)
+#define OBD_RECOVERY_TIME_MIN (2 * RECONNECT_DELAY_MAX)
#define OBD_IR_FACTOR_MIN 1
#define OBD_IR_FACTOR_MAX 10
-#define OBD_IR_FACTOR_DEFAULT (OBD_IR_FACTOR_MAX/2)
+#define OBD_IR_FACTOR_DEFAULT (OBD_IR_FACTOR_MAX / 2)
/* default timeout for the MGS to become IR_FULL */
-#define OBD_IR_MGS_TIMEOUT (4*obd_timeout)
+#define OBD_IR_MGS_TIMEOUT (4 * obd_timeout)
#define LONG_UNLINK 300 /* Unlink should happen before now */
/**
@@ -318,6 +316,10 @@ extern char obd_jobid_var[];
#define OBD_FAIL_LDLM_AGL_NOLOCK 0x31b
#define OBD_FAIL_LDLM_OST_LVB 0x31c
#define OBD_FAIL_LDLM_ENQUEUE_HANG 0x31d
+#define OBD_FAIL_LDLM_CP_CB_WAIT2 0x320
+#define OBD_FAIL_LDLM_CP_CB_WAIT3 0x321
+#define OBD_FAIL_LDLM_CP_CB_WAIT4 0x322
+#define OBD_FAIL_LDLM_CP_CB_WAIT5 0x323
/* LOCKLESS IO */
#define OBD_FAIL_LDLM_SET_CONTENTION 0x385
@@ -400,6 +402,7 @@ extern char obd_jobid_var[];
#define OBD_FAIL_MDC_GETATTR_ENQUEUE 0x803
#define OBD_FAIL_MDC_RPCS_SEM 0x804
#define OBD_FAIL_MDC_LIGHTWEIGHT 0x805
+#define OBD_FAIL_MDC_CLOSE 0x806
#define OBD_FAIL_MGS 0x900
#define OBD_FAIL_MGS_ALL_REQUEST_NET 0x901
@@ -455,6 +458,7 @@ extern char obd_jobid_var[];
#define OBD_FAIL_LOV_INIT 0x1403
#define OBD_FAIL_GLIMPSE_DELAY 0x1404
#define OBD_FAIL_LLITE_XATTR_ENOMEM 0x1405
+#define OBD_FAIL_GETATTR_DELAY 0x1409
#define OBD_FAIL_FID_INDIR 0x1501
#define OBD_FAIL_FID_INLMA 0x1502
@@ -474,11 +478,16 @@ extern char obd_jobid_var[];
#define OBD_FAIL_LFSCK_CRASH 0x160a
#define OBD_FAIL_LFSCK_NO_AUTO 0x160b
#define OBD_FAIL_LFSCK_NO_DOUBLESCAN 0x160c
+#define OBD_FAIL_LFSCK_INVALID_PFID 0x1619
+#define OBD_FAIL_LFSCK_BAD_NAME_HASH 0x1628
/* UPDATE */
#define OBD_FAIL_UPDATE_OBJ_NET 0x1700
#define OBD_FAIL_UPDATE_OBJ_NET_REP 0x1701
+/* LMV */
+#define OBD_FAIL_UNKNOWN_LMV_STRIPE 0x1901
+
/* Assign references to moved code to reduce code changes */
#define OBD_FAIL_PRECHECK(id) CFS_FAIL_PRECHECK(id)
#define OBD_FAIL_CHECK(id) CFS_FAIL_CHECK(id)
@@ -520,7 +529,8 @@ do { \
POISON_PTR(ptr); \
} while (0)
-#define KEY_IS(str) \
- (keylen >= (sizeof(str)-1) && memcmp(key, str, (sizeof(str)-1)) == 0)
+#define KEY_IS(str) \
+ (keylen >= (sizeof(str) - 1) && \
+ memcmp(key, str, (sizeof(str) - 1)) == 0)
#endif
diff --git a/drivers/staging/lustre/lustre/ldlm/interval_tree.c b/drivers/staging/lustre/lustre/ldlm/interval_tree.c
index f4a70ebddeaf..e134ecd21bb2 100644
--- a/drivers/staging/lustre/lustre/ldlm/interval_tree.c
+++ b/drivers/staging/lustre/lustre/ldlm/interval_tree.c
@@ -90,6 +90,17 @@ static inline int extent_equal(struct interval_node_extent *e1,
return (e1->start == e2->start) && (e1->end == e2->end);
}
+static inline int extent_overlapped(struct interval_node_extent *e1,
+ struct interval_node_extent *e2)
+{
+ return (e1->start <= e2->end) && (e2->start <= e1->end);
+}
+
+static inline int node_equal(struct interval_node *n1, struct interval_node *n2)
+{
+ return extent_equal(&n1->in_extent, &n2->in_extent);
+}
+
static inline __u64 max_u64(__u64 x, __u64 y)
{
return x > y ? x : y;
@@ -262,7 +273,7 @@ struct interval_node *interval_insert(struct interval_node *node,
p = root;
while (*p) {
parent = *p;
- if (extent_equal(&parent->in_extent, &node->in_extent))
+ if (node_equal(parent, node))
return parent;
/* max_high field must be updated after each iteration */
@@ -463,3 +474,90 @@ color:
interval_erase_color(child, parent, root);
}
EXPORT_SYMBOL(interval_erase);
+
+static inline int interval_may_overlap(struct interval_node *node,
+ struct interval_node_extent *ext)
+{
+ return (ext->start <= node->in_max_high &&
+ ext->end >= interval_low(node));
+}
+
+/*
+ * This function finds all intervals that overlap interval ext,
+ * and calls func to handle resulted intervals one by one.
+ * in lustre, this function will find all conflicting locks in
+ * the granted queue and add these locks to the ast work list.
+ *
+ * {
+ * if (!node)
+ * return 0;
+ * if (ext->end < interval_low(node)) {
+ * interval_search(node->in_left, ext, func, data);
+ * } else if (interval_may_overlap(node, ext)) {
+ * if (extent_overlapped(ext, &node->in_extent))
+ * func(node, data);
+ * interval_search(node->in_left, ext, func, data);
+ * interval_search(node->in_right, ext, func, data);
+ * }
+ * return 0;
+ * }
+ *
+ */
+enum interval_iter interval_search(struct interval_node *node,
+ struct interval_node_extent *ext,
+ interval_callback_t func,
+ void *data)
+{
+ enum interval_iter rc = INTERVAL_ITER_CONT;
+ struct interval_node *parent;
+
+ LASSERT(ext);
+ LASSERT(func);
+
+ while (node) {
+ if (ext->end < interval_low(node)) {
+ if (node->in_left) {
+ node = node->in_left;
+ continue;
+ }
+ } else if (interval_may_overlap(node, ext)) {
+ if (extent_overlapped(ext, &node->in_extent)) {
+ rc = func(node, data);
+ if (rc == INTERVAL_ITER_STOP)
+ break;
+ }
+
+ if (node->in_left) {
+ node = node->in_left;
+ continue;
+ }
+ if (node->in_right) {
+ node = node->in_right;
+ continue;
+ }
+ }
+
+ parent = node->in_parent;
+ while (parent) {
+ if (node_is_left_child(node) &&
+ parent->in_right) {
+ /*
+ * If we ever got the left, it means that the
+ * parent met ext->end<interval_low(parent), or
+ * may_overlap(parent). If the former is true,
+ * we needn't go back. So stop early and check
+ * may_overlap(parent) after this loop.
+ */
+ node = parent->in_right;
+ break;
+ }
+ node = parent;
+ parent = parent->in_parent;
+ }
+ if (!parent || !interval_may_overlap(parent, ext))
+ break;
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL(interval_search);
diff --git a/drivers/staging/lustre/lustre/ldlm/l_lock.c b/drivers/staging/lustre/lustre/ldlm/l_lock.c
index ea8840cb9056..3845f386f1db 100644
--- a/drivers/staging/lustre/lustre/ldlm/l_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/l_lock.c
@@ -45,6 +45,8 @@
* being an atomic operation.
*/
struct ldlm_resource *lock_res_and_lock(struct ldlm_lock *lock)
+ __acquires(&lock->l_lock)
+ __acquires(&lock->l_resource->lr_lock)
{
spin_lock(&lock->l_lock);
@@ -59,6 +61,8 @@ EXPORT_SYMBOL(lock_res_and_lock);
* Unlock a lock and its resource previously locked with lock_res_and_lock
*/
void unlock_res_and_lock(struct ldlm_lock *lock)
+ __releases(&lock->l_resource->lr_lock)
+ __releases(&lock->l_lock)
{
/* on server-side resource of lock doesn't change */
ldlm_clear_res_locked(lock);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c b/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c
index f5023d9b78f5..ecf472e4813d 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c
@@ -221,7 +221,7 @@ void ldlm_extent_unlink_lock(struct ldlm_lock *lock)
}
void ldlm_extent_policy_wire_to_local(const ldlm_wire_policy_data_t *wpolicy,
- ldlm_policy_data_t *lpolicy)
+ ldlm_policy_data_t *lpolicy)
{
memset(lpolicy, 0, sizeof(*lpolicy));
lpolicy->l_extent.start = wpolicy->l_extent.start;
@@ -230,7 +230,7 @@ void ldlm_extent_policy_wire_to_local(const ldlm_wire_policy_data_t *wpolicy,
}
void ldlm_extent_policy_local_to_wire(const ldlm_policy_data_t *lpolicy,
- ldlm_wire_policy_data_t *wpolicy)
+ ldlm_wire_policy_data_t *wpolicy)
{
memset(wpolicy, 0, sizeof(*wpolicy));
wpolicy->l_extent.start = lpolicy->l_extent.start;
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
index d6b61bc39135..861f36f039b5 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
@@ -97,7 +97,7 @@ ldlm_flock_destroy(struct ldlm_lock *lock, enum ldlm_mode mode, __u64 flags)
LASSERT(hlist_unhashed(&lock->l_exp_flock_hash));
list_del_init(&lock->l_res_link);
- if (flags == LDLM_FL_WAIT_NOREPROC && !ldlm_is_failed(lock)) {
+ if (flags == LDLM_FL_WAIT_NOREPROC) {
/* client side - set a flag to prevent sending a CANCEL */
lock->l_flags |= LDLM_FL_LOCAL_ONLY | LDLM_FL_CBPENDING;
@@ -166,7 +166,7 @@ reprocess:
*/
list_for_each(tmp, &res->lr_granted) {
lock = list_entry(tmp, struct ldlm_lock,
- l_res_link);
+ l_res_link);
if (ldlm_same_flock_owner(lock, req)) {
ownlocks = tmp;
break;
@@ -182,7 +182,7 @@ reprocess:
*/
list_for_each(tmp, &res->lr_granted) {
lock = list_entry(tmp, struct ldlm_lock,
- l_res_link);
+ l_res_link);
if (ldlm_same_flock_owner(lock, req)) {
if (!ownlocks)
@@ -339,10 +339,10 @@ reprocess:
lock->l_granted_mode, &null_cbs,
NULL, 0, LVB_T_NONE);
lock_res_and_lock(req);
- if (!new2) {
+ if (IS_ERR(new2)) {
ldlm_flock_destroy(req, lock->l_granted_mode,
*flags);
- *err = -ENOLCK;
+ *err = PTR_ERR(new2);
return LDLM_ITER_STOP;
}
goto reprocess;
@@ -455,29 +455,22 @@ ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
enum ldlm_error err;
int rc = 0;
+ OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CP_CB_WAIT2, 4);
+ if (OBD_FAIL_PRECHECK(OBD_FAIL_LDLM_CP_CB_WAIT3)) {
+ lock_res_and_lock(lock);
+ lock->l_flags |= LDLM_FL_FAIL_LOC;
+ unlock_res_and_lock(lock);
+ OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CP_CB_WAIT3, 4);
+ }
CDEBUG(D_DLMTRACE, "flags: 0x%llx data: %p getlk: %p\n",
flags, data, getlk);
- /* Import invalidation. We need to actually release the lock
- * references being held, so that it can go away. No point in
- * holding the lock even if app still believes it has it, since
- * server already dropped it anyway. Only for granted locks too.
- */
- if ((lock->l_flags & (LDLM_FL_FAILED|LDLM_FL_LOCAL_ONLY)) ==
- (LDLM_FL_FAILED|LDLM_FL_LOCAL_ONLY)) {
- if (lock->l_req_mode == lock->l_granted_mode &&
- lock->l_granted_mode != LCK_NL && !data)
- ldlm_lock_decref_internal(lock, lock->l_req_mode);
-
- /* Need to wake up the waiter if we were evicted */
- wake_up(&lock->l_waitq);
- return 0;
- }
-
LASSERT(flags != LDLM_FL_WAIT_NOREPROC);
- if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
- LDLM_FL_BLOCK_CONV))) {
+ if (flags & LDLM_FL_FAILED)
+ goto granted;
+
+ if (!(flags & LDLM_FL_BLOCKED_MASK)) {
if (!data)
/* mds granted the lock in the reply */
goto granted;
@@ -514,12 +507,21 @@ ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
granted:
OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CP_CB_WAIT, 10);
- if (ldlm_is_failed(lock)) {
- LDLM_DEBUG(lock, "client-side enqueue waking up: failed");
- return -EIO;
+ if (OBD_FAIL_PRECHECK(OBD_FAIL_LDLM_CP_CB_WAIT4)) {
+ lock_res_and_lock(lock);
+ /* DEADLOCK is always set with CBPENDING */
+ lock->l_flags |= LDLM_FL_FLOCK_DEADLOCK | LDLM_FL_CBPENDING;
+ unlock_res_and_lock(lock);
+ OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CP_CB_WAIT4, 4);
+ }
+ if (OBD_FAIL_PRECHECK(OBD_FAIL_LDLM_CP_CB_WAIT5)) {
+ lock_res_and_lock(lock);
+ /* DEADLOCK is always set with CBPENDING */
+ lock->l_flags |= LDLM_FL_FAIL_LOC |
+ LDLM_FL_FLOCK_DEADLOCK | LDLM_FL_CBPENDING;
+ unlock_res_and_lock(lock);
+ OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CP_CB_WAIT5, 4);
}
-
- LDLM_DEBUG(lock, "client-side enqueue granted");
lock_res_and_lock(lock);
@@ -530,20 +532,59 @@ granted:
if (ldlm_is_destroyed(lock)) {
unlock_res_and_lock(lock);
LDLM_DEBUG(lock, "client-side enqueue waking up: destroyed");
- return 0;
+ /*
+ * An error is still to be returned, to propagate it up to
+ * ldlm_cli_enqueue_fini() caller.
+ */
+ return -EIO;
}
/* ldlm_lock_enqueue() has already placed lock on the granted list. */
- list_del_init(&lock->l_res_link);
+ ldlm_resource_unlink_lock(lock);
+
+ /*
+ * Import invalidation. We need to actually release the lock
+ * references being held, so that it can go away. No point in
+ * holding the lock even if app still believes it has it, since
+ * server already dropped it anyway. Only for granted locks too.
+ */
+ /* Do the same for DEADLOCK'ed locks. */
+ if (ldlm_is_failed(lock) || ldlm_is_flock_deadlock(lock)) {
+ int mode;
+
+ if (flags & LDLM_FL_TEST_LOCK)
+ LASSERT(ldlm_is_test_lock(lock));
+
+ if (ldlm_is_test_lock(lock) || ldlm_is_flock_deadlock(lock))
+ mode = getlk->fl_type;
+ else
+ mode = lock->l_granted_mode;
+
+ if (ldlm_is_flock_deadlock(lock)) {
+ LDLM_DEBUG(lock, "client-side enqueue deadlock received");
+ rc = -EDEADLK;
+ }
+ ldlm_flock_destroy(lock, mode, LDLM_FL_WAIT_NOREPROC);
+ unlock_res_and_lock(lock);
+
+ /* Need to wake up the waiter if we were evicted */
+ wake_up(&lock->l_waitq);
+
+ /*
+ * An error is still to be returned, to propagate it up to
+ * ldlm_cli_enqueue_fini() caller.
+ */
+ return rc ? : -EIO;
+ }
+
+ LDLM_DEBUG(lock, "client-side enqueue granted");
- if (ldlm_is_flock_deadlock(lock)) {
- LDLM_DEBUG(lock, "client-side enqueue deadlock received");
- rc = -EDEADLK;
- } else if (flags & LDLM_FL_TEST_LOCK) {
+ if (flags & LDLM_FL_TEST_LOCK) {
/* fcntl(F_GETLK) request */
/* The old mode was saved in getlk->fl_type so that if the mode
* in the lock changes we can decref the appropriate refcount.
*/
+ LASSERT(ldlm_is_test_lock(lock));
ldlm_flock_destroy(lock, getlk->fl_type, LDLM_FL_WAIT_NOREPROC);
switch (lock->l_granted_mode) {
case LCK_PR:
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
index e4cf65d2d3b1..5e82cfc245b2 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
@@ -100,9 +100,10 @@ enum {
int ldlm_cancel_lru(struct ldlm_namespace *ns, int nr,
enum ldlm_cancel_flags sync, int flags);
int ldlm_cancel_lru_local(struct ldlm_namespace *ns,
- struct list_head *cancels, int count, int max,
- enum ldlm_cancel_flags cancel_flags, int flags);
-extern int ldlm_enqueue_min;
+ struct list_head *cancels, int count, int max,
+ enum ldlm_cancel_flags cancel_flags, int flags);
+extern unsigned int ldlm_enqueue_min;
+extern unsigned int ldlm_cancel_unused_locks_before_replay;
/* ldlm_resource.c */
int ldlm_resource_putref_locked(struct ldlm_resource *res);
@@ -200,8 +201,7 @@ ldlm_interval_extent(struct ldlm_interval *node)
LASSERT(!list_empty(&node->li_group));
- lock = list_entry(node->li_group.next, struct ldlm_lock,
- l_sl_policy);
+ lock = list_entry(node->li_group.next, struct ldlm_lock, l_sl_policy);
return &lock->l_policy_data.l_extent;
}
@@ -302,7 +302,7 @@ static inline int is_granted_or_cancelled(struct ldlm_lock *lock)
lock_res_and_lock(lock);
if ((lock->l_req_mode == lock->l_granted_mode) &&
- !ldlm_is_cp_reqd(lock))
+ !ldlm_is_cp_reqd(lock))
ret = 1;
else if (ldlm_is_failed(lock) || ldlm_is_cancel(lock))
ret = 1;
@@ -326,13 +326,13 @@ void ldlm_ibits_policy_wire_to_local(const ldlm_wire_policy_data_t *wpolicy,
void ldlm_ibits_policy_local_to_wire(const ldlm_policy_data_t *lpolicy,
ldlm_wire_policy_data_t *wpolicy);
void ldlm_extent_policy_wire_to_local(const ldlm_wire_policy_data_t *wpolicy,
- ldlm_policy_data_t *lpolicy);
+ ldlm_policy_data_t *lpolicy);
void ldlm_extent_policy_local_to_wire(const ldlm_policy_data_t *lpolicy,
- ldlm_wire_policy_data_t *wpolicy);
+ ldlm_wire_policy_data_t *wpolicy);
void ldlm_flock_policy_wire18_to_local(const ldlm_wire_policy_data_t *wpolicy,
- ldlm_policy_data_t *lpolicy);
+ ldlm_policy_data_t *lpolicy);
void ldlm_flock_policy_wire21_to_local(const ldlm_wire_policy_data_t *wpolicy,
- ldlm_policy_data_t *lpolicy);
+ ldlm_policy_data_t *lpolicy);
void ldlm_flock_policy_local_to_wire(const ldlm_policy_data_t *lpolicy,
ldlm_wire_policy_data_t *wpolicy);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
index 7c832aae7d5e..153e990c494e 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
@@ -82,7 +82,7 @@ static int import_set_conn(struct obd_import *imp, struct obd_uuid *uuid,
if (priority) {
list_del(&item->oic_item);
list_add(&item->oic_item,
- &imp->imp_conn_list);
+ &imp->imp_conn_list);
item->oic_last_attempt = 0;
}
CDEBUG(D_HA, "imp %p@%s: found existing conn %s%s\n",
@@ -102,7 +102,7 @@ static int import_set_conn(struct obd_import *imp, struct obd_uuid *uuid,
list_add(&imp_conn->oic_item, &imp->imp_conn_list);
else
list_add_tail(&imp_conn->oic_item,
- &imp->imp_conn_list);
+ &imp->imp_conn_list);
CDEBUG(D_HA, "imp %p@%s: add connection %s at %s\n",
imp, imp->imp_obd->obd_name, uuid->uuid,
(priority ? "head" : "tail"));
@@ -299,12 +299,14 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg)
min_t(unsigned int, LUSTRE_CFG_BUFLEN(lcfg, 2),
sizeof(server_uuid)));
- cli->cl_dirty = 0;
+ cli->cl_dirty_pages = 0;
cli->cl_avail_grant = 0;
- /* FIXME: Should limit this for the sum of all cl_dirty_max. */
- cli->cl_dirty_max = OSC_MAX_DIRTY_DEFAULT * 1024 * 1024;
- if (cli->cl_dirty_max >> PAGE_SHIFT > totalram_pages / 8)
- cli->cl_dirty_max = totalram_pages << (PAGE_SHIFT - 3);
+ /* FIXME: Should limit this for the sum of all cl_dirty_max_pages. */
+ /*
+ * cl_dirty_max_pages may be changed at connect time in
+ * ptlrpc_connect_interpret().
+ */
+ client_adjust_max_dirty(cli);
INIT_LIST_HEAD(&cli->cl_cache_waiters);
INIT_LIST_HEAD(&cli->cl_loi_ready_list);
INIT_LIST_HEAD(&cli->cl_loi_hp_ready_list);
@@ -326,11 +328,11 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg)
/* lru for osc. */
INIT_LIST_HEAD(&cli->cl_lru_osc);
atomic_set(&cli->cl_lru_shrinkers, 0);
- atomic_set(&cli->cl_lru_busy, 0);
- atomic_set(&cli->cl_lru_in_list, 0);
+ atomic_long_set(&cli->cl_lru_busy, 0);
+ atomic_long_set(&cli->cl_lru_in_list, 0);
INIT_LIST_HEAD(&cli->cl_lru_list);
spin_lock_init(&cli->cl_lru_list_lock);
- atomic_set(&cli->cl_unstable_count, 0);
+ atomic_long_set(&cli->cl_unstable_count, 0);
init_waitqueue_head(&cli->cl_destroy_waitq);
atomic_set(&cli->cl_destroy_in_flight, 0);
@@ -360,7 +362,7 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg)
cli->cl_chunkbits = PAGE_SHIFT;
if (!strcmp(name, LUSTRE_MDC_NAME)) {
- cli->cl_max_rpcs_in_flight = MDC_MAX_RIF_DEFAULT;
+ cli->cl_max_rpcs_in_flight = OBD_MAX_RIF_DEFAULT;
} else if (totalram_pages >> (20 - PAGE_SHIFT) <= 128 /* MB */) {
cli->cl_max_rpcs_in_flight = 2;
} else if (totalram_pages >> (20 - PAGE_SHIFT) <= 256 /* MB */) {
@@ -368,7 +370,7 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg)
} else if (totalram_pages >> (20 - PAGE_SHIFT) <= 512 /* MB */) {
cli->cl_max_rpcs_in_flight = 4;
} else {
- cli->cl_max_rpcs_in_flight = OSC_MAX_RIF_DEFAULT;
+ cli->cl_max_rpcs_in_flight = OBD_MAX_RIF_DEFAULT;
}
rc = ldlm_get_ref();
if (rc) {
@@ -534,7 +536,7 @@ int client_disconnect_export(struct obd_export *exp)
imp = cli->cl_import;
down_write(&cli->cl_sem);
- CDEBUG(D_INFO, "disconnect %s - %d\n", obd->obd_name,
+ CDEBUG(D_INFO, "disconnect %s - %zu\n", obd->obd_name,
cli->cl_conn_count);
if (!cli->cl_conn_count) {
@@ -690,7 +692,7 @@ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id)
if (rs->rs_transno > exp->exp_last_committed) {
/* not committed already */
list_add_tail(&rs->rs_obd_list,
- &exp->exp_uncommitted_replies);
+ &exp->exp_uncommitted_replies);
}
spin_unlock(&exp->exp_uncommitted_replies_lock);
@@ -795,7 +797,7 @@ void ldlm_dump_export_locks(struct obd_export *exp)
CERROR("dumping locks for export %p,ignore if the unmount doesn't hang\n",
exp);
list_for_each_entry(lock, &exp->exp_locks_list,
- l_exp_refs_link)
+ l_exp_refs_link)
LDLM_ERROR(lock, "lock:");
}
spin_unlock(&exp->exp_locks_list_guard);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index a5993f745ebe..3c48b4fb96f1 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -481,8 +481,8 @@ int ldlm_lock_change_resource(struct ldlm_namespace *ns, struct ldlm_lock *lock,
unlock_res_and_lock(lock);
newres = ldlm_resource_get(ns, NULL, new_resid, type, 1);
- if (!newres)
- return -ENOMEM;
+ if (IS_ERR(newres))
+ return PTR_ERR(newres);
lu_ref_add(&newres->lr_reference, "lock", lock);
/*
@@ -542,7 +542,7 @@ struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *handle,
LASSERT(handle);
- lock = class_handle2object(handle->cookie);
+ lock = class_handle2object(handle->cookie, NULL);
if (!lock)
return NULL;
@@ -937,7 +937,7 @@ static void search_granted_lock(struct list_head *queue,
/* go to next policy group within mode group */
tmp = policy_end->l_res_link.next;
lock = list_entry(tmp, struct ldlm_lock,
- l_res_link);
+ l_res_link);
} /* loop over policy groups within the mode group */
/* insert point is last lock of the mode group,
@@ -1028,15 +1028,28 @@ void ldlm_grant_lock(struct ldlm_lock *lock, struct list_head *work_list)
check_res_locked(res);
lock->l_granted_mode = lock->l_req_mode;
+
+ if (work_list && lock->l_completion_ast)
+ ldlm_add_ast_work_item(lock, NULL, work_list);
+
if (res->lr_type == LDLM_PLAIN || res->lr_type == LDLM_IBITS)
ldlm_grant_lock_with_skiplist(lock);
else if (res->lr_type == LDLM_EXTENT)
ldlm_extent_add_lock(res, lock);
- else
+ else if (res->lr_type == LDLM_FLOCK) {
+ /*
+ * We should not add locks to granted list in the following cases:
+ * - this is an UNLOCK but not a real lock;
+ * - this is a TEST lock;
+ * - this is a F_CANCELLK lock (async flock has req_mode == 0)
+ * - this is a deadlock (flock cannot be granted)
+ */
+ if (!lock->l_req_mode || lock->l_req_mode == LCK_NL ||
+ ldlm_is_test_lock(lock) || ldlm_is_flock_deadlock(lock))
+ return;
ldlm_resource_add_lock(res, &res->lr_granted, lock);
-
- if (work_list && lock->l_completion_ast)
- ldlm_add_ast_work_item(lock, NULL, work_list);
+ } else
+ LBUG();
ldlm_pool_add(&ldlm_res_to_ns(res)->ns_pool, lock);
}
@@ -1103,7 +1116,7 @@ static struct ldlm_lock *search_queue(struct list_head *queue,
* of bits.
*/
if (lock->l_resource->lr_type == LDLM_IBITS &&
- ((lock->l_policy_data.l_inodebits.bits &
+ ((lock->l_policy_data.l_inodebits.bits &
policy->l_inodebits.bits) !=
policy->l_inodebits.bits))
continue;
@@ -1214,7 +1227,7 @@ enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags,
}
res = ldlm_resource_get(ns, NULL, res_id, type, 0);
- if (!res) {
+ if (IS_ERR(res)) {
LASSERT(!old_lock);
return 0;
}
@@ -1363,12 +1376,12 @@ int ldlm_fill_lvb(struct ldlm_lock *lock, struct req_capsule *pill,
if (size == sizeof(struct ost_lvb)) {
if (loc == RCL_CLIENT)
lvb = req_capsule_client_swab_get(pill,
- &RMF_DLM_LVB,
- lustre_swab_ost_lvb);
+ &RMF_DLM_LVB,
+ lustre_swab_ost_lvb);
else
lvb = req_capsule_server_swab_get(pill,
- &RMF_DLM_LVB,
- lustre_swab_ost_lvb);
+ &RMF_DLM_LVB,
+ lustre_swab_ost_lvb);
if (unlikely(!lvb)) {
LDLM_ERROR(lock, "no LVB");
return -EPROTO;
@@ -1380,8 +1393,8 @@ int ldlm_fill_lvb(struct ldlm_lock *lock, struct req_capsule *pill,
if (loc == RCL_CLIENT)
lvb = req_capsule_client_swab_get(pill,
- &RMF_DLM_LVB,
- lustre_swab_ost_lvb_v1);
+ &RMF_DLM_LVB,
+ lustre_swab_ost_lvb_v1);
else
lvb = req_capsule_server_sized_swab_get(pill,
&RMF_DLM_LVB, size,
@@ -1405,12 +1418,12 @@ int ldlm_fill_lvb(struct ldlm_lock *lock, struct req_capsule *pill,
if (size == sizeof(struct lquota_lvb)) {
if (loc == RCL_CLIENT)
lvb = req_capsule_client_swab_get(pill,
- &RMF_DLM_LVB,
- lustre_swab_lquota_lvb);
+ &RMF_DLM_LVB,
+ lustre_swab_lquota_lvb);
else
lvb = req_capsule_server_swab_get(pill,
- &RMF_DLM_LVB,
- lustre_swab_lquota_lvb);
+ &RMF_DLM_LVB,
+ lustre_swab_lquota_lvb);
if (unlikely(!lvb)) {
LDLM_ERROR(lock, "no LVB");
return -EPROTO;
@@ -1462,15 +1475,15 @@ struct ldlm_lock *ldlm_lock_create(struct ldlm_namespace *ns,
{
struct ldlm_lock *lock;
struct ldlm_resource *res;
+ int rc;
res = ldlm_resource_get(ns, NULL, res_id, type, 1);
- if (!res)
- return NULL;
+ if (IS_ERR(res))
+ return ERR_CAST(res);
lock = ldlm_lock_new(res);
-
if (!lock)
- return NULL;
+ return ERR_PTR(-ENOMEM);
lock->l_req_mode = mode;
lock->l_ast_data = data;
@@ -1484,27 +1497,33 @@ struct ldlm_lock *ldlm_lock_create(struct ldlm_namespace *ns,
lock->l_tree_node = NULL;
/* if this is the extent lock, allocate the interval tree node */
if (type == LDLM_EXTENT) {
- if (!ldlm_interval_alloc(lock))
+ if (!ldlm_interval_alloc(lock)) {
+ rc = -ENOMEM;
goto out;
+ }
}
if (lvb_len) {
lock->l_lvb_len = lvb_len;
lock->l_lvb_data = kzalloc(lvb_len, GFP_NOFS);
- if (!lock->l_lvb_data)
+ if (!lock->l_lvb_data) {
+ rc = -ENOMEM;
goto out;
+ }
}
lock->l_lvb_type = lvb_type;
- if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_NEW_LOCK))
+ if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_NEW_LOCK)) {
+ rc = -ENOENT;
goto out;
+ }
return lock;
out:
ldlm_lock_destroy(lock);
LDLM_LOCK_RELEASE(lock);
- return NULL;
+ return ERR_PTR(rc);
}
/**
@@ -1522,16 +1541,13 @@ enum ldlm_error ldlm_lock_enqueue(struct ldlm_namespace *ns,
struct ldlm_lock *lock = *lockp;
struct ldlm_resource *res = lock->l_resource;
- lock->l_last_activity = ktime_get_real_seconds();
-
lock_res_and_lock(lock);
if (lock->l_req_mode == lock->l_granted_mode) {
/* The server returned a blocked lock, but it was granted
* before we got a chance to actually enqueue it. We don't
* need to do anything else.
*/
- *flags &= ~(LDLM_FL_BLOCK_GRANTED |
- LDLM_FL_BLOCK_CONV | LDLM_FL_BLOCK_WAIT);
+ *flags &= ~LDLM_FL_BLOCKED_MASK;
goto out;
}
@@ -1546,6 +1562,8 @@ enum ldlm_error ldlm_lock_enqueue(struct ldlm_namespace *ns,
*/
if (*flags & LDLM_FL_AST_DISCARD_DATA)
ldlm_set_ast_discard_data(lock);
+ if (*flags & LDLM_FL_TEST_LOCK)
+ ldlm_set_test_lock(lock);
/*
* This distinction between local lock trees is very important; a client
@@ -1688,7 +1706,7 @@ static int ldlm_work_gl_ast_lock(struct ptlrpc_request_set *rqset, void *opaq)
return -ENOENT;
gl_work = list_entry(arg->list->next, struct ldlm_glimpse_work,
- gl_list);
+ gl_list);
list_del_init(&gl_work->gl_list);
lock = gl_work->gl_lock;
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
index 821939ff2e6b..fde697ebaadc 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
@@ -559,8 +559,11 @@ static int ldlm_callback_handler(struct ptlrpc_request *req)
switch (lustre_msg_get_opc(req->rq_reqmsg)) {
case LDLM_BL_CALLBACK:
- if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_BL_CALLBACK_NET))
+ if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_BL_CALLBACK_NET)) {
+ if (cfs_fail_err)
+ ldlm_callback_reply(req, -(int)cfs_fail_err);
return 0;
+ }
break;
case LDLM_CP_CALLBACK:
if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_CP_CALLBACK_NET))
@@ -706,12 +709,12 @@ static struct ldlm_bl_work_item *ldlm_bl_get_work(struct ldlm_bl_pool *blp)
if (!list_empty(&blp->blp_list) &&
(list_empty(&blp->blp_prio_list) || num_bl == 0))
blwi = list_entry(blp->blp_list.next,
- struct ldlm_bl_work_item, blwi_entry);
+ struct ldlm_bl_work_item, blwi_entry);
else
if (!list_empty(&blp->blp_prio_list))
blwi = list_entry(blp->blp_prio_list.next,
- struct ldlm_bl_work_item,
- blwi_entry);
+ struct ldlm_bl_work_item,
+ blwi_entry);
if (blwi) {
if (++num_bl >= atomic_read(&blp->blp_num_threads))
@@ -741,7 +744,7 @@ static int ldlm_bl_thread_start(struct ldlm_bl_pool *blp)
init_completion(&bltd.bltd_comp);
bltd.bltd_num = atomic_read(&blp->blp_num_threads);
snprintf(bltd.bltd_name, sizeof(bltd.bltd_name),
- "ldlm_bl_%02d", bltd.bltd_num);
+ "ldlm_bl_%02d", bltd.bltd_num);
task = kthread_run(ldlm_bl_thread_main, &bltd, "%s", bltd.bltd_name);
if (IS_ERR(task)) {
CERROR("cannot start LDLM thread ldlm_bl_%02d: rc %ld\n",
@@ -786,8 +789,8 @@ static int ldlm_bl_thread_main(void *arg)
if (!blwi) {
atomic_dec(&blp->blp_busy_threads);
l_wait_event_exclusive(blp->blp_waitq,
- (blwi = ldlm_bl_get_work(blp)),
- &lwi);
+ (blwi = ldlm_bl_get_work(blp)),
+ &lwi);
busy = atomic_inc_return(&blp->blp_busy_threads);
} else {
busy = atomic_read(&blp->blp_busy_threads);
@@ -874,8 +877,6 @@ void ldlm_put_ref(void)
}
EXPORT_SYMBOL(ldlm_put_ref);
-extern unsigned int ldlm_cancel_unused_locks_before_replay;
-
static ssize_t cancel_unused_locks_before_replay_show(struct kobject *kobj,
struct attribute *attr,
char *buf)
@@ -1094,16 +1095,17 @@ int ldlm_init(void)
return -ENOMEM;
ldlm_lock_slab = kmem_cache_create("ldlm_locks",
- sizeof(struct ldlm_lock), 0,
- SLAB_HWCACHE_ALIGN | SLAB_DESTROY_BY_RCU, NULL);
+ sizeof(struct ldlm_lock), 0,
+ SLAB_HWCACHE_ALIGN |
+ SLAB_DESTROY_BY_RCU, NULL);
if (!ldlm_lock_slab) {
kmem_cache_destroy(ldlm_resource_slab);
return -ENOMEM;
}
ldlm_interval_slab = kmem_cache_create("interval_node",
- sizeof(struct ldlm_interval),
- 0, SLAB_HWCACHE_ALIGN, NULL);
+ sizeof(struct ldlm_interval),
+ 0, SLAB_HWCACHE_ALIGN, NULL);
if (!ldlm_interval_slab) {
kmem_cache_destroy(ldlm_resource_slab);
kmem_cache_destroy(ldlm_lock_slab);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
index 657ed4012776..9a1136e32dfc 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
@@ -357,38 +357,40 @@ static int ldlm_pool_recalc(struct ldlm_pool *pl)
int count;
recalc_interval_sec = ktime_get_seconds() - pl->pl_recalc_time;
- if (recalc_interval_sec <= 0)
- goto recalc;
-
- spin_lock(&pl->pl_lock);
if (recalc_interval_sec > 0) {
- /*
- * Update pool statistics every 1s.
- */
- ldlm_pool_recalc_stats(pl);
-
- /*
- * Zero out all rates and speed for the last period.
- */
- atomic_set(&pl->pl_grant_rate, 0);
- atomic_set(&pl->pl_cancel_rate, 0);
+ spin_lock(&pl->pl_lock);
+ recalc_interval_sec = ktime_get_seconds() - pl->pl_recalc_time;
+
+ if (recalc_interval_sec > 0) {
+ /*
+ * Update pool statistics every 1s.
+ */
+ ldlm_pool_recalc_stats(pl);
+
+ /*
+ * Zero out all rates and speed for the last period.
+ */
+ atomic_set(&pl->pl_grant_rate, 0);
+ atomic_set(&pl->pl_cancel_rate, 0);
+ }
+ spin_unlock(&pl->pl_lock);
}
- spin_unlock(&pl->pl_lock);
- recalc:
if (pl->pl_ops->po_recalc) {
count = pl->pl_ops->po_recalc(pl);
lprocfs_counter_add(pl->pl_stats, LDLM_POOL_RECALC_STAT,
count);
}
+
recalc_interval_sec = pl->pl_recalc_time - ktime_get_seconds() +
pl->pl_recalc_period;
if (recalc_interval_sec <= 0) {
+ /* DEBUG: should be re-removed after LU-4536 is fixed */
+ CDEBUG(D_DLMTRACE, "%s: Negative interval(%ld), too short period(%ld)\n",
+ pl->pl_name, (long)recalc_interval_sec,
+ (long)pl->pl_recalc_period);
+
/* Prevent too frequent recalculation. */
- CDEBUG(D_DLMTRACE,
- "Negative interval(%d), too short period(%lld)",
- recalc_interval_sec,
- (s64)pl->pl_recalc_period);
recalc_interval_sec = 1;
}
@@ -792,7 +794,8 @@ static struct completion ldlm_pools_comp;
*/
static unsigned long ldlm_pools_count(ldlm_side_t client, gfp_t gfp_mask)
{
- int total = 0, nr_ns;
+ unsigned long total = 0;
+ int nr_ns;
struct ldlm_namespace *ns;
struct ldlm_namespace *ns_old = NULL; /* loop detection */
void *cookie;
@@ -995,7 +998,7 @@ static int ldlm_pools_thread_main(void *arg)
wake_up(&thread->t_ctl_waitq);
CDEBUG(D_DLMTRACE, "%s: pool thread starting, process %d\n",
- "ldlm_poold", current_pid());
+ "ldlm_poold", current_pid());
while (1) {
struct l_wait_info lwi;
@@ -1025,7 +1028,7 @@ static int ldlm_pools_thread_main(void *arg)
wake_up(&thread->t_ctl_waitq);
CDEBUG(D_DLMTRACE, "%s: pool thread exiting, process %d\n",
- "ldlm_poold", current_pid());
+ "ldlm_poold", current_pid());
complete_and_exit(&ldlm_pools_comp, 0);
}
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index af487f9937f4..35ba6f14d95f 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -63,8 +63,8 @@
#include "ldlm_internal.h"
-int ldlm_enqueue_min = OBD_TIMEOUT_DEFAULT;
-module_param(ldlm_enqueue_min, int, 0644);
+unsigned int ldlm_enqueue_min = OBD_TIMEOUT_DEFAULT;
+module_param(ldlm_enqueue_min, uint, 0644);
MODULE_PARM_DESC(ldlm_enqueue_min, "lock enqueue timeout minimum");
/* in client side, whether the cached locks will be canceled before replay */
@@ -123,44 +123,56 @@ static int ldlm_expired_completion_wait(void *data)
return 0;
}
+/**
+ * Calculate the Completion timeout (covering enqueue, BL AST, data flush,
+ * lock cancel, and their replies). Used for lock completion timeout on the
+ * client side.
+ *
+ * \param[in] lock lock which is waiting the completion callback
+ *
+ * \retval timeout in seconds to wait for the server reply
+ */
/* We use the same basis for both server side and client side functions
* from a single node.
*/
-static int ldlm_get_enq_timeout(struct ldlm_lock *lock)
+static unsigned int ldlm_cp_timeout(struct ldlm_lock *lock)
{
- int timeout = at_get(ldlm_lock_to_ns_at(lock));
+ unsigned int timeout;
if (AT_OFF)
- return obd_timeout / 2;
- /* Since these are non-updating timeouts, we should be conservative.
- * It would be nice to have some kind of "early reply" mechanism for
- * lock callbacks too...
+ return obd_timeout;
+
+ /*
+ * Wait a long time for enqueue - server may have to callback a
+ * lock from another client. Server will evict the other client if it
+ * doesn't respond reasonably, and then give us the lock.
*/
- timeout = min_t(int, at_max, timeout + (timeout >> 1)); /* 150% */
- return max(timeout, ldlm_enqueue_min);
+ timeout = at_get(ldlm_lock_to_ns_at(lock));
+ return max(3 * timeout, ldlm_enqueue_min);
}
/**
* Helper function for ldlm_completion_ast(), updating timings when lock is
* actually granted.
*/
-static int ldlm_completion_tail(struct ldlm_lock *lock)
+static int ldlm_completion_tail(struct ldlm_lock *lock, void *data)
{
long delay;
- int result;
+ int result = 0;
if (ldlm_is_destroyed(lock) || ldlm_is_failed(lock)) {
LDLM_DEBUG(lock, "client-side enqueue: destroyed");
result = -EIO;
+ } else if (!data) {
+ LDLM_DEBUG(lock, "client-side enqueue: granted");
} else {
+ /* Take into AT only CP RPC, not immediately granted locks */
delay = ktime_get_real_seconds() - lock->l_last_activity;
LDLM_DEBUG(lock, "client-side enqueue: granted after %lds",
delay);
/* Update our time estimate */
- at_measured(ldlm_lock_to_ns_at(lock),
- delay);
- result = 0;
+ at_measured(ldlm_lock_to_ns_at(lock), delay);
}
return result;
}
@@ -177,10 +189,9 @@ int ldlm_completion_ast_async(struct ldlm_lock *lock, __u64 flags, void *data)
return 0;
}
- if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
- LDLM_FL_BLOCK_CONV))) {
+ if (!(flags & LDLM_FL_BLOCKED_MASK)) {
wake_up(&lock->l_waitq);
- return ldlm_completion_tail(lock);
+ return ldlm_completion_tail(lock, data);
}
LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, going forward");
@@ -224,8 +235,7 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
goto noreproc;
}
- if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
- LDLM_FL_BLOCK_CONV))) {
+ if (!(flags & LDLM_FL_BLOCKED_MASK)) {
wake_up(&lock->l_waitq);
return 0;
}
@@ -240,13 +250,10 @@ noreproc:
if (obd)
imp = obd->u.cli.cl_import;
- /* Wait a long time for enqueue - server may have to callback a
- * lock from another client. Server will evict the other client if it
- * doesn't respond reasonably, and then give us the lock.
- */
- timeout = ldlm_get_enq_timeout(lock) * 2;
+ timeout = ldlm_cp_timeout(lock);
lwd.lwd_lock = lock;
+ lock->l_last_activity = ktime_get_real_seconds();
if (ldlm_is_no_timeout(lock)) {
LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
@@ -279,7 +286,7 @@ noreproc:
return rc;
}
- return ldlm_completion_tail(lock);
+ return ldlm_completion_tail(lock, data);
}
EXPORT_SYMBOL(ldlm_completion_ast);
@@ -309,8 +316,6 @@ static void failed_lock_cleanup(struct ldlm_namespace *ns,
else
LDLM_DEBUG(lock, "lock was granted or failed in race");
- ldlm_lock_decref_internal(lock, mode);
-
/* XXX - HACK because we shouldn't call ldlm_lock_destroy()
* from llite/file.c/ll_file_flock().
*/
@@ -321,9 +326,14 @@ static void failed_lock_cleanup(struct ldlm_namespace *ns,
*/
if (lock->l_resource->lr_type == LDLM_FLOCK) {
lock_res_and_lock(lock);
- ldlm_resource_unlink_lock(lock);
- ldlm_lock_destroy_nolock(lock);
+ if (!ldlm_is_destroyed(lock)) {
+ ldlm_resource_unlink_lock(lock);
+ ldlm_lock_decref_internal_nolock(lock, mode);
+ ldlm_lock_destroy_nolock(lock);
+ }
unlock_res_and_lock(lock);
+ } else {
+ ldlm_lock_decref_internal(lock, mode);
}
}
@@ -418,11 +428,6 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req,
*flags = ldlm_flags_from_wire(reply->lock_flags);
lock->l_flags |= ldlm_flags_from_wire(reply->lock_flags &
LDLM_FL_INHERIT_MASK);
- /* move NO_TIMEOUT flag to the lock to force ldlm_lock_match()
- * to wait with no timeout as well
- */
- lock->l_flags |= ldlm_flags_from_wire(reply->lock_flags &
- LDLM_FL_NO_TIMEOUT);
unlock_res_and_lock(lock);
CDEBUG(D_INFO, "local: %p, remote cookie: %#llx, flags: 0x%llx\n",
@@ -556,7 +561,7 @@ static inline int ldlm_capsule_handles_avail(struct req_capsule *pill,
enum req_location loc,
int off)
{
- int size = req_capsule_msg_size(pill, loc);
+ u32 size = req_capsule_msg_size(pill, loc);
return ldlm_req_handles_avail(size, off);
}
@@ -565,7 +570,7 @@ static inline int ldlm_format_handles_avail(struct obd_import *imp,
const struct req_format *fmt,
enum req_location loc, int off)
{
- int size = req_capsule_fmt_size(imp->imp_msg_magic, fmt, loc);
+ u32 size = req_capsule_fmt_size(imp->imp_msg_magic, fmt, loc);
return ldlm_req_handles_avail(size, off);
}
@@ -696,8 +701,8 @@ int ldlm_cli_enqueue(struct obd_export *exp, struct ptlrpc_request **reqp,
lock = ldlm_lock_create(ns, res_id, einfo->ei_type,
einfo->ei_mode, &cbs, einfo->ei_cbdata,
lvb_len, lvb_type);
- if (!lock)
- return -ENOMEM;
+ if (IS_ERR(lock))
+ return PTR_ERR(lock);
/* for the local lock, add the reference */
ldlm_lock_addref_internal(lock, einfo->ei_mode);
ldlm_lock2handle(lock, lockh);
@@ -719,6 +724,7 @@ int ldlm_cli_enqueue(struct obd_export *exp, struct ptlrpc_request **reqp,
lock->l_export = NULL;
lock->l_blocking_ast = einfo->ei_cb_bl;
lock->l_flags |= (*flags & (LDLM_FL_NO_LRU | LDLM_FL_EXCL));
+ lock->l_last_activity = ktime_get_real_seconds();
/* lock not sent to server yet */
@@ -819,7 +825,7 @@ static __u64 ldlm_cli_cancel_local(struct ldlm_lock *lock)
lock_res_and_lock(lock);
ldlm_set_cbpending(lock);
local_only = !!(lock->l_flags &
- (LDLM_FL_LOCAL_ONLY|LDLM_FL_CANCEL_ON_BLOCK));
+ (LDLM_FL_LOCAL_ONLY | LDLM_FL_CANCEL_ON_BLOCK));
ldlm_cancel_callback(lock);
rc = ldlm_is_bl_ast(lock) ? LDLM_FL_BL_AST : LDLM_FL_CANCELING;
unlock_res_and_lock(lock);
@@ -1180,8 +1186,7 @@ static enum ldlm_policy_res ldlm_cancel_lrur_policy(struct ldlm_namespace *ns,
slv = ldlm_pool_get_slv(pl);
lvf = ldlm_pool_get_lvf(pl);
- la = cfs_duration_sec(cfs_time_sub(cur,
- lock->l_last_used));
+ la = cfs_duration_sec(cfs_time_sub(cur, lock->l_last_used));
lv = lvf * la * unused;
/* Inform pool about current CLV to see it via debugfs. */
@@ -1193,9 +1198,6 @@ static enum ldlm_policy_res ldlm_cancel_lrur_policy(struct ldlm_namespace *ns,
if (slv == 0 || lv < slv)
return LDLM_POLICY_KEEP_LOCK;
- if (ns->ns_cancel && ns->ns_cancel(lock) == 0)
- return LDLM_POLICY_KEEP_LOCK;
-
return LDLM_POLICY_CANCEL_LOCK;
}
@@ -1239,9 +1241,6 @@ static enum ldlm_policy_res ldlm_cancel_aged_policy(struct ldlm_namespace *ns,
cfs_time_add(lock->l_last_used, ns->ns_max_age)))
return LDLM_POLICY_KEEP_LOCK;
- if (ns->ns_cancel && ns->ns_cancel(lock) == 0)
- return LDLM_POLICY_KEEP_LOCK;
-
return LDLM_POLICY_CANCEL_LOCK;
}
@@ -1374,7 +1373,7 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns,
break;
list_for_each_entry_safe(lock, next, &ns->ns_unused_list,
- l_lru) {
+ l_lru) {
/* No locks which got blocking requests. */
LASSERT(!ldlm_is_bl_ast(lock));
@@ -1413,7 +1412,8 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns,
* That is, for shrinker policy we drop only
* old locks, but additionally choose them by
* their weight. Big extent locks will stay in
- * the cache. */
+ * the cache.
+ */
result = pf(ns, lock, unused, added, count);
if (result == LDLM_POLICY_KEEP_LOCK) {
lu_ref_del(&lock->l_reference,
@@ -1610,8 +1610,7 @@ int ldlm_cli_cancel_list(struct list_head *cancels, int count,
*/
while (count > 0) {
LASSERT(!list_empty(cancels));
- lock = list_entry(cancels->next, struct ldlm_lock,
- l_bl_ast);
+ lock = list_entry(cancels->next, struct ldlm_lock, l_bl_ast);
LASSERT(lock->l_conn_export);
if (exp_connect_cancelset(lock->l_conn_export)) {
@@ -1660,7 +1659,7 @@ int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns,
int rc;
res = ldlm_resource_get(ns, NULL, res_id, 0, 0);
- if (!res) {
+ if (IS_ERR(res)) {
/* This is not a problem. */
CDEBUG(D_INFO, "No resource %llu\n", res_id->name[0]);
return 0;
@@ -1704,7 +1703,8 @@ static int ldlm_cli_hash_cancel_unused(struct cfs_hash *hs,
* that have 0 readers/writers.
*
* If flags & LCF_LOCAL, throw the locks away without trying
- * to notify the server. */
+ * to notify the server.
+ */
int ldlm_cli_cancel_unused(struct ldlm_namespace *ns,
const struct ldlm_res_id *res_id,
enum ldlm_cancel_flags flags, void *opaque)
@@ -1811,13 +1811,10 @@ int ldlm_resource_iterate(struct ldlm_namespace *ns,
struct ldlm_resource *res;
int rc;
- if (!ns) {
- CERROR("must pass in namespace\n");
- LBUG();
- }
+ LASSERTF(ns, "must pass in namespace\n");
res = ldlm_resource_get(ns, NULL, res_id, 0, 0);
- if (!res)
+ if (IS_ERR(res))
return 0;
LDLM_RESOURCE_ADDREF(res);
@@ -1843,7 +1840,7 @@ static int ldlm_chain_lock_for_replay(struct ldlm_lock *lock, void *closure)
* bug 17614: locks being actively cancelled. Get a reference
* on a lock so that it does not disappear under us (e.g. due to cancel)
*/
- if (!(lock->l_flags & (LDLM_FL_FAILED|LDLM_FL_CANCELING))) {
+ if (!(lock->l_flags & (LDLM_FL_FAILED | LDLM_FL_CANCELING))) {
list_add(&lock->l_pending_chain, list);
LDLM_LOCK_GET(lock);
}
@@ -2013,7 +2010,7 @@ static void ldlm_cancel_unused_locks_for_replay(struct ldlm_namespace *ns)
LCF_LOCAL, LDLM_CANCEL_NO_WAIT);
CDEBUG(D_DLMTRACE, "Canceled %d unused locks from namespace %s\n",
- canceled, ldlm_ns_name(ns));
+ canceled, ldlm_ns_name(ns));
}
int ldlm_replay_locks(struct obd_import *imp)
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index 51a28d96af39..a09c25aea698 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -449,8 +449,8 @@ static unsigned ldlm_res_hop_hash(struct cfs_hash *hs,
const void *key, unsigned mask)
{
const struct ldlm_res_id *id = key;
- unsigned val = 0;
- unsigned i;
+ unsigned int val = 0;
+ unsigned int i;
for (i = 0; i < RES_NAME_SIZE; i++)
val += id->name[i];
@@ -561,9 +561,9 @@ static struct cfs_hash_ops ldlm_ns_fid_hash_ops = {
struct ldlm_ns_hash_def {
enum ldlm_ns_type nsd_type;
/** hash bucket bits */
- unsigned nsd_bkt_bits;
+ unsigned int nsd_bkt_bits;
/** hash bits */
- unsigned nsd_all_bits;
+ unsigned int nsd_all_bits;
/** hash operations */
struct cfs_hash_ops *nsd_hops;
};
@@ -758,8 +758,7 @@ static void cleanup_resource(struct ldlm_resource *res, struct list_head *q,
*/
lock_res(res);
list_for_each(tmp, q) {
- lock = list_entry(tmp, struct ldlm_lock,
- l_res_link);
+ lock = list_entry(tmp, struct ldlm_lock, l_res_link);
if (ldlm_is_cleaned(lock)) {
lock = NULL;
continue;
@@ -793,8 +792,14 @@ static void cleanup_resource(struct ldlm_resource *res, struct list_head *q,
*/
unlock_res(res);
LDLM_DEBUG(lock, "setting FL_LOCAL_ONLY");
+ if (lock->l_flags & LDLM_FL_FAIL_LOC) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(cfs_time_seconds(4));
+ set_current_state(TASK_RUNNING);
+ }
if (lock->l_completion_ast)
- lock->l_completion_ast(lock, 0, NULL);
+ lock->l_completion_ast(lock, LDLM_FL_FAILED,
+ NULL);
LDLM_LOCK_RELEASE(lock);
continue;
}
@@ -875,7 +880,8 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
ldlm_ns_name(ns), atomic_read(&ns->ns_bref));
force_wait:
if (force)
- lwi = LWI_TIMEOUT(obd_timeout * HZ / 4, NULL, NULL);
+ lwi = LWI_TIMEOUT(msecs_to_jiffies(obd_timeout *
+ MSEC_PER_SEC) / 4, NULL, NULL);
rc = l_wait_event(ns->ns_waitq,
atomic_read(&ns->ns_bref) == 0, &lwi);
@@ -1082,10 +1088,11 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
int create)
{
struct hlist_node *hnode;
- struct ldlm_resource *res;
+ struct ldlm_resource *res = NULL;
struct cfs_hash_bd bd;
__u64 version;
int ns_refcount = 0;
+ int rc;
LASSERT(!parent);
LASSERT(ns->ns_rs_hash);
@@ -1095,31 +1102,20 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
hnode = cfs_hash_bd_lookup_locked(ns->ns_rs_hash, &bd, (void *)name);
if (hnode) {
cfs_hash_bd_unlock(ns->ns_rs_hash, &bd, 0);
- res = hlist_entry(hnode, struct ldlm_resource, lr_hash);
- /* Synchronize with regard to resource creation. */
- if (ns->ns_lvbo && ns->ns_lvbo->lvbo_init) {
- mutex_lock(&res->lr_lvb_mutex);
- mutex_unlock(&res->lr_lvb_mutex);
- }
-
- if (unlikely(res->lr_lvb_len < 0)) {
- ldlm_resource_putref(res);
- res = NULL;
- }
- return res;
+ goto lvbo_init;
}
version = cfs_hash_bd_version_get(&bd);
cfs_hash_bd_unlock(ns->ns_rs_hash, &bd, 0);
if (create == 0)
- return NULL;
+ return ERR_PTR(-ENOENT);
LASSERTF(type >= LDLM_MIN_TYPE && type < LDLM_MAX_TYPE,
"type: %d\n", type);
res = ldlm_resource_new();
if (!res)
- return NULL;
+ return ERR_PTR(-ENOMEM);
res->lr_ns_bucket = cfs_hash_bd_extra_get(ns->ns_rs_hash, &bd);
res->lr_name = *name;
@@ -1137,7 +1133,7 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
/* We have taken lr_lvb_mutex. Drop it. */
mutex_unlock(&res->lr_lvb_mutex);
kmem_cache_free(ldlm_resource_slab, res);
-
+lvbo_init:
res = hlist_entry(hnode, struct ldlm_resource, lr_hash);
/* Synchronize with regard to resource creation. */
if (ns->ns_lvbo && ns->ns_lvbo->lvbo_init) {
@@ -1146,8 +1142,9 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
}
if (unlikely(res->lr_lvb_len < 0)) {
+ rc = res->lr_lvb_len;
ldlm_resource_putref(res);
- res = NULL;
+ res = ERR_PTR(rc);
}
return res;
}
@@ -1158,8 +1155,6 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
cfs_hash_bd_unlock(ns->ns_rs_hash, &bd, 1);
if (ns->ns_lvbo && ns->ns_lvbo->lvbo_init) {
- int rc;
-
OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CREATE_RESOURCE, 2);
rc = ns->ns_lvbo->lvbo_init(res);
if (rc < 0) {
@@ -1169,7 +1164,7 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
res->lr_lvb_len = rc;
mutex_unlock(&res->lr_lvb_mutex);
ldlm_resource_putref(res);
- return NULL;
+ return ERR_PTR(rc);
}
}
@@ -1386,7 +1381,7 @@ void ldlm_resource_dump(int level, struct ldlm_resource *res)
if (!list_empty(&res->lr_granted)) {
CDEBUG(level, "Granted locks (in reverse order):\n");
list_for_each_entry_reverse(lock, &res->lr_granted,
- l_res_link) {
+ l_res_link) {
LDLM_DEBUG_LIMIT(level, lock, "###");
if (!(level & D_CANTMASK) &&
++granted > ldlm_dump_granted_max) {
diff --git a/drivers/staging/lustre/lustre/llite/Makefile b/drivers/staging/lustre/lustre/llite/Makefile
index 2cbb1b80bd41..1ac0940bd8df 100644
--- a/drivers/staging/lustre/lustre/llite/Makefile
+++ b/drivers/staging/lustre/lustre/llite/Makefile
@@ -1,6 +1,6 @@
obj-$(CONFIG_LUSTRE_FS) += lustre.o
lustre-y := dcache.o dir.o file.o llite_close.o llite_lib.o llite_nfs.o \
- rw.o namei.o symlink.o llite_mmap.o \
+ rw.o namei.o symlink.o llite_mmap.o range_lock.o \
xattr.o xattr_cache.o rw26.o super25.o statahead.o \
glimpse.o lcommon_cl.o lcommon_misc.o \
vvp_dev.o vvp_page.o vvp_lock.o vvp_io.o vvp_object.o vvp_req.o \
diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c
index 463b1a360733..0e45d8fc4d7c 100644
--- a/drivers/staging/lustre/lustre/llite/dcache.c
+++ b/drivers/staging/lustre/lustre/llite/dcache.c
@@ -37,7 +37,6 @@
#define DEBUG_SUBSYSTEM S_LLITE
#include "../include/obd_support.h"
-#include "../include/lustre_lite.h"
#include "../include/lustre/lustre_idl.h"
#include "../include/lustre_dlm.h"
@@ -102,39 +101,6 @@ static int ll_dcompare(const struct dentry *dentry,
return 0;
}
-static inline int return_if_equal(struct ldlm_lock *lock, void *data)
-{
- return (ldlm_is_canceling(lock) && ldlm_is_discard_data(lock)) ?
- LDLM_ITER_CONTINUE : LDLM_ITER_STOP;
-}
-
-/* find any ldlm lock of the inode in mdc and lov
- * return 0 not find
- * 1 find one
- * < 0 error
- */
-static int find_cbdata(struct inode *inode)
-{
- struct ll_sb_info *sbi = ll_i2sbi(inode);
- struct lov_stripe_md *lsm;
- int rc = 0;
-
- LASSERT(inode);
- rc = md_find_cbdata(sbi->ll_md_exp, ll_inode2fid(inode),
- return_if_equal, NULL);
- if (rc != 0)
- return rc;
-
- lsm = ccc_inode_lsm_get(inode);
- if (!lsm)
- return rc;
-
- rc = obd_find_cbdata(sbi->ll_dt_exp, lsm, return_if_equal, NULL);
- ccc_inode_lsm_put(inode, lsm);
-
- return rc;
-}
-
/**
* Called when last reference to a dentry is dropped and dcache wants to know
* whether or not it should cache it:
@@ -155,19 +121,6 @@ static int ll_ddelete(const struct dentry *de)
/* kernel >= 2.6.38 last refcount is decreased after this function. */
LASSERT(d_count(de) == 1);
- /* Disable this piece of code temporarily because this is called
- * inside dcache_lock so it's not appropriate to do lots of work
- * here. ATTENTION: Before this piece of code enabling, LU-2487 must be
- * resolved.
- */
-#if 0
- /* if not ldlm lock for this inode, set i_nlink to 0 so that
- * this inode can be recycled later b=20433
- */
- if (d_really_is_positive(de) && !find_cbdata(d_inode(de)))
- clear_nlink(d_inode(de));
-#endif
-
if (d_lustre_invalid((struct dentry *)de))
return 1;
return 0;
@@ -325,14 +278,13 @@ static int ll_revalidate_dentry(struct dentry *dentry,
if (lookup_flags & (LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE))
return 1;
- if (d_need_statahead(dir, dentry) <= 0)
+ if (!dentry_may_statahead(dir, dentry))
return 1;
if (lookup_flags & LOOKUP_RCU)
return -ECHILD;
- do_statahead_enter(dir, &dentry, !d_inode(dentry));
- ll_statahead_mark(dir, dentry);
+ ll_statahead(dir, &dentry, !d_inode(dentry));
return 1;
}
@@ -347,18 +299,9 @@ static int ll_revalidate_nd(struct dentry *dentry, unsigned int flags)
return ll_revalidate_dentry(dentry, flags);
}
-static void ll_d_iput(struct dentry *de, struct inode *inode)
-{
- LASSERT(inode);
- if (!find_cbdata(inode))
- clear_nlink(inode);
- iput(inode);
-}
-
const struct dentry_operations ll_d_ops = {
.d_revalidate = ll_revalidate_nd,
.d_release = ll_release,
.d_delete = ll_ddelete,
- .d_iput = ll_d_iput,
.d_compare = ll_dcompare,
};
diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c
index 5b381779c827..7f32a539d260 100644
--- a/drivers/staging/lustre/lustre/llite/dir.c
+++ b/drivers/staging/lustre/lustre/llite/dir.c
@@ -46,9 +46,8 @@
#include "../include/obd_support.h"
#include "../include/obd_class.h"
+#include "../include/lustre/lustre_ioctl.h"
#include "../include/lustre_lib.h"
-#include "../include/lustre/lustre_idl.h"
-#include "../include/lustre_lite.h"
#include "../include/lustre_dlm.h"
#include "../include/lustre_fid.h"
#include "../include/lustre_kernelcomm.h"
@@ -134,111 +133,35 @@
* for this integrated page will be adjusted. See lmv_adjust_dirpages().
*
*/
-
-/* returns the page unlocked, but with a reference */
-static int ll_dir_filler(void *_hash, struct page *page0)
+struct page *ll_get_dir_page(struct inode *dir, struct md_op_data *op_data,
+ __u64 offset)
{
- struct inode *inode = page0->mapping->host;
- int hash64 = ll_i2sbi(inode)->ll_flags & LL_SBI_64BIT_HASH;
- struct obd_export *exp = ll_i2sbi(inode)->ll_md_exp;
- struct ptlrpc_request *request;
- struct mdt_body *body;
- struct md_op_data *op_data;
- __u64 hash = *((__u64 *)_hash);
- struct page **page_pool;
+ struct md_callback cb_op;
struct page *page;
- struct lu_dirpage *dp;
- int max_pages = ll_i2sbi(inode)->ll_md_brw_size >> PAGE_SHIFT;
- int nrdpgs = 0; /* number of pages read actually */
- int npages;
- int i;
int rc;
- CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p) hash %llu\n",
- PFID(ll_inode2fid(inode)), inode, hash);
-
- LASSERT(max_pages > 0 && max_pages <= MD_MAX_BRW_PAGES);
-
- op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
- LUSTRE_OPC_ANY, NULL);
- if (IS_ERR(op_data))
- return PTR_ERR(op_data);
-
- page_pool = kcalloc(max_pages, sizeof(page), GFP_NOFS);
- if (page_pool) {
- page_pool[0] = page0;
- } else {
- page_pool = &page0;
- max_pages = 1;
- }
- for (npages = 1; npages < max_pages; npages++) {
- page = page_cache_alloc_cold(inode->i_mapping);
- if (!page)
- break;
- page_pool[npages] = page;
- }
-
- op_data->op_npages = npages;
- op_data->op_offset = hash;
- rc = md_readpage(exp, op_data, page_pool, &request);
- ll_finish_md_op_data(op_data);
- if (rc < 0) {
- /* page0 is special, which was added into page cache early */
- delete_from_page_cache(page0);
- } else if (rc == 0) {
- body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY);
- /* Checked by mdc_readpage() */
- if (body->valid & OBD_MD_FLSIZE)
- i_size_write(inode, body->size);
-
- nrdpgs = (request->rq_bulk->bd_nob_transferred+PAGE_SIZE-1)
- >> PAGE_SHIFT;
- SetPageUptodate(page0);
- }
- unlock_page(page0);
- ptlrpc_req_finished(request);
-
- CDEBUG(D_VFSTRACE, "read %d/%d pages\n", nrdpgs, npages);
-
- for (i = 1; i < npages; i++) {
- unsigned long offset;
- int ret;
-
- page = page_pool[i];
-
- if (rc < 0 || i >= nrdpgs) {
- put_page(page);
- continue;
- }
-
- SetPageUptodate(page);
-
- dp = kmap(page);
- hash = le64_to_cpu(dp->ldp_hash_start);
- kunmap(page);
-
- offset = hash_x_index(hash, hash64);
-
- prefetchw(&page->flags);
- ret = add_to_page_cache_lru(page, inode->i_mapping, offset,
- GFP_NOFS);
- if (ret == 0) {
- unlock_page(page);
- } else {
- CDEBUG(D_VFSTRACE, "page %lu add to page cache failed: %d\n",
- offset, ret);
- }
- put_page(page);
- }
+ cb_op.md_blocking_ast = ll_md_blocking_ast;
+ rc = md_read_page(ll_i2mdexp(dir), op_data, &cb_op, offset, &page);
+ if (rc)
+ return ERR_PTR(rc);
- if (page_pool != &page0)
- kfree(page_pool);
- return rc;
+ return page;
}
-void ll_release_page(struct page *page, int remove)
+void ll_release_page(struct inode *inode, struct page *page, bool remove)
{
kunmap(page);
+
+ /*
+ * Always remove the page for striped dir, because the page is
+ * built from temporarily in LMV layer
+ */
+ if (inode && S_ISDIR(inode->i_mode) &&
+ ll_i2info(inode)->lli_lsm_md) {
+ __free_page(page);
+ return;
+ }
+
if (remove) {
lock_page(page);
if (likely(page->mapping))
@@ -248,225 +171,6 @@ void ll_release_page(struct page *page, int remove)
put_page(page);
}
-/*
- * Find, kmap and return page that contains given hash.
- */
-static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash,
- __u64 *start, __u64 *end)
-{
- int hash64 = ll_i2sbi(dir)->ll_flags & LL_SBI_64BIT_HASH;
- struct address_space *mapping = dir->i_mapping;
- /*
- * Complement of hash is used as an index so that
- * radix_tree_gang_lookup() can be used to find a page with starting
- * hash _smaller_ than one we are looking for.
- */
- unsigned long offset = hash_x_index(*hash, hash64);
- struct page *page;
- int found;
-
- spin_lock_irq(&mapping->tree_lock);
- found = radix_tree_gang_lookup(&mapping->page_tree,
- (void **)&page, offset, 1);
- if (found > 0 && !radix_tree_exceptional_entry(page)) {
- struct lu_dirpage *dp;
-
- get_page(page);
- spin_unlock_irq(&mapping->tree_lock);
- /*
- * In contrast to find_lock_page() we are sure that directory
- * page cannot be truncated (while DLM lock is held) and,
- * hence, can avoid restart.
- *
- * In fact, page cannot be locked here at all, because
- * ll_dir_filler() does synchronous io.
- */
- wait_on_page_locked(page);
- if (PageUptodate(page)) {
- dp = kmap(page);
- if (BITS_PER_LONG == 32 && hash64) {
- *start = le64_to_cpu(dp->ldp_hash_start) >> 32;
- *end = le64_to_cpu(dp->ldp_hash_end) >> 32;
- *hash = *hash >> 32;
- } else {
- *start = le64_to_cpu(dp->ldp_hash_start);
- *end = le64_to_cpu(dp->ldp_hash_end);
- }
- LASSERTF(*start <= *hash, "start = %#llx,end = %#llx,hash = %#llx\n",
- *start, *end, *hash);
- CDEBUG(D_VFSTRACE, "page %lu [%llu %llu], hash %llu\n",
- offset, *start, *end, *hash);
- if (*hash > *end) {
- ll_release_page(page, 0);
- page = NULL;
- } else if (*end != *start && *hash == *end) {
- /*
- * upon hash collision, remove this page,
- * otherwise put page reference, and
- * ll_get_dir_page() will issue RPC to fetch
- * the page we want.
- */
- ll_release_page(page,
- le32_to_cpu(dp->ldp_flags) & LDF_COLLIDE);
- page = NULL;
- }
- } else {
- put_page(page);
- page = ERR_PTR(-EIO);
- }
-
- } else {
- spin_unlock_irq(&mapping->tree_lock);
- page = NULL;
- }
- return page;
-}
-
-struct page *ll_get_dir_page(struct inode *dir, __u64 hash,
- struct ll_dir_chain *chain)
-{
- ldlm_policy_data_t policy = {.l_inodebits = {MDS_INODELOCK_UPDATE} };
- struct address_space *mapping = dir->i_mapping;
- struct lustre_handle lockh;
- struct lu_dirpage *dp;
- struct page *page;
- enum ldlm_mode mode;
- int rc;
- __u64 start = 0;
- __u64 end = 0;
- __u64 lhash = hash;
- struct ll_inode_info *lli = ll_i2info(dir);
- int hash64 = ll_i2sbi(dir)->ll_flags & LL_SBI_64BIT_HASH;
-
- mode = LCK_PR;
- rc = md_lock_match(ll_i2sbi(dir)->ll_md_exp, LDLM_FL_BLOCK_GRANTED,
- ll_inode2fid(dir), LDLM_IBITS, &policy, mode, &lockh);
- if (!rc) {
- struct ldlm_enqueue_info einfo = {
- .ei_type = LDLM_IBITS,
- .ei_mode = mode,
- .ei_cb_bl = ll_md_blocking_ast,
- .ei_cb_cp = ldlm_completion_ast,
- };
- struct lookup_intent it = { .it_op = IT_READDIR };
- struct ptlrpc_request *request;
- struct md_op_data *op_data;
-
- op_data = ll_prep_md_op_data(NULL, dir, dir, NULL, 0, 0,
- LUSTRE_OPC_ANY, NULL);
- if (IS_ERR(op_data))
- return (void *)op_data;
-
- rc = md_enqueue(ll_i2sbi(dir)->ll_md_exp, &einfo, &it,
- op_data, &lockh, NULL, 0, NULL, 0);
-
- ll_finish_md_op_data(op_data);
-
- request = (struct ptlrpc_request *)it.it_request;
- if (request)
- ptlrpc_req_finished(request);
- if (rc < 0) {
- CERROR("lock enqueue: " DFID " at %llu: rc %d\n",
- PFID(ll_inode2fid(dir)), hash, rc);
- return ERR_PTR(rc);
- }
-
- CDEBUG(D_INODE, "setting lr_lvb_inode to inode "DFID"(%p)\n",
- PFID(ll_inode2fid(dir)), dir);
- md_set_lock_data(ll_i2sbi(dir)->ll_md_exp,
- &it.it_lock_handle, dir, NULL);
- } else {
- /* for cross-ref object, l_ast_data of the lock may not be set,
- * we reset it here
- */
- md_set_lock_data(ll_i2sbi(dir)->ll_md_exp, &lockh.cookie,
- dir, NULL);
- }
- ldlm_lock_dump_handle(D_OTHER, &lockh);
-
- mutex_lock(&lli->lli_readdir_mutex);
- page = ll_dir_page_locate(dir, &lhash, &start, &end);
- if (IS_ERR(page)) {
- CERROR("dir page locate: "DFID" at %llu: rc %ld\n",
- PFID(ll_inode2fid(dir)), lhash, PTR_ERR(page));
- goto out_unlock;
- } else if (page) {
- /*
- * XXX nikita: not entirely correct handling of a corner case:
- * suppose hash chain of entries with hash value HASH crosses
- * border between pages P0 and P1. First both P0 and P1 are
- * cached, seekdir() is called for some entry from the P0 part
- * of the chain. Later P0 goes out of cache. telldir(HASH)
- * happens and finds P1, as it starts with matching hash
- * value. Remaining entries from P0 part of the chain are
- * skipped. (Is that really a bug?)
- *
- * Possible solutions: 0. don't cache P1 is such case, handle
- * it as an "overflow" page. 1. invalidate all pages at
- * once. 2. use HASH|1 as an index for P1.
- */
- goto hash_collision;
- }
-
- page = read_cache_page(mapping, hash_x_index(hash, hash64),
- ll_dir_filler, &lhash);
- if (IS_ERR(page)) {
- CERROR("read cache page: "DFID" at %llu: rc %ld\n",
- PFID(ll_inode2fid(dir)), hash, PTR_ERR(page));
- goto out_unlock;
- }
-
- wait_on_page_locked(page);
- (void)kmap(page);
- if (!PageUptodate(page)) {
- CERROR("page not updated: "DFID" at %llu: rc %d\n",
- PFID(ll_inode2fid(dir)), hash, -5);
- goto fail;
- }
- if (!PageChecked(page))
- /* XXX: check page format later */
- SetPageChecked(page);
- if (PageError(page)) {
- CERROR("page error: "DFID" at %llu: rc %d\n",
- PFID(ll_inode2fid(dir)), hash, -5);
- goto fail;
- }
-hash_collision:
- dp = page_address(page);
- if (BITS_PER_LONG == 32 && hash64) {
- start = le64_to_cpu(dp->ldp_hash_start) >> 32;
- end = le64_to_cpu(dp->ldp_hash_end) >> 32;
- lhash = hash >> 32;
- } else {
- start = le64_to_cpu(dp->ldp_hash_start);
- end = le64_to_cpu(dp->ldp_hash_end);
- lhash = hash;
- }
- if (end == start) {
- LASSERT(start == lhash);
- CWARN("Page-wide hash collision: %llu\n", end);
- if (BITS_PER_LONG == 32 && hash64)
- CWARN("Real page-wide hash collision at [%llu %llu] with hash %llu\n",
- le64_to_cpu(dp->ldp_hash_start),
- le64_to_cpu(dp->ldp_hash_end), hash);
- /*
- * Fetch whole overflow chain...
- *
- * XXX not yet.
- */
- goto fail;
- }
-out_unlock:
- mutex_unlock(&lli->lli_readdir_mutex);
- ldlm_lock_decref(&lockh, mode);
- return page;
-
-fail:
- ll_release_page(page, 1);
- page = ERR_PTR(-EIO);
- goto out_unlock;
-}
-
/**
* return IF_* type for given lu_dirent entry.
* IF_* flag shld be converted to particular OS file type in
@@ -489,119 +193,100 @@ static __u16 ll_dirent_type_get(struct lu_dirent *ent)
return type;
}
-int ll_dir_read(struct inode *inode, struct dir_context *ctx)
+int ll_dir_read(struct inode *inode, __u64 *ppos, struct md_op_data *op_data,
+ struct dir_context *ctx)
{
- struct ll_inode_info *info = ll_i2info(inode);
struct ll_sb_info *sbi = ll_i2sbi(inode);
- __u64 pos = ctx->pos;
- int api32 = ll_need_32bit_api(sbi);
- int hash64 = sbi->ll_flags & LL_SBI_64BIT_HASH;
+ __u64 pos = *ppos;
+ int is_api32 = ll_need_32bit_api(sbi);
+ int is_hash64 = sbi->ll_flags & LL_SBI_64BIT_HASH;
struct page *page;
- struct ll_dir_chain chain;
- int done = 0;
+ bool done = false;
int rc = 0;
- ll_dir_chain_init(&chain);
-
- page = ll_get_dir_page(inode, pos, &chain);
+ page = ll_get_dir_page(inode, op_data, pos);
while (rc == 0 && !done) {
struct lu_dirpage *dp;
struct lu_dirent *ent;
+ __u64 hash;
+ __u64 next;
- if (!IS_ERR(page)) {
- /*
- * If page is empty (end of directory is reached),
- * use this value.
- */
- __u64 hash = MDS_DIR_END_OFF;
- __u64 next;
-
- dp = page_address(page);
- for (ent = lu_dirent_start(dp); ent && !done;
- ent = lu_dirent_next(ent)) {
- __u16 type;
- int namelen;
- struct lu_fid fid;
- __u64 lhash;
- __u64 ino;
+ if (IS_ERR(page)) {
+ rc = PTR_ERR(page);
+ break;
+ }
+ hash = MDS_DIR_END_OFF;
+ dp = page_address(page);
+ for (ent = lu_dirent_start(dp); ent && !done;
+ ent = lu_dirent_next(ent)) {
+ __u16 type;
+ int namelen;
+ struct lu_fid fid;
+ __u64 lhash;
+ __u64 ino;
+
+ hash = le64_to_cpu(ent->lde_hash);
+ if (hash < pos)
/*
- * XXX: implement correct swabbing here.
+ * Skip until we find target hash
+ * value.
*/
+ continue;
- hash = le64_to_cpu(ent->lde_hash);
- if (hash < pos)
- /*
- * Skip until we find target hash
- * value.
- */
- continue;
-
- namelen = le16_to_cpu(ent->lde_namelen);
- if (namelen == 0)
- /*
- * Skip dummy record.
- */
- continue;
-
- if (api32 && hash64)
- lhash = hash >> 32;
- else
- lhash = hash;
- fid_le_to_cpu(&fid, &ent->lde_fid);
- ino = cl_fid_build_ino(&fid, api32);
- type = ll_dirent_type_get(ent);
- ctx->pos = lhash;
- /* For 'll_nfs_get_name_filldir()', it will try
- * to access the 'ent' through its 'lde_name',
- * so the parameter 'name' for 'ctx->actor()'
- * must be part of the 'ent'.
+ namelen = le16_to_cpu(ent->lde_namelen);
+ if (namelen == 0)
+ /*
+ * Skip dummy record.
*/
- done = !dir_emit(ctx, ent->lde_name,
- namelen, ino, type);
- }
- next = le64_to_cpu(dp->ldp_hash_end);
- if (!done) {
- pos = next;
- if (pos == MDS_DIR_END_OFF) {
- /*
- * End of directory reached.
- */
- done = 1;
- ll_release_page(page, 0);
- } else if (1 /* chain is exhausted*/) {
- /*
- * Normal case: continue to the next
- * page.
- */
- ll_release_page(page,
- le32_to_cpu(dp->ldp_flags) &
- LDF_COLLIDE);
- next = pos;
- page = ll_get_dir_page(inode, pos,
- &chain);
- } else {
- /*
- * go into overflow page.
- */
- LASSERT(le32_to_cpu(dp->ldp_flags) &
- LDF_COLLIDE);
- ll_release_page(page, 1);
- }
- } else {
- pos = hash;
- ll_release_page(page, 0);
- }
+ continue;
+
+ if (is_api32 && is_hash64)
+ lhash = hash >> 32;
+ else
+ lhash = hash;
+ fid_le_to_cpu(&fid, &ent->lde_fid);
+ ino = cl_fid_build_ino(&fid, is_api32);
+ type = ll_dirent_type_get(ent);
+ ctx->pos = lhash;
+ /* For 'll_nfs_get_name_filldir()', it will try
+ * to access the 'ent' through its 'lde_name',
+ * so the parameter 'name' for 'ctx->actor()'
+ * must be part of the 'ent'.
+ */
+ done = !dir_emit(ctx, ent->lde_name,
+ namelen, ino, type);
+ }
+
+ if (done) {
+ pos = hash;
+ ll_release_page(inode, page, false);
+ break;
+ }
+
+ next = le64_to_cpu(dp->ldp_hash_end);
+ pos = next;
+ if (pos == MDS_DIR_END_OFF) {
+ /*
+ * End of directory reached.
+ */
+ done = 1;
+ ll_release_page(inode, page, false);
} else {
- rc = PTR_ERR(page);
- CERROR("error reading dir "DFID" at %lu: rc %d\n",
- PFID(&info->lli_fid), (unsigned long)pos, rc);
+ /*
+ * Normal case: continue to the next
+ * page.
+ */
+ ll_release_page(inode, page,
+ le32_to_cpu(dp->ldp_flags) &
+ LDF_COLLIDE);
+ next = pos;
+ page = ll_get_dir_page(inode, op_data, pos);
}
}
ctx->pos = pos;
- ll_dir_chain_fini(&chain);
return rc;
}
@@ -613,9 +298,10 @@ static int ll_readdir(struct file *filp, struct dir_context *ctx)
__u64 pos = lfd ? lfd->lfd_pos : 0;
int hash64 = sbi->ll_flags & LL_SBI_64BIT_HASH;
int api32 = ll_need_32bit_api(sbi);
+ struct md_op_data *op_data;
int rc;
- CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p) pos %lu/%llu 32bit_api %d\n",
+ CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p) pos/size %lu/%llu 32bit_api %d\n",
PFID(ll_inode2fid(inode)), inode, (unsigned long)pos,
i_size_read(inode), api32);
@@ -627,19 +313,58 @@ static int ll_readdir(struct file *filp, struct dir_context *ctx)
goto out;
}
+ op_data = ll_prep_md_op_data(NULL, inode, inode, NULL, 0, 0,
+ LUSTRE_OPC_ANY, inode);
+ if (IS_ERR(op_data)) {
+ rc = PTR_ERR(op_data);
+ goto out;
+ }
+
+ if (unlikely(op_data->op_mea1)) {
+ /*
+ * This is only needed for striped dir to fill ..,
+ * see lmv_read_page
+ */
+ if (file_dentry(filp)->d_parent &&
+ file_dentry(filp)->d_parent->d_inode) {
+ __u64 ibits = MDS_INODELOCK_UPDATE;
+ struct inode *parent;
+
+ parent = file_dentry(filp)->d_parent->d_inode;
+ if (ll_have_md_lock(parent, &ibits, LCK_MINMODE))
+ op_data->op_fid3 = *ll_inode2fid(parent);
+ }
+
+ /*
+ * If it can not find in cache, do lookup .. on the master
+ * object
+ */
+ if (fid_is_zero(&op_data->op_fid3)) {
+ rc = ll_dir_get_parent_fid(inode, &op_data->op_fid3);
+ if (rc) {
+ ll_finish_md_op_data(op_data);
+ return rc;
+ }
+ }
+ }
+ op_data->op_max_pages = sbi->ll_md_brw_pages;
ctx->pos = pos;
- rc = ll_dir_read(inode, ctx);
+ rc = ll_dir_read(inode, &pos, op_data, ctx);
+ pos = ctx->pos;
if (lfd)
- lfd->lfd_pos = ctx->pos;
- if (ctx->pos == MDS_DIR_END_OFF) {
+ lfd->lfd_pos = pos;
+
+ if (pos == MDS_DIR_END_OFF) {
if (api32)
- ctx->pos = LL_DIR_END_OFF_32BIT;
+ pos = LL_DIR_END_OFF_32BIT;
else
- ctx->pos = LL_DIR_END_OFF;
+ pos = LL_DIR_END_OFF;
} else {
if (api32 && hash64)
- ctx->pos >>= 32;
+ pos >>= 32;
}
+ ctx->pos = pos;
+ ll_finish_md_op_data(op_data);
filp->f_version = inode->i_version;
out:
@@ -668,18 +393,40 @@ static int ll_send_mgc_param(struct obd_export *mgc, char *string)
return rc;
}
-static int ll_dir_setdirstripe(struct inode *dir, struct lmv_user_md *lump,
- char *filename)
+/**
+ * Create striped directory with specified stripe(@lump)
+ *
+ * param[in] parent the parent of the directory.
+ * param[in] lump the specified stripes.
+ * param[in] dirname the name of the directory.
+ * param[in] mode the specified mode of the directory.
+ *
+ * retval =0 if striped directory is being created successfully.
+ * <0 if the creation is failed.
+ */
+static int ll_dir_setdirstripe(struct inode *parent, struct lmv_user_md *lump,
+ const char *dirname, umode_t mode)
{
struct ptlrpc_request *request = NULL;
struct md_op_data *op_data;
- struct ll_sb_info *sbi = ll_i2sbi(dir);
- int mode;
+ struct ll_sb_info *sbi = ll_i2sbi(parent);
int err;
- mode = (~current_umask() & 0755) | S_IFDIR;
- op_data = ll_prep_md_op_data(NULL, dir, NULL, filename,
- strlen(filename), mode, LUSTRE_OPC_MKDIR,
+ if (unlikely(lump->lum_magic != LMV_USER_MAGIC))
+ return -EINVAL;
+
+ CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p) name %s stripe_offset %d, stripe_count: %u\n",
+ PFID(ll_inode2fid(parent)), parent, dirname,
+ (int)lump->lum_stripe_offset, lump->lum_stripe_count);
+
+ if (lump->lum_magic != cpu_to_le32(LMV_USER_MAGIC))
+ lustre_swab_lmv_user_md(lump);
+
+ if (!IS_POSIXACL(parent) || !exp_connect_umask(ll_i2mdexp(parent)))
+ mode &= ~current_umask();
+ mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
+ op_data = ll_prep_md_op_data(NULL, parent, NULL, dirname,
+ strlen(dirname), mode, LUSTRE_OPC_MKDIR,
lump);
if (IS_ERR(op_data)) {
err = PTR_ERR(op_data);
@@ -730,6 +477,13 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
lum_size = sizeof(struct lov_user_md_v3);
break;
}
+ case LMV_USER_MAGIC: {
+ if (lump->lmm_magic != cpu_to_le32(LMV_USER_MAGIC))
+ lustre_swab_lmv_user_md(
+ (struct lmv_user_md *)lump);
+ lum_size = sizeof(struct lmv_user_md);
+ break;
+ }
default: {
CDEBUG(D_IOCTL, "bad userland LOV MAGIC: %#08x != %#08x nor %#08x\n",
lump->lmm_magic, LOV_USER_MAGIC_V1,
@@ -746,9 +500,6 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
if (IS_ERR(op_data))
return PTR_ERR(op_data);
- if (lump && lump->lmm_magic == cpu_to_le32(LMV_USER_MAGIC))
- op_data->op_cli_flags |= CLI_SET_MEA;
-
/* swabbing is done in lov_setstripe() on server side */
rc = md_setattr(sbi->ll_md_exp, op_data, lump, lum_size,
NULL, 0, &req, NULL);
@@ -803,8 +554,16 @@ end:
return rc;
}
-int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
- int *lmm_size, struct ptlrpc_request **request)
+/**
+ * This function will be used to get default LOV/LMV/Default LMV
+ * @valid will be used to indicate which stripe it will retrieve
+ * OBD_MD_MEA LMV stripe EA
+ * OBD_MD_DEFAULT_MEA Default LMV stripe EA
+ * otherwise Default LOV EA.
+ * Each time, it can only retrieve 1 stripe EA
+ **/
+int ll_dir_getstripe(struct inode *inode, void **plmm, int *plmm_size,
+ struct ptlrpc_request **request, u64 valid)
{
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct mdt_body *body;
@@ -813,7 +572,7 @@ int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
int rc, lmmsize;
struct md_op_data *op_data;
- rc = ll_get_default_mdsize(sbi, &lmmsize);
+ rc = ll_get_max_mdsize(sbi, &lmmsize);
if (rc)
return rc;
@@ -834,9 +593,9 @@ int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
- lmmsize = body->eadatasize;
+ lmmsize = body->mbo_eadatasize;
- if (!(body->valid & (OBD_MD_FLEASIZE | OBD_MD_FLDIREA)) ||
+ if (!(body->mbo_valid & (OBD_MD_FLEASIZE | OBD_MD_FLDIREA)) ||
lmmsize == 0) {
rc = -ENODATA;
goto out;
@@ -844,6 +603,7 @@ int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
lmm = req_capsule_server_sized_get(&req->rq_pill,
&RMF_MDT_MD, lmmsize);
+ LASSERT(lmm);
/*
* This is coming from the MDS, so is probably in
@@ -860,40 +620,51 @@ int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
if (cpu_to_le32(LOV_MAGIC) != LOV_MAGIC)
lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
break;
+ case LMV_MAGIC_V1:
+ if (cpu_to_le32(LMV_MAGIC) != LMV_MAGIC)
+ lustre_swab_lmv_mds_md((union lmv_mds_md *)lmm);
+ break;
+ case LMV_USER_MAGIC:
+ if (cpu_to_le32(LMV_USER_MAGIC) != LMV_USER_MAGIC)
+ lustre_swab_lmv_user_md((struct lmv_user_md *)lmm);
+ break;
default:
CERROR("unknown magic: %lX\n", (unsigned long)lmm->lmm_magic);
rc = -EPROTO;
}
out:
- *lmmp = lmm;
- *lmm_size = lmmsize;
+ *plmm = lmm;
+ *plmm_size = lmmsize;
*request = req;
return rc;
}
-/*
- * Get MDT index for the inode.
- */
-int ll_get_mdt_idx(struct inode *inode)
+int ll_get_mdt_idx_by_fid(struct ll_sb_info *sbi, const struct lu_fid *fid)
{
- struct ll_sb_info *sbi = ll_i2sbi(inode);
struct md_op_data *op_data;
- int rc, mdtidx;
+ int mdt_index, rc;
- op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0,
- 0, LUSTRE_OPC_ANY, NULL);
- if (IS_ERR(op_data))
- return PTR_ERR(op_data);
+ op_data = kzalloc(sizeof(*op_data), GFP_NOFS);
+ if (!op_data)
+ return -ENOMEM;
op_data->op_flags |= MF_GET_MDT_IDX;
+ op_data->op_fid1 = *fid;
rc = md_getattr(sbi->ll_md_exp, op_data, NULL);
- mdtidx = op_data->op_mds;
- ll_finish_md_op_data(op_data);
- if (rc < 0) {
- CDEBUG(D_INFO, "md_getattr_name: %d\n", rc);
+ mdt_index = op_data->op_mds;
+ kvfree(op_data);
+ if (rc < 0)
return rc;
- }
- return mdtidx;
+
+ return mdt_index;
+}
+
+/*
+ * Get MDT index for the inode.
+ */
+int ll_get_mdt_idx(struct inode *inode)
+{
+ return ll_get_mdt_idx_by_fid(ll_i2sbi(inode), ll_inode2fid(inode));
}
/**
@@ -1288,11 +1059,9 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return 0;
}
case IOC_MDC_LOOKUP: {
- struct ptlrpc_request *request = NULL;
int namelen, len = 0;
char *buf = NULL;
char *filename;
- struct md_op_data *op_data;
rc = obd_ioctl_getdata(&buf, &len, (void __user *)arg);
if (rc)
@@ -1308,21 +1077,13 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
goto out_free;
}
- op_data = ll_prep_md_op_data(NULL, inode, NULL, filename, namelen,
- 0, LUSTRE_OPC_ANY, NULL);
- if (IS_ERR(op_data)) {
- rc = PTR_ERR(op_data);
- goto out_free;
- }
-
- op_data->op_valid = OBD_MD_FLID;
- rc = md_getattr_name(sbi->ll_md_exp, op_data, &request);
- ll_finish_md_op_data(op_data);
+ rc = ll_get_fid_by_name(inode, filename, namelen, NULL);
if (rc < 0) {
- CDEBUG(D_INFO, "md_getattr_name: %d\n", rc);
+ CERROR("%s: lookup %.*s failed: rc = %d\n",
+ ll_get_fsname(inode->i_sb, NULL, 0), namelen,
+ filename, rc);
goto out_free;
}
- ptlrpc_req_finished(request);
out_free:
obd_ioctl_freedata(buf, len);
return rc;
@@ -1333,6 +1094,7 @@ out_free:
char *filename;
int namelen = 0;
int lumlen = 0;
+ umode_t mode;
int len;
int rc;
@@ -1366,15 +1128,32 @@ out_free:
goto lmv_out_free;
}
- /**
- * ll_dir_setdirstripe will be used to set dir stripe
- * mdc_create--->mdt_reint_create (with dirstripe)
- */
- rc = ll_dir_setdirstripe(inode, lum, filename);
+#if OBD_OCD_VERSION(2, 9, 50, 0) > LUSTRE_VERSION_CODE
+ mode = data->ioc_type != 0 ? data->ioc_type : S_IRWXUGO;
+#else
+ mode = data->ioc_type;
+#endif
+ rc = ll_dir_setdirstripe(inode, lum, filename, mode);
lmv_out_free:
obd_ioctl_freedata(buf, len);
return rc;
}
+ case LL_IOC_LMV_SET_DEFAULT_STRIPE: {
+ struct lmv_user_md __user *ulump;
+ struct lmv_user_md lum;
+ int rc;
+
+ ulump = (struct lmv_user_md __user *)arg;
+ if (copy_from_user(&lum, ulump, sizeof(lum)))
+ return -EFAULT;
+
+ if (lum.lum_magic != LMV_USER_MAGIC)
+ return -EINVAL;
+
+ rc = ll_dir_setstripe(inode, (struct lov_user_md *)&lum, 0);
+
+ return rc;
+ }
case LL_IOC_LOV_SETSTRIPE: {
struct lov_user_md_v3 lumv3;
struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&lumv3;
@@ -1404,50 +1183,100 @@ lmv_out_free:
return rc;
}
case LL_IOC_LMV_GETSTRIPE: {
- struct lmv_user_md __user *lump = (void __user *)arg;
+ struct lmv_user_md __user *ulmv;
struct lmv_user_md lum;
- struct lmv_user_md *tmp;
+ struct ptlrpc_request *request = NULL;
+ struct lmv_user_md *tmp = NULL;
+ union lmv_mds_md *lmm = NULL;
+ u64 valid = 0;
+ int stripe_count;
+ int mdt_index;
int lum_size;
- int rc = 0;
- int mdtindex;
+ int lmmsize;
+ int rc;
+ int i;
- if (copy_from_user(&lum, lump, sizeof(struct lmv_user_md)))
+ ulmv = (struct lmv_user_md __user *)arg;
+ if (copy_from_user(&lum, ulmv, sizeof(*ulmv)))
return -EFAULT;
- if (lum.lum_magic != LMV_MAGIC_V1)
+ /*
+ * lum_magic will indicate which stripe the ioctl will like
+ * to get, LMV_MAGIC_V1 is for normal LMV stripe, LMV_USER_MAGIC
+ * is for default LMV stripe
+ */
+ if (lum.lum_magic == LMV_MAGIC_V1)
+ valid |= OBD_MD_MEA;
+ else if (lum.lum_magic == LMV_USER_MAGIC)
+ valid |= OBD_MD_DEFAULT_MEA;
+ else
return -EINVAL;
- lum_size = lmv_user_md_size(1, LMV_MAGIC_V1);
+ rc = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize, &request,
+ valid);
+ if (rc)
+ goto finish_req;
+
+ /* Get default LMV EA */
+ if (lum.lum_magic == LMV_USER_MAGIC) {
+ if (rc)
+ goto finish_req;
+
+ if (lmmsize > sizeof(*ulmv)) {
+ rc = -EINVAL;
+ goto finish_req;
+ }
+
+ if (copy_to_user(ulmv, lmm, lmmsize))
+ rc = -EFAULT;
+
+ goto finish_req;
+ }
+
+ stripe_count = lmv_mds_md_stripe_count_get(lmm);
+ lum_size = lmv_user_md_size(stripe_count, LMV_MAGIC_V1);
tmp = kzalloc(lum_size, GFP_NOFS);
if (!tmp) {
rc = -ENOMEM;
- goto free_lmv;
+ goto finish_req;
}
- *tmp = lum;
- tmp->lum_type = LMV_STRIPE_TYPE;
- tmp->lum_stripe_count = 1;
- mdtindex = ll_get_mdt_idx(inode);
- if (mdtindex < 0) {
+ mdt_index = ll_get_mdt_idx(inode);
+ if (mdt_index < 0) {
rc = -ENOMEM;
- goto free_lmv;
+ goto out_tmp;
+ }
+ tmp->lum_magic = LMV_MAGIC_V1;
+ tmp->lum_stripe_count = 0;
+ tmp->lum_stripe_offset = mdt_index;
+ for (i = 0; i < stripe_count; i++) {
+ struct lu_fid fid;
+
+ fid_le_to_cpu(&fid, &lmm->lmv_md_v1.lmv_stripe_fids[i]);
+ mdt_index = ll_get_mdt_idx_by_fid(sbi, &fid);
+ if (mdt_index < 0) {
+ rc = mdt_index;
+ goto out_tmp;
+ }
+ tmp->lum_objects[i].lum_mds = mdt_index;
+ tmp->lum_objects[i].lum_fid = fid;
+ tmp->lum_stripe_count++;
}
- tmp->lum_stripe_offset = mdtindex;
- tmp->lum_objects[0].lum_mds = mdtindex;
- memcpy(&tmp->lum_objects[0].lum_fid, ll_inode2fid(inode),
- sizeof(struct lu_fid));
- if (copy_to_user((void __user *)arg, tmp, lum_size)) {
+ if (copy_to_user(ulmv, tmp, lum_size)) {
rc = -EFAULT;
- goto free_lmv;
+ goto out_tmp;
}
-free_lmv:
+out_tmp:
kfree(tmp);
+finish_req:
+ ptlrpc_req_finished(request);
return rc;
}
+
case LL_IOC_LOV_SWAP_LAYOUTS:
return -EPERM;
- case LL_IOC_OBD_STATFS:
+ case IOC_OBD_STATFS:
return ll_obd_statfs(inode, (void __user *)arg);
case LL_IOC_LOV_GETSTRIPE:
case LL_IOC_MDC_GETINFO:
@@ -1469,7 +1298,8 @@ free_lmv:
rc = ll_lov_getstripe_ea_info(inode, filename, &lmm,
&lmmsize, &request);
} else {
- rc = ll_dir_getstripe(inode, &lmm, &lmmsize, &request);
+ rc = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize,
+ &request, 0);
}
if (request) {
@@ -1512,18 +1342,18 @@ skip_lmm:
lstat_t st = { 0 };
st.st_dev = inode->i_sb->s_dev;
- st.st_mode = body->mode;
- st.st_nlink = body->nlink;
- st.st_uid = body->uid;
- st.st_gid = body->gid;
- st.st_rdev = body->rdev;
- st.st_size = body->size;
+ st.st_mode = body->mbo_mode;
+ st.st_nlink = body->mbo_nlink;
+ st.st_uid = body->mbo_uid;
+ st.st_gid = body->mbo_gid;
+ st.st_rdev = body->mbo_rdev;
+ st.st_size = body->mbo_size;
st.st_blksize = PAGE_SIZE;
- st.st_blocks = body->blocks;
- st.st_atime = body->atime;
- st.st_mtime = body->mtime;
- st.st_ctime = body->ctime;
- st.st_ino = cl_fid_build_ino(&body->fid1,
+ st.st_blocks = body->mbo_blocks;
+ st.st_atime = body->mbo_atime;
+ st.st_mtime = body->mbo_mtime;
+ st.st_ctime = body->mbo_ctime;
+ st.st_ino = cl_fid_build_ino(&body->mbo_fid1,
sbi->ll_flags &
LL_SBI_32BIT_API);
@@ -1611,9 +1441,6 @@ free_lmm:
kvfree(lmm);
return rc;
}
- case OBD_IOC_LLOG_CATINFO: {
- return -EOPNOTSUPP;
- }
case OBD_IOC_QUOTACHECK: {
struct obd_quotactl *oqctl;
int error = 0;
@@ -1671,7 +1498,7 @@ out_poll:
kfree(check);
return rc;
}
- case LL_IOC_QUOTACTL: {
+ case OBD_IOC_QUOTACTL: {
struct if_quotactl *qctl;
qctl = kzalloc(sizeof(*qctl), GFP_NOFS);
@@ -1739,6 +1566,25 @@ out_quotactl:
return rc;
case OBD_IOC_FID2PATH:
return ll_fid2path(inode, (void __user *)arg);
+ case LL_IOC_GETPARENT:
+ return ll_getparent(file, (void __user *)arg);
+ case LL_IOC_FID2MDTIDX: {
+ struct obd_export *exp = ll_i2mdexp(inode);
+ struct lu_fid fid;
+ __u32 index;
+
+ if (copy_from_user(&fid, (const struct lu_fid __user *)arg,
+ sizeof(fid)))
+ return -EFAULT;
+
+ /* Call mdc_iocontrol */
+ rc = obd_iocontrol(LL_IOC_FID2MDTIDX, exp, sizeof(fid), &fid,
+ &index);
+ if (rc)
+ return rc;
+
+ return index;
+ }
case LL_IOC_HSM_REQUEST: {
struct hsm_user_request *hur;
ssize_t totalsize;
@@ -1853,6 +1699,45 @@ out_quotactl:
kfree(copy);
return rc;
}
+ case LL_IOC_MIGRATE: {
+ char *buf = NULL;
+ const char *filename;
+ int namelen = 0;
+ int len;
+ int rc;
+ int mdtidx;
+
+ rc = obd_ioctl_getdata(&buf, &len, (void __user *)arg);
+ if (rc < 0)
+ return rc;
+
+ data = (struct obd_ioctl_data *)buf;
+ if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2 ||
+ !data->ioc_inllen1 || !data->ioc_inllen2) {
+ rc = -EINVAL;
+ goto migrate_free;
+ }
+
+ filename = data->ioc_inlbuf1;
+ namelen = data->ioc_inllen1;
+ if (namelen < 1 || namelen != strlen(filename) + 1) {
+ rc = -EINVAL;
+ goto migrate_free;
+ }
+
+ if (data->ioc_inllen2 != sizeof(mdtidx)) {
+ rc = -EINVAL;
+ goto migrate_free;
+ }
+ mdtidx = *(int *)data->ioc_inlbuf2;
+
+ rc = ll_migrate(inode, file, mdtidx, filename, namelen - 1);
+migrate_free:
+ obd_ioctl_freedata(buf, len);
+
+ return rc;
+ }
+
default:
return obd_iocontrol(cmd, sbi->ll_dt_exp, 0, NULL,
(void __user *)arg);
diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c
index 57281b9e31ff..6e3a188baaae 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -38,14 +38,15 @@
#define DEBUG_SUBSYSTEM S_LLITE
#include "../include/lustre_dlm.h"
-#include "../include/lustre_lite.h"
#include <linux/pagemap.h>
#include <linux/file.h>
+#include <linux/sched.h>
#include <linux/mount.h>
-#include "llite_internal.h"
#include "../include/lustre/ll_fiemap.h"
+#include "../include/lustre/lustre_ioctl.h"
#include "../include/cl_object.h"
+#include "llite_internal.h"
static int
ll_put_grouplock(struct inode *inode, struct file *file, unsigned long arg);
@@ -188,17 +189,11 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp,
spin_unlock(&lli->lli_lock);
}
- if (rc == 0) {
- rc = ll_objects_destroy(req, inode);
- if (rc)
- CERROR("inode %lu ll_objects destroy: rc = %d\n",
- inode->i_ino, rc);
- }
if (rc == 0 && op_data->op_bias & MDS_HSM_RELEASE) {
struct mdt_body *body;
body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
- if (!(body->valid & OBD_MD_FLRELEASED))
+ if (!(body->mbo_valid & OBD_MD_FLRELEASED))
rc = -EBUSY;
}
@@ -349,13 +344,11 @@ int ll_file_release(struct inode *inode, struct file *file)
fd = LUSTRE_FPRIVATE(file);
LASSERT(fd);
- /* The last ref on @file, maybe not be the owner pid of statahead.
- * Different processes can open the same dir, "ll_opendir_key" means:
- * it is me that should stop the statahead thread.
+ /* The last ref on @file, maybe not be the owner pid of statahead,
+ * because parent and child process can share the same file handle.
*/
- if (S_ISDIR(inode->i_mode) && lli->lli_opendir_key == fd &&
- lli->lli_opendir_pid != 0)
- ll_stop_statahead(inode, lli->lli_opendir_key);
+ if (S_ISDIR(inode->i_mode) && lli->lli_opendir_key == fd)
+ ll_deauthorize_statahead(inode, fd);
if (is_root_inode(inode)) {
LUSTRE_FPRIVATE(file) = NULL;
@@ -364,7 +357,8 @@ int ll_file_release(struct inode *inode, struct file *file)
}
if (!S_ISDIR(inode->i_mode)) {
- lov_read_and_clear_async_rc(lli->lli_clob);
+ if (lli->lli_clob)
+ lov_read_and_clear_async_rc(lli->lli_clob);
lli->lli_async_rc = 0;
}
@@ -376,55 +370,39 @@ int ll_file_release(struct inode *inode, struct file *file)
return rc;
}
-static int ll_intent_file_open(struct dentry *dentry, void *lmm,
- int lmmsize, struct lookup_intent *itp)
+static int ll_intent_file_open(struct dentry *de, void *lmm, int lmmsize,
+ struct lookup_intent *itp)
{
- struct inode *inode = d_inode(dentry);
+ struct inode *inode = d_inode(de);
struct ll_sb_info *sbi = ll_i2sbi(inode);
- struct dentry *parent = dentry->d_parent;
- const char *name = dentry->d_name.name;
- const int len = dentry->d_name.len;
+ struct dentry *parent = de->d_parent;
+ const char *name = NULL;
struct md_op_data *op_data;
- struct ptlrpc_request *req;
- __u32 opc = LUSTRE_OPC_ANY;
- int rc;
+ struct ptlrpc_request *req = NULL;
+ int len = 0, rc;
- /* Usually we come here only for NFSD, and we want open lock. */
- /* We can also get here if there was cached open handle in revalidate_it
- * but it disappeared while we were getting from there to ll_file_open.
- * But this means this file was closed and immediately opened which
- * makes a good candidate for using OPEN lock
- */
- /* If lmmsize & lmm are not 0, we are just setting stripe info
- * parameters. No need for the open lock
+ LASSERT(parent);
+ LASSERT(itp->it_flags & MDS_OPEN_BY_FID);
+
+ /*
+ * if server supports open-by-fid, or file name is invalid, don't pack
+ * name in open request
*/
- if (!lmm && lmmsize == 0) {
- struct ll_dentry_data *ldd = ll_d2d(dentry);
- /*
- * If we came via ll_iget_for_nfs, then we need to request
- * struct ll_dentry_data *ldd = ll_d2d(file->f_dentry);
- *
- * NB: when ldd is NULL, it must have come via normal
- * lookup path only, since ll_iget_for_nfs always calls
- * ll_d_init().
- */
- if (ldd && ldd->lld_nfs_dentry) {
- ldd->lld_nfs_dentry = 0;
- itp->it_flags |= MDS_OPEN_LOCK;
- }
- if (itp->it_flags & FMODE_WRITE)
- opc = LUSTRE_OPC_CREATE;
+ if (!(exp_connect_flags(sbi->ll_md_exp) & OBD_CONNECT_OPEN_BY_FID) &&
+ lu_name_is_valid_2(de->d_name.name, de->d_name.len)) {
+ name = de->d_name.name;
+ len = de->d_name.len;
}
- op_data = ll_prep_md_op_data(NULL, d_inode(parent),
- inode, name, len,
- O_RDWR, opc, NULL);
+ op_data = ll_prep_md_op_data(NULL, d_inode(parent), inode, name, len,
+ O_RDWR, LUSTRE_OPC_ANY, NULL);
if (IS_ERR(op_data))
return PTR_ERR(op_data);
+ op_data->op_data = lmm;
+ op_data->op_data_size = lmmsize;
- itp->it_flags |= MDS_OPEN_BY_FID;
- rc = md_intent_lock(sbi->ll_md_exp, op_data, lmm, lmmsize, itp,
- 0 /*unused */, &req, ll_md_blocking_ast, 0);
+ rc = md_intent_lock(sbi->ll_md_exp, op_data, itp, &req,
+ &ll_md_blocking_ast, 0);
ll_finish_md_op_data(op_data);
if (rc == -ESTALE) {
/* reason for keep own exit path - don`t flood log
@@ -479,8 +457,8 @@ static int ll_och_fill(struct obd_export *md_exp, struct lookup_intent *it,
struct mdt_body *body;
body = req_capsule_server_get(&it->it_request->rq_pill, &RMF_MDT_BODY);
- och->och_fh = body->handle;
- och->och_fid = body->fid1;
+ och->och_fh = body->mbo_handle;
+ och->och_fid = body->mbo_fid1;
och->och_lease_handle.cookie = it->it_lock_handle;
och->och_magic = OBD_CLIENT_HANDLE_MAGIC;
och->och_flags = it->it_flags;
@@ -508,7 +486,7 @@ static int ll_local_open(struct file *file, struct lookup_intent *it,
body = req_capsule_server_get(&it->it_request->rq_pill,
&RMF_MDT_BODY);
- ll_ioepoch_open(lli, body->ioepoch);
+ ll_ioepoch_open(lli, body->mbo_ioepoch);
}
LUSTRE_FPRIVATE(file) = fd;
@@ -543,7 +521,7 @@ int ll_file_open(struct inode *inode, struct file *file)
struct obd_client_handle **och_p = NULL;
__u64 *och_usecount = NULL;
struct ll_file_data *fd;
- int rc = 0, opendir_set = 0;
+ int rc = 0;
CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), flags %o\n",
PFID(ll_inode2fid(inode)), inode, file->f_flags);
@@ -558,16 +536,8 @@ int ll_file_open(struct inode *inode, struct file *file)
}
fd->fd_file = file;
- if (S_ISDIR(inode->i_mode)) {
- spin_lock(&lli->lli_sa_lock);
- if (!lli->lli_opendir_key && !lli->lli_sai &&
- lli->lli_opendir_pid == 0) {
- lli->lli_opendir_key = fd;
- lli->lli_opendir_pid = current_pid();
- opendir_set = 1;
- }
- spin_unlock(&lli->lli_sa_lock);
- }
+ if (S_ISDIR(inode->i_mode))
+ ll_authorize_statahead(inode, fd);
if (is_root_inode(inode)) {
LUSTRE_FPRIVATE(file) = fd;
@@ -615,7 +585,7 @@ restart:
} else if (it->it_flags & FMODE_EXEC) {
och_p = &lli->lli_mds_exec_och;
och_usecount = &lli->lli_open_fd_exec_count;
- } else {
+ } else {
och_p = &lli->lli_mds_read_och;
och_usecount = &lli->lli_open_fd_read_count;
}
@@ -652,9 +622,19 @@ restart:
* result in a deadlock
*/
mutex_unlock(&lli->lli_och_mutex);
- it->it_create_mode |= M_CHECK_STALE;
+ /*
+ * Normally called under two situations:
+ * 1. NFS export.
+ * 2. revalidate with IT_OPEN (revalidate doesn't
+ * execute this intent any more).
+ *
+ * Always fetch MDS_OPEN_LOCK if this is not setstripe.
+ *
+ * Always specify MDS_OPEN_BY_FID because we don't want
+ * to get file with different fid.
+ */
+ it->it_flags |= MDS_OPEN_LOCK | MDS_OPEN_BY_FID;
rc = ll_intent_file_open(file->f_path.dentry, NULL, 0, it);
- it->it_create_mode &= ~M_CHECK_STALE;
if (rc)
goto out_openerr;
@@ -716,9 +696,10 @@ out_och_free:
mutex_unlock(&lli->lli_och_mutex);
out_openerr:
- if (opendir_set != 0)
- ll_stop_statahead(inode, lli->lli_opendir_key);
- ll_file_data_put(fd);
+ if (lli->lli_opendir_key == fd)
+ ll_deauthorize_statahead(inode, fd);
+ if (fd)
+ ll_file_data_put(fd);
} else {
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_OPEN, 1);
}
@@ -764,7 +745,7 @@ ll_lease_open(struct inode *inode, struct file *file, fmode_t fmode,
struct lookup_intent it = { .it_op = IT_OPEN };
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct md_op_data *op_data;
- struct ptlrpc_request *req;
+ struct ptlrpc_request *req = NULL;
struct lustre_handle old_handle = { 0 };
struct obd_client_handle *och = NULL;
int rc;
@@ -831,8 +812,8 @@ ll_lease_open(struct inode *inode, struct file *file, fmode_t fmode,
it.it_flags = fmode | open_flags;
it.it_flags |= MDS_OPEN_LOCK | MDS_OPEN_BY_FID | MDS_OPEN_LEASE;
- rc = md_intent_lock(sbi->ll_md_exp, op_data, NULL, 0, &it, 0, &req,
- ll_md_blocking_lease_ast,
+ rc = md_intent_lock(sbi->ll_md_exp, op_data, &it, &req,
+ &ll_md_blocking_lease_ast,
/* LDLM_FL_NO_LRU: To not put the lease lock into LRU list, otherwise
* it can be cancelled which may mislead applications that the lease is
* broken;
@@ -840,7 +821,7 @@ ll_lease_open(struct inode *inode, struct file *file, fmode_t fmode,
* open in ll_md_blocking_ast(). Otherwise as ll_md_blocking_lease_ast
* doesn't deal with openhandle, so normal openhandle will be leaked.
*/
- LDLM_FL_NO_LRU | LDLM_FL_EXCL);
+ LDLM_FL_NO_LRU | LDLM_FL_EXCL);
ll_finish_md_op_data(op_data);
ptlrpc_req_finished(req);
if (rc < 0)
@@ -908,7 +889,6 @@ static int ll_lease_close(struct obd_client_handle *och, struct inode *inode,
{
struct ldlm_lock *lock;
bool cancelled = true;
- int rc;
lock = ldlm_handle2lock(&och->och_lease_handle);
if (lock) {
@@ -926,9 +906,8 @@ static int ll_lease_close(struct obd_client_handle *och, struct inode *inode,
if (lease_broken)
*lease_broken = cancelled;
- rc = ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp, inode, och,
- NULL);
- return rc;
+ return ll_close_inode_openhandle(ll_i2sbi(inode)->ll_md_exp,
+ inode, och, NULL);
}
/* Fills the obdo with the attributes for the lsm */
@@ -1138,10 +1117,11 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,
{
struct ll_inode_info *lli = ll_i2info(file_inode(file));
struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
+ struct range_lock range;
struct cl_io *io;
ssize_t result;
- CDEBUG(D_VFSTRACE, "file: %s, type: %d ppos: %llu, count: %zd\n",
+ CDEBUG(D_VFSTRACE, "file: %s, type: %d ppos: %llu, count: %zu\n",
file->f_path.dentry->d_name.name, iot, *ppos, count);
restart:
@@ -1150,7 +1130,12 @@ restart:
if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) {
struct vvp_io *vio = vvp_env_io(env);
- int write_mutex_locked = 0;
+ bool range_locked = false;
+
+ if (file->f_flags & O_APPEND)
+ range_lock_init(&range, 0, LUSTRE_EOF);
+ else
+ range_lock_init(&range, *ppos, *ppos + count - 1);
vio->vui_fd = LUSTRE_FPRIVATE(file);
vio->vui_io_subtype = args->via_io_subtype;
@@ -1159,14 +1144,23 @@ restart:
case IO_NORMAL:
vio->vui_iter = args->u.normal.via_iter;
vio->vui_iocb = args->u.normal.via_iocb;
- if ((iot == CIT_WRITE) &&
+ /*
+ * Direct IO reads must also take range lock,
+ * or multiple reads will try to work on the same pages
+ * See LU-6227 for details.
+ */
+ if (((iot == CIT_WRITE) ||
+ (iot == CIT_READ && (file->f_flags & O_DIRECT))) &&
!(vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
- if (mutex_lock_interruptible(&lli->
- lli_write_mutex)) {
- result = -ERESTARTSYS;
+ CDEBUG(D_VFSTRACE, "Range lock [%llu, %llu]\n",
+ range.rl_node.in_extent.start,
+ range.rl_node.in_extent.end);
+ result = range_lock(&lli->lli_write_tree,
+ &range);
+ if (result < 0)
goto out;
- }
- write_mutex_locked = 1;
+
+ range_locked = true;
}
down_read(&lli->lli_trunc_sem);
break;
@@ -1183,8 +1177,12 @@ restart:
ll_cl_remove(file, env);
if (args->via_io_subtype == IO_NORMAL)
up_read(&lli->lli_trunc_sem);
- if (write_mutex_locked)
- mutex_unlock(&lli->lli_write_mutex);
+ if (range_locked) {
+ CDEBUG(D_VFSTRACE, "Range unlock [%llu, %llu]\n",
+ range.rl_node.in_extent.start,
+ range.rl_node.in_extent.end);
+ range_unlock(&lli->lli_write_tree, &range);
+ }
} else {
/* cl_io_rw_init() handled IO */
result = io->ci_result;
@@ -1201,7 +1199,7 @@ out:
* short read/write instead of restart io.
*/
if ((result == 0 || result == -ENODATA) && io->ci_need_restart) {
- CDEBUG(D_VFSTRACE, "Restart %s on %pD from %lld, count:%zd\n",
+ CDEBUG(D_VFSTRACE, "Restart %s on %pD from %lld, count:%zu\n",
iot == CIT_READ ? "read" : "write",
file, *ppos, count);
LASSERTF(io->ci_nob == 0, "%zd\n", io->ci_nob);
@@ -1296,94 +1294,15 @@ static ssize_t ll_file_splice_read(struct file *in_file, loff_t *ppos,
return result;
}
-static int ll_lov_recreate(struct inode *inode, struct ost_id *oi, u32 ost_idx)
-{
- struct obd_export *exp = ll_i2dtexp(inode);
- struct obd_trans_info oti = { 0 };
- struct obdo *oa = NULL;
- int lsm_size;
- int rc = 0;
- struct lov_stripe_md *lsm = NULL, *lsm2;
-
- oa = kmem_cache_zalloc(obdo_cachep, GFP_NOFS);
- if (!oa)
- return -ENOMEM;
-
- lsm = ccc_inode_lsm_get(inode);
- if (!lsm_has_objects(lsm)) {
- rc = -ENOENT;
- goto out;
- }
-
- lsm_size = sizeof(*lsm) + (sizeof(struct lov_oinfo) *
- (lsm->lsm_stripe_count));
-
- lsm2 = libcfs_kvzalloc(lsm_size, GFP_NOFS);
- if (!lsm2) {
- rc = -ENOMEM;
- goto out;
- }
-
- oa->o_oi = *oi;
- oa->o_nlink = ost_idx;
- oa->o_flags |= OBD_FL_RECREATE_OBJS;
- oa->o_valid = OBD_MD_FLID | OBD_MD_FLFLAGS | OBD_MD_FLGROUP;
- obdo_from_inode(oa, inode, OBD_MD_FLTYPE | OBD_MD_FLATIME |
- OBD_MD_FLMTIME | OBD_MD_FLCTIME);
- obdo_set_parent_fid(oa, &ll_i2info(inode)->lli_fid);
- memcpy(lsm2, lsm, lsm_size);
- ll_inode_size_lock(inode);
- rc = obd_create(NULL, exp, oa, &lsm2, &oti);
- ll_inode_size_unlock(inode);
-
- kvfree(lsm2);
- goto out;
-out:
- ccc_inode_lsm_put(inode, lsm);
- kmem_cache_free(obdo_cachep, oa);
- return rc;
-}
-
-static int ll_lov_recreate_obj(struct inode *inode, unsigned long arg)
-{
- struct ll_recreate_obj ucreat;
- struct ost_id oi;
-
- if (!capable(CFS_CAP_SYS_ADMIN))
- return -EPERM;
-
- if (copy_from_user(&ucreat, (struct ll_recreate_obj __user *)arg,
- sizeof(ucreat)))
- return -EFAULT;
-
- ostid_set_seq_mdt0(&oi);
- ostid_set_id(&oi, ucreat.lrc_id);
- return ll_lov_recreate(inode, &oi, ucreat.lrc_ost_idx);
-}
-
-static int ll_lov_recreate_fid(struct inode *inode, unsigned long arg)
-{
- struct lu_fid fid;
- struct ost_id oi;
- u32 ost_idx;
-
- if (!capable(CFS_CAP_SYS_ADMIN))
- return -EPERM;
-
- if (copy_from_user(&fid, (struct lu_fid __user *)arg, sizeof(fid)))
- return -EFAULT;
-
- fid_to_ostid(&fid, &oi);
- ost_idx = (fid_seq(&fid) >> 16) & 0xffff;
- return ll_lov_recreate(inode, &oi, ost_idx);
-}
-
int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry,
__u64 flags, struct lov_user_md *lum,
int lum_size)
{
struct lov_stripe_md *lsm = NULL;
- struct lookup_intent oit = {.it_op = IT_OPEN, .it_flags = flags};
+ struct lookup_intent oit = {
+ .it_op = IT_OPEN,
+ .it_flags = flags | MDS_OPEN_BY_FID,
+ };
int rc = 0;
lsm = ccc_inode_lsm_get(inode);
@@ -1397,11 +1316,11 @@ int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry,
ll_inode_size_lock(inode);
rc = ll_intent_file_open(dentry, lum, lum_size, &oit);
- if (rc)
+ if (rc < 0)
goto out_unlock;
rc = oit.it_status;
if (rc < 0)
- goto out_req_free;
+ goto out_unlock;
ll_release_openhandle(inode, &oit);
@@ -1411,9 +1330,6 @@ out_unlock:
ccc_inode_lsm_put(inode, lsm);
out:
return rc;
-out_req_free:
- ptlrpc_req_finished((struct ptlrpc_request *)oit.it_request);
- goto out;
}
int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
@@ -1448,9 +1364,9 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
- lmmsize = body->eadatasize;
+ lmmsize = body->mbo_eadatasize;
- if (!(body->valid & (OBD_MD_FLEASIZE | OBD_MD_FLDIREA)) ||
+ if (!(body->mbo_valid & (OBD_MD_FLEASIZE | OBD_MD_FLDIREA)) ||
lmmsize == 0) {
rc = -ENODATA;
goto out;
@@ -1481,13 +1397,13 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
*/
if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) {
lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
- if (S_ISREG(body->mode))
+ if (S_ISREG(body->mbo_mode))
lustre_swab_lov_user_md_objects(
((struct lov_user_md_v1 *)lmm)->lmm_objects,
stripe_count);
} else if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)) {
lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
- if (S_ISREG(body->mode))
+ if (S_ISREG(body->mbo_mode))
lustre_swab_lov_user_md_objects(
((struct lov_user_md_v3 *)lmm)->lmm_objects,
stripe_count);
@@ -1530,55 +1446,48 @@ static int ll_lov_setea(struct inode *inode, struct file *file,
return rc;
}
+static int ll_file_getstripe(struct inode *inode,
+ struct lov_user_md __user *lum)
+{
+ struct lu_env *env;
+ int refcheck;
+ int rc;
+
+ env = cl_env_get(&refcheck);
+ if (IS_ERR(env))
+ return PTR_ERR(env);
+
+ rc = cl_object_getstripe(env, ll_i2info(inode)->lli_clob, lum);
+ cl_env_put(env, &refcheck);
+ return rc;
+}
+
static int ll_lov_setstripe(struct inode *inode, struct file *file,
unsigned long arg)
{
- struct lov_user_md_v3 lumv3;
- struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&lumv3;
- struct lov_user_md_v1 __user *lumv1p = (void __user *)arg;
- struct lov_user_md_v3 __user *lumv3p = (void __user *)arg;
+ struct lov_user_md __user *lum = (struct lov_user_md __user *)arg;
+ struct lov_user_md *klum;
int lum_size, rc;
__u64 flags = FMODE_WRITE;
- /* first try with v1 which is smaller than v3 */
- lum_size = sizeof(struct lov_user_md_v1);
- if (copy_from_user(lumv1, lumv1p, lum_size))
- return -EFAULT;
-
- if (lumv1->lmm_magic == LOV_USER_MAGIC_V3) {
- lum_size = sizeof(struct lov_user_md_v3);
- if (copy_from_user(&lumv3, lumv3p, lum_size))
- return -EFAULT;
- }
+ rc = ll_copy_user_md(lum, &klum);
+ if (rc < 0)
+ return rc;
- rc = ll_lov_setstripe_ea_info(inode, file->f_path.dentry, flags, lumv1,
+ lum_size = rc;
+ rc = ll_lov_setstripe_ea_info(inode, file->f_path.dentry, flags, klum,
lum_size);
cl_lov_delay_create_clear(&file->f_flags);
if (rc == 0) {
- struct lov_stripe_md *lsm;
__u32 gen;
- put_user(0, &lumv1p->lmm_stripe_count);
+ put_user(0, &lum->lmm_stripe_count);
ll_layout_refresh(inode, &gen);
- lsm = ccc_inode_lsm_get(inode);
- rc = obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2dtexp(inode),
- 0, lsm, (void __user *)arg);
- ccc_inode_lsm_put(inode, lsm);
+ rc = ll_file_getstripe(inode, (struct lov_user_md __user *)arg);
}
- return rc;
-}
-static int ll_lov_getstripe(struct inode *inode, unsigned long arg)
-{
- struct lov_stripe_md *lsm;
- int rc = -ENODATA;
-
- lsm = ccc_inode_lsm_get(inode);
- if (lsm)
- rc = obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2dtexp(inode), 0,
- lsm, (void __user *)arg);
- ccc_inode_lsm_put(inode, lsm);
+ kfree(klum);
return rc;
}
@@ -2247,6 +2156,12 @@ free_hss:
return rc;
}
+static inline long ll_lease_type_from_fmode(fmode_t fmode)
+{
+ return ((fmode & FMODE_READ) ? LL_LEASE_RDLCK : 0) |
+ ((fmode & FMODE_WRITE) ? LL_LEASE_WRLCK : 0);
+}
+
static long
ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
@@ -2314,11 +2229,8 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return rc;
}
case LL_IOC_LOV_GETSTRIPE:
- return ll_lov_getstripe(inode, arg);
- case LL_IOC_RECREATE_OBJ:
- return ll_lov_recreate_obj(inode, arg);
- case LL_IOC_RECREATE_FID:
- return ll_lov_recreate_fid(inode, arg);
+ return ll_file_getstripe(inode,
+ (struct lov_user_md __user *)arg);
case FSFILT_IOC_FIEMAP:
return ll_ioctl_fiemap(inode, arg);
case FSFILT_IOC_GETFLAGS:
@@ -2349,6 +2261,8 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return 0;
}
+ case LL_IOC_GETPARENT:
+ return ll_getparent(file, (struct getparent __user *)arg);
case OBD_IOC_FID2PATH:
return ll_fid2path(inode, (void __user *)arg);
case LL_IOC_DATA_VERSION: {
@@ -2451,20 +2365,20 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct ll_inode_info *lli = ll_i2info(inode);
struct obd_client_handle *och = NULL;
bool lease_broken;
- fmode_t mode = 0;
+ fmode_t fmode;
switch (arg) {
- case F_WRLCK:
+ case LL_LEASE_WRLCK:
if (!(file->f_mode & FMODE_WRITE))
return -EPERM;
- mode = FMODE_WRITE;
+ fmode = FMODE_WRITE;
break;
- case F_RDLCK:
+ case LL_LEASE_RDLCK:
if (!(file->f_mode & FMODE_READ))
return -EPERM;
- mode = FMODE_READ;
+ fmode = FMODE_READ;
break;
- case F_UNLCK:
+ case LL_LEASE_UNLCK:
mutex_lock(&lli->lli_och_mutex);
if (fd->fd_lease_och) {
och = fd->fd_lease_och;
@@ -2472,26 +2386,26 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
mutex_unlock(&lli->lli_och_mutex);
- if (och) {
- mode = och->och_flags &
- (FMODE_READ|FMODE_WRITE);
- rc = ll_lease_close(och, inode, &lease_broken);
- if (rc == 0 && lease_broken)
- mode = 0;
- } else {
- rc = -ENOLCK;
- }
+ if (!och)
+ return -ENOLCK;
+
+ fmode = och->och_flags;
+ rc = ll_lease_close(och, inode, &lease_broken);
+ if (rc < 0)
+ return rc;
+
+ if (lease_broken)
+ fmode = 0;
- /* return the type of lease or error */
- return rc < 0 ? rc : (int)mode;
+ return ll_lease_type_from_fmode(fmode);
default:
return -EINVAL;
}
- CDEBUG(D_INODE, "Set lease with mode %d\n", mode);
+ CDEBUG(D_INODE, "Set lease with mode %u\n", fmode);
/* apply for lease */
- och = ll_lease_open(inode, file, mode, 0);
+ och = ll_lease_open(inode, file, fmode, 0);
if (IS_ERR(och))
return PTR_ERR(och);
@@ -2512,8 +2426,8 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case LL_IOC_GET_LEASE: {
struct ll_inode_info *lli = ll_i2info(inode);
struct ldlm_lock *lock = NULL;
+ fmode_t fmode = 0;
- rc = 0;
mutex_lock(&lli->lli_och_mutex);
if (fd->fd_lease_och) {
struct obd_client_handle *och = fd->fd_lease_och;
@@ -2522,14 +2436,13 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (lock) {
lock_res_and_lock(lock);
if (!ldlm_is_cancel(lock))
- rc = och->och_flags &
- (FMODE_READ | FMODE_WRITE);
+ fmode = och->och_flags;
unlock_res_and_lock(lock);
LDLM_LOCK_PUT(lock);
}
}
mutex_unlock(&lli->lli_och_mutex);
- return rc;
+ return ll_lease_type_from_fmode(fmode);
}
case LL_IOC_HSM_IMPORT: {
struct hsm_user_import *hui;
@@ -2574,9 +2487,8 @@ static loff_t ll_file_seek(struct file *file, loff_t offset, int origin)
eof = i_size_read(inode);
}
- retval = generic_file_llseek_size(file, offset, origin,
- ll_file_maxbytes(inode), eof);
- return retval;
+ return generic_file_llseek_size(file, offset, origin,
+ ll_file_maxbytes(inode), eof);
}
static int ll_flush(struct file *file, fl_owner_t id)
@@ -2593,9 +2505,11 @@ static int ll_flush(struct file *file, fl_owner_t id)
*/
rc = lli->lli_async_rc;
lli->lli_async_rc = 0;
- err = lov_read_and_clear_async_rc(lli->lli_clob);
- if (rc == 0)
- rc = err;
+ if (lli->lli_clob) {
+ err = lov_read_and_clear_async_rc(lli->lli_clob);
+ if (!rc)
+ rc = err;
+ }
/* The application has been told about write failure already.
* Do not report failure again.
@@ -2714,6 +2628,7 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
struct md_op_data *op_data;
struct lustre_handle lockh = {0};
ldlm_policy_data_t flock = { {0} };
+ int fl_type = file_lock->fl_type;
__u64 flags = 0;
int rc;
int rc2 = 0;
@@ -2744,7 +2659,7 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
if (file_lock->fl_lmops && file_lock->fl_lmops->lm_compare_owner)
flock.l_flock.owner = (unsigned long)file_lock->fl_pid;
- switch (file_lock->fl_type) {
+ switch (fl_type) {
case F_RDLCK:
einfo.ei_mode = LCK_PR;
break;
@@ -2764,8 +2679,7 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
einfo.ei_mode = LCK_PW;
break;
default:
- CDEBUG(D_INFO, "Unknown fcntl lock type: %d\n",
- file_lock->fl_type);
+ CDEBUG(D_INFO, "Unknown fcntl lock type: %d\n", fl_type);
return -ENOTSUPP;
}
@@ -2787,16 +2701,18 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
case F_GETLK64:
#endif
flags = LDLM_FL_TEST_LOCK;
- /* Save the old mode so that if the mode in the lock changes we
- * can decrement the appropriate reader or writer refcount.
- */
- file_lock->fl_type = einfo.ei_mode;
break;
default:
CERROR("unknown fcntl lock command: %d\n", cmd);
return -EINVAL;
}
+ /*
+ * Save the old mode so that if the mode in the lock changes we
+ * can decrement the appropriate reader or writer refcount.
+ */
+ file_lock->fl_type = einfo.ei_mode;
+
op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
LUSTRE_OPC_ANY, NULL);
if (IS_ERR(op_data))
@@ -2806,8 +2722,12 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
PFID(ll_inode2fid(inode)), flock.l_flock.pid, flags,
einfo.ei_mode, flock.l_flock.start, flock.l_flock.end);
- rc = md_enqueue(sbi->ll_md_exp, &einfo, NULL,
- op_data, &lockh, &flock, 0, NULL /* req */, flags);
+ rc = md_enqueue(sbi->ll_md_exp, &einfo, &flock, NULL, op_data, &lockh,
+ flags);
+
+ /* Restore the file lock type if not TEST lock. */
+ if (!(flags & LDLM_FL_TEST_LOCK))
+ file_lock->fl_type = fl_type;
if ((rc == 0 || file_lock->fl_type == F_UNLCK) &&
!(flags & LDLM_FL_TEST_LOCK))
@@ -2815,8 +2735,8 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
if (rc2 && file_lock->fl_type != F_UNLCK) {
einfo.ei_mode = LCK_NL;
- md_enqueue(sbi->ll_md_exp, &einfo, NULL,
- op_data, &lockh, &flock, 0, NULL /* req */, flags);
+ md_enqueue(sbi->ll_md_exp, &einfo, &flock, NULL, op_data,
+ &lockh, flags);
rc = rc2;
}
@@ -2825,6 +2745,117 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
return rc;
}
+int ll_get_fid_by_name(struct inode *parent, const char *name,
+ int namelen, struct lu_fid *fid)
+{
+ struct md_op_data *op_data = NULL;
+ struct ptlrpc_request *req;
+ struct mdt_body *body;
+ int rc;
+
+ op_data = ll_prep_md_op_data(NULL, parent, NULL, name, namelen, 0,
+ LUSTRE_OPC_ANY, NULL);
+ if (IS_ERR(op_data))
+ return PTR_ERR(op_data);
+
+ op_data->op_valid = OBD_MD_FLID;
+ rc = md_getattr_name(ll_i2sbi(parent)->ll_md_exp, op_data, &req);
+ ll_finish_md_op_data(op_data);
+ if (rc < 0)
+ return rc;
+
+ body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
+ if (!body) {
+ rc = -EFAULT;
+ goto out_req;
+ }
+ if (fid)
+ *fid = body->mbo_fid1;
+out_req:
+ ptlrpc_req_finished(req);
+ return rc;
+}
+
+int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
+ const char *name, int namelen)
+{
+ struct ptlrpc_request *request = NULL;
+ struct inode *child_inode = NULL;
+ struct dentry *dchild = NULL;
+ struct md_op_data *op_data;
+ struct qstr qstr;
+ int rc;
+
+ CDEBUG(D_VFSTRACE, "migrate %s under "DFID" to MDT%d\n",
+ name, PFID(ll_inode2fid(parent)), mdtidx);
+
+ op_data = ll_prep_md_op_data(NULL, parent, NULL, name, namelen,
+ 0, LUSTRE_OPC_ANY, NULL);
+ if (IS_ERR(op_data))
+ return PTR_ERR(op_data);
+
+ /* Get child FID first */
+ qstr.hash = full_name_hash(parent, name, namelen);
+ qstr.name = name;
+ qstr.len = namelen;
+ dchild = d_lookup(file_dentry(file), &qstr);
+ if (dchild) {
+ op_data->op_fid3 = *ll_inode2fid(dchild->d_inode);
+ if (dchild->d_inode) {
+ child_inode = igrab(dchild->d_inode);
+ if (child_inode) {
+ inode_lock(child_inode);
+ op_data->op_fid3 = *ll_inode2fid(child_inode);
+ ll_invalidate_aliases(child_inode);
+ }
+ }
+ dput(dchild);
+ } else {
+ rc = ll_get_fid_by_name(parent, name, namelen,
+ &op_data->op_fid3);
+ if (rc)
+ goto out_free;
+ }
+
+ if (!fid_is_sane(&op_data->op_fid3)) {
+ CERROR("%s: migrate %s, but fid "DFID" is insane\n",
+ ll_get_fsname(parent->i_sb, NULL, 0), name,
+ PFID(&op_data->op_fid3));
+ rc = -EINVAL;
+ goto out_free;
+ }
+
+ rc = ll_get_mdt_idx_by_fid(ll_i2sbi(parent), &op_data->op_fid3);
+ if (rc < 0)
+ goto out_free;
+
+ if (rc == mdtidx) {
+ CDEBUG(D_INFO, "%s:"DFID" is already on MDT%d.\n", name,
+ PFID(&op_data->op_fid3), mdtidx);
+ rc = 0;
+ goto out_free;
+ }
+
+ op_data->op_mds = mdtidx;
+ op_data->op_cli_flags = CLI_MIGRATE;
+ rc = md_rename(ll_i2sbi(parent)->ll_md_exp, op_data, name,
+ namelen, name, namelen, &request);
+ if (!rc)
+ ll_update_times(request, parent);
+
+ ptlrpc_req_finished(request);
+
+out_free:
+ if (child_inode) {
+ clear_nlink(child_inode);
+ inode_unlock(child_inode);
+ iput(child_inode);
+ }
+
+ ll_finish_md_op_data(op_data);
+ return rc;
+}
+
static int
ll_file_noflock(struct file *file, int cmd, struct file_lock *file_lock)
{
@@ -2847,7 +2878,7 @@ int ll_have_md_lock(struct inode *inode, __u64 *bits,
struct lustre_handle lockh;
ldlm_policy_data_t policy;
enum ldlm_mode mode = (l_req_mode == LCK_MINMODE) ?
- (LCK_CR|LCK_CW|LCK_PR|LCK_PW) : l_req_mode;
+ (LCK_CR | LCK_CW | LCK_PR | LCK_PW) : l_req_mode;
struct lu_fid *fid;
__u64 flags;
int i;
@@ -2888,15 +2919,12 @@ enum ldlm_mode ll_take_md_lock(struct inode *inode, __u64 bits,
{
ldlm_policy_data_t policy = { .l_inodebits = {bits} };
struct lu_fid *fid;
- enum ldlm_mode rc;
fid = &ll_i2info(inode)->lli_fid;
CDEBUG(D_INFO, "trying to match res "DFID"\n", PFID(fid));
- rc = md_lock_match(ll_i2mdexp(inode), flags | LDLM_FL_BLOCK_GRANTED,
- fid, LDLM_IBITS, &policy, mode, lockh);
-
- return rc;
+ return md_lock_match(ll_i2mdexp(inode), flags | LDLM_FL_BLOCK_GRANTED,
+ fid, LDLM_IBITS, &policy, mode, lockh);
}
static int ll_inode_revalidate_fini(struct inode *inode, int rc)
@@ -2949,15 +2977,9 @@ static int __ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
if (IS_ERR(op_data))
return PTR_ERR(op_data);
- oit.it_create_mode |= M_CHECK_STALE;
- rc = md_intent_lock(exp, op_data, NULL, 0,
- /* we are not interested in name
- * based lookup
- */
- &oit, 0, &req,
- ll_md_blocking_ast, 0);
+ rc = md_intent_lock(exp, op_data, &oit, &req,
+ &ll_md_blocking_ast, 0);
ll_finish_md_op_data(op_data);
- oit.it_create_mode &= ~M_CHECK_STALE;
if (rc < 0) {
rc = ll_inode_revalidate_fini(inode, rc);
goto out;
@@ -3003,10 +3025,8 @@ static int __ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
op_data->op_valid = valid;
rc = md_getattr(sbi->ll_md_exp, op_data, &req);
ll_finish_md_op_data(op_data);
- if (rc) {
- rc = ll_inode_revalidate_fini(inode, rc);
- return rc;
- }
+ if (rc)
+ return ll_inode_revalidate_fini(inode, rc);
rc = ll_prep_inode(&inode, req, NULL, NULL);
}
@@ -3015,6 +3035,28 @@ out:
return rc;
}
+static int ll_merge_md_attr(struct inode *inode)
+{
+ struct cl_attr attr = { 0 };
+ int rc;
+
+ LASSERT(ll_i2info(inode)->lli_lsm_md);
+ rc = md_merge_attr(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
+ &attr, ll_md_blocking_ast);
+ if (rc)
+ return rc;
+
+ set_nlink(inode, attr.cat_nlink);
+ inode->i_blocks = attr.cat_blocks;
+ i_size_write(inode, attr.cat_size);
+
+ ll_i2info(inode)->lli_atime = attr.cat_atime;
+ ll_i2info(inode)->lli_mtime = attr.cat_mtime;
+ ll_i2info(inode)->lli_ctime = attr.cat_ctime;
+
+ return 0;
+}
+
static int ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
{
struct inode *inode = d_inode(dentry);
@@ -3026,6 +3068,13 @@ static int ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
/* if object isn't regular file, don't validate size */
if (!S_ISREG(inode->i_mode)) {
+ if (S_ISDIR(inode->i_mode) &&
+ ll_i2info(inode)->lli_lsm_md) {
+ rc = ll_merge_md_attr(inode);
+ if (rc)
+ return rc;
+ }
+
LTIME_S(inode->i_atime) = ll_i2info(inode)->lli_atime;
LTIME_S(inode->i_mtime) = ll_i2info(inode)->lli_mtime;
LTIME_S(inode->i_ctime) = ll_i2info(inode)->lli_ctime;
@@ -3057,13 +3106,14 @@ int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat)
if (res)
return res;
+ OBD_FAIL_TIMEOUT(OBD_FAIL_GETATTR_DELAY, 30);
+
stat->dev = inode->i_sb->s_dev;
if (ll_need_32bit_api(sbi))
stat->ino = cl_fid_build_ino(&lli->lli_fid, 1);
else
stat->ino = inode->i_ino;
stat->mode = inode->i_mode;
- stat->nlink = inode->i_nlink;
stat->uid = inode->i_uid;
stat->gid = inode->i_gid;
stat->rdev = inode->i_rdev;
@@ -3072,6 +3122,7 @@ int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat)
stat->ctime = inode->i_ctime;
stat->blksize = 1 << inode->i_blkbits;
+ stat->nlink = inode->i_nlink;
stat->size = i_size_read(inode);
stat->blocks = inode->i_blocks;
@@ -3139,6 +3190,12 @@ struct posix_acl *ll_get_acl(struct inode *inode, int type)
int ll_inode_permission(struct inode *inode, int mask)
{
+ struct ll_sb_info *sbi;
+ struct root_squash_info *squash;
+ const struct cred *old_cred = NULL;
+ struct cred *cred = NULL;
+ bool squash_id = false;
+ cfs_cap_t cap;
int rc = 0;
if (mask & MAY_NOT_BLOCK)
@@ -3158,9 +3215,46 @@ int ll_inode_permission(struct inode *inode, int mask)
CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), inode mode %x mask %o\n",
PFID(ll_inode2fid(inode)), inode, inode->i_mode, mask);
+ /* squash fsuid/fsgid if needed */
+ sbi = ll_i2sbi(inode);
+ squash = &sbi->ll_squash;
+ if (unlikely(squash->rsi_uid &&
+ uid_eq(current_fsuid(), GLOBAL_ROOT_UID) &&
+ !(sbi->ll_flags & LL_SBI_NOROOTSQUASH))) {
+ squash_id = true;
+ }
+
+ if (squash_id) {
+ CDEBUG(D_OTHER, "squash creds (%d:%d)=>(%d:%d)\n",
+ __kuid_val(current_fsuid()), __kgid_val(current_fsgid()),
+ squash->rsi_uid, squash->rsi_gid);
+
+ /*
+ * update current process's credentials
+ * and FS capability
+ */
+ cred = prepare_creds();
+ if (!cred)
+ return -ENOMEM;
+
+ cred->fsuid = make_kuid(&init_user_ns, squash->rsi_uid);
+ cred->fsgid = make_kgid(&init_user_ns, squash->rsi_gid);
+ for (cap = 0; cap < sizeof(cfs_cap_t) * 8; cap++) {
+ if ((1 << cap) & CFS_CAP_FS_MASK)
+ cap_lower(cred->cap_effective, cap);
+ }
+ old_cred = override_creds(cred);
+ }
+
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_INODE_PERM, 1);
rc = generic_permission(inode, mask);
+ /* restore current process's credentials and FS capability */
+ if (squash_id) {
+ revert_creds(old_cred);
+ put_cred(cred);
+ }
+
return rc;
}
@@ -3213,10 +3307,10 @@ const struct inode_operations ll_file_inode_operations = {
.setattr = ll_setattr,
.getattr = ll_getattr,
.permission = ll_inode_permission,
- .setxattr = ll_setxattr,
- .getxattr = ll_getxattr,
+ .setxattr = generic_setxattr,
+ .getxattr = generic_getxattr,
.listxattr = ll_listxattr,
- .removexattr = ll_removexattr,
+ .removexattr = generic_removexattr,
.fiemap = ll_fiemap,
.get_acl = ll_get_acl,
};
@@ -3251,7 +3345,6 @@ void *ll_iocontrol_register(llioc_callback_t cb, int count, unsigned int *cmd)
if (!in_data)
return NULL;
- memset(in_data, 0, sizeof(*in_data));
in_data->iocd_size = size;
in_data->iocd_cb = cb;
in_data->iocd_count = count;
@@ -3389,7 +3482,7 @@ static int ll_layout_fetch(struct inode *inode, struct ldlm_lock *lock)
goto out;
}
- lmmsize = body->eadatasize;
+ lmmsize = body->mbo_eadatasize;
if (lmmsize == 0) /* empty layout */ {
rc = 0;
goto out;
@@ -3447,7 +3540,7 @@ static int ll_layout_lock_set(struct lustre_handle *lockh, enum ldlm_mode mode,
PFID(&lli->lli_fid), inode, reconf);
/* in case this is a caching lock and reinstate with new inode */
- md_set_lock_data(sbi->ll_md_exp, &lockh->cookie, inode, NULL);
+ md_set_lock_data(sbi->ll_md_exp, lockh, inode, NULL);
lock_res_and_lock(lock);
lvb_ready = ldlm_is_lvb_ready(lock);
@@ -3557,8 +3650,8 @@ int ll_layout_refresh(struct inode *inode, __u32 *gen)
struct ldlm_enqueue_info einfo = {
.ei_type = LDLM_IBITS,
.ei_mode = LCK_CR,
- .ei_cb_bl = ll_md_blocking_ast,
- .ei_cb_cp = ldlm_completion_ast,
+ .ei_cb_bl = &ll_md_blocking_ast,
+ .ei_cb_cp = &ldlm_completion_ast,
};
int rc;
@@ -3604,8 +3697,7 @@ again:
ll_get_fsname(inode->i_sb, NULL, 0),
PFID(&lli->lli_fid), inode);
- rc = md_enqueue(sbi->ll_md_exp, &einfo, &it, op_data, &lockh,
- NULL, 0, NULL, 0);
+ rc = md_enqueue(sbi->ll_md_exp, &einfo, NULL, &it, op_data, &lockh, 0);
ptlrpc_req_finished(it.it_request);
it.it_request = NULL;
diff --git a/drivers/staging/lustre/lustre/llite/glimpse.c b/drivers/staging/lustre/lustre/llite/glimpse.c
index 92004a05f9ee..22507b9c6d69 100644
--- a/drivers/staging/lustre/lustre/llite/glimpse.c
+++ b/drivers/staging/lustre/lustre/llite/glimpse.c
@@ -42,7 +42,6 @@
#include "../include/obd.h"
#include "../include/lustre_dlm.h"
-#include "../include/lustre_lite.h"
#include "../include/lustre_mdc.h"
#include <linux/pagemap.h>
#include <linux/file.h>
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_cl.c b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
index 396e4e4f0715..084330d08f7a 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_cl.c
@@ -49,7 +49,6 @@
#include "../include/obd.h"
#include "../include/obd_support.h"
#include "../include/lustre_fid.h"
-#include "../include/lustre_lite.h"
#include "../include/lustre_dlm.h"
#include "../include/lustre_ver.h"
#include "../include/lustre_mdc.h"
@@ -100,6 +99,7 @@ int cl_setattr_ost(struct inode *inode, const struct iattr *attr)
io->u.ci_setattr.sa_attr.lvb_ctime = LTIME_S(attr->ia_ctime);
io->u.ci_setattr.sa_attr.lvb_size = attr->ia_size;
io->u.ci_setattr.sa_valid = attr->ia_valid;
+ io->u.ci_setattr.sa_parent_fid = ll_inode2fid(inode);
again:
if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) {
@@ -154,7 +154,7 @@ int cl_file_inode_init(struct inode *inode, struct lustre_md *md)
int result = 0;
int refcheck;
- LASSERT(md->body->valid & OBD_MD_FLID);
+ LASSERT(md->body->mbo_valid & OBD_MD_FLID);
LASSERT(S_ISREG(inode->i_mode));
env = cl_env_get(&refcheck);
diff --git a/drivers/staging/lustre/lustre/llite/lcommon_misc.c b/drivers/staging/lustre/lustre/llite/lcommon_misc.c
index f6be105eeef7..fb346c12dad2 100644
--- a/drivers/staging/lustre/lustre/llite/lcommon_misc.c
+++ b/drivers/staging/lustre/lustre/llite/lcommon_misc.c
@@ -38,7 +38,6 @@
#include "../include/obd.h"
#include "../include/cl_object.h"
-#include "../include/lustre_lite.h"
#include "llite_internal.h"
/* Initialize the default and maximum LOV EA and cookie sizes. This allows
diff --git a/drivers/staging/lustre/lustre/llite/llite_close.c b/drivers/staging/lustre/lustre/llite/llite_close.c
index 2326b40a0870..8644631bf2ba 100644
--- a/drivers/staging/lustre/lustre/llite/llite_close.c
+++ b/drivers/staging/lustre/lustre/llite/llite_close.c
@@ -38,7 +38,6 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/lustre_lite.h"
#include "llite_internal.h"
/** records that a write is in flight */
diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h
index 4d6d589a1677..3e98bd685061 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -36,14 +36,21 @@
#include "../include/lustre_ver.h"
#include "../include/lustre_disk.h" /* for s2sbi */
#include "../include/lustre_eacl.h"
+#include "../include/lustre_linkea.h"
/* for struct cl_lock_descr and struct cl_io */
+#include "../include/lustre_patchless_compat.h"
+#include "../include/lustre_compat.h"
#include "../include/cl_object.h"
+#include "../include/lustre_lmv.h"
#include "../include/lustre_mdc.h"
#include "../include/lustre_intent.h"
#include <linux/compat.h>
+#include <linux/namei.h>
+#include <linux/xattr.h>
#include <linux/posix_acl_xattr.h>
#include "vvp_internal.h"
+#include "range_lock.h"
#ifndef FMODE_EXEC
#define FMODE_EXEC 0
@@ -57,6 +64,9 @@
#define LL_DIR_END_OFF 0x7fffffffffffffffULL
#define LL_DIR_END_OFF_32BIT 0x7fffffffUL
+/* 4UL * 1024 * 1024 */
+#define LL_MAX_BLKSIZE_BITS 22
+
#define LL_IT2STR(it) ((it) ? ldlm_it2str((it)->it_op) : "0")
#define LUSTRE_FPRIVATE(file) ((file)->private_data)
@@ -116,9 +126,7 @@ struct ll_inode_info {
/* identifying fields for both metadata and data stacks. */
struct lu_fid lli_fid;
- /* Parent fid for accessing default stripe data on parent directory
- * for allocating OST objects after a mknod() and later open-by-FID.
- */
+ /* master inode fid for stripe directory */
struct lu_fid lli_pfid;
struct list_head lli_close_list;
@@ -156,7 +164,7 @@ struct ll_inode_info {
/* for directory */
struct {
/* serialize normal readdir and statahead-readdir. */
- struct mutex d_readdir_mutex;
+ struct mutex lli_readdir_mutex;
/* metadata statahead */
/* since parent-child threads can share the same @file
@@ -164,27 +172,39 @@ struct ll_inode_info {
* case of parent exit before child -- it is me should
* cleanup the dir readahead.
*/
- void *d_opendir_key;
- struct ll_statahead_info *d_sai;
+ void *lli_opendir_key;
+ struct ll_statahead_info *lli_sai;
/* protect statahead stuff. */
- spinlock_t d_sa_lock;
+ spinlock_t lli_sa_lock;
/* "opendir_pid" is the token when lookup/revalidate
* -- I am the owner of dir statahead.
*/
- pid_t d_opendir_pid;
- } d;
-
-#define lli_readdir_mutex u.d.d_readdir_mutex
-#define lli_opendir_key u.d.d_opendir_key
-#define lli_sai u.d.d_sai
-#define lli_sa_lock u.d.d_sa_lock
-#define lli_opendir_pid u.d.d_opendir_pid
+ pid_t lli_opendir_pid;
+ /* stat will try to access statahead entries or start
+ * statahead if this flag is set, and this flag will be
+ * set upon dir open, and cleared when dir is closed,
+ * statahead hit ratio is too low, or start statahead
+ * thread failed.
+ */
+ unsigned int lli_sa_enabled:1;
+ /* generation for statahead */
+ unsigned int lli_sa_generation;
+ /* directory stripe information */
+ struct lmv_stripe_md *lli_lsm_md;
+ /* default directory stripe offset. This is extracted
+ * from the "dmv" xattr in order to decide which MDT to
+ * create a subdirectory on. The MDS itself fetches
+ * "dmv" and gets the rest of the default layout itself
+ * (count, hash, etc).
+ */
+ __u32 lli_def_stripe_offset;
+ };
/* for non-directory */
struct {
- struct mutex f_size_mutex;
- char *f_symlink_name;
- __u64 f_maxbytes;
+ struct mutex lli_size_mutex;
+ char *lli_symlink_name;
+ __u64 lli_maxbytes;
/*
* struct rw_semaphore {
* signed long count; // align d.d_def_acl
@@ -192,16 +212,16 @@ struct ll_inode_info {
* struct list_head wait_list;
* }
*/
- struct rw_semaphore f_trunc_sem;
- struct mutex f_write_mutex;
+ struct rw_semaphore lli_trunc_sem;
+ struct range_lock_tree lli_write_tree;
- struct rw_semaphore f_glimpse_sem;
- unsigned long f_glimpse_time;
- struct list_head f_agl_list;
- __u64 f_agl_index;
+ struct rw_semaphore lli_glimpse_sem;
+ unsigned long lli_glimpse_time;
+ struct list_head lli_agl_list;
+ __u64 lli_agl_index;
/* for writepage() only to communicate to fsync */
- int f_async_rc;
+ int lli_async_rc;
/*
* whenever a process try to read/write the file, the
@@ -211,22 +231,9 @@ struct ll_inode_info {
* so the read/write statistics for jobid will not be
* accurate if the file is shared by different jobs.
*/
- char f_jobid[JOBSTATS_JOBID_SIZE];
- } f;
-
-#define lli_size_mutex u.f.f_size_mutex
-#define lli_symlink_name u.f.f_symlink_name
-#define lli_maxbytes u.f.f_maxbytes
-#define lli_trunc_sem u.f.f_trunc_sem
-#define lli_write_mutex u.f.f_write_mutex
-#define lli_glimpse_sem u.f.f_glimpse_sem
-#define lli_glimpse_time u.f.f_glimpse_time
-#define lli_agl_list u.f.f_agl_list
-#define lli_agl_index u.f.f_agl_index
-#define lli_async_rc u.f.f_async_rc
-#define lli_jobid u.f.f_jobid
-
- } u;
+ char lli_jobid[LUSTRE_JOBID_SIZE];
+ };
+ };
/* XXX: For following frequent used members, although they maybe special
* used for non-directory object, it is some time-wasting to check
@@ -401,12 +408,13 @@ enum stats_track_type {
#define LL_SBI_LAYOUT_LOCK 0x20000 /* layout lock support */
#define LL_SBI_USER_FID2PATH 0x40000 /* allow fid2path by unprivileged users */
#define LL_SBI_XATTR_CACHE 0x80000 /* support for xattr cache */
+#define LL_SBI_NOROOTSQUASH 0x100000 /* do not apply root squash */
#define LL_SBI_FLAGS { \
"nolck", \
"checksum", \
"flock", \
- "xattr", \
+ "user_xattr", \
"acl", \
"???", \
"???", \
@@ -422,9 +430,27 @@ enum stats_track_type {
"verbose", \
"layout", \
"user_fid2path",\
- "xattr", \
+ "xattr_cache", \
+ "norootsquash", \
}
+/*
+ * This is embedded into llite super-blocks to keep track of connect
+ * flags (capabilities) supported by all imports given mount is
+ * connected to.
+ */
+struct lustre_client_ocd {
+ /*
+ * This is conjunction of connect_flags across all imports
+ * (LOVs) this mount is connected to. This field is updated by
+ * cl_ocd_update() under ->lco_lock.
+ */
+ __u64 lco_flags;
+ struct mutex lco_lock;
+ struct obd_export *lco_md_exp;
+ struct obd_export *lco_dt_exp;
+};
+
struct ll_sb_info {
/* this protects pglist and ra_info. It isn't safe to
* grab from interrupt contexts
@@ -461,7 +487,7 @@ struct ll_sb_info {
unsigned int ll_namelen;
struct file_operations *ll_fop;
- unsigned int ll_md_brw_size; /* used by readdir */
+ unsigned int ll_md_brw_pages; /* readdir pages per RPC */
struct lu_site *ll_site;
struct cl_device *ll_cl;
@@ -484,11 +510,17 @@ struct ll_sb_info {
atomic_t ll_sa_wrong; /* statahead thread stopped for
* low hit ratio
*/
+ atomic_t ll_sa_running; /* running statahead thread
+ * count
+ */
atomic_t ll_agl_total; /* AGL thread started count */
dev_t ll_sdev_orig; /* save s_dev before assign for
* clustered nfs
*/
+ /* root squash */
+ struct root_squash_info ll_squash;
+
__kernel_fsid_t ll_fsid;
struct kobject ll_kobj; /* sysfs object */
struct super_block *ll_sb; /* struct super_block (for sysfs code)*/
@@ -643,25 +675,66 @@ void ll_rw_stats_tally(struct ll_sb_info *sbi, pid_t pid,
struct ll_file_data *file, loff_t pos,
size_t count, int rw);
+enum {
+ LPROC_LL_DIRTY_HITS,
+ LPROC_LL_DIRTY_MISSES,
+ LPROC_LL_READ_BYTES,
+ LPROC_LL_WRITE_BYTES,
+ LPROC_LL_BRW_READ,
+ LPROC_LL_BRW_WRITE,
+ LPROC_LL_OSC_READ,
+ LPROC_LL_OSC_WRITE,
+ LPROC_LL_IOCTL,
+ LPROC_LL_OPEN,
+ LPROC_LL_RELEASE,
+ LPROC_LL_MAP,
+ LPROC_LL_LLSEEK,
+ LPROC_LL_FSYNC,
+ LPROC_LL_READDIR,
+ LPROC_LL_SETATTR,
+ LPROC_LL_TRUNC,
+ LPROC_LL_FLOCK,
+ LPROC_LL_GETATTR,
+ LPROC_LL_CREATE,
+ LPROC_LL_LINK,
+ LPROC_LL_UNLINK,
+ LPROC_LL_SYMLINK,
+ LPROC_LL_MKDIR,
+ LPROC_LL_RMDIR,
+ LPROC_LL_MKNOD,
+ LPROC_LL_RENAME,
+ LPROC_LL_STAFS,
+ LPROC_LL_ALLOC_INODE,
+ LPROC_LL_SETXATTR,
+ LPROC_LL_GETXATTR,
+ LPROC_LL_GETXATTR_HITS,
+ LPROC_LL_LISTXATTR,
+ LPROC_LL_REMOVEXATTR,
+ LPROC_LL_INODE_PERM,
+ LPROC_LL_FILE_OPCODES
+};
+
/* llite/dir.c */
-void ll_release_page(struct page *page, int remove);
extern const struct file_operations ll_dir_operations;
extern const struct inode_operations ll_dir_inode_operations;
-struct page *ll_get_dir_page(struct inode *dir, __u64 hash,
- struct ll_dir_chain *chain);
-int ll_dir_read(struct inode *inode, struct dir_context *ctx);
-
+int ll_dir_read(struct inode *inode, __u64 *ppos, struct md_op_data *op_data,
+ struct dir_context *ctx);
int ll_get_mdt_idx(struct inode *inode);
+int ll_get_mdt_idx_by_fid(struct ll_sb_info *sbi, const struct lu_fid *fid);
+struct page *ll_get_dir_page(struct inode *dir, struct md_op_data *op_data,
+ __u64 offset);
+void ll_release_page(struct inode *inode, struct page *page, bool remove);
+
/* llite/namei.c */
extern const struct inode_operations ll_special_inode_operations;
-int ll_objects_destroy(struct ptlrpc_request *request,
- struct inode *dir);
struct inode *ll_iget(struct super_block *sb, ino_t hash,
struct lustre_md *lic);
+int ll_test_inode_by_fid(struct inode *inode, void *opaque);
int ll_md_blocking_ast(struct ldlm_lock *, struct ldlm_lock_desc *,
void *data, int flag);
struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de);
+void ll_update_times(struct ptlrpc_request *request, struct inode *inode);
/* llite/rw.c */
int ll_writepage(struct page *page, struct writeback_control *wbc);
@@ -704,7 +777,10 @@ void ll_pack_inode2opdata(struct inode *inode, struct md_op_data *op_data,
struct lustre_handle *fh);
int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat);
struct posix_acl *ll_get_acl(struct inode *inode, int type);
-
+int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
+ const char *name, int namelen);
+int ll_get_fid_by_name(struct inode *parent, const char *name,
+ int namelen, struct lu_fid *fid);
int ll_inode_permission(struct inode *inode, int mask);
int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry,
@@ -715,8 +791,8 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
struct ptlrpc_request **request);
int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
int set_default);
-int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
- int *lmm_size, struct ptlrpc_request **request);
+int ll_dir_getstripe(struct inode *inode, void **lmmp, int *lmm_size,
+ struct ptlrpc_request **request, u64 valid);
int ll_fsync(struct file *file, loff_t start, loff_t end, int data);
int ll_merge_attr(const struct lu_env *env, struct inode *inode);
int ll_fid2path(struct inode *inode, void __user *arg);
@@ -748,8 +824,8 @@ int ll_setattr(struct dentry *de, struct iattr *attr);
int ll_statfs(struct dentry *de, struct kstatfs *sfs);
int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
__u64 max_age, __u32 flags);
-void ll_update_inode(struct inode *inode, struct lustre_md *md);
-void ll_read_inode2(struct inode *inode, void *opaque);
+int ll_update_inode(struct inode *inode, struct lustre_md *md);
+int ll_read_inode2(struct inode *inode, void *opaque);
void ll_delete_inode(struct inode *inode);
int ll_iocontrol(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
@@ -763,15 +839,46 @@ int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req,
int ll_obd_statfs(struct inode *inode, void __user *arg);
int ll_get_max_mdsize(struct ll_sb_info *sbi, int *max_mdsize);
int ll_get_default_mdsize(struct ll_sb_info *sbi, int *default_mdsize);
+int ll_set_default_mdsize(struct ll_sb_info *sbi, int default_mdsize);
int ll_process_config(struct lustre_cfg *lcfg);
+
+enum {
+ LUSTRE_OPC_MKDIR = 0,
+ LUSTRE_OPC_SYMLINK = 1,
+ LUSTRE_OPC_MKNOD = 2,
+ LUSTRE_OPC_CREATE = 3,
+ LUSTRE_OPC_ANY = 5,
+};
+
struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
struct inode *i1, struct inode *i2,
- const char *name, int namelen,
- int mode, __u32 opc, void *data);
+ const char *name, size_t namelen,
+ u32 mode, __u32 opc, void *data);
void ll_finish_md_op_data(struct md_op_data *op_data);
int ll_get_obd_name(struct inode *inode, unsigned int cmd, unsigned long arg);
char *ll_get_fsname(struct super_block *sb, char *buf, int buflen);
+void ll_compute_rootsquash_state(struct ll_sb_info *sbi);
void ll_open_cleanup(struct super_block *sb, struct ptlrpc_request *open_req);
+ssize_t ll_copy_user_md(const struct lov_user_md __user *md,
+ struct lov_user_md **kbuf);
+
+/* Compute expected user md size when passing in a md from user space */
+static inline ssize_t ll_lov_user_md_size(const struct lov_user_md *lum)
+{
+ switch (lum->lmm_magic) {
+ case LOV_USER_MAGIC_V1:
+ return sizeof(struct lov_user_md_v1);
+ case LOV_USER_MAGIC_V3:
+ return sizeof(struct lov_user_md_v3);
+ case LOV_USER_MAGIC_SPECIFIC:
+ if (lum->lmm_stripe_count > LOV_MAX_STRIPE_COUNT)
+ return -EINVAL;
+
+ return lov_user_md_size(lum->lmm_stripe_count,
+ LOV_USER_MAGIC_SPECIFIC);
+ }
+ return -EINVAL;
+}
/* llite/llite_nfs.c */
extern const struct export_operations lustre_export_operations;
@@ -779,6 +886,7 @@ __u32 get_uuid2int(const char *name, int len);
void get_uuid2fsid(const char *name, int len, __kernel_fsid_t *fsid);
struct inode *search_inode_for_lustre(struct super_block *sb,
const struct lu_fid *fid);
+int ll_dir_get_parent_fid(struct inode *dir, struct lu_fid *parent_fid);
/* llite/symlink.c */
extern const struct inode_operations ll_fast_symlink_inode_operations;
@@ -933,12 +1041,19 @@ static inline __u64 ll_file_maxbytes(struct inode *inode)
}
/* llite/xattr.c */
-int ll_setxattr(struct dentry *dentry, struct inode *inode,
- const char *name, const void *value, size_t size, int flags);
-ssize_t ll_getxattr(struct dentry *dentry, struct inode *inode,
- const char *name, void *buffer, size_t size);
+extern const struct xattr_handler *ll_xattr_handlers[];
+
+#define XATTR_USER_T 1
+#define XATTR_TRUSTED_T 2
+#define XATTR_SECURITY_T 3
+#define XATTR_ACL_ACCESS_T 4
+#define XATTR_ACL_DEFAULT_T 5
+#define XATTR_LUSTRE_T 6
+#define XATTR_OTHER_T 7
+
ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size);
-int ll_removexattr(struct dentry *dentry, const char *name);
+int ll_xattr_list(struct inode *inode, const char *name, int type,
+ void *buffer, size_t size, __u64 valid);
/**
* Common IO arguments for various VFS I/O interfaces.
@@ -964,11 +1079,10 @@ void ll_ra_stats_inc(struct inode *inode, enum ra_stat which);
/* per inode struct, for dir only */
struct ll_statahead_info {
- struct inode *sai_inode;
+ struct dentry *sai_dentry;
atomic_t sai_refcount; /* when access this struct, hold
* refcount
*/
- unsigned int sai_generation; /* generation for statahead */
unsigned int sai_max; /* max ahead of lookup */
__u64 sai_sent; /* stat requests sent count */
__u64 sai_replied; /* stat requests which received
@@ -995,22 +1109,25 @@ struct ll_statahead_info {
unsigned int sai_ls_all:1, /* "ls -al", do stat-ahead for
* hidden entries
*/
- sai_agl_valid:1;/* AGL is valid for the dir */
+ sai_agl_valid:1,/* AGL is valid for the dir */
+ sai_in_readpage:1;/* statahead is in readdir() */
wait_queue_head_t sai_waitq; /* stat-ahead wait queue */
struct ptlrpc_thread sai_thread; /* stat-ahead thread */
struct ptlrpc_thread sai_agl_thread; /* AGL thread */
- struct list_head sai_entries; /* entry list */
- struct list_head sai_entries_received; /* entries returned */
- struct list_head sai_entries_stated; /* entries stated */
- struct list_head sai_entries_agl; /* AGL entries to be sent */
+ struct list_head sai_interim_entries; /* entries which got async
+ * stat reply, but not
+ * instantiated
+ */
+ struct list_head sai_entries; /* completed entries */
+ struct list_head sai_agls; /* AGLs to be sent */
struct list_head sai_cache[LL_SA_CACHE_SIZE];
spinlock_t sai_cache_lock[LL_SA_CACHE_SIZE];
atomic_t sai_cache_count; /* entry count in cache */
};
-int do_statahead_enter(struct inode *dir, struct dentry **dentry,
- int only_unplug);
-void ll_stop_statahead(struct inode *dir, void *key);
+int ll_statahead(struct inode *dir, struct dentry **dentry, bool unplug);
+void ll_authorize_statahead(struct inode *dir, void *key);
+void ll_deauthorize_statahead(struct inode *dir, void *key);
blkcnt_t dirty_cnt(struct inode *inode);
@@ -1040,73 +1157,53 @@ static inline int ll_glimpse_size(struct inode *inode)
return rc;
}
-static inline void
-ll_statahead_mark(struct inode *dir, struct dentry *dentry)
-{
- struct ll_inode_info *lli = ll_i2info(dir);
- struct ll_statahead_info *sai = lli->lli_sai;
- struct ll_dentry_data *ldd = ll_d2d(dentry);
-
- /* not the same process, don't mark */
- if (lli->lli_opendir_pid != current_pid())
- return;
-
- LASSERT(ldd);
- if (sai)
- ldd->lld_sa_generation = sai->sai_generation;
-}
-
-static inline int
-d_need_statahead(struct inode *dir, struct dentry *dentryp)
+/*
+ * dentry may statahead when statahead is enabled and current process has opened
+ * parent directory, and this dentry hasn't accessed statahead cache before
+ */
+static inline bool
+dentry_may_statahead(struct inode *dir, struct dentry *dentry)
{
struct ll_inode_info *lli;
struct ll_dentry_data *ldd;
if (ll_i2sbi(dir)->ll_sa_max == 0)
- return -EAGAIN;
+ return false;
lli = ll_i2info(dir);
+
+ /*
+ * statahead is not allowed for this dir, there may be three causes:
+ * 1. dir is not opened.
+ * 2. statahead hit ratio is too low.
+ * 3. previous stat started statahead thread failed.
+ */
+ if (!lli->lli_sa_enabled)
+ return false;
+
/* not the same process, don't statahead */
if (lli->lli_opendir_pid != current_pid())
- return -EAGAIN;
-
- /* statahead has been stopped */
- if (!lli->lli_opendir_key)
- return -EAGAIN;
+ return false;
- ldd = ll_d2d(dentryp);
/*
- * When stats a dentry, the system trigger more than once "revalidate"
- * or "lookup", for "getattr", for "getxattr", and maybe for others.
- * Under patchless client mode, the operation intent is not accurate,
- * which maybe misguide the statahead thread. For example:
- * The "revalidate" call for "getattr" and "getxattr" of a dentry maybe
- * have the same operation intent -- "IT_GETATTR".
- * In fact, one dentry should has only one chance to interact with the
- * statahead thread, otherwise the statahead windows will be confused.
+ * When stating a dentry, kernel may trigger 'revalidate' or 'lookup'
+ * multiple times, eg. for 'getattr', 'getxattr' and etc.
+ * For patchless client, lookup intent is not accurate, which may
+ * misguide statahead. For example:
+ * The 'revalidate' call for 'getattr' and 'getxattr' of a dentry will
+ * have the same intent -- IT_GETATTR, while one dentry should access
+ * statahead cache once, otherwise statahead windows is messed up.
* The solution is as following:
- * Assign "lld_sa_generation" with "sai_generation" when a dentry
- * "IT_GETATTR" for the first time, and the subsequent "IT_GETATTR"
- * will bypass interacting with statahead thread for checking:
- * "lld_sa_generation == lli_sai->sai_generation"
+ * Assign 'lld_sa_generation' with 'lli_sa_generation' when a dentry
+ * IT_GETATTR for the first time, and subsequent IT_GETATTR will
+ * bypass interacting with statahead cache by checking
+ * 'lld_sa_generation == lli->lli_sa_generation'.
*/
- if (ldd && lli->lli_sai &&
- ldd->lld_sa_generation == lli->lli_sai->sai_generation)
- return -EAGAIN;
+ ldd = ll_d2d(dentry);
+ if (ldd && ldd->lld_sa_generation == lli->lli_sa_generation)
+ return false;
- return 1;
-}
-
-static inline int
-ll_statahead_enter(struct inode *dir, struct dentry **dentryp, int only_unplug)
-{
- int ret;
-
- ret = d_need_statahead(dir, *dentryp);
- if (ret <= 0)
- return ret;
-
- return do_statahead_enter(dir, dentryp, only_unplug);
+ return true;
}
/* llite ioctl register support routine */
@@ -1213,7 +1310,7 @@ static inline void ll_set_lock_data(struct obd_export *exp, struct inode *inode,
CDEBUG(D_DLMTRACE, "setting l_data to inode "DFID"%p for remote lock %#llx\n",
PFID(ll_inode2fid(inode)), inode,
handle.cookie);
- md_set_lock_data(exp, &handle.cookie, inode, NULL);
+ md_set_lock_data(exp, &handle, inode, NULL);
}
handle.cookie = it->it_lock_handle;
@@ -1221,8 +1318,7 @@ static inline void ll_set_lock_data(struct obd_export *exp, struct inode *inode,
CDEBUG(D_DLMTRACE, "setting l_data to inode "DFID"%p for lock %#llx\n",
PFID(ll_inode2fid(inode)), inode, handle.cookie);
- md_set_lock_data(exp, &handle.cookie, inode,
- &it->it_lock_bits);
+ md_set_lock_data(exp, &handle, inode, &it->it_lock_bits);
it->it_lock_set = 1;
}
@@ -1295,6 +1391,8 @@ void ll_xattr_fini(void);
int ll_page_sync_io(const struct lu_env *env, struct cl_io *io,
struct cl_page *page, enum cl_req_type crt);
+int ll_getparent(struct file *file, struct getparent __user *arg);
+
/* lcommon_cl.c */
int cl_setattr_ost(struct inode *inode, const struct iattr *attr);
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 546063e728db..6bb41b09172e 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -41,7 +41,7 @@
#include <linux/types.h>
#include <linux/mm.h>
-#include "../include/lustre_lite.h"
+#include "../include/lustre/lustre_ioctl.h"
#include "../include/lustre_ha.h"
#include "../include/lustre_dlm.h"
#include "../include/lprocfs_status.h"
@@ -115,9 +115,16 @@ static struct ll_sb_info *ll_init_sbi(struct super_block *sb)
sbi->ll_sa_max = LL_SA_RPC_DEF;
atomic_set(&sbi->ll_sa_total, 0);
atomic_set(&sbi->ll_sa_wrong, 0);
+ atomic_set(&sbi->ll_sa_running, 0);
atomic_set(&sbi->ll_agl_total, 0);
sbi->ll_flags |= LL_SBI_AGL_ENABLED;
+ /* root squash */
+ sbi->ll_squash.rsi_uid = 0;
+ sbi->ll_squash.rsi_gid = 0;
+ INIT_LIST_HEAD(&sbi->ll_squash.rsi_nosquash_nids);
+ init_rwsem(&sbi->ll_squash.rsi_sem);
+
sbi->ll_sb = sb;
return sbi;
@@ -128,6 +135,8 @@ static void ll_free_sbi(struct super_block *sb)
struct ll_sb_info *sbi = ll_s2sbi(sb);
if (sbi->ll_cache) {
+ if (!list_empty(&sbi->ll_squash.rsi_nosquash_nids))
+ cfs_free_nidlist(&sbi->ll_squash.rsi_nosquash_nids);
cl_cache_decref(sbi->ll_cache);
sbi->ll_cache = NULL;
}
@@ -180,7 +189,9 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
OBD_CONNECT_PINGLESS |
OBD_CONNECT_MAX_EASIZE |
OBD_CONNECT_FLOCK_DEAD |
- OBD_CONNECT_DISP_STRIPE;
+ OBD_CONNECT_DISP_STRIPE | OBD_CONNECT_LFSCK |
+ OBD_CONNECT_OPEN_BY_FID |
+ OBD_CONNECT_DIR_STRIPE;
if (sbi->ll_flags & LL_SBI_SOM_PREVIEW)
data->ocd_connect_flags |= OBD_CONNECT_SOM;
@@ -310,9 +321,9 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
sbi->ll_flags |= LL_SBI_64BIT_HASH;
if (data->ocd_connect_flags & OBD_CONNECT_BRW_SIZE)
- sbi->ll_md_brw_size = data->ocd_brw_size;
+ sbi->ll_md_brw_pages = data->ocd_brw_size >> PAGE_SHIFT;
else
- sbi->ll_md_brw_size = PAGE_SIZE;
+ sbi->ll_md_brw_pages = 1;
if (data->ocd_connect_flags & OBD_CONNECT_LAYOUTLOCK)
sbi->ll_flags |= LL_SBI_LAYOUT_LOCK;
@@ -418,6 +429,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
CDEBUG(D_SUPER, "rootfid "DFID"\n", PFID(&sbi->ll_root_fid));
sb->s_op = &lustre_super_operations;
+ sb->s_xattr = ll_xattr_handlers;
#if THREAD_SIZE >= 8192 /*b=17630*/
sb->s_export_op = &lustre_export_operations;
#endif
@@ -462,7 +474,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
md_free_lustre_md(sbi->ll_md_exp, &lmd);
ptlrpc_req_finished(request);
- if (!(root)) {
+ if (IS_ERR(root)) {
if (lmd.lsm)
obd_free_memmd(sbi->ll_dt_exp, &lmd.lsm);
#ifdef CONFIG_FS_POSIX_ACL
@@ -486,11 +498,21 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
err = obd_set_info_async(NULL, sbi->ll_dt_exp, sizeof(KEY_CHECKSUM),
KEY_CHECKSUM, sizeof(checksum), &checksum,
NULL);
+ if (err) {
+ CERROR("%s: Set checksum failed: rc = %d\n",
+ sbi->ll_dt_exp->exp_obd->obd_name, err);
+ goto out_root;
+ }
cl_sb_init(sb);
err = obd_set_info_async(NULL, sbi->ll_dt_exp, sizeof(KEY_CACHE_SET),
KEY_CACHE_SET, sizeof(*sbi->ll_cache),
sbi->ll_cache, NULL);
+ if (err) {
+ CERROR("%s: Set cache_set failed: rc = %d\n",
+ sbi->ll_dt_exp->exp_obd->obd_name, err);
+ goto out_root;
+ }
sb->s_root = d_make_root(root);
if (!sb->s_root) {
@@ -560,6 +582,17 @@ int ll_get_max_mdsize(struct ll_sb_info *sbi, int *lmmsize)
return rc;
}
+/**
+ * Get the value of the default_easize parameter.
+ *
+ * \see client_obd::cl_default_mds_easize
+ *
+ * \param[in] sbi superblock info for this filesystem
+ * \param[out] lmmsize pointer to storage location for value
+ *
+ * \retval 0 on success
+ * \retval negative negated errno on failure
+ */
int ll_get_default_mdsize(struct ll_sb_info *sbi, int *lmmsize)
{
int size, rc;
@@ -573,6 +606,29 @@ int ll_get_default_mdsize(struct ll_sb_info *sbi, int *lmmsize)
return rc;
}
+/**
+ * Set the default_easize parameter to the given value.
+ *
+ * \see client_obd::cl_default_mds_easize
+ *
+ * \param[in] sbi superblock info for this filesystem
+ * \param[in] lmmsize the size to set
+ *
+ * \retval 0 on success
+ * \retval negative negated errno on failure
+ */
+int ll_set_default_mdsize(struct ll_sb_info *sbi, int lmmsize)
+{
+ if (lmmsize < sizeof(struct lov_mds_md) ||
+ lmmsize > OBD_MAX_DEFAULT_EA_SIZE)
+ return -EINVAL;
+
+ return obd_set_info_async(NULL, sbi->ll_md_exp,
+ sizeof(KEY_DEFAULT_EASIZE),
+ KEY_DEFAULT_EASIZE,
+ sizeof(int), &lmmsize, NULL);
+}
+
static void client_common_put_super(struct super_block *sb)
{
struct ll_sb_info *sbi = ll_s2sbi(sb);
@@ -608,6 +664,12 @@ void ll_kill_super(struct super_block *sb)
if (sbi) {
sb->s_dev = sbi->ll_sdev_orig;
sbi->ll_umounting = 1;
+
+ /* wait running statahead threads to quit */
+ while (atomic_read(&sbi->ll_sa_running) > 0) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(msecs_to_jiffies(MSEC_PER_SEC >> 3));
+ }
}
}
@@ -647,7 +709,8 @@ static int ll_options(char *options, int *flags)
*flags |= tmp;
goto next;
}
- tmp = ll_set_opt("noflock", s1, LL_SBI_FLOCK|LL_SBI_LOCALFLOCK);
+ tmp = ll_set_opt("noflock", s1,
+ LL_SBI_FLOCK | LL_SBI_LOCALFLOCK);
if (tmp) {
*flags &= ~tmp;
goto next;
@@ -772,11 +835,13 @@ void ll_lli_init(struct ll_inode_info *lli)
lli->lli_sai = NULL;
spin_lock_init(&lli->lli_sa_lock);
lli->lli_opendir_pid = 0;
+ lli->lli_sa_enabled = 0;
+ lli->lli_def_stripe_offset = -1;
} else {
mutex_init(&lli->lli_size_mutex);
lli->lli_symlink_name = NULL;
init_rwsem(&lli->lli_trunc_sem);
- mutex_init(&lli->lli_write_mutex);
+ range_lock_tree_init(&lli->lli_write_tree);
init_rwsem(&lli->lli_glimpse_sem);
lli->lli_glimpse_time = 0;
INIT_LIST_HEAD(&lli->lli_agl_list);
@@ -896,7 +961,8 @@ void ll_put_super(struct super_block *sb)
struct lustre_sb_info *lsi = s2lsi(sb);
struct ll_sb_info *sbi = ll_s2sbi(sb);
char *profilenm = get_profile_name(sb);
- int ccc_count, next, force = 1, rc = 0;
+ int next, force = 1, rc = 0;
+ long ccc_count;
CDEBUG(D_VFSTRACE, "VFS Op: sb %p - %s\n", sb, profilenm);
@@ -917,13 +983,13 @@ void ll_put_super(struct super_block *sb)
struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
rc = l_wait_event(sbi->ll_cache->ccc_unstable_waitq,
- !atomic_read(&sbi->ll_cache->ccc_unstable_nr),
+ !atomic_long_read(&sbi->ll_cache->ccc_unstable_nr),
&lwi);
}
- ccc_count = atomic_read(&sbi->ll_cache->ccc_unstable_nr);
+ ccc_count = atomic_long_read(&sbi->ll_cache->ccc_unstable_nr);
if (!force && rc != -EINTR)
- LASSERTF(!ccc_count, "count: %i\n", ccc_count);
+ LASSERTF(!ccc_count, "count: %li\n", ccc_count);
/* We need to set force before the lov_disconnect in
* lustre_common_put_super, since l_d cleans up osc's as well.
@@ -991,6 +1057,206 @@ struct inode *ll_inode_from_resource_lock(struct ldlm_lock *lock)
return inode;
}
+static void ll_dir_clear_lsm_md(struct inode *inode)
+{
+ struct ll_inode_info *lli = ll_i2info(inode);
+
+ LASSERT(S_ISDIR(inode->i_mode));
+
+ if (lli->lli_lsm_md) {
+ lmv_free_memmd(lli->lli_lsm_md);
+ lli->lli_lsm_md = NULL;
+ }
+}
+
+static struct inode *ll_iget_anon_dir(struct super_block *sb,
+ const struct lu_fid *fid,
+ struct lustre_md *md)
+{
+ struct ll_sb_info *sbi = ll_s2sbi(sb);
+ struct mdt_body *body = md->body;
+ struct inode *inode;
+ ino_t ino;
+
+ ino = cl_fid_build_ino(fid, sbi->ll_flags & LL_SBI_32BIT_API);
+ inode = iget_locked(sb, ino);
+ if (!inode) {
+ CERROR("%s: failed get simple inode "DFID": rc = -ENOENT\n",
+ ll_get_fsname(sb, NULL, 0), PFID(fid));
+ return ERR_PTR(-ENOENT);
+ }
+
+ if (inode->i_state & I_NEW) {
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct lmv_stripe_md *lsm = md->lmv;
+
+ inode->i_mode = (inode->i_mode & ~S_IFMT) |
+ (body->mbo_mode & S_IFMT);
+ LASSERTF(S_ISDIR(inode->i_mode), "Not slave inode "DFID"\n",
+ PFID(fid));
+
+ LTIME_S(inode->i_mtime) = 0;
+ LTIME_S(inode->i_atime) = 0;
+ LTIME_S(inode->i_ctime) = 0;
+ inode->i_rdev = 0;
+
+ inode->i_op = &ll_dir_inode_operations;
+ inode->i_fop = &ll_dir_operations;
+ lli->lli_fid = *fid;
+ ll_lli_init(lli);
+
+ LASSERT(lsm);
+ /* master object FID */
+ lli->lli_pfid = body->mbo_fid1;
+ CDEBUG(D_INODE, "lli %p slave "DFID" master "DFID"\n",
+ lli, PFID(fid), PFID(&lli->lli_pfid));
+ unlock_new_inode(inode);
+ }
+
+ return inode;
+}
+
+static int ll_init_lsm_md(struct inode *inode, struct lustre_md *md)
+{
+ struct lmv_stripe_md *lsm = md->lmv;
+ struct lu_fid *fid;
+ int i;
+
+ LASSERT(lsm);
+ /*
+ * XXX sigh, this lsm_root initialization should be in
+ * LMV layer, but it needs ll_iget right now, so we
+ * put this here right now.
+ */
+ for (i = 0; i < lsm->lsm_md_stripe_count; i++) {
+ fid = &lsm->lsm_md_oinfo[i].lmo_fid;
+ LASSERT(!lsm->lsm_md_oinfo[i].lmo_root);
+ /* Unfortunately ll_iget will call ll_update_inode,
+ * where the initialization of slave inode is slightly
+ * different, so it reset lsm_md to NULL to avoid
+ * initializing lsm for slave inode.
+ */
+ /* For migrating inode, master stripe and master object will
+ * be same, so we only need assign this inode
+ */
+ if (lsm->lsm_md_hash_type & LMV_HASH_FLAG_MIGRATION && !i)
+ lsm->lsm_md_oinfo[i].lmo_root = inode;
+ else
+ lsm->lsm_md_oinfo[i].lmo_root =
+ ll_iget_anon_dir(inode->i_sb, fid, md);
+ if (IS_ERR(lsm->lsm_md_oinfo[i].lmo_root)) {
+ int rc = PTR_ERR(lsm->lsm_md_oinfo[i].lmo_root);
+
+ lsm->lsm_md_oinfo[i].lmo_root = NULL;
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+static inline int lli_lsm_md_eq(const struct lmv_stripe_md *lsm_md1,
+ const struct lmv_stripe_md *lsm_md2)
+{
+ return lsm_md1->lsm_md_magic == lsm_md2->lsm_md_magic &&
+ lsm_md1->lsm_md_stripe_count == lsm_md2->lsm_md_stripe_count &&
+ lsm_md1->lsm_md_master_mdt_index ==
+ lsm_md2->lsm_md_master_mdt_index &&
+ lsm_md1->lsm_md_hash_type == lsm_md2->lsm_md_hash_type &&
+ lsm_md1->lsm_md_layout_version ==
+ lsm_md2->lsm_md_layout_version &&
+ !strcmp(lsm_md1->lsm_md_pool_name,
+ lsm_md2->lsm_md_pool_name);
+}
+
+static int ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
+{
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct lmv_stripe_md *lsm = md->lmv;
+ int rc;
+
+ LASSERT(S_ISDIR(inode->i_mode));
+ CDEBUG(D_INODE, "update lsm %p of "DFID"\n", lli->lli_lsm_md,
+ PFID(ll_inode2fid(inode)));
+
+ /* no striped information from request. */
+ if (!lsm) {
+ if (!lli->lli_lsm_md) {
+ return 0;
+ } else if (lli->lli_lsm_md->lsm_md_hash_type &
+ LMV_HASH_FLAG_MIGRATION) {
+ /*
+ * migration is done, the temporay MIGRATE layout has
+ * been removed
+ */
+ CDEBUG(D_INODE, DFID" finish migration.\n",
+ PFID(ll_inode2fid(inode)));
+ lmv_free_memmd(lli->lli_lsm_md);
+ lli->lli_lsm_md = NULL;
+ return 0;
+ } else {
+ /*
+ * The lustre_md from req does not include stripeEA,
+ * see ll_md_setattr
+ */
+ return 0;
+ }
+ }
+
+ /* set the directory layout */
+ if (!lli->lli_lsm_md) {
+ rc = ll_init_lsm_md(inode, md);
+ if (rc)
+ return rc;
+
+ lli->lli_lsm_md = lsm;
+ /*
+ * set lsm_md to NULL, so the following free lustre_md
+ * will not free this lsm
+ */
+ md->lmv = NULL;
+ CDEBUG(D_INODE, "Set lsm %p magic %x to "DFID"\n", lsm,
+ lsm->lsm_md_magic, PFID(ll_inode2fid(inode)));
+ return 0;
+ }
+
+ /* Compare the old and new stripe information */
+ if (!lsm_md_eq(lli->lli_lsm_md, lsm)) {
+ struct lmv_stripe_md *old_lsm = lli->lli_lsm_md;
+ int idx;
+
+ CERROR("%s: inode "DFID"(%p)'s lmv layout mismatch (%p)/(%p) magic:0x%x/0x%x stripe count: %d/%d master_mdt: %d/%d hash_type:0x%x/0x%x layout: 0x%x/0x%x pool:%s/%s\n",
+ ll_get_fsname(inode->i_sb, NULL, 0), PFID(&lli->lli_fid),
+ inode, lsm, old_lsm,
+ lsm->lsm_md_magic, old_lsm->lsm_md_magic,
+ lsm->lsm_md_stripe_count,
+ old_lsm->lsm_md_stripe_count,
+ lsm->lsm_md_master_mdt_index,
+ old_lsm->lsm_md_master_mdt_index,
+ lsm->lsm_md_hash_type, old_lsm->lsm_md_hash_type,
+ lsm->lsm_md_layout_version,
+ old_lsm->lsm_md_layout_version,
+ lsm->lsm_md_pool_name,
+ old_lsm->lsm_md_pool_name);
+
+ for (idx = 0; idx < old_lsm->lsm_md_stripe_count; idx++) {
+ CERROR("%s: sub FIDs in old lsm idx %d, old: "DFID"\n",
+ ll_get_fsname(inode->i_sb, NULL, 0), idx,
+ PFID(&old_lsm->lsm_md_oinfo[idx].lmo_fid));
+ }
+
+ for (idx = 0; idx < lsm->lsm_md_stripe_count; idx++) {
+ CERROR("%s: sub FIDs in new lsm idx %d, new: "DFID"\n",
+ ll_get_fsname(inode->i_sb, NULL, 0), idx,
+ PFID(&lsm->lsm_md_oinfo[idx].lmo_fid));
+ }
+
+ return -EIO;
+ }
+
+ return 0;
+}
+
void ll_clear_inode(struct inode *inode)
{
struct ll_inode_info *lli = ll_i2info(inode);
@@ -1031,14 +1297,15 @@ void ll_clear_inode(struct inode *inode)
#ifdef CONFIG_FS_POSIX_ACL
if (lli->lli_posix_acl) {
- LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) == 1);
posix_acl_release(lli->lli_posix_acl);
lli->lli_posix_acl = NULL;
}
#endif
lli->lli_inode_magic = LLI_INODE_DEAD;
- if (!S_ISDIR(inode->i_mode))
+ if (S_ISDIR(inode->i_mode))
+ ll_dir_clear_lsm_md(inode);
+ if (S_ISREG(inode->i_mode) && !is_bad_inode(inode))
LASSERT(list_empty(&lli->lli_agl_list));
/*
@@ -1103,10 +1370,10 @@ static int ll_md_setattr(struct dentry *dentry, struct md_op_data *op_data,
op_data->op_attr.ia_valid = ia_valid;
/* Extract epoch data if obtained. */
- op_data->op_handle = md.body->handle;
- op_data->op_ioepoch = md.body->ioepoch;
+ op_data->op_handle = md.body->mbo_handle;
+ op_data->op_ioepoch = md.body->mbo_ioepoch;
- ll_update_inode(inode, &md);
+ rc = ll_update_inode(inode, &md);
ptlrpc_req_finished(request);
return rc;
@@ -1138,8 +1405,8 @@ static int ll_setattr_done_writing(struct inode *inode,
rc = ll_som_update(inode, op_data);
else if (rc) {
CERROR("%s: inode "DFID" mdc truncate failed: rc = %d\n",
- ll_i2sbi(inode)->ll_md_exp->exp_obd->obd_name,
- PFID(ll_inode2fid(inode)), rc);
+ ll_i2sbi(inode)->ll_md_exp->exp_obd->obd_name,
+ PFID(ll_inode2fid(inode)), rc);
}
return rc;
}
@@ -1331,14 +1598,14 @@ int ll_setattr(struct dentry *de, struct iattr *attr)
{
int mode = d_inode(de)->i_mode;
- if ((attr->ia_valid & (ATTR_CTIME|ATTR_SIZE|ATTR_MODE)) ==
- (ATTR_CTIME|ATTR_SIZE|ATTR_MODE))
+ if ((attr->ia_valid & (ATTR_CTIME | ATTR_SIZE | ATTR_MODE)) ==
+ (ATTR_CTIME | ATTR_SIZE | ATTR_MODE))
attr->ia_valid |= MDS_OPEN_OWNEROVERRIDE;
- if (((attr->ia_valid & (ATTR_MODE|ATTR_FORCE|ATTR_SIZE)) ==
- (ATTR_SIZE|ATTR_MODE)) &&
+ if (((attr->ia_valid & (ATTR_MODE | ATTR_FORCE | ATTR_SIZE)) ==
+ (ATTR_SIZE | ATTR_MODE)) &&
(((mode & S_ISUID) && !(attr->ia_mode & S_ISUID)) ||
- (((mode & (S_ISGID|S_IXGRP)) == (S_ISGID|S_IXGRP)) &&
+ (((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) &&
!(attr->ia_mode & S_ISGID))))
attr->ia_valid |= ATTR_FORCE;
@@ -1349,7 +1616,7 @@ int ll_setattr(struct dentry *de, struct iattr *attr)
attr->ia_valid |= ATTR_KILL_SUID;
if ((attr->ia_valid & ATTR_MODE) &&
- ((mode & (S_ISGID|S_IXGRP)) == (S_ISGID|S_IXGRP)) &&
+ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) &&
!(attr->ia_mode & S_ISGID) &&
!(attr->ia_valid & ATTR_KILL_SGID))
attr->ia_valid |= ATTR_KILL_SGID;
@@ -1465,14 +1732,14 @@ void ll_inode_size_unlock(struct inode *inode)
mutex_unlock(&lli->lli_size_mutex);
}
-void ll_update_inode(struct inode *inode, struct lustre_md *md)
+int ll_update_inode(struct inode *inode, struct lustre_md *md)
{
struct ll_inode_info *lli = ll_i2info(inode);
struct mdt_body *body = md->body;
struct lov_stripe_md *lsm = md->lsm;
struct ll_sb_info *sbi = ll_i2sbi(inode);
- LASSERT((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0));
+ LASSERT((lsm != NULL) == ((body->mbo_valid & OBD_MD_FLEASIZE) != 0));
if (lsm) {
if (!lli->lli_has_smd &&
!(sbi->ll_flags & LL_SBI_LAYOUT_LOCK))
@@ -1483,8 +1750,16 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
lli->lli_maxbytes = MAX_LFS_FILESIZE;
}
+ if (S_ISDIR(inode->i_mode)) {
+ int rc;
+
+ rc = ll_update_lsm_md(inode, md);
+ if (rc)
+ return rc;
+ }
+
#ifdef CONFIG_FS_POSIX_ACL
- if (body->valid & OBD_MD_FLACL) {
+ if (body->mbo_valid & OBD_MD_FLACL) {
spin_lock(&lli->lli_lock);
if (lli->lli_posix_acl)
posix_acl_release(lli->lli_posix_acl);
@@ -1492,65 +1767,67 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
spin_unlock(&lli->lli_lock);
}
#endif
- inode->i_ino = cl_fid_build_ino(&body->fid1,
+ inode->i_ino = cl_fid_build_ino(&body->mbo_fid1,
sbi->ll_flags & LL_SBI_32BIT_API);
- inode->i_generation = cl_fid_build_gen(&body->fid1);
+ inode->i_generation = cl_fid_build_gen(&body->mbo_fid1);
- if (body->valid & OBD_MD_FLATIME) {
- if (body->atime > LTIME_S(inode->i_atime))
- LTIME_S(inode->i_atime) = body->atime;
- lli->lli_atime = body->atime;
+ if (body->mbo_valid & OBD_MD_FLATIME) {
+ if (body->mbo_atime > LTIME_S(inode->i_atime))
+ LTIME_S(inode->i_atime) = body->mbo_atime;
+ lli->lli_atime = body->mbo_atime;
}
- if (body->valid & OBD_MD_FLMTIME) {
- if (body->mtime > LTIME_S(inode->i_mtime)) {
+ if (body->mbo_valid & OBD_MD_FLMTIME) {
+ if (body->mbo_mtime > LTIME_S(inode->i_mtime)) {
CDEBUG(D_INODE, "setting ino %lu mtime from %lu to %llu\n",
inode->i_ino, LTIME_S(inode->i_mtime),
- body->mtime);
- LTIME_S(inode->i_mtime) = body->mtime;
+ body->mbo_mtime);
+ LTIME_S(inode->i_mtime) = body->mbo_mtime;
}
- lli->lli_mtime = body->mtime;
- }
- if (body->valid & OBD_MD_FLCTIME) {
- if (body->ctime > LTIME_S(inode->i_ctime))
- LTIME_S(inode->i_ctime) = body->ctime;
- lli->lli_ctime = body->ctime;
- }
- if (body->valid & OBD_MD_FLMODE)
- inode->i_mode = (inode->i_mode & S_IFMT)|(body->mode & ~S_IFMT);
- if (body->valid & OBD_MD_FLTYPE)
- inode->i_mode = (inode->i_mode & ~S_IFMT)|(body->mode & S_IFMT);
+ lli->lli_mtime = body->mbo_mtime;
+ }
+ if (body->mbo_valid & OBD_MD_FLCTIME) {
+ if (body->mbo_ctime > LTIME_S(inode->i_ctime))
+ LTIME_S(inode->i_ctime) = body->mbo_ctime;
+ lli->lli_ctime = body->mbo_ctime;
+ }
+ if (body->mbo_valid & OBD_MD_FLMODE)
+ inode->i_mode = (inode->i_mode & S_IFMT) |
+ (body->mbo_mode & ~S_IFMT);
+ if (body->mbo_valid & OBD_MD_FLTYPE)
+ inode->i_mode = (inode->i_mode & ~S_IFMT) |
+ (body->mbo_mode & S_IFMT);
LASSERT(inode->i_mode != 0);
if (S_ISREG(inode->i_mode))
inode->i_blkbits = min(PTLRPC_MAX_BRW_BITS + 1,
LL_MAX_BLKSIZE_BITS);
else
inode->i_blkbits = inode->i_sb->s_blocksize_bits;
- if (body->valid & OBD_MD_FLUID)
- inode->i_uid = make_kuid(&init_user_ns, body->uid);
- if (body->valid & OBD_MD_FLGID)
- inode->i_gid = make_kgid(&init_user_ns, body->gid);
- if (body->valid & OBD_MD_FLFLAGS)
- inode->i_flags = ll_ext_to_inode_flags(body->flags);
- if (body->valid & OBD_MD_FLNLINK)
- set_nlink(inode, body->nlink);
- if (body->valid & OBD_MD_FLRDEV)
- inode->i_rdev = old_decode_dev(body->rdev);
-
- if (body->valid & OBD_MD_FLID) {
+ if (body->mbo_valid & OBD_MD_FLUID)
+ inode->i_uid = make_kuid(&init_user_ns, body->mbo_uid);
+ if (body->mbo_valid & OBD_MD_FLGID)
+ inode->i_gid = make_kgid(&init_user_ns, body->mbo_gid);
+ if (body->mbo_valid & OBD_MD_FLFLAGS)
+ inode->i_flags = ll_ext_to_inode_flags(body->mbo_flags);
+ if (body->mbo_valid & OBD_MD_FLNLINK)
+ set_nlink(inode, body->mbo_nlink);
+ if (body->mbo_valid & OBD_MD_FLRDEV)
+ inode->i_rdev = old_decode_dev(body->mbo_rdev);
+
+ if (body->mbo_valid & OBD_MD_FLID) {
/* FID shouldn't be changed! */
if (fid_is_sane(&lli->lli_fid)) {
- LASSERTF(lu_fid_eq(&lli->lli_fid, &body->fid1),
+ LASSERTF(lu_fid_eq(&lli->lli_fid, &body->mbo_fid1),
"Trying to change FID "DFID" to the "DFID", inode "DFID"(%p)\n",
- PFID(&lli->lli_fid), PFID(&body->fid1),
+ PFID(&lli->lli_fid), PFID(&body->mbo_fid1),
PFID(ll_inode2fid(inode)), inode);
} else {
- lli->lli_fid = body->fid1;
+ lli->lli_fid = body->mbo_fid1;
}
}
LASSERT(fid_seq(&lli->lli_fid) != 0);
- if (body->valid & OBD_MD_FLSIZE) {
+ if (body->mbo_valid & OBD_MD_FLSIZE) {
if (exp_connect_som(ll_i2mdexp(inode)) &&
S_ISREG(inode->i_mode)) {
struct lustre_handle lockh;
@@ -1577,7 +1854,7 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
/* Use old size assignment to avoid
* deadlock bz14138 & bz14326
*/
- i_size_write(inode, body->size);
+ i_size_write(inode, body->mbo_size);
spin_lock(&lli->lli_lock);
lli->lli_flags |= LLIF_MDS_SIZE_LOCK;
spin_unlock(&lli->lli_lock);
@@ -1588,26 +1865,29 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
/* Use old size assignment to avoid
* deadlock bz14138 & bz14326
*/
- i_size_write(inode, body->size);
+ i_size_write(inode, body->mbo_size);
CDEBUG(D_VFSTRACE, "inode=%lu, updating i_size %llu\n",
- inode->i_ino, (unsigned long long)body->size);
+ inode->i_ino, (unsigned long long)body->mbo_size);
}
- if (body->valid & OBD_MD_FLBLOCKS)
- inode->i_blocks = body->blocks;
+ if (body->mbo_valid & OBD_MD_FLBLOCKS)
+ inode->i_blocks = body->mbo_blocks;
}
- if (body->valid & OBD_MD_TSTATE) {
- if (body->t_state & MS_RESTORE)
+ if (body->mbo_valid & OBD_MD_TSTATE) {
+ if (body->mbo_t_state & MS_RESTORE)
lli->lli_flags |= LLIF_FILE_RESTORING;
}
+
+ return 0;
}
-void ll_read_inode2(struct inode *inode, void *opaque)
+int ll_read_inode2(struct inode *inode, void *opaque)
{
struct lustre_md *md = opaque;
struct ll_inode_info *lli = ll_i2info(inode);
+ int rc;
CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
PFID(&lli->lli_fid), inode);
@@ -1623,7 +1903,9 @@ void ll_read_inode2(struct inode *inode, void *opaque)
LTIME_S(inode->i_atime) = 0;
LTIME_S(inode->i_ctime) = 0;
inode->i_rdev = 0;
- ll_update_inode(inode, md);
+ rc = ll_update_inode(inode, md);
+ if (rc)
+ return rc;
/* OIDEBUG(inode); */
@@ -1644,6 +1926,8 @@ void ll_read_inode2(struct inode *inode, void *opaque)
init_special_inode(inode, inode->i_mode,
inode->i_rdev);
}
+
+ return 0;
}
void ll_delete_inode(struct inode *inode)
@@ -1655,20 +1939,13 @@ void ll_delete_inode(struct inode *inode)
* osc_extent implementation at LU-1030.
*/
cl_sync_file_range(inode, 0, OBD_OBJECT_EOF,
- CL_FSYNC_DISCARD, 1);
+ CL_FSYNC_LOCAL, 1);
truncate_inode_pages_final(&inode->i_data);
- /* Workaround for LU-118 */
- if (inode->i_data.nrpages) {
- spin_lock_irq(&inode->i_data.tree_lock);
- spin_unlock_irq(&inode->i_data.tree_lock);
- LASSERTF(inode->i_data.nrpages == 0,
- "inode="DFID"(%p) nrpages=%lu, see http://jira.whamcloud.com/browse/LU-118\n",
- PFID(ll_inode2fid(inode)), inode,
- inode->i_data.nrpages);
- }
- /* Workaround end */
+ LASSERTF(!inode->i_data.nrpages,
+ "inode=" DFID "(%p) nrpages=%lu, see http://jira.whamcloud.com/browse/LU-118\n",
+ PFID(ll_inode2fid(inode)), inode, inode->i_data.nrpages);
ll_clear_inode(inode);
clear_inode(inode);
@@ -1704,7 +1981,7 @@ int ll_iocontrol(struct inode *inode, struct file *file,
body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
- flags = body->flags;
+ flags = body->mbo_flags;
ptlrpc_req_finished(req);
@@ -1886,9 +2163,9 @@ void ll_open_cleanup(struct super_block *sb, struct ptlrpc_request *open_req)
if (!op_data)
return;
- op_data->op_fid1 = body->fid1;
- op_data->op_ioepoch = body->ioepoch;
- op_data->op_handle = body->handle;
+ op_data->op_fid1 = body->mbo_fid1;
+ op_data->op_ioepoch = body->mbo_ioepoch;
+ op_data->op_handle = body->mbo_handle;
op_data->op_mod_time = get_seconds();
md_close(exp, op_data, NULL, &close_req);
ptlrpc_req_finished(close_req);
@@ -1910,7 +2187,9 @@ int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req,
goto cleanup;
if (*inode) {
- ll_update_inode(*inode, &md);
+ rc = ll_update_inode(*inode, &md);
+ if (rc)
+ goto out;
} else {
LASSERT(sb);
@@ -1918,18 +2197,18 @@ int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req,
* At this point server returns to client's same fid as client
* generated for creating. So using ->fid1 is okay here.
*/
- if (!fid_is_sane(&md.body->fid1)) {
+ if (!fid_is_sane(&md.body->mbo_fid1)) {
CERROR("%s: Fid is insane " DFID "\n",
ll_get_fsname(sb, NULL, 0),
- PFID(&md.body->fid1));
+ PFID(&md.body->mbo_fid1));
rc = -EINVAL;
goto out;
}
- *inode = ll_iget(sb, cl_fid_build_ino(&md.body->fid1,
+ *inode = ll_iget(sb, cl_fid_build_ino(&md.body->mbo_fid1,
sbi->ll_flags & LL_SBI_32BIT_API),
&md);
- if (!*inode) {
+ if (IS_ERR(*inode)) {
#ifdef CONFIG_FS_POSIX_ACL
if (md.posix_acl) {
posix_acl_release(md.posix_acl);
@@ -2075,11 +2354,20 @@ int ll_process_config(struct lustre_cfg *lcfg)
/* this function prepares md_op_data hint for passing ot down to MD stack. */
struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
struct inode *i1, struct inode *i2,
- const char *name, int namelen,
- int mode, __u32 opc, void *data)
+ const char *name, size_t namelen,
+ u32 mode, __u32 opc, void *data)
{
- if (namelen > ll_i2sbi(i1)->ll_namelen)
- return ERR_PTR(-ENAMETOOLONG);
+ if (!name) {
+ /* Do not reuse namelen for something else. */
+ if (namelen)
+ return ERR_PTR(-EINVAL);
+ } else {
+ if (namelen > ll_i2sbi(i1)->ll_namelen)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ if (!lu_name_is_valid_2(name, namelen))
+ return ERR_PTR(-EINVAL);
+ }
if (!op_data)
op_data = kzalloc(sizeof(*op_data), GFP_NOFS);
@@ -2089,11 +2377,26 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
ll_i2gids(op_data->op_suppgids, i1, i2);
op_data->op_fid1 = *ll_inode2fid(i1);
+ op_data->op_default_stripe_offset = -1;
+ if (S_ISDIR(i1->i_mode)) {
+ op_data->op_mea1 = ll_i2info(i1)->lli_lsm_md;
+ op_data->op_default_stripe_offset =
+ ll_i2info(i1)->lli_def_stripe_offset;
+ }
- if (i2)
+ if (i2) {
op_data->op_fid2 = *ll_inode2fid(i2);
- else
+ if (S_ISDIR(i2->i_mode))
+ op_data->op_mea2 = ll_i2info(i2)->lli_lsm_md;
+ } else {
fid_zero(&op_data->op_fid2);
+ }
+
+ if (ll_i2sbi(i1)->ll_flags & LL_SBI_64BIT_HASH)
+ op_data->op_cli_flags |= CLI_HASH64;
+
+ if (ll_need_32bit_api(ll_i2sbi(i1)))
+ op_data->op_cli_flags |= CLI_API32;
op_data->op_name = name;
op_data->op_namelen = namelen;
@@ -2105,26 +2408,12 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
op_data->op_bias = 0;
op_data->op_cli_flags = 0;
if ((opc == LUSTRE_OPC_CREATE) && name &&
- filename_is_volatile(name, namelen, NULL))
+ filename_is_volatile(name, namelen, &op_data->op_mds))
op_data->op_bias |= MDS_CREATE_VOLATILE;
- op_data->op_opc = opc;
- op_data->op_mds = 0;
+ else
+ op_data->op_mds = 0;
op_data->op_data = data;
- /* If the file is being opened after mknod() (normally due to NFS)
- * try to use the default stripe data from parent directory for
- * allocating OST objects. Try to pass the parent FID to MDS.
- */
- if (opc == LUSTRE_OPC_CREATE && i1 == i2 && S_ISREG(i2->i_mode) &&
- !ll_i2info(i2)->lli_has_smd) {
- struct ll_inode_info *lli = ll_i2info(i2);
-
- spin_lock(&lli->lli_lock);
- if (likely(!lli->lli_has_smd && !fid_is_zero(&lli->lli_pfid)))
- op_data->op_fid1 = lli->lli_pfid;
- spin_unlock(&lli->lli_lock);
- }
-
/* When called by ll_setattr_raw, file is i1. */
if (ll_i2info(i1)->lli_flags & LLIF_DATA_MODIFIED)
op_data->op_bias |= MDS_DATA_MODIFIED;
@@ -2251,3 +2540,197 @@ void ll_dirty_page_discard_warn(struct page *page, int ioret)
if (buf)
free_page((unsigned long)buf);
}
+
+ssize_t ll_copy_user_md(const struct lov_user_md __user *md,
+ struct lov_user_md **kbuf)
+{
+ struct lov_user_md lum;
+ ssize_t lum_size;
+
+ if (copy_from_user(&lum, md, sizeof(lum))) {
+ lum_size = -EFAULT;
+ goto no_kbuf;
+ }
+
+ lum_size = ll_lov_user_md_size(&lum);
+ if (lum_size < 0)
+ goto no_kbuf;
+
+ *kbuf = kzalloc(lum_size, GFP_NOFS);
+ if (!*kbuf) {
+ lum_size = -ENOMEM;
+ goto no_kbuf;
+ }
+
+ if (copy_from_user(*kbuf, md, lum_size) != 0) {
+ kfree(*kbuf);
+ *kbuf = NULL;
+ lum_size = -EFAULT;
+ }
+no_kbuf:
+ return lum_size;
+}
+
+/*
+ * Compute llite root squash state after a change of root squash
+ * configuration setting or add/remove of a lnet nid
+ */
+void ll_compute_rootsquash_state(struct ll_sb_info *sbi)
+{
+ struct root_squash_info *squash = &sbi->ll_squash;
+ lnet_process_id_t id;
+ bool matched;
+ int i;
+
+ /* Update norootsquash flag */
+ down_write(&squash->rsi_sem);
+ if (list_empty(&squash->rsi_nosquash_nids)) {
+ sbi->ll_flags &= ~LL_SBI_NOROOTSQUASH;
+ } else {
+ /*
+ * Do not apply root squash as soon as one of our NIDs is
+ * in the nosquash_nids list
+ */
+ matched = false;
+ i = 0;
+
+ while (LNetGetId(i++, &id) != -ENOENT) {
+ if (LNET_NETTYP(LNET_NIDNET(id.nid)) == LOLND)
+ continue;
+ if (cfs_match_nid(id.nid, &squash->rsi_nosquash_nids)) {
+ matched = true;
+ break;
+ }
+ }
+ if (matched)
+ sbi->ll_flags |= LL_SBI_NOROOTSQUASH;
+ else
+ sbi->ll_flags &= ~LL_SBI_NOROOTSQUASH;
+ }
+ up_write(&squash->rsi_sem);
+}
+
+/**
+ * Parse linkea content to extract information about a given hardlink
+ *
+ * \param[in] ldata - Initialized linkea data
+ * \param[in] linkno - Link identifier
+ * \param[out] parent_fid - The entry's parent FID
+ * \param[in] size - Entry name destination buffer
+ *
+ * \retval 0 on success
+ * \retval Appropriate negative error code on failure
+ */
+static int ll_linkea_decode(struct linkea_data *ldata, unsigned int linkno,
+ struct lu_fid *parent_fid, struct lu_name *ln)
+{
+ unsigned int idx;
+ int rc;
+
+ rc = linkea_init(ldata);
+ if (rc < 0)
+ return rc;
+
+ if (linkno >= ldata->ld_leh->leh_reccount)
+ /* beyond last link */
+ return -ENODATA;
+
+ linkea_first_entry(ldata);
+ for (idx = 0; ldata->ld_lee; idx++) {
+ linkea_entry_unpack(ldata->ld_lee, &ldata->ld_reclen, ln,
+ parent_fid);
+ if (idx == linkno)
+ break;
+
+ linkea_next_entry(ldata);
+ }
+
+ if (idx < linkno)
+ return -ENODATA;
+
+ return 0;
+}
+
+/**
+ * Get parent FID and name of an identified link. Operation is performed for
+ * a given link number, letting the caller iterate over linkno to list one or
+ * all links of an entry.
+ *
+ * \param[in] file - File descriptor against which to perform the operation
+ * \param[in,out] arg - User-filled structure containing the linkno to operate
+ * on and the available size. It is eventually filled with
+ * the requested information or left untouched on error
+ *
+ * \retval - 0 on success
+ * \retval - Appropriate negative error code on failure
+ */
+int ll_getparent(struct file *file, struct getparent __user *arg)
+{
+ struct inode *inode = file_inode(file);
+ struct linkea_data *ldata;
+ struct lu_fid parent_fid;
+ struct lu_buf buf = {
+ .lb_buf = NULL,
+ .lb_len = 0
+ };
+ struct lu_name ln;
+ u32 name_size;
+ u32 linkno;
+ int rc;
+
+ if (!capable(CFS_CAP_DAC_READ_SEARCH) &&
+ !(ll_i2sbi(inode)->ll_flags & LL_SBI_USER_FID2PATH))
+ return -EPERM;
+
+ if (get_user(name_size, &arg->gp_name_size))
+ return -EFAULT;
+
+ if (get_user(linkno, &arg->gp_linkno))
+ return -EFAULT;
+
+ if (name_size > PATH_MAX)
+ return -EINVAL;
+
+ ldata = kzalloc(sizeof(*ldata), GFP_NOFS);
+ if (!ldata)
+ return -ENOMEM;
+
+ rc = linkea_data_new(ldata, &buf);
+ if (rc < 0)
+ goto ldata_free;
+
+ rc = ll_xattr_list(inode, XATTR_NAME_LINK, XATTR_TRUSTED_T, buf.lb_buf,
+ buf.lb_len, OBD_MD_FLXATTR);
+ if (rc < 0)
+ goto lb_free;
+
+ rc = ll_linkea_decode(ldata, linkno, &parent_fid, &ln);
+ if (rc < 0)
+ goto lb_free;
+
+ if (ln.ln_namelen >= name_size) {
+ rc = -EOVERFLOW;
+ goto lb_free;
+ }
+
+ if (copy_to_user(&arg->gp_fid, &parent_fid, sizeof(arg->gp_fid))) {
+ rc = -EFAULT;
+ goto lb_free;
+ }
+
+ if (copy_to_user(&arg->gp_name, ln.ln_name, ln.ln_namelen)) {
+ rc = -EFAULT;
+ goto lb_free;
+ }
+
+ if (put_user('\0', arg->gp_name + ln.ln_namelen)) {
+ rc = -EFAULT;
+ goto lb_free;
+ }
+
+lb_free:
+ lu_buf_free(&buf);
+ldata_free:
+ kfree(ldata);
+ return rc;
+}
diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c
index 66ee5db5fce8..436691814a5e 100644
--- a/drivers/staging/lustre/lustre/llite/llite_mmap.c
+++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c
@@ -43,9 +43,7 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/lustre_lite.h"
#include "llite_internal.h"
-#include "../include/linux/lustre_compat25.h"
static const struct vm_operations_struct ll_file_vm_ops;
@@ -126,7 +124,7 @@ restart:
fio = &io->u.ci_fault;
fio->ft_index = index;
- fio->ft_executable = vma->vm_flags&VM_EXEC;
+ fio->ft_executable = vma->vm_flags & VM_EXEC;
/*
* disable VM_SEQ_READ and use VM_RAND_READ to make sure that
@@ -134,7 +132,7 @@ restart:
* filemap_nopage. we do our readahead in ll_readpage.
*/
if (ra_flags)
- *ra_flags = vma->vm_flags & (VM_RAND_READ|VM_SEQ_READ);
+ *ra_flags = vma->vm_flags & (VM_RAND_READ | VM_SEQ_READ);
vma->vm_flags &= ~VM_SEQ_READ;
vma->vm_flags |= VM_RAND_READ;
@@ -429,7 +427,6 @@ static void ll_vm_open(struct vm_area_struct *vma)
struct inode *inode = file_inode(vma->vm_file);
struct vvp_object *vob = cl_inode2vvp(inode);
- LASSERT(vma->vm_file);
LASSERT(atomic_read(&vob->vob_mmap_cnt) >= 0);
atomic_inc(&vob->vob_mmap_cnt);
}
@@ -442,7 +439,6 @@ static void ll_vm_close(struct vm_area_struct *vma)
struct inode *inode = file_inode(vma->vm_file);
struct vvp_object *vob = cl_inode2vvp(inode);
- LASSERT(vma->vm_file);
atomic_dec(&vob->vob_mmap_cnt);
LASSERT(atomic_read(&vob->vob_mmap_cnt) >= 0);
}
diff --git a/drivers/staging/lustre/lustre/llite/llite_nfs.c b/drivers/staging/lustre/lustre/llite/llite_nfs.c
index 65972c892731..709230571b4b 100644
--- a/drivers/staging/lustre/lustre/llite/llite_nfs.c
+++ b/drivers/staging/lustre/lustre/llite/llite_nfs.c
@@ -38,7 +38,6 @@
*/
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/lustre_lite.h"
#include "llite_internal.h"
#include <linux/exportfs.h>
@@ -73,11 +72,6 @@ void get_uuid2fsid(const char *name, int len, __kernel_fsid_t *fsid)
fsid->val[1] = key >> 32;
}
-static int ll_nfs_test_inode(struct inode *inode, void *opaque)
-{
- return lu_fid_eq(&ll_i2info(inode)->lli_fid, opaque);
-}
-
struct inode *search_inode_for_lustre(struct super_block *sb,
const struct lu_fid *fid)
{
@@ -92,7 +86,7 @@ struct inode *search_inode_for_lustre(struct super_block *sb,
CDEBUG(D_INFO, "searching inode for:(%lu,"DFID")\n", hash, PFID(fid));
- inode = ilookup5(sb, hash, ll_nfs_test_inode, (void *)fid);
+ inode = ilookup5(sb, hash, ll_test_inode_by_fid, (void *)fid);
if (inode)
return inode;
@@ -153,12 +147,18 @@ ll_iget_for_nfs(struct super_block *sb, struct lu_fid *fid, struct lu_fid *paren
return ERR_PTR(-ESTALE);
}
+ result = d_obtain_alias(inode);
+ if (IS_ERR(result)) {
+ iput(inode);
+ return result;
+ }
+
/**
- * It is an anonymous dentry without OST objects created yet.
- * We have to find the parent to tell MDS how to init lov objects.
+ * In case d_obtain_alias() found a disconnected dentry, always update
+ * lli_pfid to allow later operation (normally open) have parent fid,
+ * which may be used by MDS to create data.
*/
- if (S_ISREG(inode->i_mode) && !ll_i2info(inode)->lli_has_smd &&
- parent && !fid_is_zero(parent)) {
+ if (parent) {
struct ll_inode_info *lli = ll_i2info(inode);
spin_lock(&lli->lli_lock);
@@ -255,6 +255,8 @@ static int ll_get_name(struct dentry *dentry, char *name,
.lgd_fid = ll_i2info(d_inode(child))->lli_fid,
.ctx.actor = ll_nfs_get_name_filldir,
};
+ struct md_op_data *op_data;
+ __u64 pos = 0;
if (!dir || !S_ISDIR(dir->i_mode)) {
rc = -ENOTDIR;
@@ -266,9 +268,18 @@ static int ll_get_name(struct dentry *dentry, char *name,
goto out;
}
+ op_data = ll_prep_md_op_data(NULL, dir, dir, NULL, 0, 0,
+ LUSTRE_OPC_ANY, dir);
+ if (IS_ERR(op_data)) {
+ rc = PTR_ERR(op_data);
+ goto out;
+ }
+
+ op_data->op_max_pages = ll_i2sbi(dir)->ll_md_brw_pages;
inode_lock(dir);
- rc = ll_dir_read(dir, &lgd.ctx);
+ rc = ll_dir_read(dir, &pos, op_data, &lgd.ctx);
inode_unlock(dir);
+ ll_finish_md_op_data(op_data);
if (!rc && !lgd.lgd_found)
rc = -ENOENT;
out:
@@ -297,14 +308,12 @@ static struct dentry *ll_fh_to_parent(struct super_block *sb, struct fid *fid,
return ll_iget_for_nfs(sb, &nfs_fid->lnf_parent, NULL);
}
-static struct dentry *ll_get_parent(struct dentry *dchild)
+int ll_dir_get_parent_fid(struct inode *dir, struct lu_fid *parent_fid)
{
struct ptlrpc_request *req = NULL;
- struct inode *dir = d_inode(dchild);
struct ll_sb_info *sbi;
- struct dentry *result = NULL;
struct mdt_body *body;
- static char dotdot[] = "..";
+ static const char dotdot[] = "..";
struct md_op_data *op_data;
int rc;
int lmmsize;
@@ -319,13 +328,13 @@ static struct dentry *ll_get_parent(struct dentry *dchild)
rc = ll_get_default_mdsize(sbi, &lmmsize);
if (rc != 0)
- return ERR_PTR(rc);
+ return rc;
op_data = ll_prep_md_op_data(NULL, dir, NULL, dotdot,
strlen(dotdot), lmmsize,
LUSTRE_OPC_ANY, NULL);
if (IS_ERR(op_data))
- return (void *)op_data;
+ return PTR_ERR(op_data);
rc = md_getattr_name(sbi->ll_md_exp, op_data, &req);
ll_finish_md_op_data(op_data);
@@ -333,21 +342,36 @@ static struct dentry *ll_get_parent(struct dentry *dchild)
CERROR("%s: failure inode "DFID" get parent: rc = %d\n",
ll_get_fsname(dir->i_sb, NULL, 0),
PFID(ll_inode2fid(dir)), rc);
- return ERR_PTR(rc);
+ return rc;
}
body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
/*
* LU-3952: MDT may lost the FID of its parent, we should not crash
* the NFS server, ll_iget_for_nfs() will handle the error.
*/
- if (body->valid & OBD_MD_FLID) {
+ if (body->mbo_valid & OBD_MD_FLID) {
CDEBUG(D_INFO, "parent for " DFID " is " DFID "\n",
- PFID(ll_inode2fid(dir)), PFID(&body->fid1));
+ PFID(ll_inode2fid(dir)), PFID(&body->mbo_fid1));
+ *parent_fid = body->mbo_fid1;
}
- result = ll_iget_for_nfs(dir->i_sb, &body->fid1, NULL);
ptlrpc_req_finished(req);
- return result;
+ return 0;
+}
+
+static struct dentry *ll_get_parent(struct dentry *dchild)
+{
+ struct lu_fid parent_fid = { 0 };
+ struct dentry *dentry;
+ int rc;
+
+ rc = ll_dir_get_parent_fid(dchild->d_inode, &parent_fid);
+ if (rc)
+ return ERR_PTR(rc);
+
+ dentry = ll_iget_for_nfs(dchild->d_inode->i_sb, &parent_fid, NULL);
+
+ return dentry;
}
const struct export_operations lustre_export_operations = {
diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c
index e86bf3c53be3..6eae60595905 100644
--- a/drivers/staging/lustre/lustre/llite/lproc_llite.c
+++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c
@@ -31,7 +31,6 @@
*/
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/lustre_lite.h"
#include "../include/lprocfs_status.h"
#include <linux/seq_file.h>
#include "../include/obd_support.h"
@@ -358,16 +357,16 @@ static int ll_max_cached_mb_seq_show(struct seq_file *m, void *v)
struct ll_sb_info *sbi = ll_s2sbi(sb);
struct cl_client_cache *cache = sbi->ll_cache;
int shift = 20 - PAGE_SHIFT;
- int max_cached_mb;
- int unused_mb;
+ long max_cached_mb;
+ long unused_mb;
max_cached_mb = cache->ccc_lru_max >> shift;
- unused_mb = atomic_read(&cache->ccc_lru_left) >> shift;
+ unused_mb = atomic_long_read(&cache->ccc_lru_left) >> shift;
seq_printf(m,
"users: %d\n"
- "max_cached_mb: %d\n"
- "used_mb: %d\n"
- "unused_mb: %d\n"
+ "max_cached_mb: %ld\n"
+ "used_mb: %ld\n"
+ "unused_mb: %ld\n"
"reclaim_count: %u\n",
atomic_read(&cache->ccc_users),
max_cached_mb,
@@ -385,10 +384,13 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file,
struct ll_sb_info *sbi = ll_s2sbi(sb);
struct cl_client_cache *cache = sbi->ll_cache;
struct lu_env *env;
+ long diff = 0;
+ long nrpages = 0;
int refcheck;
- int mult, rc, pages_number;
- int diff = 0;
- int nrpages = 0;
+ long pages_number;
+ int mult;
+ long rc;
+ u64 val;
char kernbuf[128];
if (count >= sizeof(kernbuf))
@@ -401,10 +403,14 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file,
mult = 1 << (20 - PAGE_SHIFT);
buffer += lprocfs_find_named_value(kernbuf, "max_cached_mb:", &count) -
kernbuf;
- rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult);
+ rc = lprocfs_write_frac_u64_helper(buffer, count, &val, mult);
if (rc)
return rc;
+ if (val > LONG_MAX)
+ return -ERANGE;
+ pages_number = (long)val;
+
if (pages_number < 0 || pages_number > totalram_pages) {
CERROR("%s: can't set max cache more than %lu MB\n",
ll_get_fsname(sb, NULL, 0),
@@ -418,7 +424,7 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file,
/* easy - add more LRU slots. */
if (diff >= 0) {
- atomic_add(diff, &cache->ccc_lru_left);
+ atomic_long_add(diff, &cache->ccc_lru_left);
rc = 0;
goto out;
}
@@ -429,18 +435,18 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file,
diff = -diff;
while (diff > 0) {
- int tmp;
+ long tmp;
/* reduce LRU budget from free slots. */
do {
- int ov, nv;
+ long ov, nv;
- ov = atomic_read(&cache->ccc_lru_left);
+ ov = atomic_long_read(&cache->ccc_lru_left);
if (ov == 0)
break;
nv = ov > diff ? ov - diff : 0;
- rc = atomic_cmpxchg(&cache->ccc_lru_left, ov, nv);
+ rc = atomic_long_cmpxchg(&cache->ccc_lru_left, ov, nv);
if (likely(ov == rc)) {
diff -= ov - nv;
nrpages += ov - nv;
@@ -474,7 +480,7 @@ out:
spin_unlock(&sbi->ll_lock);
rc = count;
} else {
- atomic_add(nrpages, &cache->ccc_lru_left);
+ atomic_long_add(nrpages, &cache->ccc_lru_left);
}
return rc;
}
@@ -738,6 +744,18 @@ static ssize_t max_easize_show(struct kobject *kobj,
}
LUSTRE_RO_ATTR(max_easize);
+/**
+ * Get default_easize.
+ *
+ * \see client_obd::cl_default_mds_easize
+ *
+ * \param[in] kobj kernel object for sysfs tree
+ * \param[in] attr attribute of this kernel object
+ * \param[in] buf buffer to write data into
+ *
+ * \retval positive \a count on success
+ * \retval negative negated errno on failure
+ */
static ssize_t default_easize_show(struct kobject *kobj,
struct attribute *attr,
char *buf)
@@ -753,7 +771,44 @@ static ssize_t default_easize_show(struct kobject *kobj,
return sprintf(buf, "%u\n", ealen);
}
-LUSTRE_RO_ATTR(default_easize);
+
+/**
+ * Set default_easize.
+ *
+ * Range checking on the passed value is handled by
+ * ll_set_default_mdsize().
+ *
+ * \see client_obd::cl_default_mds_easize
+ *
+ * \param[in] kobj kernel object for sysfs tree
+ * \param[in] attr attribute of this kernel object
+ * \param[in] buffer string passed from user space
+ * \param[in] count \a buffer length
+ *
+ * \retval positive \a count on success
+ * \retval negative negated errno on failure
+ */
+static ssize_t default_easize_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer,
+ size_t count)
+{
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kobj);
+ unsigned long val;
+ int rc;
+
+ rc = kstrtoul(buffer, 10, &val);
+ if (rc)
+ return rc;
+
+ rc = ll_set_default_mdsize(sbi, val);
+ if (rc)
+ return rc;
+
+ return count;
+}
+LUSTRE_RW_ATTR(default_easize);
static int ll_sbi_flags_seq_show(struct seq_file *m, void *v)
{
@@ -774,7 +829,7 @@ static int ll_sbi_flags_seq_show(struct seq_file *m, void *v)
flags >>= 1;
++i;
}
- seq_printf(m, "\b\n");
+ seq_puts(m, "\b\n");
return 0;
}
@@ -823,15 +878,116 @@ static ssize_t unstable_stats_show(struct kobject *kobj,
struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
ll_kobj);
struct cl_client_cache *cache = sbi->ll_cache;
- int pages, mb;
+ long pages;
+ int mb;
- pages = atomic_read(&cache->ccc_unstable_nr);
+ pages = atomic_long_read(&cache->ccc_unstable_nr);
mb = (pages * PAGE_SIZE) >> 20;
- return sprintf(buf, "unstable_pages: %8d\n"
- "unstable_mb: %8d\n", pages, mb);
+ return sprintf(buf, "unstable_check: %8d\n"
+ "unstable_pages: %12ld\n"
+ "unstable_mb: %8d\n",
+ cache->ccc_unstable_check, pages, mb);
}
-LUSTRE_RO_ATTR(unstable_stats);
+
+static ssize_t unstable_stats_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer,
+ size_t count)
+{
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kobj);
+ char kernbuf[128];
+ int val, rc;
+
+ if (!count)
+ return 0;
+ if (count >= sizeof(kernbuf))
+ return -EINVAL;
+
+ if (copy_from_user(kernbuf, buffer, count))
+ return -EFAULT;
+ kernbuf[count] = 0;
+
+ buffer += lprocfs_find_named_value(kernbuf, "unstable_check:", &count) -
+ kernbuf;
+ rc = lprocfs_write_helper(buffer, count, &val);
+ if (rc < 0)
+ return rc;
+
+ /* borrow lru lock to set the value */
+ spin_lock(&sbi->ll_cache->ccc_lru_lock);
+ sbi->ll_cache->ccc_unstable_check = !!val;
+ spin_unlock(&sbi->ll_cache->ccc_lru_lock);
+
+ return count;
+}
+LUSTRE_RW_ATTR(unstable_stats);
+
+static ssize_t root_squash_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kobj);
+ struct root_squash_info *squash = &sbi->ll_squash;
+
+ return sprintf(buf, "%u:%u\n", squash->rsi_uid, squash->rsi_gid);
+}
+
+static ssize_t root_squash_store(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kobj);
+ struct root_squash_info *squash = &sbi->ll_squash;
+
+ return lprocfs_wr_root_squash(buffer, count, squash,
+ ll_get_fsname(sbi->ll_sb, NULL, 0));
+}
+LUSTRE_RW_ATTR(root_squash);
+
+static int ll_nosquash_nids_seq_show(struct seq_file *m, void *v)
+{
+ struct super_block *sb = m->private;
+ struct ll_sb_info *sbi = ll_s2sbi(sb);
+ struct root_squash_info *squash = &sbi->ll_squash;
+ int len;
+
+ down_read(&squash->rsi_sem);
+ if (!list_empty(&squash->rsi_nosquash_nids)) {
+ len = cfs_print_nidlist(m->buf + m->count, m->size - m->count,
+ &squash->rsi_nosquash_nids);
+ m->count += len;
+ seq_puts(m, "\n");
+ } else {
+ seq_puts(m, "NONE\n");
+ }
+ up_read(&squash->rsi_sem);
+
+ return 0;
+}
+
+static ssize_t ll_nosquash_nids_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *off)
+{
+ struct seq_file *m = file->private_data;
+ struct super_block *sb = m->private;
+ struct ll_sb_info *sbi = ll_s2sbi(sb);
+ struct root_squash_info *squash = &sbi->ll_squash;
+ int rc;
+
+ rc = lprocfs_wr_nosquash_nids(buffer, count, squash,
+ ll_get_fsname(sb, NULL, 0));
+ if (rc < 0)
+ return rc;
+
+ ll_compute_rootsquash_state(sbi);
+
+ return rc;
+}
+
+LPROC_SEQ_FOPS(ll_nosquash_nids);
static struct lprocfs_vars lprocfs_llite_obd_vars[] = {
/* { "mntpt_path", ll_rd_path, 0, 0 }, */
@@ -840,6 +996,8 @@ static struct lprocfs_vars lprocfs_llite_obd_vars[] = {
{ "max_cached_mb", &ll_max_cached_mb_fops, NULL },
{ "statahead_stats", &ll_statahead_stats_fops, NULL, 0 },
{ "sbi_flags", &ll_sbi_flags_fops, NULL, 0 },
+ { .name = "nosquash_nids",
+ .fops = &ll_nosquash_nids_fops },
{ NULL }
};
@@ -869,6 +1027,7 @@ static struct attribute *llite_attrs[] = {
&lustre_attr_default_easize.attr,
&lustre_attr_xattr_cache.attr,
&lustre_attr_unstable_stats.attr,
+ &lustre_attr_root_squash.attr,
NULL,
};
@@ -893,17 +1052,17 @@ static const struct llite_file_opcode {
/* file operation */
{ LPROC_LL_DIRTY_HITS, LPROCFS_TYPE_REGS, "dirty_pages_hits" },
{ LPROC_LL_DIRTY_MISSES, LPROCFS_TYPE_REGS, "dirty_pages_misses" },
- { LPROC_LL_READ_BYTES, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_BYTES,
+ { LPROC_LL_READ_BYTES, LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_BYTES,
"read_bytes" },
- { LPROC_LL_WRITE_BYTES, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_BYTES,
+ { LPROC_LL_WRITE_BYTES, LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_BYTES,
"write_bytes" },
- { LPROC_LL_BRW_READ, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_PAGES,
+ { LPROC_LL_BRW_READ, LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_PAGES,
"brw_read" },
- { LPROC_LL_BRW_WRITE, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_PAGES,
+ { LPROC_LL_BRW_WRITE, LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_PAGES,
"brw_write" },
- { LPROC_LL_OSC_READ, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_BYTES,
+ { LPROC_LL_OSC_READ, LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_BYTES,
"osc_read" },
- { LPROC_LL_OSC_WRITE, LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_BYTES,
+ { LPROC_LL_OSC_WRITE, LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_BYTES,
"osc_write" },
{ LPROC_LL_IOCTL, LPROCFS_TYPE_REGS, "ioctl" },
{ LPROC_LL_OPEN, LPROCFS_TYPE_REGS, "open" },
@@ -1150,7 +1309,7 @@ static void ll_display_extents_info(struct ll_rw_extents_info *io_extents,
r, pct(r, read_tot), pct(read_cum, read_tot),
w, pct(w, write_tot), pct(write_cum, write_tot));
start = end;
- if (start == 1<<10) {
+ if (start == 1 << 10) {
start = 1;
units += 10;
unitp++;
diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c
index 2c4dc69731e8..dfa36d34c645 100644
--- a/drivers/staging/lustre/lustre/llite/namei.c
+++ b/drivers/staging/lustre/lustre/llite/namei.c
@@ -42,13 +42,12 @@
#include "../include/obd_support.h"
#include "../include/lustre_fid.h"
-#include "../include/lustre_lite.h"
#include "../include/lustre_dlm.h"
#include "../include/lustre_ver.h"
#include "llite_internal.h"
-static int ll_create_it(struct inode *, struct dentry *,
- int, struct lookup_intent *);
+static int ll_create_it(struct inode *dir, struct dentry *dentry,
+ struct lookup_intent *it);
/* called from iget5_locked->find_inode() under inode_hash_lock spinlock */
static int ll_test_inode(struct inode *inode, void *opaque)
@@ -56,12 +55,12 @@ static int ll_test_inode(struct inode *inode, void *opaque)
struct ll_inode_info *lli = ll_i2info(inode);
struct lustre_md *md = opaque;
- if (unlikely(!(md->body->valid & OBD_MD_FLID))) {
+ if (unlikely(!(md->body->mbo_valid & OBD_MD_FLID))) {
CERROR("MDS body missing FID\n");
return 0;
}
- if (!lu_fid_eq(&lli->lli_fid, &md->body->fid1))
+ if (!lu_fid_eq(&lli->lli_fid, &md->body->mbo_fid1))
return 0;
return 1;
@@ -72,20 +71,20 @@ static int ll_set_inode(struct inode *inode, void *opaque)
struct ll_inode_info *lli = ll_i2info(inode);
struct mdt_body *body = ((struct lustre_md *)opaque)->body;
- if (unlikely(!(body->valid & OBD_MD_FLID))) {
+ if (unlikely(!(body->mbo_valid & OBD_MD_FLID))) {
CERROR("MDS body missing FID\n");
return -EINVAL;
}
- lli->lli_fid = body->fid1;
- if (unlikely(!(body->valid & OBD_MD_FLTYPE))) {
+ lli->lli_fid = body->mbo_fid1;
+ if (unlikely(!(body->mbo_valid & OBD_MD_FLTYPE))) {
CERROR("Can not initialize inode " DFID
" without object type: valid = %#llx\n",
- PFID(&lli->lli_fid), body->valid);
+ PFID(&lli->lli_fid), body->mbo_valid);
return -EINVAL;
}
- inode->i_mode = (inode->i_mode & ~S_IFMT) | (body->mode & S_IFMT);
+ inode->i_mode = (inode->i_mode & ~S_IFMT) | (body->mbo_mode & S_IFMT);
if (unlikely(inode->i_mode == 0)) {
CERROR("Invalid inode "DFID" type\n", PFID(&lli->lli_fid));
return -EINVAL;
@@ -96,41 +95,45 @@ static int ll_set_inode(struct inode *inode, void *opaque)
return 0;
}
-/*
- * Get an inode by inode number (already instantiated by the intent lookup).
- * Returns inode or NULL
+/**
+ * Get an inode by inode number(@hash), which is already instantiated by
+ * the intent lookup).
*/
struct inode *ll_iget(struct super_block *sb, ino_t hash,
struct lustre_md *md)
{
struct inode *inode;
+ int rc = 0;
LASSERT(hash != 0);
inode = iget5_locked(sb, hash, ll_test_inode, ll_set_inode, md);
-
- if (inode) {
- if (inode->i_state & I_NEW) {
- int rc = 0;
-
- ll_read_inode2(inode, md);
- if (S_ISREG(inode->i_mode) &&
- !ll_i2info(inode)->lli_clob) {
- CDEBUG(D_INODE,
- "%s: apply lsm %p to inode " DFID ".\n",
- ll_get_fsname(sb, NULL, 0), md->lsm,
- PFID(ll_inode2fid(inode)));
- rc = cl_file_inode_init(inode, md);
- }
- if (rc != 0) {
- iget_failed(inode);
- inode = NULL;
- } else {
- unlock_new_inode(inode);
- }
- } else if (!(inode->i_state & (I_FREEING | I_CLEAR))) {
- ll_update_inode(inode, md);
- CDEBUG(D_VFSTRACE, "got inode: "DFID"(%p)\n",
- PFID(&md->body->fid1), inode);
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+
+ if (inode->i_state & I_NEW) {
+ rc = ll_read_inode2(inode, md);
+ if (!rc && S_ISREG(inode->i_mode) &&
+ !ll_i2info(inode)->lli_clob) {
+ CDEBUG(D_INODE, "%s: apply lsm %p to inode "DFID"\n",
+ ll_get_fsname(sb, NULL, 0), md->lsm,
+ PFID(ll_inode2fid(inode)));
+ rc = cl_file_inode_init(inode, md);
+ }
+ if (rc) {
+ make_bad_inode(inode);
+ unlock_new_inode(inode);
+ iput(inode);
+ inode = ERR_PTR(rc);
+ } else {
+ unlock_new_inode(inode);
+ }
+ } else if (!(inode->i_state & (I_FREEING | I_CLEAR))) {
+ rc = ll_update_inode(inode, md);
+ CDEBUG(D_VFSTRACE, "got inode: "DFID"(%p): rc = %d\n",
+ PFID(&md->body->mbo_fid1), inode, rc);
+ if (rc) {
+ iput(inode);
+ inode = ERR_PTR(rc);
}
}
return inode;
@@ -158,6 +161,11 @@ static void ll_invalidate_negative_children(struct inode *dir)
spin_unlock(&dir->i_lock);
}
+int ll_test_inode_by_fid(struct inode *inode, void *opaque)
+{
+ return lu_fid_eq(&ll_i2info(inode)->lli_fid, opaque);
+}
+
int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
void *data, int flag)
{
@@ -196,6 +204,8 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
}
if (bits & MDS_INODELOCK_XATTR) {
+ if (S_ISDIR(inode->i_mode))
+ ll_i2info(inode)->lli_def_stripe_offset = -1;
ll_xattr_cache_destroy(inode);
bits &= ~MDS_INODELOCK_XATTR;
}
@@ -253,10 +263,41 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
}
if ((bits & MDS_INODELOCK_UPDATE) && S_ISDIR(inode->i_mode)) {
- CDEBUG(D_INODE, "invalidating inode "DFID"\n",
- PFID(ll_inode2fid(inode)));
+ struct ll_inode_info *lli = ll_i2info(inode);
+
+ CDEBUG(D_INODE, "invalidating inode "DFID" lli = %p, pfid = "DFID"\n",
+ PFID(ll_inode2fid(inode)), lli,
+ PFID(&lli->lli_pfid));
+
truncate_inode_pages(inode->i_mapping, 0);
- ll_invalidate_negative_children(inode);
+
+ if (unlikely(!fid_is_zero(&lli->lli_pfid))) {
+ struct inode *master_inode = NULL;
+ unsigned long hash;
+
+ /*
+ * This is slave inode, since all of the child
+ * dentry is connected on the master inode, so
+ * we have to invalidate the negative children
+ * on master inode
+ */
+ CDEBUG(D_INODE, "Invalidate s"DFID" m"DFID"\n",
+ PFID(ll_inode2fid(inode)),
+ PFID(&lli->lli_pfid));
+
+ hash = cl_fid_build_ino(&lli->lli_pfid,
+ ll_need_32bit_api(ll_i2sbi(inode)));
+
+ master_inode = ilookup5(inode->i_sb, hash,
+ ll_test_inode_by_fid,
+ (void *)&lli->lli_pfid);
+ if (master_inode && !IS_ERR(master_inode)) {
+ ll_invalidate_negative_children(master_inode);
+ iput(master_inode);
+ }
+ } else {
+ ll_invalidate_negative_children(inode);
+ }
}
if ((bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM)) &&
@@ -322,7 +363,8 @@ static struct dentry *ll_find_alias(struct inode *inode, struct dentry *dentry)
LASSERT(alias != dentry);
spin_lock(&alias->d_lock);
- if (alias->d_flags & DCACHE_DISCONNECTED)
+ if ((alias->d_flags & DCACHE_DISCONNECTED) &&
+ S_ISDIR(inode->i_mode))
/* LASSERT(last_discon == NULL); LU-405, bz 20055 */
discon_alias = alias;
else if (alias->d_parent == dentry->d_parent &&
@@ -433,9 +475,20 @@ static int ll_lookup_it_finish(struct ptlrpc_request *request,
struct lookup_intent parent_it = {
.it_op = IT_GETATTR,
.it_lock_handle = 0 };
+ struct lu_fid fid = ll_i2info(parent)->lli_fid;
+
+ /* If it is striped directory, get the real stripe parent */
+ if (unlikely(ll_i2info(parent)->lli_lsm_md)) {
+ rc = md_get_fid_from_lsm(ll_i2mdexp(parent),
+ ll_i2info(parent)->lli_lsm_md,
+ (*de)->d_name.name,
+ (*de)->d_name.len, &fid);
+ if (rc)
+ return rc;
+ }
- if (md_revalidate_lock(ll_i2mdexp(parent), &parent_it,
- &ll_i2info(parent)->lli_fid, NULL)) {
+ if (md_revalidate_lock(ll_i2mdexp(parent), &parent_it, &fid,
+ NULL)) {
d_lustre_revalidate(*de);
ll_intent_release(&parent_it);
}
@@ -449,13 +502,13 @@ out:
}
static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry,
- struct lookup_intent *it, int lookup_flags)
+ struct lookup_intent *it)
{
struct lookup_intent lookup_it = { .it_op = IT_LOOKUP };
struct dentry *save = dentry, *retval;
struct ptlrpc_request *req = NULL;
+ struct md_op_data *op_data = NULL;
struct inode *inode;
- struct md_op_data *op_data;
__u32 opc;
int rc;
@@ -471,8 +524,8 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry,
if (!it || it->it_op == IT_GETXATTR)
it = &lookup_it;
- if (it->it_op == IT_GETATTR) {
- rc = ll_statahead_enter(parent, &dentry, 0);
+ if (it->it_op == IT_GETATTR && dentry_may_statahead(parent, dentry)) {
+ rc = ll_statahead(parent, &dentry, 0);
if (rc == 1) {
if (dentry == save)
retval = NULL;
@@ -488,8 +541,7 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry,
opc = LUSTRE_OPC_ANY;
op_data = ll_prep_md_op_data(NULL, parent, NULL, dentry->d_name.name,
- dentry->d_name.len, lookup_flags, opc,
- NULL);
+ dentry->d_name.len, 0, opc, NULL);
if (IS_ERR(op_data))
return (void *)op_data;
@@ -497,9 +549,38 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry,
if (!IS_POSIXACL(parent) || !exp_connect_umask(ll_i2mdexp(parent)))
it->it_create_mode &= ~current_umask();
- rc = md_intent_lock(ll_i2mdexp(parent), op_data, NULL, 0, it,
- lookup_flags, &req, ll_md_blocking_ast, 0);
- ll_finish_md_op_data(op_data);
+ rc = md_intent_lock(ll_i2mdexp(parent), op_data, it, &req,
+ &ll_md_blocking_ast, 0);
+ /*
+ * If the MDS allows the client to chgrp (CFS_SETGRP_PERM), but the
+ * client does not know which suppgid should be sent to the MDS, or
+ * some other(s) changed the target file's GID after this RPC sent
+ * to the MDS with the suppgid as the original GID, then we should
+ * try again with right suppgid.
+ */
+ if (rc == -EACCES && it->it_op & IT_OPEN &&
+ it_disposition(it, DISP_OPEN_DENY)) {
+ struct mdt_body *body;
+
+ LASSERT(req);
+
+ body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
+ if (op_data->op_suppgids[0] == body->mbo_gid ||
+ op_data->op_suppgids[1] == body->mbo_gid ||
+ !in_group_p(make_kgid(&init_user_ns, body->mbo_gid))) {
+ retval = ERR_PTR(-EACCES);
+ goto out;
+ }
+
+ fid_zero(&op_data->op_fid2);
+ op_data->op_suppgids[1] = body->mbo_gid;
+ ptlrpc_req_finished(req);
+ req = NULL;
+ ll_intent_release(it);
+ rc = md_intent_lock(ll_i2mdexp(parent), op_data, it, &req,
+ ll_md_blocking_ast, 0);
+ }
+
if (rc < 0) {
retval = ERR_PTR(rc);
goto out;
@@ -524,11 +605,11 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry,
retval = NULL;
else
retval = dentry;
- out:
- if (req)
- ptlrpc_req_finished(req);
- if (it->it_op == IT_GETATTR && (!retval || retval == dentry))
- ll_statahead_mark(parent, dentry);
+out:
+ if (op_data && !IS_ERR(op_data))
+ ll_finish_md_op_data(op_data);
+
+ ptlrpc_req_finished(req);
return retval;
}
@@ -541,15 +622,19 @@ static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry,
CDEBUG(D_VFSTRACE, "VFS Op:name=%pd, dir="DFID"(%p),flags=%u\n",
dentry, PFID(ll_inode2fid(parent)), parent, flags);
- /* Optimize away (CREATE && !OPEN). Let .create handle the race. */
- if ((flags & LOOKUP_CREATE) && !(flags & LOOKUP_OPEN))
+ /* Optimize away (CREATE && !OPEN). Let .create handle the race.
+ * but only if we have write permissions there, otherwise we need
+ * to proceed with lookup. LU-4185
+ */
+ if ((flags & LOOKUP_CREATE) && !(flags & LOOKUP_OPEN) &&
+ (inode_permission(parent, MAY_WRITE | MAY_EXEC) == 0))
return NULL;
- if (flags & (LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE))
+ if (flags & (LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE))
itp = NULL;
else
itp = &it;
- de = ll_lookup_it(parent, dentry, itp, 0);
+ de = ll_lookup_it(parent, dentry, itp);
if (itp)
ll_intent_release(itp);
@@ -567,7 +652,6 @@ static int ll_atomic_open(struct inode *dir, struct dentry *dentry,
{
struct lookup_intent *it;
struct dentry *de;
- long long lookup_flags = LOOKUP_OPEN;
int rc = 0;
CDEBUG(D_VFSTRACE, "VFS Op:name=%pd, dir="DFID"(%p),file %p,open_flags %x,mode %x opened %d\n",
@@ -597,15 +681,14 @@ static int ll_atomic_open(struct inode *dir, struct dentry *dentry,
return -ENOMEM;
it->it_op = IT_OPEN;
- if (open_flags & O_CREAT) {
+ if (open_flags & O_CREAT)
it->it_op |= IT_CREAT;
- lookup_flags |= LOOKUP_CREATE;
- }
it->it_create_mode = (mode & S_IALLUGO) | S_IFREG;
it->it_flags = (open_flags & ~O_ACCMODE) | OPEN_FMODE(open_flags);
+ it->it_flags &= ~MDS_OPEN_FL_INTERNAL;
/* Dentry added to dcache tree in ll_lookup_it */
- de = ll_lookup_it(dir, dentry, it, lookup_flags);
+ de = ll_lookup_it(dir, dentry, it);
if (IS_ERR(de))
rc = PTR_ERR(de);
else if (de)
@@ -614,7 +697,7 @@ static int ll_atomic_open(struct inode *dir, struct dentry *dentry,
if (!rc) {
if (it_disposition(it, DISP_OPEN_CREATE)) {
/* Dentry instantiated in ll_create_it. */
- rc = ll_create_it(dir, dentry, mode, it);
+ rc = ll_create_it(dir, dentry, it);
if (rc) {
/* We dget in ll_splice_alias. */
if (de)
@@ -700,7 +783,7 @@ static struct inode *ll_create_node(struct inode *dir, struct lookup_intent *it)
* If the create succeeds, we fill in the inode information
* with d_instantiate().
*/
-static int ll_create_it(struct inode *dir, struct dentry *dentry, int mode,
+static int ll_create_it(struct inode *dir, struct dentry *dentry,
struct lookup_intent *it)
{
struct inode *inode;
@@ -721,27 +804,26 @@ static int ll_create_it(struct inode *dir, struct dentry *dentry, int mode,
return 0;
}
-static void ll_update_times(struct ptlrpc_request *request,
- struct inode *inode)
+void ll_update_times(struct ptlrpc_request *request, struct inode *inode)
{
struct mdt_body *body = req_capsule_server_get(&request->rq_pill,
&RMF_MDT_BODY);
LASSERT(body);
- if (body->valid & OBD_MD_FLMTIME &&
- body->mtime > LTIME_S(inode->i_mtime)) {
+ if (body->mbo_valid & OBD_MD_FLMTIME &&
+ body->mbo_mtime > LTIME_S(inode->i_mtime)) {
CDEBUG(D_INODE, "setting fid "DFID" mtime from %lu to %llu\n",
PFID(ll_inode2fid(inode)), LTIME_S(inode->i_mtime),
- body->mtime);
- LTIME_S(inode->i_mtime) = body->mtime;
+ body->mbo_mtime);
+ LTIME_S(inode->i_mtime) = body->mbo_mtime;
}
- if (body->valid & OBD_MD_FLCTIME &&
- body->ctime > LTIME_S(inode->i_ctime))
- LTIME_S(inode->i_ctime) = body->ctime;
+ if (body->mbo_valid & OBD_MD_FLCTIME &&
+ body->mbo_ctime > LTIME_S(inode->i_ctime))
+ LTIME_S(inode->i_ctime) = body->mbo_ctime;
}
static int ll_new_node(struct inode *dir, struct dentry *dentry,
- const char *tgt, int mode, int rdev,
+ const char *tgt, umode_t mode, int rdev,
__u32 opc)
{
struct ptlrpc_request *request = NULL;
@@ -753,7 +835,7 @@ static int ll_new_node(struct inode *dir, struct dentry *dentry,
if (unlikely(tgt))
tgt_len = strlen(tgt) + 1;
-
+again:
op_data = ll_prep_md_op_data(NULL, dir, NULL,
dentry->d_name.name,
dentry->d_name.len,
@@ -768,9 +850,45 @@ static int ll_new_node(struct inode *dir, struct dentry *dentry,
from_kgid(&init_user_ns, current_fsgid()),
cfs_curproc_cap_pack(), rdev, &request);
ll_finish_md_op_data(op_data);
- if (err)
+ if (err < 0 && err != -EREMOTE)
goto err_exit;
+ /*
+ * If the client doesn't know where to create a subdirectory (or
+ * in case of a race that sends the RPC to the wrong MDS), the
+ * MDS will return -EREMOTE and the client will fetch the layout
+ * of the directory, then create the directory on the right MDT.
+ */
+ if (unlikely(err == -EREMOTE)) {
+ struct ll_inode_info *lli = ll_i2info(dir);
+ struct lmv_user_md *lum;
+ int lumsize, err2;
+
+ ptlrpc_req_finished(request);
+ request = NULL;
+
+ err2 = ll_dir_getstripe(dir, (void **)&lum, &lumsize, &request,
+ OBD_MD_DEFAULT_MEA);
+ if (!err2) {
+ /* Update stripe_offset and retry */
+ lli->lli_def_stripe_offset = lum->lum_stripe_offset;
+ } else if (err2 == -ENODATA &&
+ lli->lli_def_stripe_offset != -1) {
+ /*
+ * If there are no default stripe EA on the MDT, but the
+ * client has default stripe, then it probably means
+ * default stripe EA has just been deleted.
+ */
+ lli->lli_def_stripe_offset = -1;
+ } else {
+ goto err_exit;
+ }
+
+ ptlrpc_req_finished(request);
+ request = NULL;
+ goto again;
+ }
+
ll_update_times(request, dir);
err = ll_prep_inode(&inode, request, dir->i_sb, NULL);
@@ -779,7 +897,8 @@ static int ll_new_node(struct inode *dir, struct dentry *dentry,
d_instantiate(dentry, inode);
err_exit:
- ptlrpc_req_finished(request);
+ if (request)
+ ptlrpc_req_finished(request);
return err;
}
@@ -842,77 +961,6 @@ static int ll_create_nd(struct inode *dir, struct dentry *dentry,
return rc;
}
-int ll_objects_destroy(struct ptlrpc_request *request, struct inode *dir)
-{
- struct mdt_body *body;
- struct lov_mds_md *eadata;
- struct lov_stripe_md *lsm = NULL;
- struct obd_trans_info oti = { 0 };
- struct obdo *oa;
- int rc;
-
- /* req is swabbed so this is safe */
- body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY);
- if (!(body->valid & OBD_MD_FLEASIZE))
- return 0;
-
- if (body->eadatasize == 0) {
- CERROR("OBD_MD_FLEASIZE set but eadatasize zero\n");
- rc = -EPROTO;
- goto out;
- }
-
- /* The MDS sent back the EA because we unlinked the last reference
- * to this file. Use this EA to unlink the objects on the OST.
- * It's opaque so we don't swab here; we leave it to obd_unpackmd() to
- * check it is complete and sensible.
- */
- eadata = req_capsule_server_sized_get(&request->rq_pill, &RMF_MDT_MD,
- body->eadatasize);
- LASSERT(eadata);
-
- rc = obd_unpackmd(ll_i2dtexp(dir), &lsm, eadata, body->eadatasize);
- if (rc < 0) {
- CERROR("obd_unpackmd: %d\n", rc);
- goto out;
- }
- LASSERT(rc >= sizeof(*lsm));
-
- oa = kmem_cache_zalloc(obdo_cachep, GFP_NOFS);
- if (!oa) {
- rc = -ENOMEM;
- goto out_free_memmd;
- }
-
- oa->o_oi = lsm->lsm_oi;
- oa->o_mode = body->mode & S_IFMT;
- oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLGROUP;
-
- if (body->valid & OBD_MD_FLCOOKIE) {
- oa->o_valid |= OBD_MD_FLCOOKIE;
- oti.oti_logcookies =
- req_capsule_server_sized_get(&request->rq_pill,
- &RMF_LOGCOOKIES,
- sizeof(struct llog_cookie) *
- lsm->lsm_stripe_count);
- if (!oti.oti_logcookies) {
- oa->o_valid &= ~OBD_MD_FLCOOKIE;
- body->valid &= ~OBD_MD_FLCOOKIE;
- }
- }
-
- rc = obd_destroy(NULL, ll_i2dtexp(dir), oa, lsm, &oti,
- ll_i2mdexp(dir));
- if (rc)
- CERROR("obd destroy objid "DOSTID" error %d\n",
- POSTID(&lsm->lsm_oi), rc);
-out_free_memmd:
- obd_free_memmd(ll_i2dtexp(dir), &lsm);
- kmem_cache_free(obdo_cachep, oa);
-out:
- return rc;
-}
-
/* ll_unlink() doesn't update the inode with the new link count.
* Instead, ll_ddelete() and ll_d_iput() will update it based upon if there
* is any lock existing. They will recycle dentries and inodes based upon locks
@@ -934,7 +982,7 @@ static int ll_unlink(struct inode *dir, struct dentry *dchild)
if (IS_ERR(op_data))
return PTR_ERR(op_data);
- if (dchild && dchild->d_inode)
+ if (dchild->d_inode)
op_data->op_fid3 = *ll_inode2fid(dchild->d_inode);
op_data->op_fid2 = op_data->op_fid3;
@@ -946,7 +994,6 @@ static int ll_unlink(struct inode *dir, struct dentry *dchild)
ll_update_times(request, dir);
ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_UNLINK, 1);
- rc = ll_objects_destroy(request, dir);
out:
ptlrpc_req_finished(request);
return rc;
@@ -961,9 +1008,9 @@ static int ll_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
if (!IS_POSIXACL(dir) || !exp_connect_umask(ll_i2mdexp(dir)))
mode &= ~current_umask();
- mode = (mode & (S_IRWXUGO|S_ISVTX)) | S_IFDIR;
- err = ll_new_node(dir, dentry, NULL, mode, 0, LUSTRE_OPC_MKDIR);
+ mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
+ err = ll_new_node(dir, dentry, NULL, mode, 0, LUSTRE_OPC_MKDIR);
if (!err)
ll_stats_ops_tally(ll_i2sbi(dir), LPROC_LL_MKDIR, 1);
@@ -986,7 +1033,7 @@ static int ll_rmdir(struct inode *dir, struct dentry *dchild)
if (IS_ERR(op_data))
return PTR_ERR(op_data);
- if (dchild && dchild->d_inode)
+ if (dchild->d_inode)
op_data->op_fid3 = *ll_inode2fid(dchild->d_inode);
op_data->op_fid2 = op_data->op_fid3;
@@ -1067,9 +1114,9 @@ static int ll_rename(struct inode *src, struct dentry *src_dchild,
if (IS_ERR(op_data))
return PTR_ERR(op_data);
- if (src_dchild && src_dchild->d_inode)
+ if (src_dchild->d_inode)
op_data->op_fid3 = *ll_inode2fid(src_dchild->d_inode);
- if (tgt_dchild && tgt_dchild->d_inode)
+ if (tgt_dchild->d_inode)
op_data->op_fid4 = *ll_inode2fid(tgt_dchild->d_inode);
err = md_rename(sbi->ll_md_exp, op_data,
@@ -1082,7 +1129,6 @@ static int ll_rename(struct inode *src, struct dentry *src_dchild,
ll_update_times(request, src);
ll_update_times(request, tgt);
ll_stats_ops_tally(sbi, LPROC_LL_RENAME, 1);
- err = ll_objects_destroy(request, src);
}
ptlrpc_req_finished(request);
@@ -1106,10 +1152,10 @@ const struct inode_operations ll_dir_inode_operations = {
.setattr = ll_setattr,
.getattr = ll_getattr,
.permission = ll_inode_permission,
- .setxattr = ll_setxattr,
- .getxattr = ll_getxattr,
+ .setxattr = generic_setxattr,
+ .getxattr = generic_getxattr,
.listxattr = ll_listxattr,
- .removexattr = ll_removexattr,
+ .removexattr = generic_removexattr,
.get_acl = ll_get_acl,
};
@@ -1117,9 +1163,9 @@ const struct inode_operations ll_special_inode_operations = {
.setattr = ll_setattr,
.getattr = ll_getattr,
.permission = ll_inode_permission,
- .setxattr = ll_setxattr,
- .getxattr = ll_getxattr,
+ .setxattr = generic_setxattr,
+ .getxattr = generic_getxattr,
.listxattr = ll_listxattr,
- .removexattr = ll_removexattr,
+ .removexattr = generic_removexattr,
.get_acl = ll_get_acl,
};
diff --git a/drivers/staging/lustre/lustre/llite/range_lock.c b/drivers/staging/lustre/lustre/llite/range_lock.c
new file mode 100644
index 000000000000..94c818f1478b
--- /dev/null
+++ b/drivers/staging/lustre/lustre/llite/range_lock.c
@@ -0,0 +1,233 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * 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 version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Range lock is used to allow multiple threads writing a single shared
+ * file given each thread is writing to a non-overlapping portion of the
+ * file.
+ *
+ * Refer to the possible upstream kernel version of range lock by
+ * Jan Kara <jack@suse.cz>: https://lkml.org/lkml/2013/1/31/480
+ *
+ * This file could later replaced by the upstream kernel version.
+ */
+/*
+ * Author: Prakash Surya <surya1@llnl.gov>
+ * Author: Bobi Jam <bobijam.xu@intel.com>
+ */
+#include "range_lock.h"
+#include "../include/lustre/lustre_user.h"
+
+/**
+ * Initialize a range lock tree
+ *
+ * \param tree [in] an empty range lock tree
+ *
+ * Pre: Caller should have allocated the range lock tree.
+ * Post: The range lock tree is ready to function.
+ */
+void range_lock_tree_init(struct range_lock_tree *tree)
+{
+ tree->rlt_root = NULL;
+ tree->rlt_sequence = 0;
+ spin_lock_init(&tree->rlt_lock);
+}
+
+/**
+ * Initialize a range lock node
+ *
+ * \param lock [in] an empty range lock node
+ * \param start [in] start of the covering region
+ * \param end [in] end of the covering region
+ *
+ * Pre: Caller should have allocated the range lock node.
+ * Post: The range lock node is meant to cover [start, end] region
+ */
+void range_lock_init(struct range_lock *lock, __u64 start, __u64 end)
+{
+ memset(&lock->rl_node, 0, sizeof(lock->rl_node));
+ if (end != LUSTRE_EOF)
+ end >>= PAGE_SHIFT;
+ interval_set(&lock->rl_node, start >> PAGE_SHIFT, end);
+ INIT_LIST_HEAD(&lock->rl_next_lock);
+ lock->rl_task = NULL;
+ lock->rl_lock_count = 0;
+ lock->rl_blocking_ranges = 0;
+ lock->rl_sequence = 0;
+}
+
+static inline struct range_lock *next_lock(struct range_lock *lock)
+{
+ return list_entry(lock->rl_next_lock.next, typeof(*lock), rl_next_lock);
+}
+
+/**
+ * Helper function of range_unlock()
+ *
+ * \param node [in] a range lock found overlapped during interval node
+ * search
+ * \param arg [in] the range lock to be tested
+ *
+ * \retval INTERVAL_ITER_CONT indicate to continue the search for next
+ * overlapping range node
+ * \retval INTERVAL_ITER_STOP indicate to stop the search
+ */
+static enum interval_iter range_unlock_cb(struct interval_node *node, void *arg)
+{
+ struct range_lock *lock = arg;
+ struct range_lock *overlap = node2rangelock(node);
+ struct range_lock *iter;
+
+ list_for_each_entry(iter, &overlap->rl_next_lock, rl_next_lock) {
+ if (iter->rl_sequence > lock->rl_sequence) {
+ --iter->rl_blocking_ranges;
+ LASSERT(iter->rl_blocking_ranges > 0);
+ }
+ }
+ if (overlap->rl_sequence > lock->rl_sequence) {
+ --overlap->rl_blocking_ranges;
+ if (overlap->rl_blocking_ranges == 0)
+ wake_up_process(overlap->rl_task);
+ }
+ return INTERVAL_ITER_CONT;
+}
+
+/**
+ * Unlock a range lock, wake up locks blocked by this lock.
+ *
+ * \param tree [in] range lock tree
+ * \param lock [in] range lock to be deleted
+ *
+ * If this lock has been granted, relase it; if not, just delete it from
+ * the tree or the same region lock list. Wake up those locks only blocked
+ * by this lock through range_unlock_cb().
+ */
+void range_unlock(struct range_lock_tree *tree, struct range_lock *lock)
+{
+ spin_lock(&tree->rlt_lock);
+ if (!list_empty(&lock->rl_next_lock)) {
+ struct range_lock *next;
+
+ if (interval_is_intree(&lock->rl_node)) { /* first lock */
+ /* Insert the next same range lock into the tree */
+ next = next_lock(lock);
+ next->rl_lock_count = lock->rl_lock_count - 1;
+ interval_erase(&lock->rl_node, &tree->rlt_root);
+ interval_insert(&next->rl_node, &tree->rlt_root);
+ } else {
+ /* find the first lock in tree */
+ list_for_each_entry(next, &lock->rl_next_lock,
+ rl_next_lock) {
+ if (!interval_is_intree(&next->rl_node))
+ continue;
+
+ LASSERT(next->rl_lock_count > 0);
+ next->rl_lock_count--;
+ break;
+ }
+ }
+ list_del_init(&lock->rl_next_lock);
+ } else {
+ LASSERT(interval_is_intree(&lock->rl_node));
+ interval_erase(&lock->rl_node, &tree->rlt_root);
+ }
+
+ interval_search(tree->rlt_root, &lock->rl_node.in_extent,
+ range_unlock_cb, lock);
+ spin_unlock(&tree->rlt_lock);
+}
+
+/**
+ * Helper function of range_lock()
+ *
+ * \param node [in] a range lock found overlapped during interval node
+ * search
+ * \param arg [in] the range lock to be tested
+ *
+ * \retval INTERVAL_ITER_CONT indicate to continue the search for next
+ * overlapping range node
+ * \retval INTERVAL_ITER_STOP indicate to stop the search
+ */
+static enum interval_iter range_lock_cb(struct interval_node *node, void *arg)
+{
+ struct range_lock *lock = (struct range_lock *)arg;
+ struct range_lock *overlap = node2rangelock(node);
+
+ lock->rl_blocking_ranges += overlap->rl_lock_count + 1;
+ return INTERVAL_ITER_CONT;
+}
+
+/**
+ * Lock a region
+ *
+ * \param tree [in] range lock tree
+ * \param lock [in] range lock node containing the region span
+ *
+ * \retval 0 get the range lock
+ * \retval <0 error code while not getting the range lock
+ *
+ * If there exists overlapping range lock, the new lock will wait and
+ * retry, if later it find that it is not the chosen one to wake up,
+ * it wait again.
+ */
+int range_lock(struct range_lock_tree *tree, struct range_lock *lock)
+{
+ struct interval_node *node;
+ int rc = 0;
+
+ spin_lock(&tree->rlt_lock);
+ /*
+ * We need to check for all conflicting intervals
+ * already in the tree.
+ */
+ interval_search(tree->rlt_root, &lock->rl_node.in_extent,
+ range_lock_cb, lock);
+ /*
+ * Insert to the tree if I am unique, otherwise I've been linked to
+ * the rl_next_lock of another lock which has the same range as mine
+ * in range_lock_cb().
+ */
+ node = interval_insert(&lock->rl_node, &tree->rlt_root);
+ if (node) {
+ struct range_lock *tmp = node2rangelock(node);
+
+ list_add_tail(&lock->rl_next_lock, &tmp->rl_next_lock);
+ tmp->rl_lock_count++;
+ }
+ lock->rl_sequence = ++tree->rlt_sequence;
+
+ while (lock->rl_blocking_ranges > 0) {
+ lock->rl_task = current;
+ __set_current_state(TASK_INTERRUPTIBLE);
+ spin_unlock(&tree->rlt_lock);
+ schedule();
+
+ if (signal_pending(current)) {
+ range_unlock(tree, lock);
+ rc = -EINTR;
+ goto out;
+ }
+ spin_lock(&tree->rlt_lock);
+ }
+ spin_unlock(&tree->rlt_lock);
+out:
+ return rc;
+}
diff --git a/drivers/staging/lustre/lustre/llite/range_lock.h b/drivers/staging/lustre/lustre/llite/range_lock.h
new file mode 100644
index 000000000000..c6d04a6f99fd
--- /dev/null
+++ b/drivers/staging/lustre/lustre/llite/range_lock.h
@@ -0,0 +1,82 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * 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 version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Range lock is used to allow multiple threads writing a single shared
+ * file given each thread is writing to a non-overlapping portion of the
+ * file.
+ *
+ * Refer to the possible upstream kernel version of range lock by
+ * Jan Kara <jack@suse.cz>: https://lkml.org/lkml/2013/1/31/480
+ *
+ * This file could later replaced by the upstream kernel version.
+ */
+/*
+ * Author: Prakash Surya <surya1@llnl.gov>
+ * Author: Bobi Jam <bobijam.xu@intel.com>
+ */
+#ifndef _RANGE_LOCK_H
+#define _RANGE_LOCK_H
+
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../include/interval_tree.h"
+
+struct range_lock {
+ struct interval_node rl_node;
+ /**
+ * Process to enqueue this lock.
+ */
+ struct task_struct *rl_task;
+ /**
+ * List of locks with the same range.
+ */
+ struct list_head rl_next_lock;
+ /**
+ * Number of locks in the list rl_next_lock
+ */
+ unsigned int rl_lock_count;
+ /**
+ * Number of ranges which are blocking acquisition of the lock
+ */
+ unsigned int rl_blocking_ranges;
+ /**
+ * Sequence number of range lock. This number is used to get to know
+ * the order the locks are queued; this is required for range_cancel().
+ */
+ __u64 rl_sequence;
+};
+
+static inline struct range_lock *node2rangelock(const struct interval_node *n)
+{
+ return container_of(n, struct range_lock, rl_node);
+}
+
+struct range_lock_tree {
+ struct interval_node *rlt_root;
+ spinlock_t rlt_lock; /* protect range lock tree */
+ __u64 rlt_sequence;
+};
+
+void range_lock_tree_init(struct range_lock_tree *tree);
+void range_lock_init(struct range_lock *lock, __u64 start, __u64 end);
+int range_lock(struct range_lock_tree *tree, struct range_lock *lock);
+void range_unlock(struct range_lock_tree *tree, struct range_lock *lock);
+#endif
diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c
index 87393c4bd51e..50c0152ba022 100644
--- a/drivers/staging/lustre/lustre/llite/rw.c
+++ b/drivers/staging/lustre/lustre/llite/rw.c
@@ -50,10 +50,8 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/lustre_lite.h"
#include "../include/obd_cksum.h"
#include "llite_internal.h"
-#include "../include/linux/lustre_compat25.h"
static void ll_ra_stats_inc_sbi(struct ll_sb_info *sbi, enum ra_stat which);
@@ -413,7 +411,7 @@ static int ll_read_ahead_pages(const struct lu_env *env,
* forward read-ahead, it will be fixed when backward
* read-ahead is implemented
*/
- LASSERTF(page_idx > ria->ria_stoff, "Invalid page_idx %lu rs %lu re %lu ro %lu rl %lu rp %lu\n",
+ LASSERTF(page_idx >= ria->ria_stoff, "Invalid page_idx %lu rs %lu re %lu ro %lu rl %lu rp %lu\n",
page_idx,
ria->ria_start, ria->ria_end, ria->ria_stoff,
ria->ria_length, ria->ria_pages);
@@ -474,10 +472,22 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io,
}
/* Reserve a part of the read-ahead window that we'll be issuing */
- if (ras->ras_window_len) {
- start = ras->ras_next_readahead;
+ if (ras->ras_window_len > 0) {
+ /*
+ * Note: other thread might rollback the ras_next_readahead,
+ * if it can not get the full size of prepared pages, see the
+ * end of this function. For stride read ahead, it needs to
+ * make sure the offset is no less than ras_stride_offset,
+ * so that stride read ahead can work correctly.
+ */
+ if (stride_io_mode(ras))
+ start = max(ras->ras_next_readahead,
+ ras->ras_stride_offset);
+ else
+ start = ras->ras_next_readahead;
end = ras->ras_window_start + ras->ras_window_len - 1;
}
+
if (end != 0) {
unsigned long rpc_boundary;
/*
@@ -648,10 +658,11 @@ static void ras_update_stride_detector(struct ll_readahead_state *ras,
{
unsigned long stride_gap = index - ras->ras_last_readpage - 1;
- if (!stride_io_mode(ras) && (stride_gap != 0 ||
- ras->ras_consecutive_stride_requests == 0)) {
+ if ((stride_gap != 0 || ras->ras_consecutive_stride_requests == 0) &&
+ !stride_io_mode(ras)) {
ras->ras_stride_pages = ras->ras_consecutive_pages;
- ras->ras_stride_length = stride_gap+ras->ras_consecutive_pages;
+ ras->ras_stride_length = ras->ras_consecutive_pages +
+ stride_gap;
}
LASSERT(ras->ras_request_index == 0);
LASSERT(ras->ras_consecutive_stride_requests == 0);
@@ -663,10 +674,9 @@ static void ras_update_stride_detector(struct ll_readahead_state *ras,
}
ras->ras_stride_pages = ras->ras_consecutive_pages;
- ras->ras_stride_length = stride_gap+ras->ras_consecutive_pages;
+ ras->ras_stride_length = stride_gap + ras->ras_consecutive_pages;
RAS_CDEBUG(ras);
- return;
}
/* Stride Read-ahead window will be increased inc_len according to
@@ -882,7 +892,6 @@ out_unlock:
RAS_CDEBUG(ras);
ras->ras_request_index++;
spin_unlock(&ras->ras_lock);
- return;
}
int ll_writepage(struct page *vmpage, struct writeback_control *wbc)
@@ -1015,11 +1024,15 @@ int ll_writepages(struct address_space *mapping, struct writeback_control *wbc)
* is called later on.
*/
ignore_layout = 1;
+
+ if (!ll_i2info(inode)->lli_clob)
+ return 0;
+
result = cl_sync_file_range(inode, start, end, mode, ignore_layout);
if (result > 0) {
wbc->nr_to_write -= result;
result = 0;
- }
+ }
if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) {
if (end == OBD_OBJECT_EOF)
diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c
index d98c7acc0832..26f3a37873a7 100644
--- a/drivers/staging/lustre/lustre/llite/rw26.c
+++ b/drivers/staging/lustre/lustre/llite/rw26.c
@@ -51,9 +51,7 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/lustre_lite.h"
#include "llite_internal.h"
-#include "../include/linux/lustre_compat25.h"
/**
* Implements Linux VM address_space::invalidatepage() method. This method is
@@ -161,7 +159,7 @@ static int ll_releasepage(struct page *vmpage, gfp_t gfp_mask)
return result;
}
-#define MAX_DIRECTIO_SIZE (2*1024*1024*1024UL)
+#define MAX_DIRECTIO_SIZE (2 * 1024 * 1024 * 1024UL)
static inline int ll_get_user_pages(int rw, unsigned long user_addr,
size_t size, struct page ***pages,
@@ -214,10 +212,10 @@ ssize_t ll_direct_rw_pages(const struct lu_env *env, struct cl_io *io,
int i;
ssize_t rc = 0;
loff_t file_offset = pv->ldp_start_offset;
- long size = pv->ldp_size;
+ size_t size = pv->ldp_size;
int page_count = pv->ldp_nr;
struct page **pages = pv->ldp_pages;
- long page_size = cl_page_size(obj);
+ size_t page_size = cl_page_size(obj);
bool do_io;
int io_pages = 0;
@@ -346,7 +344,6 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter)
struct cl_io *io;
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
- struct vvp_object *obj = cl_inode2vvp(inode);
loff_t file_offset = iocb->ki_pos;
ssize_t count = iov_iter_count(iter);
ssize_t tot_bytes = 0, result = 0;
@@ -375,14 +372,6 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter)
io = vvp_env_io(env)->vui_cl.cis_io;
LASSERT(io);
- /* 0. Need locking between buffered and direct access. and race with
- * size changing by concurrent truncates and writes.
- * 1. Need inode mutex to operate transient pages.
- */
- if (iov_iter_rw(iter) == READ)
- inode_lock(inode);
-
- LASSERT(obj->vob_transient_pages == 0);
while (iov_iter_count(iter)) {
struct page **pages;
size_t offs;
@@ -430,10 +419,6 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter)
file_offset += result;
}
out:
- LASSERT(obj->vob_transient_pages == 0);
- if (iov_iter_rw(iter) == READ)
- inode_unlock(inode);
-
if (tot_bytes > 0) {
struct vvp_io *vio = vvp_env_io(env);
@@ -616,6 +601,13 @@ static int ll_write_end(struct file *file, struct address_space *mapping,
LASSERT(from == 0);
vio->u.write.vui_to = from + copied;
+ /*
+ * To address the deadlock in balance_dirty_pages() where
+ * this dirty page may be written back in the same thread.
+ */
+ if (PageDirty(vmpage))
+ unplug = true;
+
/* We may have one full RPC, commit it soon */
if (plist->pl_nr >= PTLRPC_MAX_BRW_PAGES)
unplug = true;
diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c
index c1cb6b19e724..0677513476ec 100644
--- a/drivers/staging/lustre/lustre/llite/statahead.c
+++ b/drivers/staging/lustre/lustre/llite/statahead.c
@@ -39,7 +39,6 @@
#define DEBUG_SUBSYSTEM S_LLITE
#include "../include/obd_support.h"
-#include "../include/lustre_lite.h"
#include "../include/lustre_dlm.h"
#include "llite_internal.h"
@@ -50,24 +49,26 @@ enum se_stat {
SA_ENTRY_INIT = 0, /** init entry */
SA_ENTRY_SUCC = 1, /** stat succeed */
SA_ENTRY_INVA = 2, /** invalid entry */
- SA_ENTRY_DEST = 3, /** entry to be destroyed */
};
-struct ll_sa_entry {
- /* link into sai->sai_entries */
- struct list_head se_link;
- /* link into sai->sai_entries_{received,stated} */
+/*
+ * sa_entry is not refcounted: statahead thread allocates it and do async stat,
+ * and in async stat callback ll_statahead_interpret() will add it into
+ * sai_interim_entries, later statahead thread will call sa_handle_callback() to
+ * instantiate entry and move it into sai_entries, and then only scanner process
+ * can access and free it.
+ */
+struct sa_entry {
+ /* link into sai_interim_entries or sai_entries */
struct list_head se_list;
/* link into sai hash table locally */
struct list_head se_hash;
- /* entry reference count */
- atomic_t se_refcount;
/* entry index in the sai */
__u64 se_index;
/* low layer ldlm lock handle */
__u64 se_handle;
/* entry status */
- enum se_stat se_stat;
+ enum se_stat se_state;
/* entry size, contains name */
int se_size;
/* pointer to async getattr enqueue info */
@@ -83,27 +84,24 @@ struct ll_sa_entry {
static unsigned int sai_generation;
static DEFINE_SPINLOCK(sai_generation_lock);
-/*
- * The entry only can be released by the caller, it is necessary to hold lock.
- */
-static inline int ll_sa_entry_stated(struct ll_sa_entry *entry)
+/* sa_entry is ready to use */
+static inline int sa_ready(struct sa_entry *entry)
{
smp_rmb();
- return (entry->se_stat != SA_ENTRY_INIT);
+ return (entry->se_state != SA_ENTRY_INIT);
}
-static inline int ll_sa_entry_hash(int val)
+/* hash value to put in sai_cache */
+static inline int sa_hash(int val)
{
return val & LL_SA_CACHE_MASK;
}
-/*
- * Insert entry to hash SA table.
- */
+/* hash entry into sai_cache */
static inline void
-ll_sa_entry_enhash(struct ll_statahead_info *sai, struct ll_sa_entry *entry)
+sa_rehash(struct ll_statahead_info *sai, struct sa_entry *entry)
{
- int i = ll_sa_entry_hash(entry->se_qstr.hash);
+ int i = sa_hash(entry->se_qstr.hash);
spin_lock(&sai->sai_cache_lock[i]);
list_add_tail(&entry->se_hash, &sai->sai_cache[i]);
@@ -114,9 +112,9 @@ ll_sa_entry_enhash(struct ll_statahead_info *sai, struct ll_sa_entry *entry)
* Remove entry from SA table.
*/
static inline void
-ll_sa_entry_unhash(struct ll_statahead_info *sai, struct ll_sa_entry *entry)
+sa_unhash(struct ll_statahead_info *sai, struct sa_entry *entry)
{
- int i = ll_sa_entry_hash(entry->se_qstr.hash);
+ int i = sa_hash(entry->se_qstr.hash);
spin_lock(&sai->sai_cache_lock[i]);
list_del_init(&entry->se_hash);
@@ -129,19 +127,21 @@ static inline int agl_should_run(struct ll_statahead_info *sai,
return (inode && S_ISREG(inode->i_mode) && sai->sai_agl_valid);
}
+/* statahead window is full */
static inline int sa_sent_full(struct ll_statahead_info *sai)
{
return atomic_read(&sai->sai_cache_count) >= sai->sai_max;
}
-static inline int sa_received_empty(struct ll_statahead_info *sai)
+/* got async stat replies */
+static inline int sa_has_callback(struct ll_statahead_info *sai)
{
- return list_empty(&sai->sai_entries_received);
+ return !list_empty(&sai->sai_interim_entries);
}
static inline int agl_list_empty(struct ll_statahead_info *sai)
{
- return list_empty(&sai->sai_entries_agl);
+ return list_empty(&sai->sai_agls);
}
/**
@@ -157,7 +157,7 @@ static inline int sa_low_hit(struct ll_statahead_info *sai)
}
/*
- * If the given index is behind of statahead window more than
+ * if the given index is behind of statahead window more than
* SA_OMITTED_ENTRY_MAX, then it is old.
*/
static inline int is_omitted_entry(struct ll_statahead_info *sai, __u64 index)
@@ -166,20 +166,17 @@ static inline int is_omitted_entry(struct ll_statahead_info *sai, __u64 index)
sai->sai_index);
}
-/*
- * Insert it into sai_entries tail when init.
- */
-static struct ll_sa_entry *
-ll_sa_entry_alloc(struct dentry *parent,
- struct ll_statahead_info *sai, __u64 index,
- const char *name, int len)
+/* allocate sa_entry and hash it to allow scanner process to find it */
+static struct sa_entry *
+sa_alloc(struct dentry *parent, struct ll_statahead_info *sai, __u64 index,
+ const char *name, int len)
{
struct ll_inode_info *lli;
- struct ll_sa_entry *entry;
+ struct sa_entry *entry;
int entry_size;
char *dname;
- entry_size = sizeof(struct ll_sa_entry) + (len & ~3) + 4;
+ entry_size = sizeof(struct sa_entry) + (len & ~3) + 4;
entry = kzalloc(entry_size, GFP_NOFS);
if (unlikely(!entry))
return ERR_PTR(-ENOMEM);
@@ -188,34 +185,9 @@ ll_sa_entry_alloc(struct dentry *parent,
len, name, entry, index);
entry->se_index = index;
-
- /*
- * Statahead entry reference rules:
- *
- * 1) When statahead entry is initialized, its reference is set as 2.
- * One reference is used by the directory scanner. When the scanner
- * searches the statahead cache for the given name, it can perform
- * lockless hash lookup (only the scanner can remove entry from hash
- * list), and once found, it needn't to call "atomic_inc()" for the
- * entry reference. So the performance is improved. After using the
- * statahead entry, the scanner will call "atomic_dec()" to drop the
- * reference held when initialization. If it is the last reference,
- * the statahead entry will be freed.
- *
- * 2) All other threads, including statahead thread and ptlrpcd thread,
- * when they process the statahead entry, the reference for target
- * should be held to guarantee the entry will not be released by the
- * directory scanner. After processing the entry, these threads will
- * drop the entry reference. If it is the last reference, the entry
- * will be freed.
- *
- * The second reference when initializes the statahead entry is used
- * by the statahead thread, following the rule 2).
- */
- atomic_set(&entry->se_refcount, 2);
- entry->se_stat = SA_ENTRY_INIT;
+ entry->se_state = SA_ENTRY_INIT;
entry->se_size = entry_size;
- dname = (char *)entry + sizeof(struct ll_sa_entry);
+ dname = (char *)entry + sizeof(struct sa_entry);
memcpy(dname, name, len);
dname[len] = 0;
@@ -223,11 +195,10 @@ ll_sa_entry_alloc(struct dentry *parent,
entry->se_qstr.len = len;
entry->se_qstr.name = dname;
- lli = ll_i2info(sai->sai_inode);
+ lli = ll_i2info(sai->sai_dentry->d_inode);
spin_lock(&lli->lli_sa_lock);
- list_add_tail(&entry->se_link, &sai->sai_entries);
INIT_LIST_HEAD(&entry->se_list);
- ll_sa_entry_enhash(sai, entry);
+ sa_rehash(sai, entry);
spin_unlock(&lli->lli_sa_lock);
atomic_inc(&sai->sai_cache_count);
@@ -235,18 +206,29 @@ ll_sa_entry_alloc(struct dentry *parent,
return entry;
}
+/* free sa_entry, which should have been unhashed and not in any list */
+static void sa_free(struct ll_statahead_info *sai, struct sa_entry *entry)
+{
+ CDEBUG(D_READA, "free sa entry %.*s(%p) index %llu\n",
+ entry->se_qstr.len, entry->se_qstr.name, entry,
+ entry->se_index);
+
+ LASSERT(list_empty(&entry->se_list));
+ LASSERT(list_empty(&entry->se_hash));
+
+ kfree(entry);
+ atomic_dec(&sai->sai_cache_count);
+}
+
/*
- * Used by the directory scanner to search entry with name.
- *
- * Only the caller can remove the entry from hash, so it is unnecessary to hold
- * hash lock. It is caller's duty to release the init refcount on the entry, so
- * it is also unnecessary to increase refcount on the entry.
+ * find sa_entry by name, used by directory scanner, lock is not needed because
+ * only scanner can remove the entry from cache.
*/
-static struct ll_sa_entry *
-ll_sa_entry_get_byname(struct ll_statahead_info *sai, const struct qstr *qstr)
+static struct sa_entry *
+sa_get(struct ll_statahead_info *sai, const struct qstr *qstr)
{
- struct ll_sa_entry *entry;
- int i = ll_sa_entry_hash(qstr->hash);
+ struct sa_entry *entry;
+ int i = sa_hash(qstr->hash);
list_for_each_entry(entry, &sai->sai_cache[i], se_hash) {
if (entry->se_qstr.hash == qstr->hash &&
@@ -257,164 +239,126 @@ ll_sa_entry_get_byname(struct ll_statahead_info *sai, const struct qstr *qstr)
return NULL;
}
-/*
- * Used by the async getattr request callback to find entry with index.
- *
- * Inside lli_sa_lock to prevent others to change the list during the search.
- * It needs to increase entry refcount before returning to guarantee that the
- * entry cannot be freed by others.
- */
-static struct ll_sa_entry *
-ll_sa_entry_get_byindex(struct ll_statahead_info *sai, __u64 index)
-{
- struct ll_sa_entry *entry;
-
- list_for_each_entry(entry, &sai->sai_entries, se_link) {
- if (entry->se_index == index) {
- LASSERT(atomic_read(&entry->se_refcount) > 0);
- atomic_inc(&entry->se_refcount);
- return entry;
- }
- if (entry->se_index > index)
- break;
- }
- return NULL;
-}
-
-static void ll_sa_entry_cleanup(struct ll_statahead_info *sai,
- struct ll_sa_entry *entry)
-{
- struct md_enqueue_info *minfo = entry->se_minfo;
- struct ptlrpc_request *req = entry->se_req;
-
- if (minfo) {
- entry->se_minfo = NULL;
- ll_intent_release(&minfo->mi_it);
- iput(minfo->mi_dir);
- kfree(minfo);
- }
-
- if (req) {
- entry->se_req = NULL;
- ptlrpc_req_finished(req);
- }
-}
-
-static void ll_sa_entry_put(struct ll_statahead_info *sai,
- struct ll_sa_entry *entry)
-{
- if (atomic_dec_and_test(&entry->se_refcount)) {
- CDEBUG(D_READA, "free sa entry %.*s(%p) index %llu\n",
- entry->se_qstr.len, entry->se_qstr.name, entry,
- entry->se_index);
-
- LASSERT(list_empty(&entry->se_link));
- LASSERT(list_empty(&entry->se_list));
- LASSERT(list_empty(&entry->se_hash));
-
- ll_sa_entry_cleanup(sai, entry);
- iput(entry->se_inode);
-
- kfree(entry);
- atomic_dec(&sai->sai_cache_count);
- }
-}
-
+/* unhash and unlink sa_entry, and then free it */
static inline void
-do_sa_entry_fini(struct ll_statahead_info *sai, struct ll_sa_entry *entry)
+sa_kill(struct ll_statahead_info *sai, struct sa_entry *entry)
{
- struct ll_inode_info *lli = ll_i2info(sai->sai_inode);
+ struct ll_inode_info *lli = ll_i2info(sai->sai_dentry->d_inode);
LASSERT(!list_empty(&entry->se_hash));
- LASSERT(!list_empty(&entry->se_link));
+ LASSERT(!list_empty(&entry->se_list));
+ LASSERT(sa_ready(entry));
- ll_sa_entry_unhash(sai, entry);
+ sa_unhash(sai, entry);
spin_lock(&lli->lli_sa_lock);
- entry->se_stat = SA_ENTRY_DEST;
- list_del_init(&entry->se_link);
- if (likely(!list_empty(&entry->se_list)))
- list_del_init(&entry->se_list);
+ list_del_init(&entry->se_list);
spin_unlock(&lli->lli_sa_lock);
- ll_sa_entry_put(sai, entry);
+ if (entry->se_inode)
+ iput(entry->se_inode);
+
+ sa_free(sai, entry);
}
-/*
- * Delete it from sai_entries_stated list when fini.
- */
+/* called by scanner after use, sa_entry will be killed */
static void
-ll_sa_entry_fini(struct ll_statahead_info *sai, struct ll_sa_entry *entry)
+sa_put(struct ll_statahead_info *sai, struct sa_entry *entry)
{
- struct ll_sa_entry *pos, *next;
+ struct sa_entry *tmp, *next;
+
+ if (entry && entry->se_state == SA_ENTRY_SUCC) {
+ struct ll_sb_info *sbi = ll_i2sbi(sai->sai_dentry->d_inode);
+
+ sai->sai_hit++;
+ sai->sai_consecutive_miss = 0;
+ sai->sai_max = min(2 * sai->sai_max, sbi->ll_sa_max);
+ } else {
+ sai->sai_miss++;
+ sai->sai_consecutive_miss++;
+ }
if (entry)
- do_sa_entry_fini(sai, entry);
+ sa_kill(sai, entry);
- /* drop old entry, only 'scanner' process does this, no need to lock */
- list_for_each_entry_safe(pos, next, &sai->sai_entries, se_link) {
- if (!is_omitted_entry(sai, pos->se_index))
+ /*
+ * kill old completed entries, only scanner process does this, no need
+ * to lock
+ */
+ list_for_each_entry_safe(tmp, next, &sai->sai_entries, se_list) {
+ if (!is_omitted_entry(sai, tmp->se_index))
break;
- do_sa_entry_fini(sai, pos);
+ sa_kill(sai, tmp);
}
+
+ wake_up(&sai->sai_thread.t_ctl_waitq);
}
/*
- * Inside lli_sa_lock.
+ * update state and sort add entry to sai_entries by index, return true if
+ * scanner is waiting on this entry.
*/
-static void
-do_sa_entry_to_stated(struct ll_statahead_info *sai,
- struct ll_sa_entry *entry, enum se_stat stat)
+static bool
+__sa_make_ready(struct ll_statahead_info *sai, struct sa_entry *entry, int ret)
{
- struct ll_sa_entry *se;
- struct list_head *pos = &sai->sai_entries_stated;
+ struct list_head *pos = &sai->sai_entries;
+ __u64 index = entry->se_index;
+ struct sa_entry *se;
- if (!list_empty(&entry->se_list))
- list_del_init(&entry->se_list);
+ LASSERT(!sa_ready(entry));
+ LASSERT(list_empty(&entry->se_list));
- list_for_each_entry_reverse(se, &sai->sai_entries_stated, se_list) {
+ list_for_each_entry_reverse(se, &sai->sai_entries, se_list) {
if (se->se_index < entry->se_index) {
pos = &se->se_list;
break;
}
}
-
list_add(&entry->se_list, pos);
- entry->se_stat = stat;
+ entry->se_state = ret < 0 ? SA_ENTRY_INVA : SA_ENTRY_SUCC;
+
+ return (index == sai->sai_index_wait);
}
/*
- * Move entry to sai_entries_stated and sort with the index.
- * \retval 1 -- entry to be destroyed.
- * \retval 0 -- entry is inserted into stated list.
+ * release resources used in async stat RPC, update entry state and wakeup if
+ * scanner process it waiting on this entry.
*/
-static int
-ll_sa_entry_to_stated(struct ll_statahead_info *sai,
- struct ll_sa_entry *entry, enum se_stat stat)
+static void
+sa_make_ready(struct ll_statahead_info *sai, struct sa_entry *entry, int ret)
{
- struct ll_inode_info *lli = ll_i2info(sai->sai_inode);
- int ret = 1;
+ struct ll_inode_info *lli = ll_i2info(sai->sai_dentry->d_inode);
+ struct md_enqueue_info *minfo = entry->se_minfo;
+ struct ptlrpc_request *req = entry->se_req;
+ bool wakeup;
+
+ /* release resources used in RPC */
+ if (minfo) {
+ entry->se_minfo = NULL;
+ ll_intent_release(&minfo->mi_it);
+ iput(minfo->mi_dir);
+ kfree(minfo);
+ }
- ll_sa_entry_cleanup(sai, entry);
+ if (req) {
+ entry->se_req = NULL;
+ ptlrpc_req_finished(req);
+ }
spin_lock(&lli->lli_sa_lock);
- if (likely(entry->se_stat != SA_ENTRY_DEST)) {
- do_sa_entry_to_stated(sai, entry, stat);
- ret = 0;
- }
+ wakeup = __sa_make_ready(sai, entry, ret);
spin_unlock(&lli->lli_sa_lock);
- return ret;
+ if (wakeup)
+ wake_up(&sai->sai_waitq);
}
-/*
- * Insert inode into the list of sai_entries_agl.
- */
+/* Insert inode into the list of sai_agls. */
static void ll_agl_add(struct ll_statahead_info *sai,
struct inode *inode, int index)
{
struct ll_inode_info *child = ll_i2info(inode);
- struct ll_inode_info *parent = ll_i2info(sai->sai_inode);
+ struct ll_inode_info *parent = ll_i2info(sai->sai_dentry->d_inode);
int added = 0;
spin_lock(&child->lli_agl_lock);
@@ -426,9 +370,9 @@ static void ll_agl_add(struct ll_statahead_info *sai,
igrab(inode);
spin_lock(&parent->lli_agl_lock);
- if (list_empty(&sai->sai_entries_agl))
+ if (list_empty(&sai->sai_agls))
added = 1;
- list_add_tail(&child->lli_agl_list, &sai->sai_entries_agl);
+ list_add_tail(&child->lli_agl_list, &sai->sai_agls);
spin_unlock(&parent->lli_agl_lock);
} else {
spin_unlock(&child->lli_agl_lock);
@@ -438,8 +382,10 @@ static void ll_agl_add(struct ll_statahead_info *sai,
wake_up(&sai->sai_agl_thread.t_ctl_waitq);
}
-static struct ll_statahead_info *ll_sai_alloc(void)
+/* allocate sai */
+static struct ll_statahead_info *ll_sai_alloc(struct dentry *dentry)
{
+ struct ll_inode_info *lli = ll_i2info(dentry->d_inode);
struct ll_statahead_info *sai;
int i;
@@ -447,24 +393,18 @@ static struct ll_statahead_info *ll_sai_alloc(void)
if (!sai)
return NULL;
+ sai->sai_dentry = dget(dentry);
atomic_set(&sai->sai_refcount, 1);
- spin_lock(&sai_generation_lock);
- sai->sai_generation = ++sai_generation;
- if (unlikely(sai_generation == 0))
- sai->sai_generation = ++sai_generation;
- spin_unlock(&sai_generation_lock);
-
sai->sai_max = LL_SA_RPC_MIN;
sai->sai_index = 1;
init_waitqueue_head(&sai->sai_waitq);
init_waitqueue_head(&sai->sai_thread.t_ctl_waitq);
init_waitqueue_head(&sai->sai_agl_thread.t_ctl_waitq);
+ INIT_LIST_HEAD(&sai->sai_interim_entries);
INIT_LIST_HEAD(&sai->sai_entries);
- INIT_LIST_HEAD(&sai->sai_entries_received);
- INIT_LIST_HEAD(&sai->sai_entries_stated);
- INIT_LIST_HEAD(&sai->sai_entries_agl);
+ INIT_LIST_HEAD(&sai->sai_agls);
for (i = 0; i < LL_SA_CACHE_SIZE; i++) {
INIT_LIST_HEAD(&sai->sai_cache[i]);
@@ -472,63 +412,74 @@ static struct ll_statahead_info *ll_sai_alloc(void)
}
atomic_set(&sai->sai_cache_count, 0);
+ spin_lock(&sai_generation_lock);
+ lli->lli_sa_generation = ++sai_generation;
+ if (unlikely(!sai_generation))
+ lli->lli_sa_generation = ++sai_generation;
+ spin_unlock(&sai_generation_lock);
+
return sai;
}
-static inline struct ll_statahead_info *
-ll_sai_get(struct ll_statahead_info *sai)
+/* free sai */
+static inline void ll_sai_free(struct ll_statahead_info *sai)
{
- atomic_inc(&sai->sai_refcount);
+ LASSERT(sai->sai_dentry);
+ dput(sai->sai_dentry);
+ kfree(sai);
+}
+
+/*
+ * take refcount of sai if sai for @dir exists, which means statahead is on for
+ * this directory.
+ */
+static inline struct ll_statahead_info *ll_sai_get(struct inode *dir)
+{
+ struct ll_inode_info *lli = ll_i2info(dir);
+ struct ll_statahead_info *sai = NULL;
+
+ spin_lock(&lli->lli_sa_lock);
+ sai = lli->lli_sai;
+ if (sai)
+ atomic_inc(&sai->sai_refcount);
+ spin_unlock(&lli->lli_sa_lock);
+
return sai;
}
+/*
+ * put sai refcount after use, if refcount reaches zero, free sai and sa_entries
+ * attached to it.
+ */
static void ll_sai_put(struct ll_statahead_info *sai)
{
- struct inode *inode = sai->sai_inode;
- struct ll_inode_info *lli = ll_i2info(inode);
+ struct ll_inode_info *lli = ll_i2info(sai->sai_dentry->d_inode);
if (atomic_dec_and_lock(&sai->sai_refcount, &lli->lli_sa_lock)) {
- struct ll_sa_entry *entry, *next;
-
- if (unlikely(atomic_read(&sai->sai_refcount) > 0)) {
- /* It is race case, the interpret callback just hold
- * a reference count
- */
- spin_unlock(&lli->lli_sa_lock);
- return;
- }
-
- LASSERT(!lli->lli_opendir_key);
- LASSERT(thread_is_stopped(&sai->sai_thread));
- LASSERT(thread_is_stopped(&sai->sai_agl_thread));
+ struct ll_sb_info *sbi = ll_i2sbi(sai->sai_dentry->d_inode);
+ struct sa_entry *entry, *next;
lli->lli_sai = NULL;
- lli->lli_opendir_pid = 0;
spin_unlock(&lli->lli_sa_lock);
- if (sai->sai_sent > sai->sai_replied)
- CDEBUG(D_READA, "statahead for dir "DFID
- " does not finish: [sent:%llu] [replied:%llu]\n",
- PFID(&lli->lli_fid),
- sai->sai_sent, sai->sai_replied);
+ LASSERT(thread_is_stopped(&sai->sai_thread));
+ LASSERT(thread_is_stopped(&sai->sai_agl_thread));
+ LASSERT(sai->sai_sent == sai->sai_replied);
+ LASSERT(!sa_has_callback(sai));
list_for_each_entry_safe(entry, next, &sai->sai_entries,
- se_link)
- do_sa_entry_fini(sai, entry);
-
- LASSERT(list_empty(&sai->sai_entries));
- LASSERT(list_empty(&sai->sai_entries_received));
- LASSERT(list_empty(&sai->sai_entries_stated));
+ se_list)
+ sa_kill(sai, entry);
LASSERT(atomic_read(&sai->sai_cache_count) == 0);
- LASSERT(list_empty(&sai->sai_entries_agl));
+ LASSERT(list_empty(&sai->sai_agls));
- iput(inode);
- kfree(sai);
+ ll_sai_free(sai);
+ atomic_dec(&sbi->ll_sa_running);
}
}
-/* Do NOT forget to drop inode refcount when into sai_entries_agl. */
+/* Do NOT forget to drop inode refcount when into sai_agls. */
static void ll_agl_trigger(struct inode *inode, struct ll_statahead_info *sai)
{
struct ll_inode_info *lli = ll_i2info(inode);
@@ -588,29 +539,21 @@ static void ll_agl_trigger(struct inode *inode, struct ll_statahead_info *sai)
iput(inode);
}
-static void ll_post_statahead(struct ll_statahead_info *sai)
+/*
+ * prepare inode for sa entry, add it into agl list, now sa_entry is ready
+ * to be used by scanner process.
+ */
+static void sa_instantiate(struct ll_statahead_info *sai,
+ struct sa_entry *entry)
{
- struct inode *dir = sai->sai_inode;
+ struct inode *dir = sai->sai_dentry->d_inode;
struct inode *child;
- struct ll_inode_info *lli = ll_i2info(dir);
- struct ll_sa_entry *entry;
struct md_enqueue_info *minfo;
struct lookup_intent *it;
struct ptlrpc_request *req;
struct mdt_body *body;
int rc = 0;
- spin_lock(&lli->lli_sa_lock);
- if (unlikely(list_empty(&sai->sai_entries_received))) {
- spin_unlock(&lli->lli_sa_lock);
- return;
- }
- entry = list_entry(sai->sai_entries_received.next,
- struct ll_sa_entry, se_list);
- atomic_inc(&entry->se_refcount);
- list_del_init(&entry->se_list);
- spin_unlock(&lli->lli_sa_lock);
-
LASSERT(entry->se_handle != 0);
minfo = entry->se_minfo;
@@ -632,7 +575,7 @@ static void ll_post_statahead(struct ll_statahead_info *sai)
/* XXX: No fid in reply, this is probably cross-ref case.
* SA can't handle it yet.
*/
- if (body->valid & OBD_MD_MDS) {
+ if (body->mbo_valid & OBD_MD_MDS) {
rc = -EAGAIN;
goto out;
}
@@ -641,7 +584,7 @@ static void ll_post_statahead(struct ll_statahead_info *sai)
* revalidate.
*/
/* unlinked and re-created with the same name */
- if (unlikely(!lu_fid_eq(&minfo->mi_data.op_fid2, &body->fid1))) {
+ if (unlikely(!lu_fid_eq(&minfo->mi_data.op_fid2, &body->mbo_fid1))) {
entry->se_inode = NULL;
iput(child);
child = NULL;
@@ -659,8 +602,9 @@ static void ll_post_statahead(struct ll_statahead_info *sai)
if (rc)
goto out;
- CDEBUG(D_DLMTRACE, "%s: setting l_data to inode "DFID"%p\n",
+ CDEBUG(D_READA, "%s: setting %.*s" DFID " l_data to inode %p\n",
ll_get_fsname(child->i_sb, NULL, 0),
+ entry->se_qstr.len, entry->se_qstr.name,
PFID(ll_inode2fid(child)), child);
ll_set_lock_data(ll_i2sbi(dir)->ll_md_exp, child, it, NULL);
@@ -670,34 +614,75 @@ static void ll_post_statahead(struct ll_statahead_info *sai)
ll_agl_add(sai, child, entry->se_index);
out:
- /* The "ll_sa_entry_to_stated()" will drop related ldlm ibits lock
- * reference count by calling "ll_intent_drop_lock()" in spite of the
- * above operations failed or not. Do not worry about calling
- * "ll_intent_drop_lock()" more than once.
+ /*
+ * sa_make_ready() will drop ldlm ibits lock refcount by calling
+ * ll_intent_drop_lock() in spite of failures. Do not worry about
+ * calling ll_intent_drop_lock() more than once.
*/
- rc = ll_sa_entry_to_stated(sai, entry,
- rc < 0 ? SA_ENTRY_INVA : SA_ENTRY_SUCC);
- if (rc == 0 && entry->se_index == sai->sai_index_wait)
- wake_up(&sai->sai_waitq);
- ll_sa_entry_put(sai, entry);
+ sa_make_ready(sai, entry, rc);
}
+/* once there are async stat replies, instantiate sa_entry from replies */
+static void sa_handle_callback(struct ll_statahead_info *sai)
+{
+ struct ll_inode_info *lli;
+
+ lli = ll_i2info(sai->sai_dentry->d_inode);
+
+ while (sa_has_callback(sai)) {
+ struct sa_entry *entry;
+
+ spin_lock(&lli->lli_sa_lock);
+ if (unlikely(!sa_has_callback(sai))) {
+ spin_unlock(&lli->lli_sa_lock);
+ break;
+ }
+ entry = list_entry(sai->sai_interim_entries.next,
+ struct sa_entry, se_list);
+ list_del_init(&entry->se_list);
+ spin_unlock(&lli->lli_sa_lock);
+
+ sa_instantiate(sai, entry);
+ }
+}
+
+/*
+ * callback for async stat, because this is called in ptlrpcd context, we only
+ * put sa_entry in sai_cb_entries list, and let sa_handle_callback() to really
+ * prepare inode and instantiate sa_entry later.
+ */
static int ll_statahead_interpret(struct ptlrpc_request *req,
struct md_enqueue_info *minfo, int rc)
{
struct lookup_intent *it = &minfo->mi_it;
struct inode *dir = minfo->mi_dir;
struct ll_inode_info *lli = ll_i2info(dir);
- struct ll_statahead_info *sai = NULL;
- struct ll_sa_entry *entry;
- __u64 handle = 0;
- int wakeup;
+ struct ll_statahead_info *sai = lli->lli_sai;
+ struct sa_entry *entry = (struct sa_entry *)minfo->mi_cbdata;
+ __u64 handle = 0;
+ bool wakeup;
if (it_disposition(it, DISP_LOOKUP_NEG))
rc = -ENOENT;
- if (rc == 0) {
- /* release ibits lock ASAP to avoid deadlock when statahead
+ /*
+ * because statahead thread will wait for all inflight RPC to finish,
+ * sai should be always valid, no need to refcount
+ */
+ LASSERT(sai);
+ LASSERT(!thread_is_stopped(&sai->sai_thread));
+ LASSERT(entry);
+
+ CDEBUG(D_READA, "sa_entry %.*s rc %d\n",
+ entry->se_qstr.len, entry->se_qstr.name, rc);
+
+ if (rc) {
+ ll_intent_release(it);
+ iput(dir);
+ kfree(minfo);
+ } else {
+ /*
+ * release ibits lock ASAP to avoid deadlock when statahead
* thread enqueues lock on parent in readdir and another
* process enqueues lock on child with parent lock held, eg.
* unlink.
@@ -707,65 +692,32 @@ static int ll_statahead_interpret(struct ptlrpc_request *req,
}
spin_lock(&lli->lli_sa_lock);
- /* stale entry */
- if (unlikely(!lli->lli_sai ||
- lli->lli_sai->sai_generation != minfo->mi_generation)) {
- spin_unlock(&lli->lli_sa_lock);
- rc = -ESTALE;
- goto out;
+ if (rc) {
+ wakeup = __sa_make_ready(sai, entry, rc);
} else {
- sai = ll_sai_get(lli->lli_sai);
- if (unlikely(!thread_is_running(&sai->sai_thread))) {
- sai->sai_replied++;
- spin_unlock(&lli->lli_sa_lock);
- rc = -EBADFD;
- goto out;
- }
-
- entry = ll_sa_entry_get_byindex(sai, minfo->mi_cbdata);
- if (!entry) {
- sai->sai_replied++;
- spin_unlock(&lli->lli_sa_lock);
- rc = -EIDRM;
- goto out;
- }
-
- if (rc != 0) {
- do_sa_entry_to_stated(sai, entry, SA_ENTRY_INVA);
- wakeup = (entry->se_index == sai->sai_index_wait);
- } else {
- entry->se_minfo = minfo;
- entry->se_req = ptlrpc_request_addref(req);
- /* Release the async ibits lock ASAP to avoid deadlock
- * when statahead thread tries to enqueue lock on parent
- * for readpage and other tries to enqueue lock on child
- * with parent's lock held, for example: unlink.
- */
- entry->se_handle = handle;
- wakeup = list_empty(&sai->sai_entries_received);
- list_add_tail(&entry->se_list,
- &sai->sai_entries_received);
- }
- sai->sai_replied++;
- spin_unlock(&lli->lli_sa_lock);
-
- ll_sa_entry_put(sai, entry);
- if (wakeup)
- wake_up(&sai->sai_thread.t_ctl_waitq);
+ entry->se_minfo = minfo;
+ entry->se_req = ptlrpc_request_addref(req);
+ /*
+ * Release the async ibits lock ASAP to avoid deadlock
+ * when statahead thread tries to enqueue lock on parent
+ * for readpage and other tries to enqueue lock on child
+ * with parent's lock held, for example: unlink.
+ */
+ entry->se_handle = handle;
+ wakeup = !sa_has_callback(sai);
+ list_add_tail(&entry->se_list, &sai->sai_interim_entries);
}
+ sai->sai_replied++;
+
+ if (wakeup)
+ wake_up(&sai->sai_thread.t_ctl_waitq);
+ spin_unlock(&lli->lli_sa_lock);
-out:
- if (rc != 0) {
- ll_intent_release(it);
- iput(dir);
- kfree(minfo);
- }
- if (sai)
- ll_sai_put(sai);
return rc;
}
-static void sa_args_fini(struct md_enqueue_info *minfo,
+/* finish async stat RPC arguments */
+static void sa_fini_data(struct md_enqueue_info *minfo,
struct ldlm_enqueue_info *einfo)
{
LASSERT(minfo && einfo);
@@ -777,12 +729,11 @@ static void sa_args_fini(struct md_enqueue_info *minfo,
/**
* prepare arguments for async stat RPC.
*/
-static int sa_args_init(struct inode *dir, struct inode *child,
- struct ll_sa_entry *entry, struct md_enqueue_info **pmi,
+static int sa_prep_data(struct inode *dir, struct inode *child,
+ struct sa_entry *entry, struct md_enqueue_info **pmi,
struct ldlm_enqueue_info **pei)
{
const struct qstr *qstr = &entry->se_qstr;
- struct ll_inode_info *lli = ll_i2info(dir);
struct md_enqueue_info *minfo;
struct ldlm_enqueue_info *einfo;
struct md_op_data *op_data;
@@ -808,8 +759,7 @@ static int sa_args_init(struct inode *dir, struct inode *child,
minfo->mi_it.it_op = IT_GETATTR;
minfo->mi_dir = igrab(dir);
minfo->mi_cb = ll_statahead_interpret;
- minfo->mi_generation = lli->lli_sai->sai_generation;
- minfo->mi_cbdata = entry->se_index;
+ minfo->mi_cbdata = entry;
einfo->ei_type = LDLM_IBITS;
einfo->ei_mode = it_to_lock_mode(&minfo->mi_it);
@@ -824,31 +774,33 @@ static int sa_args_init(struct inode *dir, struct inode *child,
return 0;
}
-static int do_sa_lookup(struct inode *dir, struct ll_sa_entry *entry)
+/* async stat for file not found in dcache */
+static int sa_lookup(struct inode *dir, struct sa_entry *entry)
{
struct md_enqueue_info *minfo;
struct ldlm_enqueue_info *einfo;
int rc;
- rc = sa_args_init(dir, NULL, entry, &minfo, &einfo);
+ rc = sa_prep_data(dir, NULL, entry, &minfo, &einfo);
if (rc)
return rc;
rc = md_intent_getattr_async(ll_i2mdexp(dir), minfo, einfo);
- if (rc < 0)
- sa_args_fini(minfo, einfo);
+ if (rc)
+ sa_fini_data(minfo, einfo);
return rc;
}
/**
- * similar to ll_revalidate_it().
- * \retval 1 -- dentry valid
- * \retval 0 -- will send stat-ahead request
- * \retval others -- prepare stat-ahead request failed
+ * async stat for file found in dcache, similar to .revalidate
+ *
+ * \retval 1 dentry valid, no RPC sent
+ * \retval 0 dentry invalid, will send async stat RPC
+ * \retval negative number upon error
*/
-static int do_sa_revalidate(struct inode *dir, struct ll_sa_entry *entry,
- struct dentry *dentry)
+static int sa_revalidate(struct inode *dir, struct sa_entry *entry,
+ struct dentry *dentry)
{
struct inode *inode = d_inode(dentry);
struct lookup_intent it = { .it_op = IT_GETATTR,
@@ -872,7 +824,7 @@ static int do_sa_revalidate(struct inode *dir, struct ll_sa_entry *entry,
return 1;
}
- rc = sa_args_init(dir, inode, entry, &minfo, &einfo);
+ rc = sa_prep_data(dir, inode, entry, &minfo, &einfo);
if (rc) {
entry->se_inode = NULL;
iput(inode);
@@ -880,56 +832,50 @@ static int do_sa_revalidate(struct inode *dir, struct ll_sa_entry *entry,
}
rc = md_intent_getattr_async(ll_i2mdexp(dir), minfo, einfo);
- if (rc < 0) {
+ if (rc) {
entry->se_inode = NULL;
iput(inode);
- sa_args_fini(minfo, einfo);
+ sa_fini_data(minfo, einfo);
}
return rc;
}
-static void ll_statahead_one(struct dentry *parent, const char *entry_name,
- int entry_name_len)
+/* async stat for file with @name */
+static void sa_statahead(struct dentry *parent, const char *name, int len)
{
struct inode *dir = d_inode(parent);
struct ll_inode_info *lli = ll_i2info(dir);
struct ll_statahead_info *sai = lli->lli_sai;
struct dentry *dentry = NULL;
- struct ll_sa_entry *entry;
+ struct sa_entry *entry;
int rc;
- int rc1;
- entry = ll_sa_entry_alloc(parent, sai, sai->sai_index, entry_name,
- entry_name_len);
+ entry = sa_alloc(parent, sai, sai->sai_index, name, len);
if (IS_ERR(entry))
return;
dentry = d_lookup(parent, &entry->se_qstr);
if (!dentry) {
- rc = do_sa_lookup(dir, entry);
+ rc = sa_lookup(dir, entry);
} else {
- rc = do_sa_revalidate(dir, entry, dentry);
+ rc = sa_revalidate(dir, entry, dentry);
if (rc == 1 && agl_should_run(sai, d_inode(dentry)))
ll_agl_add(sai, d_inode(dentry), entry->se_index);
+ }
+ if (dentry)
dput(dentry);
- }
- if (rc) {
- rc1 = ll_sa_entry_to_stated(sai, entry,
- rc < 0 ? SA_ENTRY_INVA : SA_ENTRY_SUCC);
- if (rc1 == 0 && entry->se_index == sai->sai_index_wait)
- wake_up(&sai->sai_waitq);
- } else {
+ if (rc)
+ sa_make_ready(sai, entry, rc);
+ else
sai->sai_sent++;
- }
sai->sai_index++;
- /* drop one refcount on entry by ll_sa_entry_alloc */
- ll_sa_entry_put(sai, entry);
}
+/* async glimpse (agl) thread main function */
static int ll_agl_thread(void *arg)
{
struct dentry *parent = arg;
@@ -937,10 +883,12 @@ static int ll_agl_thread(void *arg)
struct ll_inode_info *plli = ll_i2info(dir);
struct ll_inode_info *clli;
struct ll_sb_info *sbi = ll_i2sbi(dir);
- struct ll_statahead_info *sai = ll_sai_get(plli->lli_sai);
- struct ptlrpc_thread *thread = &sai->sai_agl_thread;
+ struct ll_statahead_info *sai;
+ struct ptlrpc_thread *thread;
struct l_wait_info lwi = { 0 };
+ sai = ll_sai_get(dir);
+ thread = &sai->sai_agl_thread;
thread->t_pid = current_pid();
CDEBUG(D_READA, "agl thread started: sai %p, parent %pd\n",
sai, parent);
@@ -959,7 +907,7 @@ static int ll_agl_thread(void *arg)
while (1) {
l_wait_event(thread->t_ctl_waitq,
- !list_empty(&sai->sai_entries_agl) ||
+ !list_empty(&sai->sai_agls) ||
!thread_is_running(thread),
&lwi);
@@ -970,8 +918,8 @@ static int ll_agl_thread(void *arg)
/* The statahead thread maybe help to process AGL entries,
* so check whether list empty again.
*/
- if (!list_empty(&sai->sai_entries_agl)) {
- clli = list_entry(sai->sai_entries_agl.next,
+ if (!list_empty(&sai->sai_agls)) {
+ clli = list_entry(sai->sai_agls.next,
struct ll_inode_info, lli_agl_list);
list_del_init(&clli->lli_agl_list);
spin_unlock(&plli->lli_agl_lock);
@@ -983,8 +931,8 @@ static int ll_agl_thread(void *arg)
spin_lock(&plli->lli_agl_lock);
sai->sai_agl_valid = 0;
- while (!list_empty(&sai->sai_entries_agl)) {
- clli = list_entry(sai->sai_entries_agl.next,
+ while (!list_empty(&sai->sai_agls)) {
+ clli = list_entry(sai->sai_agls.next,
struct ll_inode_info, lli_agl_list);
list_del_init(&clli->lli_agl_list);
spin_unlock(&plli->lli_agl_lock);
@@ -1001,6 +949,7 @@ static int ll_agl_thread(void *arg)
return 0;
}
+/* start agl thread */
static void ll_start_agl(struct dentry *parent, struct ll_statahead_info *sai)
{
struct ptlrpc_thread *thread = &sai->sai_agl_thread;
@@ -1025,58 +974,71 @@ static void ll_start_agl(struct dentry *parent, struct ll_statahead_info *sai)
&lwi);
}
+/* statahead thread main function */
static int ll_statahead_thread(void *arg)
{
struct dentry *parent = arg;
struct inode *dir = d_inode(parent);
- struct ll_inode_info *plli = ll_i2info(dir);
- struct ll_inode_info *clli;
+ struct ll_inode_info *lli = ll_i2info(dir);
struct ll_sb_info *sbi = ll_i2sbi(dir);
- struct ll_statahead_info *sai = ll_sai_get(plli->lli_sai);
- struct ptlrpc_thread *thread = &sai->sai_thread;
- struct ptlrpc_thread *agl_thread = &sai->sai_agl_thread;
- struct page *page;
+ struct ll_statahead_info *sai;
+ struct ptlrpc_thread *sa_thread;
+ struct ptlrpc_thread *agl_thread;
+ struct page *page = NULL;
__u64 pos = 0;
int first = 0;
int rc = 0;
- struct ll_dir_chain chain;
+ struct md_op_data *op_data;
struct l_wait_info lwi = { 0 };
- thread->t_pid = current_pid();
+ sai = ll_sai_get(dir);
+ sa_thread = &sai->sai_thread;
+ agl_thread = &sai->sai_agl_thread;
+ sa_thread->t_pid = current_pid();
CDEBUG(D_READA, "statahead thread starting: sai %p, parent %pd\n",
sai, parent);
+ op_data = ll_prep_md_op_data(NULL, dir, dir, NULL, 0, 0,
+ LUSTRE_OPC_ANY, dir);
+ if (IS_ERR(op_data)) {
+ rc = PTR_ERR(op_data);
+ goto out;
+ }
+
+ op_data->op_max_pages = ll_i2sbi(dir)->ll_md_brw_pages;
+
if (sbi->ll_flags & LL_SBI_AGL_ENABLED)
ll_start_agl(parent, sai);
atomic_inc(&sbi->ll_sa_total);
- spin_lock(&plli->lli_sa_lock);
- if (thread_is_init(thread))
+ spin_lock(&lli->lli_sa_lock);
+ if (thread_is_init(sa_thread))
/* If someone else has changed the thread state
* (e.g. already changed to SVC_STOPPING), we can't just
* blindly overwrite that setting.
*/
- thread_set_flags(thread, SVC_RUNNING);
- spin_unlock(&plli->lli_sa_lock);
- wake_up(&thread->t_ctl_waitq);
-
- ll_dir_chain_init(&chain);
- page = ll_get_dir_page(dir, pos, &chain);
+ thread_set_flags(sa_thread, SVC_RUNNING);
+ spin_unlock(&lli->lli_sa_lock);
+ wake_up(&sa_thread->t_ctl_waitq);
- while (1) {
+ while (pos != MDS_DIR_END_OFF && thread_is_running(sa_thread)) {
struct lu_dirpage *dp;
struct lu_dirent *ent;
+ sai->sai_in_readpage = 1;
+ page = ll_get_dir_page(dir, op_data, pos);
+ sai->sai_in_readpage = 0;
if (IS_ERR(page)) {
rc = PTR_ERR(page);
- CDEBUG(D_READA, "error reading dir "DFID" at %llu/%llu: [rc %d] [parent %u]\n",
+ CDEBUG(D_READA, "error reading dir "DFID" at %llu/%llu: opendir_pid = %u: rc = %d\n",
PFID(ll_inode2fid(dir)), pos, sai->sai_index,
- rc, plli->lli_opendir_pid);
- goto out;
+ lli->lli_opendir_pid, rc);
+ break;
}
dp = page_address(page);
- for (ent = lu_dirent_start(dp); ent;
+ for (ent = lu_dirent_start(dp);
+ ent && thread_is_running(sa_thread) && !sa_low_hit(sai);
ent = lu_dirent_next(ent)) {
__u64 hash;
int namelen;
@@ -1123,123 +1085,79 @@ static int ll_statahead_thread(void *arg)
if (unlikely(++first == 1))
continue;
-keep_it:
- l_wait_event(thread->t_ctl_waitq,
- !sa_sent_full(sai) ||
- !list_empty(&sai->sai_entries_received) ||
- !list_empty(&sai->sai_entries_agl) ||
- !thread_is_running(thread),
- &lwi);
-
-interpret_it:
- while (!list_empty(&sai->sai_entries_received))
- ll_post_statahead(sai);
-
- if (unlikely(!thread_is_running(thread))) {
- ll_release_page(page, 0);
- rc = 0;
- goto out;
- }
+ /* wait for spare statahead window */
+ do {
+ l_wait_event(sa_thread->t_ctl_waitq,
+ !sa_sent_full(sai) ||
+ sa_has_callback(sai) ||
+ !list_empty(&sai->sai_agls) ||
+ !thread_is_running(sa_thread),
+ &lwi);
+ sa_handle_callback(sai);
- /* If no window for metadata statahead, but there are
- * some AGL entries to be triggered, then try to help
- * to process the AGL entries.
- */
- if (sa_sent_full(sai)) {
- spin_lock(&plli->lli_agl_lock);
- while (!list_empty(&sai->sai_entries_agl)) {
- clli = list_entry(sai->sai_entries_agl.next,
+ spin_lock(&lli->lli_agl_lock);
+ while (sa_sent_full(sai) &&
+ !agl_list_empty(sai)) {
+ struct ll_inode_info *clli;
+
+ clli = list_entry(sai->sai_agls.next,
struct ll_inode_info, lli_agl_list);
list_del_init(&clli->lli_agl_list);
- spin_unlock(&plli->lli_agl_lock);
+ spin_unlock(&lli->lli_agl_lock);
+
ll_agl_trigger(&clli->lli_vfs_inode,
sai);
- if (!list_empty(&sai->sai_entries_received))
- goto interpret_it;
-
- if (unlikely(
- !thread_is_running(thread))) {
- ll_release_page(page, 0);
- rc = 0;
- goto out;
- }
-
- if (!sa_sent_full(sai))
- goto do_it;
-
- spin_lock(&plli->lli_agl_lock);
+ spin_lock(&lli->lli_agl_lock);
}
- spin_unlock(&plli->lli_agl_lock);
+ spin_unlock(&lli->lli_agl_lock);
+ } while (sa_sent_full(sai) &&
+ thread_is_running(sa_thread));
- goto keep_it;
- }
-
-do_it:
- ll_statahead_one(parent, name, namelen);
+ sa_statahead(parent, name, namelen);
}
- pos = le64_to_cpu(dp->ldp_hash_end);
- if (pos == MDS_DIR_END_OFF) {
- /*
- * End of directory reached.
- */
- ll_release_page(page, 0);
- while (1) {
- l_wait_event(thread->t_ctl_waitq,
- !list_empty(&sai->sai_entries_received) ||
- sai->sai_sent == sai->sai_replied ||
- !thread_is_running(thread),
- &lwi);
- while (!list_empty(&sai->sai_entries_received))
- ll_post_statahead(sai);
+ pos = le64_to_cpu(dp->ldp_hash_end);
+ ll_release_page(dir, page,
+ le32_to_cpu(dp->ldp_flags) & LDF_COLLIDE);
- if (unlikely(!thread_is_running(thread))) {
- rc = 0;
- goto out;
- }
+ if (sa_low_hit(sai)) {
+ rc = -EFAULT;
+ atomic_inc(&sbi->ll_sa_wrong);
+ CDEBUG(D_READA, "Statahead for dir "DFID" hit ratio too low: hit/miss %llu/%llu, sent/replied %llu/%llu, stopping statahead thread: pid %d\n",
+ PFID(&lli->lli_fid), sai->sai_hit,
+ sai->sai_miss, sai->sai_sent,
+ sai->sai_replied, current_pid());
+ break;
+ }
+ }
+ ll_finish_md_op_data(op_data);
- if (sai->sai_sent == sai->sai_replied &&
- list_empty(&sai->sai_entries_received))
- break;
- }
+ if (rc < 0) {
+ spin_lock(&lli->lli_sa_lock);
+ thread_set_flags(sa_thread, SVC_STOPPING);
+ lli->lli_sa_enabled = 0;
+ spin_unlock(&lli->lli_sa_lock);
+ }
- spin_lock(&plli->lli_agl_lock);
- while (!list_empty(&sai->sai_entries_agl) &&
- thread_is_running(thread)) {
- clli = list_entry(sai->sai_entries_agl.next,
- struct ll_inode_info, lli_agl_list);
- list_del_init(&clli->lli_agl_list);
- spin_unlock(&plli->lli_agl_lock);
- ll_agl_trigger(&clli->lli_vfs_inode, sai);
- spin_lock(&plli->lli_agl_lock);
- }
- spin_unlock(&plli->lli_agl_lock);
+ /*
+ * statahead is finished, but statahead entries need to be cached, wait
+ * for file release to stop me.
+ */
+ while (thread_is_running(sa_thread)) {
+ l_wait_event(sa_thread->t_ctl_waitq,
+ sa_has_callback(sai) ||
+ !agl_list_empty(sai) ||
+ !thread_is_running(sa_thread),
+ &lwi);
- rc = 0;
- goto out;
- } else if (1) {
- /*
- * chain is exhausted.
- * Normal case: continue to the next page.
- */
- ll_release_page(page, le32_to_cpu(dp->ldp_flags) &
- LDF_COLLIDE);
- page = ll_get_dir_page(dir, pos, &chain);
- } else {
- LASSERT(le32_to_cpu(dp->ldp_flags) & LDF_COLLIDE);
- ll_release_page(page, 1);
- /*
- * go into overflow page.
- */
- }
+ sa_handle_callback(sai);
}
-
out:
if (sai->sai_agl_valid) {
- spin_lock(&plli->lli_agl_lock);
+ spin_lock(&lli->lli_agl_lock);
thread_set_flags(agl_thread, SVC_STOPPING);
- spin_unlock(&plli->lli_agl_lock);
+ spin_unlock(&lli->lli_agl_lock);
wake_up(&agl_thread->t_ctl_waitq);
CDEBUG(D_READA, "stop agl thread: sai %p pid %u\n",
@@ -1249,84 +1167,93 @@ out:
&lwi);
} else {
/* Set agl_thread flags anyway. */
- thread_set_flags(&sai->sai_agl_thread, SVC_STOPPED);
+ thread_set_flags(agl_thread, SVC_STOPPED);
}
- ll_dir_chain_fini(&chain);
- spin_lock(&plli->lli_sa_lock);
- if (!list_empty(&sai->sai_entries_received)) {
- thread_set_flags(thread, SVC_STOPPING);
- spin_unlock(&plli->lli_sa_lock);
-
- /* To release the resources held by received entries. */
- while (!list_empty(&sai->sai_entries_received))
- ll_post_statahead(sai);
- spin_lock(&plli->lli_sa_lock);
+ /*
+ * wait for inflight statahead RPCs to finish, and then we can free sai
+ * safely because statahead RPC will access sai data
+ */
+ while (sai->sai_sent != sai->sai_replied) {
+ /* in case we're not woken up, timeout wait */
+ lwi = LWI_TIMEOUT(msecs_to_jiffies(MSEC_PER_SEC >> 3),
+ NULL, NULL);
+ l_wait_event(sa_thread->t_ctl_waitq,
+ sai->sai_sent == sai->sai_replied, &lwi);
}
- thread_set_flags(thread, SVC_STOPPED);
- spin_unlock(&plli->lli_sa_lock);
- wake_up(&sai->sai_waitq);
- wake_up(&thread->t_ctl_waitq);
- ll_sai_put(sai);
- dput(parent);
+
+ /* release resources held by statahead RPCs */
+ sa_handle_callback(sai);
+
+ spin_lock(&lli->lli_sa_lock);
+ thread_set_flags(sa_thread, SVC_STOPPED);
+ spin_unlock(&lli->lli_sa_lock);
+
CDEBUG(D_READA, "statahead thread stopped: sai %p, parent %pd\n",
sai, parent);
+
+ wake_up(&sai->sai_waitq);
+ wake_up(&sa_thread->t_ctl_waitq);
+ ll_sai_put(sai);
+
return rc;
}
-/**
- * called in ll_file_release().
- */
-void ll_stop_statahead(struct inode *dir, void *key)
+/* authorize opened dir handle @key to statahead */
+void ll_authorize_statahead(struct inode *dir, void *key)
{
struct ll_inode_info *lli = ll_i2info(dir);
- if (unlikely(!key))
- return;
-
spin_lock(&lli->lli_sa_lock);
- if (lli->lli_opendir_key != key || lli->lli_opendir_pid == 0) {
- spin_unlock(&lli->lli_sa_lock);
- return;
+ if (!lli->lli_opendir_key && !lli->lli_sai) {
+ /*
+ * if lli_sai is not NULL, it means previous statahead is not
+ * finished yet, we'd better not start a new statahead for now.
+ */
+ LASSERT(!lli->lli_opendir_pid);
+ lli->lli_opendir_key = key;
+ lli->lli_opendir_pid = current_pid();
+ lli->lli_sa_enabled = 1;
}
+ spin_unlock(&lli->lli_sa_lock);
+}
- lli->lli_opendir_key = NULL;
-
- if (lli->lli_sai) {
- struct l_wait_info lwi = { 0 };
- struct ptlrpc_thread *thread = &lli->lli_sai->sai_thread;
+/*
+ * deauthorize opened dir handle @key to statahead, but statahead thread may
+ * still be running, notify it to quit.
+ */
+void ll_deauthorize_statahead(struct inode *dir, void *key)
+{
+ struct ll_inode_info *lli = ll_i2info(dir);
+ struct ll_statahead_info *sai;
- if (!thread_is_stopped(thread)) {
- thread_set_flags(thread, SVC_STOPPING);
- spin_unlock(&lli->lli_sa_lock);
- wake_up(&thread->t_ctl_waitq);
+ LASSERT(lli->lli_opendir_key == key);
+ LASSERT(lli->lli_opendir_pid);
- CDEBUG(D_READA, "stop statahead thread: sai %p pid %u\n",
- lli->lli_sai, (unsigned int)thread->t_pid);
- l_wait_event(thread->t_ctl_waitq,
- thread_is_stopped(thread),
- &lwi);
- } else {
- spin_unlock(&lli->lli_sa_lock);
- }
+ CDEBUG(D_READA, "deauthorize statahead for "DFID"\n",
+ PFID(&lli->lli_fid));
+ spin_lock(&lli->lli_sa_lock);
+ lli->lli_opendir_key = NULL;
+ lli->lli_opendir_pid = 0;
+ lli->lli_sa_enabled = 0;
+ sai = lli->lli_sai;
+ if (sai && thread_is_running(&sai->sai_thread)) {
/*
- * Put the ref which was held when first statahead_enter.
- * It maybe not the last ref for some statahead requests
- * maybe inflight.
+ * statahead thread may not quit yet because it needs to cache
+ * entries, now it's time to tell it to quit.
*/
- ll_sai_put(lli->lli_sai);
- } else {
- lli->lli_opendir_pid = 0;
- spin_unlock(&lli->lli_sa_lock);
+ thread_set_flags(&sai->sai_thread, SVC_STOPPING);
+ wake_up(&sai->sai_thread.t_ctl_waitq);
}
+ spin_unlock(&lli->lli_sa_lock);
}
enum {
/**
* not first dirent, or is "."
*/
- LS_NONE_FIRST_DE = 0,
+ LS_NOT_FIRST_DE = 0,
/**
* the first non-hidden dirent
*/
@@ -1337,17 +1264,26 @@ enum {
LS_FIRST_DOT_DE
};
+/* file is first dirent under @dir */
static int is_first_dirent(struct inode *dir, struct dentry *dentry)
{
- struct ll_dir_chain chain;
const struct qstr *target = &dentry->d_name;
+ struct md_op_data *op_data;
struct page *page;
__u64 pos = 0;
int dot_de;
- int rc = LS_NONE_FIRST_DE;
+ int rc = LS_NOT_FIRST_DE;
- ll_dir_chain_init(&chain);
- page = ll_get_dir_page(dir, pos, &chain);
+ op_data = ll_prep_md_op_data(NULL, dir, dir, NULL, 0, 0,
+ LUSTRE_OPC_ANY, dir);
+ if (IS_ERR(op_data))
+ return PTR_ERR(op_data);
+ /**
+ * FIXME choose the start offset of the readdir
+ */
+ op_data->op_max_pages = ll_i2sbi(dir)->ll_md_brw_pages;
+
+ page = ll_get_dir_page(dir, op_data, pos);
while (1) {
struct lu_dirpage *dp;
@@ -1357,9 +1293,10 @@ static int is_first_dirent(struct inode *dir, struct dentry *dentry)
struct ll_inode_info *lli = ll_i2info(dir);
rc = PTR_ERR(page);
- CERROR("error reading dir "DFID" at %llu: [rc %d] [parent %u]\n",
+ CERROR("%s: error reading dir "DFID" at %llu: opendir_pid = %u : rc = %d\n",
+ ll_get_fsname(dir->i_sb, NULL, 0),
PFID(ll_inode2fid(dir)), pos,
- rc, lli->lli_opendir_pid);
+ lli->lli_opendir_pid, rc);
break;
}
@@ -1411,13 +1348,13 @@ static int is_first_dirent(struct inode *dir, struct dentry *dentry)
if (target->len != namelen ||
memcmp(target->name, name, namelen) != 0)
- rc = LS_NONE_FIRST_DE;
+ rc = LS_NOT_FIRST_DE;
else if (!dot_de)
rc = LS_FIRST_DE;
else
rc = LS_FIRST_DOT_DE;
- ll_release_page(page, 0);
+ ll_release_page(dir, page, false);
goto out;
}
pos = le64_to_cpu(dp->ldp_hash_end);
@@ -1425,261 +1362,228 @@ static int is_first_dirent(struct inode *dir, struct dentry *dentry)
/*
* End of directory reached.
*/
- ll_release_page(page, 0);
- break;
- } else if (1) {
+ ll_release_page(dir, page, false);
+ goto out;
+ } else {
/*
* chain is exhausted
* Normal case: continue to the next page.
*/
- ll_release_page(page, le32_to_cpu(dp->ldp_flags) &
- LDF_COLLIDE);
- page = ll_get_dir_page(dir, pos, &chain);
- } else {
- /*
- * go into overflow page.
- */
- LASSERT(le32_to_cpu(dp->ldp_flags) & LDF_COLLIDE);
- ll_release_page(page, 1);
+ ll_release_page(dir, page,
+ le32_to_cpu(dp->ldp_flags) &
+ LDF_COLLIDE);
+ page = ll_get_dir_page(dir, op_data, pos);
}
}
-
out:
- ll_dir_chain_fini(&chain);
+ ll_finish_md_op_data(op_data);
return rc;
}
-static void
-ll_sai_unplug(struct ll_statahead_info *sai, struct ll_sa_entry *entry)
-{
- struct ptlrpc_thread *thread = &sai->sai_thread;
- struct ll_sb_info *sbi = ll_i2sbi(sai->sai_inode);
- int hit;
-
- if (entry && entry->se_stat == SA_ENTRY_SUCC)
- hit = 1;
- else
- hit = 0;
-
- ll_sa_entry_fini(sai, entry);
- if (hit) {
- sai->sai_hit++;
- sai->sai_consecutive_miss = 0;
- sai->sai_max = min(2 * sai->sai_max, sbi->ll_sa_max);
- } else {
- struct ll_inode_info *lli = ll_i2info(sai->sai_inode);
-
- sai->sai_miss++;
- sai->sai_consecutive_miss++;
- if (sa_low_hit(sai) && thread_is_running(thread)) {
- atomic_inc(&sbi->ll_sa_wrong);
- CDEBUG(D_READA, "Statahead for dir " DFID " hit ratio too low: hit/miss %llu/%llu, sent/replied %llu/%llu, stopping statahead thread\n",
- PFID(&lli->lli_fid), sai->sai_hit,
- sai->sai_miss, sai->sai_sent,
- sai->sai_replied);
- spin_lock(&lli->lli_sa_lock);
- if (!thread_is_stopped(thread))
- thread_set_flags(thread, SVC_STOPPING);
- spin_unlock(&lli->lli_sa_lock);
- }
- }
-
- if (!thread_is_stopped(thread))
- wake_up(&thread->t_ctl_waitq);
-}
-
/**
- * Start statahead thread if this is the first dir entry.
- * Otherwise if a thread is started already, wait it until it is ahead of me.
- * \retval 1 -- find entry with lock in cache, the caller needs to do
- * nothing.
- * \retval 0 -- find entry in cache, but without lock, the caller needs
- * refresh from MDS.
- * \retval others -- the caller need to process as non-statahead.
+ * revalidate @dentryp from statahead cache
+ *
+ * \param[in] dir parent directory
+ * \param[in] sai sai structure
+ * \param[out] dentryp pointer to dentry which will be revalidated
+ * \param[in] unplug unplug statahead window only (normally for negative
+ * dentry)
+ * \retval 1 on success, dentry is saved in @dentryp
+ * \retval 0 if revalidation failed (no proper lock on client)
+ * \retval negative number upon error
*/
-int do_statahead_enter(struct inode *dir, struct dentry **dentryp,
- int only_unplug)
+static int revalidate_statahead_dentry(struct inode *dir,
+ struct ll_statahead_info *sai,
+ struct dentry **dentryp,
+ bool unplug)
{
- struct ll_inode_info *lli = ll_i2info(dir);
- struct ll_statahead_info *sai = lli->lli_sai;
- struct dentry *parent;
- struct ll_sa_entry *entry;
- struct ptlrpc_thread *thread;
- struct l_wait_info lwi = { 0 };
- struct task_struct *task;
- int rc = 0;
- struct ll_inode_info *plli;
+ struct sa_entry *entry = NULL;
+ struct l_wait_info lwi = { 0 };
+ struct ll_dentry_data *ldd;
+ struct ll_inode_info *lli;
+ int rc = 0;
- LASSERT(lli->lli_opendir_pid == current_pid());
+ if ((*dentryp)->d_name.name[0] == '.') {
+ if (sai->sai_ls_all ||
+ sai->sai_miss_hidden >= sai->sai_skip_hidden) {
+ /*
+ * Hidden dentry is the first one, or statahead
+ * thread does not skip so many hidden dentries
+ * before "sai_ls_all" enabled as below.
+ */
+ } else {
+ if (!sai->sai_ls_all)
+ /*
+ * It maybe because hidden dentry is not
+ * the first one, "sai_ls_all" was not
+ * set, then "ls -al" missed. Enable
+ * "sai_ls_all" for such case.
+ */
+ sai->sai_ls_all = 1;
- if (sai) {
- thread = &sai->sai_thread;
- if (unlikely(thread_is_stopped(thread) &&
- list_empty(&sai->sai_entries_stated))) {
- /* to release resource */
- ll_stop_statahead(dir, lli->lli_opendir_key);
+ /*
+ * Such "getattr" has been skipped before
+ * "sai_ls_all" enabled as above.
+ */
+ sai->sai_miss_hidden++;
return -EAGAIN;
}
+ }
- if ((*dentryp)->d_name.name[0] == '.') {
- if (sai->sai_ls_all ||
- sai->sai_miss_hidden >= sai->sai_skip_hidden) {
- /*
- * Hidden dentry is the first one, or statahead
- * thread does not skip so many hidden dentries
- * before "sai_ls_all" enabled as below.
- */
- } else {
- if (!sai->sai_ls_all)
- /*
- * It maybe because hidden dentry is not
- * the first one, "sai_ls_all" was not
- * set, then "ls -al" missed. Enable
- * "sai_ls_all" for such case.
- */
- sai->sai_ls_all = 1;
+ if (unplug) {
+ rc = 1;
+ goto out_unplug;
+ }
- /*
- * Such "getattr" has been skipped before
- * "sai_ls_all" enabled as above.
- */
- sai->sai_miss_hidden++;
- return -EAGAIN;
- }
- }
+ entry = sa_get(sai, &(*dentryp)->d_name);
+ if (!entry) {
+ rc = -EAGAIN;
+ goto out_unplug;
+ }
- entry = ll_sa_entry_get_byname(sai, &(*dentryp)->d_name);
- if (!entry || only_unplug) {
- ll_sai_unplug(sai, entry);
- return entry ? 1 : -EAGAIN;
- }
+ /* if statahead is busy in readdir, help it do post-work */
+ if (!sa_ready(entry) && sai->sai_in_readpage)
+ sa_handle_callback(sai);
- if (!ll_sa_entry_stated(entry)) {
- sai->sai_index_wait = entry->se_index;
- lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(30), NULL,
- LWI_ON_SIGNAL_NOOP, NULL);
- rc = l_wait_event(sai->sai_waitq,
- ll_sa_entry_stated(entry) ||
- thread_is_stopped(thread),
- &lwi);
- if (rc < 0) {
- ll_sai_unplug(sai, entry);
- return -EAGAIN;
- }
+ if (!sa_ready(entry)) {
+ sai->sai_index_wait = entry->se_index;
+ lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(30), NULL,
+ LWI_ON_SIGNAL_NOOP, NULL);
+ rc = l_wait_event(sai->sai_waitq, sa_ready(entry), &lwi);
+ if (rc < 0) {
+ /*
+ * entry may not be ready, so it may be used by inflight
+ * statahead RPC, don't free it.
+ */
+ entry = NULL;
+ rc = -EAGAIN;
+ goto out_unplug;
}
+ }
- if (entry->se_stat == SA_ENTRY_SUCC && entry->se_inode) {
- struct inode *inode = entry->se_inode;
- struct lookup_intent it = { .it_op = IT_GETATTR,
- .it_lock_handle =
- entry->se_handle };
- __u64 bits;
-
- rc = md_revalidate_lock(ll_i2mdexp(dir), &it,
- ll_inode2fid(inode), &bits);
- if (rc == 1) {
- if (!d_inode(*dentryp)) {
- struct dentry *alias;
-
- alias = ll_splice_alias(inode,
- *dentryp);
- if (IS_ERR(alias)) {
- ll_sai_unplug(sai, entry);
- return PTR_ERR(alias);
- }
- *dentryp = alias;
- } else if (d_inode(*dentryp) != inode) {
- /* revalidate, but inode is recreated */
- CDEBUG(D_READA, "%s: stale dentry %pd inode "DFID", statahead inode "DFID"\n",
- ll_get_fsname(d_inode(*dentryp)->i_sb, NULL, 0),
- *dentryp,
- PFID(ll_inode2fid(d_inode(*dentryp))),
- PFID(ll_inode2fid(inode)));
- ll_sai_unplug(sai, entry);
- return -ESTALE;
- } else {
- iput(inode);
+ if (entry->se_state == SA_ENTRY_SUCC && entry->se_inode) {
+ struct inode *inode = entry->se_inode;
+ struct lookup_intent it = { .it_op = IT_GETATTR,
+ .it_lock_handle = entry->se_handle };
+ __u64 bits;
+
+ rc = md_revalidate_lock(ll_i2mdexp(dir), &it,
+ ll_inode2fid(inode), &bits);
+ if (rc == 1) {
+ if (!(*dentryp)->d_inode) {
+ struct dentry *alias;
+
+ alias = ll_splice_alias(inode, *dentryp);
+ if (IS_ERR(alias)) {
+ rc = PTR_ERR(alias);
+ goto out_unplug;
}
+ *dentryp = alias;
+ /**
+ * statahead prepared this inode, transfer inode
+ * refcount from sa_entry to dentry
+ */
entry->se_inode = NULL;
-
- if ((bits & MDS_INODELOCK_LOOKUP) &&
- d_lustre_invalid(*dentryp))
- d_lustre_revalidate(*dentryp);
- ll_intent_release(&it);
+ } else if ((*dentryp)->d_inode != inode) {
+ /* revalidate, but inode is recreated */
+ CDEBUG(D_READA,
+ "%s: stale dentry %pd inode "DFID", statahead inode "DFID"\n",
+ ll_get_fsname((*dentryp)->d_inode->i_sb,
+ NULL, 0),
+ *dentryp,
+ PFID(ll_inode2fid((*dentryp)->d_inode)),
+ PFID(ll_inode2fid(inode)));
+ rc = -ESTALE;
+ goto out_unplug;
}
- }
- ll_sai_unplug(sai, entry);
- return rc;
+ if ((bits & MDS_INODELOCK_LOOKUP) &&
+ d_lustre_invalid(*dentryp))
+ d_lustre_revalidate(*dentryp);
+ ll_intent_release(&it);
+ }
}
+out_unplug:
+ /*
+ * statahead cached sa_entry can be used only once, and will be killed
+ * right after use, so if lookup/revalidate accessed statahead cache,
+ * set dentry ldd_sa_generation to parent lli_sa_generation, later if we
+ * stat this file again, we know we've done statahead before, see
+ * dentry_may_statahead().
+ */
+ ldd = ll_d2d(*dentryp);
+ lli = ll_i2info(dir);
+ /* ldd can be NULL if llite lookup failed. */
+ if (ldd)
+ ldd->lld_sa_generation = lli->lli_sa_generation;
+ sa_put(sai, entry);
+ return rc;
+}
+
+/**
+ * start statahead thread
+ *
+ * \param[in] dir parent directory
+ * \param[in] dentry dentry that triggers statahead, normally the first
+ * dirent under @dir
+ * \retval -EAGAIN on success, because when this function is
+ * called, it's already in lookup call, so client should
+ * do it itself instead of waiting for statahead thread
+ * to do it asynchronously.
+ * \retval negative number upon error
+ */
+static int start_statahead_thread(struct inode *dir, struct dentry *dentry)
+{
+ struct ll_inode_info *lli = ll_i2info(dir);
+ struct ll_statahead_info *sai = NULL;
+ struct l_wait_info lwi = { 0 };
+ struct ptlrpc_thread *thread;
+ struct task_struct *task;
+ struct dentry *parent = dentry->d_parent;
+ int rc;
/* I am the "lli_opendir_pid" owner, only me can set "lli_sai". */
- rc = is_first_dirent(dir, *dentryp);
- if (rc == LS_NONE_FIRST_DE) {
+ rc = is_first_dirent(dir, dentry);
+ if (rc == LS_NOT_FIRST_DE) {
/* It is not "ls -{a}l" operation, no need statahead for it. */
- rc = -EAGAIN;
+ rc = -EFAULT;
goto out;
}
- sai = ll_sai_alloc();
+ sai = ll_sai_alloc(parent);
if (!sai) {
rc = -ENOMEM;
goto out;
}
sai->sai_ls_all = (rc == LS_FIRST_DOT_DE);
- sai->sai_inode = igrab(dir);
- if (unlikely(!sai->sai_inode)) {
- CWARN("Do not start stat ahead on dying inode "DFID"\n",
- PFID(&lli->lli_fid));
- rc = -ESTALE;
- goto out;
- }
-
- /* get parent reference count here, and put it in ll_statahead_thread */
- parent = dget((*dentryp)->d_parent);
- if (unlikely(sai->sai_inode != d_inode(parent))) {
- struct ll_inode_info *nlli = ll_i2info(d_inode(parent));
-
- CWARN("Race condition, someone changed %pd just now: old parent "DFID", new parent "DFID"\n",
- *dentryp,
- PFID(&lli->lli_fid), PFID(&nlli->lli_fid));
- dput(parent);
- iput(sai->sai_inode);
- rc = -EAGAIN;
+ /*
+ * if current lli_opendir_key was deauthorized, or dir re-opened by
+ * another process, don't start statahead, otherwise the newly spawned
+ * statahead thread won't be notified to quit.
+ */
+ spin_lock(&lli->lli_sa_lock);
+ if (unlikely(lli->lli_sai || lli->lli_opendir_key ||
+ lli->lli_opendir_pid != current->pid)) {
+ spin_unlock(&lli->lli_sa_lock);
+ rc = -EPERM;
goto out;
}
+ lli->lli_sai = sai;
+ spin_unlock(&lli->lli_sa_lock);
- CDEBUG(D_READA, "start statahead thread: sai %p, parent %pd\n",
- sai, parent);
+ atomic_inc(&ll_i2sbi(parent->d_inode)->ll_sa_running);
- /* The sai buffer already has one reference taken at allocation time,
- * but as soon as we expose the sai by attaching it to the lli that
- * default reference can be dropped by another thread calling
- * ll_stop_statahead. We need to take a local reference to protect
- * the sai buffer while we intend to access it.
- */
- ll_sai_get(sai);
- lli->lli_sai = sai;
+ CDEBUG(D_READA, "start statahead thread: [pid %d] [parent %pd]\n",
+ current_pid(), parent);
- plli = ll_i2info(d_inode(parent));
task = kthread_run(ll_statahead_thread, parent, "ll_sa_%u",
- plli->lli_opendir_pid);
+ lli->lli_opendir_pid);
thread = &sai->sai_thread;
if (IS_ERR(task)) {
rc = PTR_ERR(task);
- CERROR("can't start ll_sa thread, rc: %d\n", rc);
- dput(parent);
- lli->lli_opendir_key = NULL;
- thread_set_flags(thread, SVC_STOPPED);
- thread_set_flags(&sai->sai_agl_thread, SVC_STOPPED);
- /* Drop both our own local reference and the default
- * reference from allocation time.
- */
- ll_sai_put(sai);
- ll_sai_put(sai);
- LASSERT(!lli->lli_sai);
- return -EAGAIN;
+ CERROR("can't start ll_sa thread, rc : %d\n", rc);
+ goto out;
}
l_wait_event(thread->t_ctl_waitq,
@@ -1694,10 +1598,47 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp,
return -EAGAIN;
out:
- kfree(sai);
+ /*
+ * once we start statahead thread failed, disable statahead so
+ * that subsequent stat won't waste time to try it.
+ */
spin_lock(&lli->lli_sa_lock);
- lli->lli_opendir_key = NULL;
- lli->lli_opendir_pid = 0;
+ lli->lli_sa_enabled = 0;
+ lli->lli_sai = NULL;
spin_unlock(&lli->lli_sa_lock);
+ if (sai)
+ ll_sai_free(sai);
return rc;
}
+
+/**
+ * statahead entry function, this is called when client getattr on a file, it
+ * will start statahead thread if this is the first dir entry, else revalidate
+ * dentry from statahead cache.
+ *
+ * \param[in] dir parent directory
+ * \param[out] dentryp dentry to getattr
+ * \param[in] unplug unplug statahead window only (normally for negative
+ * dentry)
+ * \retval 1 on success
+ * \retval 0 revalidation from statahead cache failed, caller needs
+ * to getattr from server directly
+ * \retval negative number on error, caller often ignores this and
+ * then getattr from server
+ */
+int ll_statahead(struct inode *dir, struct dentry **dentryp, bool unplug)
+{
+ struct ll_statahead_info *sai;
+
+ sai = ll_sai_get(dir);
+ if (sai) {
+ int rc;
+
+ rc = revalidate_statahead_dentry(dir, sai, dentryp, unplug);
+ CDEBUG(D_READA, "revalidate statahead %pd: %d.\n",
+ *dentryp, rc);
+ ll_sai_put(sai);
+ return rc;
+ }
+ return start_statahead_thread(dir, *dentryp);
+}
diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c
index 3dd7e0eb0b54..106cd00910a7 100644
--- a/drivers/staging/lustre/lustre/llite/super25.c
+++ b/drivers/staging/lustre/lustre/llite/super25.c
@@ -34,7 +34,6 @@
#include <linux/module.h>
#include <linux/types.h>
-#include "../include/lustre_lite.h"
#include "../include/lustre_ha.h"
#include "../include/lustre_dlm.h"
#include <linux/init.h>
@@ -83,8 +82,6 @@ struct super_operations lustre_super_operations = {
};
MODULE_ALIAS_FS("lustre");
-void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg));
-
static int __init lustre_init(void)
{
lnet_process_id_t lnet_id;
@@ -102,8 +99,8 @@ static int __init lustre_init(void)
rc = -ENOMEM;
ll_inode_cachep = kmem_cache_create("lustre_inode_cache",
- sizeof(struct ll_inode_info),
- 0, SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT,
+ sizeof(struct ll_inode_info), 0,
+ SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT,
NULL);
if (!ll_inode_cachep)
goto out_cache;
diff --git a/drivers/staging/lustre/lustre/llite/symlink.c b/drivers/staging/lustre/lustre/llite/symlink.c
index 8c8bdfe1ad71..f8bc7ed59646 100644
--- a/drivers/staging/lustre/lustre/llite/symlink.c
+++ b/drivers/staging/lustre/lustre/llite/symlink.c
@@ -35,7 +35,6 @@
#include <linux/stat.h>
#define DEBUG_SUBSYSTEM S_LLITE
-#include "../include/lustre_lite.h"
#include "llite_internal.h"
static int ll_readlink_internal(struct inode *inode,
@@ -80,17 +79,17 @@ static int ll_readlink_internal(struct inode *inode,
}
body = req_capsule_server_get(&(*request)->rq_pill, &RMF_MDT_BODY);
- if ((body->valid & OBD_MD_LINKNAME) == 0) {
+ if ((body->mbo_valid & OBD_MD_LINKNAME) == 0) {
CERROR("OBD_MD_LINKNAME not set on reply\n");
rc = -EPROTO;
goto failed;
}
LASSERT(symlen != 0);
- if (body->eadatasize != symlen) {
+ if (body->mbo_eadatasize != symlen) {
CERROR("%s: inode "DFID": symlink length %d not expected %d\n",
ll_get_fsname(inode->i_sb, NULL, 0),
- PFID(ll_inode2fid(inode)), body->eadatasize - 1,
+ PFID(ll_inode2fid(inode)), body->mbo_eadatasize - 1,
symlen - 1);
rc = -EPROTO;
goto failed;
@@ -155,8 +154,8 @@ const struct inode_operations ll_fast_symlink_inode_operations = {
.get_link = ll_get_link,
.getattr = ll_getattr,
.permission = ll_inode_permission,
- .setxattr = ll_setxattr,
- .getxattr = ll_getxattr,
+ .setxattr = generic_setxattr,
+ .getxattr = generic_getxattr,
.listxattr = ll_listxattr,
- .removexattr = ll_removexattr,
+ .removexattr = generic_removexattr,
};
diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c
index e623216e962d..8aa8ecc09a48 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_dev.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c
@@ -38,7 +38,6 @@
#define DEBUG_SUBSYSTEM S_LLITE
#include "../include/obd.h"
-#include "../include/lustre_lite.h"
#include "llite_internal.h"
#include "vvp_internal.h"
@@ -368,12 +367,6 @@ int cl_sb_fini(struct super_block *sb)
CERROR("Cannot cleanup cl-stack due to memory shortage.\n");
result = PTR_ERR(env);
}
- /*
- * If mount failed (sbi->ll_cl == NULL), and this there are no other
- * mounts, stop device types manually (this usually happens
- * automatically when last device is destroyed).
- */
- lu_types_stop();
return result;
}
diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h
index 79fc428461ed..5802da81cd0e 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_internal.h
+++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h
@@ -217,11 +217,12 @@ struct vvp_object {
struct list_head vob_pending_list;
/**
- * Access this counter is protected by inode->i_sem. Now that
- * the lifetime of transient pages must be covered by inode sem,
- * we don't need to hold any lock..
+ * Number of transient pages. This is no longer protected by i_sem,
+ * and needs to be atomic. This is not actually used for anything,
+ * and can probably be removed.
*/
- int vob_transient_pages;
+ atomic_t vob_transient_pages;
+
/**
* Number of outstanding mmaps on this file.
*
@@ -247,9 +248,9 @@ struct vvp_object {
*/
struct vvp_page {
struct cl_page_slice vpg_cl;
- int vpg_defer_uptodate;
- int vpg_ra_used;
- int vpg_write_queued;
+ unsigned int vpg_defer_uptodate:1,
+ vpg_ra_used:1,
+ vpg_write_queued:1;
/**
* Non-empty iff this page is already counted in
* vvp_object::vob_pending_list. This list is only used as a flag,
diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c
index 94916dcc6caa..2ab450359b6d 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_io.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_io.c
@@ -38,7 +38,6 @@
#define DEBUG_SUBSYSTEM S_LLITE
#include "../include/obd.h"
-#include "../include/lustre_lite.h"
#include "llite_internal.h"
#include "vvp_internal.h"
@@ -628,7 +627,7 @@ static int vvp_io_setattr_time(const struct lu_env *env,
attr->cat_mtime = io->u.ci_setattr.sa_attr.lvb_mtime;
valid |= CAT_MTIME;
}
- result = cl_object_attr_set(env, obj, attr, valid);
+ result = cl_object_attr_update(env, obj, attr, valid);
cl_object_attr_unlock(obj);
return result;
@@ -821,7 +820,7 @@ static void write_commit_callback(const struct lu_env *env, struct cl_io *io,
cl_page_disown(env, io, page);
/* held in ll_cl_init() */
- lu_ref_del(&page->cp_reference, "cl_io", io);
+ lu_ref_del(&page->cp_reference, "cl_io", cl_io_top(io));
cl_page_put(env, page);
}
@@ -959,10 +958,30 @@ static int vvp_io_write_start(const struct lu_env *env,
CDEBUG(D_VFSTRACE, "write: [%lli, %lli)\n", pos, pos + (long long)cnt);
- if (!vio->vui_iter) /* from a temp io in ll_cl_init(). */
+ if (!vio->vui_iter) {
+ /* from a temp io in ll_cl_init(). */
result = 0;
- else
- result = generic_file_write_iter(vio->vui_iocb, vio->vui_iter);
+ } else {
+ /*
+ * When using the locked AIO function (generic_file_aio_write())
+ * testing has shown the inode mutex to be a limiting factor
+ * with multi-threaded single shared file performance. To get
+ * around this, we now use the lockless version. To maintain
+ * consistency, proper locking to protect against writes,
+ * trucates, etc. is handled in the higher layers of lustre.
+ */
+ bool lock_node = !IS_NOSEC(inode);
+
+ if (lock_node)
+ inode_lock(inode);
+ result = __generic_file_write_iter(vio->vui_iocb,
+ vio->vui_iter);
+ if (lock_node)
+ inode_unlock(inode);
+
+ if (result > 0 || result == -EIOCBQUEUED)
+ result = generic_write_sync(vio->vui_iocb, result);
+ }
if (result > 0) {
result = vvp_io_write_commit(env, io);
diff --git a/drivers/staging/lustre/lustre/llite/vvp_lock.c b/drivers/staging/lustre/lustre/llite/vvp_lock.c
index 64be0c9df35b..07eb26cc43f5 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_lock.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_lock.c
@@ -37,7 +37,6 @@
#define DEBUG_SUBSYSTEM S_LLITE
#include "../include/obd_support.h"
-#include "../include/lustre_lite.h"
#include "vvp_internal.h"
diff --git a/drivers/staging/lustre/lustre/llite/vvp_object.c b/drivers/staging/lustre/lustre/llite/vvp_object.c
index 2c520b0bf6ca..b57195d15674 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_object.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_object.c
@@ -39,7 +39,6 @@
#include "../../include/linux/libcfs/libcfs.h"
#include "../include/obd.h"
-#include "../include/lustre_lite.h"
#include "llite_internal.h"
#include "vvp_internal.h"
@@ -68,8 +67,8 @@ static int vvp_object_print(const struct lu_env *env, void *cookie,
(*p)(env, cookie, "(%s %d %d) inode: %p ",
list_empty(&obj->vob_pending_list) ? "-" : "+",
- obj->vob_transient_pages, atomic_read(&obj->vob_mmap_cnt),
- inode);
+ atomic_read(&obj->vob_transient_pages),
+ atomic_read(&obj->vob_mmap_cnt), inode);
if (inode) {
lli = ll_i2info(inode);
(*p)(env, cookie, "%lu/%u %o %u %d %p "DFID,
@@ -102,8 +101,8 @@ static int vvp_attr_get(const struct lu_env *env, struct cl_object *obj,
return 0; /* layers below have to fill in the rest */
}
-static int vvp_attr_set(const struct lu_env *env, struct cl_object *obj,
- const struct cl_attr *attr, unsigned valid)
+static int vvp_attr_update(const struct lu_env *env, struct cl_object *obj,
+ const struct cl_attr *attr, unsigned int valid)
{
struct inode *inode = vvp_object_inode(obj);
@@ -120,7 +119,7 @@ static int vvp_attr_set(const struct lu_env *env, struct cl_object *obj,
if (0 && valid & CAT_SIZE)
i_size_write(inode, attr->cat_size);
/* not currently necessary */
- if (0 && valid & (CAT_UID|CAT_GID|CAT_SIZE))
+ if (0 && valid & (CAT_UID | CAT_GID | CAT_SIZE))
mark_inode_dirty(inode);
return 0;
}
@@ -210,7 +209,7 @@ static const struct cl_object_operations vvp_ops = {
.coo_lock_init = vvp_lock_init,
.coo_io_init = vvp_io_init,
.coo_attr_get = vvp_attr_get,
- .coo_attr_set = vvp_attr_set,
+ .coo_attr_update = vvp_attr_update,
.coo_conf_set = vvp_conf_set,
.coo_prune = vvp_prune,
.coo_glimpse = vvp_object_glimpse
@@ -221,7 +220,7 @@ static int vvp_object_init0(const struct lu_env *env,
const struct cl_object_conf *conf)
{
vob->vob_inode = conf->coc_inode;
- vob->vob_transient_pages = 0;
+ atomic_set(&vob->vob_transient_pages, 0);
cl_object_page_init(&vob->vob_cl, sizeof(struct vvp_page));
return 0;
}
diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c
index 2e566d90bb94..5d79efc1aafe 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_page.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_page.c
@@ -44,8 +44,6 @@
#include <linux/page-flags.h>
#include <linux/pagemap.h>
-#include "../include/lustre_lite.h"
-
#include "llite_internal.h"
#include "vvp_internal.h"
@@ -249,7 +247,7 @@ static void vvp_vmpage_error(struct inode *inode, struct page *vmpage, int ioret
set_bit(AS_EIO, &inode->i_mapping->flags);
if ((ioret == -ESHUTDOWN || ioret == -EINTR) &&
- obj->vob_discard_page_warned == 0) {
+ obj->vob_discard_page_warned == 0) {
obj->vob_discard_page_warned = 1;
ll_dirty_page_discard_warn(vmpage, ioret);
}
@@ -444,18 +442,10 @@ static int vvp_transient_page_prep(const struct lu_env *env,
return 0;
}
-static void vvp_transient_page_verify(const struct cl_page *page)
-{
- struct inode *inode = vvp_object_inode(page->cp_obj);
-
- LASSERT(!inode_trylock(inode));
-}
-
static int vvp_transient_page_own(const struct lu_env *env,
const struct cl_page_slice *slice,
struct cl_io *unused, int nonblock)
{
- vvp_transient_page_verify(slice->cpl_page);
return 0;
}
@@ -463,21 +453,18 @@ static void vvp_transient_page_assume(const struct lu_env *env,
const struct cl_page_slice *slice,
struct cl_io *unused)
{
- vvp_transient_page_verify(slice->cpl_page);
}
static void vvp_transient_page_unassume(const struct lu_env *env,
const struct cl_page_slice *slice,
struct cl_io *unused)
{
- vvp_transient_page_verify(slice->cpl_page);
}
static void vvp_transient_page_disown(const struct lu_env *env,
const struct cl_page_slice *slice,
struct cl_io *unused)
{
- vvp_transient_page_verify(slice->cpl_page);
}
static void vvp_transient_page_discard(const struct lu_env *env,
@@ -486,8 +473,6 @@ static void vvp_transient_page_discard(const struct lu_env *env,
{
struct cl_page *page = slice->cpl_page;
- vvp_transient_page_verify(slice->cpl_page);
-
/*
* For transient pages, remove it from the radix tree.
*/
@@ -511,7 +496,6 @@ vvp_transient_page_completion(const struct lu_env *env,
const struct cl_page_slice *slice,
int ioret)
{
- vvp_transient_page_verify(slice->cpl_page);
}
static void vvp_transient_page_fini(const struct lu_env *env,
@@ -522,8 +506,7 @@ static void vvp_transient_page_fini(const struct lu_env *env,
struct vvp_object *clobj = cl2vvp(clp->cp_obj);
vvp_page_fini_common(vpg);
- LASSERT(!inode_trylock(clobj->vob_inode));
- clobj->vob_transient_pages--;
+ atomic_dec(&clobj->vob_transient_pages);
}
static const struct cl_page_operations vvp_transient_page_ops = {
@@ -549,7 +532,7 @@ static const struct cl_page_operations vvp_transient_page_ops = {
};
int vvp_page_init(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, pgoff_t index)
+ struct cl_page *page, pgoff_t index)
{
struct vvp_page *vpg = cl_object_page_slice(obj, page);
struct page *vmpage = page->cp_vmpage;
@@ -570,10 +553,9 @@ int vvp_page_init(const struct lu_env *env, struct cl_object *obj,
} else {
struct vvp_object *clobj = cl2vvp(obj);
- LASSERT(!inode_trylock(clobj->vob_inode));
cl_page_slice_add(page, &vpg->vpg_cl, obj, index,
&vvp_transient_page_ops);
- clobj->vob_transient_pages++;
+ atomic_inc(&clobj->vob_transient_pages);
}
return 0;
}
diff --git a/drivers/staging/lustre/lustre/llite/vvp_req.c b/drivers/staging/lustre/lustre/llite/vvp_req.c
index 9fe9d6c0a7d1..e3f4c790d646 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_req.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_req.c
@@ -32,7 +32,6 @@
#include "../include/cl_object.h"
#include "../include/obd.h"
#include "../include/obd_support.h"
-#include "../include/lustre_lite.h"
#include "llite_internal.h"
#include "vvp_internal.h"
@@ -83,8 +82,10 @@ static void vvp_req_attr_set(const struct lu_env *env,
}
obdo_from_inode(oa, inode, valid_flags & flags);
obdo_set_parent_fid(oa, &ll_i2info(inode)->lli_fid);
+ if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_INVALID_PFID))
+ oa->o_parent_oid++;
memcpy(attr->cra_jobid, ll_i2info(inode)->lli_jobid,
- JOBSTATS_JOBID_SIZE);
+ LUSTRE_JOBID_SIZE);
}
static void vvp_req_completion(const struct lu_env *env,
diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c
index 98303cf85815..e070adb7a3cc 100644
--- a/drivers/staging/lustre/lustre/llite/xattr.c
+++ b/drivers/staging/lustre/lustre/llite/xattr.c
@@ -38,21 +38,12 @@
#define DEBUG_SUBSYSTEM S_LLITE
#include "../include/obd_support.h"
-#include "../include/lustre_lite.h"
#include "../include/lustre_dlm.h"
#include "../include/lustre_ver.h"
#include "../include/lustre_eacl.h"
#include "llite_internal.h"
-#define XATTR_USER_T (1)
-#define XATTR_TRUSTED_T (2)
-#define XATTR_SECURITY_T (3)
-#define XATTR_ACL_ACCESS_T (4)
-#define XATTR_ACL_DEFAULT_T (5)
-#define XATTR_LUSTRE_T (6)
-#define XATTR_OTHER_T (7)
-
static
int get_xattr_type(const char *name)
{
@@ -99,46 +90,57 @@ int xattr_type_filter(struct ll_sb_info *sbi, int xattr_type)
return 0;
}
-static
-int ll_setxattr_common(struct inode *inode, const char *name,
- const void *value, size_t size,
- int flags, __u64 valid)
+static int
+ll_xattr_set_common(const struct xattr_handler *handler,
+ struct dentry *dentry, struct inode *inode,
+ const char *name, const void *value, size_t size,
+ int flags)
{
+ char fullname[strlen(handler->prefix) + strlen(name) + 1];
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ptlrpc_request *req = NULL;
- int xattr_type, rc;
const char *pv = value;
+ __u64 valid;
+ int rc;
+
+ if (flags == XATTR_REPLACE) {
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_REMOVEXATTR, 1);
+ valid = OBD_MD_FLXATTRRM;
+ } else {
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
+ valid = OBD_MD_FLXATTR;
+ }
- xattr_type = get_xattr_type(name);
- rc = xattr_type_filter(sbi, xattr_type);
+ rc = xattr_type_filter(sbi, handler->flags);
if (rc)
return rc;
- if ((xattr_type == XATTR_ACL_ACCESS_T ||
- xattr_type == XATTR_ACL_DEFAULT_T) &&
+ if ((handler->flags == XATTR_ACL_ACCESS_T ||
+ handler->flags == XATTR_ACL_DEFAULT_T) &&
!inode_owner_or_capable(inode))
return -EPERM;
/* b10667: ignore lustre special xattr for now */
- if ((xattr_type == XATTR_TRUSTED_T && strcmp(name, "trusted.lov") == 0) ||
- (xattr_type == XATTR_LUSTRE_T && strcmp(name, "lustre.lov") == 0))
+ if ((handler->flags == XATTR_TRUSTED_T && !strcmp(name, "lov")) ||
+ (handler->flags == XATTR_LUSTRE_T && !strcmp(name, "lov")))
return 0;
/* b15587: ignore security.capability xattr for now */
- if ((xattr_type == XATTR_SECURITY_T &&
- strcmp(name, "security.capability") == 0))
+ if ((handler->flags == XATTR_SECURITY_T &&
+ !strcmp(name, "capability")))
return 0;
/* LU-549: Disable security.selinux when selinux is disabled */
- if (xattr_type == XATTR_SECURITY_T && !selinux_is_enabled() &&
- strcmp(name, "security.selinux") == 0)
+ if (handler->flags == XATTR_SECURITY_T && !selinux_is_enabled() &&
+ strcmp(name, "selinux") == 0)
return -EOPNOTSUPP;
+ sprintf(fullname, "%s%s\n", handler->prefix, name);
rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode),
- valid, name, pv, size, 0, flags,
+ valid, fullname, pv, size, 0, flags,
ll_i2suppgid(inode), &req);
if (rc) {
- if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
+ if (rc == -EOPNOTSUPP && handler->flags == XATTR_USER_T) {
LCONSOLE_INFO("Disabling user_xattr feature because it is not supported on the server\n");
sbi->ll_flags &= ~LL_SBI_USER_XATTR;
}
@@ -149,8 +151,10 @@ int ll_setxattr_common(struct inode *inode, const char *name,
return 0;
}
-int ll_setxattr(struct dentry *dentry, struct inode *inode,
- const char *name, const void *value, size_t size, int flags)
+static int ll_xattr_set(const struct xattr_handler *handler,
+ struct dentry *dentry, struct inode *inode,
+ const char *name, const void *value, size_t size,
+ int flags)
{
LASSERT(inode);
LASSERT(name);
@@ -158,20 +162,24 @@ int ll_setxattr(struct dentry *dentry, struct inode *inode,
CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), xattr %s\n",
PFID(ll_inode2fid(inode)), inode, name);
- ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
-
- if ((strncmp(name, XATTR_TRUSTED_PREFIX,
- sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0 &&
- strcmp(name + sizeof(XATTR_TRUSTED_PREFIX) - 1, "lov") == 0) ||
- (strncmp(name, XATTR_LUSTRE_PREFIX,
- sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 &&
- strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) {
+ if (!strcmp(name, "lov")) {
struct lov_user_md *lump = (struct lov_user_md *)value;
+ int op_type = flags == XATTR_REPLACE ? LPROC_LL_REMOVEXATTR :
+ LPROC_LL_SETXATTR;
int rc = 0;
+ ll_stats_ops_tally(ll_i2sbi(inode), op_type, 1);
+
if (size != 0 && size < sizeof(struct lov_user_md))
return -EINVAL;
+ /*
+ * It is possible to set an xattr to a "" value of zero size.
+ * For this case we are going to treat it as a removal.
+ */
+ if (!size && lump)
+ lump = NULL;
+
/* Attributes that are saved via getxattr will always have
* the stripe_offset as 0. Instead, the MDS should be
* allowed to pick the starting OST index. b=17846
@@ -181,12 +189,15 @@ int ll_setxattr(struct dentry *dentry, struct inode *inode,
if (lump && S_ISREG(inode->i_mode)) {
__u64 it_flags = FMODE_WRITE;
- int lum_size = (lump->lmm_magic == LOV_USER_MAGIC_V1) ?
- sizeof(*lump) : sizeof(struct lov_user_md_v3);
+ int lum_size;
+
+ lum_size = ll_lov_user_md_size(lump);
+ if (lum_size < 0 || size < lum_size)
+ return 0; /* b=10667: ignore error */
rc = ll_lov_setstripe_ea_info(inode, dentry, it_flags,
lump, lum_size);
- /* b10667: rc always be 0 here for now */
+ /* b=10667: rc always be 0 here for now */
rc = 0;
} else if (S_ISDIR(inode->i_mode)) {
rc = ll_dir_setstripe(inode, lump, 0);
@@ -194,92 +205,27 @@ int ll_setxattr(struct dentry *dentry, struct inode *inode,
return rc;
- } else if (strcmp(name, XATTR_NAME_LMA) == 0 ||
- strcmp(name, XATTR_NAME_LINK) == 0)
+ } else if (!strcmp(name, "lma") || !strcmp(name, "link")) {
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
return 0;
+ }
- return ll_setxattr_common(inode, name, value, size, flags,
- OBD_MD_FLXATTR);
-}
-
-int ll_removexattr(struct dentry *dentry, const char *name)
-{
- struct inode *inode = d_inode(dentry);
-
- LASSERT(inode);
- LASSERT(name);
-
- CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), xattr %s\n",
- PFID(ll_inode2fid(inode)), inode, name);
-
- ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_REMOVEXATTR, 1);
- return ll_setxattr_common(inode, name, NULL, 0, 0,
- OBD_MD_FLXATTRRM);
+ return ll_xattr_set_common(handler, dentry, inode, name, value, size,
+ flags);
}
-static
-int ll_getxattr_common(struct inode *inode, const char *name,
- void *buffer, size_t size, __u64 valid)
+int
+ll_xattr_list(struct inode *inode, const char *name, int type, void *buffer,
+ size_t size, __u64 valid)
{
+ struct ll_inode_info *lli = ll_i2info(inode);
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ptlrpc_request *req = NULL;
struct mdt_body *body;
- int xattr_type, rc;
void *xdata;
- struct ll_inode_info *lli = ll_i2info(inode);
-
- CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
- PFID(ll_inode2fid(inode)), inode);
-
- /* listxattr have slightly different behavior from of ext3:
- * without 'user_xattr' ext3 will list all xattr names but
- * filtered out "^user..*"; we list them all for simplicity.
- */
- if (!name) {
- xattr_type = XATTR_OTHER_T;
- goto do_getxattr;
- }
+ int rc;
- xattr_type = get_xattr_type(name);
- rc = xattr_type_filter(sbi, xattr_type);
- if (rc)
- return rc;
-
- /* b15587: ignore security.capability xattr for now */
- if ((xattr_type == XATTR_SECURITY_T &&
- strcmp(name, "security.capability") == 0))
- return -ENODATA;
-
- /* LU-549: Disable security.selinux when selinux is disabled */
- if (xattr_type == XATTR_SECURITY_T && !selinux_is_enabled() &&
- strcmp(name, "security.selinux") == 0)
- return -EOPNOTSUPP;
-
-#ifdef CONFIG_FS_POSIX_ACL
- /* posix acl is under protection of LOOKUP lock. when calling to this,
- * we just have path resolution to the target inode, so we have great
- * chance that cached ACL is uptodate.
- */
- if (xattr_type == XATTR_ACL_ACCESS_T) {
- struct posix_acl *acl;
-
- spin_lock(&lli->lli_lock);
- acl = posix_acl_dup(lli->lli_posix_acl);
- spin_unlock(&lli->lli_lock);
-
- if (!acl)
- return -ENODATA;
-
- rc = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
- posix_acl_release(acl);
- return rc;
- }
- if (xattr_type == XATTR_ACL_DEFAULT_T && !S_ISDIR(inode->i_mode))
- return -ENODATA;
-#endif
-
-do_getxattr:
- if (sbi->ll_xattr_cache_enabled && xattr_type != XATTR_ACL_ACCESS_T) {
+ if (sbi->ll_xattr_cache_enabled && type != XATTR_ACL_ACCESS_T) {
rc = ll_xattr_cache_get(inode, name, buffer, size, valid);
if (rc == -EAGAIN)
goto getxattr_nocache;
@@ -311,36 +257,36 @@ getxattr_nocache:
/* only detect the xattr size */
if (size == 0) {
- rc = body->eadatasize;
+ rc = body->mbo_eadatasize;
goto out;
}
- if (size < body->eadatasize) {
+ if (size < body->mbo_eadatasize) {
CERROR("server bug: replied size %u > %u\n",
- body->eadatasize, (int)size);
+ body->mbo_eadatasize, (int)size);
rc = -ERANGE;
goto out;
}
- if (body->eadatasize == 0) {
+ if (body->mbo_eadatasize == 0) {
rc = -ENODATA;
goto out;
}
/* do not need swab xattr data */
xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA,
- body->eadatasize);
+ body->mbo_eadatasize);
if (!xdata) {
rc = -EFAULT;
goto out;
}
- memcpy(buffer, xdata, body->eadatasize);
- rc = body->eadatasize;
+ memcpy(buffer, xdata, body->mbo_eadatasize);
+ rc = body->mbo_eadatasize;
}
out_xattr:
- if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
+ if (rc == -EOPNOTSUPP && type == XATTR_USER_T) {
LCONSOLE_INFO(
"%s: disabling user_xattr feature because it is not supported on the server: rc = %d\n",
ll_get_fsname(inode->i_sb, NULL, 0), rc);
@@ -351,8 +297,65 @@ out:
return rc;
}
-ssize_t ll_getxattr(struct dentry *dentry, struct inode *inode,
- const char *name, void *buffer, size_t size)
+static int ll_xattr_get_common(const struct xattr_handler *handler,
+ struct dentry *dentry, struct inode *inode,
+ const char *name, void *buffer, size_t size)
+{
+ char fullname[strlen(handler->prefix) + strlen(name) + 1];
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+#ifdef CONFIG_FS_POSIX_ACL
+ struct ll_inode_info *lli = ll_i2info(inode);
+#endif
+ int rc;
+
+ CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
+ PFID(ll_inode2fid(inode)), inode);
+
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR, 1);
+
+ rc = xattr_type_filter(sbi, handler->flags);
+ if (rc)
+ return rc;
+
+ /* b15587: ignore security.capability xattr for now */
+ if ((handler->flags == XATTR_SECURITY_T && !strcmp(name, "capability")))
+ return -ENODATA;
+
+ /* LU-549: Disable security.selinux when selinux is disabled */
+ if (handler->flags == XATTR_SECURITY_T && !selinux_is_enabled() &&
+ !strcmp(name, "selinux"))
+ return -EOPNOTSUPP;
+
+#ifdef CONFIG_FS_POSIX_ACL
+ /* posix acl is under protection of LOOKUP lock. when calling to this,
+ * we just have path resolution to the target inode, so we have great
+ * chance that cached ACL is uptodate.
+ */
+ if (handler->flags == XATTR_ACL_ACCESS_T) {
+ struct posix_acl *acl;
+
+ spin_lock(&lli->lli_lock);
+ acl = posix_acl_dup(lli->lli_posix_acl);
+ spin_unlock(&lli->lli_lock);
+
+ if (!acl)
+ return -ENODATA;
+
+ rc = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
+ posix_acl_release(acl);
+ return rc;
+ }
+ if (handler->flags == XATTR_ACL_DEFAULT_T && !S_ISDIR(inode->i_mode))
+ return -ENODATA;
+#endif
+ sprintf(fullname, "%s%s\n", handler->prefix, name);
+ return ll_xattr_list(inode, fullname, handler->flags, buffer, size,
+ OBD_MD_FLXATTR);
+}
+
+static int ll_xattr_get(const struct xattr_handler *handler,
+ struct dentry *dentry, struct inode *inode,
+ const char *name, void *buffer, size_t size)
{
LASSERT(inode);
LASSERT(name);
@@ -360,36 +363,23 @@ ssize_t ll_getxattr(struct dentry *dentry, struct inode *inode,
CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), xattr %s\n",
PFID(ll_inode2fid(inode)), inode, name);
- ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR, 1);
-
- if ((strncmp(name, XATTR_TRUSTED_PREFIX,
- sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0 &&
- strcmp(name + sizeof(XATTR_TRUSTED_PREFIX) - 1, "lov") == 0) ||
- (strncmp(name, XATTR_LUSTRE_PREFIX,
- sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 &&
- strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) {
+ if (!strcmp(name, "lov")) {
struct lov_stripe_md *lsm;
struct lov_user_md *lump;
struct lov_mds_md *lmm = NULL;
struct ptlrpc_request *request = NULL;
int rc = 0, lmmsize = 0;
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR, 1);
+
if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
return -ENODATA;
- if (size == 0 && S_ISDIR(inode->i_mode)) {
- /* XXX directory EA is fix for now, optimize to save
- * RPC transfer
- */
- rc = sizeof(struct lov_user_md);
- goto out;
- }
-
lsm = ccc_inode_lsm_get(inode);
if (!lsm) {
if (S_ISDIR(inode->i_mode)) {
- rc = ll_dir_getstripe(inode, &lmm,
- &lmmsize, &request);
+ rc = ll_dir_getstripe(inode, (void **)&lmm,
+ &lmmsize, &request, 0);
} else {
rc = -ENODATA;
}
@@ -439,7 +429,7 @@ out:
return rc;
}
- return ll_getxattr_common(inode, name, buffer, size, OBD_MD_FLXATTR);
+ return ll_xattr_get_common(handler, dentry, inode, name, buffer, size);
}
ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
@@ -457,7 +447,8 @@ ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_LISTXATTR, 1);
- rc = ll_getxattr_common(inode, NULL, buffer, size, OBD_MD_FLXATTRLS);
+ rc = ll_xattr_list(inode, NULL, XATTR_OTHER_T, buffer, size,
+ OBD_MD_FLXATTRLS);
if (rc < 0)
goto out;
@@ -488,7 +479,8 @@ ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
if (!ll_i2info(inode)->lli_has_smd)
rc2 = -1;
} else if (S_ISDIR(inode->i_mode)) {
- rc2 = ll_dir_getstripe(inode, &lmm, &lmmsize, &request);
+ rc2 = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize,
+ &request, 0);
}
if (rc2 < 0) {
@@ -518,3 +510,57 @@ out:
return rc;
}
+
+static const struct xattr_handler ll_user_xattr_handler = {
+ .prefix = XATTR_USER_PREFIX,
+ .flags = XATTR_USER_T,
+ .get = ll_xattr_get_common,
+ .set = ll_xattr_set_common,
+};
+
+static const struct xattr_handler ll_trusted_xattr_handler = {
+ .prefix = XATTR_TRUSTED_PREFIX,
+ .flags = XATTR_TRUSTED_T,
+ .get = ll_xattr_get,
+ .set = ll_xattr_set,
+};
+
+static const struct xattr_handler ll_security_xattr_handler = {
+ .prefix = XATTR_SECURITY_PREFIX,
+ .flags = XATTR_SECURITY_T,
+ .get = ll_xattr_get_common,
+ .set = ll_xattr_set_common,
+};
+
+static const struct xattr_handler ll_acl_access_xattr_handler = {
+ .prefix = XATTR_NAME_POSIX_ACL_ACCESS,
+ .flags = XATTR_ACL_ACCESS_T,
+ .get = ll_xattr_get_common,
+ .set = ll_xattr_set_common,
+};
+
+static const struct xattr_handler ll_acl_default_xattr_handler = {
+ .prefix = XATTR_NAME_POSIX_ACL_DEFAULT,
+ .flags = XATTR_ACL_DEFAULT_T,
+ .get = ll_xattr_get_common,
+ .set = ll_xattr_set_common,
+};
+
+static const struct xattr_handler ll_lustre_xattr_handler = {
+ .prefix = XATTR_LUSTRE_PREFIX,
+ .flags = XATTR_LUSTRE_T,
+ .get = ll_xattr_get,
+ .set = ll_xattr_set,
+};
+
+const struct xattr_handler *ll_xattr_handlers[] = {
+ &ll_user_xattr_handler,
+ &ll_trusted_xattr_handler,
+ &ll_security_xattr_handler,
+#ifdef CONFIG_FS_POSIX_ACL
+ &ll_acl_access_xattr_handler,
+ &ll_acl_default_xattr_handler,
+#endif
+ &ll_lustre_xattr_handler,
+ NULL,
+};
diff --git a/drivers/staging/lustre/lustre/llite/xattr_cache.c b/drivers/staging/lustre/lustre/llite/xattr_cache.c
index 8089da8143d9..50a19a40bd4e 100644
--- a/drivers/staging/lustre/lustre/llite/xattr_cache.c
+++ b/drivers/staging/lustre/lustre/llite/xattr_cache.c
@@ -13,7 +13,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include "../include/obd_support.h"
-#include "../include/lustre_lite.h"
#include "../include/lustre_dlm.h"
#include "../include/lustre_ver.h"
#include "llite_internal.h"
@@ -270,10 +269,12 @@ static int ll_xattr_find_get_lock(struct inode *inode,
struct lustre_handle lockh = { 0 };
struct md_op_data *op_data;
struct ll_inode_info *lli = ll_i2info(inode);
- struct ldlm_enqueue_info einfo = { .ei_type = LDLM_IBITS,
- .ei_mode = it_to_lock_mode(oit),
- .ei_cb_bl = ll_md_blocking_ast,
- .ei_cb_cp = ldlm_completion_ast };
+ struct ldlm_enqueue_info einfo = {
+ .ei_type = LDLM_IBITS,
+ .ei_mode = it_to_lock_mode(oit),
+ .ei_cb_bl = &ll_md_blocking_ast,
+ .ei_cb_cp = &ldlm_completion_ast,
+ };
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct obd_export *exp = sbi->ll_md_exp;
int rc;
@@ -304,7 +305,7 @@ static int ll_xattr_find_get_lock(struct inode *inode,
op_data->op_valid = OBD_MD_FLXATTR | OBD_MD_FLXATTRLS;
- rc = md_enqueue(exp, &einfo, oit, op_data, &lockh, NULL, 0, NULL, 0);
+ rc = md_enqueue(exp, &einfo, NULL, oit, op_data, &lockh, 0);
ll_finish_md_op_data(op_data);
if (rc < 0) {
@@ -380,25 +381,25 @@ static int ll_xattr_cache_refill(struct inode *inode, struct lookup_intent *oit)
}
/* do not need swab xattr data */
xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA,
- body->eadatasize);
+ body->mbo_eadatasize);
xval = req_capsule_server_sized_get(&req->rq_pill, &RMF_EAVALS,
- body->aclsize);
+ body->mbo_aclsize);
xsizes = req_capsule_server_sized_get(&req->rq_pill, &RMF_EAVALS_LENS,
- body->max_mdsize * sizeof(__u32));
+ body->mbo_max_mdsize * sizeof(__u32));
if (!xdata || !xval || !xsizes) {
CERROR("wrong setxattr reply\n");
rc = -EPROTO;
goto out_destroy;
}
- xtail = xdata + body->eadatasize;
- xvtail = xval + body->aclsize;
+ xtail = xdata + body->mbo_eadatasize;
+ xvtail = xval + body->mbo_aclsize;
CDEBUG(D_CACHE, "caching: xdata=%p xtail=%p\n", xdata, xtail);
ll_xattr_cache_init(lli);
- for (i = 0; i < body->max_mdsize; i++) {
+ for (i = 0; i < body->mbo_max_mdsize; i++) {
CDEBUG(D_CACHE, "caching [%s]=%.*s\n", xdata, *xsizes, xval);
/* Perform consistency checks: attr names and vals in pill */
if (!memchr(xdata, 0, xtail - xdata)) {
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_fld.c b/drivers/staging/lustre/lustre/lmv/lmv_fld.c
index a3d170aa6fd2..a5265f9b5797 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_fld.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_fld.c
@@ -47,18 +47,20 @@
#include "../include/lprocfs_status.h"
#include "lmv_internal.h"
-int lmv_fld_lookup(struct lmv_obd *lmv,
- const struct lu_fid *fid,
- u32 *mds)
+int lmv_fld_lookup(struct lmv_obd *lmv, const struct lu_fid *fid, u32 *mds)
{
+ struct obd_device *obd = lmv2obd_dev(lmv);
int rc;
- /* FIXME: Currently ZFS still use local seq for ROOT unfortunately, and
+ /*
+ * FIXME: Currently ZFS still use local seq for ROOT unfortunately, and
* this fid_is_local check should be removed once LU-2240 is fixed
*/
- LASSERTF((fid_seq_in_fldb(fid_seq(fid)) ||
- fid_seq_is_local_file(fid_seq(fid))) &&
- fid_is_sane(fid), DFID" is insane!\n", PFID(fid));
+ if (!fid_is_sane(fid) || !(fid_seq_in_fldb(fid_seq(fid)) ||
+ fid_seq_is_local_file(fid_seq(fid)))) {
+ CERROR("%s: invalid FID " DFID "\n", obd->obd_name, PFID(fid));
+ return -EINVAL;
+ }
rc = fld_client_lookup(&lmv->lmv_fld, fid_seq(fid), mds,
LU_SEQ_RANGE_MDT, NULL);
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_intent.c b/drivers/staging/lustre/lustre/lmv/lmv_intent.c
index 2f58fdab8d1e..9f4e826bb0af 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_intent.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_intent.c
@@ -43,13 +43,13 @@
#include "../include/lustre_lib.h"
#include "../include/lustre_net.h"
#include "../include/lustre_dlm.h"
+#include "../include/lustre_mdc.h"
#include "../include/obd_class.h"
#include "../include/lprocfs_status.h"
#include "lmv_internal.h"
-static int lmv_intent_remote(struct obd_export *exp, void *lmm,
- int lmmsize, struct lookup_intent *it,
- const struct lu_fid *parent_fid, int flags,
+static int lmv_intent_remote(struct obd_export *exp, struct lookup_intent *it,
+ const struct lu_fid *parent_fid,
struct ptlrpc_request **reqp,
ldlm_blocking_callback cb_blocking,
__u64 extra_lock_flags)
@@ -68,7 +68,7 @@ static int lmv_intent_remote(struct obd_export *exp, void *lmm,
if (!body)
return -EPROTO;
- LASSERT((body->valid & OBD_MD_MDS));
+ LASSERT((body->mbo_valid & OBD_MD_MDS));
/*
* Unfortunately, we have to lie to MDC/MDS to retrieve
@@ -87,9 +87,9 @@ static int lmv_intent_remote(struct obd_export *exp, void *lmm,
it->it_request = NULL;
}
- LASSERT(fid_is_sane(&body->fid1));
+ LASSERT(fid_is_sane(&body->mbo_fid1));
- tgt = lmv_find_target(lmv, &body->fid1);
+ tgt = lmv_find_target(lmv, &body->mbo_fid1);
if (IS_ERR(tgt)) {
rc = PTR_ERR(tgt);
goto out;
@@ -101,7 +101,7 @@ static int lmv_intent_remote(struct obd_export *exp, void *lmm,
goto out;
}
- op_data->op_fid1 = body->fid1;
+ op_data->op_fid1 = body->mbo_fid1;
/* Sent the parent FID to the remote MDT */
if (parent_fid) {
/* The parent fid is only for remote open to
@@ -110,18 +110,14 @@ static int lmv_intent_remote(struct obd_export *exp, void *lmm,
*/
LASSERT(it->it_op & IT_OPEN);
op_data->op_fid2 = *parent_fid;
- /* Add object FID to op_fid3, in case it needs to check stale
- * (M_CHECK_STALE), see mdc_finish_intent_lock
- */
- op_data->op_fid3 = body->fid1;
}
op_data->op_bias = MDS_CROSS_REF;
- CDEBUG(D_INODE, "REMOTE_INTENT with fid="DFID" -> mds #%d\n",
- PFID(&body->fid1), tgt->ltd_idx);
+ CDEBUG(D_INODE, "REMOTE_INTENT with fid=" DFID " -> mds #%u\n",
+ PFID(&body->mbo_fid1), tgt->ltd_idx);
- rc = md_intent_lock(tgt->ltd_exp, op_data, lmm, lmmsize, it,
- flags, &req, cb_blocking, extra_lock_flags);
+ rc = md_intent_lock(tgt->ltd_exp, op_data, it, &req, cb_blocking,
+ extra_lock_flags);
if (rc)
goto out_free_op_data;
@@ -136,8 +132,10 @@ static int lmv_intent_remote(struct obd_export *exp, void *lmm,
it->it_remote_lock_mode = it->it_lock_mode;
}
- it->it_lock_handle = plock.cookie;
- it->it_lock_mode = pmode;
+ if (pmode) {
+ it->it_lock_handle = plock.cookie;
+ it->it_lock_mode = pmode;
+ }
out_free_op_data:
kfree(op_data);
@@ -150,13 +148,126 @@ out:
return rc;
}
+int lmv_revalidate_slaves(struct obd_export *exp,
+ const struct lmv_stripe_md *lsm,
+ ldlm_blocking_callback cb_blocking,
+ int extra_lock_flags)
+{
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+ struct ptlrpc_request *req = NULL;
+ struct mdt_body *body;
+ struct md_op_data *op_data;
+ int rc = 0, i;
+
+ /**
+ * revalidate slaves has some problems, temporarily return,
+ * we may not need that
+ */
+ op_data = kzalloc(sizeof(*op_data), GFP_NOFS);
+ if (!op_data)
+ return -ENOMEM;
+
+ /**
+ * Loop over the stripe information, check validity and update them
+ * from MDS if needed.
+ */
+ for (i = 0; i < lsm->lsm_md_stripe_count; i++) {
+ struct lookup_intent it = { .it_op = IT_GETATTR };
+ struct lustre_handle *lockh = NULL;
+ struct lmv_tgt_desc *tgt = NULL;
+ struct inode *inode;
+ struct lu_fid fid;
+
+ fid = lsm->lsm_md_oinfo[i].lmo_fid;
+ inode = lsm->lsm_md_oinfo[i].lmo_root;
+
+ /*
+ * Prepare op_data for revalidating. Note that @fid2 shluld be
+ * defined otherwise it will go to server and take new lock
+ * which is not needed here.
+ */
+ memset(op_data, 0, sizeof(*op_data));
+ op_data->op_fid1 = fid;
+ op_data->op_fid2 = fid;
+
+ tgt = lmv_locate_mds(lmv, op_data, &fid);
+ if (IS_ERR(tgt)) {
+ rc = PTR_ERR(tgt);
+ goto cleanup;
+ }
+
+ CDEBUG(D_INODE, "Revalidate slave " DFID " -> mds #%u\n",
+ PFID(&fid), tgt->ltd_idx);
+
+ if (req) {
+ ptlrpc_req_finished(req);
+ req = NULL;
+ }
+
+ rc = md_intent_lock(tgt->ltd_exp, op_data, &it, &req,
+ cb_blocking, extra_lock_flags);
+ if (rc < 0)
+ goto cleanup;
+
+ lockh = (struct lustre_handle *)&it.it_lock_handle;
+ if (rc > 0 && !req) {
+ /* slave inode is still valid */
+ CDEBUG(D_INODE, "slave "DFID" is still valid.\n",
+ PFID(&fid));
+ rc = 0;
+ } else {
+ /* refresh slave from server */
+ body = req_capsule_server_get(&req->rq_pill,
+ &RMF_MDT_BODY);
+ LASSERT(body);
+
+ if (unlikely(body->mbo_nlink < 2)) {
+ CERROR("%s: nlink %d < 2 corrupt stripe %d "DFID":" DFID"\n",
+ obd->obd_name, body->mbo_nlink, i,
+ PFID(&lsm->lsm_md_oinfo[i].lmo_fid),
+ PFID(&lsm->lsm_md_oinfo[0].lmo_fid));
+
+ if (it.it_lock_mode && lockh) {
+ ldlm_lock_decref(lockh, it.it_lock_mode);
+ it.it_lock_mode = 0;
+ }
+
+ rc = -EIO;
+ goto cleanup;
+ }
+
+ i_size_write(inode, body->mbo_size);
+ inode->i_blocks = body->mbo_blocks;
+ set_nlink(inode, body->mbo_nlink);
+ LTIME_S(inode->i_atime) = body->mbo_atime;
+ LTIME_S(inode->i_ctime) = body->mbo_ctime;
+ LTIME_S(inode->i_mtime) = body->mbo_mtime;
+ }
+
+ md_set_lock_data(tgt->ltd_exp, lockh, inode, NULL);
+
+ if (it.it_lock_mode && lockh) {
+ ldlm_lock_decref(lockh, it.it_lock_mode);
+ it.it_lock_mode = 0;
+ }
+ }
+
+cleanup:
+ if (req)
+ ptlrpc_req_finished(req);
+
+ kfree(op_data);
+ return rc;
+}
+
/*
* IT_OPEN is intended to open (and create, possible) an object. Parent (pid)
* may be split dir.
*/
static int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data,
- void *lmm, int lmmsize, struct lookup_intent *it,
- int flags, struct ptlrpc_request **reqp,
+ struct lookup_intent *it,
+ struct ptlrpc_request **reqp,
ldlm_blocking_callback cb_blocking,
__u64 extra_lock_flags)
{
@@ -166,35 +277,55 @@ static int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data,
struct mdt_body *body;
int rc;
- tgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid1);
- if (IS_ERR(tgt))
- return PTR_ERR(tgt);
+ if (it->it_flags & MDS_OPEN_BY_FID) {
+ LASSERT(fid_is_sane(&op_data->op_fid2));
+
+ /*
+ * for striped directory, we can't know parent stripe fid
+ * without name, but we can set it to child fid, and MDT
+ * will obtain it from linkea in open in such case.
+ */
+ if (op_data->op_mea1)
+ op_data->op_fid1 = op_data->op_fid2;
+
+ tgt = lmv_find_target(lmv, &op_data->op_fid2);
+ if (IS_ERR(tgt))
+ return PTR_ERR(tgt);
+
+ op_data->op_mds = tgt->ltd_idx;
+ } else {
+ LASSERT(fid_is_sane(&op_data->op_fid1));
+ LASSERT(fid_is_zero(&op_data->op_fid2));
+ LASSERT(op_data->op_name);
+
+ tgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid1);
+ if (IS_ERR(tgt))
+ return PTR_ERR(tgt);
+ }
/* If it is ready to open the file by FID, do not need
* allocate FID at all, otherwise it will confuse MDT
*/
- if ((it->it_op & IT_CREAT) &&
- !(it->it_flags & MDS_OPEN_BY_FID)) {
+ if ((it->it_op & IT_CREAT) && !(it->it_flags & MDS_OPEN_BY_FID)) {
/*
- * For open with IT_CREATE and for IT_CREATE cases allocate new
- * fid and setup FLD for it.
+ * For lookup(IT_CREATE) cases allocate new fid and setup FLD
+ * for it.
*/
- op_data->op_fid3 = op_data->op_fid2;
- rc = lmv_fid_alloc(exp, &op_data->op_fid2, op_data);
+ rc = lmv_fid_alloc(NULL, exp, &op_data->op_fid2, op_data);
if (rc != 0)
return rc;
}
- CDEBUG(D_INODE, "OPEN_INTENT with fid1=" DFID ", fid2=" DFID ", name='%s' -> mds #%d\n",
+ CDEBUG(D_INODE, "OPEN_INTENT with fid1=" DFID ", fid2=" DFID ", name='%s' -> mds #%u\n",
PFID(&op_data->op_fid1),
PFID(&op_data->op_fid2), op_data->op_name, tgt->ltd_idx);
- rc = md_intent_lock(tgt->ltd_exp, op_data, lmm, lmmsize, it, flags,
- reqp, cb_blocking, extra_lock_flags);
+ rc = md_intent_lock(tgt->ltd_exp, op_data, it, reqp, cb_blocking,
+ extra_lock_flags);
if (rc != 0)
return rc;
/*
- * Nothing is found, do not access body->fid1 as it is zero and thus
+ * Nothing is found, do not access body->mbo_fid1 as it is zero and thus
* pointless.
*/
if ((it->it_disposition & DISP_LOOKUP_NEG) &&
@@ -205,31 +336,17 @@ static int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data,
body = req_capsule_server_get(&(*reqp)->rq_pill, &RMF_MDT_BODY);
if (!body)
return -EPROTO;
- /*
- * Not cross-ref case, just get out of here.
- */
- if (likely(!(body->valid & OBD_MD_MDS)))
- return 0;
- /*
- * Okay, MDS has returned success. Probably name has been resolved in
- * remote inode.
- */
- rc = lmv_intent_remote(exp, lmm, lmmsize, it, &op_data->op_fid1, flags,
- reqp, cb_blocking, extra_lock_flags);
- if (rc != 0) {
- LASSERT(rc < 0);
- /*
- * This is possible, that some userspace application will try to
- * open file as directory and we will have -ENOTDIR here. As
- * this is normal situation, we should not print error here,
- * only debug info.
- */
- CDEBUG(D_INODE, "Can't handle remote %s: dir " DFID "(" DFID "):%*s: %d\n",
- LL_IT2STR(it), PFID(&op_data->op_fid2),
- PFID(&op_data->op_fid1), op_data->op_namelen,
- op_data->op_name, rc);
- return rc;
+ /* Not cross-ref case, just get out of here. */
+ if (unlikely((body->mbo_valid & OBD_MD_MDS))) {
+ rc = lmv_intent_remote(exp, it, &op_data->op_fid1, reqp,
+ cb_blocking, extra_lock_flags);
+ if (rc != 0)
+ return rc;
+
+ body = req_capsule_server_get(&(*reqp)->rq_pill, &RMF_MDT_BODY);
+ if (!body)
+ return -EPROTO;
}
return rc;
@@ -240,37 +357,102 @@ static int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data,
*/
static int lmv_intent_lookup(struct obd_export *exp,
struct md_op_data *op_data,
- void *lmm, int lmmsize, struct lookup_intent *it,
- int flags, struct ptlrpc_request **reqp,
+ struct lookup_intent *it,
+ struct ptlrpc_request **reqp,
ldlm_blocking_callback cb_blocking,
__u64 extra_lock_flags)
{
+ struct lmv_stripe_md *lsm = op_data->op_mea1;
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt = NULL;
struct mdt_body *body;
int rc = 0;
+ /*
+ * If it returns ERR_PTR(-EBADFD) then it is an unknown hash type
+ * it will try all stripes to locate the object
+ */
tgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid1);
- if (IS_ERR(tgt))
+ if (IS_ERR(tgt) && (PTR_ERR(tgt) != -EBADFD))
return PTR_ERR(tgt);
+ /*
+ * Both migrating dir and unknown hash dir need to try
+ * all of sub-stripes
+ */
+ if (lsm && !lmv_is_known_hash_type(lsm->lsm_md_hash_type)) {
+ struct lmv_oinfo *oinfo = &lsm->lsm_md_oinfo[0];
+
+ op_data->op_fid1 = oinfo->lmo_fid;
+ op_data->op_mds = oinfo->lmo_mds;
+ tgt = lmv_get_target(lmv, oinfo->lmo_mds, NULL);
+ if (IS_ERR(tgt))
+ return PTR_ERR(tgt);
+ }
+
if (!fid_is_sane(&op_data->op_fid2))
fid_zero(&op_data->op_fid2);
- CDEBUG(D_INODE, "LOOKUP_INTENT with fid1="DFID", fid2="DFID
- ", name='%s' -> mds #%d\n", PFID(&op_data->op_fid1),
- PFID(&op_data->op_fid2),
+ CDEBUG(D_INODE, "LOOKUP_INTENT with fid1=" DFID ", fid2=" DFID ", name='%s' -> mds #%u lsm=%p lsm_magic=%x\n",
+ PFID(&op_data->op_fid1), PFID(&op_data->op_fid2),
op_data->op_name ? op_data->op_name : "<NULL>",
- tgt->ltd_idx);
+ tgt->ltd_idx, lsm, !lsm ? -1 : lsm->lsm_md_magic);
op_data->op_bias &= ~MDS_CROSS_REF;
- rc = md_intent_lock(tgt->ltd_exp, op_data, lmm, lmmsize, it,
- flags, reqp, cb_blocking, extra_lock_flags);
+ rc = md_intent_lock(tgt->ltd_exp, op_data, it, reqp, cb_blocking,
+ extra_lock_flags);
+ if (rc < 0)
+ return rc;
- if (rc < 0 || !*reqp)
+ if (!*reqp) {
+ /*
+ * If RPC happens, lsm information will be revalidated
+ * during update_inode process (see ll_update_lsm_md)
+ */
+ if (op_data->op_mea2) {
+ rc = lmv_revalidate_slaves(exp, op_data->op_mea2,
+ cb_blocking,
+ extra_lock_flags);
+ if (rc != 0)
+ return rc;
+ }
return rc;
+ } else if (it_disposition(it, DISP_LOOKUP_NEG) && lsm &&
+ lmv_need_try_all_stripes(lsm)) {
+ /*
+ * For migrating and unknown hash type directory, it will
+ * try to target the entry on other stripes
+ */
+ int stripe_index;
+
+ for (stripe_index = 1;
+ stripe_index < lsm->lsm_md_stripe_count &&
+ it_disposition(it, DISP_LOOKUP_NEG); stripe_index++) {
+ struct lmv_oinfo *oinfo;
+
+ /* release the previous request */
+ ptlrpc_req_finished(*reqp);
+ it->it_request = NULL;
+ *reqp = NULL;
+
+ oinfo = &lsm->lsm_md_oinfo[stripe_index];
+ tgt = lmv_find_target(lmv, &oinfo->lmo_fid);
+ if (IS_ERR(tgt))
+ return PTR_ERR(tgt);
+
+ CDEBUG(D_INODE, "Try other stripes " DFID"\n",
+ PFID(&oinfo->lmo_fid));
+
+ op_data->op_fid1 = oinfo->lmo_fid;
+ it->it_disposition &= ~DISP_ENQ_COMPLETE;
+ rc = md_intent_lock(tgt->ltd_exp, op_data, it, reqp,
+ cb_blocking, extra_lock_flags);
+ if (rc)
+ return rc;
+ }
+ }
/*
* MDS has returned success. Probably name has been resolved in
@@ -279,19 +461,23 @@ static int lmv_intent_lookup(struct obd_export *exp,
body = req_capsule_server_get(&(*reqp)->rq_pill, &RMF_MDT_BODY);
if (!body)
return -EPROTO;
- /* Not cross-ref case, just get out of here. */
- if (likely(!(body->valid & OBD_MD_MDS)))
- return 0;
- rc = lmv_intent_remote(exp, lmm, lmmsize, it, NULL, flags, reqp,
- cb_blocking, extra_lock_flags);
+ /* Not cross-ref case, just get out of here. */
+ if (unlikely((body->mbo_valid & OBD_MD_MDS))) {
+ rc = lmv_intent_remote(exp, it, NULL, reqp, cb_blocking,
+ extra_lock_flags);
+ if (rc != 0)
+ return rc;
+ body = req_capsule_server_get(&(*reqp)->rq_pill, &RMF_MDT_BODY);
+ if (!body)
+ return -EPROTO;
+ }
return rc;
}
int lmv_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
- void *lmm, int lmmsize, struct lookup_intent *it,
- int flags, struct ptlrpc_request **reqp,
+ struct lookup_intent *it, struct ptlrpc_request **reqp,
ldlm_blocking_callback cb_blocking,
__u64 extra_lock_flags)
{
@@ -300,8 +486,9 @@ int lmv_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
LASSERT(fid_is_sane(&op_data->op_fid1));
- CDEBUG(D_INODE, "INTENT LOCK '%s' for '%*s' on "DFID"\n",
- LL_IT2STR(it), op_data->op_namelen, op_data->op_name,
+ CDEBUG(D_INODE, "INTENT LOCK '%s' for "DFID" '%*s' on "DFID"\n",
+ LL_IT2STR(it), PFID(&op_data->op_fid2),
+ (int)op_data->op_namelen, op_data->op_name,
PFID(&op_data->op_fid1));
rc = lmv_check_connect(obd);
@@ -309,14 +496,34 @@ int lmv_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
return rc;
if (it->it_op & (IT_LOOKUP | IT_GETATTR | IT_LAYOUT))
- rc = lmv_intent_lookup(exp, op_data, lmm, lmmsize, it,
- flags, reqp, cb_blocking,
+ rc = lmv_intent_lookup(exp, op_data, it, reqp, cb_blocking,
extra_lock_flags);
else if (it->it_op & IT_OPEN)
- rc = lmv_intent_open(exp, op_data, lmm, lmmsize, it,
- flags, reqp, cb_blocking,
+ rc = lmv_intent_open(exp, op_data, it, reqp, cb_blocking,
extra_lock_flags);
else
LBUG();
+
+ if (rc < 0) {
+ struct lustre_handle lock_handle;
+
+ if (it->it_lock_mode) {
+ lock_handle.cookie = it->it_lock_handle;
+ ldlm_lock_decref(&lock_handle, it->it_lock_mode);
+ }
+
+ it->it_lock_handle = 0;
+ it->it_lock_mode = 0;
+
+ if (it->it_remote_lock_mode) {
+ lock_handle.cookie = it->it_remote_lock_handle;
+ ldlm_lock_decref(&lock_handle,
+ it->it_remote_lock_mode);
+ }
+
+ it->it_remote_lock_handle = 0;
+ it->it_remote_lock_mode = 0;
+ }
+
return rc;
}
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_internal.h b/drivers/staging/lustre/lustre/lmv/lmv_internal.h
index 0beafc49b8d2..52b03745ac19 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_internal.h
+++ b/drivers/staging/lustre/lustre/lmv/lmv_internal.h
@@ -35,6 +35,7 @@
#include "../include/lustre/lustre_idl.h"
#include "../include/obd.h"
+#include "../include/lustre_lmv.h"
#define LMV_MAX_TGT_COUNT 128
@@ -44,77 +45,116 @@
int lmv_check_connect(struct obd_device *obd);
int lmv_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
- void *lmm, int lmmsize, struct lookup_intent *it,
- int flags, struct ptlrpc_request **reqp,
+ struct lookup_intent *it, struct ptlrpc_request **reqp,
ldlm_blocking_callback cb_blocking,
__u64 extra_lock_flags);
int lmv_fld_lookup(struct lmv_obd *lmv, const struct lu_fid *fid, u32 *mds);
int __lmv_fid_alloc(struct lmv_obd *lmv, struct lu_fid *fid, u32 mds);
-int lmv_fid_alloc(struct obd_export *exp, struct lu_fid *fid,
- struct md_op_data *op_data);
+int lmv_fid_alloc(const struct lu_env *env, struct obd_export *exp,
+ struct lu_fid *fid, struct md_op_data *op_data);
-static inline struct lmv_stripe_md *lmv_get_mea(struct ptlrpc_request *req)
-{
- struct mdt_body *body;
- struct lmv_stripe_md *mea;
-
- LASSERT(req);
-
- body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
-
- if (!body || !S_ISDIR(body->mode) || !body->eadatasize)
- return NULL;
+int lmv_unpack_md(struct obd_export *exp, struct lmv_stripe_md **lsmp,
+ const union lmv_mds_md *lmm, int stripe_count);
- mea = req_capsule_server_sized_get(&req->rq_pill, &RMF_MDT_MD,
- body->eadatasize);
- if (mea->mea_count == 0)
- return NULL;
- if (mea->mea_magic != MEA_MAGIC_LAST_CHAR &&
- mea->mea_magic != MEA_MAGIC_ALL_CHARS &&
- mea->mea_magic != MEA_MAGIC_HASH_SEGMENT)
- return NULL;
+int lmv_revalidate_slaves(struct obd_export *exp,
+ const struct lmv_stripe_md *lsm,
+ ldlm_blocking_callback cb_blocking,
+ int extra_lock_flags);
- return mea;
-}
-
-static inline int lmv_get_easize(struct lmv_obd *lmv)
+static inline struct obd_device *lmv2obd_dev(struct lmv_obd *lmv)
{
- return sizeof(struct lmv_stripe_md) +
- lmv->desc.ld_tgt_count *
- sizeof(struct lu_fid);
+ return container_of0(lmv, struct obd_device, u.lmv);
}
static inline struct lmv_tgt_desc *
-lmv_get_target(struct lmv_obd *lmv, u32 mds)
+lmv_get_target(struct lmv_obd *lmv, u32 mdt_idx, int *index)
{
- int count = lmv->desc.ld_tgt_count;
int i;
- for (i = 0; i < count; i++) {
+ for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
if (!lmv->tgts[i])
continue;
- if (lmv->tgts[i]->ltd_idx == mds)
+ if (lmv->tgts[i]->ltd_idx == mdt_idx) {
+ if (index)
+ *index = i;
return lmv->tgts[i];
+ }
}
return ERR_PTR(-ENODEV);
}
-static inline struct lmv_tgt_desc *
-lmv_find_target(struct lmv_obd *lmv, const struct lu_fid *fid)
+static inline int
+lmv_find_target_index(struct lmv_obd *lmv, const struct lu_fid *fid)
{
- u32 mds = 0;
- int rc;
+ struct lmv_tgt_desc *ltd;
+ u32 mdt_idx = 0;
+ int index = 0;
if (lmv->desc.ld_tgt_count > 1) {
- rc = lmv_fld_lookup(lmv, fid, &mds);
- if (rc)
- return ERR_PTR(rc);
+ int rc;
+
+ rc = lmv_fld_lookup(lmv, fid, &mdt_idx);
+ if (rc < 0)
+ return rc;
}
- return lmv_get_target(lmv, mds);
+ ltd = lmv_get_target(lmv, mdt_idx, &index);
+ if (IS_ERR(ltd))
+ return PTR_ERR(ltd);
+
+ return index;
+}
+
+static inline struct lmv_tgt_desc *
+lmv_find_target(struct lmv_obd *lmv, const struct lu_fid *fid)
+{
+ int index;
+
+ index = lmv_find_target_index(lmv, fid);
+ if (index < 0)
+ return ERR_PTR(index);
+
+ return lmv->tgts[index];
+}
+
+static inline int lmv_stripe_md_size(int stripe_count)
+{
+ struct lmv_stripe_md *lsm;
+
+ return sizeof(*lsm) + stripe_count * sizeof(lsm->lsm_md_oinfo[0]);
+}
+
+int lmv_name_to_stripe_index(enum lmv_hash_type hashtype,
+ unsigned int max_mdt_index,
+ const char *name, int namelen);
+
+static inline const struct lmv_oinfo *
+lsm_name_to_stripe_info(const struct lmv_stripe_md *lsm, const char *name,
+ int namelen)
+{
+ int stripe_index;
+
+ stripe_index = lmv_name_to_stripe_index(lsm->lsm_md_hash_type,
+ lsm->lsm_md_stripe_count,
+ name, namelen);
+ if (stripe_index < 0)
+ return ERR_PTR(stripe_index);
+
+ LASSERTF(stripe_index < lsm->lsm_md_stripe_count,
+ "stripe_index = %d, stripe_count = %d hash_type = %x name = %.*s\n",
+ stripe_index, lsm->lsm_md_stripe_count,
+ lsm->lsm_md_hash_type, namelen, name);
+
+ return &lsm->lsm_md_oinfo[stripe_index];
+}
+
+static inline bool lmv_need_try_all_stripes(const struct lmv_stripe_md *lsm)
+{
+ return !lmv_is_known_hash_type(lsm->lsm_md_hash_type) ||
+ lsm->lsm_md_hash_type & LMV_HASH_FLAG_MIGRATION;
}
struct lmv_tgt_desc
@@ -123,6 +163,6 @@ struct lmv_tgt_desc
/* lproc_lmv.c */
void lprocfs_lmv_init_vars(struct lprocfs_static_vars *lvars);
-extern struct file_operations lmv_proc_target_fops;
+extern const struct file_operations lmv_proc_target_fops;
#endif
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
index 0e1588a43187..7dbb2b946acf 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
@@ -43,12 +43,13 @@
#include "../include/lustre/lustre_idl.h"
#include "../include/obd_support.h"
-#include "../include/lustre_lib.h"
#include "../include/lustre_net.h"
#include "../include/obd_class.h"
+#include "../include/lustre_lmv.h"
#include "../include/lprocfs_status.h"
-#include "../include/lustre_lite.h"
+#include "../include/cl_object.h"
#include "../include/lustre_fid.h"
+#include "../include/lustre/lustre_ioctl.h"
#include "../include/lustre_kernelcomm.h"
#include "lmv_internal.h"
@@ -70,12 +71,12 @@ static void lmv_activate_target(struct lmv_obd *lmv,
* -ENOTCONN: The UUID is found, but the target connection is bad (!)
* -EBADF : The UUID is found, but the OBD of the wrong type (!)
*/
-static int lmv_set_mdc_active(struct lmv_obd *lmv, struct obd_uuid *uuid,
+static int lmv_set_mdc_active(struct lmv_obd *lmv, const struct obd_uuid *uuid,
int activate)
{
struct lmv_tgt_desc *uninitialized_var(tgt);
struct obd_device *obd;
- int i;
+ u32 i;
int rc = 0;
CDEBUG(D_INFO, "Searching in lmv %p for uuid %s (activate=%d)\n",
@@ -244,36 +245,12 @@ static int lmv_connect(const struct lu_env *env,
return rc;
}
-static void lmv_set_timeouts(struct obd_device *obd)
-{
- struct lmv_obd *lmv;
- int i;
-
- lmv = &obd->u.lmv;
- if (lmv->server_timeout == 0)
- return;
-
- if (lmv->connected == 0)
- return;
-
- for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
- struct lmv_tgt_desc *tgt = lmv->tgts[i];
-
- tgt = lmv->tgts[i];
- if (!tgt || !tgt->ltd_exp || !tgt->ltd_active)
- continue;
-
- obd_set_info_async(NULL, tgt->ltd_exp, sizeof(KEY_INTERMDS),
- KEY_INTERMDS, 0, NULL, NULL);
- }
-}
-
-static int lmv_init_ea_size(struct obd_export *exp, int easize,
- int def_easize, int cookiesize, int def_cookiesize)
+static int lmv_init_ea_size(struct obd_export *exp, u32 easize, u32 def_easize,
+ u32 cookiesize, u32 def_cookiesize)
{
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
- int i;
+ u32 i;
int rc = 0;
int change = 0;
@@ -420,6 +397,7 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp,
{
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt;
+ int orig_tgt_count = 0;
int rc = 0;
CDEBUG(D_CONFIG, "Target uuid: %s. index %d\n", uuidp->uuid, index);
@@ -489,14 +467,17 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp,
tgt->ltd_uuid = *uuidp;
tgt->ltd_active = 0;
lmv->tgts[index] = tgt;
- if (index >= lmv->desc.ld_tgt_count)
+ if (index >= lmv->desc.ld_tgt_count) {
+ orig_tgt_count = lmv->desc.ld_tgt_count;
lmv->desc.ld_tgt_count = index + 1;
+ }
if (lmv->connected) {
rc = lmv_connect_mdc(obd, tgt);
if (rc) {
spin_lock(&lmv->lmv_lock);
- lmv->desc.ld_tgt_count--;
+ if (lmv->desc.ld_tgt_count == index + 1)
+ lmv->desc.ld_tgt_count = orig_tgt_count;
memset(tgt, 0, sizeof(*tgt));
spin_unlock(&lmv->lmv_lock);
} else {
@@ -514,7 +495,7 @@ int lmv_check_connect(struct obd_device *obd)
{
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt;
- int i;
+ u32 i;
int rc;
int easize;
@@ -554,10 +535,9 @@ int lmv_check_connect(struct obd_device *obd)
goto out_disc;
}
- lmv_set_timeouts(obd);
class_export_put(lmv->exp);
lmv->connected = 1;
- easize = lmv_get_easize(lmv);
+ easize = lmv_mds_md_size(lmv->desc.ld_tgt_count, LMV_MAGIC);
lmv_init_ea_size(obd->obd_self_export, easize, 0, 0, 0);
mutex_unlock(&lmv->lmv_init_mutex);
return 0;
@@ -629,7 +609,7 @@ static int lmv_disconnect(struct obd_export *exp)
struct obd_device *obd = class_exp2obd(exp);
struct lmv_obd *lmv = &obd->u.lmv;
int rc;
- int i;
+ u32 i;
if (!lmv->tgts)
goto out_local;
@@ -758,7 +738,7 @@ static int lmv_hsm_req_count(struct lmv_obd *lmv,
const struct hsm_user_request *hur,
const struct lmv_tgt_desc *tgt_mds)
{
- int i, nr = 0;
+ u32 i, nr = 0;
struct lmv_tgt_desc *curr_tgt;
/* count how many requests must be sent to the given target */
@@ -885,10 +865,8 @@ static int lmv_hsm_ct_register(struct lmv_obd *lmv, unsigned int cmd, int len,
rc = libcfs_kkuc_group_add(filp, lk->lk_uid, lk->lk_group,
&kcd, sizeof(kcd));
- if (rc) {
- if (filp)
- fput(filp);
- }
+ if (rc)
+ fput(filp);
return rc;
}
@@ -899,10 +877,10 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp,
struct obd_device *obddev = class_exp2obd(exp);
struct lmv_obd *lmv = &obddev->u.lmv;
struct lmv_tgt_desc *tgt = NULL;
- int i = 0;
+ u32 i = 0;
int rc = 0;
int set = 0;
- int count = lmv->desc.ld_tgt_count;
+ u32 count = lmv->desc.ld_tgt_count;
if (count == 0)
return -ENOTTY;
@@ -1011,6 +989,21 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp,
rc = obd_iocontrol(cmd, tgt->ltd_exp, len, karg, uarg);
break;
}
+ case LL_IOC_FID2MDTIDX: {
+ struct lu_fid *fid = karg;
+ int mdt_index;
+
+ rc = lmv_fld_lookup(lmv, fid, &mdt_index);
+ if (rc)
+ return rc;
+
+ /*
+ * Note: this is from llite(see ll_dir_ioctl()), @uarg does not
+ * point to user space memory for FID2MDTIDX.
+ */
+ *(__u32 *)uarg = mdt_index;
+ break;
+ }
case OBD_IOC_FID2PATH: {
rc = lmv_fid2path(exp, len, karg, uarg);
break;
@@ -1169,32 +1162,37 @@ static int lmv_placement_policy(struct obd_device *obd,
return 0;
}
+ if (op_data->op_default_stripe_offset != -1) {
+ *mds = op_data->op_default_stripe_offset;
+ return 0;
+ }
+
/**
* If stripe_offset is provided during setdirstripe
* (setdirstripe -i xx), xx MDS will be chosen.
*/
- if (op_data->op_cli_flags & CLI_SET_MEA) {
+ if (op_data->op_cli_flags & CLI_SET_MEA && op_data->op_data) {
struct lmv_user_md *lum;
- lum = (struct lmv_user_md *)op_data->op_data;
- if (lum->lum_type == LMV_STRIPE_TYPE &&
- lum->lum_stripe_offset != -1) {
- if (lum->lum_stripe_offset >= lmv->desc.ld_tgt_count) {
- CERROR("%s: Stripe_offset %d > MDT count %d: rc = %d\n",
- obd->obd_name,
- lum->lum_stripe_offset,
- lmv->desc.ld_tgt_count, -ERANGE);
- return -ERANGE;
- }
- *mds = lum->lum_stripe_offset;
- return 0;
+ lum = op_data->op_data;
+ if (le32_to_cpu(lum->lum_stripe_offset) != (__u32)-1) {
+ *mds = le32_to_cpu(lum->lum_stripe_offset);
+ } else {
+ /*
+ * -1 means default, which will be in the same MDT with
+ * the stripe
+ */
+ *mds = op_data->op_mds;
+ lum->lum_stripe_offset = cpu_to_le32(op_data->op_mds);
}
+ } else {
+ /*
+ * Allocate new fid on target according to operation type and
+ * parent home mds.
+ */
+ *mds = op_data->op_mds;
}
- /* Allocate new fid on target according to operation type and parent
- * home mds.
- */
- *mds = op_data->op_mds;
return 0;
}
@@ -1203,7 +1201,7 @@ int __lmv_fid_alloc(struct lmv_obd *lmv, struct lu_fid *fid, u32 mds)
struct lmv_tgt_desc *tgt;
int rc;
- tgt = lmv_get_target(lmv, mds);
+ tgt = lmv_get_target(lmv, mds, NULL);
if (IS_ERR(tgt))
return PTR_ERR(tgt);
@@ -1221,7 +1219,7 @@ int __lmv_fid_alloc(struct lmv_obd *lmv, struct lu_fid *fid, u32 mds)
/*
* Asking underlaying tgt layer to allocate new fid.
*/
- rc = obd_fid_alloc(tgt->ltd_exp, fid, NULL);
+ rc = obd_fid_alloc(NULL, tgt->ltd_exp, fid, NULL);
if (rc > 0) {
LASSERT(fid_is_sane(fid));
rc = 0;
@@ -1232,8 +1230,8 @@ out:
return rc;
}
-int lmv_fid_alloc(struct obd_export *exp, struct lu_fid *fid,
- struct md_op_data *op_data)
+int lmv_fid_alloc(const struct lu_env *env, struct obd_export *exp,
+ struct lu_fid *fid, struct md_op_data *op_data)
{
struct obd_device *obd = class_exp2obd(exp);
struct lmv_obd *lmv = &obd->u.lmv;
@@ -1278,10 +1276,10 @@ static int lmv_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
return -EINVAL;
}
- lmv->tgts = kcalloc(32, sizeof(*lmv->tgts), GFP_NOFS);
+ lmv->tgts_size = 32U;
+ lmv->tgts = kcalloc(lmv->tgts_size, sizeof(*lmv->tgts), GFP_NOFS);
if (!lmv->tgts)
return -ENOMEM;
- lmv->tgts_size = 32;
obd_str2uuid(&lmv->desc.ld_uuid, desc->ld_uuid.uuid);
lmv->desc.ld_tgt_count = 0;
@@ -1354,7 +1352,7 @@ static int lmv_process_config(struct obd_device *obd, u32 len, void *buf)
obd_str2uuid(&obd_uuid, lustre_cfg_buf(lcfg, 1));
- if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
+ if (sscanf(lustre_cfg_buf(lcfg, 2), "%u", &index) != 1) {
rc = -EINVAL;
goto out;
}
@@ -1380,7 +1378,7 @@ static int lmv_statfs(const struct lu_env *env, struct obd_export *exp,
struct lmv_obd *lmv = &obd->u.lmv;
struct obd_statfs *temp;
int rc = 0;
- int i;
+ u32 i;
rc = lmv_check_connect(obd);
if (rc)
@@ -1522,7 +1520,7 @@ static int lmv_null_inode(struct obd_export *exp, const struct lu_fid *fid)
{
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
- int i;
+ u32 i;
int rc;
rc = lmv_check_connect(obd);
@@ -1545,36 +1543,6 @@ static int lmv_null_inode(struct obd_export *exp, const struct lu_fid *fid)
return 0;
}
-static int lmv_find_cbdata(struct obd_export *exp, const struct lu_fid *fid,
- ldlm_iterator_t it, void *data)
-{
- struct obd_device *obd = exp->exp_obd;
- struct lmv_obd *lmv = &obd->u.lmv;
- int i;
- int rc;
-
- rc = lmv_check_connect(obd);
- if (rc)
- return rc;
-
- CDEBUG(D_INODE, "CBDATA for "DFID"\n", PFID(fid));
-
- /*
- * With DNE every object can have two locks in different namespaces:
- * lookup lock in space of MDT storing direntry and update/open lock in
- * space of MDT storing inode.
- */
- for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
- if (!lmv->tgts[i] || !lmv->tgts[i]->ltd_exp)
- continue;
- rc = md_find_cbdata(lmv->tgts[i]->ltd_exp, fid, it, data);
- if (rc)
- return rc;
- }
-
- return rc;
-}
-
static int lmv_close(struct obd_export *exp, struct md_op_data *op_data,
struct md_open_data *mod, struct ptlrpc_request **request)
{
@@ -1596,25 +1564,116 @@ static int lmv_close(struct obd_export *exp, struct md_op_data *op_data,
return rc;
}
-struct lmv_tgt_desc
-*lmv_locate_mds(struct lmv_obd *lmv, struct md_op_data *op_data,
- struct lu_fid *fid)
+/**
+ * Choosing the MDT by name or FID in @op_data.
+ * For non-striped directory, it will locate MDT by fid.
+ * For striped-directory, it will locate MDT by name. And also
+ * it will reset op_fid1 with the FID of the chosen stripe.
+ **/
+static struct lmv_tgt_desc *
+lmv_locate_target_for_name(struct lmv_obd *lmv, struct lmv_stripe_md *lsm,
+ const char *name, int namelen, struct lu_fid *fid,
+ u32 *mds)
+{
+ const struct lmv_oinfo *oinfo;
+ struct lmv_tgt_desc *tgt;
+
+ if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_NAME_HASH)) {
+ if (cfs_fail_val >= lsm->lsm_md_stripe_count)
+ return ERR_PTR(-EBADF);
+ oinfo = &lsm->lsm_md_oinfo[cfs_fail_val];
+ } else {
+ oinfo = lsm_name_to_stripe_info(lsm, name, namelen);
+ if (IS_ERR(oinfo))
+ return ERR_CAST(oinfo);
+ }
+
+ if (fid)
+ *fid = oinfo->lmo_fid;
+ if (mds)
+ *mds = oinfo->lmo_mds;
+
+ tgt = lmv_get_target(lmv, oinfo->lmo_mds, NULL);
+
+ CDEBUG(D_INFO, "locate on mds %u " DFID "\n", oinfo->lmo_mds,
+ PFID(&oinfo->lmo_fid));
+ return tgt;
+}
+
+/**
+ * Locate mds by fid or name
+ *
+ * For striped directory (lsm != NULL), it will locate the stripe
+ * by name hash (see lsm_name_to_stripe_info()). Note: if the hash_type
+ * is unknown, it will return -EBADFD, and lmv_intent_lookup might need
+ * walk through all of stripes to locate the entry.
+ *
+ * For normal direcotry, it will locate MDS by FID directly.
+ * \param[in] lmv LMV device
+ * \param[in] op_data client MD stack parameters, name, namelen
+ * mds_num etc.
+ * \param[in] fid object FID used to locate MDS.
+ *
+ * retval pointer to the lmv_tgt_desc if succeed.
+ * ERR_PTR(errno) if failed.
+ */
+struct lmv_tgt_desc*
+lmv_locate_mds(struct lmv_obd *lmv, struct md_op_data *op_data,
+ struct lu_fid *fid)
{
+ struct lmv_stripe_md *lsm = op_data->op_mea1;
struct lmv_tgt_desc *tgt;
- tgt = lmv_find_target(lmv, fid);
- if (IS_ERR(tgt))
+ /*
+ * During creating VOLATILE file, it should honor the mdt
+ * index if the file under striped dir is being restored, see
+ * ct_restore().
+ */
+ if (op_data->op_bias & MDS_CREATE_VOLATILE &&
+ (int)op_data->op_mds != -1 && lsm) {
+ int i;
+
+ tgt = lmv_get_target(lmv, op_data->op_mds, NULL);
+ if (IS_ERR(tgt))
+ return tgt;
+
+ /* refill the right parent fid */
+ for (i = 0; i < lsm->lsm_md_stripe_count; i++) {
+ struct lmv_oinfo *oinfo;
+
+ oinfo = &lsm->lsm_md_oinfo[i];
+ if (oinfo->lmo_mds == op_data->op_mds) {
+ *fid = oinfo->lmo_fid;
+ break;
+ }
+ }
+
+ /* Hmm, can not find the stripe by mdt_index(op_mds) */
+ if (i == lsm->lsm_md_stripe_count)
+ tgt = ERR_PTR(-EINVAL);
+
return tgt;
+ }
- op_data->op_mds = tgt->ltd_idx;
+ if (!lsm || !op_data->op_namelen) {
+ tgt = lmv_find_target(lmv, fid);
+ if (IS_ERR(tgt))
+ return tgt;
- return tgt;
+ op_data->op_mds = tgt->ltd_idx;
+
+ return tgt;
+ }
+
+ return lmv_locate_target_for_name(lmv, lsm, op_data->op_name,
+ op_data->op_namelen, fid,
+ &op_data->op_mds);
}
static int lmv_create(struct obd_export *exp, struct md_op_data *op_data,
- const void *data, int datalen, int mode, __u32 uid,
- __u32 gid, cfs_cap_t cap_effective, __u64 rdev,
- struct ptlrpc_request **request)
+ const void *data, size_t datalen, umode_t mode,
+ uid_t uid, gid_t gid, cfs_cap_t cap_effective,
+ __u64 rdev, struct ptlrpc_request **request)
{
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
@@ -1632,13 +1691,30 @@ static int lmv_create(struct obd_export *exp, struct md_op_data *op_data,
if (IS_ERR(tgt))
return PTR_ERR(tgt);
- rc = lmv_fid_alloc(exp, &op_data->op_fid2, op_data);
+ CDEBUG(D_INODE, "CREATE name '%.*s' on "DFID" -> mds #%x\n",
+ (int)op_data->op_namelen, op_data->op_name,
+ PFID(&op_data->op_fid1), op_data->op_mds);
+
+ rc = lmv_fid_alloc(NULL, exp, &op_data->op_fid2, op_data);
if (rc)
return rc;
- CDEBUG(D_INODE, "CREATE '%*s' on "DFID" -> mds #%x\n",
- op_data->op_namelen, op_data->op_name, PFID(&op_data->op_fid1),
- op_data->op_mds);
+ if (exp_connect_flags(exp) & OBD_CONNECT_DIR_STRIPE) {
+ /*
+ * Send the create request to the MDT where the object
+ * will be located
+ */
+ tgt = lmv_find_target(lmv, &op_data->op_fid2);
+ if (IS_ERR(tgt))
+ return PTR_ERR(tgt);
+
+ op_data->op_mds = tgt->ltd_idx;
+ } else {
+ CDEBUG(D_CONFIG, "Server doesn't support striped dirs\n");
+ }
+
+ CDEBUG(D_INODE, "CREATE obj "DFID" -> mds #%x\n",
+ PFID(&op_data->op_fid1), op_data->op_mds);
op_data->op_flags |= MF_MDC_CANCEL_FID1;
rc = md_create(tgt->ltd_exp, op_data, data, datalen, mode, uid, gid,
@@ -1674,70 +1750,10 @@ static int lmv_done_writing(struct obd_export *exp,
}
static int
-lmv_enqueue_remote(struct obd_export *exp, struct ldlm_enqueue_info *einfo,
- struct lookup_intent *it, struct md_op_data *op_data,
- struct lustre_handle *lockh, void *lmm, int lmmsize,
- __u64 extra_lock_flags)
-{
- struct ptlrpc_request *req = it->it_request;
- struct obd_device *obd = exp->exp_obd;
- struct lmv_obd *lmv = &obd->u.lmv;
- struct lustre_handle plock;
- struct lmv_tgt_desc *tgt;
- struct md_op_data *rdata;
- struct lu_fid fid1;
- struct mdt_body *body;
- int rc = 0;
- int pmode;
-
- body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
-
- if (!(body->valid & OBD_MD_MDS))
- return 0;
-
- CDEBUG(D_INODE, "REMOTE_ENQUEUE '%s' on "DFID" -> "DFID"\n",
- LL_IT2STR(it), PFID(&op_data->op_fid1), PFID(&body->fid1));
-
- /*
- * We got LOOKUP lock, but we really need attrs.
- */
- pmode = it->it_lock_mode;
- LASSERT(pmode != 0);
- memcpy(&plock, lockh, sizeof(plock));
- it->it_lock_mode = 0;
- it->it_request = NULL;
- fid1 = body->fid1;
-
- ptlrpc_req_finished(req);
-
- tgt = lmv_find_target(lmv, &fid1);
- if (IS_ERR(tgt)) {
- rc = PTR_ERR(tgt);
- goto out;
- }
-
- rdata = kzalloc(sizeof(*rdata), GFP_NOFS);
- if (!rdata) {
- rc = -ENOMEM;
- goto out;
- }
-
- rdata->op_fid1 = fid1;
- rdata->op_bias = MDS_CROSS_REF;
-
- rc = md_enqueue(tgt->ltd_exp, einfo, it, rdata, lockh,
- lmm, lmmsize, NULL, extra_lock_flags);
- kfree(rdata);
-out:
- ldlm_lock_decref(&plock, pmode);
- return rc;
-}
-
-static int
lmv_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo,
+ const ldlm_policy_data_t *policy,
struct lookup_intent *it, struct md_op_data *op_data,
- struct lustre_handle *lockh, void *lmm, int lmmsize,
- struct ptlrpc_request **req, __u64 extra_lock_flags)
+ struct lustre_handle *lockh, __u64 extra_lock_flags)
{
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
@@ -1755,22 +1771,18 @@ lmv_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo,
if (IS_ERR(tgt))
return PTR_ERR(tgt);
- CDEBUG(D_INODE, "ENQUEUE '%s' on "DFID" -> mds #%d\n",
+ CDEBUG(D_INODE, "ENQUEUE '%s' on " DFID " -> mds #%u\n",
LL_IT2STR(it), PFID(&op_data->op_fid1), tgt->ltd_idx);
- rc = md_enqueue(tgt->ltd_exp, einfo, it, op_data, lockh,
- lmm, lmmsize, req, extra_lock_flags);
+ rc = md_enqueue(tgt->ltd_exp, einfo, policy, it, op_data, lockh,
+ extra_lock_flags);
- if (rc == 0 && it && it->it_op == IT_OPEN) {
- rc = lmv_enqueue_remote(exp, einfo, it, op_data, lockh,
- lmm, lmmsize, extra_lock_flags);
- }
return rc;
}
static int
lmv_getattr_name(struct obd_export *exp, struct md_op_data *op_data,
- struct ptlrpc_request **request)
+ struct ptlrpc_request **preq)
{
struct ptlrpc_request *req = NULL;
struct obd_device *obd = exp->exp_obd;
@@ -1787,26 +1799,25 @@ lmv_getattr_name(struct obd_export *exp, struct md_op_data *op_data,
if (IS_ERR(tgt))
return PTR_ERR(tgt);
- CDEBUG(D_INODE, "GETATTR_NAME for %*s on "DFID" -> mds #%d\n",
- op_data->op_namelen, op_data->op_name, PFID(&op_data->op_fid1),
- tgt->ltd_idx);
+ CDEBUG(D_INODE, "GETATTR_NAME for %*s on " DFID " -> mds #%u\n",
+ (int)op_data->op_namelen, op_data->op_name,
+ PFID(&op_data->op_fid1), tgt->ltd_idx);
- rc = md_getattr_name(tgt->ltd_exp, op_data, request);
+ rc = md_getattr_name(tgt->ltd_exp, op_data, preq);
if (rc != 0)
return rc;
- body = req_capsule_server_get(&(*request)->rq_pill,
- &RMF_MDT_BODY);
-
- if (body->valid & OBD_MD_MDS) {
- struct lu_fid rid = body->fid1;
+ body = req_capsule_server_get(&(*preq)->rq_pill, &RMF_MDT_BODY);
+ if (body->mbo_valid & OBD_MD_MDS) {
+ struct lu_fid rid = body->mbo_fid1;
CDEBUG(D_INODE, "Request attrs for "DFID"\n",
PFID(&rid));
tgt = lmv_find_target(lmv, &rid);
if (IS_ERR(tgt)) {
- ptlrpc_req_finished(*request);
+ ptlrpc_req_finished(*preq);
+ *preq = NULL;
return PTR_ERR(tgt);
}
@@ -1815,8 +1826,8 @@ lmv_getattr_name(struct obd_export *exp, struct md_op_data *op_data,
op_data->op_namelen = 0;
op_data->op_name = NULL;
rc = md_getattr_name(tgt->ltd_exp, op_data, &req);
- ptlrpc_req_finished(*request);
- *request = req;
+ ptlrpc_req_finished(*preq);
+ *preq = req;
}
return rc;
@@ -1829,23 +1840,24 @@ lmv_getattr_name(struct obd_export *exp, struct md_op_data *op_data,
fl == MF_MDC_CANCEL_FID4 ? &op_data->op_fid4 : \
NULL)
-static int lmv_early_cancel(struct obd_export *exp, struct md_op_data *op_data,
- int op_tgt, enum ldlm_mode mode, int bits,
- int flag)
+static int lmv_early_cancel(struct obd_export *exp, struct lmv_tgt_desc *tgt,
+ struct md_op_data *op_data, int op_tgt,
+ enum ldlm_mode mode, int bits, int flag)
{
struct lu_fid *fid = md_op_data_fid(op_data, flag);
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
- struct lmv_tgt_desc *tgt;
ldlm_policy_data_t policy = { {0} };
int rc = 0;
if (!fid_is_sane(fid))
return 0;
- tgt = lmv_find_target(lmv, fid);
- if (IS_ERR(tgt))
- return PTR_ERR(tgt);
+ if (!tgt) {
+ tgt = lmv_find_target(lmv, fid);
+ if (IS_ERR(tgt))
+ return PTR_ERR(tgt);
+ }
if (tgt->ltd_idx != op_tgt) {
CDEBUG(D_INODE, "EARLY_CANCEL on "DFID"\n", PFID(fid));
@@ -1882,12 +1894,24 @@ static int lmv_link(struct obd_export *exp, struct md_op_data *op_data,
LASSERT(op_data->op_namelen != 0);
CDEBUG(D_INODE, "LINK "DFID":%*s to "DFID"\n",
- PFID(&op_data->op_fid2), op_data->op_namelen,
+ PFID(&op_data->op_fid2), (int)op_data->op_namelen,
op_data->op_name, PFID(&op_data->op_fid1));
op_data->op_fsuid = from_kuid(&init_user_ns, current_fsuid());
op_data->op_fsgid = from_kgid(&init_user_ns, current_fsgid());
op_data->op_cap = cfs_curproc_cap_pack();
+ if (op_data->op_mea2) {
+ struct lmv_stripe_md *lsm = op_data->op_mea2;
+ const struct lmv_oinfo *oinfo;
+
+ oinfo = lsm_name_to_stripe_info(lsm, op_data->op_name,
+ op_data->op_namelen);
+ if (IS_ERR(oinfo))
+ return PTR_ERR(oinfo);
+
+ op_data->op_fid2 = oinfo->lmo_fid;
+ }
+
tgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid2);
if (IS_ERR(tgt))
return PTR_ERR(tgt);
@@ -1896,7 +1920,7 @@ static int lmv_link(struct obd_export *exp, struct md_op_data *op_data,
* Cancel UPDATE lock on child (fid1).
*/
op_data->op_flags |= MF_MDC_CANCEL_FID2;
- rc = lmv_early_cancel(exp, op_data, tgt->ltd_idx, LCK_EX,
+ rc = lmv_early_cancel(exp, NULL, op_data, tgt->ltd_idx, LCK_EX,
MDS_INODELOCK_UPDATE, MF_MDC_CANCEL_FID1);
if (rc != 0)
return rc;
@@ -1907,20 +1931,22 @@ static int lmv_link(struct obd_export *exp, struct md_op_data *op_data,
}
static int lmv_rename(struct obd_export *exp, struct md_op_data *op_data,
- const char *old, int oldlen, const char *new, int newlen,
+ const char *old, size_t oldlen,
+ const char *new, size_t newlen,
struct ptlrpc_request **request)
{
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *src_tgt;
- struct lmv_tgt_desc *tgt_tgt;
int rc;
LASSERT(oldlen != 0);
- CDEBUG(D_INODE, "RENAME %*s in "DFID" to %*s in "DFID"\n",
- oldlen, old, PFID(&op_data->op_fid1),
- newlen, new, PFID(&op_data->op_fid2));
+ CDEBUG(D_INODE, "RENAME %.*s in "DFID":%d to %.*s in "DFID":%d\n",
+ (int)oldlen, old, PFID(&op_data->op_fid1),
+ op_data->op_mea1 ? op_data->op_mea1->lsm_md_stripe_count : 0,
+ (int)newlen, new, PFID(&op_data->op_fid2),
+ op_data->op_mea2 ? op_data->op_mea2->lsm_md_stripe_count : 0);
rc = lmv_check_connect(obd);
if (rc)
@@ -1929,13 +1955,60 @@ static int lmv_rename(struct obd_export *exp, struct md_op_data *op_data,
op_data->op_fsuid = from_kuid(&init_user_ns, current_fsuid());
op_data->op_fsgid = from_kgid(&init_user_ns, current_fsgid());
op_data->op_cap = cfs_curproc_cap_pack();
- src_tgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid1);
+
+ if (op_data->op_cli_flags & CLI_MIGRATE) {
+ LASSERTF(fid_is_sane(&op_data->op_fid3), "invalid FID "DFID"\n",
+ PFID(&op_data->op_fid3));
+
+ if (op_data->op_mea1) {
+ struct lmv_stripe_md *lsm = op_data->op_mea1;
+ struct lmv_tgt_desc *tmp;
+
+ /* Fix the parent fid for striped dir */
+ tmp = lmv_locate_target_for_name(lmv, lsm, old,
+ oldlen,
+ &op_data->op_fid1,
+ NULL);
+ if (IS_ERR(tmp))
+ return PTR_ERR(tmp);
+ }
+
+ rc = lmv_fid_alloc(NULL, exp, &op_data->op_fid2, op_data);
+ if (rc)
+ return rc;
+ src_tgt = lmv_find_target(lmv, &op_data->op_fid3);
+ } else {
+ if (op_data->op_mea1) {
+ struct lmv_stripe_md *lsm = op_data->op_mea1;
+
+ src_tgt = lmv_locate_target_for_name(lmv, lsm, old,
+ oldlen,
+ &op_data->op_fid1,
+ &op_data->op_mds);
+ if (IS_ERR(src_tgt))
+ return PTR_ERR(src_tgt);
+ } else {
+ src_tgt = lmv_find_target(lmv, &op_data->op_fid1);
+ if (IS_ERR(src_tgt))
+ return PTR_ERR(src_tgt);
+
+ op_data->op_mds = src_tgt->ltd_idx;
+ }
+
+ if (op_data->op_mea2) {
+ struct lmv_stripe_md *lsm = op_data->op_mea2;
+ const struct lmv_oinfo *oinfo;
+
+ oinfo = lsm_name_to_stripe_info(lsm, new, newlen);
+ if (IS_ERR(oinfo))
+ return PTR_ERR(oinfo);
+
+ op_data->op_fid2 = oinfo->lmo_fid;
+ }
+ }
if (IS_ERR(src_tgt))
return PTR_ERR(src_tgt);
- tgt_tgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid2);
- if (IS_ERR(tgt_tgt))
- return PTR_ERR(tgt_tgt);
/*
* LOOKUP lock on src child (fid3) should also be cancelled for
* src_tgt in mdc_rename.
@@ -1946,35 +2019,53 @@ static int lmv_rename(struct obd_export *exp, struct md_op_data *op_data,
* Cancel UPDATE locks on tgt parent (fid2), tgt_tgt is its
* own target.
*/
- rc = lmv_early_cancel(exp, op_data, src_tgt->ltd_idx,
+ rc = lmv_early_cancel(exp, NULL, op_data, src_tgt->ltd_idx,
LCK_EX, MDS_INODELOCK_UPDATE,
MF_MDC_CANCEL_FID2);
-
+ if (rc)
+ return rc;
/*
- * Cancel LOOKUP locks on tgt child (fid4) for parent tgt_tgt.
+ * Cancel LOOKUP locks on source child (fid3) for parent tgt_tgt.
*/
- if (rc == 0) {
- rc = lmv_early_cancel(exp, op_data, src_tgt->ltd_idx,
+ if (fid_is_sane(&op_data->op_fid3)) {
+ struct lmv_tgt_desc *tgt;
+
+ tgt = lmv_find_target(lmv, &op_data->op_fid1);
+ if (IS_ERR(tgt))
+ return PTR_ERR(tgt);
+
+ /* Cancel LOOKUP lock on its parent */
+ rc = lmv_early_cancel(exp, tgt, op_data, src_tgt->ltd_idx,
LCK_EX, MDS_INODELOCK_LOOKUP,
- MF_MDC_CANCEL_FID4);
+ MF_MDC_CANCEL_FID3);
+ if (rc)
+ return rc;
+
+ rc = lmv_early_cancel(exp, NULL, op_data, src_tgt->ltd_idx,
+ LCK_EX, MDS_INODELOCK_FULL,
+ MF_MDC_CANCEL_FID3);
+ if (rc)
+ return rc;
}
/*
* Cancel all the locks on tgt child (fid4).
*/
- if (rc == 0)
- rc = lmv_early_cancel(exp, op_data, src_tgt->ltd_idx,
+ if (fid_is_sane(&op_data->op_fid4))
+ rc = lmv_early_cancel(exp, NULL, op_data, src_tgt->ltd_idx,
LCK_EX, MDS_INODELOCK_FULL,
MF_MDC_CANCEL_FID4);
- if (rc == 0)
- rc = md_rename(src_tgt->ltd_exp, op_data, old, oldlen,
- new, newlen, request);
+ CDEBUG(D_INODE, DFID":m%d to "DFID"\n", PFID(&op_data->op_fid1),
+ op_data->op_mds, PFID(&op_data->op_fid2));
+
+ rc = md_rename(src_tgt->ltd_exp, op_data, old, oldlen,
+ new, newlen, request);
return rc;
}
static int lmv_setattr(struct obd_export *exp, struct md_op_data *op_data,
- void *ea, int ealen, void *ea2, int ea2len,
+ void *ea, size_t ealen, void *ea2, size_t ea2len,
struct ptlrpc_request **request,
struct md_open_data **mod)
{
@@ -2021,169 +2112,419 @@ static int lmv_sync(struct obd_export *exp, const struct lu_fid *fid,
return rc;
}
-/*
- * Adjust a set of pages, each page containing an array of lu_dirpages,
- * so that each page can be used as a single logical lu_dirpage.
+/**
+ * Get current minimum entry from striped directory
*
- * A lu_dirpage is laid out as follows, where s = ldp_hash_start,
- * e = ldp_hash_end, f = ldp_flags, p = padding, and each "ent" is a
- * struct lu_dirent. It has size up to LU_PAGE_SIZE. The ldp_hash_end
- * value is used as a cookie to request the next lu_dirpage in a
- * directory listing that spans multiple pages (two in this example):
- * ________
- * | |
- * .|--------v------- -----.
- * |s|e|f|p|ent|ent| ... |ent|
- * '--|-------------- -----' Each CFS_PAGE contains a single
- * '------. lu_dirpage.
- * .---------v------- -----.
- * |s|e|f|p|ent| 0 | ... | 0 |
- * '----------------- -----'
+ * This function will search the dir entry, whose hash value is the
+ * closest(>=) to @hash_offset, from all of sub-stripes, and it is
+ * only being called for striped directory.
*
- * However, on hosts where the native VM page size (PAGE_SIZE) is
- * larger than LU_PAGE_SIZE, a single host page may contain multiple
- * lu_dirpages. After reading the lu_dirpages from the MDS, the
- * ldp_hash_end of the first lu_dirpage refers to the one immediately
- * after it in the same CFS_PAGE (arrows simplified for brevity, but
- * in general e0==s1, e1==s2, etc.):
+ * \param[in] exp export of LMV
+ * \param[in] op_data parameters transferred beween client MD stack
+ * stripe_information will be included in this
+ * parameter
+ * \param[in] cb_op ldlm callback being used in enqueue in
+ * mdc_read_page
+ * \param[in] hash_offset the hash value, which is used to locate
+ * minum(closet) dir entry
+ * \param[in|out] stripe_offset the caller use this to indicate the stripe
+ * index of last entry, so to avoid hash conflict
+ * between stripes. It will also be used to
+ * return the stripe index of current dir entry.
+ * \param[in|out] entp the minum entry and it also is being used
+ * to input the last dir entry to resolve the
+ * hash conflict
*
- * .-------------------- -----.
- * |s0|e0|f0|p|ent|ent| ... |ent|
- * |---v---------------- -----|
- * |s1|e1|f1|p|ent|ent| ... |ent|
- * |---v---------------- -----| Here, each CFS_PAGE contains
- * ... multiple lu_dirpages.
- * |---v---------------- -----|
- * |s'|e'|f'|p|ent|ent| ... |ent|
- * '---|---------------- -----'
- * v
- * .----------------------------.
- * | next CFS_PAGE |
+ * \param[out] ppage the page which holds the minum entry
*
- * This structure is transformed into a single logical lu_dirpage as follows:
+ * \retval = 0 get the entry successfully
+ * negative errno (< 0) does not get the entry
+ */
+static int lmv_get_min_striped_entry(struct obd_export *exp,
+ struct md_op_data *op_data,
+ struct md_callback *cb_op,
+ __u64 hash_offset, int *stripe_offset,
+ struct lu_dirent **entp,
+ struct page **ppage)
+{
+ struct lmv_stripe_md *lsm = op_data->op_mea1;
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+ struct lu_dirent *min_ent = NULL;
+ struct page *min_page = NULL;
+ struct lmv_tgt_desc *tgt;
+ int stripe_count;
+ int min_idx = 0;
+ int rc = 0;
+ int i;
+
+ stripe_count = lsm->lsm_md_stripe_count;
+ for (i = 0; i < stripe_count; i++) {
+ __u64 stripe_hash = hash_offset;
+ struct lu_dirent *ent = NULL;
+ struct page *page = NULL;
+ struct lu_dirpage *dp;
+
+ tgt = lmv_get_target(lmv, lsm->lsm_md_oinfo[i].lmo_mds, NULL);
+ if (IS_ERR(tgt)) {
+ rc = PTR_ERR(tgt);
+ goto out;
+ }
+
+ /*
+ * op_data will be shared by each stripe, so we need
+ * reset these value for each stripe
+ */
+ op_data->op_fid1 = lsm->lsm_md_oinfo[i].lmo_fid;
+ op_data->op_fid2 = lsm->lsm_md_oinfo[i].lmo_fid;
+ op_data->op_data = lsm->lsm_md_oinfo[i].lmo_root;
+next:
+ rc = md_read_page(tgt->ltd_exp, op_data, cb_op, stripe_hash,
+ &page);
+ if (rc)
+ goto out;
+
+ dp = page_address(page);
+ for (ent = lu_dirent_start(dp); ent;
+ ent = lu_dirent_next(ent)) {
+ /* Skip dummy entry */
+ if (!le16_to_cpu(ent->lde_namelen))
+ continue;
+
+ if (le64_to_cpu(ent->lde_hash) < hash_offset)
+ continue;
+
+ if (le64_to_cpu(ent->lde_hash) == hash_offset &&
+ (*entp == ent || i < *stripe_offset))
+ continue;
+
+ /* skip . and .. for other stripes */
+ if (i && (!strncmp(ent->lde_name, ".",
+ le16_to_cpu(ent->lde_namelen)) ||
+ !strncmp(ent->lde_name, "..",
+ le16_to_cpu(ent->lde_namelen))))
+ continue;
+ break;
+ }
+
+ if (!ent) {
+ stripe_hash = le64_to_cpu(dp->ldp_hash_end);
+
+ kunmap(page);
+ put_page(page);
+ page = NULL;
+
+ /*
+ * reach the end of current stripe, go to next stripe
+ */
+ if (stripe_hash == MDS_DIR_END_OFF)
+ continue;
+ else
+ goto next;
+ }
+
+ if (min_ent) {
+ if (le64_to_cpu(min_ent->lde_hash) >
+ le64_to_cpu(ent->lde_hash)) {
+ min_ent = ent;
+ kunmap(min_page);
+ put_page(min_page);
+ min_idx = i;
+ min_page = page;
+ } else {
+ kunmap(page);
+ put_page(page);
+ page = NULL;
+ }
+ } else {
+ min_ent = ent;
+ min_page = page;
+ min_idx = i;
+ }
+ }
+
+out:
+ if (*ppage) {
+ kunmap(*ppage);
+ put_page(*ppage);
+ }
+ *stripe_offset = min_idx;
+ *entp = min_ent;
+ *ppage = min_page;
+ return rc;
+}
+
+/**
+ * Build dir entry page from a striped directory
*
- * - Replace e0 with e' so the request for the next lu_dirpage gets the page
- * labeled 'next CFS_PAGE'.
+ * This function gets one entry by @offset from a striped directory. It will
+ * read entries from all of stripes, and choose one closest to the required
+ * offset(&offset). A few notes
+ * 1. skip . and .. for non-zero stripes, because there can only have one .
+ * and .. in a directory.
+ * 2. op_data will be shared by all of stripes, instead of allocating new
+ * one, so need to restore before reusing.
+ * 3. release the entry page if that is not being chosen.
*
- * - Copy the LDF_COLLIDE flag from f' to f0 to correctly reflect whether
- * a hash collision with the next page exists.
+ * \param[in] exp obd export refer to LMV
+ * \param[in] op_data hold those MD parameters of read_entry
+ * \param[in] cb_op ldlm callback being used in enqueue in mdc_read_entry
+ * \param[out] ldp the entry being read
+ * \param[out] ppage the page holding the entry. Note: because the entry
+ * will be accessed in upper layer, so we need hold the
+ * page until the usages of entry is finished, see
+ * ll_dir_entry_next.
*
- * - Adjust the lde_reclen of the ending entry of each lu_dirpage to span
- * to the first entry of the next lu_dirpage.
+ * retval =0 if get entry successfully
+ * <0 cannot get entry
*/
-#if PAGE_SIZE > LU_PAGE_SIZE
-static void lmv_adjust_dirpages(struct page **pages, int ncfspgs, int nlupgs)
-{
- int i;
+static int lmv_read_striped_page(struct obd_export *exp,
+ struct md_op_data *op_data,
+ struct md_callback *cb_op,
+ __u64 offset, struct page **ppage)
+{
+ struct inode *master_inode = op_data->op_data;
+ struct lu_fid master_fid = op_data->op_fid1;
+ struct obd_device *obd = exp->exp_obd;
+ __u64 hash_offset = offset;
+ struct page *min_ent_page = NULL;
+ struct page *ent_page = NULL;
+ struct lu_dirent *min_ent = NULL;
+ struct lu_dirent *last_ent;
+ struct lu_dirent *ent;
+ struct lu_dirpage *dp;
+ size_t left_bytes;
+ int ent_idx = 0;
+ void *area;
+ int rc;
- for (i = 0; i < ncfspgs; i++) {
- struct lu_dirpage *dp = kmap(pages[i]);
- struct lu_dirpage *first = dp;
- struct lu_dirent *end_dirent = NULL;
- struct lu_dirent *ent;
- __u64 hash_end = dp->ldp_hash_end;
- __u32 flags = dp->ldp_flags;
-
- while (--nlupgs > 0) {
- ent = lu_dirent_start(dp);
- for (end_dirent = ent; ent;
- end_dirent = ent, ent = lu_dirent_next(ent))
- ;
-
- /* Advance dp to next lu_dirpage. */
- dp = (struct lu_dirpage *)((char *)dp + LU_PAGE_SIZE);
-
- /* Check if we've reached the end of the CFS_PAGE. */
- if (!((unsigned long)dp & ~PAGE_MASK))
- break;
+ rc = lmv_check_connect(obd);
+ if (rc)
+ return rc;
- /* Save the hash and flags of this lu_dirpage. */
- hash_end = dp->ldp_hash_end;
- flags = dp->ldp_flags;
+ /*
+ * Allocate a page and read entries from all of stripes and fill
+ * the page by hash order
+ */
+ ent_page = alloc_page(GFP_KERNEL);
+ if (!ent_page)
+ return -ENOMEM;
- /* Check if lu_dirpage contains no entries. */
- if (!end_dirent)
- break;
+ /* Initialize the entry page */
+ dp = kmap(ent_page);
+ memset(dp, 0, sizeof(*dp));
+ dp->ldp_hash_start = cpu_to_le64(offset);
+ dp->ldp_flags |= LDF_COLLIDE;
+
+ area = dp + 1;
+ left_bytes = PAGE_SIZE - sizeof(*dp);
+ ent = area;
+ last_ent = ent;
+ do {
+ __u16 ent_size;
+
+ /* Find the minum entry from all sub-stripes */
+ rc = lmv_get_min_striped_entry(exp, op_data, cb_op, hash_offset,
+ &ent_idx, &min_ent,
+ &min_ent_page);
+ if (rc)
+ goto out;
- /* Enlarge the end entry lde_reclen from 0 to
- * first entry of next lu_dirpage.
- */
- LASSERT(le16_to_cpu(end_dirent->lde_reclen) == 0);
- end_dirent->lde_reclen =
- cpu_to_le16((char *)(dp->ldp_entries) -
- (char *)end_dirent);
+ /*
+ * If it can not get minum entry, it means it already reaches
+ * the end of this directory
+ */
+ if (!min_ent) {
+ last_ent->lde_reclen = 0;
+ hash_offset = MDS_DIR_END_OFF;
+ goto out;
+ }
+
+ ent_size = le16_to_cpu(min_ent->lde_reclen);
+
+ /*
+ * the last entry lde_reclen is 0, but it might not
+ * the end of this entry of this temporay entry
+ */
+ if (!ent_size)
+ ent_size = lu_dirent_calc_size(
+ le16_to_cpu(min_ent->lde_namelen),
+ le32_to_cpu(min_ent->lde_attrs));
+ if (ent_size > left_bytes) {
+ last_ent->lde_reclen = cpu_to_le16(0);
+ hash_offset = le64_to_cpu(min_ent->lde_hash);
+ goto out;
}
- first->ldp_hash_end = hash_end;
- first->ldp_flags &= ~cpu_to_le32(LDF_COLLIDE);
- first->ldp_flags |= flags & cpu_to_le32(LDF_COLLIDE);
+ memcpy(ent, min_ent, ent_size);
+
+ /*
+ * Replace . with master FID and Replace .. with the parent FID
+ * of master object
+ */
+ if (!strncmp(ent->lde_name, ".",
+ le16_to_cpu(ent->lde_namelen)) &&
+ le16_to_cpu(ent->lde_namelen) == 1)
+ fid_cpu_to_le(&ent->lde_fid, &master_fid);
+ else if (!strncmp(ent->lde_name, "..",
+ le16_to_cpu(ent->lde_namelen)) &&
+ le16_to_cpu(ent->lde_namelen) == 2)
+ fid_cpu_to_le(&ent->lde_fid, &op_data->op_fid3);
+
+ left_bytes -= ent_size;
+ ent->lde_reclen = cpu_to_le16(ent_size);
+ last_ent = ent;
+ ent = (void *)ent + ent_size;
+ hash_offset = le64_to_cpu(min_ent->lde_hash);
+ if (hash_offset == MDS_DIR_END_OFF) {
+ last_ent->lde_reclen = 0;
+ break;
+ }
+ } while (1);
+out:
+ if (min_ent_page) {
+ kunmap(min_ent_page);
+ put_page(min_ent_page);
+ }
- kunmap(pages[i]);
+ if (unlikely(rc)) {
+ __free_page(ent_page);
+ ent_page = NULL;
+ } else {
+ if (ent == area)
+ dp->ldp_flags |= LDF_EMPTY;
+ dp->ldp_flags = cpu_to_le32(dp->ldp_flags);
+ dp->ldp_hash_end = cpu_to_le64(hash_offset);
}
- LASSERTF(nlupgs == 0, "left = %d", nlupgs);
+
+ /*
+ * We do not want to allocate md_op_data during each
+ * dir entry reading, so op_data will be shared by every stripe,
+ * then we need to restore it back to original value before
+ * return to the upper layer
+ */
+ op_data->op_fid1 = master_fid;
+ op_data->op_fid2 = master_fid;
+ op_data->op_data = master_inode;
+
+ *ppage = ent_page;
+
+ return rc;
}
-#else
-#define lmv_adjust_dirpages(pages, ncfspgs, nlupgs) do {} while (0)
-#endif /* PAGE_SIZE > LU_PAGE_SIZE */
-static int lmv_readpage(struct obd_export *exp, struct md_op_data *op_data,
- struct page **pages, struct ptlrpc_request **request)
+static int lmv_read_page(struct obd_export *exp, struct md_op_data *op_data,
+ struct md_callback *cb_op, __u64 offset,
+ struct page **ppage)
{
- struct obd_device *obd = exp->exp_obd;
- struct lmv_obd *lmv = &obd->u.lmv;
- __u64 offset = op_data->op_offset;
- int rc;
- int ncfspgs; /* pages read in PAGE_SIZE */
- int nlupgs; /* pages read in LU_PAGE_SIZE */
- struct lmv_tgt_desc *tgt;
+ struct lmv_stripe_md *lsm = op_data->op_mea1;
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+ struct lmv_tgt_desc *tgt;
+ int rc;
rc = lmv_check_connect(obd);
if (rc)
return rc;
- CDEBUG(D_INODE, "READPAGE at %#llx from "DFID"\n",
- offset, PFID(&op_data->op_fid1));
+ if (unlikely(lsm)) {
+ rc = lmv_read_striped_page(exp, op_data, cb_op, offset, ppage);
+ return rc;
+ }
tgt = lmv_find_target(lmv, &op_data->op_fid1);
if (IS_ERR(tgt))
return PTR_ERR(tgt);
- rc = md_readpage(tgt->ltd_exp, op_data, pages, request);
- if (rc != 0)
- return rc;
-
- ncfspgs = ((*request)->rq_bulk->bd_nob_transferred + PAGE_SIZE - 1)
- >> PAGE_SHIFT;
- nlupgs = (*request)->rq_bulk->bd_nob_transferred >> LU_PAGE_SHIFT;
- LASSERT(!((*request)->rq_bulk->bd_nob_transferred & ~LU_PAGE_MASK));
- LASSERT(ncfspgs > 0 && ncfspgs <= op_data->op_npages);
-
- CDEBUG(D_INODE, "read %d(%d)/%d pages\n", ncfspgs, nlupgs,
- op_data->op_npages);
-
- lmv_adjust_dirpages(pages, ncfspgs, nlupgs);
+ rc = md_read_page(tgt->ltd_exp, op_data, cb_op, offset, ppage);
return rc;
}
+/**
+ * Unlink a file/directory
+ *
+ * Unlink a file or directory under the parent dir. The unlink request
+ * usually will be sent to the MDT where the child is located, but if
+ * the client does not have the child FID then request will be sent to the
+ * MDT where the parent is located.
+ *
+ * If the parent is a striped directory then it also needs to locate which
+ * stripe the name of the child is located, and replace the parent FID
+ * (@op->op_fid1) with the stripe FID. Note: if the stripe is unknown,
+ * it will walk through all of sub-stripes until the child is being
+ * unlinked finally.
+ *
+ * \param[in] exp export refer to LMV
+ * \param[in] op_data different parameters transferred beween client
+ * MD stacks, name, namelen, FIDs etc.
+ * op_fid1 is the parent FID, op_fid2 is the child
+ * FID.
+ * \param[out] request point to the request of unlink.
+ *
+ * retval 0 if succeed
+ * negative errno if failed.
+ */
static int lmv_unlink(struct obd_export *exp, struct md_op_data *op_data,
struct ptlrpc_request **request)
{
- struct obd_device *obd = exp->exp_obd;
+ struct lmv_stripe_md *lsm = op_data->op_mea1;
+ struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
+ struct lmv_tgt_desc *parent_tgt = NULL;
struct lmv_tgt_desc *tgt = NULL;
struct mdt_body *body;
+ int stripe_index = 0;
int rc;
rc = lmv_check_connect(obd);
if (rc)
return rc;
-retry:
+retry_unlink:
+ /* For striped dir, we need to locate the parent as well */
+ if (lsm) {
+ struct lmv_tgt_desc *tmp;
+
+ LASSERT(op_data->op_name && op_data->op_namelen);
+
+ tmp = lmv_locate_target_for_name(lmv, lsm,
+ op_data->op_name,
+ op_data->op_namelen,
+ &op_data->op_fid1,
+ &op_data->op_mds);
+
+ /*
+ * return -EBADFD means unknown hash type, might
+ * need try all sub-stripe here
+ */
+ if (IS_ERR(tmp) && PTR_ERR(tmp) != -EBADFD)
+ return PTR_ERR(tmp);
+
+ /*
+ * Note: both migrating dir and unknown hash dir need to
+ * try all of sub-stripes, so we need start search the
+ * name from stripe 0, but migrating dir is already handled
+ * inside lmv_locate_target_for_name(), so we only check
+ * unknown hash type directory here
+ */
+ if (!lmv_is_known_hash_type(lsm->lsm_md_hash_type)) {
+ struct lmv_oinfo *oinfo;
+
+ oinfo = &lsm->lsm_md_oinfo[stripe_index];
+
+ op_data->op_fid1 = oinfo->lmo_fid;
+ op_data->op_mds = oinfo->lmo_mds;
+ }
+ }
+
+try_next_stripe:
/* Send unlink requests to the MDT where the child is located */
if (likely(!fid_is_zero(&op_data->op_fid2)))
- tgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid2);
+ tgt = lmv_find_target(lmv, &op_data->op_fid2);
+ else if (lsm)
+ tgt = lmv_get_target(lmv, op_data->op_mds, NULL);
else
tgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid1);
+
if (IS_ERR(tgt))
return PTR_ERR(tgt);
@@ -2203,29 +2544,57 @@ retry:
/*
* Cancel FULL locks on child (fid3).
*/
- rc = lmv_early_cancel(exp, op_data, tgt->ltd_idx, LCK_EX,
- MDS_INODELOCK_FULL, MF_MDC_CANCEL_FID3);
+ parent_tgt = lmv_find_target(lmv, &op_data->op_fid1);
+ if (IS_ERR(parent_tgt))
+ return PTR_ERR(parent_tgt);
+ if (parent_tgt != tgt) {
+ rc = lmv_early_cancel(exp, parent_tgt, op_data, tgt->ltd_idx,
+ LCK_EX, MDS_INODELOCK_LOOKUP,
+ MF_MDC_CANCEL_FID3);
+ }
+
+ rc = lmv_early_cancel(exp, NULL, op_data, tgt->ltd_idx, LCK_EX,
+ MDS_INODELOCK_FULL, MF_MDC_CANCEL_FID3);
if (rc != 0)
return rc;
- CDEBUG(D_INODE, "unlink with fid="DFID"/"DFID" -> mds #%d\n",
+ CDEBUG(D_INODE, "unlink with fid=" DFID "/" DFID " -> mds #%u\n",
PFID(&op_data->op_fid1), PFID(&op_data->op_fid2), tgt->ltd_idx);
rc = md_unlink(tgt->ltd_exp, op_data, request);
- if (rc != 0 && rc != -EREMOTE)
+ if (rc != 0 && rc != -EREMOTE && rc != -ENOENT)
return rc;
+ /* Try next stripe if it is needed. */
+ if (rc == -ENOENT && lsm && lmv_need_try_all_stripes(lsm)) {
+ struct lmv_oinfo *oinfo;
+
+ stripe_index++;
+ if (stripe_index >= lsm->lsm_md_stripe_count)
+ return rc;
+
+ oinfo = &lsm->lsm_md_oinfo[stripe_index];
+
+ op_data->op_fid1 = oinfo->lmo_fid;
+ op_data->op_mds = oinfo->lmo_mds;
+
+ ptlrpc_req_finished(*request);
+ *request = NULL;
+
+ goto try_next_stripe;
+ }
+
body = req_capsule_server_get(&(*request)->rq_pill, &RMF_MDT_BODY);
if (!body)
return -EPROTO;
/* Not cross-ref case, just get out of here. */
- if (likely(!(body->valid & OBD_MD_MDS)))
- return 0;
+ if (likely(!(body->mbo_valid & OBD_MD_MDS)))
+ return rc;
CDEBUG(D_INODE, "%s: try unlink to another MDT for "DFID"\n",
- exp->exp_obd->obd_name, PFID(&body->fid1));
+ exp->exp_obd->obd_name, PFID(&body->mbo_fid1));
/* This is a remote object, try remote MDT, Note: it may
* try more than 1 time here, Considering following case
@@ -2247,11 +2616,11 @@ retry:
* In theory, it might try unlimited time here, but it should
* be very rare case.
*/
- op_data->op_fid2 = body->fid1;
+ op_data->op_fid2 = body->mbo_fid1;
ptlrpc_req_finished(*request);
*request = NULL;
- goto retry;
+ goto retry_unlink;
}
static int lmv_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
@@ -2274,6 +2643,22 @@ static int lmv_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
return 0;
}
+/**
+ * Get by key a value associated with a LMV device.
+ *
+ * Dispatch request to lower-layer devices as needed.
+ *
+ * \param[in] env execution environment for this thread
+ * \param[in] exp export for the LMV device
+ * \param[in] keylen length of key identifier
+ * \param[in] key identifier of key to get value for
+ * \param[in] vallen size of \a val
+ * \param[out] val pointer to storage location for value
+ * \param[in] lsm optional striping metadata of object
+ *
+ * \retval 0 on success
+ * \retval negative negated errno on failure
+ */
static int lmv_get_info(const struct lu_env *env, struct obd_export *exp,
__u32 keylen, void *key, __u32 *vallen, void *val,
struct lov_stripe_md *lsm)
@@ -2337,6 +2722,22 @@ static int lmv_get_info(const struct lu_env *env, struct obd_export *exp,
return -EINVAL;
}
+/**
+ * Asynchronously set by key a value associated with a LMV device.
+ *
+ * Dispatch request to lower-layer devices as needed.
+ *
+ * \param[in] env execution environment for this thread
+ * \param[in] exp export for the LMV device
+ * \param[in] keylen length of key identifier
+ * \param[in] key identifier of key to store value for
+ * \param[in] vallen size of value to store
+ * \param[in] val pointer to data to be stored
+ * \param[in] set optional list of related ptlrpc requests
+ *
+ * \retval 0 on success
+ * \retval negative negated errno on failure
+ */
static int lmv_set_info_async(const struct lu_env *env, struct obd_export *exp,
u32 keylen, void *key, u32 vallen,
void *val, struct ptlrpc_request_set *set)
@@ -2354,7 +2755,8 @@ static int lmv_set_info_async(const struct lu_env *env, struct obd_export *exp,
}
lmv = &obd->u.lmv;
- if (KEY_IS(KEY_READ_ONLY) || KEY_IS(KEY_FLUSH_CTX)) {
+ if (KEY_IS(KEY_READ_ONLY) || KEY_IS(KEY_FLUSH_CTX) ||
+ KEY_IS(KEY_DEFAULT_EASIZE)) {
int i, err = 0;
for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
@@ -2375,105 +2777,247 @@ static int lmv_set_info_async(const struct lu_env *env, struct obd_export *exp,
return -EINVAL;
}
-static int lmv_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
- struct lov_stripe_md *lsm)
+static int lmv_pack_md_v1(const struct lmv_stripe_md *lsm,
+ struct lmv_mds_md_v1 *lmm1)
{
- struct obd_device *obd = class_exp2obd(exp);
- struct lmv_obd *lmv = &obd->u.lmv;
- struct lmv_stripe_md *meap;
- struct lmv_stripe_md *lsmp;
- int mea_size;
- int i;
+ int cplen;
+ int i;
+
+ lmm1->lmv_magic = cpu_to_le32(lsm->lsm_md_magic);
+ lmm1->lmv_stripe_count = cpu_to_le32(lsm->lsm_md_stripe_count);
+ lmm1->lmv_master_mdt_index = cpu_to_le32(lsm->lsm_md_master_mdt_index);
+ lmm1->lmv_hash_type = cpu_to_le32(lsm->lsm_md_hash_type);
+ cplen = strlcpy(lmm1->lmv_pool_name, lsm->lsm_md_pool_name,
+ sizeof(lmm1->lmv_pool_name));
+ if (cplen >= sizeof(lmm1->lmv_pool_name))
+ return -E2BIG;
+
+ for (i = 0; i < lsm->lsm_md_stripe_count; i++)
+ fid_cpu_to_le(&lmm1->lmv_stripe_fids[i],
+ &lsm->lsm_md_oinfo[i].lmo_fid);
+ return 0;
+}
- mea_size = lmv_get_easize(lmv);
- if (!lmmp)
- return mea_size;
+static int
+lmv_pack_md(union lmv_mds_md **lmmp, const struct lmv_stripe_md *lsm,
+ int stripe_count)
+{
+ int lmm_size = 0, rc = 0;
+ bool allocated = false;
+ LASSERT(lmmp);
+
+ /* Free lmm */
if (*lmmp && !lsm) {
+ int stripe_cnt;
+
+ stripe_cnt = lmv_mds_md_stripe_count_get(*lmmp);
+ lmm_size = lmv_mds_md_size(stripe_cnt,
+ le32_to_cpu((*lmmp)->lmv_magic));
+ if (!lmm_size)
+ return -EINVAL;
kvfree(*lmmp);
*lmmp = NULL;
return 0;
}
+ /* Alloc lmm */
+ if (!*lmmp && !lsm) {
+ lmm_size = lmv_mds_md_size(stripe_count, LMV_MAGIC);
+ LASSERT(lmm_size > 0);
+ *lmmp = libcfs_kvzalloc(lmm_size, GFP_NOFS);
+ if (!*lmmp)
+ return -ENOMEM;
+ lmv_mds_md_stripe_count_set(*lmmp, stripe_count);
+ (*lmmp)->lmv_magic = cpu_to_le32(LMV_MAGIC);
+ return lmm_size;
+ }
+
+ /* pack lmm */
+ LASSERT(lsm);
+ lmm_size = lmv_mds_md_size(lsm->lsm_md_stripe_count,
+ lsm->lsm_md_magic);
if (!*lmmp) {
- *lmmp = libcfs_kvzalloc(mea_size, GFP_NOFS);
+ *lmmp = libcfs_kvzalloc(lmm_size, GFP_NOFS);
if (!*lmmp)
return -ENOMEM;
+ allocated = true;
}
- if (!lsm)
- return mea_size;
+ switch (lsm->lsm_md_magic) {
+ case LMV_MAGIC_V1:
+ rc = lmv_pack_md_v1(lsm, &(*lmmp)->lmv_md_v1);
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+ }
- lsmp = (struct lmv_stripe_md *)lsm;
- meap = (struct lmv_stripe_md *)*lmmp;
+ if (rc && allocated) {
+ kvfree(*lmmp);
+ *lmmp = NULL;
+ }
- if (lsmp->mea_magic != MEA_MAGIC_LAST_CHAR &&
- lsmp->mea_magic != MEA_MAGIC_ALL_CHARS)
- return -EINVAL;
+ return lmm_size;
+}
- meap->mea_magic = cpu_to_le32(lsmp->mea_magic);
- meap->mea_count = cpu_to_le32(lsmp->mea_count);
- meap->mea_master = cpu_to_le32(lsmp->mea_master);
+static int lmv_unpack_md_v1(struct obd_export *exp, struct lmv_stripe_md *lsm,
+ const struct lmv_mds_md_v1 *lmm1)
+{
+ struct lmv_obd *lmv = &exp->exp_obd->u.lmv;
+ int stripe_count;
+ int rc = 0;
+ int cplen;
+ int i;
- for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
- meap->mea_ids[i] = lsmp->mea_ids[i];
- fid_cpu_to_le(&meap->mea_ids[i], &lsmp->mea_ids[i]);
+ lsm->lsm_md_magic = le32_to_cpu(lmm1->lmv_magic);
+ lsm->lsm_md_stripe_count = le32_to_cpu(lmm1->lmv_stripe_count);
+ lsm->lsm_md_master_mdt_index = le32_to_cpu(lmm1->lmv_master_mdt_index);
+ if (OBD_FAIL_CHECK(OBD_FAIL_UNKNOWN_LMV_STRIPE))
+ lsm->lsm_md_hash_type = LMV_HASH_TYPE_UNKNOWN;
+ else
+ lsm->lsm_md_hash_type = le32_to_cpu(lmm1->lmv_hash_type);
+ lsm->lsm_md_layout_version = le32_to_cpu(lmm1->lmv_layout_version);
+ cplen = strlcpy(lsm->lsm_md_pool_name, lmm1->lmv_pool_name,
+ sizeof(lsm->lsm_md_pool_name));
+
+ if (cplen >= sizeof(lsm->lsm_md_pool_name))
+ return -E2BIG;
+
+ CDEBUG(D_INFO, "unpack lsm count %d, master %d hash_type %d layout_version %d\n",
+ lsm->lsm_md_stripe_count, lsm->lsm_md_master_mdt_index,
+ lsm->lsm_md_hash_type, lsm->lsm_md_layout_version);
+
+ stripe_count = le32_to_cpu(lmm1->lmv_stripe_count);
+ for (i = 0; i < stripe_count; i++) {
+ fid_le_to_cpu(&lsm->lsm_md_oinfo[i].lmo_fid,
+ &lmm1->lmv_stripe_fids[i]);
+ rc = lmv_fld_lookup(lmv, &lsm->lsm_md_oinfo[i].lmo_fid,
+ &lsm->lsm_md_oinfo[i].lmo_mds);
+ if (rc)
+ return rc;
+ CDEBUG(D_INFO, "unpack fid #%d "DFID"\n", i,
+ PFID(&lsm->lsm_md_oinfo[i].lmo_fid));
}
- return mea_size;
+ return rc;
}
-static int lmv_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
- struct lov_mds_md *lmm, int lmm_size)
+int lmv_unpack_md(struct obd_export *exp, struct lmv_stripe_md **lsmp,
+ const union lmv_mds_md *lmm, int stripe_count)
{
- struct obd_device *obd = class_exp2obd(exp);
- struct lmv_stripe_md **tmea = (struct lmv_stripe_md **)lsmp;
- struct lmv_stripe_md *mea = (struct lmv_stripe_md *)lmm;
- struct lmv_obd *lmv = &obd->u.lmv;
- int mea_size;
- int i;
- __u32 magic;
+ struct lmv_stripe_md *lsm;
+ bool allocated = false;
+ int lsm_size, rc;
- mea_size = lmv_get_easize(lmv);
- if (!lsmp)
- return mea_size;
+ LASSERT(lsmp);
- if (*lsmp && !lmm) {
- kvfree(*tmea);
+ lsm = *lsmp;
+ /* Free memmd */
+ if (lsm && !lmm) {
+ int i;
+
+ for (i = 1; i < lsm->lsm_md_stripe_count; i++) {
+ /*
+ * For migrating inode, the master stripe and master
+ * object will be the same, so do not need iput, see
+ * ll_update_lsm_md
+ */
+ if (!(lsm->lsm_md_hash_type & LMV_HASH_FLAG_MIGRATION &&
+ !i) && lsm->lsm_md_oinfo[i].lmo_root)
+ iput(lsm->lsm_md_oinfo[i].lmo_root);
+ }
+
+ kvfree(lsm);
*lsmp = NULL;
return 0;
}
- LASSERT(mea_size == lmm_size);
+ /* Alloc memmd */
+ if (!lsm && !lmm) {
+ lsm_size = lmv_stripe_md_size(stripe_count);
+ lsm = libcfs_kvzalloc(lsm_size, GFP_NOFS);
+ if (!lsm)
+ return -ENOMEM;
+ lsm->lsm_md_stripe_count = stripe_count;
+ *lsmp = lsm;
+ return 0;
+ }
- *tmea = libcfs_kvzalloc(mea_size, GFP_NOFS);
- if (!*tmea)
- return -ENOMEM;
+ if (le32_to_cpu(lmm->lmv_magic) == LMV_MAGIC_STRIPE)
+ return -EPERM;
- if (!lmm)
- return mea_size;
+ /* Unpack memmd */
+ if (le32_to_cpu(lmm->lmv_magic) != LMV_MAGIC_V1 &&
+ le32_to_cpu(lmm->lmv_magic) != LMV_USER_MAGIC) {
+ CERROR("%s: invalid lmv magic %x: rc = %d\n",
+ exp->exp_obd->obd_name, le32_to_cpu(lmm->lmv_magic),
+ -EIO);
+ return -EIO;
+ }
- if (mea->mea_magic == MEA_MAGIC_LAST_CHAR ||
- mea->mea_magic == MEA_MAGIC_ALL_CHARS ||
- mea->mea_magic == MEA_MAGIC_HASH_SEGMENT) {
- magic = le32_to_cpu(mea->mea_magic);
- } else {
- /*
- * Old mea is not handled here.
+ if (le32_to_cpu(lmm->lmv_magic) == LMV_MAGIC_V1)
+ lsm_size = lmv_stripe_md_size(lmv_mds_md_stripe_count_get(lmm));
+ else
+ /**
+ * Unpack default dirstripe(lmv_user_md) to lmv_stripe_md,
+ * stripecount should be 0 then.
*/
- CERROR("Old not supportable EA is found\n");
- LBUG();
+ lsm_size = lmv_stripe_md_size(0);
+
+ if (!lsm) {
+ lsm = libcfs_kvzalloc(lsm_size, GFP_NOFS);
+ if (!lsm)
+ return -ENOMEM;
+ allocated = true;
+ *lsmp = lsm;
+ }
+
+ switch (le32_to_cpu(lmm->lmv_magic)) {
+ case LMV_MAGIC_V1:
+ rc = lmv_unpack_md_v1(exp, lsm, &lmm->lmv_md_v1);
+ break;
+ default:
+ CERROR("%s: unrecognized magic %x\n", exp->exp_obd->obd_name,
+ le32_to_cpu(lmm->lmv_magic));
+ rc = -EINVAL;
+ break;
}
- (*tmea)->mea_magic = magic;
- (*tmea)->mea_count = le32_to_cpu(mea->mea_count);
- (*tmea)->mea_master = le32_to_cpu(mea->mea_master);
+ if (rc && allocated) {
+ kvfree(lsm);
+ *lsmp = NULL;
+ lsm_size = rc;
+ }
+ return lsm_size;
+}
+EXPORT_SYMBOL(lmv_unpack_md);
+
+static int lmv_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
+ struct lov_mds_md *lmm, int disk_len)
+{
+ return lmv_unpack_md(exp, (struct lmv_stripe_md **)lsmp,
+ (union lmv_mds_md *)lmm, disk_len);
+}
+
+static int lmv_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
+ struct lov_stripe_md *lsm)
+{
+ const struct lmv_stripe_md *lmv = (struct lmv_stripe_md *)lsm;
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv_obd = &obd->u.lmv;
+ int stripe_count;
- for (i = 0; i < (*tmea)->mea_count; i++) {
- (*tmea)->mea_ids[i] = mea->mea_ids[i];
- fid_le_to_cpu(&(*tmea)->mea_ids[i], &(*tmea)->mea_ids[i]);
+ if (!lmmp) {
+ if (lsm)
+ stripe_count = lmv->lsm_md_stripe_count;
+ else
+ stripe_count = lmv_obd->desc.ld_tgt_count;
+
+ return lmv_mds_md_size(stripe_count, LMV_MAGIC_V1);
}
- return mea_size;
+
+ return lmv_pack_md((union lmv_mds_md **)lmmp, lmv, 0);
}
static int lmv_cancel_unused(struct obd_export *exp, const struct lu_fid *fid,
@@ -2484,7 +3028,7 @@ static int lmv_cancel_unused(struct obd_export *exp, const struct lu_fid *fid,
struct lmv_obd *lmv = &obd->u.lmv;
int rc = 0;
int err;
- int i;
+ u32 i;
LASSERT(fid);
@@ -2502,8 +3046,9 @@ static int lmv_cancel_unused(struct obd_export *exp, const struct lu_fid *fid,
return rc;
}
-static int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data,
- __u64 *bits)
+static int lmv_set_lock_data(struct obd_export *exp,
+ const struct lustre_handle *lockh,
+ void *data, __u64 *bits)
{
struct lmv_obd *lmv = &exp->exp_obd->u.lmv;
struct lmv_tgt_desc *tgt = lmv->tgts[0];
@@ -2526,24 +3071,32 @@ static enum ldlm_mode lmv_lock_match(struct obd_export *exp, __u64 flags,
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
enum ldlm_mode rc;
- int i;
+ int tgt;
+ u32 i;
CDEBUG(D_INODE, "Lock match for "DFID"\n", PFID(fid));
/*
- * With CMD every object can have two locks in different namespaces:
- * lookup lock in space of mds storing direntry and update/open lock in
- * space of mds storing inode. Thus we check all targets, not only that
- * one fid was created in.
+ * With DNE every object can have two locks in different namespaces:
+ * lookup lock in space of MDT storing direntry and update/open lock in
+ * space of MDT storing inode. Try the MDT that the FID maps to first,
+ * since this can be easily found, and only try others if that fails.
*/
- for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
- struct lmv_tgt_desc *tgt = lmv->tgts[i];
+ for (i = 0, tgt = lmv_find_target_index(lmv, fid);
+ i < lmv->desc.ld_tgt_count;
+ i++, tgt = (tgt + 1) % lmv->desc.ld_tgt_count) {
+ if (tgt < 0) {
+ CDEBUG(D_HA, "%s: "DFID" is inaccessible: rc = %d\n",
+ obd->obd_name, PFID(fid), tgt);
+ tgt = 0;
+ }
- if (!tgt || !tgt->ltd_exp || !tgt->ltd_active)
+ if (!lmv->tgts[tgt] || !lmv->tgts[tgt]->ltd_exp ||
+ !lmv->tgts[tgt]->ltd_active)
continue;
- rc = md_lock_match(tgt->ltd_exp, flags, fid, type, policy, mode,
- lockh);
+ rc = md_lock_match(lmv->tgts[tgt]->ltd_exp, flags, fid,
+ type, policy, mode, lockh);
if (rc)
return rc;
}
@@ -2571,8 +3124,10 @@ static int lmv_free_lustre_md(struct obd_export *exp, struct lustre_md *md)
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt = lmv->tgts[0];
- if (md->mea)
- obd_free_memmd(exp, (void *)&md->mea);
+ if (md->lmv) {
+ lmv_free_memmd(md->lmv);
+ md->lmv = NULL;
+ }
if (!tgt || !tgt->ltd_exp)
return -EINVAL;
return md_free_lustre_md(tgt->ltd_exp, md);
@@ -2621,7 +3176,7 @@ static int lmv_intent_getattr_async(struct obd_export *exp,
if (rc)
return rc;
- tgt = lmv_find_target(lmv, &op_data->op_fid1);
+ tgt = lmv_locate_mds(lmv, op_data, &op_data->op_fid1);
if (IS_ERR(tgt))
return PTR_ERR(tgt);
@@ -2649,6 +3204,23 @@ static int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
return rc;
}
+static int
+lmv_get_fid_from_lsm(struct obd_export *exp,
+ const struct lmv_stripe_md *lsm,
+ const char *name, int namelen, struct lu_fid *fid)
+{
+ const struct lmv_oinfo *oinfo;
+
+ LASSERT(lsm);
+ oinfo = lsm_name_to_stripe_info(lsm, name, namelen);
+ if (IS_ERR(oinfo))
+ return PTR_ERR(oinfo);
+
+ *fid = oinfo->lmo_fid;
+
+ return 0;
+}
+
/**
* For lmv, only need to send request to master MDT, and the master MDT will
* process with other slave MDTs. The only exception is Q_GETOQUOTA for which
@@ -2660,8 +3232,9 @@ static int lmv_quotactl(struct obd_device *unused, struct obd_export *exp,
struct obd_device *obd = class_exp2obd(exp);
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt = lmv->tgts[0];
- int rc = 0, i;
+ int rc = 0;
__u64 curspace = 0, curinodes = 0;
+ u32 i;
if (!tgt || !tgt->ltd_exp || !tgt->ltd_active ||
!lmv->desc.ld_tgt_count) {
@@ -2704,7 +3277,8 @@ static int lmv_quotacheck(struct obd_device *unused, struct obd_export *exp,
struct obd_device *obd = class_exp2obd(exp);
struct lmv_obd *lmv = &obd->u.lmv;
struct lmv_tgt_desc *tgt;
- int i, rc = 0;
+ int rc = 0;
+ u32 i;
for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
int err;
@@ -2723,6 +3297,47 @@ static int lmv_quotacheck(struct obd_device *unused, struct obd_export *exp,
return rc;
}
+static int lmv_merge_attr(struct obd_export *exp,
+ const struct lmv_stripe_md *lsm,
+ struct cl_attr *attr,
+ ldlm_blocking_callback cb_blocking)
+{
+ int rc, i;
+
+ rc = lmv_revalidate_slaves(exp, lsm, cb_blocking, 0);
+ if (rc < 0)
+ return rc;
+
+ for (i = 0; i < lsm->lsm_md_stripe_count; i++) {
+ struct inode *inode = lsm->lsm_md_oinfo[i].lmo_root;
+
+ CDEBUG(D_INFO, ""DFID" size %llu, blocks %llu nlink %u, atime %lu ctime %lu, mtime %lu.\n",
+ PFID(&lsm->lsm_md_oinfo[i].lmo_fid),
+ i_size_read(inode), (unsigned long long)inode->i_blocks,
+ inode->i_nlink, LTIME_S(inode->i_atime),
+ LTIME_S(inode->i_ctime), LTIME_S(inode->i_mtime));
+
+ /* for slave stripe, it needs to subtract nlink for . and .. */
+ if (i)
+ attr->cat_nlink += inode->i_nlink - 2;
+ else
+ attr->cat_nlink = inode->i_nlink;
+
+ attr->cat_size += i_size_read(inode);
+ attr->cat_blocks += inode->i_blocks;
+
+ if (attr->cat_atime < LTIME_S(inode->i_atime))
+ attr->cat_atime = LTIME_S(inode->i_atime);
+
+ if (attr->cat_ctime < LTIME_S(inode->i_ctime))
+ attr->cat_ctime = LTIME_S(inode->i_ctime);
+
+ if (attr->cat_mtime < LTIME_S(inode->i_mtime))
+ attr->cat_mtime = LTIME_S(inode->i_mtime);
+ }
+ return 0;
+}
+
static struct obd_ops lmv_obd_ops = {
.owner = THIS_MODULE,
.setup = lmv_setup,
@@ -2746,7 +3361,6 @@ static struct obd_ops lmv_obd_ops = {
static struct md_ops lmv_md_ops = {
.getstatus = lmv_getstatus,
.null_inode = lmv_null_inode,
- .find_cbdata = lmv_find_cbdata,
.close = lmv_close,
.create = lmv_create,
.done_writing = lmv_done_writing,
@@ -2760,7 +3374,7 @@ static struct md_ops lmv_md_ops = {
.setattr = lmv_setattr,
.setxattr = lmv_setxattr,
.sync = lmv_sync,
- .readpage = lmv_readpage,
+ .read_page = lmv_read_page,
.unlink = lmv_unlink,
.init_ea_size = lmv_init_ea_size,
.cancel_unused = lmv_cancel_unused,
@@ -2768,10 +3382,12 @@ static struct md_ops lmv_md_ops = {
.lock_match = lmv_lock_match,
.get_lustre_md = lmv_get_lustre_md,
.free_lustre_md = lmv_free_lustre_md,
+ .merge_attr = lmv_merge_attr,
.set_open_replay_data = lmv_set_open_replay_data,
.clear_open_replay_data = lmv_clear_open_replay_data,
.intent_getattr_async = lmv_intent_getattr_async,
- .revalidate_lock = lmv_revalidate_lock
+ .revalidate_lock = lmv_revalidate_lock,
+ .get_fid_from_lsm = lmv_get_fid_from_lsm,
};
static int __init lmv_init(void)
diff --git a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
index c29c361eb0cc..20bbdfc21d15 100644
--- a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
+++ b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
@@ -169,7 +169,7 @@ static int lmv_tgt_seq_show(struct seq_file *p, void *v)
if (!tgt)
return 0;
- seq_printf(p, "%d: %s %sACTIVE\n",
+ seq_printf(p, "%u: %s %sACTIVE\n",
tgt->ltd_idx, tgt->ltd_uuid.uuid,
tgt->ltd_active ? "" : "IN");
return 0;
@@ -202,7 +202,7 @@ static struct lprocfs_vars lprocfs_lmv_obd_vars[] = {
{ NULL }
};
-struct file_operations lmv_proc_target_fops = {
+const struct file_operations lmv_proc_target_fops = {
.owner = THIS_MODULE,
.open = lmv_target_seq_open,
.read = seq_read,
diff --git a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h
index 9740568d9521..4d2b7d303fea 100644
--- a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h
+++ b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h
@@ -289,8 +289,8 @@ struct lov_lock {
};
struct lov_page {
- struct cl_page_slice lps_cl;
- int lps_invalid;
+ struct cl_page_slice lps_cl;
+ unsigned int lps_stripe; /* stripe index */
};
/*
@@ -556,6 +556,8 @@ struct lov_lock_link *lov_lock_link_find(const struct lu_env *env,
struct lovsub_lock *sub);
struct lov_io_sub *lov_page_subio(const struct lu_env *env, struct lov_io *lio,
const struct cl_page_slice *slice);
+
+struct lov_stripe_md *lov_lsm_addref(struct lov_object *lov);
int lov_page_stripe(const struct cl_page *page);
#define lov_foreach_target(lov, var) \
@@ -742,11 +744,15 @@ static inline struct lov_thread_info *lov_env_info(const struct lu_env *env)
static inline struct lov_layout_raid0 *lov_r0(struct lov_object *lov)
{
LASSERT(lov->lo_type == LLT_RAID0);
- LASSERT(lov->lo_lsm->lsm_wire.lw_magic == LOV_MAGIC ||
- lov->lo_lsm->lsm_wire.lw_magic == LOV_MAGIC_V3);
+ LASSERT(lov->lo_lsm->lsm_magic == LOV_MAGIC ||
+ lov->lo_lsm->lsm_magic == LOV_MAGIC_V3);
return &lov->u.raid0;
}
+/* lov_pack.c */
+int lov_getstripe(struct lov_object *obj, struct lov_stripe_md *lsm,
+ struct lov_user_md __user *lump);
+
/** @} lov */
#endif
diff --git a/drivers/staging/lustre/lustre/lov/lov_dev.c b/drivers/staging/lustre/lustre/lov/lov_dev.c
index b1f260d43bc7..056ae2ed88e8 100644
--- a/drivers/staging/lustre/lustre/lov/lov_dev.c
+++ b/drivers/staging/lustre/lustre/lov/lov_dev.c
@@ -516,6 +516,5 @@ struct lu_device_type lov_device_type = {
.ldt_ops = &lov_device_type_ops,
.ldt_ctx_tags = LCT_CL_THREAD
};
-EXPORT_SYMBOL(lov_device_type);
/** @} lov */
diff --git a/drivers/staging/lustre/lustre/lov/lov_ea.c b/drivers/staging/lustre/lustre/lov/lov_ea.c
index 5053dead17bb..214c561767e0 100644
--- a/drivers/staging/lustre/lustre/lov/lov_ea.c
+++ b/drivers/staging/lustre/lustre/lov/lov_ea.c
@@ -66,7 +66,8 @@ static int lsm_lmm_verify_common(struct lov_mds_md *lmm, int lmm_bytes,
}
if (lmm->lmm_stripe_size == 0 ||
- (le32_to_cpu(lmm->lmm_stripe_size)&(LOV_MIN_STRIPE_SIZE-1)) != 0) {
+ (le32_to_cpu(lmm->lmm_stripe_size) &
+ (LOV_MIN_STRIPE_SIZE - 1)) != 0) {
CERROR("bad stripe size %u\n",
le32_to_cpu(lmm->lmm_stripe_size));
lov_dump_lmm_common(D_WARNING, lmm);
@@ -146,21 +147,15 @@ lsm_stripe_by_offset_plain(struct lov_stripe_md *lsm, int *stripeno,
*swidth = (u64)lsm->lsm_stripe_size * lsm->lsm_stripe_count;
}
-static int lsm_destroy_plain(struct lov_stripe_md *lsm, struct obdo *oa,
- struct obd_export *md_exp)
-{
- return 0;
-}
-
/* Find minimum stripe maxbytes value. For inactive or
- * reconnecting targets use LUSTRE_STRIPE_MAXBYTES.
+ * reconnecting targets use LUSTRE_EXT3_STRIPE_MAXBYTES.
*/
static void lov_tgt_maxbytes(struct lov_tgt_desc *tgt, __u64 *stripe_maxbytes)
{
struct obd_import *imp = tgt->ltd_obd->u.cli.cl_import;
if (!imp || !tgt->ltd_active) {
- *stripe_maxbytes = LUSTRE_STRIPE_MAXBYTES;
+ *stripe_maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES;
return;
}
@@ -171,7 +166,7 @@ static void lov_tgt_maxbytes(struct lov_tgt_desc *tgt, __u64 *stripe_maxbytes)
if (*stripe_maxbytes > imp->imp_connect_data.ocd_maxbytes)
*stripe_maxbytes = imp->imp_connect_data.ocd_maxbytes;
} else {
- *stripe_maxbytes = LUSTRE_STRIPE_MAXBYTES;
+ *stripe_maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES;
}
spin_unlock(&imp->imp_lock);
}
@@ -245,7 +240,6 @@ static int lsm_unpackmd_v1(struct lov_obd *lov, struct lov_stripe_md *lsm,
const struct lsm_operations lsm_v1_ops = {
.lsm_free = lsm_free_plain,
- .lsm_destroy = lsm_destroy_plain,
.lsm_stripe_by_index = lsm_stripe_by_index_plain,
.lsm_stripe_by_offset = lsm_stripe_by_offset_plain,
.lsm_lmm_verify = lsm_lmm_verify_v1,
@@ -335,7 +329,6 @@ static int lsm_unpackmd_v3(struct lov_obd *lov, struct lov_stripe_md *lsm,
const struct lsm_operations lsm_v3_ops = {
.lsm_free = lsm_free_plain,
- .lsm_destroy = lsm_destroy_plain,
.lsm_stripe_by_index = lsm_stripe_by_index_plain,
.lsm_stripe_by_offset = lsm_stripe_by_offset_plain,
.lsm_lmm_verify = lsm_lmm_verify_v3,
diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h b/drivers/staging/lustre/lustre/lov/lov_internal.h
index 12bd511e8988..07e5ede3e952 100644
--- a/drivers/staging/lustre/lustre/lov/lov_internal.h
+++ b/drivers/staging/lustre/lustre/lov/lov_internal.h
@@ -134,8 +134,6 @@ static inline void lov_put_reqset(struct lov_request_set *set)
/* lov_merge.c */
void lov_merge_attrs(struct obdo *tgt, struct obdo *src, u64 valid,
struct lov_stripe_md *lsm, int stripeno, int *set);
-int lov_adjust_kms(struct obd_export *exp, struct lov_stripe_md *lsm,
- u64 size, int shrink);
int lov_merge_lvb_kms(struct lov_stripe_md *lsm,
struct ost_lvb *lvb, __u64 *kms_place);
@@ -157,11 +155,6 @@ int lov_update_common_set(struct lov_request_set *set,
int lov_prep_getattr_set(struct obd_export *exp, struct obd_info *oinfo,
struct lov_request_set **reqset);
int lov_fini_getattr_set(struct lov_request_set *set);
-int lov_prep_destroy_set(struct obd_export *exp, struct obd_info *oinfo,
- struct obdo *src_oa, struct lov_stripe_md *lsm,
- struct obd_trans_info *oti,
- struct lov_request_set **reqset);
-int lov_fini_destroy_set(struct lov_request_set *set);
int lov_prep_setattr_set(struct obd_export *exp, struct obd_info *oinfo,
struct obd_trans_info *oti,
struct lov_request_set **reqset);
@@ -197,8 +190,6 @@ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmm,
struct lov_stripe_md *lsm);
int lov_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
struct lov_mds_md *lmm, int lmm_bytes);
-int lov_getstripe(struct obd_export *exp,
- struct lov_stripe_md *lsm, struct lov_user_md __user *lump);
int lov_alloc_memmd(struct lov_stripe_md **lsmp, __u16 stripe_count,
int pattern, int magic);
int lov_free_memmd(struct lov_stripe_md **lsmp);
diff --git a/drivers/staging/lustre/lustre/lov/lov_io.c b/drivers/staging/lustre/lustre/lov/lov_io.c
index 84032a510254..d10157985ed9 100644
--- a/drivers/staging/lustre/lustre/lov/lov_io.c
+++ b/drivers/staging/lustre/lustre/lov/lov_io.c
@@ -87,6 +87,9 @@ static void lov_io_sub_inherit(struct cl_io *io, struct lov_io *lio,
case CIT_SETATTR: {
io->u.ci_setattr.sa_attr = parent->u.ci_setattr.sa_attr;
io->u.ci_setattr.sa_valid = parent->u.ci_setattr.sa_valid;
+ io->u.ci_setattr.sa_stripe_index = stripe;
+ io->u.ci_setattr.sa_parent_fid =
+ parent->u.ci_setattr.sa_parent_fid;
if (cl_io_is_trunc(io)) {
loff_t new_size = parent->u.ci_setattr.sa_attr.lvb_size;
@@ -244,14 +247,12 @@ void lov_sub_put(struct lov_io_sub *sub)
int lov_page_stripe(const struct cl_page *page)
{
- struct lovsub_object *subobj;
const struct cl_page_slice *slice;
- slice = cl_page_at(page, &lovsub_device_type);
+ slice = cl_page_at(page, &lov_device_type);
LASSERT(slice->cpl_obj);
- subobj = cl2lovsub(slice->cpl_obj);
- return subobj->lso_index;
+ return cl2lov_page(slice)->lps_stripe;
}
struct lov_io_sub *lov_page_subio(const struct lu_env *env, struct lov_io *lio,
@@ -298,8 +299,8 @@ static int lov_io_subio_init(const struct lu_env *env, struct lov_io *lio,
return result;
}
-static void lov_io_slice_init(struct lov_io *lio,
- struct lov_object *obj, struct cl_io *io)
+static int lov_io_slice_init(struct lov_io *lio, struct lov_object *obj,
+ struct cl_io *io)
{
io->ci_result = 0;
lio->lis_object = obj;
@@ -314,6 +315,15 @@ static void lov_io_slice_init(struct lov_io *lio,
lio->lis_io_endpos = lio->lis_endpos;
if (cl_io_is_append(io)) {
LASSERT(io->ci_type == CIT_WRITE);
+
+ /*
+ * If there is LOV EA hole, then we may cannot locate
+ * the current file-tail exactly.
+ */
+ if (unlikely(obj->lo_lsm->lsm_pattern &
+ LOV_PATTERN_F_HOLE))
+ return -EIO;
+
lio->lis_pos = 0;
lio->lis_endpos = OBD_OBJECT_EOF;
}
@@ -349,6 +359,7 @@ static void lov_io_slice_init(struct lov_io *lio,
default:
LBUG();
}
+ return 0;
}
static void lov_io_fini(const struct lu_env *env, const struct cl_io_slice *ios)
@@ -870,7 +881,7 @@ int lov_io_init_raid0(const struct lu_env *env, struct cl_object *obj,
struct lov_object *lov = cl2lov(obj);
INIT_LIST_HEAD(&lio->lis_active);
- lov_io_slice_init(lio, lov, io);
+ io->ci_result = lov_io_slice_init(lio, lov, io);
if (io->ci_result == 0) {
io->ci_result = lov_io_subio_init(env, lio, io);
if (io->ci_result == 0) {
diff --git a/drivers/staging/lustre/lustre/lov/lov_merge.c b/drivers/staging/lustre/lustre/lov/lov_merge.c
index b9c90865fdfc..674af106b50b 100644
--- a/drivers/staging/lustre/lustre/lov/lov_merge.c
+++ b/drivers/staging/lustre/lustre/lov/lov_merge.c
@@ -105,45 +105,6 @@ int lov_merge_lvb_kms(struct lov_stripe_md *lsm,
return rc;
}
-/* Must be called under the lov_stripe_lock() */
-int lov_adjust_kms(struct obd_export *exp, struct lov_stripe_md *lsm,
- u64 size, int shrink)
-{
- struct lov_oinfo *loi;
- int stripe = 0;
- __u64 kms;
-
- assert_spin_locked(&lsm->lsm_lock);
- LASSERT(lsm->lsm_lock_owner == current_pid());
-
- if (shrink) {
- for (; stripe < lsm->lsm_stripe_count; stripe++) {
- struct lov_oinfo *loi = lsm->lsm_oinfo[stripe];
-
- kms = lov_size_to_stripe(lsm, size, stripe);
- CDEBUG(D_INODE,
- "stripe %d KMS %sing %llu->%llu\n",
- stripe, kms > loi->loi_kms ? "increase":"shrink",
- loi->loi_kms, kms);
- loi->loi_lvb.lvb_size = kms;
- loi_kms_set(loi, loi->loi_lvb.lvb_size);
- }
- return 0;
- }
-
- if (size > 0)
- stripe = lov_stripe_number(lsm, size - 1);
- kms = lov_size_to_stripe(lsm, size, stripe);
- loi = lsm->lsm_oinfo[stripe];
-
- CDEBUG(D_INODE, "stripe %d KMS %sincreasing %llu->%llu\n",
- stripe, kms > loi->loi_kms ? "" : "not ", loi->loi_kms, kms);
- if (kms > loi->loi_kms)
- loi_kms_set(loi, kms);
-
- return 0;
-}
-
void lov_merge_attrs(struct obdo *tgt, struct obdo *src, u64 valid,
struct lov_stripe_md *lsm, int stripeno, int *set)
{
diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c
index 9b92d5522edb..b23016f7ec26 100644
--- a/drivers/staging/lustre/lustre/lov/lov_obd.c
+++ b/drivers/staging/lustre/lustre/lov/lov_obd.c
@@ -41,6 +41,7 @@
#include "../../include/linux/libcfs/libcfs.h"
#include "../include/obd_support.h"
+#include "../include/lustre/lustre_ioctl.h"
#include "../include/lustre_lib.h"
#include "../include/lustre_net.h"
#include "../include/lustre/lustre_idl.h"
@@ -940,7 +941,7 @@ int lov_process_config_base(struct obd_device *obd, struct lustre_cfg *lcfg,
}
case LCFG_PARAM: {
struct lprocfs_static_vars lvars = { NULL };
- struct lov_desc *desc = &(obd->u.lov.desc);
+ struct lov_desc *desc = &obd->u.lov.desc;
if (!desc) {
rc = -EINVAL;
@@ -971,92 +972,6 @@ out:
return rc;
}
-static int lov_recreate(struct obd_export *exp, struct obdo *src_oa,
- struct lov_stripe_md **ea, struct obd_trans_info *oti)
-{
- struct lov_stripe_md *obj_mdp, *lsm;
- struct lov_obd *lov = &exp->exp_obd->u.lov;
- unsigned ost_idx;
- int rc, i;
-
- LASSERT(src_oa->o_valid & OBD_MD_FLFLAGS &&
- src_oa->o_flags & OBD_FL_RECREATE_OBJS);
-
- obj_mdp = kzalloc(sizeof(*obj_mdp), GFP_NOFS);
- if (!obj_mdp)
- return -ENOMEM;
-
- ost_idx = src_oa->o_nlink;
- lsm = *ea;
- if (!lsm) {
- rc = -EINVAL;
- goto out;
- }
- if (ost_idx >= lov->desc.ld_tgt_count ||
- !lov->lov_tgts[ost_idx]) {
- rc = -EINVAL;
- goto out;
- }
-
- for (i = 0; i < lsm->lsm_stripe_count; i++) {
- struct lov_oinfo *loi = lsm->lsm_oinfo[i];
-
- if (lov_oinfo_is_dummy(loi))
- continue;
-
- if (loi->loi_ost_idx == ost_idx) {
- if (ostid_id(&loi->loi_oi) != ostid_id(&src_oa->o_oi)) {
- rc = -EINVAL;
- goto out;
- }
- break;
- }
- }
- if (i == lsm->lsm_stripe_count) {
- rc = -EINVAL;
- goto out;
- }
-
- rc = obd_create(NULL, lov->lov_tgts[ost_idx]->ltd_exp,
- src_oa, &obj_mdp, oti);
-out:
- kfree(obj_mdp);
- return rc;
-}
-
-/* the LOV expects oa->o_id to be set to the LOV object id */
-static int lov_create(const struct lu_env *env, struct obd_export *exp,
- struct obdo *src_oa, struct lov_stripe_md **ea,
- struct obd_trans_info *oti)
-{
- struct lov_obd *lov;
- int rc = 0;
-
- LASSERT(ea);
- if (!exp)
- return -EINVAL;
-
- if ((src_oa->o_valid & OBD_MD_FLFLAGS) &&
- src_oa->o_flags == OBD_FL_DELORPHAN) {
- /* should be used with LOV anymore */
- LBUG();
- }
-
- lov = &exp->exp_obd->u.lov;
- if (!lov->desc.ld_active_tgt_count)
- return -EIO;
-
- obd_getref(exp->exp_obd);
- /* Recreate a specific object id at the given OST index */
- if ((src_oa->o_valid & OBD_MD_FLFLAGS) &&
- (src_oa->o_flags & OBD_FL_RECREATE_OBJS)) {
- rc = lov_recreate(exp, src_oa, ea, oti);
- }
-
- obd_putref(exp->exp_obd);
- return rc;
-}
-
#define ASSERT_LSM_MAGIC(lsmp) \
do { \
LASSERT((lsmp)); \
@@ -1065,59 +980,6 @@ do { \
"%p->lsm_magic=%x\n", (lsmp), (lsmp)->lsm_magic); \
} while (0)
-static int lov_destroy(const struct lu_env *env, struct obd_export *exp,
- struct obdo *oa, struct lov_stripe_md *lsm,
- struct obd_trans_info *oti, struct obd_export *md_exp)
-{
- struct lov_request_set *set;
- struct obd_info oinfo;
- struct lov_request *req;
- struct lov_obd *lov;
- int rc = 0, err = 0;
-
- ASSERT_LSM_MAGIC(lsm);
-
- if (!exp || !exp->exp_obd)
- return -ENODEV;
-
- if (oa->o_valid & OBD_MD_FLCOOKIE) {
- LASSERT(oti);
- LASSERT(oti->oti_logcookies);
- }
-
- lov = &exp->exp_obd->u.lov;
- obd_getref(exp->exp_obd);
- rc = lov_prep_destroy_set(exp, &oinfo, oa, lsm, oti, &set);
- if (rc)
- goto out;
-
- list_for_each_entry(req, &set->set_list, rq_link) {
- if (oa->o_valid & OBD_MD_FLCOOKIE)
- oti->oti_logcookies = set->set_cookies + req->rq_stripe;
-
- err = obd_destroy(env, lov->lov_tgts[req->rq_idx]->ltd_exp,
- req->rq_oi.oi_oa, NULL, oti, NULL);
- err = lov_update_common_set(set, req, err);
- if (err) {
- CERROR("%s: destroying objid "DOSTID" subobj "
- DOSTID" on OST idx %d: rc = %d\n",
- exp->exp_obd->obd_name, POSTID(&oa->o_oi),
- POSTID(&req->rq_oi.oi_oa->o_oi),
- req->rq_idx, err);
- if (!rc)
- rc = err;
- }
- }
-
- if (rc == 0)
- rc = lsm_op_find(lsm->lsm_magic)->lsm_destroy(lsm, oa, md_exp);
-
- err = lov_fini_destroy_set(set);
-out:
- obd_putref(exp->exp_obd);
- return rc ? rc : err;
-}
-
static int lov_getattr_interpret(struct ptlrpc_request_set *rqset,
void *data, int rc)
{
@@ -1267,46 +1129,6 @@ static int lov_setattr_async(struct obd_export *exp, struct obd_info *oinfo,
return 0;
}
-/* find any ldlm lock of the inode in lov
- * return 0 not find
- * 1 find one
- * < 0 error
- */
-static int lov_find_cbdata(struct obd_export *exp,
- struct lov_stripe_md *lsm, ldlm_iterator_t it,
- void *data)
-{
- struct lov_obd *lov;
- int rc = 0, i;
-
- ASSERT_LSM_MAGIC(lsm);
-
- if (!exp || !exp->exp_obd)
- return -ENODEV;
-
- lov = &exp->exp_obd->u.lov;
- for (i = 0; i < lsm->lsm_stripe_count; i++) {
- struct lov_stripe_md submd;
- struct lov_oinfo *loi = lsm->lsm_oinfo[i];
-
- if (lov_oinfo_is_dummy(loi))
- continue;
-
- if (!lov->lov_tgts[loi->loi_ost_idx]) {
- CDEBUG(D_HA, "lov idx %d NULL\n", loi->loi_ost_idx);
- continue;
- }
-
- submd.lsm_oi = loi->loi_oi;
- submd.lsm_stripe_count = 0;
- rc = obd_find_cbdata(lov->lov_tgts[loi->loi_ost_idx]->ltd_exp,
- &submd, it, data);
- if (rc != 0)
- return rc;
- }
- return rc;
-}
-
int lov_statfs_interpret(struct ptlrpc_request_set *rqset, void *data, int rc)
{
struct lov_request_set *lovset = (struct lov_request_set *)data;
@@ -1460,7 +1282,7 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
}
desc = (struct lov_desc *)data->ioc_inlbuf1;
- memcpy(desc, &(lov->desc), sizeof(*desc));
+ memcpy(desc, &lov->desc, sizeof(*desc));
uuidp = (struct obd_uuid *)data->ioc_inlbuf2;
genp = (__u32 *)data->ioc_inlbuf3;
@@ -1477,9 +1299,6 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
obd_ioctl_freedata(buf, len);
break;
}
- case LL_IOC_LOV_GETSTRIPE:
- rc = lov_getstripe(exp, karg, uarg);
- break;
case OBD_IOC_QUOTACTL: {
struct if_quotactl *qctl = karg;
struct lov_tgt_desc *tgt = NULL;
@@ -1726,6 +1545,8 @@ static int lov_fiemap(struct lov_obd *lov, __u32 keylen, void *key,
u64 fm_start, fm_end, fm_length, fm_end_offset;
u64 curr_loc;
int current_extent = 0, rc = 0, i;
+ /* Whether have we collected enough extents */
+ bool enough = false;
int ost_eof = 0; /* EOF for object */
int ost_done = 0; /* done with required mapping for this OST? */
int last_stripe;
@@ -1860,7 +1681,7 @@ static int lov_fiemap(struct lov_obd *lov, __u32 keylen, void *key,
lun_start += len_mapped_single_call;
fm_local->fm_length = req_fm_len - len_mapped_single_call;
req_fm_len = fm_local->fm_length;
- fm_local->fm_extent_count = count_local;
+ fm_local->fm_extent_count = enough ? 1 : count_local;
fm_local->fm_mapped_extents = 0;
fm_local->fm_flags = fiemap->fm_flags;
@@ -1908,6 +1729,12 @@ inactive_tgt:
goto finish;
}
break;
+ } else if (enough) {
+ /*
+ * We've collected enough extents and there are
+ * more extents after it.
+ */
+ goto finish;
}
/* If we just need num of extents then go to next device */
@@ -1916,8 +1743,9 @@ inactive_tgt:
break;
}
- len_mapped_single_call = lcl_fm_ext[ext_count-1].fe_logical -
- lun_start + lcl_fm_ext[ext_count - 1].fe_length;
+ len_mapped_single_call =
+ lcl_fm_ext[ext_count - 1].fe_logical -
+ lun_start + lcl_fm_ext[ext_count - 1].fe_length;
/* Have we finished mapping on this device? */
if (req_fm_len <= len_mapped_single_call)
@@ -1926,14 +1754,15 @@ inactive_tgt:
/* Clear the EXTENT_LAST flag which can be present on
* last extent
*/
- if (lcl_fm_ext[ext_count-1].fe_flags & FIEMAP_EXTENT_LAST)
+ if (lcl_fm_ext[ext_count - 1].fe_flags &
+ FIEMAP_EXTENT_LAST)
lcl_fm_ext[ext_count - 1].fe_flags &=
~FIEMAP_EXTENT_LAST;
curr_loc = lov_stripe_size(lsm,
- lcl_fm_ext[ext_count - 1].fe_logical+
- lcl_fm_ext[ext_count - 1].fe_length,
- cur_stripe);
+ lcl_fm_ext[ext_count - 1].fe_logical +
+ lcl_fm_ext[ext_count - 1].fe_length,
+ cur_stripe);
if (curr_loc >= fm_key->oa.o_size)
ost_eof = 1;
@@ -1945,7 +1774,7 @@ inactive_tgt:
/* Ran out of available extents? */
if (current_extent >= fiemap->fm_extent_count)
- goto finish;
+ enough = true;
} while (ost_done == 0 && ost_eof == 0);
if (cur_stripe_wrap == last_stripe)
@@ -1985,73 +1814,14 @@ static int lov_get_info(const struct lu_env *env, struct obd_export *exp,
{
struct obd_device *obddev = class_exp2obd(exp);
struct lov_obd *lov = &obddev->u.lov;
- int i, rc;
+ int rc;
if (!vallen || !val)
return -EFAULT;
obd_getref(obddev);
- if (KEY_IS(KEY_LOCK_TO_STRIPE)) {
- struct {
- char name[16];
- struct ldlm_lock *lock;
- } *data = key;
- struct ldlm_res_id *res_id = &data->lock->l_resource->lr_name;
- struct lov_oinfo *loi;
- __u32 *stripe = val;
-
- if (*vallen < sizeof(*stripe)) {
- rc = -EFAULT;
- goto out;
- }
- *vallen = sizeof(*stripe);
-
- /* XXX This is another one of those bits that will need to
- * change if we ever actually support nested LOVs. It uses
- * the lock's export to find out which stripe it is.
- */
- /* XXX - it's assumed all the locks for deleted OSTs have
- * been cancelled. Also, the export for deleted OSTs will
- * be NULL and won't match the lock's export.
- */
- for (i = 0; i < lsm->lsm_stripe_count; i++) {
- loi = lsm->lsm_oinfo[i];
- if (lov_oinfo_is_dummy(loi))
- continue;
-
- if (!lov->lov_tgts[loi->loi_ost_idx])
- continue;
- if (lov->lov_tgts[loi->loi_ost_idx]->ltd_exp ==
- data->lock->l_conn_export &&
- ostid_res_name_eq(&loi->loi_oi, res_id)) {
- *stripe = i;
- rc = 0;
- goto out;
- }
- }
- LDLM_ERROR(data->lock, "lock on inode without such object");
- dump_lsm(D_ERROR, lsm);
- rc = -ENXIO;
- goto out;
- } else if (KEY_IS(KEY_LAST_ID)) {
- struct obd_id_info *info = val;
- __u32 size = sizeof(u64);
- struct lov_tgt_desc *tgt;
-
- LASSERT(*vallen == sizeof(struct obd_id_info));
- tgt = lov->lov_tgts[info->idx];
-
- if (!tgt || !tgt->ltd_active) {
- rc = -ESRCH;
- goto out;
- }
-
- rc = obd_get_info(env, tgt->ltd_exp, keylen, key,
- &size, info->data, NULL);
- rc = 0;
- goto out;
- } else if (KEY_IS(KEY_LOVDESC)) {
+ if (KEY_IS(KEY_LOVDESC)) {
struct lov_desc *desc_ret = val;
*desc_ret = lov->desc;
@@ -2060,22 +1830,6 @@ static int lov_get_info(const struct lu_env *env, struct obd_export *exp,
} else if (KEY_IS(KEY_FIEMAP)) {
rc = lov_fiemap(lov, keylen, key, vallen, val, lsm);
goto out;
- } else if (KEY_IS(KEY_CONNECT_FLAG)) {
- struct lov_tgt_desc *tgt;
- __u64 ost_idx = *((__u64 *)val);
-
- LASSERT(*vallen == sizeof(__u64));
- LASSERT(ost_idx < lov->desc.ld_tgt_count);
- tgt = lov->lov_tgts[ost_idx];
-
- if (!tgt || !tgt->ltd_exp) {
- rc = -ESRCH;
- goto out;
- }
-
- *((__u64 *)val) = exp_connect_flags(tgt->ltd_exp);
- rc = 0;
- goto out;
} else if (KEY_IS(KEY_TGT_COUNT)) {
*((int *)val) = lov->desc.ld_tgt_count;
rc = 0;
@@ -2098,8 +1852,7 @@ static int lov_set_info_async(const struct lu_env *env, struct obd_export *exp,
u32 count;
int i, rc = 0, err;
struct lov_tgt_desc *tgt;
- unsigned int incr = 0, check_uuid = 0, do_inactive = 0, no_set = 0;
- unsigned int next_id = 0, mds_con = 0;
+ int do_inactive = 0, no_set = 0;
if (!set) {
no_set = 1;
@@ -2111,18 +1864,8 @@ static int lov_set_info_async(const struct lu_env *env, struct obd_export *exp,
obd_getref(obddev);
count = lov->desc.ld_tgt_count;
- if (KEY_IS(KEY_NEXT_ID)) {
- count = vallen / sizeof(struct obd_id_info);
- vallen = sizeof(u64);
- incr = sizeof(struct obd_id_info);
- do_inactive = 1;
- next_id = 1;
- } else if (KEY_IS(KEY_CHECKSUM)) {
+ if (KEY_IS(KEY_CHECKSUM)) {
do_inactive = 1;
- } else if (KEY_IS(KEY_EVICT_BY_NID)) {
- /* use defaults: do_inactive = incr = 0; */
- } else if (KEY_IS(KEY_MDS_CONN)) {
- mds_con = 1;
} else if (KEY_IS(KEY_CACHE_SET)) {
LASSERT(!lov->lov_cache);
lov->lov_cache = val;
@@ -2130,11 +1873,9 @@ static int lov_set_info_async(const struct lu_env *env, struct obd_export *exp,
cl_cache_incref(lov->lov_cache);
}
- for (i = 0; i < count; i++, val = (char *)val + incr) {
- if (next_id)
- tgt = lov->lov_tgts[((struct obd_id_info *)val)->idx];
- else
- tgt = lov->lov_tgts[i];
+ for (i = 0; i < count; i++) {
+ tgt = lov->lov_tgts[i];
+
/* OST was disconnected */
if (!tgt || !tgt->ltd_exp)
continue;
@@ -2143,34 +1884,8 @@ static int lov_set_info_async(const struct lu_env *env, struct obd_export *exp,
if (!tgt->ltd_active && !do_inactive)
continue;
- if (mds_con) {
- struct mds_group_info *mgi;
-
- LASSERT(vallen == sizeof(*mgi));
- mgi = (struct mds_group_info *)val;
-
- /* Only want a specific OSC */
- if (mgi->uuid && !obd_uuid_equals(mgi->uuid,
- &tgt->ltd_uuid))
- continue;
-
- err = obd_set_info_async(env, tgt->ltd_exp,
- keylen, key, sizeof(int),
- &mgi->group, set);
- } else if (next_id) {
- err = obd_set_info_async(env, tgt->ltd_exp,
- keylen, key, vallen,
- ((struct obd_id_info *)val)->data, set);
- } else {
- /* Only want a specific OSC */
- if (check_uuid &&
- !obd_uuid_equals(val, &tgt->ltd_uuid))
- continue;
-
- err = obd_set_info_async(env, tgt->ltd_exp,
- keylen, key, vallen, val, set);
- }
-
+ err = obd_set_info_async(env, tgt->ltd_exp, keylen, key,
+ vallen, val, set);
if (!rc)
rc = err;
}
@@ -2318,12 +2033,8 @@ static struct obd_ops lov_obd_ops = {
.statfs_async = lov_statfs_async,
.packmd = lov_packmd,
.unpackmd = lov_unpackmd,
- .create = lov_create,
- .destroy = lov_destroy,
.getattr_async = lov_getattr_async,
.setattr_async = lov_setattr_async,
- .adjust_kms = lov_adjust_kms,
- .find_cbdata = lov_find_cbdata,
.iocontrol = lov_iocontrol,
.get_info = lov_get_info,
.set_info_async = lov_set_info_async,
diff --git a/drivers/staging/lustre/lustre/lov/lov_object.c b/drivers/staging/lustre/lustre/lov/lov_object.c
index f9621b0fd469..52f736338887 100644
--- a/drivers/staging/lustre/lustre/lov/lov_object.c
+++ b/drivers/staging/lustre/lustre/lov/lov_object.c
@@ -75,6 +75,13 @@ struct lov_layout_operations {
static int lov_layout_wait(const struct lu_env *env, struct lov_object *lov);
+void lov_lsm_put(struct cl_object *unused, struct lov_stripe_md *lsm)
+{
+ if (lsm)
+ lov_free_memmd(&lsm);
+}
+EXPORT_SYMBOL(lov_lsm_put);
+
/*****************************************************************************
*
* Lov object layout operations.
@@ -195,6 +202,10 @@ static int lov_page_slice_fixup(struct lov_object *lov,
struct cl_object_header *hdr = cl_object_header(&lov->lo_cl);
struct cl_object *o;
+ if (!stripe)
+ return hdr->coh_page_bufsize - lov->lo_cl.co_slice_off -
+ cfs_size_round(sizeof(struct lov_page));
+
cl_object_for_each(o, stripe)
o->co_slice_off += hdr->coh_page_bufsize;
@@ -224,6 +235,7 @@ static int lov_init_raid0(const struct lu_env *env,
LASSERT(!lov->lo_lsm);
lov->lo_lsm = lsm_addref(lsm);
+ lov->lo_layout_invalid = true;
r0->lo_nr = lsm->lsm_stripe_count;
LASSERT(r0->lo_nr <= lov_targets_nr(dev));
@@ -719,6 +731,10 @@ static int lov_layout_change(const struct lu_env *unused,
LASSERT(atomic_read(&lov->lo_active_ios) == 0);
lov->lo_type = LLT_EMPTY;
+ /* page bufsize fixup */
+ cl_object_header(&lov->lo_cl)->coh_page_bufsize -=
+ lov_page_slice_fixup(lov, NULL);
+
result = new_ops->llo_init(env,
lu2lov_dev(lov->lo_cl.co_lu.lo_dev),
lov, conf, state);
@@ -878,8 +894,8 @@ static int lov_attr_get(const struct lu_env *env, struct cl_object *obj,
return LOV_2DISPATCH_NOLOCK(cl2lov(obj), llo_getattr, env, obj, attr);
}
-static int lov_attr_set(const struct lu_env *env, struct cl_object *obj,
- const struct cl_attr *attr, unsigned valid)
+static int lov_attr_update(const struct lu_env *env, struct cl_object *obj,
+ const struct cl_attr *attr, unsigned int valid)
{
/*
* No dispatch is required here, as no layout implements this.
@@ -895,13 +911,30 @@ int lov_lock_init(const struct lu_env *env, struct cl_object *obj,
io);
}
+static int lov_object_getstripe(const struct lu_env *env, struct cl_object *obj,
+ struct lov_user_md __user *lum)
+{
+ struct lov_object *lov = cl2lov(obj);
+ struct lov_stripe_md *lsm;
+ int rc = 0;
+
+ lsm = lov_lsm_addref(lov);
+ if (!lsm)
+ return -ENODATA;
+
+ rc = lov_getstripe(cl2lov(obj), lsm, lum);
+ lov_lsm_put(obj, lsm);
+ return rc;
+}
+
static const struct cl_object_operations lov_ops = {
.coo_page_init = lov_page_init,
.coo_lock_init = lov_lock_init,
.coo_io_init = lov_io_init,
.coo_attr_get = lov_attr_get,
- .coo_attr_set = lov_attr_set,
- .coo_conf_set = lov_conf_set
+ .coo_attr_update = lov_attr_update,
+ .coo_conf_set = lov_conf_set,
+ .coo_getstripe = lov_object_getstripe
};
static const struct lu_object_operations lov_lu_obj_ops = {
@@ -938,7 +971,7 @@ struct lu_object *lov_object_alloc(const struct lu_env *env,
return obj;
}
-static struct lov_stripe_md *lov_lsm_addref(struct lov_object *lov)
+struct lov_stripe_md *lov_lsm_addref(struct lov_object *lov)
{
struct lov_stripe_md *lsm = NULL;
@@ -969,13 +1002,6 @@ struct lov_stripe_md *lov_lsm_get(struct cl_object *clobj)
}
EXPORT_SYMBOL(lov_lsm_get);
-void lov_lsm_put(struct cl_object *unused, struct lov_stripe_md *lsm)
-{
- if (lsm)
- lov_free_memmd(&lsm);
-}
-EXPORT_SYMBOL(lov_lsm_put);
-
int lov_read_and_clear_async_rc(struct cl_object *clob)
{
struct lu_object *luobj;
diff --git a/drivers/staging/lustre/lustre/lov/lov_pack.c b/drivers/staging/lustre/lustre/lov/lov_pack.c
index 869ef41b13ca..be6e9857ce2a 100644
--- a/drivers/staging/lustre/lustre/lov/lov_pack.c
+++ b/drivers/staging/lustre/lustre/lov/lov_pack.c
@@ -45,6 +45,7 @@
#include "../include/lustre/lustre_user.h"
#include "lov_internal.h"
+#include "lov_cl_internal.h"
void lov_dump_lmm_common(int level, void *lmmp)
{
@@ -104,11 +105,9 @@ void lov_dump_lmm_v3(int level, struct lov_mds_md_v3 *lmm)
* LOVs properly. For now lov_mds_md_size() just assumes one u64
* per stripe.
*/
-int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
- struct lov_stripe_md *lsm)
+int lov_obd_packmd(struct lov_obd *lov, struct lov_mds_md **lmmp,
+ struct lov_stripe_md *lsm)
{
- struct obd_device *obd = class_exp2obd(exp);
- struct lov_obd *lov = &obd->u.lov;
struct lov_mds_md_v1 *lmmv1;
struct lov_mds_md_v3 *lmmv3;
__u16 stripe_count;
@@ -148,16 +147,11 @@ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
stripe_count = 0;
}
} else {
- /* No need to allocate more than maximum supported stripes.
- * Anyway, this is pretty inaccurate since ld_tgt_count now
- * represents max index and we should rely on the actual number
- * of OSTs instead
+ /*
+ * To calculate maximum easize by active targets at present,
+ * which is exactly the maximum easize to be seen by LOV
*/
- stripe_count = lov_mds_md_max_stripe_count(
- lov->lov_ocd.ocd_max_easize, lmm_magic);
-
- if (stripe_count > lov->desc.ld_tgt_count)
- stripe_count = lov->desc.ld_tgt_count;
+ stripe_count = lov->desc.ld_active_tgt_count;
}
/* XXX LOV STACKING call into osc for sizes */
@@ -225,6 +219,15 @@ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
return lmm_size;
}
+int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
+ struct lov_stripe_md *lsm)
+{
+ struct obd_device *obd = class_exp2obd(exp);
+ struct lov_obd *lov = &obd->u.lov;
+
+ return lov_obd_packmd(lov, lmmp, lsm);
+}
+
/* Find the max stripecount we should use */
__u16 lov_get_stripecnt(struct lov_obd *lov, __u32 magic, __u16 stripe_count)
{
@@ -284,7 +287,7 @@ int lov_alloc_memmd(struct lov_stripe_md **lsmp, __u16 stripe_count,
spin_lock_init(&(*lsmp)->lsm_lock);
(*lsmp)->lsm_magic = magic;
(*lsmp)->lsm_stripe_count = stripe_count;
- (*lsmp)->lsm_maxbytes = LUSTRE_STRIPE_MAXBYTES * stripe_count;
+ (*lsmp)->lsm_maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES * stripe_count;
(*lsmp)->lsm_pattern = pattern;
(*lsmp)->lsm_pool_name[0] = '\0';
(*lsmp)->lsm_layout_gen = 0;
@@ -372,16 +375,17 @@ int lov_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
* the maximum number of OST indices which will fit in the user buffer.
* lmm_magic must be LOV_USER_MAGIC.
*/
-int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm,
+int lov_getstripe(struct lov_object *obj, struct lov_stripe_md *lsm,
struct lov_user_md __user *lump)
{
/*
* XXX huge struct allocated on stack.
*/
/* we use lov_user_md_v3 because it is larger than lov_user_md_v1 */
+ struct lov_obd *lov;
struct lov_user_md_v3 lum;
struct lov_mds_md *lmmk = NULL;
- int rc, lmm_size;
+ int rc, lmmk_size, lmm_size;
int lum_size;
mm_segment_t seg;
@@ -401,12 +405,13 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm,
lum_size = sizeof(struct lov_user_md_v1);
if (copy_from_user(&lum, lump, lum_size)) {
rc = -EFAULT;
- goto out_set;
+ goto out;
}
- if ((lum.lmm_magic != LOV_USER_MAGIC) &&
- (lum.lmm_magic != LOV_USER_MAGIC_V3)) {
+ if (lum.lmm_magic != LOV_USER_MAGIC_V1 &&
+ lum.lmm_magic != LOV_USER_MAGIC_V3 &&
+ lum.lmm_magic != LOV_USER_MAGIC_SPECIFIC) {
rc = -EINVAL;
- goto out_set;
+ goto out;
}
if (lum.lmm_stripe_count &&
@@ -415,11 +420,13 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm,
lum.lmm_stripe_count = lsm->lsm_stripe_count;
rc = copy_to_user(lump, &lum, lum_size);
rc = -EOVERFLOW;
- goto out_set;
+ goto out;
}
- rc = lov_packmd(exp, &lmmk, lsm);
+ lov = lu2lov_dev(obj->lo_cl.co_lu.lo_dev)->ld_lov;
+ rc = lov_obd_packmd(lov, &lmmk, lsm);
if (rc < 0)
- goto out_set;
+ goto out;
+ lmmk_size = rc;
lmm_size = rc;
rc = 0;
@@ -455,7 +462,7 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm,
lmm_size = lum_size;
} else if (lum.lmm_stripe_count < lmmk->lmm_stripe_count) {
rc = -EOVERFLOW;
- goto out_set;
+ goto out_free;
}
/*
* Have a difference between lov_mds_md & lov_user_md.
@@ -468,8 +475,9 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm,
if (copy_to_user(lump, lmmk, lmm_size))
rc = -EFAULT;
- obd_free_diskmd(exp, &lmmk);
-out_set:
+out_free:
+ kfree(lmmk);
+out:
set_fs(seg);
return rc;
}
diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c
index c17026f14896..00bfabad78eb 100644
--- a/drivers/staging/lustre/lustre/lov/lov_page.c
+++ b/drivers/staging/lustre/lustre/lov/lov_page.c
@@ -65,7 +65,9 @@ static int lov_raid0_page_is_under_lock(const struct lu_env *env,
pgoff_t index = *max_index;
unsigned int pps; /* pages per stripe */
- CDEBUG(D_READA, "*max_index = %lu, nr = %d\n", index, r0->lo_nr);
+ CDEBUG(D_READA, DFID "*max_index = %lu, nr = %d\n",
+ PFID(lu_object_fid(lov2lu(loo))), index, r0->lo_nr);
+
if (index == 0) /* the page is not covered by any lock */
return 0;
@@ -80,7 +82,12 @@ static int lov_raid0_page_is_under_lock(const struct lu_env *env,
/* calculate the end of current stripe */
pps = loo->lo_lsm->lsm_stripe_size >> PAGE_SHIFT;
- index = ((slice->cpl_index + pps) & ~(pps - 1)) - 1;
+ index = slice->cpl_index + pps - slice->cpl_index % pps - 1;
+
+ CDEBUG(D_READA, DFID "*max_index = %lu, index = %lu, pps = %u, stripe_size = %u, stripe no = %u, page index = %lu\n",
+ PFID(lu_object_fid(lov2lu(loo))), *max_index, index, pps,
+ loo->lo_lsm->lsm_stripe_size, lov_page_stripe(slice->cpl_page),
+ slice->cpl_index);
/* never exceed the end of the stripe */
*max_index = min_t(pgoff_t, *max_index, index);
@@ -122,6 +129,7 @@ int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj,
rc = lov_stripe_offset(loo->lo_lsm, offset, stripe, &suboff);
LASSERT(rc == 0);
+ lpg->lps_stripe = stripe;
cl_page_slice_add(page, &lpg->lps_cl, obj, index, &lov_raid0_page_ops);
sub = lov_sub_get(env, lio, stripe);
diff --git a/drivers/staging/lustre/lustre/lov/lov_pool.c b/drivers/staging/lustre/lustre/lov/lov_pool.c
index 4c2d21729589..f8c8a361ef79 100644
--- a/drivers/staging/lustre/lustre/lov/lov_pool.c
+++ b/drivers/staging/lustre/lustre/lov/lov_pool.c
@@ -61,7 +61,7 @@ void lov_pool_putref(struct pool_desc *pool)
LASSERT(hlist_unhashed(&pool->pool_hash));
LASSERT(list_empty(&pool->pool_list));
LASSERT(!pool->pool_debugfs_entry);
- lov_ost_pool_free(&(pool->pool_obds));
+ lov_ost_pool_free(&pool->pool_obds);
kfree(pool);
}
}
@@ -92,7 +92,7 @@ static __u32 pool_hashfn(struct cfs_hash *hash_body, const void *key, unsigned m
for (i = 0; i < LOV_MAXPOOLNAME; i++) {
if (poolname[i] == '\0')
break;
- result = (result << 4)^(result >> 28) ^ poolname[i];
+ result = (result << 4) ^ (result >> 28) ^ poolname[i];
}
return (result % mask);
}
@@ -260,7 +260,7 @@ static int pool_proc_show(struct seq_file *s, void *v)
tgt = pool_tgt(iter->pool, iter->idx);
up_read(&pool_tgt_rw_sem(iter->pool));
if (tgt)
- seq_printf(s, "%s\n", obd_uuid2str(&(tgt->ltd_uuid)));
+ seq_printf(s, "%s\n", obd_uuid2str(&tgt->ltd_uuid));
return 0;
}
@@ -400,7 +400,7 @@ int lov_pool_new(struct obd_device *obd, char *poolname)
struct pool_desc *new_pool;
int rc;
- lov = &(obd->u.lov);
+ lov = &obd->u.lov;
if (strlen(poolname) > LOV_MAXPOOLNAME)
return -ENAMETOOLONG;
@@ -471,7 +471,7 @@ int lov_pool_del(struct obd_device *obd, char *poolname)
struct lov_obd *lov;
struct pool_desc *pool;
- lov = &(obd->u.lov);
+ lov = &obd->u.lov;
/* lookup and kill hash reference */
pool = cfs_hash_del_key(lov->lov_pools_hash_body, poolname);
@@ -503,7 +503,7 @@ int lov_pool_add(struct obd_device *obd, char *poolname, char *ostname)
unsigned int lov_idx;
int rc;
- lov = &(obd->u.lov);
+ lov = &obd->u.lov;
pool = cfs_hash_lookup(lov->lov_pools_hash_body, poolname);
if (!pool)
@@ -517,7 +517,7 @@ int lov_pool_add(struct obd_device *obd, char *poolname, char *ostname)
if (!lov->lov_tgts[lov_idx])
continue;
if (obd_uuid_equals(&ost_uuid,
- &(lov->lov_tgts[lov_idx]->ltd_uuid)))
+ &lov->lov_tgts[lov_idx]->ltd_uuid))
break;
}
/* test if ost found in lov */
@@ -547,7 +547,7 @@ int lov_pool_remove(struct obd_device *obd, char *poolname, char *ostname)
unsigned int lov_idx;
int rc = 0;
- lov = &(obd->u.lov);
+ lov = &obd->u.lov;
pool = cfs_hash_lookup(lov->lov_pools_hash_body, poolname);
if (!pool)
@@ -562,7 +562,7 @@ int lov_pool_remove(struct obd_device *obd, char *poolname, char *ostname)
continue;
if (obd_uuid_equals(&ost_uuid,
- &(lov->lov_tgts[lov_idx]->ltd_uuid)))
+ &lov->lov_tgts[lov_idx]->ltd_uuid))
break;
}
diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c
index 4099b51f826e..09dcaf484c89 100644
--- a/drivers/staging/lustre/lustre/lov/lov_request.c
+++ b/drivers/staging/lustre/lustre/lov/lov_request.c
@@ -325,84 +325,6 @@ out_set:
return rc;
}
-int lov_fini_destroy_set(struct lov_request_set *set)
-{
- if (!set)
- return 0;
- LASSERT(set->set_exp);
- if (atomic_read(&set->set_completes)) {
- /* FIXME update qos data here */
- }
-
- lov_put_reqset(set);
-
- return 0;
-}
-
-int lov_prep_destroy_set(struct obd_export *exp, struct obd_info *oinfo,
- struct obdo *src_oa, struct lov_stripe_md *lsm,
- struct obd_trans_info *oti,
- struct lov_request_set **reqset)
-{
- struct lov_request_set *set;
- struct lov_obd *lov = &exp->exp_obd->u.lov;
- int rc = 0, i;
-
- set = kzalloc(sizeof(*set), GFP_NOFS);
- if (!set)
- return -ENOMEM;
- lov_init_set(set);
-
- set->set_exp = exp;
- set->set_oi = oinfo;
- set->set_oi->oi_md = lsm;
- set->set_oi->oi_oa = src_oa;
- if (oti && src_oa->o_valid & OBD_MD_FLCOOKIE)
- set->set_cookies = oti->oti_logcookies;
-
- for (i = 0; i < lsm->lsm_stripe_count; i++) {
- struct lov_oinfo *loi;
- struct lov_request *req;
-
- loi = lsm->lsm_oinfo[i];
- if (lov_oinfo_is_dummy(loi))
- continue;
-
- if (!lov_check_and_wait_active(lov, loi->loi_ost_idx)) {
- CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx);
- continue;
- }
-
- req = kzalloc(sizeof(*req), GFP_NOFS);
- if (!req) {
- rc = -ENOMEM;
- goto out_set;
- }
-
- req->rq_stripe = i;
- req->rq_idx = loi->loi_ost_idx;
-
- req->rq_oi.oi_oa = kmem_cache_zalloc(obdo_cachep, GFP_NOFS);
- if (!req->rq_oi.oi_oa) {
- kfree(req);
- rc = -ENOMEM;
- goto out_set;
- }
- memcpy(req->rq_oi.oi_oa, src_oa, sizeof(*req->rq_oi.oi_oa));
- req->rq_oi.oi_oa->o_oi = loi->loi_oi;
- lov_set_add_req(req, set);
- }
- if (!set->set_count) {
- rc = -EIO;
- goto out_set;
- }
- *reqset = set;
- return rc;
-out_set:
- lov_fini_destroy_set(set);
- return rc;
-}
-
int lov_fini_setattr_set(struct lov_request_set *set)
{
int rc = 0;
diff --git a/drivers/staging/lustre/lustre/lov/lovsub_object.c b/drivers/staging/lustre/lustre/lov/lovsub_object.c
index fb2f2660b3e9..a2bac7a3b71b 100644
--- a/drivers/staging/lustre/lustre/lov/lovsub_object.c
+++ b/drivers/staging/lustre/lustre/lov/lovsub_object.c
@@ -98,8 +98,8 @@ static int lovsub_object_print(const struct lu_env *env, void *cookie,
return (*p)(env, cookie, "[%d]", los->lso_index);
}
-static int lovsub_attr_set(const struct lu_env *env, struct cl_object *obj,
- const struct cl_attr *attr, unsigned valid)
+static int lovsub_attr_update(const struct lu_env *env, struct cl_object *obj,
+ const struct cl_attr *attr, unsigned int valid)
{
struct lov_object *lov = cl2lovsub(obj)->lso_super;
@@ -119,7 +119,7 @@ static int lovsub_object_glimpse(const struct lu_env *env,
static const struct cl_object_operations lovsub_ops = {
.coo_page_init = lovsub_page_init,
.coo_lock_init = lovsub_lock_init,
- .coo_attr_set = lovsub_attr_set,
+ .coo_attr_update = lovsub_attr_update,
.coo_glimpse = lovsub_object_glimpse
};
diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
index 98d15fb247bc..fca9450de57c 100644
--- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
+++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
@@ -43,11 +43,10 @@ static ssize_t max_rpcs_in_flight_show(struct kobject *kobj,
int len;
struct obd_device *dev = container_of(kobj, struct obd_device,
obd_kobj);
- struct client_obd *cli = &dev->u.cli;
+ __u32 max;
- spin_lock(&cli->cl_loi_list_lock);
- len = sprintf(buf, "%u\n", cli->cl_max_rpcs_in_flight);
- spin_unlock(&cli->cl_loi_list_lock);
+ max = obd_get_max_rpcs_in_flight(&dev->u.cli);
+ len = sprintf(buf, "%u\n", max);
return len;
}
@@ -59,7 +58,6 @@ static ssize_t max_rpcs_in_flight_store(struct kobject *kobj,
{
struct obd_device *dev = container_of(kobj, struct obd_device,
obd_kobj);
- struct client_obd *cli = &dev->u.cli;
int rc;
unsigned long val;
@@ -67,12 +65,9 @@ static ssize_t max_rpcs_in_flight_store(struct kobject *kobj,
if (rc)
return rc;
- if (val < 1 || val > MDC_MAX_RIF_MAX)
- return -ERANGE;
-
- spin_lock(&cli->cl_loi_list_lock);
- cli->cl_max_rpcs_in_flight = val;
- spin_unlock(&cli->cl_loi_list_lock);
+ rc = obd_set_max_rpcs_in_flight(&dev->u.cli, val);
+ if (rc)
+ count = rc;
return count;
}
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_internal.h b/drivers/staging/lustre/lustre/mdc/mdc_internal.h
index 58f2841cabe4..f446c1c2584b 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_internal.h
+++ b/drivers/staging/lustre/lustre/mdc/mdc_internal.h
@@ -34,63 +34,57 @@
#define _MDC_INTERNAL_H
#include "../include/lustre_mdc.h"
-#include "../include/lustre_mds.h"
void lprocfs_mdc_init_vars(struct lprocfs_static_vars *lvars);
void mdc_pack_body(struct ptlrpc_request *req, const struct lu_fid *fid,
- __u64 valid, int ea_size, __u32 suppgid, int flags);
-void mdc_is_subdir_pack(struct ptlrpc_request *req, const struct lu_fid *pfid,
- const struct lu_fid *cfid, int flags);
+ __u64 valid, size_t ea_size, __u32 suppgid, u32 flags);
void mdc_swap_layouts_pack(struct ptlrpc_request *req,
struct md_op_data *op_data);
-void mdc_readdir_pack(struct ptlrpc_request *req, __u64 pgoff, __u32 size,
+void mdc_readdir_pack(struct ptlrpc_request *req, __u64 pgoff, size_t size,
const struct lu_fid *fid);
-void mdc_getattr_pack(struct ptlrpc_request *req, __u64 valid, int flags,
- struct md_op_data *data, int ea_size);
+void mdc_getattr_pack(struct ptlrpc_request *req, __u64 valid, u32 flags,
+ struct md_op_data *data, size_t ea_size);
void mdc_setattr_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
- void *ea, int ealen, void *ea2, int ea2len);
+ void *ea, size_t ealen, void *ea2, size_t ea2len);
void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
- const void *data, int datalen, __u32 mode, __u32 uid,
- __u32 gid, cfs_cap_t capability, __u64 rdev);
+ const void *data, size_t datalen, umode_t mode, uid_t uid,
+ gid_t gid, cfs_cap_t capability, __u64 rdev);
void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
- __u32 mode, __u64 rdev, __u64 flags, const void *data,
- int datalen);
+ umode_t mode, __u64 rdev, __u64 flags, const void *data,
+ size_t datalen);
void mdc_unlink_pack(struct ptlrpc_request *req, struct md_op_data *op_data);
void mdc_link_pack(struct ptlrpc_request *req, struct md_op_data *op_data);
void mdc_rename_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
- const char *old, int oldlen, const char *new, int newlen);
+ const char *old, size_t oldlen,
+ const char *new, size_t newlen);
void mdc_close_pack(struct ptlrpc_request *req, struct md_op_data *op_data);
-int mdc_enter_request(struct client_obd *cli);
-void mdc_exit_request(struct client_obd *cli);
/* mdc/mdc_locks.c */
int mdc_set_lock_data(struct obd_export *exp,
- __u64 *lockh, void *data, __u64 *bits);
+ const struct lustre_handle *lockh,
+ void *data, __u64 *bits);
int mdc_null_inode(struct obd_export *exp, const struct lu_fid *fid);
-int mdc_find_cbdata(struct obd_export *exp, const struct lu_fid *fid,
- ldlm_iterator_t it, void *data);
-
int mdc_intent_lock(struct obd_export *exp,
- struct md_op_data *,
- void *lmm, int lmmsize,
- struct lookup_intent *, int,
+ struct md_op_data *op_data,
+ struct lookup_intent *it,
struct ptlrpc_request **reqp,
ldlm_blocking_callback cb_blocking,
__u64 extra_lock_flags);
+
int mdc_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo,
+ const ldlm_policy_data_t *policy,
struct lookup_intent *it, struct md_op_data *op_data,
- struct lustre_handle *lockh, void *lmm, int lmmsize,
- struct ptlrpc_request **req, __u64 extra_lock_flags);
+ struct lustre_handle *lockh, __u64 extra_lock_flags);
int mdc_resource_get_unused(struct obd_export *exp, const struct lu_fid *fid,
struct list_head *cancels, enum ldlm_mode mode,
__u64 bits);
/* mdc/mdc_request.c */
-int mdc_fid_alloc(struct obd_export *exp, struct lu_fid *fid,
- struct md_op_data *op_data);
+int mdc_fid_alloc(const struct lu_env *env, struct obd_export *exp,
+ struct lu_fid *fid, struct md_op_data *op_data);
struct obd_client_handle;
int mdc_set_open_replay_data(struct obd_export *exp,
@@ -101,16 +95,17 @@ void mdc_commit_open(struct ptlrpc_request *req);
void mdc_replay_open(struct ptlrpc_request *req);
int mdc_create(struct obd_export *exp, struct md_op_data *op_data,
- const void *data, int datalen, int mode, __u32 uid, __u32 gid,
- cfs_cap_t capability, __u64 rdev,
+ const void *data, size_t datalen, umode_t mode, uid_t uid,
+ gid_t gid, cfs_cap_t capability, __u64 rdev,
struct ptlrpc_request **request);
int mdc_link(struct obd_export *exp, struct md_op_data *op_data,
struct ptlrpc_request **request);
int mdc_rename(struct obd_export *exp, struct md_op_data *op_data,
- const char *old, int oldlen, const char *new, int newlen,
+ const char *old, size_t oldlen,
+ const char *new, size_t newlen,
struct ptlrpc_request **request);
int mdc_setattr(struct obd_export *exp, struct md_op_data *op_data,
- void *ea, int ealen, void *ea2, int ea2len,
+ void *ea, size_t ealen, void *ea2, size_t ea2len,
struct ptlrpc_request **request, struct md_open_data **mod);
int mdc_unlink(struct obd_export *exp, struct md_op_data *op_data,
struct ptlrpc_request **request);
@@ -138,4 +133,12 @@ static inline int mdc_prep_elc_req(struct obd_export *exp,
count);
}
+static inline unsigned long hash_x_index(__u64 hash, int hash64)
+{
+ if (BITS_PER_LONG == 32 && hash64)
+ hash >>= 32;
+ /* save hash 0 with hash 1 */
+ return ~0UL - (hash + !hash);
+}
+
#endif
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c
index 143bd7628572..aac7e04873e2 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c
@@ -37,27 +37,12 @@
static void __mdc_pack_body(struct mdt_body *b, __u32 suppgid)
{
- b->suppgid = suppgid;
- b->uid = from_kuid(&init_user_ns, current_uid());
- b->gid = from_kgid(&init_user_ns, current_gid());
- b->fsuid = from_kuid(&init_user_ns, current_fsuid());
- b->fsgid = from_kgid(&init_user_ns, current_fsgid());
- b->capability = cfs_curproc_cap_pack();
-}
-
-void mdc_is_subdir_pack(struct ptlrpc_request *req, const struct lu_fid *pfid,
- const struct lu_fid *cfid, int flags)
-{
- struct mdt_body *b = req_capsule_client_get(&req->rq_pill,
- &RMF_MDT_BODY);
-
- if (pfid) {
- b->fid1 = *pfid;
- b->valid = OBD_MD_FLID;
- }
- if (cfid)
- b->fid2 = *cfid;
- b->flags = flags;
+ b->mbo_suppgid = suppgid;
+ b->mbo_uid = from_kuid(&init_user_ns, current_uid());
+ b->mbo_gid = from_kgid(&init_user_ns, current_gid());
+ b->mbo_fsuid = from_kuid(&init_user_ns, current_fsuid());
+ b->mbo_fsgid = from_kgid(&init_user_ns, current_fsgid());
+ b->mbo_capability = cfs_curproc_cap_pack();
}
void mdc_swap_layouts_pack(struct ptlrpc_request *req,
@@ -67,43 +52,74 @@ void mdc_swap_layouts_pack(struct ptlrpc_request *req,
&RMF_MDT_BODY);
__mdc_pack_body(b, op_data->op_suppgids[0]);
- b->fid1 = op_data->op_fid1;
- b->fid2 = op_data->op_fid2;
- b->valid |= OBD_MD_FLID;
+ b->mbo_fid1 = op_data->op_fid1;
+ b->mbo_fid2 = op_data->op_fid2;
+ b->mbo_valid |= OBD_MD_FLID;
}
void mdc_pack_body(struct ptlrpc_request *req, const struct lu_fid *fid,
- __u64 valid, int ea_size, __u32 suppgid, int flags)
+ __u64 valid, size_t ea_size, __u32 suppgid, u32 flags)
{
struct mdt_body *b = req_capsule_client_get(&req->rq_pill,
&RMF_MDT_BODY);
- b->valid = valid;
- b->eadatasize = ea_size;
- b->flags = flags;
+ b->mbo_valid = valid;
+ b->mbo_eadatasize = ea_size;
+ b->mbo_flags = flags;
__mdc_pack_body(b, suppgid);
if (fid) {
- b->fid1 = *fid;
- b->valid |= OBD_MD_FLID;
+ b->mbo_fid1 = *fid;
+ b->mbo_valid |= OBD_MD_FLID;
}
}
-void mdc_readdir_pack(struct ptlrpc_request *req, __u64 pgoff,
- __u32 size, const struct lu_fid *fid)
+/**
+ * Pack a name (path component) into a request
+ *
+ * \param[in] req request
+ * \param[in] field request field (usually RMF_NAME)
+ * \param[in] name path component
+ * \param[in] name_len length of path component
+ *
+ * \a field must be present in \a req and of size \a name_len + 1.
+ *
+ * \a name must be '\0' terminated of length \a name_len and represent
+ * a single path component (not contain '/').
+ */
+static void mdc_pack_name(struct ptlrpc_request *req,
+ const struct req_msg_field *field,
+ const char *name, size_t name_len)
+{
+ size_t buf_size;
+ size_t cpy_len;
+ char *buf;
+
+ buf = req_capsule_client_get(&req->rq_pill, field);
+ buf_size = req_capsule_get_size(&req->rq_pill, field, RCL_CLIENT);
+
+ LASSERT(name && name_len && buf && buf_size == name_len + 1);
+
+ cpy_len = strlcpy(buf, name, buf_size);
+
+ LASSERT(cpy_len == name_len && lu_name_is_valid_2(buf, cpy_len));
+}
+
+void mdc_readdir_pack(struct ptlrpc_request *req, __u64 pgoff, size_t size,
+ const struct lu_fid *fid)
{
struct mdt_body *b = req_capsule_client_get(&req->rq_pill,
&RMF_MDT_BODY);
- b->fid1 = *fid;
- b->valid |= OBD_MD_FLID;
- b->size = pgoff; /* !! */
- b->nlink = size; /* !! */
+ b->mbo_fid1 = *fid;
+ b->mbo_valid |= OBD_MD_FLID;
+ b->mbo_size = pgoff; /* !! */
+ b->mbo_nlink = size; /* !! */
__mdc_pack_body(b, -1);
- b->mode = LUDA_FID | LUDA_TYPE;
+ b->mbo_mode = LUDA_FID | LUDA_TYPE;
}
/* packing of MDS records */
void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
- const void *data, int datalen, __u32 mode,
- __u32 uid, __u32 gid, cfs_cap_t cap_effective, __u64 rdev)
+ const void *data, size_t datalen, umode_t mode,
+ uid_t uid, gid_t gid, cfs_cap_t cap_effective, __u64 rdev)
{
struct mdt_rec_create *rec;
char *tmp;
@@ -130,22 +146,17 @@ void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
rec->cr_bias = op_data->op_bias;
rec->cr_umask = current_umask();
- tmp = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
- LOGL0(op_data->op_name, op_data->op_namelen, tmp);
-
+ mdc_pack_name(req, &RMF_NAME, op_data->op_name, op_data->op_namelen);
if (data) {
tmp = req_capsule_client_get(&req->rq_pill, &RMF_EADATA);
memcpy(tmp, data, datalen);
}
}
-static __u64 mds_pack_open_flags(__u64 flags, __u32 mode)
+static inline __u64 mds_pack_open_flags(__u64 flags)
{
__u64 cr_flags = (flags & (FMODE_READ | FMODE_WRITE |
- MDS_OPEN_HAS_EA | MDS_OPEN_HAS_OBJS |
- MDS_OPEN_OWNEROVERRIDE | MDS_OPEN_LOCK |
- MDS_OPEN_BY_FID | MDS_OPEN_LEASE |
- MDS_OPEN_RELEASE));
+ MDS_OPEN_FL_INTERNAL));
if (flags & O_CREAT)
cr_flags |= MDS_OPEN_CREAT;
if (flags & O_EXCL)
@@ -171,8 +182,8 @@ static __u64 mds_pack_open_flags(__u64 flags, __u32 mode)
/* packing of MDS records */
void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
- __u32 mode, __u64 rdev, __u64 flags, const void *lmm,
- int lmmlen)
+ umode_t mode, __u64 rdev, __u64 flags, const void *lmm,
+ size_t lmmlen)
{
struct mdt_rec_create *rec;
char *tmp;
@@ -190,7 +201,7 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
rec->cr_fid2 = op_data->op_fid2;
rec->cr_mode = mode;
- cr_flags = mds_pack_open_flags(flags, mode);
+ cr_flags = mds_pack_open_flags(flags);
rec->cr_rdev = rdev;
rec->cr_time = op_data->op_mod_time;
rec->cr_suppgid1 = op_data->op_suppgids[0];
@@ -200,8 +211,9 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
rec->cr_old_handle = op_data->op_handle;
if (op_data->op_name) {
- tmp = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
- LOGL0(op_data->op_name, op_data->op_namelen, tmp);
+ mdc_pack_name(req, &RMF_NAME, op_data->op_name,
+ op_data->op_namelen);
+
if (op_data->op_bias & MDS_CREATE_VOLATILE)
cr_flags |= MDS_OPEN_VOLATILE;
}
@@ -295,7 +307,7 @@ static void mdc_ioepoch_pack(struct mdt_ioepoch *epoch,
}
void mdc_setattr_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
- void *ea, int ealen, void *ea2, int ea2len)
+ void *ea, size_t ealen, void *ea2, size_t ea2len)
{
struct mdt_rec_setattr *rec;
struct mdt_ioepoch *epoch;
@@ -316,7 +328,7 @@ void mdc_setattr_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
lum = req_capsule_client_get(&req->rq_pill, &RMF_EADATA);
if (!ea) { /* Remove LOV EA */
- lum->lmm_magic = LOV_USER_MAGIC_V1;
+ lum->lmm_magic = cpu_to_le32(LOV_USER_MAGIC_V1);
lum->lmm_stripe_size = 0;
lum->lmm_stripe_count = 0;
lum->lmm_stripe_offset = (typeof(lum->lmm_stripe_offset))(-1);
@@ -334,7 +346,6 @@ void mdc_setattr_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
void mdc_unlink_pack(struct ptlrpc_request *req, struct md_op_data *op_data)
{
struct mdt_rec_unlink *rec;
- char *tmp;
CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_unlink));
rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT);
@@ -352,15 +363,12 @@ void mdc_unlink_pack(struct ptlrpc_request *req, struct md_op_data *op_data)
rec->ul_time = op_data->op_mod_time;
rec->ul_bias = op_data->op_bias;
- tmp = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
- LASSERT(tmp);
- LOGL0(op_data->op_name, op_data->op_namelen, tmp);
+ mdc_pack_name(req, &RMF_NAME, op_data->op_name, op_data->op_namelen);
}
void mdc_link_pack(struct ptlrpc_request *req, struct md_op_data *op_data)
{
struct mdt_rec_link *rec;
- char *tmp;
CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_link));
rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT);
@@ -376,20 +384,21 @@ void mdc_link_pack(struct ptlrpc_request *req, struct md_op_data *op_data)
rec->lk_time = op_data->op_mod_time;
rec->lk_bias = op_data->op_bias;
- tmp = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
- LOGL0(op_data->op_name, op_data->op_namelen, tmp);
+ mdc_pack_name(req, &RMF_NAME, op_data->op_name, op_data->op_namelen);
}
void mdc_rename_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
- const char *old, int oldlen, const char *new, int newlen)
+ const char *old, size_t oldlen,
+ const char *new, size_t newlen)
{
struct mdt_rec_rename *rec;
- char *tmp;
CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_rename));
rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT);
/* XXX do something about time, uid, gid */
+ rec->rn_opcode = op_data->op_cli_flags & CLI_MIGRATE ?
+ REINT_MIGRATE : REINT_RENAME;
rec->rn_opcode = REINT_RENAME;
rec->rn_fsuid = op_data->op_fsuid;
rec->rn_fsgid = op_data->op_fsgid;
@@ -402,39 +411,34 @@ void mdc_rename_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
rec->rn_mode = op_data->op_mode;
rec->rn_bias = op_data->op_bias;
- tmp = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
- LOGL0(old, oldlen, tmp);
+ mdc_pack_name(req, &RMF_NAME, old, oldlen);
- if (new) {
- tmp = req_capsule_client_get(&req->rq_pill, &RMF_SYMTGT);
- LOGL0(new, newlen, tmp);
- }
+ if (new)
+ mdc_pack_name(req, &RMF_SYMTGT, new, newlen);
}
-void mdc_getattr_pack(struct ptlrpc_request *req, __u64 valid, int flags,
- struct md_op_data *op_data, int ea_size)
+void mdc_getattr_pack(struct ptlrpc_request *req, __u64 valid, u32 flags,
+ struct md_op_data *op_data, size_t ea_size)
{
struct mdt_body *b = req_capsule_client_get(&req->rq_pill,
&RMF_MDT_BODY);
- b->valid = valid;
+ b->mbo_valid = valid;
if (op_data->op_bias & MDS_CHECK_SPLIT)
- b->valid |= OBD_MD_FLCKSPLIT;
+ b->mbo_valid |= OBD_MD_FLCKSPLIT;
if (op_data->op_bias & MDS_CROSS_REF)
- b->valid |= OBD_MD_FLCROSSREF;
- b->eadatasize = ea_size;
- b->flags = flags;
+ b->mbo_valid |= OBD_MD_FLCROSSREF;
+ b->mbo_eadatasize = ea_size;
+ b->mbo_flags = flags;
__mdc_pack_body(b, op_data->op_suppgids[0]);
- b->fid1 = op_data->op_fid1;
- b->fid2 = op_data->op_fid2;
- b->valid |= OBD_MD_FLID;
-
- if (op_data->op_name) {
- char *tmp = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
+ b->mbo_fid1 = op_data->op_fid1;
+ b->mbo_fid2 = op_data->op_fid2;
+ b->mbo_valid |= OBD_MD_FLID;
- LOGL0(op_data->op_name, op_data->op_namelen, tmp);
- }
+ if (op_data->op_name)
+ mdc_pack_name(req, &RMF_NAME, op_data->op_name,
+ op_data->op_namelen);
}
static void mdc_hsm_release_pack(struct ptlrpc_request *req,
@@ -482,67 +486,3 @@ void mdc_close_pack(struct ptlrpc_request *req, struct md_op_data *op_data)
mdc_ioepoch_pack(epoch, op_data);
mdc_hsm_release_pack(req, op_data);
}
-
-static int mdc_req_avail(struct client_obd *cli, struct mdc_cache_waiter *mcw)
-{
- int rc;
-
- spin_lock(&cli->cl_loi_list_lock);
- rc = list_empty(&mcw->mcw_entry);
- spin_unlock(&cli->cl_loi_list_lock);
- return rc;
-};
-
-/* We record requests in flight in cli->cl_r_in_flight here.
- * There is only one write rpc possible in mdc anyway. If this to change
- * in the future - the code may need to be revisited.
- */
-int mdc_enter_request(struct client_obd *cli)
-{
- int rc = 0;
- struct mdc_cache_waiter mcw;
- struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
-
- spin_lock(&cli->cl_loi_list_lock);
- if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) {
- list_add_tail(&mcw.mcw_entry, &cli->cl_cache_waiters);
- init_waitqueue_head(&mcw.mcw_waitq);
- spin_unlock(&cli->cl_loi_list_lock);
- rc = l_wait_event(mcw.mcw_waitq, mdc_req_avail(cli, &mcw),
- &lwi);
- if (rc) {
- spin_lock(&cli->cl_loi_list_lock);
- if (list_empty(&mcw.mcw_entry))
- cli->cl_r_in_flight--;
- list_del_init(&mcw.mcw_entry);
- spin_unlock(&cli->cl_loi_list_lock);
- }
- } else {
- cli->cl_r_in_flight++;
- spin_unlock(&cli->cl_loi_list_lock);
- }
- return rc;
-}
-
-void mdc_exit_request(struct client_obd *cli)
-{
- struct list_head *l, *tmp;
- struct mdc_cache_waiter *mcw;
-
- spin_lock(&cli->cl_loi_list_lock);
- cli->cl_r_in_flight--;
- list_for_each_safe(l, tmp, &cli->cl_cache_waiters) {
- if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) {
- /* No free request slots anymore */
- break;
- }
-
- mcw = list_entry(l, struct mdc_cache_waiter, mcw_entry);
- list_del_init(&mcw->mcw_entry);
- cli->cl_r_in_flight++;
- wake_up(&mcw->mcw_waitq);
- }
- /* Empty waiting list? Decrease reqs in-flight number */
-
- spin_unlock(&cli->cl_loi_list_lock);
-}
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c
index f48b58423307..f1f6c082fa42 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c
@@ -93,8 +93,8 @@ int it_open_error(int phase, struct lookup_intent *it)
EXPORT_SYMBOL(it_open_error);
/* this must be called on a lockh that is known to have a referenced lock */
-int mdc_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data,
- __u64 *bits)
+int mdc_set_lock_data(struct obd_export *exp, const struct lustre_handle *lockh,
+ void *data, __u64 *bits)
{
struct ldlm_lock *lock;
struct inode *new_inode = data;
@@ -102,10 +102,10 @@ int mdc_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data,
if (bits)
*bits = 0;
- if (!*lockh)
+ if (!lustre_handle_is_used(lockh))
return 0;
- lock = ldlm_handle2lock((struct lustre_handle *)lockh);
+ lock = ldlm_handle2lock(lockh);
LASSERT(lock);
lock_res_and_lock(lock);
@@ -174,7 +174,7 @@ int mdc_null_inode(struct obd_export *exp,
fid_build_reg_res_name(fid, &res_id);
res = ldlm_resource_get(ns, NULL, &res_id, 0, 0);
- if (!res)
+ if (IS_ERR(res))
return 0;
lock_res(res);
@@ -185,28 +185,6 @@ int mdc_null_inode(struct obd_export *exp,
return 0;
}
-/* find any ldlm lock of the inode in mdc
- * return 0 not find
- * 1 find one
- * < 0 error
- */
-int mdc_find_cbdata(struct obd_export *exp,
- const struct lu_fid *fid,
- ldlm_iterator_t it, void *data)
-{
- struct ldlm_res_id res_id;
- int rc = 0;
-
- fid_build_reg_res_name((struct lu_fid *)fid, &res_id);
- rc = ldlm_resource_iterate(class_exp2obd(exp)->obd_namespace, &res_id,
- it, data);
- if (rc == LDLM_ITER_STOP)
- return 1;
- else if (rc == LDLM_ITER_CONTINUE)
- return 0;
- return rc;
-}
-
static inline void mdc_clear_replay_flag(struct ptlrpc_request *req, int rc)
{
/* Don't hold error requests for replay. */
@@ -240,24 +218,24 @@ static void mdc_realloc_openmsg(struct ptlrpc_request *req,
/* FIXME: remove this explicit offset. */
rc = sptlrpc_cli_enlarge_reqbuf(req, DLM_INTENT_REC_OFF + 4,
- body->eadatasize);
+ body->mbo_eadatasize);
if (rc) {
CERROR("Can't enlarge segment %d size to %d\n",
- DLM_INTENT_REC_OFF + 4, body->eadatasize);
- body->valid &= ~OBD_MD_FLEASIZE;
- body->eadatasize = 0;
+ DLM_INTENT_REC_OFF + 4, body->mbo_eadatasize);
+ body->mbo_valid &= ~OBD_MD_FLEASIZE;
+ body->mbo_eadatasize = 0;
}
}
-static struct ptlrpc_request *mdc_intent_open_pack(struct obd_export *exp,
- struct lookup_intent *it,
- struct md_op_data *op_data,
- void *lmm, int lmmsize,
- void *cb_data)
+static struct ptlrpc_request *
+mdc_intent_open_pack(struct obd_export *exp, struct lookup_intent *it,
+ struct md_op_data *op_data)
{
struct ptlrpc_request *req;
struct obd_device *obddev = class_exp2obd(exp);
struct ldlm_intent *lit;
+ const void *lmm = op_data->op_data;
+ u32 lmmsize = op_data->op_data_size;
LIST_HEAD(cancels);
int count = 0;
int mode;
@@ -274,7 +252,7 @@ static struct ptlrpc_request *mdc_intent_open_pack(struct obd_export *exp,
else
mode = LCK_PR;
} else {
- if (it->it_flags & (FMODE_WRITE|MDS_OPEN_TRUNC))
+ if (it->it_flags & (FMODE_WRITE | MDS_OPEN_TRUNC))
mode = LCK_CW;
else if (it->it_flags & __FMODE_EXEC)
mode = LCK_PR;
@@ -325,6 +303,9 @@ static struct ptlrpc_request *mdc_intent_open_pack(struct obd_export *exp,
mdc_open_pack(req, op_data, it->it_create_mode, 0, it->it_flags, lmm,
lmmsize);
+ req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER,
+ obddev->u.cli.cl_max_mds_easize);
+
ptlrpc_request_set_replen(req);
return req;
}
@@ -336,7 +317,8 @@ mdc_intent_getxattr_pack(struct obd_export *exp,
{
struct ptlrpc_request *req;
struct ldlm_intent *lit;
- int rc, count = 0, maxdata;
+ int rc, count = 0;
+ u32 maxdata;
LIST_HEAD(cancels);
req = ptlrpc_request_alloc(class_exp2cliimp(exp),
@@ -421,7 +403,7 @@ static struct ptlrpc_request *mdc_intent_getattr_pack(struct obd_export *exp,
OBD_MD_MEA | OBD_MD_FLACL;
struct ldlm_intent *lit;
int rc;
- int easize;
+ u32 easize;
req = ptlrpc_request_alloc(class_exp2cliimp(exp),
&RQF_LDLM_INTENT_GETATTR);
@@ -526,7 +508,7 @@ static int mdc_finish_enqueue(struct obd_export *exp,
struct ldlm_reply *lockrep;
struct ldlm_lock *lock;
void *lvb_data = NULL;
- int lvb_len = 0;
+ u32 lvb_len = 0;
LASSERT(rc >= 0);
/* Similarly, if we're going to replay this request, we don't want to
@@ -605,7 +587,7 @@ static int mdc_finish_enqueue(struct obd_export *exp,
mdc_set_open_replay_data(NULL, NULL, it);
}
- if ((body->valid & (OBD_MD_FLDIREA | OBD_MD_FLEASIZE)) != 0) {
+ if ((body->mbo_valid & (OBD_MD_FLDIREA | OBD_MD_FLEASIZE)) != 0) {
void *eadata;
mdc_update_max_ea_from_body(exp, body);
@@ -615,7 +597,7 @@ static int mdc_finish_enqueue(struct obd_export *exp,
* Eventually, obd_unpackmd() will check the contents.
*/
eadata = req_capsule_server_sized_get(pill, &RMF_MDT_MD,
- body->eadatasize);
+ body->mbo_eadatasize);
if (!eadata)
return -EPROTO;
@@ -623,7 +605,7 @@ static int mdc_finish_enqueue(struct obd_export *exp,
* lock
*/
lvb_data = eadata;
- lvb_len = body->eadatasize;
+ lvb_len = body->mbo_eadatasize;
/*
* We save the reply LOV EA in case we have to replay a
@@ -639,20 +621,20 @@ static int mdc_finish_enqueue(struct obd_export *exp,
if (req_capsule_get_size(pill, &RMF_EADATA,
RCL_CLIENT) <
- body->eadatasize)
+ body->mbo_eadatasize)
mdc_realloc_openmsg(req, body);
else
req_capsule_shrink(pill, &RMF_EADATA,
- body->eadatasize,
+ body->mbo_eadatasize,
RCL_CLIENT);
req_capsule_set_size(pill, &RMF_EADATA,
RCL_CLIENT,
- body->eadatasize);
+ body->mbo_eadatasize);
lmm = req_capsule_client_get(pill, &RMF_EADATA);
if (lmm)
- memcpy(lmm, eadata, body->eadatasize);
+ memcpy(lmm, eadata, body->mbo_eadatasize);
}
}
} else if (it->it_op & IT_LAYOUT) {
@@ -662,7 +644,8 @@ static int mdc_finish_enqueue(struct obd_export *exp,
lvb_len = req_capsule_get_size(pill, &RMF_DLM_LVB, RCL_SERVER);
if (lvb_len > 0) {
lvb_data = req_capsule_server_sized_get(pill,
- &RMF_DLM_LVB, lvb_len);
+ &RMF_DLM_LVB,
+ lvb_len);
if (!lvb_data)
return -EPROTO;
}
@@ -705,9 +688,9 @@ static int mdc_finish_enqueue(struct obd_export *exp,
* we don't know in advance the file type.
*/
int mdc_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo,
+ const ldlm_policy_data_t *policy,
struct lookup_intent *it, struct md_op_data *op_data,
- struct lustre_handle *lockh, void *lmm, int lmmsize,
- struct ptlrpc_request **reqp, u64 extra_lock_flags)
+ struct lustre_handle *lockh, u64 extra_lock_flags)
{
static const ldlm_policy_data_t lookup_policy = {
.l_inodebits = { MDS_INODELOCK_LOOKUP }
@@ -721,9 +704,8 @@ int mdc_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo,
static const ldlm_policy_data_t getxattr_policy = {
.l_inodebits = { MDS_INODELOCK_XATTR }
};
- ldlm_policy_data_t const *policy = &lookup_policy;
struct obd_device *obddev = class_exp2obd(exp);
- struct ptlrpc_request *req;
+ struct ptlrpc_request *req = NULL;
u64 flags, saved_flags = extra_lock_flags;
struct ldlm_res_id res_id;
int generation, resends = 0;
@@ -733,40 +715,32 @@ int mdc_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo,
LASSERTF(!it || einfo->ei_type == LDLM_IBITS, "lock type %d\n",
einfo->ei_type);
-
fid_build_reg_res_name(&op_data->op_fid1, &res_id);
if (it) {
+ LASSERT(!policy);
+
saved_flags |= LDLM_FL_HAS_INTENT;
- if (it->it_op & (IT_UNLINK | IT_GETATTR | IT_READDIR))
+ if (it->it_op & (IT_OPEN | IT_UNLINK | IT_GETATTR | IT_READDIR))
policy = &update_policy;
else if (it->it_op & IT_LAYOUT)
policy = &layout_policy;
else if (it->it_op & (IT_GETXATTR | IT_SETXATTR))
policy = &getxattr_policy;
+ else
+ policy = &lookup_policy;
}
- LASSERT(!reqp);
-
generation = obddev->u.cli.cl_import->imp_generation;
resend:
flags = saved_flags;
if (!it) {
- /* The only way right now is FLOCK, in this case we hide flock
- * policy as lmm, but lmmsize is 0
- */
- LASSERT(lmm && lmmsize == 0);
+ /* The only way right now is FLOCK. */
LASSERTF(einfo->ei_type == LDLM_FLOCK, "lock type %d\n",
einfo->ei_type);
- policy = lmm;
res_id.name[3] = LDLM_FLOCK;
- req = NULL;
} else if (it->it_op & IT_OPEN) {
- req = mdc_intent_open_pack(exp, it, op_data, lmm, lmmsize,
- einfo->ei_cbdata);
- policy = &update_policy;
- einfo->ei_cbdata = NULL;
- lmm = NULL;
+ req = mdc_intent_open_pack(exp, it, op_data);
} else if (it->it_op & IT_UNLINK) {
req = mdc_intent_unlink_pack(exp, it, op_data);
} else if (it->it_op & (IT_GETATTR | IT_LOOKUP)) {
@@ -806,7 +780,7 @@ resend:
*/
if (it) {
mdc_get_rpc_lock(obddev->u.cli.cl_rpc_lock, it);
- rc = mdc_enter_request(&obddev->u.cli);
+ rc = obd_get_request_slot(&obddev->u.cli);
if (rc != 0) {
mdc_put_rpc_lock(obddev->u.cli.cl_rpc_lock, it);
mdc_clear_replay_flag(req, 0);
@@ -834,13 +808,12 @@ resend:
return rc;
}
- mdc_exit_request(&obddev->u.cli);
+ obd_put_request_slot(&obddev->u.cli);
mdc_put_rpc_lock(obddev->u.cli.cl_rpc_lock, it);
if (rc < 0) {
- CDEBUG_LIMIT((rc == -EACCES || rc == -EIDRM) ? D_INFO : D_ERROR,
- "%s: ldlm_cli_enqueue failed: rc = %d\n",
- obddev->obd_name, rc);
+ CDEBUG(D_INFO, "%s: ldlm_cli_enqueue failed: rc = %d\n",
+ obddev->obd_name, rc);
mdc_clear_replay_flag(req, rc);
ptlrpc_req_finished(req);
@@ -903,6 +876,9 @@ static int mdc_finish_intent_lock(struct obd_export *exp,
LASSERT(request != LP_POISON);
LASSERT(request->rq_repmsg != LP_POISON);
+ if (it->it_op & IT_READDIR)
+ return 0;
+
if (!it_disposition(it, DISP_IT_EXECD)) {
/* The server failed before it even started executing the
* intent, i.e. because it couldn't unpack the request.
@@ -917,27 +893,6 @@ static int mdc_finish_intent_lock(struct obd_export *exp,
mdt_body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY);
LASSERT(mdt_body); /* mdc_enqueue checked */
- /* If we were revalidating a fid/name pair, mark the intent in
- * case we fail and get called again from lookup
- */
- if (fid_is_sane(&op_data->op_fid2) &&
- it->it_create_mode & M_CHECK_STALE &&
- it->it_op != IT_GETATTR) {
- /* Also: did we find the same inode? */
- /* sever can return one of two fids:
- * op_fid2 - new allocated fid - if file is created.
- * op_fid3 - existent fid - if file only open.
- * op_fid3 is saved in lmv_intent_open
- */
- if ((!lu_fid_eq(&op_data->op_fid2, &mdt_body->fid1)) &&
- (!lu_fid_eq(&op_data->op_fid3, &mdt_body->fid1))) {
- CDEBUG(D_DENTRY, "Found stale data "DFID"("DFID")/"DFID
- "\n", PFID(&op_data->op_fid2),
- PFID(&op_data->op_fid2), PFID(&mdt_body->fid1));
- return -ESTALE;
- }
- }
-
rc = it_open_error(DISP_LOOKUP_EXECD, it);
if (rc)
return rc;
@@ -980,10 +935,10 @@ static int mdc_finish_intent_lock(struct obd_export *exp,
LDLM_DEBUG(lock, "matching against this");
- LASSERTF(fid_res_name_eq(&mdt_body->fid1,
+ LASSERTF(fid_res_name_eq(&mdt_body->mbo_fid1,
&lock->l_resource->lr_name),
"Lock res_id: "DLDLMRES", fid: "DFID"\n",
- PLDLMRES(lock->l_resource), PFID(&mdt_body->fid1));
+ PLDLMRES(lock->l_resource), PFID(&mdt_body->mbo_fid1));
LDLM_LOCK_PUT(lock);
memcpy(&old_lock, lockh, sizeof(*lockh));
@@ -998,8 +953,8 @@ static int mdc_finish_intent_lock(struct obd_export *exp,
}
CDEBUG(D_DENTRY,
"D_IT dentry %.*s intent: %s status %d disp %x rc %d\n",
- op_data->op_namelen, op_data->op_name, ldlm_it2str(it->it_op),
- it->it_status, it->it_disposition, rc);
+ (int)op_data->op_namelen, op_data->op_name,
+ ldlm_it2str(it->it_op), it->it_status, it->it_disposition, rc);
return rc;
}
@@ -1042,6 +997,9 @@ int mdc_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
MDS_INODELOCK_LOOKUP |
MDS_INODELOCK_PERM;
break;
+ case IT_READDIR:
+ policy.l_inodebits.bits = MDS_INODELOCK_UPDATE;
+ break;
case IT_LAYOUT:
policy.l_inodebits.bits = MDS_INODELOCK_LAYOUT;
break;
@@ -1095,10 +1053,8 @@ int mdc_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
* child lookup.
*/
int mdc_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
- void *lmm, int lmmsize, struct lookup_intent *it,
- int lookup_flags, struct ptlrpc_request **reqp,
- ldlm_blocking_callback cb_blocking,
- __u64 extra_lock_flags)
+ struct lookup_intent *it, struct ptlrpc_request **reqp,
+ ldlm_blocking_callback cb_blocking, __u64 extra_lock_flags)
{
struct ldlm_enqueue_info einfo = {
.ei_type = LDLM_IBITS,
@@ -1112,14 +1068,14 @@ int mdc_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
LASSERT(it);
CDEBUG(D_DLMTRACE, "(name: %.*s,"DFID") in obj "DFID
- ", intent: %s flags %#Lo\n", op_data->op_namelen,
+ ", intent: %s flags %#Lo\n", (int)op_data->op_namelen,
op_data->op_name, PFID(&op_data->op_fid2),
PFID(&op_data->op_fid1), ldlm_it2str(it->it_op),
it->it_flags);
lockh.cookie = 0;
if (fid_is_sane(&op_data->op_fid2) &&
- (it->it_op & (IT_LOOKUP | IT_GETATTR))) {
+ (it->it_op & (IT_LOOKUP | IT_GETATTR | IT_READDIR))) {
/* We could just return 1 immediately, but since we should only
* be called in revalidate_it if we already have a lock, let's
* verify that.
@@ -1135,13 +1091,13 @@ int mdc_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
/* For case if upper layer did not alloc fid, do it now. */
if (!fid_is_sane(&op_data->op_fid2) && it->it_op & IT_CREAT) {
- rc = mdc_fid_alloc(exp, &op_data->op_fid2, op_data);
+ rc = mdc_fid_alloc(NULL, exp, &op_data->op_fid2, op_data);
if (rc < 0) {
CERROR("Can't alloc new fid, rc %d\n", rc);
return rc;
}
}
- rc = mdc_enqueue(exp, &einfo, it, op_data, &lockh, lmm, lmmsize, NULL,
+ rc = mdc_enqueue(exp, &einfo, NULL, it, op_data, &lockh,
extra_lock_flags);
if (rc < 0)
return rc;
@@ -1170,7 +1126,7 @@ static int mdc_intent_getattr_async_interpret(const struct lu_env *env,
obddev = class_exp2obd(exp);
- mdc_exit_request(&obddev->u.cli);
+ obd_put_request_slot(&obddev->u.cli);
if (OBD_FAIL_CHECK(OBD_FAIL_MDC_GETATTR_ENQUEUE))
rc = -ETIMEDOUT;
@@ -1222,15 +1178,15 @@ int mdc_intent_getattr_async(struct obd_export *exp,
CDEBUG(D_DLMTRACE,
"name: %.*s in inode " DFID ", intent: %s flags %#Lo\n",
- op_data->op_namelen, op_data->op_name, PFID(&op_data->op_fid1),
- ldlm_it2str(it->it_op), it->it_flags);
+ (int)op_data->op_namelen, op_data->op_name,
+ PFID(&op_data->op_fid1), ldlm_it2str(it->it_op), it->it_flags);
fid_build_reg_res_name(&op_data->op_fid1, &res_id);
req = mdc_intent_getattr_pack(exp, it, op_data);
if (IS_ERR(req))
return PTR_ERR(req);
- rc = mdc_enter_request(&obddev->u.cli);
+ rc = obd_get_request_slot(&obddev->u.cli);
if (rc != 0) {
ptlrpc_req_finished(req);
return rc;
@@ -1239,7 +1195,7 @@ int mdc_intent_getattr_async(struct obd_export *exp,
rc = ldlm_cli_enqueue(exp, &req, einfo, &res_id, &policy, &flags, NULL,
0, LVB_T_NONE, &minfo->mi_lockh, 1);
if (rc < 0) {
- mdc_exit_request(&obddev->u.cli);
+ obd_put_request_slot(&obddev->u.cli);
ptlrpc_req_finished(req);
return rc;
}
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_reint.c b/drivers/staging/lustre/lustre/mdc/mdc_reint.c
index 5dba2c813857..c921e471fa27 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_reint.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_reint.c
@@ -86,7 +86,7 @@ int mdc_resource_get_unused(struct obd_export *exp, const struct lu_fid *fid,
fid_build_reg_res_name(fid, &res_id);
res = ldlm_resource_get(exp->exp_obd->obd_namespace,
NULL, &res_id, 0, 0);
- if (!res)
+ if (IS_ERR(res))
return 0;
LDLM_RESOURCE_ADDREF(res);
/* Initialize ibits lock policy. */
@@ -99,7 +99,7 @@ int mdc_resource_get_unused(struct obd_export *exp, const struct lu_fid *fid,
}
int mdc_setattr(struct obd_export *exp, struct md_op_data *op_data,
- void *ea, int ealen, void *ea2, int ea2len,
+ void *ea, size_t ealen, void *ea2, size_t ea2len,
struct ptlrpc_request **request, struct md_open_data **mod)
{
LIST_HEAD(cancels);
@@ -110,11 +110,10 @@ int mdc_setattr(struct obd_export *exp, struct md_op_data *op_data,
__u64 bits;
bits = MDS_INODELOCK_UPDATE;
- if (op_data->op_attr.ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID))
+ if (op_data->op_attr.ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
bits |= MDS_INODELOCK_LOOKUP;
if ((op_data->op_flags & MF_MDC_CANCEL_FID1) &&
- (fid_is_sane(&op_data->op_fid1)) &&
- !OBD_FAIL_CHECK(OBD_FAIL_LDLM_BL_CALLBACK_NET))
+ (fid_is_sane(&op_data->op_fid1)))
count = mdc_resource_get_unused(exp, &op_data->op_fid1,
&cancels, LCK_EX, bits);
req = ptlrpc_request_alloc(class_exp2cliimp(exp),
@@ -177,8 +176,8 @@ int mdc_setattr(struct obd_export *exp, struct md_op_data *op_data,
epoch = req_capsule_client_get(&req->rq_pill, &RMF_MDT_EPOCH);
body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
- epoch->handle = body->handle;
- epoch->ioepoch = body->ioepoch;
+ epoch->handle = body->mbo_handle;
+ epoch->ioepoch = body->mbo_ioepoch;
req->rq_replay_cb = mdc_replay_open;
/** bug 3633, open may be committed and estale answer is not error */
} else if (rc == -ESTALE && (op_data->op_flags & MF_SOM_CHANGE)) {
@@ -197,9 +196,9 @@ int mdc_setattr(struct obd_export *exp, struct md_op_data *op_data,
}
int mdc_create(struct obd_export *exp, struct md_op_data *op_data,
- const void *data, int datalen, int mode, __u32 uid, __u32 gid,
- cfs_cap_t cap_effective, __u64 rdev,
- struct ptlrpc_request **request)
+ const void *data, size_t datalen, umode_t mode,
+ uid_t uid, gid_t gid, cfs_cap_t cap_effective,
+ __u64 rdev, struct ptlrpc_request **request)
{
struct ptlrpc_request *req;
int level, rc;
@@ -214,11 +213,9 @@ int mdc_create(struct obd_export *exp, struct md_op_data *op_data,
* mdc_fid_alloc() may return errno 1 in case of switch to new
* sequence, handle this.
*/
- rc = mdc_fid_alloc(exp, &op_data->op_fid2, op_data);
- if (rc < 0) {
- CERROR("Can't alloc new fid, rc %d\n", rc);
+ rc = mdc_fid_alloc(NULL, exp, &op_data->op_fid2, op_data);
+ if (rc < 0)
return rc;
- }
}
rebuild:
@@ -307,14 +304,12 @@ int mdc_unlink(struct obd_export *exp, struct md_op_data *op_data,
LASSERT(!req);
if ((op_data->op_flags & MF_MDC_CANCEL_FID1) &&
- (fid_is_sane(&op_data->op_fid1)) &&
- !OBD_FAIL_CHECK(OBD_FAIL_LDLM_BL_CALLBACK_NET))
+ (fid_is_sane(&op_data->op_fid1)))
count = mdc_resource_get_unused(exp, &op_data->op_fid1,
&cancels, LCK_EX,
MDS_INODELOCK_UPDATE);
if ((op_data->op_flags & MF_MDC_CANCEL_FID3) &&
- (fid_is_sane(&op_data->op_fid3)) &&
- !OBD_FAIL_CHECK(OBD_FAIL_LDLM_BL_CALLBACK_NET))
+ (fid_is_sane(&op_data->op_fid3)))
count += mdc_resource_get_unused(exp, &op_data->op_fid3,
&cancels, LCK_EX,
MDS_INODELOCK_FULL);
@@ -394,7 +389,7 @@ int mdc_link(struct obd_export *exp, struct md_op_data *op_data,
}
int mdc_rename(struct obd_export *exp, struct md_op_data *op_data,
- const char *old, int oldlen, const char *new, int newlen,
+ const char *old, size_t oldlen, const char *new, size_t newlen,
struct ptlrpc_request **request)
{
LIST_HEAD(cancels);
@@ -431,7 +426,8 @@ int mdc_rename(struct obd_export *exp, struct md_op_data *op_data,
}
req_capsule_set_size(&req->rq_pill, &RMF_NAME, RCL_CLIENT, oldlen + 1);
- req_capsule_set_size(&req->rq_pill, &RMF_SYMTGT, RCL_CLIENT, newlen+1);
+ req_capsule_set_size(&req->rq_pill, &RMF_SYMTGT, RCL_CLIENT,
+ newlen + 1);
rc = mdc_prep_elc_req(exp, req, MDS_REINT, &cancels, count);
if (rc) {
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c
index 542801f04b0d..f56ea643f9bf 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_request.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c
@@ -39,7 +39,9 @@
# include <linux/utsname.h>
#include "../include/lustre_acl.h"
+#include "../include/lustre/lustre_ioctl.h"
#include "../include/obd_class.h"
+#include "../include/lustre_lmv.h"
#include "../include/lustre_fid.h"
#include "../include/lprocfs_status.h"
#include "../include/lustre_param.h"
@@ -57,16 +59,16 @@ static inline int mdc_queue_wait(struct ptlrpc_request *req)
struct client_obd *cli = &req->rq_import->imp_obd->u.cli;
int rc;
- /* mdc_enter_request() ensures that this client has no more
+ /* obd_get_request_slot() ensures that this client has no more
* than cl_max_rpcs_in_flight RPCs simultaneously inf light
* against an MDT.
*/
- rc = mdc_enter_request(cli);
+ rc = obd_get_request_slot(cli);
if (rc != 0)
return rc;
rc = ptlrpc_queue_wait(req);
- mdc_exit_request(cli);
+ obd_put_request_slot(cli);
return rc;
}
@@ -98,7 +100,7 @@ static int mdc_getstatus(struct obd_export *exp, struct lu_fid *rootfid)
goto out;
}
- *rootfid = body->fid1;
+ *rootfid = body->mbo_fid1;
CDEBUG(D_NET,
"root fid="DFID", last_committed=%llu\n",
PFID(rootfid),
@@ -136,12 +138,12 @@ static int mdc_getattr_common(struct obd_export *exp,
if (!body)
return -EPROTO;
- CDEBUG(D_NET, "mode: %o\n", body->mode);
+ CDEBUG(D_NET, "mode: %o\n", body->mbo_mode);
mdc_update_max_ea_from_body(exp, body);
- if (body->eadatasize != 0) {
+ if (body->mbo_eadatasize != 0) {
eadata = req_capsule_server_sized_get(pill, &RMF_MDT_MD,
- body->eadatasize);
+ body->mbo_eadatasize);
if (!eadata)
return -EPROTO;
}
@@ -230,32 +232,6 @@ static int mdc_getattr_name(struct obd_export *exp, struct md_op_data *op_data,
return rc;
}
-static int mdc_is_subdir(struct obd_export *exp,
- const struct lu_fid *pfid,
- const struct lu_fid *cfid,
- struct ptlrpc_request **request)
-{
- struct ptlrpc_request *req;
- int rc;
-
- *request = NULL;
- req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp),
- &RQF_MDS_IS_SUBDIR, LUSTRE_MDS_VERSION,
- MDS_IS_SUBDIR);
- if (!req)
- return -ENOMEM;
-
- mdc_is_subdir_pack(req, pfid, cfid, 0);
- ptlrpc_request_set_replen(req);
-
- rc = ptlrpc_queue_wait(req);
- if (rc && rc != -EREMOTE)
- ptlrpc_req_finished(req);
- else
- *request = req;
- return rc;
-}
-
static int mdc_xattr_common(struct obd_export *exp,
const struct req_format *fmt,
const struct lu_fid *fid,
@@ -397,15 +373,15 @@ static int mdc_unpack_acl(struct ptlrpc_request *req, struct lustre_md *md)
void *buf;
int rc;
- if (!body->aclsize)
+ if (!body->mbo_aclsize)
return 0;
- buf = req_capsule_server_sized_get(pill, &RMF_ACL, body->aclsize);
+ buf = req_capsule_server_sized_get(pill, &RMF_ACL, body->mbo_aclsize);
if (!buf)
return -EPROTO;
- acl = posix_acl_from_xattr(&init_user_ns, buf, body->aclsize);
+ acl = posix_acl_from_xattr(&init_user_ns, buf, body->mbo_aclsize);
if (!acl)
return 0;
@@ -443,24 +419,24 @@ static int mdc_get_lustre_md(struct obd_export *exp,
md->body = req_capsule_server_get(pill, &RMF_MDT_BODY);
- if (md->body->valid & OBD_MD_FLEASIZE) {
+ if (md->body->mbo_valid & OBD_MD_FLEASIZE) {
int lmmsize;
struct lov_mds_md *lmm;
- if (!S_ISREG(md->body->mode)) {
+ if (!S_ISREG(md->body->mbo_mode)) {
CDEBUG(D_INFO,
"OBD_MD_FLEASIZE set, should be a regular file, but is not\n");
rc = -EPROTO;
goto out;
}
- if (md->body->eadatasize == 0) {
+ if (md->body->mbo_eadatasize == 0) {
CDEBUG(D_INFO,
"OBD_MD_FLEASIZE set, but eadatasize 0\n");
rc = -EPROTO;
goto out;
}
- lmmsize = md->body->eadatasize;
+ lmmsize = md->body->mbo_eadatasize;
lmm = req_capsule_server_sized_get(pill, &RMF_MDT_MD, lmmsize);
if (!lmm) {
rc = -EPROTO;
@@ -471,7 +447,7 @@ static int mdc_get_lustre_md(struct obd_export *exp,
if (rc < 0)
goto out;
- if (rc < sizeof(*md->lsm)) {
+ if (rc < (typeof(rc))sizeof(*md->lsm)) {
CDEBUG(D_INFO,
"lsm size too small: rc < sizeof (*md->lsm) (%d < %d)\n",
rc, (int)sizeof(*md->lsm));
@@ -479,24 +455,24 @@ static int mdc_get_lustre_md(struct obd_export *exp,
goto out;
}
- } else if (md->body->valid & OBD_MD_FLDIREA) {
+ } else if (md->body->mbo_valid & OBD_MD_FLDIREA) {
int lmvsize;
struct lov_mds_md *lmv;
- if (!S_ISDIR(md->body->mode)) {
+ if (!S_ISDIR(md->body->mbo_mode)) {
CDEBUG(D_INFO,
"OBD_MD_FLDIREA set, should be a directory, but is not\n");
rc = -EPROTO;
goto out;
}
- if (md->body->eadatasize == 0) {
+ if (md->body->mbo_eadatasize == 0) {
CDEBUG(D_INFO,
"OBD_MD_FLDIREA is set, but eadatasize 0\n");
return -EPROTO;
}
- if (md->body->valid & OBD_MD_MEA) {
- lmvsize = md->body->eadatasize;
+ if (md->body->mbo_valid & OBD_MD_MEA) {
+ lmvsize = md->body->mbo_eadatasize;
lmv = req_capsule_server_sized_get(pill, &RMF_MDT_MD,
lmvsize);
if (!lmv) {
@@ -504,15 +480,15 @@ static int mdc_get_lustre_md(struct obd_export *exp,
goto out;
}
- rc = obd_unpackmd(md_exp, (void *)&md->mea, lmv,
+ rc = obd_unpackmd(md_exp, (void *)&md->lmv, lmv,
lmvsize);
if (rc < 0)
goto out;
- if (rc < sizeof(*md->mea)) {
+ if (rc < (typeof(rc))sizeof(*md->lmv)) {
CDEBUG(D_INFO,
- "size too small: rc < sizeof(*md->mea) (%d < %d)\n",
- rc, (int)sizeof(*md->mea));
+ "size too small: rc < sizeof(*md->lmv) (%d < %d)\n",
+ rc, (int)sizeof(*md->lmv));
rc = -EPROTO;
goto out;
}
@@ -520,12 +496,12 @@ static int mdc_get_lustre_md(struct obd_export *exp,
}
rc = 0;
- if (md->body->valid & OBD_MD_FLACL) {
+ if (md->body->mbo_valid & OBD_MD_FLACL) {
/* for ACL, it's possible that FLACL is set but aclsize is zero.
* only when aclsize != 0 there's an actual segment for ACL
* in reply buffer.
*/
- if (md->body->aclsize) {
+ if (md->body->mbo_aclsize) {
rc = mdc_unpack_acl(req, md);
if (rc)
goto out;
@@ -580,9 +556,9 @@ void mdc_replay_open(struct ptlrpc_request *req)
file_fh = &och->och_fh;
CDEBUG(D_HA, "updating handle from %#llx to %#llx\n",
- file_fh->cookie, body->handle.cookie);
+ file_fh->cookie, body->mbo_handle.cookie);
old = *file_fh;
- *file_fh = body->handle;
+ *file_fh = body->mbo_handle;
}
close_req = mod->mod_close_req;
if (close_req) {
@@ -597,7 +573,7 @@ void mdc_replay_open(struct ptlrpc_request *req)
if (och)
LASSERT(!memcmp(&old, &epoch->handle, sizeof(old)));
DEBUG_REQ(D_HA, close_req, "updating close body with new fh");
- epoch->handle = body->handle;
+ epoch->handle = body->mbo_handle;
}
}
@@ -679,11 +655,11 @@ int mdc_set_open_replay_data(struct obd_export *exp,
spin_unlock(&open_req->rq_lock);
}
- rec->cr_fid2 = body->fid1;
- rec->cr_ioepoch = body->ioepoch;
- rec->cr_old_handle.cookie = body->handle.cookie;
+ rec->cr_fid2 = body->mbo_fid1;
+ rec->cr_ioepoch = body->mbo_ioepoch;
+ rec->cr_old_handle.cookie = body->mbo_handle.cookie;
open_req->rq_replay_cb = mdc_replay_open;
- if (!fid_is_sane(&body->fid1)) {
+ if (!fid_is_sane(&body->mbo_fid1)) {
DEBUG_REQ(D_ERROR, open_req,
"Saving replay request with insane fid");
LBUG();
@@ -701,9 +677,15 @@ static void mdc_free_open(struct md_open_data *mod)
imp_connect_disp_stripe(mod->mod_open_req->rq_import))
committed = 1;
- LASSERT(mod->mod_open_req->rq_replay == 0);
-
- DEBUG_REQ(D_RPCTRACE, mod->mod_open_req, "free open request\n");
+ /*
+ * No reason to asssert here if the open request has
+ * rq_replay == 1. It means that mdc_close failed, and
+ * close request wasn`t sent. It is not fatal to client.
+ * The worst thing is eviction if the client gets open lock
+ */
+ DEBUG_REQ(D_RPCTRACE, mod->mod_open_req,
+ "free open request rq_replay = %d\n",
+ mod->mod_open_req->rq_replay);
ptlrpc_request_committed(mod->mod_open_req, committed);
if (mod->mod_close_req)
@@ -744,7 +726,7 @@ static void mdc_close_handle_reply(struct ptlrpc_request *req,
epoch = req_capsule_client_get(&req->rq_pill, &RMF_MDT_EPOCH);
epoch->flags |= MF_SOM_AU;
- if (repbody->valid & OBD_MD_FLGETATTRLOCK)
+ if (repbody->mbo_valid & OBD_MD_FLGETATTRLOCK)
op_data->op_flags |= MF_GETATTR_LOCK;
}
}
@@ -763,7 +745,7 @@ static int mdc_close(struct obd_export *exp, struct md_op_data *op_data,
req_fmt = &RQF_MDS_RELEASE_CLOSE;
/* allocate a FID for volatile file */
- rc = mdc_fid_alloc(exp, &op_data->op_fid2, op_data);
+ rc = mdc_fid_alloc(NULL, exp, &op_data->op_fid2, op_data);
if (rc < 0) {
CERROR("%s: "DFID" failed to allocate FID: %d\n",
obd->obd_name, PFID(&op_data->op_fid1), rc);
@@ -773,22 +755,10 @@ static int mdc_close(struct obd_export *exp, struct md_op_data *op_data,
}
*request = NULL;
- req = ptlrpc_request_alloc(class_exp2cliimp(exp), req_fmt);
- if (!req)
- return -ENOMEM;
-
- rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, MDS_CLOSE);
- if (rc) {
- ptlrpc_request_free(req);
- return rc;
- }
-
- /* To avoid a livelock (bug 7034), we need to send CLOSE RPCs to a
- * portal whose threads are not taking any DLM locks and are therefore
- * always progressing
- */
- req->rq_request_portal = MDS_READPAGE_PORTAL;
- ptlrpc_at_set_req_timeout(req);
+ if (OBD_FAIL_CHECK(OBD_FAIL_MDC_CLOSE))
+ req = NULL;
+ else
+ req = ptlrpc_request_alloc(class_exp2cliimp(exp), req_fmt);
/* Ensure that this close's handle is fixed up during replay. */
if (likely(mod)) {
@@ -809,6 +779,29 @@ static int mdc_close(struct obd_export *exp, struct md_op_data *op_data,
CDEBUG(D_HA,
"couldn't find open req; expecting close error\n");
}
+ if (!req) {
+ /*
+ * TODO: repeat close after errors
+ */
+ CWARN("%s: close of FID "DFID" failed, file reference will be dropped when this client unmounts or is evicted\n",
+ obd->obd_name, PFID(&op_data->op_fid1));
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, MDS_CLOSE);
+ if (rc) {
+ ptlrpc_request_free(req);
+ goto out;
+ }
+
+ /*
+ * To avoid a livelock (bug 7034), we need to send CLOSE RPCs to a
+ * portal whose threads are not taking any DLM locks and are therefore
+ * always progressing
+ */
+ req->rq_request_portal = MDS_READPAGE_PORTAL;
+ ptlrpc_at_set_req_timeout(req);
mdc_close_pack(req, op_data);
@@ -854,6 +847,7 @@ static int mdc_close(struct obd_export *exp, struct md_op_data *op_data,
}
}
+out:
if (mod) {
if (rc != 0)
mod->mod_close_req = NULL;
@@ -936,16 +930,17 @@ static int mdc_done_writing(struct obd_export *exp, struct md_op_data *op_data,
return rc;
}
-static int mdc_readpage(struct obd_export *exp, struct md_op_data *op_data,
- struct page **pages, struct ptlrpc_request **request)
+static int mdc_getpage(struct obd_export *exp, const struct lu_fid *fid,
+ u64 offset, struct page **pages, int npages,
+ struct ptlrpc_request **request)
{
- struct ptlrpc_request *req;
struct ptlrpc_bulk_desc *desc;
- int i;
- wait_queue_head_t waitq;
- int resends = 0;
- struct l_wait_info lwi;
- int rc;
+ struct ptlrpc_request *req;
+ wait_queue_head_t waitq;
+ struct l_wait_info lwi;
+ int resends = 0;
+ int rc;
+ int i;
*request = NULL;
init_waitqueue_head(&waitq);
@@ -964,7 +959,7 @@ restart_bulk:
req->rq_request_portal = MDS_READPAGE_PORTAL;
ptlrpc_at_set_req_timeout(req);
- desc = ptlrpc_prep_bulk_imp(req, op_data->op_npages, 1, BULK_PUT_SINK,
+ desc = ptlrpc_prep_bulk_imp(req, npages, 1, BULK_PUT_SINK,
MDS_BULK_PORTAL);
if (!desc) {
ptlrpc_request_free(req);
@@ -972,12 +967,10 @@ restart_bulk:
}
/* NB req now owns desc and will free it when it gets freed */
- for (i = 0; i < op_data->op_npages; i++)
+ for (i = 0; i < npages; i++)
ptlrpc_prep_bulk_page_pin(desc, pages[i], 0, PAGE_SIZE);
- mdc_readdir_pack(req, op_data->op_offset,
- PAGE_SIZE * op_data->op_npages,
- &op_data->op_fid1);
+ mdc_readdir_pack(req, offset, PAGE_SIZE * npages, fid);
ptlrpc_request_set_replen(req);
rc = ptlrpc_queue_wait(req);
@@ -988,11 +981,12 @@ restart_bulk:
resends++;
if (!client_should_resend(resends, &exp->exp_obd->u.cli)) {
- CERROR("too many resend retries, returning error\n");
+ CERROR("%s: too many resend retries: rc = %d\n",
+ exp->exp_obd->obd_name, -EIO);
return -EIO;
}
- lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(resends),
- NULL, NULL, NULL);
+ lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(resends), NULL, NULL,
+ NULL);
l_wait_event(waitq, 0, &lwi);
goto restart_bulk;
@@ -1006,9 +1000,9 @@ restart_bulk:
}
if (req->rq_bulk->bd_nob_transferred & ~LU_PAGE_MASK) {
- CERROR("Unexpected # bytes transferred: %d (%ld expected)\n",
- req->rq_bulk->bd_nob_transferred,
- PAGE_SIZE * op_data->op_npages);
+ CERROR("%s: unexpected bytes transferred: %d (%ld expected)\n",
+ exp->exp_obd->obd_name, req->rq_bulk->bd_nob_transferred,
+ PAGE_SIZE * npages);
ptlrpc_req_finished(req);
return -EPROTO;
}
@@ -1017,6 +1011,453 @@ restart_bulk:
return 0;
}
+static void mdc_release_page(struct page *page, int remove)
+{
+ if (remove) {
+ lock_page(page);
+ if (likely(page->mapping))
+ truncate_complete_page(page->mapping, page);
+ unlock_page(page);
+ }
+ put_page(page);
+}
+
+static struct page *mdc_page_locate(struct address_space *mapping, __u64 *hash,
+ __u64 *start, __u64 *end, int hash64)
+{
+ /*
+ * Complement of hash is used as an index so that
+ * radix_tree_gang_lookup() can be used to find a page with starting
+ * hash _smaller_ than one we are looking for.
+ */
+ unsigned long offset = hash_x_index(*hash, hash64);
+ struct page *page;
+ int found;
+
+ spin_lock_irq(&mapping->tree_lock);
+ found = radix_tree_gang_lookup(&mapping->page_tree,
+ (void **)&page, offset, 1);
+ if (found > 0 && !radix_tree_exceptional_entry(page)) {
+ struct lu_dirpage *dp;
+
+ get_page(page);
+ spin_unlock_irq(&mapping->tree_lock);
+ /*
+ * In contrast to find_lock_page() we are sure that directory
+ * page cannot be truncated (while DLM lock is held) and,
+ * hence, can avoid restart.
+ *
+ * In fact, page cannot be locked here at all, because
+ * mdc_read_page_remote does synchronous io.
+ */
+ wait_on_page_locked(page);
+ if (PageUptodate(page)) {
+ dp = kmap(page);
+ if (BITS_PER_LONG == 32 && hash64) {
+ *start = le64_to_cpu(dp->ldp_hash_start) >> 32;
+ *end = le64_to_cpu(dp->ldp_hash_end) >> 32;
+ *hash = *hash >> 32;
+ } else {
+ *start = le64_to_cpu(dp->ldp_hash_start);
+ *end = le64_to_cpu(dp->ldp_hash_end);
+ }
+ if (unlikely(*start == 1 && *hash == 0))
+ *hash = *start;
+ else
+ LASSERTF(*start <= *hash, "start = %#llx,end = %#llx,hash = %#llx\n",
+ *start, *end, *hash);
+ CDEBUG(D_VFSTRACE, "offset %lx [%#llx %#llx], hash %#llx\n",
+ offset, *start, *end, *hash);
+ if (*hash > *end) {
+ kunmap(page);
+ mdc_release_page(page, 0);
+ page = NULL;
+ } else if (*end != *start && *hash == *end) {
+ /*
+ * upon hash collision, remove this page,
+ * otherwise put page reference, and
+ * mdc_read_page_remote() will issue RPC to
+ * fetch the page we want.
+ */
+ kunmap(page);
+ mdc_release_page(page,
+ le32_to_cpu(dp->ldp_flags) & LDF_COLLIDE);
+ page = NULL;
+ }
+ } else {
+ put_page(page);
+ page = ERR_PTR(-EIO);
+ }
+ } else {
+ spin_unlock_irq(&mapping->tree_lock);
+ page = NULL;
+ }
+ return page;
+}
+
+/*
+ * Adjust a set of pages, each page containing an array of lu_dirpages,
+ * so that each page can be used as a single logical lu_dirpage.
+ *
+ * A lu_dirpage is laid out as follows, where s = ldp_hash_start,
+ * e = ldp_hash_end, f = ldp_flags, p = padding, and each "ent" is a
+ * struct lu_dirent. It has size up to LU_PAGE_SIZE. The ldp_hash_end
+ * value is used as a cookie to request the next lu_dirpage in a
+ * directory listing that spans multiple pages (two in this example):
+ * ________
+ * | |
+ * .|--------v------- -----.
+ * |s|e|f|p|ent|ent| ... |ent|
+ * '--|-------------- -----' Each PAGE contains a single
+ * '------. lu_dirpage.
+ * .---------v------- -----.
+ * |s|e|f|p|ent| 0 | ... | 0 |
+ * '----------------- -----'
+ *
+ * However, on hosts where the native VM page size (PAGE_SIZE) is
+ * larger than LU_PAGE_SIZE, a single host page may contain multiple
+ * lu_dirpages. After reading the lu_dirpages from the MDS, the
+ * ldp_hash_end of the first lu_dirpage refers to the one immediately
+ * after it in the same PAGE (arrows simplified for brevity, but
+ * in general e0==s1, e1==s2, etc.):
+ *
+ * .-------------------- -----.
+ * |s0|e0|f0|p|ent|ent| ... |ent|
+ * |---v---------------- -----|
+ * |s1|e1|f1|p|ent|ent| ... |ent|
+ * |---v---------------- -----| Here, each PAGE contains
+ * ... multiple lu_dirpages.
+ * |---v---------------- -----|
+ * |s'|e'|f'|p|ent|ent| ... |ent|
+ * '---|---------------- -----'
+ * v
+ * .----------------------------.
+ * | next PAGE |
+ *
+ * This structure is transformed into a single logical lu_dirpage as follows:
+ *
+ * - Replace e0 with e' so the request for the next lu_dirpage gets the page
+ * labeled 'next PAGE'.
+ *
+ * - Copy the LDF_COLLIDE flag from f' to f0 to correctly reflect whether
+ * a hash collision with the next page exists.
+ *
+ * - Adjust the lde_reclen of the ending entry of each lu_dirpage to span
+ * to the first entry of the next lu_dirpage.
+ */
+#if PAGE_SIZE > LU_PAGE_SIZE
+static void mdc_adjust_dirpages(struct page **pages, int cfs_pgs, int lu_pgs)
+{
+ int i;
+
+ for (i = 0; i < cfs_pgs; i++) {
+ struct lu_dirpage *dp = kmap(pages[i]);
+ __u64 hash_end = le64_to_cpu(dp->ldp_hash_end);
+ __u32 flags = le32_to_cpu(dp->ldp_flags);
+ struct lu_dirpage *first = dp;
+ struct lu_dirent *end_dirent = NULL;
+ struct lu_dirent *ent;
+
+ while (--lu_pgs > 0) {
+ ent = lu_dirent_start(dp);
+ for (end_dirent = ent; ent;
+ end_dirent = ent, ent = lu_dirent_next(ent));
+
+ /* Advance dp to next lu_dirpage. */
+ dp = (struct lu_dirpage *)((char *)dp + LU_PAGE_SIZE);
+
+ /* Check if we've reached the end of the CFS_PAGE. */
+ if (!((unsigned long)dp & ~PAGE_MASK))
+ break;
+
+ /* Save the hash and flags of this lu_dirpage. */
+ hash_end = le64_to_cpu(dp->ldp_hash_end);
+ flags = le32_to_cpu(dp->ldp_flags);
+
+ /* Check if lu_dirpage contains no entries. */
+ if (!end_dirent)
+ break;
+
+ /*
+ * Enlarge the end entry lde_reclen from 0 to
+ * first entry of next lu_dirpage.
+ */
+ LASSERT(!le16_to_cpu(end_dirent->lde_reclen));
+ end_dirent->lde_reclen =
+ cpu_to_le16((char *)(dp->ldp_entries) -
+ (char *)end_dirent);
+ }
+
+ first->ldp_hash_end = hash_end;
+ first->ldp_flags &= ~cpu_to_le32(LDF_COLLIDE);
+ first->ldp_flags |= flags & cpu_to_le32(LDF_COLLIDE);
+
+ kunmap(pages[i]);
+ }
+ LASSERTF(lu_pgs == 0, "left = %d", lu_pgs);
+}
+#else
+#define mdc_adjust_dirpages(pages, cfs_pgs, lu_pgs) do {} while (0)
+#endif /* PAGE_SIZE > LU_PAGE_SIZE */
+
+/* parameters for readdir page */
+struct readpage_param {
+ struct md_op_data *rp_mod;
+ __u64 rp_off;
+ int rp_hash64;
+ struct obd_export *rp_exp;
+ struct md_callback *rp_cb;
+};
+
+/**
+ * Read pages from server.
+ *
+ * Page in MDS_READPAGE RPC is packed in LU_PAGE_SIZE, and each page contains
+ * a header lu_dirpage which describes the start/end hash, and whether this
+ * page is empty (contains no dir entry) or hash collide with next page.
+ * After client receives reply, several pages will be integrated into dir page
+ * in PAGE_SIZE (if PAGE_SIZE greater than LU_PAGE_SIZE), and the
+ * lu_dirpage for this integrated page will be adjusted.
+ **/
+static int mdc_read_page_remote(void *data, struct page *page0)
+{
+ struct readpage_param *rp = data;
+ struct page **page_pool;
+ struct page *page;
+ struct lu_dirpage *dp;
+ int rd_pgs = 0; /* number of pages read actually */
+ int npages;
+ struct md_op_data *op_data = rp->rp_mod;
+ struct ptlrpc_request *req;
+ int max_pages = op_data->op_max_pages;
+ struct inode *inode;
+ struct lu_fid *fid;
+ int i;
+ int rc;
+
+ LASSERT(max_pages > 0 && max_pages <= PTLRPC_MAX_BRW_PAGES);
+ inode = op_data->op_data;
+ fid = &op_data->op_fid1;
+ LASSERT(inode);
+
+ page_pool = kcalloc(max_pages, sizeof(page), GFP_NOFS);
+ if (page_pool) {
+ page_pool[0] = page0;
+ } else {
+ page_pool = &page0;
+ max_pages = 1;
+ }
+
+ for (npages = 1; npages < max_pages; npages++) {
+ page = page_cache_alloc_cold(inode->i_mapping);
+ if (!page)
+ break;
+ page_pool[npages] = page;
+ }
+
+ rc = mdc_getpage(rp->rp_exp, fid, rp->rp_off, page_pool, npages, &req);
+ if (!rc) {
+ int lu_pgs = req->rq_bulk->bd_nob_transferred;
+
+ rd_pgs = (req->rq_bulk->bd_nob_transferred +
+ PAGE_SIZE - 1) >> PAGE_SHIFT;
+ lu_pgs >>= LU_PAGE_SHIFT;
+ LASSERT(!(req->rq_bulk->bd_nob_transferred & ~LU_PAGE_MASK));
+
+ CDEBUG(D_INODE, "read %d(%d) pages\n", rd_pgs, lu_pgs);
+
+ mdc_adjust_dirpages(page_pool, rd_pgs, lu_pgs);
+
+ SetPageUptodate(page0);
+ }
+
+ unlock_page(page0);
+ ptlrpc_req_finished(req);
+ CDEBUG(D_CACHE, "read %d/%d pages\n", rd_pgs, npages);
+ for (i = 1; i < npages; i++) {
+ unsigned long offset;
+ __u64 hash;
+ int ret;
+
+ page = page_pool[i];
+
+ if (rc < 0 || i >= rd_pgs) {
+ put_page(page);
+ continue;
+ }
+
+ SetPageUptodate(page);
+
+ dp = kmap(page);
+ hash = le64_to_cpu(dp->ldp_hash_start);
+ kunmap(page);
+
+ offset = hash_x_index(hash, rp->rp_hash64);
+
+ prefetchw(&page->flags);
+ ret = add_to_page_cache_lru(page, inode->i_mapping, offset,
+ GFP_KERNEL);
+ if (!ret)
+ unlock_page(page);
+ else
+ CDEBUG(D_VFSTRACE, "page %lu add to page cache failed: rc = %d\n",
+ offset, ret);
+ put_page(page);
+ }
+
+ if (page_pool != &page0)
+ kfree(page_pool);
+
+ return rc;
+}
+
+/**
+ * Read dir page from cache first, if it can not find it, read it from
+ * server and add into the cache.
+ *
+ * \param[in] exp MDC export
+ * \param[in] op_data client MD stack parameters, transferring parameters
+ * between different layers on client MD stack.
+ * \param[in] cb_op callback required for ldlm lock enqueue during
+ * read page
+ * \param[in] hash_offset the hash offset of the page to be read
+ * \param[in] ppage the page to be read
+ *
+ * retval = 0 get the page successfully
+ * errno(<0) get the page failed
+ */
+static int mdc_read_page(struct obd_export *exp, struct md_op_data *op_data,
+ struct md_callback *cb_op, __u64 hash_offset,
+ struct page **ppage)
+{
+ struct lookup_intent it = { .it_op = IT_READDIR };
+ struct page *page;
+ struct inode *dir = op_data->op_data;
+ struct address_space *mapping;
+ struct lu_dirpage *dp;
+ __u64 start = 0;
+ __u64 end = 0;
+ struct lustre_handle lockh;
+ struct ptlrpc_request *enq_req = NULL;
+ struct readpage_param rp_param;
+ int rc;
+
+ *ppage = NULL;
+
+ LASSERT(dir);
+ mapping = dir->i_mapping;
+
+ rc = mdc_intent_lock(exp, op_data, &it, &enq_req,
+ cb_op->md_blocking_ast, 0);
+ if (enq_req)
+ ptlrpc_req_finished(enq_req);
+
+ if (rc < 0) {
+ CERROR("%s: "DFID" lock enqueue fails: rc = %d\n",
+ exp->exp_obd->obd_name, PFID(&op_data->op_fid1), rc);
+ return rc;
+ }
+
+ rc = 0;
+ lockh.cookie = it.it_lock_handle;
+ mdc_set_lock_data(exp, &lockh, dir, NULL);
+
+ rp_param.rp_off = hash_offset;
+ rp_param.rp_hash64 = op_data->op_cli_flags & CLI_HASH64;
+ page = mdc_page_locate(mapping, &rp_param.rp_off, &start, &end,
+ rp_param.rp_hash64);
+ if (IS_ERR(page)) {
+ CDEBUG(D_INFO, "%s: dir page locate: " DFID " at %llu: rc %ld\n",
+ exp->exp_obd->obd_name, PFID(&op_data->op_fid1),
+ rp_param.rp_off, PTR_ERR(page));
+ rc = PTR_ERR(page);
+ goto out_unlock;
+ } else if (page) {
+ /*
+ * XXX nikita: not entirely correct handling of a corner case:
+ * suppose hash chain of entries with hash value HASH crosses
+ * border between pages P0 and P1. First both P0 and P1 are
+ * cached, seekdir() is called for some entry from the P0 part
+ * of the chain. Later P0 goes out of cache. telldir(HASH)
+ * happens and finds P1, as it starts with matching hash
+ * value. Remaining entries from P0 part of the chain are
+ * skipped. (Is that really a bug?)
+ *
+ * Possible solutions: 0. don't cache P1 is such case, handle
+ * it as an "overflow" page. 1. invalidate all pages at
+ * once. 2. use HASH|1 as an index for P1.
+ */
+ goto hash_collision;
+ }
+
+ rp_param.rp_exp = exp;
+ rp_param.rp_mod = op_data;
+ page = read_cache_page(mapping,
+ hash_x_index(rp_param.rp_off,
+ rp_param.rp_hash64),
+ mdc_read_page_remote, &rp_param);
+ if (IS_ERR(page)) {
+ CERROR("%s: read cache page: "DFID" at %llu: rc %ld\n",
+ exp->exp_obd->obd_name, PFID(&op_data->op_fid1),
+ rp_param.rp_off, PTR_ERR(page));
+ rc = PTR_ERR(page);
+ goto out_unlock;
+ }
+
+ wait_on_page_locked(page);
+ (void)kmap(page);
+ if (!PageUptodate(page)) {
+ CERROR("%s: page not updated: "DFID" at %llu: rc %d\n",
+ exp->exp_obd->obd_name, PFID(&op_data->op_fid1),
+ rp_param.rp_off, -5);
+ goto fail;
+ }
+ if (!PageChecked(page))
+ SetPageChecked(page);
+ if (PageError(page)) {
+ CERROR("%s: page error: "DFID" at %llu: rc %d\n",
+ exp->exp_obd->obd_name, PFID(&op_data->op_fid1),
+ rp_param.rp_off, -5);
+ goto fail;
+ }
+
+hash_collision:
+ dp = page_address(page);
+ if (BITS_PER_LONG == 32 && rp_param.rp_hash64) {
+ start = le64_to_cpu(dp->ldp_hash_start) >> 32;
+ end = le64_to_cpu(dp->ldp_hash_end) >> 32;
+ rp_param.rp_off = hash_offset >> 32;
+ } else {
+ start = le64_to_cpu(dp->ldp_hash_start);
+ end = le64_to_cpu(dp->ldp_hash_end);
+ rp_param.rp_off = hash_offset;
+ }
+ if (end == start) {
+ LASSERT(start == rp_param.rp_off);
+ CWARN("Page-wide hash collision: %#lx\n", (unsigned long)end);
+#if BITS_PER_LONG == 32
+ CWARN("Real page-wide hash collision at [%llu %llu] with hash %llu\n",
+ le64_to_cpu(dp->ldp_hash_start),
+ le64_to_cpu(dp->ldp_hash_end), hash_offset);
+#endif
+ /*
+ * Fetch whole overflow chain...
+ *
+ * XXX not yet.
+ */
+ goto fail;
+ }
+ *ppage = page;
+out_unlock:
+ ldlm_lock_decref(&lockh, it.it_lock_mode);
+ return rc;
+fail:
+ kunmap(page);
+ mdc_release_page(page, 1);
+ rc = -EIO;
+ goto out_unlock;
+}
+
static int mdc_statfs(const struct lu_env *env,
struct obd_export *exp, struct obd_statfs *osfs,
__u64 max_age, __u32 flags)
@@ -1401,7 +1842,7 @@ out:
return rc;
}
-static struct kuc_hdr *changelog_kuc_hdr(char *buf, int len, int flags)
+static struct kuc_hdr *changelog_kuc_hdr(char *buf, size_t len, u32 flags)
{
struct kuc_hdr *lh = (struct kuc_hdr *)buf;
@@ -1415,40 +1856,44 @@ static struct kuc_hdr *changelog_kuc_hdr(char *buf, int len, int flags)
return lh;
}
-#define D_CHANGELOG 0
-
struct changelog_show {
__u64 cs_startrec;
- __u32 cs_flags;
+ enum changelog_send_flag cs_flags;
struct file *cs_fp;
char *cs_buf;
struct obd_device *cs_obd;
};
+static inline char *cs_obd_name(struct changelog_show *cs)
+{
+ return cs->cs_obd->obd_name;
+}
+
static int changelog_kkuc_cb(const struct lu_env *env, struct llog_handle *llh,
struct llog_rec_hdr *hdr, void *data)
{
struct changelog_show *cs = data;
struct llog_changelog_rec *rec = (struct llog_changelog_rec *)hdr;
struct kuc_hdr *lh;
- int len, rc;
+ size_t len;
+ int rc;
if (rec->cr_hdr.lrh_type != CHANGELOG_REC) {
rc = -EINVAL;
CERROR("%s: not a changelog rec %x/%d: rc = %d\n",
- cs->cs_obd->obd_name, rec->cr_hdr.lrh_type,
+ cs_obd_name(cs), rec->cr_hdr.lrh_type,
rec->cr.cr_type, rc);
return rc;
}
if (rec->cr.cr_index < cs->cs_startrec) {
/* Skip entries earlier than what we are interested in */
- CDEBUG(D_CHANGELOG, "rec=%llu start=%llu\n",
+ CDEBUG(D_HSM, "rec=%llu start=%llu\n",
rec->cr.cr_index, cs->cs_startrec);
return 0;
}
- CDEBUG(D_CHANGELOG, "%llu %02d%-5s %llu 0x%x t="DFID" p="DFID
+ CDEBUG(D_HSM, "%llu %02d%-5s %llu 0x%x t=" DFID " p=" DFID
" %.*s\n", rec->cr.cr_index, rec->cr.cr_type,
changelog_type2str(rec->cr.cr_type), rec->cr.cr_time,
rec->cr.cr_flags & CLF_FLAGMASK,
@@ -1462,20 +1907,21 @@ static int changelog_kkuc_cb(const struct lu_env *env, struct llog_handle *llh,
memcpy(lh + 1, &rec->cr, len - sizeof(*lh));
rc = libcfs_kkuc_msg_put(cs->cs_fp, lh);
- CDEBUG(D_CHANGELOG, "kucmsg fp %p len %d rc %d\n", cs->cs_fp, len, rc);
+ CDEBUG(D_HSM, "kucmsg fp %p len %zu rc %d\n", cs->cs_fp, len, rc);
return rc;
}
static int mdc_changelog_send_thread(void *csdata)
{
+ enum llog_flag flags = LLOG_F_IS_CAT;
struct changelog_show *cs = csdata;
struct llog_ctxt *ctxt = NULL;
struct llog_handle *llh = NULL;
struct kuc_hdr *kuch;
int rc;
- CDEBUG(D_CHANGELOG, "changelog to fp=%p start %llu\n",
+ CDEBUG(D_HSM, "changelog to fp=%p start %llu\n",
cs->cs_fp, cs->cs_startrec);
cs->cs_buf = kzalloc(KUC_CHANGELOG_MSG_MAXSIZE, GFP_NOFS);
@@ -1494,10 +1940,14 @@ static int mdc_changelog_send_thread(void *csdata)
LLOG_OPEN_EXISTS);
if (rc) {
CERROR("%s: fail to open changelog catalog: rc = %d\n",
- cs->cs_obd->obd_name, rc);
+ cs_obd_name(cs), rc);
goto out;
}
- rc = llog_init_handle(NULL, llh, LLOG_F_IS_CAT, NULL);
+
+ if (cs->cs_flags & CHANGELOG_FLAG_JOBID)
+ flags |= LLOG_F_EXT_JOBID;
+
+ rc = llog_init_handle(NULL, llh, flags, NULL);
if (rc) {
CERROR("llog_init_handle failed %d\n", rc);
goto out;
@@ -1550,12 +2000,12 @@ static int mdc_ioc_changelog_send(struct obd_device *obd,
if (IS_ERR(task)) {
rc = PTR_ERR(task);
CERROR("%s: can't start changelog thread: rc = %d\n",
- obd->obd_name, rc);
+ cs_obd_name(cs), rc);
kfree(cs);
} else {
rc = 0;
- CDEBUG(D_CHANGELOG, "%s: started changelog thread\n",
- obd->obd_name);
+ CDEBUG(D_HSM, "%s: started changelog thread\n",
+ cs_obd_name(cs));
}
CERROR("Failed to start changelog thread: %d\n", rc);
@@ -1669,9 +2119,11 @@ static int mdc_ioc_swap_layouts(struct obd_export *exp,
* with the request RPC to avoid extra RPC round trips
*/
count = mdc_resource_get_unused(exp, &op_data->op_fid1, &cancels,
- LCK_CR, MDS_INODELOCK_LAYOUT);
+ LCK_CR, MDS_INODELOCK_LAYOUT |
+ MDS_INODELOCK_XATTR);
count += mdc_resource_get_unused(exp, &op_data->op_fid2, &cancels,
- LCK_CR, MDS_INODELOCK_LAYOUT);
+ LCK_CR, MDS_INODELOCK_LAYOUT |
+ MDS_INODELOCK_XATTR);
req = ptlrpc_request_alloc(class_exp2cliimp(exp),
&RQF_MDS_SWAP_LAYOUTS);
@@ -1917,7 +2369,7 @@ static void lustre_swab_hai(struct hsm_action_item *h)
static void lustre_swab_hal(struct hsm_action_list *h)
{
struct hsm_action_item *hai;
- int i;
+ u32 i;
__swab32s(&h->hal_version);
__swab32s(&h->hal_count);
@@ -1966,14 +2418,14 @@ static int mdc_ioc_hsm_ct_start(struct obd_export *exp,
* @param val KUC message (kuc_hdr + hsm_action_list)
* @param len total length of message
*/
-static int mdc_hsm_copytool_send(int len, void *val)
+static int mdc_hsm_copytool_send(size_t len, void *val)
{
struct kuc_hdr *lh = (struct kuc_hdr *)val;
struct hsm_action_list *hal = (struct hsm_action_list *)(lh + 1);
if (len < sizeof(*lh) + sizeof(*hal)) {
- CERROR("Short HSM message %d < %d\n", len,
- (int)(sizeof(*lh) + sizeof(*hal)));
+ CERROR("Short HSM message %zu < %zu\n", len,
+ sizeof(*lh) + sizeof(*hal));
return -EPROTO;
}
if (lh->kuc_magic == __swab16(KUC_MAGIC)) {
@@ -2044,9 +2496,8 @@ static int mdc_set_info_async(const struct lu_env *env,
}
spin_unlock(&imp->imp_lock);
- rc = do_set_info_async(imp, MDS_SET_INFO, LUSTRE_MDS_VERSION,
- keylen, key, vallen, val, set);
- return rc;
+ return do_set_info_async(imp, MDS_SET_INFO, LUSTRE_MDS_VERSION,
+ keylen, key, vallen, val, set);
}
if (KEY_IS(KEY_SPTLRPC_CONF)) {
sptlrpc_conf_client_adapt(exp->exp_obd);
@@ -2065,6 +2516,12 @@ static int mdc_set_info_async(const struct lu_env *env,
rc = mdc_hsm_copytool_send(vallen, val);
return rc;
}
+ if (KEY_IS(KEY_DEFAULT_EASIZE)) {
+ u32 *default_easize = val;
+
+ exp->exp_obd->u.cli.cl_default_mds_easize = *default_easize;
+ return 0;
+ }
CERROR("Unknown key %s\n", (char *)key);
return -EINVAL;
@@ -2077,18 +2534,18 @@ static int mdc_get_info(const struct lu_env *env, struct obd_export *exp,
int rc = -EINVAL;
if (KEY_IS(KEY_MAX_EASIZE)) {
- int mdsize, *max_easize;
+ u32 mdsize, *max_easize;
if (*vallen != sizeof(int))
return -EINVAL;
- mdsize = *(int *)val;
+ mdsize = *(u32 *)val;
if (mdsize > exp->exp_obd->u.cli.cl_max_mds_easize)
exp->exp_obd->u.cli.cl_max_mds_easize = mdsize;
max_easize = val;
*max_easize = exp->exp_obd->u.cli.cl_max_mds_easize;
return 0;
} else if (KEY_IS(KEY_DEFAULT_EASIZE)) {
- int *default_easize;
+ u32 *default_easize;
if (*vallen != sizeof(int))
return -EINVAL;
@@ -2105,7 +2562,7 @@ static int mdc_get_info(const struct lu_env *env, struct obd_export *exp,
*data = imp->imp_connect_data;
return 0;
} else if (KEY_IS(KEY_TGT_COUNT)) {
- *((int *)val) = 1;
+ *((u32 *)val) = 1;
return 0;
}
@@ -2199,13 +2656,13 @@ static int mdc_import_event(struct obd_device *obd, struct obd_import *imp,
return rc;
}
-int mdc_fid_alloc(struct obd_export *exp, struct lu_fid *fid,
- struct md_op_data *op_data)
+int mdc_fid_alloc(const struct lu_env *env, struct obd_export *exp,
+ struct lu_fid *fid, struct md_op_data *op_data)
{
struct client_obd *cli = &exp->exp_obd->u.cli;
struct lu_client_seq *seq = cli->cl_seq;
- return seq_client_alloc_fid(NULL, seq, fid);
+ return seq_client_alloc_fid(env, seq, fid);
}
static struct obd_uuid *mdc_get_uuid(struct obd_export *exp)
@@ -2333,8 +2790,8 @@ err_rpc_lock:
* a large number of stripes is possible. If a larger reply buffer is
* required it will be reallocated in the ptlrpc layer due to overflow.
*/
-static int mdc_init_ea_size(struct obd_export *exp, int easize,
- int def_easize, int cookiesize, int def_cookiesize)
+static int mdc_init_ea_size(struct obd_export *exp, u32 easize, u32 def_easize,
+ u32 cookiesize, u32 def_cookiesize)
{
struct obd_device *obd = exp->exp_obd;
struct client_obd *cli = &obd->u.cli;
@@ -2430,7 +2887,6 @@ static struct obd_ops mdc_obd_ops = {
static struct md_ops mdc_md_ops = {
.getstatus = mdc_getstatus,
.null_inode = mdc_null_inode,
- .find_cbdata = mdc_find_cbdata,
.close = mdc_close,
.create = mdc_create,
.done_writing = mdc_done_writing,
@@ -2439,13 +2895,12 @@ static struct md_ops mdc_md_ops = {
.getattr_name = mdc_getattr_name,
.intent_lock = mdc_intent_lock,
.link = mdc_link,
- .is_subdir = mdc_is_subdir,
.rename = mdc_rename,
.setattr = mdc_setattr,
.setxattr = mdc_setxattr,
.getxattr = mdc_getxattr,
.sync = mdc_sync,
- .readpage = mdc_readpage,
+ .read_page = mdc_read_page,
.unlink = mdc_unlink,
.cancel_unused = mdc_cancel_unused,
.init_ea_size = mdc_init_ea_size,
diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c
index 9d0bd4745865..23374cae5133 100644
--- a/drivers/staging/lustre/lustre/mgc/mgc_request.c
+++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c
@@ -549,8 +549,9 @@ static int mgc_requeue_thread(void *data)
* caused the lock revocation to finish its setup, plus some
* random so everyone doesn't try to reconnect at once.
*/
- to = MGC_TIMEOUT_MIN_SECONDS * HZ;
- to += rand * HZ / 100; /* rand is centi-seconds */
+ to = msecs_to_jiffies(MGC_TIMEOUT_MIN_SECONDS * MSEC_PER_SEC);
+ /* rand is centi-seconds */
+ to += msecs_to_jiffies(rand * MSEC_PER_SEC / 100);
lwi = LWI_TIMEOUT(to, NULL, NULL);
l_wait_event(rq_waitq, rq_state & (RQ_STOP | RQ_PRECLEANUP),
&lwi);
@@ -1158,7 +1159,7 @@ static int mgc_apply_recover_logs(struct obd_device *mgc,
while (datalen > 0) {
int entry_len = sizeof(*entry);
- int is_ost;
+ int is_ost, i;
struct obd_device *obd;
char *obdname;
char *cname;
@@ -1264,11 +1265,17 @@ static int mgc_apply_recover_logs(struct obd_device *mgc,
continue;
}
- /* TODO: iterate all nids to find one */
+ /* iterate all nids to find one */
/* find uuid by nid */
- rc = client_import_find_conn(obd->u.cli.cl_import,
- entry->u.nids[0],
- (struct obd_uuid *)uuid);
+ rc = -ENOENT;
+ for (i = 0; i < entry->mne_nid_count; i++) {
+ rc = client_import_find_conn(obd->u.cli.cl_import,
+ entry->u.nids[0],
+ (struct obd_uuid *)uuid);
+ if (!rc)
+ break;
+ }
+
up_read(&obd->u.cli.cl_sem);
if (rc < 0) {
CERROR("mgc: cannot find uuid by nid %s\n",
@@ -1428,14 +1435,12 @@ again:
}
mne_swab = !!ptlrpc_rep_need_swab(req);
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 2, 50, 0)
+#if OBD_OCD_VERSION(3, 0, 53, 0) > LUSTRE_VERSION_CODE
/* This import flag means the server did an extra swab of IR MNE
* records (fixed in LU-1252), reverse it here if needed. LU-1644
*/
if (unlikely(req->rq_import->imp_need_mne_swab))
mne_swab = !mne_swab;
-#else
-#warning "LU-1644: Remove old OBD_CONNECT_MNE_SWAB fixup and imp_need_mne_swab"
#endif
for (i = 0; i < nrpages && ealen > 0; i++) {
@@ -1740,8 +1745,6 @@ static struct obd_ops mgc_obd_ops = {
.del_conn = client_import_del_conn,
.connect = client_connect_import,
.disconnect = client_disconnect_export,
- /* .enqueue = mgc_enqueue, */
- /* .iocontrol = mgc_iocontrol, */
.set_info_async = mgc_set_info_async,
.get_info = mgc_get_info,
.import_event = mgc_import_event,
diff --git a/drivers/staging/lustre/lustre/obdclass/Makefile b/drivers/staging/lustre/lustre/obdclass/Makefile
index df7e47f35a66..b42e109b30e0 100644
--- a/drivers/staging/lustre/lustre/obdclass/Makefile
+++ b/drivers/staging/lustre/lustre/obdclass/Makefile
@@ -3,6 +3,6 @@ obj-$(CONFIG_LUSTRE_FS) += obdclass.o
obdclass-y := linux/linux-module.o linux/linux-obdo.o linux/linux-sysctl.o \
llog.o llog_cat.o llog_obd.o llog_swab.o class_obd.o debug.o \
genops.o uuid.o lprocfs_status.o lprocfs_counters.o \
- lustre_handles.o lustre_peer.o statfs_pack.o \
+ lustre_handles.o lustre_peer.o statfs_pack.o linkea.o \
obdo.o obd_config.o obd_mount.o lu_object.o lu_ref.o \
cl_object.o cl_page.o cl_lock.o cl_io.o kernelcomm.o
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index e72f1fc00a13..bc4b7b6b9a20 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -73,7 +73,6 @@ int cl_io_is_going(const struct lu_env *env)
{
return cl_env_info(env)->clt_current_io != NULL;
}
-EXPORT_SYMBOL(cl_io_is_going);
/**
* cl_io invariant that holds at all times when exported cl_io_*() functions
@@ -859,9 +858,6 @@ void cl_page_list_add(struct cl_page_list *plist, struct cl_page *page)
LASSERT(page->cp_owner);
LINVRNT(plist->pl_owner == current);
- lockdep_off();
- mutex_lock(&page->cp_mutex);
- lockdep_on();
LASSERT(list_empty(&page->cp_batch));
list_add_tail(&page->cp_batch, &plist->pl_pages);
++plist->pl_nr;
@@ -877,12 +873,10 @@ void cl_page_list_del(const struct lu_env *env, struct cl_page_list *plist,
struct cl_page *page)
{
LASSERT(plist->pl_nr > 0);
+ LASSERT(cl_page_is_vmlocked(env, page));
LINVRNT(plist->pl_owner == current);
list_del_init(&page->cp_batch);
- lockdep_off();
- mutex_unlock(&page->cp_mutex);
- lockdep_on();
--plist->pl_nr;
lu_ref_del_at(&page->cp_reference, &page->cp_queue_ref, "queue", plist);
cl_page_put(env, page);
@@ -941,8 +935,6 @@ void cl_page_list_splice(struct cl_page_list *list, struct cl_page_list *head)
}
EXPORT_SYMBOL(cl_page_list_splice);
-void cl_page_disown0(const struct lu_env *env,
- struct cl_io *io, struct cl_page *pg);
/**
* Disowns pages in a queue.
@@ -959,9 +951,6 @@ void cl_page_list_disown(const struct lu_env *env,
LASSERT(plist->pl_nr > 0);
list_del_init(&page->cp_batch);
- lockdep_off();
- mutex_unlock(&page->cp_mutex);
- lockdep_on();
--plist->pl_nr;
/*
* cl_page_disown0 rather than usual cl_page_disown() is used,
@@ -1221,7 +1210,7 @@ void cl_req_page_add(const struct lu_env *env,
{
struct cl_object *obj;
struct cl_req_obj *rqo;
- int i;
+ unsigned int i;
LASSERT(list_empty(&page->cp_flight));
LASSERT(!page->cp_req);
@@ -1268,7 +1257,7 @@ EXPORT_SYMBOL(cl_req_page_done);
*/
int cl_req_prep(const struct lu_env *env, struct cl_req *req)
{
- int i;
+ unsigned int i;
int result;
const struct cl_req_slice *slice;
@@ -1301,7 +1290,7 @@ void cl_req_attr_set(const struct lu_env *env, struct cl_req *req,
{
const struct cl_req_slice *slice;
struct cl_page *page;
- int i;
+ unsigned int i;
LASSERT(!list_empty(&req->crq_pages));
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index 91a5806d0239..3199dd4a3b72 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -163,7 +163,7 @@ static spinlock_t *cl_object_attr_guard(struct cl_object *o)
*
* Prevents data-attributes from changing, until lock is released by
* cl_object_attr_unlock(). This has to be called before calls to
- * cl_object_attr_get(), cl_object_attr_set().
+ * cl_object_attr_get(), cl_object_attr_update().
*/
void cl_object_attr_lock(struct cl_object *o)
__acquires(cl_object_attr_guard(o))
@@ -217,11 +217,11 @@ EXPORT_SYMBOL(cl_object_attr_get);
* Updates data-attributes of an object \a obj.
*
* Only attributes, mentioned in a validness bit-mask \a v are
- * updated. Calls cl_object_operations::coo_attr_set() on every layer, bottom
- * to top.
+ * updated. Calls cl_object_operations::coo_attr_update() on every layer,
+ * bottom to top.
*/
-int cl_object_attr_set(const struct lu_env *env, struct cl_object *obj,
- const struct cl_attr *attr, unsigned v)
+int cl_object_attr_update(const struct lu_env *env, struct cl_object *obj,
+ const struct cl_attr *attr, unsigned int v)
{
struct lu_object_header *top;
int result;
@@ -231,8 +231,9 @@ int cl_object_attr_set(const struct lu_env *env, struct cl_object *obj,
top = obj->co_lu.lo_header;
result = 0;
list_for_each_entry_reverse(obj, &top->loh_layers, co_lu.lo_linkage) {
- if (obj->co_ops->coo_attr_set) {
- result = obj->co_ops->coo_attr_set(env, obj, attr, v);
+ if (obj->co_ops->coo_attr_update) {
+ result = obj->co_ops->coo_attr_update(env, obj, attr,
+ v);
if (result != 0) {
if (result > 0)
result = 0;
@@ -242,7 +243,7 @@ int cl_object_attr_set(const struct lu_env *env, struct cl_object *obj,
}
return result;
}
-EXPORT_SYMBOL(cl_object_attr_set);
+EXPORT_SYMBOL(cl_object_attr_update);
/**
* Notifies layers (bottom-to-top) that glimpse AST was received.
@@ -321,6 +322,27 @@ int cl_object_prune(const struct lu_env *env, struct cl_object *obj)
EXPORT_SYMBOL(cl_object_prune);
/**
+ * Get stripe information of this object.
+ */
+int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
+ struct lov_user_md __user *uarg)
+{
+ struct lu_object_header *top;
+ int result = 0;
+
+ top = obj->co_lu.lo_header;
+ list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
+ if (obj->co_ops->coo_getstripe) {
+ result = obj->co_ops->coo_getstripe(env, obj, uarg);
+ if (result)
+ break;
+ }
+ }
+ return result;
+}
+EXPORT_SYMBOL(cl_object_getstripe);
+
+/**
* Helper function removing all object locks, and marking object for
* deletion. All object pages must have been deleted at this point.
*
@@ -377,7 +399,7 @@ static void cl_env_percpu_refill(void);
*/
int cl_site_init(struct cl_site *s, struct cl_device *d)
{
- int i;
+ size_t i;
int result;
result = lu_site_init(&s->cs_lu, &d->cd_lu_dev);
@@ -411,7 +433,7 @@ static struct cache_stats cl_env_stats = {
*/
int cl_site_stats_print(const struct cl_site *site, struct seq_file *m)
{
- int i;
+ size_t i;
static const char *pstate[] = {
[CPS_CACHED] = "c",
[CPS_OWNED] = "o",
@@ -1000,7 +1022,7 @@ static int cl_env_percpu_init(void)
* thus we must uninitialize up to i, the rest are undefined.
*/
for (j = 0; j < i; j++) {
- cle = &cl_env_percpu[i];
+ cle = &cl_env_percpu[j];
lu_context_exit(&cle->ce_ses);
lu_context_fini(&cle->ce_ses);
lu_env_fini(&cle->ce_lu);
@@ -1126,7 +1148,7 @@ static void *cl_key_init(const struct lu_context *ctx,
info = cl0_key_init(ctx, key);
if (!IS_ERR(info)) {
- int i;
+ size_t i;
for (i = 0; i < ARRAY_SIZE(info->clt_counters); ++i)
lu_ref_init(&info->clt_counters[i].ctc_locks_locked);
@@ -1138,7 +1160,7 @@ static void cl_key_fini(const struct lu_context *ctx,
struct lu_context_key *key, void *data)
{
struct cl_thread_info *info;
- int i;
+ size_t i;
info = data;
for (i = 0; i < ARRAY_SIZE(info->clt_counters); ++i)
@@ -1150,7 +1172,7 @@ static void cl_key_exit(const struct lu_context *ctx,
struct lu_context_key *key, void *data)
{
struct cl_thread_info *info = data;
- int i;
+ size_t i;
for (i = 0; i < ARRAY_SIZE(info->clt_counters); ++i) {
LASSERT(info->clt_counters[i].ctc_nr_held == 0);
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
index db2dc6b39073..63973ba096da 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
@@ -151,7 +151,6 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
INIT_LIST_HEAD(&page->cp_layers);
INIT_LIST_HEAD(&page->cp_batch);
INIT_LIST_HEAD(&page->cp_flight);
- mutex_init(&page->cp_mutex);
lu_ref_init(&page->cp_reference);
head = o->co_lu.lo_header;
list_for_each_entry(o, &head->loh_layers, co_lu.lo_linkage) {
@@ -171,7 +170,6 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
}
return page;
}
-EXPORT_SYMBOL(cl_page_alloc);
/**
* Returns a cl_page with index \a idx at the object \a o, and associated with
@@ -229,11 +227,6 @@ EXPORT_SYMBOL(cl_page_find);
static inline int cl_page_invariant(const struct cl_page *pg)
{
- /*
- * Page invariant is protected by a VM lock.
- */
- LINVRNT(cl_page_is_vmlocked(NULL, pg));
-
return cl_page_in_use_noref(pg);
}
@@ -478,7 +471,6 @@ static void cl_page_owner_clear(struct cl_page *page)
LASSERT(page->cp_owner->ci_owned_nr > 0);
page->cp_owner->ci_owned_nr--;
page->cp_owner = NULL;
- page->cp_task = NULL;
}
}
@@ -562,7 +554,6 @@ static int cl_page_own0(const struct lu_env *env, struct cl_io *io,
PASSERT(env, pg, !pg->cp_owner);
PASSERT(env, pg, !pg->cp_req);
pg->cp_owner = cl_io_top(io);
- pg->cp_task = current;
cl_page_owner_set(pg);
if (pg->cp_state != CPS_FREEING) {
cl_page_state_set(env, pg, CPS_OWNED);
@@ -619,7 +610,6 @@ void cl_page_assume(const struct lu_env *env,
cl_page_invoid(env, io, pg, CL_PAGE_OP(cpo_assume));
PASSERT(env, pg, !pg->cp_owner);
pg->cp_owner = cl_io_top(io);
- pg->cp_task = current;
cl_page_owner_set(pg);
cl_page_state_set(env, pg, CPS_OWNED);
}
@@ -860,10 +850,6 @@ void cl_page_completion(const struct lu_env *env,
PASSERT(env, pg, pg->cp_state == cl_req_type_state(crt));
CL_PAGE_HEADER(D_TRACE, env, pg, "%d %d\n", crt, ioret);
- if (crt == CRT_READ && ioret == 0) {
- PASSERT(env, pg, !(pg->cp_flags & CPF_READ_COMPLETED));
- pg->cp_flags |= CPF_READ_COMPLETED;
- }
cl_page_state_set(env, pg, CPS_CACHED);
if (crt >= CRT_NR)
@@ -872,7 +858,6 @@ void cl_page_completion(const struct lu_env *env,
(const struct lu_env *,
const struct cl_page_slice *, int), ioret);
if (anchor) {
- LASSERT(cl_page_is_vmlocked(env, pg));
LASSERT(pg->cp_sync_io == anchor);
pg->cp_sync_io = NULL;
}
@@ -989,10 +974,10 @@ void cl_page_header_print(const struct lu_env *env, void *cookie,
lu_printer_t printer, const struct cl_page *pg)
{
(*printer)(env, cookie,
- "page@%p[%d %p %d %d %d %p %p %#x]\n",
+ "page@%p[%d %p %d %d %p %p]\n",
pg, atomic_read(&pg->cp_ref), pg->cp_obj,
- pg->cp_state, pg->cp_error, pg->cp_type,
- pg->cp_owner, pg->cp_req, pg->cp_flags);
+ pg->cp_state, pg->cp_type,
+ pg->cp_owner, pg->cp_req);
}
EXPORT_SYMBOL(cl_page_header_print);
@@ -1020,7 +1005,6 @@ int cl_page_cancel(const struct lu_env *env, struct cl_page *page)
(const struct lu_env *,
const struct cl_page_slice *));
}
-EXPORT_SYMBOL(cl_page_cancel);
/**
* Converts a byte offset within object \a obj into a page index.
@@ -1046,9 +1030,9 @@ pgoff_t cl_index(const struct cl_object *obj, loff_t offset)
}
EXPORT_SYMBOL(cl_index);
-int cl_page_size(const struct cl_object *obj)
+size_t cl_page_size(const struct cl_object *obj)
{
- return 1 << PAGE_SHIFT;
+ return 1UL << PAGE_SHIFT;
}
EXPORT_SYMBOL(cl_page_size);
@@ -1087,11 +1071,11 @@ struct cl_client_cache *cl_cache_init(unsigned long lru_page_max)
/* Initialize cache data */
atomic_set(&cache->ccc_users, 1);
cache->ccc_lru_max = lru_page_max;
- atomic_set(&cache->ccc_lru_left, lru_page_max);
+ atomic_long_set(&cache->ccc_lru_left, lru_page_max);
spin_lock_init(&cache->ccc_lru_lock);
INIT_LIST_HEAD(&cache->ccc_lru);
- atomic_set(&cache->ccc_unstable_nr, 0);
+ atomic_long_set(&cache->ccc_unstable_nr, 0);
init_waitqueue_head(&cache->ccc_unstable_waitq);
return cache;
diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
index d9d2a1952b8b..76e1ee83a723 100644
--- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
@@ -40,10 +40,10 @@
#include "../include/lprocfs_status.h"
#include <linux/list.h>
#include "../include/cl_object.h"
+#include "../include/lustre/lustre_ioctl.h"
#include "llog_internal.h"
struct obd_device *obd_devs[MAX_OBD_DEVICES];
-EXPORT_SYMBOL(obd_devs);
struct list_head obd_types;
DEFINE_RWLOCK(obd_dev_lock);
@@ -54,11 +54,9 @@ unsigned int obd_dump_on_timeout;
EXPORT_SYMBOL(obd_dump_on_timeout);
unsigned int obd_dump_on_eviction;
EXPORT_SYMBOL(obd_dump_on_eviction);
-unsigned int obd_max_dirty_pages = 256;
+unsigned long obd_max_dirty_pages;
EXPORT_SYMBOL(obd_max_dirty_pages);
-atomic_t obd_unstable_pages;
-EXPORT_SYMBOL(obd_unstable_pages);
-atomic_t obd_dirty_pages;
+atomic_long_t obd_dirty_pages;
EXPORT_SYMBOL(obd_dirty_pages);
unsigned int obd_timeout = OBD_TIMEOUT_DEFAULT; /* seconds */
EXPORT_SYMBOL(obd_timeout);
@@ -76,13 +74,11 @@ EXPORT_SYMBOL(at_early_margin);
int at_extra = 30;
EXPORT_SYMBOL(at_extra);
-atomic_t obd_dirty_transit_pages;
+atomic_long_t obd_dirty_transit_pages;
EXPORT_SYMBOL(obd_dirty_transit_pages);
char obd_jobid_var[JOBSTATS_JOBID_VAR_MAX_LEN + 1] = JOBSTATS_DISABLE;
-EXPORT_SYMBOL(obd_jobid_var);
-
-char obd_jobid_node[JOBSTATS_JOBID_SIZE + 1];
+char obd_jobid_node[LUSTRE_JOBID_SIZE + 1];
/* Get jobid of current process from stored variable or calculate
* it from pid and user_id.
@@ -93,14 +89,14 @@ char obd_jobid_node[JOBSTATS_JOBID_SIZE + 1];
*/
int lustre_get_jobid(char *jobid)
{
- memset(jobid, 0, JOBSTATS_JOBID_SIZE);
+ memset(jobid, 0, LUSTRE_JOBID_SIZE);
/* Jobstats isn't enabled */
if (strcmp(obd_jobid_var, JOBSTATS_DISABLE) == 0)
return 0;
/* Use process name + fsuid as jobid */
if (strcmp(obd_jobid_var, JOBSTATS_PROCNAME_UID) == 0) {
- snprintf(jobid, JOBSTATS_JOBID_SIZE, "%s.%u",
+ snprintf(jobid, LUSTRE_JOBID_SIZE, "%s.%u",
current_comm(),
from_kuid(&init_user_ns, current_fsuid()));
return 0;
@@ -116,19 +112,6 @@ int lustre_get_jobid(char *jobid)
}
EXPORT_SYMBOL(lustre_get_jobid);
-static inline void obd_data2conn(struct lustre_handle *conn,
- struct obd_ioctl_data *data)
-{
- memset(conn, 0, sizeof(*conn));
- conn->cookie = data->ioc_cookie;
-}
-
-static inline void obd_conn2data(struct obd_ioctl_data *data,
- struct lustre_handle *conn)
-{
- data->ioc_cookie = conn->cookie;
-}
-
static int class_resolve_dev_name(__u32 len, const char *name)
{
int rc;
@@ -287,13 +270,6 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
goto out;
}
- case OBD_IOC_CLOSE_UUID: {
- CDEBUG(D_IOCTL, "closing all connections to uuid %s (NOOP)\n",
- data->ioc_inlbuf1);
- err = 0;
- goto out;
- }
-
case OBD_IOC_GETDEVICE: {
int index = data->ioc_count;
char *status, *str;
@@ -467,15 +443,10 @@ static int obd_init_checks(void)
return ret;
}
-extern int class_procfs_init(void);
-extern int class_procfs_clean(void);
-
static int __init obdclass_init(void)
{
int i, err;
- int lustre_register_fs(void);
-
LCONSOLE_INFO("Lustre: Build Version: " LUSTRE_VERSION_STRING "\n");
spin_lock_init(&obd_types_lock);
@@ -542,23 +513,9 @@ static int __init obdclass_init(void)
static void obdclass_exit(void)
{
- int i;
-
- int lustre_unregister_fs(void);
-
lustre_unregister_fs();
misc_deregister(&obd_psdev);
- for (i = 0; i < class_devno_max(); i++) {
- struct obd_device *obd = class_num2obd(i);
-
- if (obd && obd->obd_set_up &&
- OBT(obd) && OBP(obd, detach)) {
- /* XXX should this call generic detach otherwise? */
- LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
- OBP(obd, detach)(obd);
- }
- }
llog_info_fini();
cl_global_fini();
lu_global_fini();
diff --git a/drivers/staging/lustre/lustre/obdclass/debug.c b/drivers/staging/lustre/lustre/obdclass/debug.c
index 8acf67239fa8..0bd4ad20aba7 100644
--- a/drivers/staging/lustre/lustre/obdclass/debug.c
+++ b/drivers/staging/lustre/lustre/obdclass/debug.c
@@ -48,10 +48,10 @@ int block_debug_setup(void *addr, int len, __u64 off, __u64 id)
LASSERT(addr);
put_unaligned_le64(off, addr);
- put_unaligned_le64(id, addr+LPDS);
+ put_unaligned_le64(id, addr + LPDS);
addr += len - LPDS - LPDS;
put_unaligned_le64(off, addr);
- put_unaligned_le64(id, addr+LPDS);
+ put_unaligned_le64(id, addr + LPDS);
return 0;
}
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index 99c2da632b51..cf8bb2a2f40b 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -133,7 +133,6 @@ void class_put_type(struct obd_type *type)
module_put(type->typ_dt_ops->owner);
spin_unlock(&type->obd_type_lock);
}
-EXPORT_SYMBOL(class_put_type);
#define CLASS_MAX_NAME 1024
@@ -166,10 +165,10 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops,
!type->typ_name)
goto failed;
- *(type->typ_dt_ops) = *dt_ops;
+ *type->typ_dt_ops = *dt_ops;
/* md_ops is optional */
if (md_ops)
- *(type->typ_md_ops) = *md_ops;
+ *type->typ_md_ops = *md_ops;
strcpy(type->typ_name, name);
spin_lock_init(&type->obd_type_lock);
@@ -391,7 +390,6 @@ int class_name2dev(const char *name)
return -1;
}
-EXPORT_SYMBOL(class_name2dev);
struct obd_device *class_name2obd(const char *name)
{
@@ -421,7 +419,6 @@ int class_uuid2dev(struct obd_uuid *uuid)
return -1;
}
-EXPORT_SYMBOL(class_uuid2dev);
/**
* Get obd device from ::obd_devs[]
@@ -450,7 +447,6 @@ struct obd_device *class_num2obd(int num)
return obd;
}
-EXPORT_SYMBOL(class_num2obd);
/* Search for a client OBD connected to tgt_uuid. If grp_uuid is
* specified, then only the client with that uuid is returned,
@@ -509,7 +505,7 @@ struct obd_device *class_devices_in_group(struct obd_uuid *grp_uuid, int *next)
continue;
if (obd_uuid_equals(grp_uuid, &obd->obd_uuid)) {
if (next)
- *next = i+1;
+ *next = i + 1;
read_unlock(&obd_dev_lock);
return obd;
}
@@ -618,7 +614,7 @@ struct obd_export *class_conn2export(struct lustre_handle *conn)
}
CDEBUG(D_INFO, "looking for export cookie %#llx\n", conn->cookie);
- export = class_handle2object(conn->cookie);
+ export = class_handle2object(conn->cookie, NULL);
return export;
}
EXPORT_SYMBOL(class_conn2export);
@@ -817,7 +813,6 @@ void class_unlink_export(struct obd_export *exp)
spin_unlock(&exp->exp_obd->obd_dev_lock);
class_export_put(exp);
}
-EXPORT_SYMBOL(class_unlink_export);
/* Import management functions */
static void class_import_destroy(struct obd_import *imp)
@@ -973,7 +968,6 @@ void __class_export_add_lock_ref(struct obd_export *exp, struct ldlm_lock *lock)
lock, exp, lock->l_exp_refs_nr);
spin_unlock(&exp->exp_locks_list_guard);
}
-EXPORT_SYMBOL(__class_export_add_lock_ref);
void __class_export_del_lock_ref(struct obd_export *exp, struct ldlm_lock *lock)
{
@@ -991,7 +985,6 @@ void __class_export_del_lock_ref(struct obd_export *exp, struct ldlm_lock *lock)
lock, exp, lock->l_exp_refs_nr);
spin_unlock(&exp->exp_locks_list_guard);
}
-EXPORT_SYMBOL(__class_export_del_lock_ref);
#endif
/* A connection defines an export context in which preallocation can
@@ -1100,7 +1093,6 @@ EXPORT_SYMBOL(class_fail_export);
#if LUSTRE_TRACKS_LOCK_EXP_REFS
void (*class_export_dump_hook)(struct obd_export *) = NULL;
-EXPORT_SYMBOL(class_export_dump_hook);
#endif
/* Total amount of zombies to be destroyed */
@@ -1312,3 +1304,135 @@ void obd_zombie_impexp_stop(void)
obd_zombie_impexp_notify();
wait_for_completion(&obd_zombie_stop);
}
+
+struct obd_request_slot_waiter {
+ struct list_head orsw_entry;
+ wait_queue_head_t orsw_waitq;
+ bool orsw_signaled;
+};
+
+static bool obd_request_slot_avail(struct client_obd *cli,
+ struct obd_request_slot_waiter *orsw)
+{
+ bool avail;
+
+ spin_lock(&cli->cl_loi_list_lock);
+ avail = !!list_empty(&orsw->orsw_entry);
+ spin_unlock(&cli->cl_loi_list_lock);
+
+ return avail;
+};
+
+/*
+ * For network flow control, the RPC sponsor needs to acquire a credit
+ * before sending the RPC. The credits count for a connection is defined
+ * by the "cl_max_rpcs_in_flight". If all the credits are occpuied, then
+ * the subsequent RPC sponsors need to wait until others released their
+ * credits, or the administrator increased the "cl_max_rpcs_in_flight".
+ */
+int obd_get_request_slot(struct client_obd *cli)
+{
+ struct obd_request_slot_waiter orsw;
+ struct l_wait_info lwi;
+ int rc;
+
+ spin_lock(&cli->cl_loi_list_lock);
+ if (cli->cl_r_in_flight < cli->cl_max_rpcs_in_flight) {
+ cli->cl_r_in_flight++;
+ spin_unlock(&cli->cl_loi_list_lock);
+ return 0;
+ }
+
+ init_waitqueue_head(&orsw.orsw_waitq);
+ list_add_tail(&orsw.orsw_entry, &cli->cl_loi_read_list);
+ orsw.orsw_signaled = false;
+ spin_unlock(&cli->cl_loi_list_lock);
+
+ lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
+ rc = l_wait_event(orsw.orsw_waitq,
+ obd_request_slot_avail(cli, &orsw) ||
+ orsw.orsw_signaled,
+ &lwi);
+
+ /*
+ * Here, we must take the lock to avoid the on-stack 'orsw' to be
+ * freed but other (such as obd_put_request_slot) is using it.
+ */
+ spin_lock(&cli->cl_loi_list_lock);
+ if (rc) {
+ if (!orsw.orsw_signaled) {
+ if (list_empty(&orsw.orsw_entry))
+ cli->cl_r_in_flight--;
+ else
+ list_del(&orsw.orsw_entry);
+ }
+ }
+
+ if (orsw.orsw_signaled) {
+ LASSERT(list_empty(&orsw.orsw_entry));
+
+ rc = -EINTR;
+ }
+ spin_unlock(&cli->cl_loi_list_lock);
+
+ return rc;
+}
+EXPORT_SYMBOL(obd_get_request_slot);
+
+void obd_put_request_slot(struct client_obd *cli)
+{
+ struct obd_request_slot_waiter *orsw;
+
+ spin_lock(&cli->cl_loi_list_lock);
+ cli->cl_r_in_flight--;
+
+ /* If there is free slot, wakeup the first waiter. */
+ if (!list_empty(&cli->cl_loi_read_list) &&
+ likely(cli->cl_r_in_flight < cli->cl_max_rpcs_in_flight)) {
+ orsw = list_entry(cli->cl_loi_read_list.next,
+ struct obd_request_slot_waiter, orsw_entry);
+ list_del_init(&orsw->orsw_entry);
+ cli->cl_r_in_flight++;
+ wake_up(&orsw->orsw_waitq);
+ }
+ spin_unlock(&cli->cl_loi_list_lock);
+}
+EXPORT_SYMBOL(obd_put_request_slot);
+
+__u32 obd_get_max_rpcs_in_flight(struct client_obd *cli)
+{
+ return cli->cl_max_rpcs_in_flight;
+}
+EXPORT_SYMBOL(obd_get_max_rpcs_in_flight);
+
+int obd_set_max_rpcs_in_flight(struct client_obd *cli, __u32 max)
+{
+ struct obd_request_slot_waiter *orsw;
+ __u32 old;
+ int diff;
+ int i;
+
+ if (max > OBD_MAX_RIF_MAX || max < 1)
+ return -ERANGE;
+
+ spin_lock(&cli->cl_loi_list_lock);
+ old = cli->cl_max_rpcs_in_flight;
+ cli->cl_max_rpcs_in_flight = max;
+ diff = max - old;
+
+ /* We increase the max_rpcs_in_flight, then wakeup some waiters. */
+ for (i = 0; i < diff; i++) {
+ if (list_empty(&cli->cl_loi_read_list))
+ break;
+
+ orsw = list_entry(cli->cl_loi_read_list.next,
+ struct obd_request_slot_waiter, orsw_entry);
+ list_del_init(&orsw->orsw_entry);
+ cli->cl_r_in_flight++;
+ wake_up(&orsw->orsw_waitq);
+ }
+ spin_unlock(&cli->cl_loi_list_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(obd_set_max_rpcs_in_flight);
diff --git a/drivers/staging/lustre/lustre/obdclass/linkea.c b/drivers/staging/lustre/lustre/obdclass/linkea.c
new file mode 100644
index 000000000000..0b1d2f0a422c
--- /dev/null
+++ b/drivers/staging/lustre/lustre/obdclass/linkea.c
@@ -0,0 +1,201 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * 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 version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2013, 2014, Intel Corporation.
+ * Use is subject to license terms.
+ *
+ * Author: Di Wang <di.wang@intel.com>
+ */
+
+#include "../include/lustre/lustre_idl.h"
+#include "../include/obd.h"
+#include "../include/lustre_linkea.h"
+
+int linkea_data_new(struct linkea_data *ldata, struct lu_buf *buf)
+{
+ ldata->ld_buf = lu_buf_check_and_alloc(buf, PAGE_SIZE);
+ if (!ldata->ld_buf->lb_buf)
+ return -ENOMEM;
+ ldata->ld_leh = ldata->ld_buf->lb_buf;
+ ldata->ld_leh->leh_magic = LINK_EA_MAGIC;
+ ldata->ld_leh->leh_len = sizeof(struct link_ea_header);
+ ldata->ld_leh->leh_reccount = 0;
+ return 0;
+}
+EXPORT_SYMBOL(linkea_data_new);
+
+int linkea_init(struct linkea_data *ldata)
+{
+ struct link_ea_header *leh;
+
+ LASSERT(ldata->ld_buf);
+ leh = ldata->ld_buf->lb_buf;
+ if (leh->leh_magic == __swab32(LINK_EA_MAGIC)) {
+ leh->leh_magic = LINK_EA_MAGIC;
+ leh->leh_reccount = __swab32(leh->leh_reccount);
+ leh->leh_len = __swab64(leh->leh_len);
+ /* entries are swabbed by linkea_entry_unpack */
+ }
+ if (leh->leh_magic != LINK_EA_MAGIC)
+ return -EINVAL;
+ if (leh->leh_reccount == 0)
+ return -ENODATA;
+
+ ldata->ld_leh = leh;
+ return 0;
+}
+EXPORT_SYMBOL(linkea_init);
+
+/**
+ * Pack a link_ea_entry.
+ * All elements are stored as chars to avoid alignment issues.
+ * Numbers are always big-endian
+ * \retval record length
+ */
+int linkea_entry_pack(struct link_ea_entry *lee, const struct lu_name *lname,
+ const struct lu_fid *pfid)
+{
+ struct lu_fid tmpfid;
+ int reclen;
+
+ tmpfid = *pfid;
+ if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_LINKEA_CRASH))
+ tmpfid.f_ver = ~0;
+ fid_cpu_to_be(&tmpfid, &tmpfid);
+ memcpy(&lee->lee_parent_fid, &tmpfid, sizeof(tmpfid));
+ memcpy(lee->lee_name, lname->ln_name, lname->ln_namelen);
+ reclen = sizeof(struct link_ea_entry) + lname->ln_namelen;
+
+ lee->lee_reclen[0] = (reclen >> 8) & 0xff;
+ lee->lee_reclen[1] = reclen & 0xff;
+ return reclen;
+}
+EXPORT_SYMBOL(linkea_entry_pack);
+
+void linkea_entry_unpack(const struct link_ea_entry *lee, int *reclen,
+ struct lu_name *lname, struct lu_fid *pfid)
+{
+ *reclen = (lee->lee_reclen[0] << 8) | lee->lee_reclen[1];
+ memcpy(pfid, &lee->lee_parent_fid, sizeof(*pfid));
+ fid_be_to_cpu(pfid, pfid);
+ if (lname) {
+ lname->ln_name = lee->lee_name;
+ lname->ln_namelen = *reclen - sizeof(struct link_ea_entry);
+ }
+}
+EXPORT_SYMBOL(linkea_entry_unpack);
+
+/**
+ * Add a record to the end of link ea buf
+ **/
+int linkea_add_buf(struct linkea_data *ldata, const struct lu_name *lname,
+ const struct lu_fid *pfid)
+{
+ LASSERT(ldata->ld_leh);
+
+ if (!lname || !pfid)
+ return -EINVAL;
+
+ ldata->ld_reclen = lname->ln_namelen + sizeof(struct link_ea_entry);
+ if (ldata->ld_leh->leh_len + ldata->ld_reclen >
+ ldata->ld_buf->lb_len) {
+ if (lu_buf_check_and_grow(ldata->ld_buf,
+ ldata->ld_leh->leh_len +
+ ldata->ld_reclen) < 0)
+ return -ENOMEM;
+ }
+
+ ldata->ld_leh = ldata->ld_buf->lb_buf;
+ ldata->ld_lee = ldata->ld_buf->lb_buf + ldata->ld_leh->leh_len;
+ ldata->ld_reclen = linkea_entry_pack(ldata->ld_lee, lname, pfid);
+ ldata->ld_leh->leh_len += ldata->ld_reclen;
+ ldata->ld_leh->leh_reccount++;
+ CDEBUG(D_INODE, "New link_ea name '" DFID ":%.*s' is added\n",
+ PFID(pfid), lname->ln_namelen, lname->ln_name);
+ return 0;
+}
+EXPORT_SYMBOL(linkea_add_buf);
+
+/** Del the current record from the link ea buf */
+void linkea_del_buf(struct linkea_data *ldata, const struct lu_name *lname)
+{
+ LASSERT(ldata->ld_leh && ldata->ld_lee);
+
+ ldata->ld_leh->leh_reccount--;
+ ldata->ld_leh->leh_len -= ldata->ld_reclen;
+ memmove(ldata->ld_lee, (char *)ldata->ld_lee + ldata->ld_reclen,
+ (char *)ldata->ld_leh + ldata->ld_leh->leh_len -
+ (char *)ldata->ld_lee);
+ CDEBUG(D_INODE, "Old link_ea name '%.*s' is removed\n",
+ lname->ln_namelen, lname->ln_name);
+
+ if ((char *)ldata->ld_lee >= ((char *)ldata->ld_leh +
+ ldata->ld_leh->leh_len))
+ ldata->ld_lee = NULL;
+}
+EXPORT_SYMBOL(linkea_del_buf);
+
+/**
+ * Check if such a link exists in linkEA.
+ *
+ * \param ldata link data the search to be done on
+ * \param lname name in the parent's directory entry pointing to this object
+ * \param pfid parent fid the link to be found for
+ *
+ * \retval 0 success
+ * \retval -ENOENT link does not exist
+ * \retval -ve on error
+ */
+int linkea_links_find(struct linkea_data *ldata, const struct lu_name *lname,
+ const struct lu_fid *pfid)
+{
+ struct lu_name tmpname;
+ struct lu_fid tmpfid;
+ int count;
+
+ LASSERT(ldata->ld_leh);
+
+ /* link #0 */
+ ldata->ld_lee = (struct link_ea_entry *)(ldata->ld_leh + 1);
+
+ for (count = 0; count < ldata->ld_leh->leh_reccount; count++) {
+ linkea_entry_unpack(ldata->ld_lee, &ldata->ld_reclen,
+ &tmpname, &tmpfid);
+ if (tmpname.ln_namelen == lname->ln_namelen &&
+ lu_fid_eq(&tmpfid, pfid) &&
+ (strncmp(tmpname.ln_name, lname->ln_name,
+ tmpname.ln_namelen) == 0))
+ break;
+ ldata->ld_lee = (struct link_ea_entry *)((char *)ldata->ld_lee +
+ ldata->ld_reclen);
+ }
+
+ if (count == ldata->ld_leh->leh_reccount) {
+ CDEBUG(D_INODE, "Old link_ea name '%.*s' not found\n",
+ lname->ln_namelen, lname->ln_name);
+ ldata->ld_lee = NULL;
+ ldata->ld_reclen = 0;
+ return -ENOENT;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(linkea_links_find);
diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
index 33342bfcc90e..be09e04b042f 100644
--- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
+++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
@@ -65,6 +65,7 @@
#include "../../include/obd_support.h"
#include "../../include/obd_class.h"
#include "../../include/lprocfs_status.h"
+#include "../../include/lustre/lustre_ioctl.h"
#include "../../include/lustre_ver.h"
/* buffer MUST be at least the size of obd_ioctl_hdr */
@@ -157,7 +158,6 @@ int obd_ioctl_popdata(void __user *arg, void *data, int len)
err = copy_to_user(arg, data, len) ? -EFAULT : 0;
return err;
}
-EXPORT_SYMBOL(obd_ioctl_popdata);
/* opening /dev/obd */
static int obd_class_open(struct inode *inode, struct file *file)
@@ -191,7 +191,7 @@ static long obd_class_ioctl(struct file *filp, unsigned int cmd,
}
/* declare character device */
-static struct file_operations obd_psdev_fops = {
+static const struct file_operations obd_psdev_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = obd_class_ioctl, /* unlocked_ioctl */
.open = obd_class_open, /* open */
@@ -291,7 +291,7 @@ static ssize_t jobid_name_store(struct kobject *kobj, struct attribute *attr,
const char *buffer,
size_t count)
{
- if (!count || count > JOBSTATS_JOBID_SIZE)
+ if (!count || count > LUSTRE_JOBID_SIZE)
return -EINVAL;
memcpy(obd_jobid_node, buffer, count);
diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c
index c6cc6a7666e3..41b77a30feb3 100644
--- a/drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c
+++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c
@@ -44,7 +44,7 @@
#include <linux/fs.h>
-void obdo_refresh_inode(struct inode *dst, struct obdo *src, u32 valid)
+void obdo_refresh_inode(struct inode *dst, const struct obdo *src, u32 valid)
{
valid &= src->o_valid;
diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c
index 8f70dd2686f9..e6c785afceba 100644
--- a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c
+++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c
@@ -45,6 +45,7 @@
#include "../../include/obd_support.h"
#include "../../include/lprocfs_status.h"
+#include "../../include/obd_class.h"
struct static_lustre_uintvalue_attr {
struct {
@@ -95,8 +96,8 @@ LUSTRE_STATIC_UINT_ATTR(timeout, &obd_timeout);
static ssize_t max_dirty_mb_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
- return sprintf(buf, "%ul\n",
- obd_max_dirty_pages / (1 << (20 - PAGE_SHIFT)));
+ return sprintf(buf, "%lu\n",
+ obd_max_dirty_pages / (1 << (20 - PAGE_SHIFT)));
}
static ssize_t max_dirty_mb_store(struct kobject *kobj, struct attribute *attr,
diff --git a/drivers/staging/lustre/lustre/obdclass/llog.c b/drivers/staging/lustre/lustre/obdclass/llog.c
index 1784ca063428..43797f106745 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog.c
@@ -80,7 +80,7 @@ static void llog_free_handle(struct llog_handle *loghandle)
LASSERT(list_empty(&loghandle->u.phd.phd_entry));
else if (loghandle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)
LASSERT(list_empty(&loghandle->u.chd.chd_head));
- LASSERT(sizeof(*(loghandle->lgh_hdr)) == LLOG_CHUNK_SIZE);
+ LASSERT(sizeof(*loghandle->lgh_hdr) == LLOG_CHUNK_SIZE);
kfree(loghandle->lgh_hdr);
out:
kfree(loghandle);
@@ -137,6 +137,7 @@ static int llog_read_header(const struct lu_env *env,
int llog_init_handle(const struct lu_env *env, struct llog_handle *handle,
int flags, struct obd_uuid *uuid)
{
+ enum llog_flag fmt = flags & LLOG_F_EXT_MASK;
struct llog_log_hdr *llh;
int rc;
@@ -194,6 +195,7 @@ int llog_init_handle(const struct lu_env *env, struct llog_handle *handle,
flags, LLOG_F_IS_CAT, LLOG_F_IS_PLAIN);
rc = -EINVAL;
}
+ llh->llh_flags |= fmt;
out:
if (rc) {
kfree(llh);
@@ -233,6 +235,10 @@ static int llog_process_thread(void *arg)
else
last_index = LLOG_BITMAP_BYTES * 8 - 1;
+ /* Record is not in this buffer. */
+ if (index > last_index)
+ goto out;
+
while (rc == 0) {
struct llog_rec_hdr *rec;
@@ -262,7 +268,7 @@ repeat:
*/
for (rec = (struct llog_rec_hdr *)buf;
(char *)rec < buf + LLOG_CHUNK_SIZE;
- rec = (struct llog_rec_hdr *)((char *)rec + rec->lrh_len)) {
+ rec = llog_rec_hdr_next(rec)) {
CDEBUG(D_OTHER, "processing rec 0x%p type %#x\n",
rec, rec->lrh_type);
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_cat.c b/drivers/staging/lustre/lustre/obdclass/llog_cat.c
index a82a2950295a..ce8e2f6f002a 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_cat.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_cat.c
@@ -63,11 +63,13 @@ static int llog_cat_id2handle(const struct lu_env *env,
struct llog_logid *logid)
{
struct llog_handle *loghandle;
+ enum llog_flag fmt;
int rc = 0;
if (!cathandle)
return -EBADF;
+ fmt = cathandle->lgh_hdr->llh_flags & LLOG_F_EXT_MASK;
down_write(&cathandle->lgh_lock);
list_for_each_entry(loghandle, &cathandle->u.chd.chd_head,
u.phd.phd_entry) {
@@ -99,7 +101,7 @@ static int llog_cat_id2handle(const struct lu_env *env,
return rc;
}
- rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
+ rc = llog_init_handle(env, loghandle, fmt | LLOG_F_IS_PLAIN, NULL);
if (rc < 0) {
llog_close(env, loghandle);
loghandle = NULL;
@@ -107,7 +109,7 @@ static int llog_cat_id2handle(const struct lu_env *env,
}
down_write(&cathandle->lgh_lock);
- list_add(&loghandle->u.phd.phd_entry, &cathandle->u.chd.chd_head);
+ list_add_tail(&loghandle->u.phd.phd_entry, &cathandle->u.chd.chd_head);
up_write(&cathandle->lgh_lock);
loghandle->u.phd.phd_cat_handle = cathandle;
@@ -123,7 +125,6 @@ out:
int llog_cat_close(const struct lu_env *env, struct llog_handle *cathandle)
{
struct llog_handle *loghandle, *n;
- int rc;
list_for_each_entry_safe(loghandle, n, &cathandle->u.chd.chd_head,
u.phd.phd_entry) {
@@ -134,8 +135,7 @@ int llog_cat_close(const struct lu_env *env, struct llog_handle *cathandle)
/* if handle was stored in ctxt, remove it too */
if (cathandle->lgh_ctxt->loc_handle == cathandle)
cathandle->lgh_ctxt->loc_handle = NULL;
- rc = llog_close(env, cathandle);
- return rc;
+ return llog_close(env, cathandle);
}
EXPORT_SYMBOL(llog_cat_close);
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_internal.h b/drivers/staging/lustre/lustre/obdclass/llog_internal.h
index f7949525d952..21a93c73756a 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_internal.h
+++ b/drivers/staging/lustre/lustre/obdclass/llog_internal.h
@@ -70,4 +70,9 @@ int llog_process_or_fork(const struct lu_env *env,
llog_cb_t cb, void *data, void *catdata, bool fork);
int llog_cat_cleanup(const struct lu_env *env, struct llog_handle *cathandle,
struct llog_handle *loghandle, int index);
+
+static inline struct llog_rec_hdr *llog_rec_hdr_next(struct llog_rec_hdr *rec)
+{
+ return (struct llog_rec_hdr *)((char *)rec + rec->lrh_len);
+}
#endif
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
index 6ace7e097859..a4277d684614 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
@@ -210,7 +210,6 @@ LU_KEY_INIT_FINI(llog, struct llog_thread_info);
/* context key: llog_thread_key */
LU_CONTEXT_KEY_DEFINE(llog, LCT_MD_THREAD | LCT_MG_THREAD | LCT_LOCAL);
LU_KEY_INIT_GENERIC(llog);
-EXPORT_SYMBOL(llog_thread_key);
int llog_info_init(void)
{
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_swab.c b/drivers/staging/lustre/lustre/obdclass/llog_swab.c
index f7b9b190350c..8c4c1b3f1b45 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_swab.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_swab.c
@@ -172,20 +172,23 @@ void lustre_swab_llog_rec(struct llog_rec_hdr *rec)
__swab64s(&cr->cr.cr_time);
lustre_swab_lu_fid(&cr->cr.cr_tfid);
lustre_swab_lu_fid(&cr->cr.cr_pfid);
- if (CHANGELOG_REC_EXTENDED(&cr->cr)) {
- struct llog_changelog_ext_rec *ext =
- (struct llog_changelog_ext_rec *)rec;
-
- lustre_swab_lu_fid(&ext->cr.cr_sfid);
- lustre_swab_lu_fid(&ext->cr.cr_spfid);
- tail = &ext->cr_tail;
- } else {
- tail = &cr->cr_tail;
+ if (cr->cr.cr_flags & CLF_RENAME) {
+ struct changelog_ext_rename *rnm =
+ changelog_rec_rename(&cr->cr);
+
+ lustre_swab_lu_fid(&rnm->cr_sfid);
+ lustre_swab_lu_fid(&rnm->cr_spfid);
}
- tail = (struct llog_rec_tail *)((char *)tail +
+ /*
+ * Because the tail follows a variable-length structure we need
+ * to compute its location at runtime
+ */
+ tail = (struct llog_rec_tail *)((char *)&cr->cr +
+ changelog_rec_size(&cr->cr) +
cr->cr.cr_namelen);
break;
}
+
case CHANGELOG_USER_REC:
{
struct llog_changelog_user_rec *cur =
@@ -224,6 +227,7 @@ void lustre_swab_llog_rec(struct llog_rec_hdr *rec)
__swab32s(&lsr->lsr_uid_h);
__swab32s(&lsr->lsr_gid);
__swab32s(&lsr->lsr_gid_h);
+ __swab64s(&lsr->lsr_valid);
tail = &lsr->lsr_tail;
break;
}
@@ -343,7 +347,6 @@ void lustre_swab_lustre_cfg(struct lustre_cfg *lcfg)
print_lustre_cfg(lcfg);
}
-EXPORT_SYMBOL(lustre_swab_lustre_cfg);
/* used only for compatibility with old on-disk cfg_marker data */
struct cfg_marker32 {
@@ -403,4 +406,3 @@ void lustre_swab_cfg_marker(struct cfg_marker *marker, int swab, int size)
__swab64s(&marker->cm_canceltime);
}
}
-EXPORT_SYMBOL(lustre_swab_cfg_marker);
diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
index 279b625f1afe..852a5acfefab 100644
--- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
+++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
@@ -96,6 +96,12 @@ static const char * const obd_connect_names[] = {
"pingless",
"flock_deadlock",
"disp_stripe",
+ "open_by_fid",
+ "lfsck",
+ "unknown",
+ "unlink_close",
+ "unknown",
+ "dir_stripe",
"unknown",
NULL
};
@@ -309,7 +315,7 @@ struct dentry *ldebugfs_add_simple(struct dentry *root,
}
EXPORT_SYMBOL_GPL(ldebugfs_add_simple);
-static struct file_operations lprocfs_generic_fops = { };
+static const struct file_operations lprocfs_generic_fops = { };
int ldebugfs_add_vars(struct dentry *parent,
struct lprocfs_vars *list,
@@ -615,7 +621,6 @@ void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
}
-EXPORT_SYMBOL(lprocfs_stats_collect);
/**
* Append a space separated list of current set flags to str.
@@ -1043,7 +1048,6 @@ int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, unsigned int cpuid)
}
return rc;
}
-EXPORT_SYMBOL(lprocfs_stats_alloc_one);
struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num,
enum lprocfs_stats_flags flags)
@@ -1547,6 +1551,146 @@ void lprocfs_oh_clear(struct obd_histogram *oh)
}
EXPORT_SYMBOL(lprocfs_oh_clear);
+int lprocfs_wr_root_squash(const char __user *buffer, unsigned long count,
+ struct root_squash_info *squash, char *name)
+{
+ char kernbuf[64], *tmp, *errmsg;
+ unsigned long uid, gid;
+ int rc;
+
+ if (count >= sizeof(kernbuf)) {
+ errmsg = "string too long";
+ rc = -EINVAL;
+ goto failed_noprint;
+ }
+ if (copy_from_user(kernbuf, buffer, count)) {
+ errmsg = "bad address";
+ rc = -EFAULT;
+ goto failed_noprint;
+ }
+ kernbuf[count] = '\0';
+
+ /* look for uid gid separator */
+ tmp = strchr(kernbuf, ':');
+ if (!tmp) {
+ errmsg = "needs uid:gid format";
+ rc = -EINVAL;
+ goto failed;
+ }
+ *tmp = '\0';
+ tmp++;
+
+ /* parse uid */
+ if (kstrtoul(kernbuf, 0, &uid) != 0) {
+ errmsg = "bad uid";
+ rc = -EINVAL;
+ goto failed;
+ }
+ /* parse gid */
+ if (kstrtoul(tmp, 0, &gid) != 0) {
+ errmsg = "bad gid";
+ rc = -EINVAL;
+ goto failed;
+ }
+
+ squash->rsi_uid = uid;
+ squash->rsi_gid = gid;
+
+ LCONSOLE_INFO("%s: root_squash is set to %u:%u\n",
+ name, squash->rsi_uid, squash->rsi_gid);
+ return count;
+
+failed:
+ if (tmp) {
+ tmp--;
+ *tmp = ':';
+ }
+ CWARN("%s: failed to set root_squash to \"%s\", %s, rc = %d\n",
+ name, kernbuf, errmsg, rc);
+ return rc;
+failed_noprint:
+ CWARN("%s: failed to set root_squash due to %s, rc = %d\n",
+ name, errmsg, rc);
+ return rc;
+}
+EXPORT_SYMBOL(lprocfs_wr_root_squash);
+
+int lprocfs_wr_nosquash_nids(const char __user *buffer, unsigned long count,
+ struct root_squash_info *squash, char *name)
+{
+ char *kernbuf = NULL, *errmsg;
+ struct list_head tmp;
+ int len = count;
+ int rc;
+
+ if (count > 4096) {
+ errmsg = "string too long";
+ rc = -EINVAL;
+ goto failed;
+ }
+
+ kernbuf = kzalloc(count + 1, GFP_NOFS);
+ if (!kernbuf) {
+ errmsg = "no memory";
+ rc = -ENOMEM;
+ goto failed;
+ }
+
+ if (copy_from_user(kernbuf, buffer, count)) {
+ errmsg = "bad address";
+ rc = -EFAULT;
+ goto failed;
+ }
+ kernbuf[count] = '\0';
+
+ if (count > 0 && kernbuf[count - 1] == '\n')
+ len = count - 1;
+
+ if ((len == 4 && !strncmp(kernbuf, "NONE", len)) ||
+ (len == 5 && !strncmp(kernbuf, "clear", len))) {
+ /* empty string is special case */
+ down_write(&squash->rsi_sem);
+ if (!list_empty(&squash->rsi_nosquash_nids))
+ cfs_free_nidlist(&squash->rsi_nosquash_nids);
+ up_write(&squash->rsi_sem);
+ LCONSOLE_INFO("%s: nosquash_nids is cleared\n", name);
+ kfree(kernbuf);
+ return count;
+ }
+
+ INIT_LIST_HEAD(&tmp);
+ if (cfs_parse_nidlist(kernbuf, count, &tmp) <= 0) {
+ errmsg = "can't parse";
+ rc = -EINVAL;
+ goto failed;
+ }
+ LCONSOLE_INFO("%s: nosquash_nids set to %s\n",
+ name, kernbuf);
+ kfree(kernbuf);
+ kernbuf = NULL;
+
+ down_write(&squash->rsi_sem);
+ if (!list_empty(&squash->rsi_nosquash_nids))
+ cfs_free_nidlist(&squash->rsi_nosquash_nids);
+ list_splice(&tmp, &squash->rsi_nosquash_nids);
+ up_write(&squash->rsi_sem);
+
+ return count;
+
+failed:
+ if (kernbuf) {
+ CWARN("%s: failed to set nosquash_nids to \"%s\", %s rc = %d\n",
+ name, kernbuf, errmsg, rc);
+ kfree(kernbuf);
+ kernbuf = NULL;
+ } else {
+ CWARN("%s: failed to set nosquash_nids due to %s rc = %d\n",
+ name, errmsg, rc);
+ }
+ return rc;
+}
+EXPORT_SYMBOL(lprocfs_wr_nosquash_nids);
+
static ssize_t lustre_attr_show(struct kobject *kobj,
struct attribute *attr, char *buf)
{
diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c
index 9b03059f34d6..054e567e6c8d 100644
--- a/drivers/staging/lustre/lustre/obdclass/lu_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c
@@ -55,6 +55,34 @@
#include "../include/lu_ref.h"
#include <linux/list.h>
+enum {
+ LU_CACHE_PERCENT_MAX = 50,
+ LU_CACHE_PERCENT_DEFAULT = 20
+};
+
+#define LU_CACHE_NR_MAX_ADJUST 128
+#define LU_CACHE_NR_UNLIMITED -1
+#define LU_CACHE_NR_DEFAULT LU_CACHE_NR_UNLIMITED
+#define LU_CACHE_NR_LDISKFS_LIMIT LU_CACHE_NR_UNLIMITED
+#define LU_CACHE_NR_ZFS_LIMIT 256
+
+#define LU_SITE_BITS_MIN 12
+#define LU_SITE_BITS_MAX 24
+/**
+ * total 256 buckets, we don't want too many buckets because:
+ * - consume too much memory
+ * - avoid unbalanced LRU list
+ */
+#define LU_SITE_BKT_BITS 8
+
+static unsigned int lu_cache_percent = LU_CACHE_PERCENT_DEFAULT;
+module_param(lu_cache_percent, int, 0644);
+MODULE_PARM_DESC(lu_cache_percent, "Percentage of memory to be used as lu_object cache");
+
+static long lu_cache_nr = LU_CACHE_NR_DEFAULT;
+module_param(lu_cache_nr, long, 0644);
+MODULE_PARM_DESC(lu_cache_nr, "Maximum number of objects in lu_object cache");
+
static void lu_object_free(const struct lu_env *env, struct lu_object *o);
static __u32 ls_stats_read(struct lprocfs_stats *stats, int idx);
@@ -310,10 +338,10 @@ int lu_site_purge(const struct lu_env *env, struct lu_site *s, int nr)
struct cfs_hash_bd bd2;
struct list_head dispose;
int did_sth;
- int start;
+ unsigned int start;
int count;
int bnr;
- int i;
+ unsigned int i;
if (OBD_FAIL_CHECK(OBD_FAIL_OBD_NO_LRU))
return 0;
@@ -324,8 +352,13 @@ int lu_site_purge(const struct lu_env *env, struct lu_site *s, int nr)
* the dispose list, removing them from LRU and hash table.
*/
start = s->ls_purge_start;
- bnr = (nr == ~0) ? -1 : nr / CFS_HASH_NBKT(s->ls_obj_hash) + 1;
+ bnr = (nr == ~0) ? -1 : nr / (int)CFS_HASH_NBKT(s->ls_obj_hash) + 1;
again:
+ /*
+ * It doesn't make any sense to make purge threads parallel, that can
+ * only bring troubles to us. See LU-5331.
+ */
+ mutex_lock(&s->ls_purge_mutex);
did_sth = 0;
cfs_hash_for_each_bucket(s->ls_obj_hash, &bd, i) {
if (i < start)
@@ -371,6 +404,7 @@ int lu_site_purge(const struct lu_env *env, struct lu_site *s, int nr)
if (nr == 0)
break;
}
+ mutex_unlock(&s->ls_purge_mutex);
if (nr != 0 && did_sth && start != 0) {
start = 0; /* restart from the first bucket */
@@ -573,6 +607,27 @@ static struct lu_object *lu_object_find(const struct lu_env *env,
return lu_object_find_at(env, dev->ld_site->ls_top_dev, f, conf);
}
+/*
+ * Limit the lu_object cache to a maximum of lu_cache_nr objects. Because
+ * the calculation for the number of objects to reclaim is not covered by
+ * a lock the maximum number of objects is capped by LU_CACHE_MAX_ADJUST.
+ * This ensures that many concurrent threads will not accidentally purge
+ * the entire cache.
+ */
+static void lu_object_limit(const struct lu_env *env, struct lu_device *dev)
+{
+ __u64 size, nr;
+
+ if (lu_cache_nr == LU_CACHE_NR_UNLIMITED)
+ return;
+
+ size = cfs_hash_size_get(dev->ld_site->ls_obj_hash);
+ nr = (__u64)lu_cache_nr;
+ if (size > nr)
+ lu_site_purge(env, dev->ld_site,
+ min_t(__u64, size - nr, LU_CACHE_NR_MAX_ADJUST));
+}
+
static struct lu_object *lu_object_new(const struct lu_env *env,
struct lu_device *dev,
const struct lu_fid *f,
@@ -590,6 +645,9 @@ static struct lu_object *lu_object_new(const struct lu_env *env,
cfs_hash_bd_get_and_lock(hs, (void *)f, &bd, 1);
cfs_hash_bd_add_locked(hs, &bd, &o->lo_header->loh_hash);
cfs_hash_bd_unlock(hs, &bd, 1);
+
+ lu_object_limit(env, dev);
+
return o;
}
@@ -656,6 +714,9 @@ static struct lu_object *lu_object_find_try(const struct lu_env *env,
if (likely(PTR_ERR(shadow) == -ENOENT)) {
cfs_hash_bd_add_locked(hs, &bd, &o->lo_header->loh_hash);
cfs_hash_bd_unlock(hs, &bd, 1);
+
+ lu_object_limit(env, dev);
+
return o;
}
@@ -706,13 +767,15 @@ struct lu_object *lu_object_find_slice(const struct lu_env *env,
struct lu_object *obj;
top = lu_object_find(env, dev, f, conf);
- if (!IS_ERR(top)) {
- obj = lu_object_locate(top->lo_header, dev->ld_type);
- if (!obj)
- lu_object_put(env, top);
- } else {
- obj = top;
+ if (IS_ERR(top))
+ return top;
+
+ obj = lu_object_locate(top->lo_header, dev->ld_type);
+ if (unlikely(!obj)) {
+ lu_object_put(env, top);
+ obj = ERR_PTR(-ENOENT);
}
+
return obj;
}
EXPORT_SYMBOL(lu_object_find_slice);
@@ -726,34 +789,31 @@ int lu_device_type_init(struct lu_device_type *ldt)
{
int result = 0;
+ atomic_set(&ldt->ldt_device_nr, 0);
INIT_LIST_HEAD(&ldt->ldt_linkage);
if (ldt->ldt_ops->ldto_init)
result = ldt->ldt_ops->ldto_init(ldt);
- if (result == 0)
+
+ if (!result) {
+ spin_lock(&obd_types_lock);
list_add(&ldt->ldt_linkage, &lu_device_types);
+ spin_unlock(&obd_types_lock);
+ }
+
return result;
}
EXPORT_SYMBOL(lu_device_type_init);
void lu_device_type_fini(struct lu_device_type *ldt)
{
+ spin_lock(&obd_types_lock);
list_del_init(&ldt->ldt_linkage);
+ spin_unlock(&obd_types_lock);
if (ldt->ldt_ops->ldto_fini)
ldt->ldt_ops->ldto_fini(ldt);
}
EXPORT_SYMBOL(lu_device_type_fini);
-void lu_types_stop(void)
-{
- struct lu_device_type *ldt;
-
- list_for_each_entry(ldt, &lu_device_types, ldt_linkage) {
- if (ldt->ldt_device_nr == 0 && ldt->ldt_ops->ldto_stop)
- ldt->ldt_ops->ldto_stop(ldt);
- }
-}
-EXPORT_SYMBOL(lu_types_stop);
-
/**
* Global list of all sites on this node
*/
@@ -808,22 +868,14 @@ void lu_site_print(const struct lu_env *env, struct lu_site *s, void *cookie,
}
EXPORT_SYMBOL(lu_site_print);
-enum {
- LU_CACHE_PERCENT_MAX = 50,
- LU_CACHE_PERCENT_DEFAULT = 20
-};
-
-static unsigned int lu_cache_percent = LU_CACHE_PERCENT_DEFAULT;
-module_param(lu_cache_percent, int, 0644);
-MODULE_PARM_DESC(lu_cache_percent, "Percentage of memory to be used as lu_object cache");
-
/**
* Return desired hash table order.
*/
-static int lu_htable_order(void)
+static unsigned long lu_htable_order(struct lu_device *top)
{
+ unsigned long bits_max = LU_SITE_BITS_MAX;
unsigned long cache_size;
- int bits;
+ unsigned long bits;
/*
* Calculate hash table size, assuming that we want reasonable
@@ -854,7 +906,7 @@ static int lu_htable_order(void)
for (bits = 1; (1 << bits) < cache_size; ++bits) {
;
}
- return bits;
+ return clamp_t(typeof(bits), bits, LU_SITE_BITS_MIN, bits_max);
}
static unsigned lu_obj_hop_hash(struct cfs_hash *hs,
@@ -930,28 +982,18 @@ static void lu_dev_add_linkage(struct lu_site *s, struct lu_device *d)
/**
* Initialize site \a s, with \a d as the top level device.
*/
-#define LU_SITE_BITS_MIN 12
-#define LU_SITE_BITS_MAX 19
-/**
- * total 256 buckets, we don't want too many buckets because:
- * - consume too much memory
- * - avoid unbalanced LRU list
- */
-#define LU_SITE_BKT_BITS 8
-
int lu_site_init(struct lu_site *s, struct lu_device *top)
{
struct lu_site_bkt_data *bkt;
struct cfs_hash_bd bd;
+ unsigned long bits;
+ unsigned long i;
char name[16];
- int bits;
- int i;
memset(s, 0, sizeof(*s));
- bits = lu_htable_order();
- snprintf(name, 16, "lu_site_%s", top->ld_type->ldt_name);
- for (bits = min(max(LU_SITE_BITS_MIN, bits), LU_SITE_BITS_MAX);
- bits >= LU_SITE_BITS_MIN; bits--) {
+ mutex_init(&s->ls_purge_mutex);
+ snprintf(name, sizeof(name), "lu_site_%s", top->ld_type->ldt_name);
+ for (bits = lu_htable_order(top); bits >= LU_SITE_BITS_MIN; bits--) {
s->ls_obj_hash = cfs_hash_create(name, bits, bits,
bits - LU_SITE_BKT_BITS,
sizeof(*bkt), 0, 0,
@@ -959,13 +1001,14 @@ int lu_site_init(struct lu_site *s, struct lu_device *top)
CFS_HASH_SPIN_BKTLOCK |
CFS_HASH_NO_ITEMREF |
CFS_HASH_DEPTH |
- CFS_HASH_ASSERT_EMPTY);
+ CFS_HASH_ASSERT_EMPTY |
+ CFS_HASH_COUNTER);
if (s->ls_obj_hash)
break;
}
if (!s->ls_obj_hash) {
- CERROR("failed to create lu_site hash with bits: %d\n", bits);
+ CERROR("failed to create lu_site hash with bits: %lu\n", bits);
return -ENOMEM;
}
@@ -1082,8 +1125,10 @@ EXPORT_SYMBOL(lu_device_put);
*/
int lu_device_init(struct lu_device *d, struct lu_device_type *t)
{
- if (t->ldt_device_nr++ == 0 && t->ldt_ops->ldto_start)
+ if (atomic_inc_return(&t->ldt_device_nr) == 1 &&
+ t->ldt_ops->ldto_start)
t->ldt_ops->ldto_start(t);
+
memset(d, 0, sizeof(*d));
atomic_set(&d->ld_ref, 0);
d->ld_type = t;
@@ -1098,9 +1143,8 @@ EXPORT_SYMBOL(lu_device_init);
*/
void lu_device_fini(struct lu_device *d)
{
- struct lu_device_type *t;
+ struct lu_device_type *t = d->ld_type;
- t = d->ld_type;
if (d->ld_obd) {
d->ld_obd->obd_lu_dev = NULL;
d->ld_obd = NULL;
@@ -1109,8 +1153,10 @@ void lu_device_fini(struct lu_device *d)
lu_ref_fini(&d->ld_reference);
LASSERTF(atomic_read(&d->ld_ref) == 0,
"Refcount is %u\n", atomic_read(&d->ld_ref));
- LASSERT(t->ldt_device_nr > 0);
- if (--t->ldt_device_nr == 0 && t->ldt_ops->ldto_stop)
+ LASSERT(atomic_read(&t->ldt_device_nr) > 0);
+
+ if (atomic_dec_and_test(&t->ldt_device_nr) &&
+ t->ldt_ops->ldto_stop)
t->ldt_ops->ldto_stop(t);
}
EXPORT_SYMBOL(lu_device_fini);
@@ -1254,7 +1300,6 @@ void lu_stack_fini(const struct lu_env *env, struct lu_device *top)
}
}
}
-EXPORT_SYMBOL(lu_stack_fini);
enum {
/**
@@ -1281,7 +1326,7 @@ static unsigned key_set_version;
int lu_context_key_register(struct lu_context_key *key)
{
int result;
- int i;
+ unsigned int i;
LASSERT(key->lct_init);
LASSERT(key->lct_fini);
@@ -1476,18 +1521,16 @@ void lu_context_key_quiesce(struct lu_context_key *key)
++key_set_version;
}
}
-EXPORT_SYMBOL(lu_context_key_quiesce);
void lu_context_key_revive(struct lu_context_key *key)
{
key->lct_tags &= ~LCT_QUIESCENT;
++key_set_version;
}
-EXPORT_SYMBOL(lu_context_key_revive);
static void keys_fini(struct lu_context *ctx)
{
- int i;
+ unsigned int i;
if (!ctx->lc_value)
return;
@@ -1501,7 +1544,7 @@ static void keys_fini(struct lu_context *ctx)
static int keys_fill(struct lu_context *ctx)
{
- int i;
+ unsigned int i;
LINVRNT(ctx->lc_value);
for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) {
@@ -1614,7 +1657,7 @@ EXPORT_SYMBOL(lu_context_enter);
*/
void lu_context_exit(struct lu_context *ctx)
{
- int i;
+ unsigned int i;
LINVRNT(ctx->lc_state == LCS_ENTERED);
ctx->lc_state = LCS_LEFT;
@@ -1642,7 +1685,6 @@ int lu_context_refill(struct lu_context *ctx)
{
return likely(ctx->lc_version == key_set_version) ? 0 : keys_fill(ctx);
}
-EXPORT_SYMBOL(lu_context_refill);
/**
* lu_ctx_tags/lu_ses_tags will be updated if there are new types of
@@ -1696,7 +1738,7 @@ static void lu_site_stats_get(struct cfs_hash *hs,
struct lu_site_stats *stats, int populated)
{
struct cfs_hash_bd bd;
- int i;
+ unsigned int i;
cfs_hash_for_each_bucket(hs, &bd, i) {
struct lu_site_bkt_data *bkt = cfs_hash_bd_extra_get(hs, &bd);
@@ -1940,3 +1982,73 @@ void lu_kmem_fini(struct lu_kmem_descr *caches)
}
}
EXPORT_SYMBOL(lu_kmem_fini);
+
+void lu_buf_free(struct lu_buf *buf)
+{
+ LASSERT(buf);
+ if (buf->lb_buf) {
+ LASSERT(buf->lb_len > 0);
+ kvfree(buf->lb_buf);
+ buf->lb_buf = NULL;
+ buf->lb_len = 0;
+ }
+}
+EXPORT_SYMBOL(lu_buf_free);
+
+void lu_buf_alloc(struct lu_buf *buf, size_t size)
+{
+ LASSERT(buf);
+ LASSERT(!buf->lb_buf);
+ LASSERT(!buf->lb_len);
+ buf->lb_buf = libcfs_kvzalloc(size, GFP_NOFS);
+ if (likely(buf->lb_buf))
+ buf->lb_len = size;
+}
+EXPORT_SYMBOL(lu_buf_alloc);
+
+void lu_buf_realloc(struct lu_buf *buf, size_t size)
+{
+ lu_buf_free(buf);
+ lu_buf_alloc(buf, size);
+}
+EXPORT_SYMBOL(lu_buf_realloc);
+
+struct lu_buf *lu_buf_check_and_alloc(struct lu_buf *buf, size_t len)
+{
+ if (!buf->lb_buf && !buf->lb_len)
+ lu_buf_alloc(buf, len);
+
+ if ((len > buf->lb_len) && buf->lb_buf)
+ lu_buf_realloc(buf, len);
+
+ return buf;
+}
+EXPORT_SYMBOL(lu_buf_check_and_alloc);
+
+/**
+ * Increase the size of the \a buf.
+ * preserves old data in buffer
+ * old buffer remains unchanged on error
+ * \retval 0 or -ENOMEM
+ */
+int lu_buf_check_and_grow(struct lu_buf *buf, size_t len)
+{
+ char *ptr;
+
+ if (len <= buf->lb_len)
+ return 0;
+
+ ptr = libcfs_kvzalloc(len, GFP_NOFS);
+ if (!ptr)
+ return -ENOMEM;
+
+ /* Free the old buf */
+ if (buf->lb_buf) {
+ memcpy(ptr, buf->lb_buf, buf->lb_len);
+ kvfree(buf->lb_buf);
+ }
+
+ buf->lb_buf = ptr;
+ buf->lb_len = len;
+ return 0;
+}
diff --git a/drivers/staging/lustre/lustre/obdclass/lustre_handles.c b/drivers/staging/lustre/lustre/obdclass/lustre_handles.c
index 082f530c527c..c9445e5ec271 100644
--- a/drivers/staging/lustre/lustre/obdclass/lustre_handles.c
+++ b/drivers/staging/lustre/lustre/obdclass/lustre_handles.c
@@ -130,7 +130,7 @@ void class_handle_unhash(struct portals_handle *h)
}
EXPORT_SYMBOL(class_handle_unhash);
-void *class_handle2object(__u64 cookie)
+void *class_handle2object(__u64 cookie, const void *owner)
{
struct handle_bucket *bucket;
struct portals_handle *h;
@@ -145,7 +145,7 @@ void *class_handle2object(__u64 cookie)
rcu_read_lock();
list_for_each_entry_rcu(h, &bucket->head, h_link) {
- if (h->h_cookie != cookie)
+ if (h->h_cookie != cookie || h->h_owner != owner)
continue;
spin_lock(&h->h_lock);
@@ -164,8 +164,11 @@ EXPORT_SYMBOL(class_handle2object);
void class_handle_free_cb(struct rcu_head *rcu)
{
- struct portals_handle *h = RCU2HANDLE(rcu);
- void *ptr = (void *)(unsigned long)h->h_cookie;
+ struct portals_handle *h;
+ void *ptr;
+
+ h = container_of(rcu, struct portals_handle, h_rcu);
+ ptr = (void *)(unsigned long)h->h_cookie;
if (h->h_ops->hop_free)
h->h_ops->hop_free(ptr, h->h_size);
@@ -214,7 +217,7 @@ static int cleanup_all_handles(void)
struct portals_handle *h;
spin_lock(&handle_hash[i].lock);
- list_for_each_entry_rcu(h, &(handle_hash[i].head), h_link) {
+ list_for_each_entry_rcu(h, &handle_hash[i].head, h_link) {
CERROR("force clean handle %#llx addr %p ops %p\n",
h->h_cookie, h, h->h_ops);
diff --git a/drivers/staging/lustre/lustre/obdclass/lustre_peer.c b/drivers/staging/lustre/lustre/obdclass/lustre_peer.c
index 5974a9bf77c0..ffa740aa861c 100644
--- a/drivers/staging/lustre/lustre/obdclass/lustre_peer.c
+++ b/drivers/staging/lustre/lustre/obdclass/lustre_peer.c
@@ -139,7 +139,6 @@ int class_add_uuid(const char *uuid, __u64 nid)
}
return 0;
}
-EXPORT_SYMBOL(class_add_uuid);
/* Delete the nids for one uuid if specified, otherwise delete all */
int class_del_uuid(const char *uuid)
diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c
index 0eab1236501b..bbed1b72d52e 100644
--- a/drivers/staging/lustre/lustre/obdclass/obd_config.c
+++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c
@@ -37,6 +37,7 @@
#define DEBUG_SUBSYSTEM S_CLASS
#include "../include/obd_class.h"
#include <linux/string.h>
+#include "../include/lustre/lustre_ioctl.h"
#include "../include/lustre_log.h"
#include "../include/lprocfs_status.h"
#include "../include/lustre_param.h"
@@ -237,7 +238,7 @@ static int class_attach(struct lustre_cfg *lcfg)
/* recovery data */
init_waitqueue_head(&obd->obd_evict_inprogress_waitq);
- llog_group_init(&obd->obd_olg, FID_SEQ_LLOG);
+ llog_group_init(&obd->obd_olg);
obd->obd_conn_inprogress = 0;
@@ -250,15 +251,6 @@ static int class_attach(struct lustre_cfg *lcfg)
}
memcpy(obd->obd_uuid.uuid, uuid, len);
- /* do the attach */
- if (OBP(obd, attach)) {
- rc = OBP(obd, attach)(obd, sizeof(*lcfg), lcfg);
- if (rc) {
- rc = -EINVAL;
- goto out;
- }
- }
-
/* Detach drops this */
spin_lock(&obd->obd_dev_lock);
atomic_set(&obd->obd_refcount, 1);
@@ -422,17 +414,12 @@ static int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
}
/* Leave this on forever */
obd->obd_stopping = 1;
-
- /* wait for already-arrived-connections to finish. */
- while (obd->obd_conn_inprogress > 0) {
- spin_unlock(&obd->obd_dev_lock);
-
- cond_resched();
-
- spin_lock(&obd->obd_dev_lock);
- }
spin_unlock(&obd->obd_dev_lock);
+ while (obd->obd_conn_inprogress > 0)
+ yield();
+ smp_rmb();
+
if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
switch (*flag) {
@@ -526,11 +513,6 @@ void class_decref(struct obd_device *obd, const char *scope, const void *source)
CERROR("Cleanup %s returned %d\n",
obd->obd_name, err);
}
- if (OBP(obd, detach)) {
- err = OBP(obd, detach)(obd);
- if (err)
- CERROR("Detach returned %d\n", err);
- }
class_release_dev(obd);
}
}
@@ -756,7 +738,7 @@ static int process_param2_config(struct lustre_cfg *lcfg)
}
start = ktime_get();
- rc = call_usermodehelper(argv[0], argv, NULL, 1);
+ rc = call_usermodehelper(argv[0], argv, NULL, UMH_WAIT_PROC);
end = ktime_get();
if (rc < 0) {
@@ -1026,7 +1008,7 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
oldfs = get_fs();
set_fs(KERNEL_DS);
- rc = (var->fops->write)(&fakefile, sval,
+ rc = var->fops->write(&fakefile, sval,
vallen, NULL);
set_fs(oldfs);
}
@@ -1060,8 +1042,6 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
}
EXPORT_SYMBOL(class_process_proc_param);
-extern int lustre_check_exclusion(struct super_block *sb, char *svname);
-
/** Parse a configuration llog, doing various manipulations on them
* for various reasons, (modifications for compatibility, skip obsolete
* records, change uuids, etc), then class_process_config() resulting
@@ -1317,33 +1297,33 @@ static int class_config_parse_rec(struct llog_rec_hdr *rec, char *buf,
if (rc < 0)
return rc;
- ptr += snprintf(ptr, end-ptr, "cmd=%05x ", lcfg->lcfg_command);
+ ptr += snprintf(ptr, end - ptr, "cmd=%05x ", lcfg->lcfg_command);
if (lcfg->lcfg_flags)
- ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
+ ptr += snprintf(ptr, end - ptr, "flags=%#08x ",
lcfg->lcfg_flags);
if (lcfg->lcfg_num)
- ptr += snprintf(ptr, end-ptr, "num=%#08x ", lcfg->lcfg_num);
+ ptr += snprintf(ptr, end - ptr, "num=%#08x ", lcfg->lcfg_num);
if (lcfg->lcfg_nid) {
char nidstr[LNET_NIDSTR_SIZE];
libcfs_nid2str_r(lcfg->lcfg_nid, nidstr, sizeof(nidstr));
- ptr += snprintf(ptr, end-ptr, "nid=%s(%#llx)\n ",
+ ptr += snprintf(ptr, end - ptr, "nid=%s(%#llx)\n ",
nidstr, lcfg->lcfg_nid);
}
if (lcfg->lcfg_command == LCFG_MARKER) {
struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
- ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
+ ptr += snprintf(ptr, end - ptr, "marker=%d(%#x)%s '%s'",
marker->cm_step, marker->cm_flags,
marker->cm_tgtname, marker->cm_comment);
} else {
int i;
for (i = 0; i < lcfg->lcfg_bufcount; i++) {
- ptr += snprintf(ptr, end-ptr, "%d:%s ", i,
+ ptr += snprintf(ptr, end - ptr, "%d:%s ", i,
lustre_cfg_string(lcfg, i));
}
}
diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c
index aa84a50e9904..0d3a3b05a637 100644
--- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c
+++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c
@@ -37,11 +37,11 @@
*/
#define DEBUG_SUBSYSTEM S_CLASS
-#define D_MOUNT (D_SUPER|D_CONFIG/*|D_WARNING */)
+#define D_MOUNT (D_SUPER | D_CONFIG/*|D_WARNING */)
#define PRINT_CMD CDEBUG
#include "../include/obd.h"
-#include "../include/linux/lustre_compat25.h"
+#include "../include/lustre_compat.h"
#include "../include/obd_class.h"
#include "../include/lustre/lustre_user.h"
#include "../include/lustre_log.h"
@@ -68,7 +68,7 @@ static void (*kill_super_cb)(struct super_block *sb);
* this log, and is added to the mgc's list of logs to follow.
*/
int lustre_process_log(struct super_block *sb, char *logname,
- struct config_llog_instance *cfg)
+ struct config_llog_instance *cfg)
{
struct lustre_cfg *lcfg;
struct lustre_cfg_bufs *bufs;
@@ -384,17 +384,15 @@ int lustre_start_mgc(struct super_block *sb)
OBD_CONNECT_FULL20 | OBD_CONNECT_IMP_RECOV |
OBD_CONNECT_LVB_TYPE;
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 2, 50, 0)
+#if OBD_OCD_VERSION(3, 0, 53, 0) > LUSTRE_VERSION_CODE
data->ocd_connect_flags |= OBD_CONNECT_MNE_SWAB;
-#else
-#warning "LU-1644: Remove old OBD_CONNECT_MNE_SWAB fixup and imp_need_mne_swab"
#endif
if (lmd_is_client(lsi->lsi_lmd) &&
lsi->lsi_lmd->lmd_flags & LMD_FLG_NOIR)
data->ocd_connect_flags &= ~OBD_CONNECT_IMP_RECOV;
data->ocd_version = LUSTRE_VERSION_CODE;
- rc = obd_connect(NULL, &exp, obd, &(obd->obd_uuid), data, NULL);
+ rc = obd_connect(NULL, &exp, obd, &obd->obd_uuid, data, NULL);
if (rc) {
CERROR("connect failed %d\n", rc);
goto out;
@@ -670,7 +668,6 @@ int lustre_common_put_super(struct super_block *sb)
}
/* Drop a ref to the mounted disk */
lustre_put_lsi(sb);
- lu_types_stop();
return rc;
}
EXPORT_SYMBOL(lustre_common_put_super);
@@ -731,7 +728,7 @@ int lustre_check_exclusion(struct super_block *sb, char *svname)
static int lmd_make_exclusion(struct lustre_mount_data *lmd, const char *ptr)
{
const char *s1 = ptr, *s2;
- __u32 index, *exclude_list;
+ __u32 index = 0, *exclude_list;
int rc = 0, devmax;
/* The shortest an ost name can be is 8 chars: -OST0000.
@@ -758,7 +755,7 @@ static int lmd_make_exclusion(struct lustre_mount_data *lmd, const char *ptr)
exclude_list[lmd->lmd_exclude_count++] = index;
else
CDEBUG(D_MOUNT, "ignoring exclude %.*s: type = %#x\n",
- (uint)(s2-s1), s1, rc);
+ (uint)(s2 - s1), s1, rc);
s1 = s2;
/* now we are pointing at ':' (next exclude)
* or ',' (end of excludes)
@@ -880,7 +877,7 @@ static int lmd_parse_mgs(struct lustre_mount_data *lmd, char **ptr)
*/
static int lmd_parse(char *options, struct lustre_mount_data *lmd)
{
- char *s1, *s2, *devname = NULL;
+ char *s1, *s2, *s3, *devname = NULL;
struct lustre_mount_data *raw = (struct lustre_mount_data *)options;
int rc = 0;
@@ -913,6 +910,7 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd)
/* Skip whitespace and extra commas */
while (*s1 == ' ' || *s1 == ',')
s1++;
+ s3 = s1;
/* Client options are parsed in ll_options: eg. flock,
* user_xattr, acl
@@ -970,6 +968,7 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd)
rc = lmd_parse_mgssec(lmd, s1 + 7);
if (rc)
goto invalid;
+ s3 = s2;
clear++;
/* ost exclusion list */
} else if (strncmp(s1, "exclude=", 8) == 0) {
@@ -990,10 +989,19 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd)
size_t length, params_length;
char *tail = strchr(s1 + 6, ',');
- if (!tail)
+ if (!tail) {
length = strlen(s1);
- else
- length = tail - s1;
+ } else {
+ lnet_nid_t nid;
+ char *param_str = tail + 1;
+ int supplementary = 1;
+
+ while (!class_parse_nid_quiet(param_str, &nid,
+ &param_str)) {
+ supplementary = 0;
+ }
+ length = param_str - s1 - supplementary;
+ }
length -= 6;
params_length = strlen(lmd->lmd_params);
if (params_length + length + 1 >= LMD_PARAMS_MAXLEN)
@@ -1001,6 +1009,7 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd)
strncat(lmd->lmd_params, s1 + 6, length);
lmd->lmd_params[params_length + length] = '\0';
strlcat(lmd->lmd_params, " ", LMD_PARAMS_MAXLEN);
+ s3 = s1 + 6 + length;
clear++;
} else if (strncmp(s1, "osd=", 4) == 0) {
rc = lmd_parse_string(&lmd->lmd_osd_type, s1 + 4);
@@ -1097,7 +1106,7 @@ static int lustre_fill_super(struct super_block *sb, void *data, int silent)
struct lustre_sb_info *lsi;
int rc;
- CDEBUG(D_MOUNT|D_VFSTRACE, "VFS Op: sb %p\n", sb);
+ CDEBUG(D_MOUNT | D_VFSTRACE, "VFS Op: sb %p\n", sb);
lsi = lustre_init_lsi(sb);
if (!lsi)
@@ -1133,7 +1142,7 @@ static int lustre_fill_super(struct super_block *sb, void *data, int silent)
} else {
rc = lustre_start_mgc(sb);
if (rc) {
- lustre_put_lsi(sb);
+ lustre_common_put_super(sb);
goto out;
}
/* Connect and start */
diff --git a/drivers/staging/lustre/lustre/obdclass/obdo.c b/drivers/staging/lustre/lustre/obdclass/obdo.c
index 8583a4a8c206..79104a66da96 100644
--- a/drivers/staging/lustre/lustre/obdclass/obdo.c
+++ b/drivers/staging/lustre/lustre/obdclass/obdo.c
@@ -112,7 +112,7 @@ void obdo_from_inode(struct obdo *dst, struct inode *src, u32 valid)
}
EXPORT_SYMBOL(obdo_from_inode);
-void obdo_to_ioobj(struct obdo *oa, struct obd_ioobj *ioobj)
+void obdo_to_ioobj(const struct obdo *oa, struct obd_ioobj *ioobj)
{
ioobj->ioo_oid = oa->o_oi;
if (unlikely(!(oa->o_valid & OBD_MD_FLGROUP)))
@@ -125,7 +125,8 @@ void obdo_to_ioobj(struct obdo *oa, struct obd_ioobj *ioobj)
}
EXPORT_SYMBOL(obdo_to_ioobj);
-static void iattr_from_obdo(struct iattr *attr, struct obdo *oa, u32 valid)
+static void iattr_from_obdo(struct iattr *attr, const struct obdo *oa,
+ u32 valid)
{
valid &= oa->o_valid;
@@ -152,12 +153,14 @@ static void iattr_from_obdo(struct iattr *attr, struct obdo *oa, u32 valid)
}
#if 0 /* you shouldn't be able to change a file's type with setattr */
if (valid & OBD_MD_FLTYPE) {
- attr->ia_mode = (attr->ia_mode & ~S_IFMT)|(oa->o_mode & S_IFMT);
+ attr->ia_mode = (attr->ia_mode & ~S_IFMT) |
+ (oa->o_mode & S_IFMT);
attr->ia_valid |= ATTR_MODE;
}
#endif
if (valid & OBD_MD_FLMODE) {
- attr->ia_mode = (attr->ia_mode & S_IFMT)|(oa->o_mode & ~S_IFMT);
+ attr->ia_mode = (attr->ia_mode & S_IFMT) |
+ (oa->o_mode & ~S_IFMT);
attr->ia_valid |= ATTR_MODE;
if (!in_group_p(make_kgid(&init_user_ns, oa->o_gid)) &&
!capable(CFS_CAP_FSETID))
@@ -173,7 +176,7 @@ static void iattr_from_obdo(struct iattr *attr, struct obdo *oa, u32 valid)
}
}
-void md_from_obdo(struct md_op_data *op_data, struct obdo *oa, u32 valid)
+void md_from_obdo(struct md_op_data *op_data, const struct obdo *oa, u32 valid)
{
iattr_from_obdo(&op_data->op_attr, oa, valid);
if (valid & OBD_MD_FLBLOCKS) {
diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c
index 5b29c4a44fe5..505582ff4d1e 100644
--- a/drivers/staging/lustre/lustre/obdecho/echo_client.c
+++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c
@@ -41,6 +41,7 @@
#include "../include/cl_object.h"
#include "../include/lustre_fid.h"
#include "../include/lustre_acl.h"
+#include "../include/lustre/lustre_ioctl.h"
#include "../include/lustre_net.h"
#include "echo_internal.h"
@@ -64,14 +65,14 @@ struct echo_object {
struct echo_device *eo_dev;
struct list_head eo_obj_chain;
- struct lov_stripe_md *eo_lsm;
+ struct lov_oinfo *eo_oinfo;
atomic_t eo_npages;
int eo_deleted;
};
struct echo_object_conf {
struct cl_object_conf eoc_cl;
- struct lov_stripe_md **eoc_md;
+ struct lov_oinfo **eoc_oinfo;
};
struct echo_page {
@@ -152,9 +153,6 @@ struct echo_object_conf *cl2echo_conf(const struct cl_object_conf *c)
}
/** @} echo_helpers */
-
-static struct echo_object *cl_echo_object_find(struct echo_device *d,
- struct lov_stripe_md **lsm);
static int cl_echo_object_put(struct echo_object *eco);
static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset,
struct page **pages, int npages, int async);
@@ -413,10 +411,13 @@ static int echo_object_init(const struct lu_env *env, struct lu_object *obj,
cconf = lu2cl_conf(conf);
econf = cl2echo_conf(cconf);
- LASSERT(econf->eoc_md);
- eco->eo_lsm = *econf->eoc_md;
- /* clear the lsm pointer so that it won't get freed. */
- *econf->eoc_md = NULL;
+ LASSERT(econf->eoc_oinfo);
+ /*
+ * Transfer the oinfo pointer to eco that it won't be
+ * freed.
+ */
+ eco->eo_oinfo = *econf->eoc_oinfo;
+ *econf->eoc_oinfo = NULL;
eco->eo_dev = ed;
atomic_set(&eco->eo_npages, 0);
@@ -429,52 +430,6 @@ static int echo_object_init(const struct lu_env *env, struct lu_object *obj,
return 0;
}
-/* taken from osc_unpackmd() */
-static int echo_alloc_memmd(struct echo_device *ed,
- struct lov_stripe_md **lsmp)
-{
- int lsm_size;
-
- /* If export is lov/osc then use their obd method */
- if (ed->ed_next)
- return obd_alloc_memmd(ed->ed_ec->ec_exp, lsmp);
- /* OFD has no unpackmd method, do everything here */
- lsm_size = lov_stripe_md_size(1);
-
- LASSERT(!*lsmp);
- *lsmp = kzalloc(lsm_size, GFP_NOFS);
- if (!*lsmp)
- return -ENOMEM;
-
- (*lsmp)->lsm_oinfo[0] = kzalloc(sizeof(struct lov_oinfo), GFP_NOFS);
- if (!(*lsmp)->lsm_oinfo[0]) {
- kfree(*lsmp);
- return -ENOMEM;
- }
-
- loi_init((*lsmp)->lsm_oinfo[0]);
- (*lsmp)->lsm_maxbytes = LUSTRE_STRIPE_MAXBYTES;
- ostid_set_seq_echo(&(*lsmp)->lsm_oi);
-
- return lsm_size;
-}
-
-static int echo_free_memmd(struct echo_device *ed, struct lov_stripe_md **lsmp)
-{
- int lsm_size;
-
- /* If export is lov/osc then use their obd method */
- if (ed->ed_next)
- return obd_free_memmd(ed->ed_ec->ec_exp, lsmp);
- /* OFD has no unpackmd method, do everything here */
- lsm_size = lov_stripe_md_size(1);
-
- kfree((*lsmp)->lsm_oinfo[0]);
- kfree(*lsmp);
- *lsmp = NULL;
- return 0;
-}
-
static void echo_object_free(const struct lu_env *env, struct lu_object *obj)
{
struct echo_object *eco = cl2echo_obj(lu2cl(obj));
@@ -489,8 +444,7 @@ static void echo_object_free(const struct lu_env *env, struct lu_object *obj)
lu_object_fini(obj);
lu_object_header_fini(obj->lo_header);
- if (eco->eo_lsm)
- echo_free_memmd(eco->eo_dev, &eco->eo_lsm);
+ kfree(eco->eo_oinfo);
kmem_cache_free(echo_object_kmem, eco);
}
@@ -864,25 +818,21 @@ static struct lu_device_type echo_device_type = {
*/
/* Interfaces to echo client obd device */
-static struct echo_object *cl_echo_object_find(struct echo_device *d,
- struct lov_stripe_md **lsmp)
+static struct echo_object *
+cl_echo_object_find(struct echo_device *d, const struct ost_id *oi)
{
struct lu_env *env;
struct echo_thread_info *info;
struct echo_object_conf *conf;
- struct lov_stripe_md *lsm;
+ struct lov_oinfo *oinfo = NULL;
struct echo_object *eco;
struct cl_object *obj;
struct lu_fid *fid;
int refcheck;
int rc;
- LASSERT(lsmp);
- lsm = *lsmp;
- LASSERT(lsm);
- LASSERTF(ostid_id(&lsm->lsm_oi) != 0, DOSTID"\n", POSTID(&lsm->lsm_oi));
- LASSERTF(ostid_seq(&lsm->lsm_oi) == FID_SEQ_ECHO, DOSTID"\n",
- POSTID(&lsm->lsm_oi));
+ LASSERTF(ostid_id(oi), DOSTID "\n", POSTID(oi));
+ LASSERTF(ostid_seq(oi) == FID_SEQ_ECHO, DOSTID "\n", POSTID(oi));
/* Never return an object if the obd is to be freed. */
if (echo_dev2cl(d)->cd_lu_dev.ld_obd->obd_stopping)
@@ -895,16 +845,24 @@ static struct echo_object *cl_echo_object_find(struct echo_device *d,
info = echo_env_info(env);
conf = &info->eti_conf;
if (d->ed_next) {
- struct lov_oinfo *oinfo = lsm->lsm_oinfo[0];
+ oinfo = kzalloc(sizeof(*oinfo), GFP_NOFS);
+ if (!oinfo) {
+ eco = ERR_PTR(-ENOMEM);
+ goto out;
+ }
- LASSERT(oinfo);
- oinfo->loi_oi = lsm->lsm_oi;
+ oinfo->loi_oi = *oi;
conf->eoc_cl.u.coc_oinfo = oinfo;
}
- conf->eoc_md = lsmp;
+
+ /*
+ * If echo_object_init() is successful then ownership of oinfo
+ * is transferred to the object.
+ */
+ conf->eoc_oinfo = &oinfo;
fid = &info->eti_fid;
- rc = ostid_to_fid(fid, &lsm->lsm_oi, 0);
+ rc = ostid_to_fid(fid, (struct ost_id *)oi, 0);
if (rc != 0) {
eco = ERR_PTR(rc);
goto out;
@@ -927,6 +885,7 @@ static struct echo_object *cl_echo_object_find(struct echo_device *d,
}
out:
+ kfree(oinfo);
cl_env_put(env, &refcheck);
return eco;
}
@@ -1051,7 +1010,7 @@ static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset,
struct cl_io *io;
struct cl_page *clp;
struct lustre_handle lh = { 0 };
- int page_size = cl_page_size(obj);
+ size_t page_size = cl_page_size(obj);
int refcheck;
int rc;
int i;
@@ -1145,7 +1104,6 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed,
{
struct echo_object *eco;
struct echo_client_obd *ec = ed->ed_ec;
- struct lov_stripe_md *lsm = NULL;
int rc;
int created = 0;
@@ -1156,30 +1114,19 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed,
return -EINVAL;
}
- rc = echo_alloc_memmd(ed, &lsm);
- if (rc < 0) {
- CERROR("Cannot allocate md: rc = %d\n", rc);
- goto failed;
- }
-
- /* setup object ID here */
- lsm->lsm_oi = oa->o_oi;
+ if (!ostid_id(&oa->o_oi))
+ ostid_set_id(&oa->o_oi, ++last_object_id);
- if (ostid_id(&lsm->lsm_oi) == 0)
- ostid_set_id(&lsm->lsm_oi, ++last_object_id);
-
- rc = obd_create(env, ec->ec_exp, oa, &lsm, oti);
+ rc = obd_create(env, ec->ec_exp, oa, oti);
if (rc != 0) {
CERROR("Cannot create objects: rc = %d\n", rc);
goto failed;
}
created = 1;
- /* See what object ID we were given */
- oa->o_oi = lsm->lsm_oi;
oa->o_valid |= OBD_MD_FLID;
- eco = cl_echo_object_find(ed, &lsm);
+ eco = cl_echo_object_find(ed, &oa->o_oi);
if (IS_ERR(eco)) {
rc = PTR_ERR(eco);
goto failed;
@@ -1190,9 +1137,7 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed,
failed:
if (created && rc)
- obd_destroy(env, ec->ec_exp, oa, lsm, oti, NULL);
- if (lsm)
- echo_free_memmd(ed, &lsm);
+ obd_destroy(env, ec->ec_exp, oa, oti);
if (rc)
CERROR("create object failed with: rc = %d\n", rc);
return rc;
@@ -1201,32 +1146,21 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed,
static int echo_get_object(struct echo_object **ecop, struct echo_device *ed,
struct obdo *oa)
{
- struct lov_stripe_md *lsm = NULL;
struct echo_object *eco;
int rc;
- if ((oa->o_valid & OBD_MD_FLID) == 0 || ostid_id(&oa->o_oi) == 0) {
- /* disallow use of object id 0 */
- CERROR("No valid oid\n");
+ if (!(oa->o_valid & OBD_MD_FLID) || !(oa->o_valid & OBD_MD_FLGROUP) ||
+ !ostid_id(&oa->o_oi)) {
+ CERROR("invalid oid " DOSTID "\n", POSTID(&oa->o_oi));
return -EINVAL;
}
- rc = echo_alloc_memmd(ed, &lsm);
- if (rc < 0)
- return rc;
-
- lsm->lsm_oi = oa->o_oi;
- if (!(oa->o_valid & OBD_MD_FLGROUP))
- ostid_set_seq_echo(&lsm->lsm_oi);
-
rc = 0;
- eco = cl_echo_object_find(ed, &lsm);
+ eco = cl_echo_object_find(ed, &oa->o_oi);
if (!IS_ERR(eco))
*ecop = eco;
else
rc = PTR_ERR(eco);
- if (lsm)
- echo_free_memmd(ed, &lsm);
return rc;
}
@@ -1436,13 +1370,12 @@ static int echo_client_prep_commit(const struct lu_env *env,
npages = tot_pages;
for (i = 0; i < npages; i++, off += PAGE_SIZE) {
- rnb[i].offset = off;
- rnb[i].len = PAGE_SIZE;
- rnb[i].flags = brw_flags;
+ rnb[i].rnb_offset = off;
+ rnb[i].rnb_len = PAGE_SIZE;
+ rnb[i].rnb_flags = brw_flags;
}
ioo.ioo_bufcnt = npages;
- oti->oti_transno = 0;
lpages = npages;
ret = obd_preprw(env, rw, exp, oa, 1, &ioo, rnb, &lpages,
@@ -1452,14 +1385,14 @@ static int echo_client_prep_commit(const struct lu_env *env,
LASSERT(lpages == npages);
for (i = 0; i < lpages; i++) {
- struct page *page = lnb[i].page;
+ struct page *page = lnb[i].lnb_page;
/* read past eof? */
- if (!page && lnb[i].rc == 0)
+ if (!page && lnb[i].lnb_rc == 0)
continue;
if (async)
- lnb[i].flags |= OBD_BRW_ASYNC;
+ lnb[i].lnb_flags |= OBD_BRW_ASYNC;
if (ostid_id(&oa->o_oi) == ECHO_PERSISTENT_OBJID ||
(oa->o_valid & OBD_MD_FLFLAGS) == 0 ||
@@ -1469,13 +1402,13 @@ static int echo_client_prep_commit(const struct lu_env *env,
if (rw == OBD_BRW_WRITE)
echo_client_page_debug_setup(page, rw,
ostid_id(&oa->o_oi),
- rnb[i].offset,
- rnb[i].len);
+ rnb[i].rnb_offset,
+ rnb[i].rnb_len);
else
echo_client_page_debug_check(page,
ostid_id(&oa->o_oi),
- rnb[i].offset,
- rnb[i].len);
+ rnb[i].rnb_offset,
+ rnb[i].rnb_len);
}
ret = obd_commitrw(env, rw, exp, oa, 1, &ioo,
@@ -1613,8 +1546,7 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
rc = echo_get_object(&eco, ed, oa);
if (rc == 0) {
- rc = obd_destroy(env, ec->ec_exp, oa, NULL,
- &dummy_oti, NULL);
+ rc = obd_destroy(env, ec->ec_exp, oa, &dummy_oti);
if (rc == 0)
eco->eo_deleted = 1;
echo_put_object(eco);
diff --git a/drivers/staging/lustre/lustre/obdecho/echo_internal.h b/drivers/staging/lustre/lustre/obdecho/echo_internal.h
index f5034a253f6d..966414fd5424 100644
--- a/drivers/staging/lustre/lustre/obdecho/echo_internal.h
+++ b/drivers/staging/lustre/lustre/obdecho/echo_internal.h
@@ -33,9 +33,9 @@
/* The persistent object (i.e. actually stores stuff!) */
#define ECHO_PERSISTENT_OBJID 1ULL
-#define ECHO_PERSISTENT_SIZE ((__u64)(1<<20))
+#define ECHO_PERSISTENT_SIZE ((__u64)(1 << 20))
/* block size to use for data verification */
-#define OBD_ECHO_BLOCK_SIZE (4<<10)
+#define OBD_ECHO_BLOCK_SIZE (4 << 10)
#endif
diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c
index 7e83d395b998..f0062d44ee03 100644
--- a/drivers/staging/lustre/lustre/osc/lproc_osc.c
+++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c
@@ -119,6 +119,7 @@ static ssize_t max_rpcs_in_flight_store(struct kobject *kobj,
spin_lock(&cli->cl_loi_list_lock);
cli->cl_max_rpcs_in_flight = val;
+ client_adjust_max_dirty(cli);
spin_unlock(&cli->cl_loi_list_lock);
return count;
@@ -136,10 +137,10 @@ static ssize_t max_dirty_mb_show(struct kobject *kobj,
int mult;
spin_lock(&cli->cl_loi_list_lock);
- val = cli->cl_dirty_max;
+ val = cli->cl_dirty_max_pages;
spin_unlock(&cli->cl_loi_list_lock);
- mult = 1 << 20;
+ mult = 1 << (20 - PAGE_SHIFT);
return lprocfs_read_frac_helper(buf, PAGE_SIZE, val, mult);
}
@@ -166,7 +167,7 @@ static ssize_t max_dirty_mb_store(struct kobject *kobj,
return -ERANGE;
spin_lock(&cli->cl_loi_list_lock);
- cli->cl_dirty_max = (u32)(pages_number << PAGE_SHIFT);
+ cli->cl_dirty_max_pages = pages_number;
osc_wake_cache_waiters(cli);
spin_unlock(&cli->cl_loi_list_lock);
@@ -181,11 +182,11 @@ static int osc_cached_mb_seq_show(struct seq_file *m, void *v)
int shift = 20 - PAGE_SHIFT;
seq_printf(m,
- "used_mb: %d\n"
- "busy_cnt: %d\n",
- (atomic_read(&cli->cl_lru_in_list) +
- atomic_read(&cli->cl_lru_busy)) >> shift,
- atomic_read(&cli->cl_lru_busy));
+ "used_mb: %ld\n"
+ "busy_cnt: %ld\n",
+ (atomic_long_read(&cli->cl_lru_in_list) +
+ atomic_long_read(&cli->cl_lru_busy)) >> shift,
+ atomic_long_read(&cli->cl_lru_busy));
return 0;
}
@@ -197,8 +198,10 @@ static ssize_t osc_cached_mb_seq_write(struct file *file,
{
struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
struct client_obd *cli = &dev->u.cli;
- int pages_number, mult, rc;
+ long pages_number, rc;
char kernbuf[128];
+ int mult;
+ u64 val;
if (count >= sizeof(kernbuf))
return -EINVAL;
@@ -210,14 +213,18 @@ static ssize_t osc_cached_mb_seq_write(struct file *file,
mult = 1 << (20 - PAGE_SHIFT);
buffer += lprocfs_find_named_value(kernbuf, "used_mb:", &count) -
kernbuf;
- rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult);
+ rc = lprocfs_write_frac_u64_helper(buffer, count, &val, mult);
if (rc)
return rc;
+ if (val > LONG_MAX)
+ return -ERANGE;
+ pages_number = (long)val;
+
if (pages_number < 0)
return -ERANGE;
- rc = atomic_read(&cli->cl_lru_in_list) - pages_number;
+ rc = atomic_long_read(&cli->cl_lru_in_list) - pages_number;
if (rc > 0) {
struct lu_env *env;
int refcheck;
@@ -244,7 +251,7 @@ static ssize_t cur_dirty_bytes_show(struct kobject *kobj,
int len;
spin_lock(&cli->cl_loi_list_lock);
- len = sprintf(buf, "%lu\n", cli->cl_dirty);
+ len = sprintf(buf, "%lu\n", cli->cl_dirty_pages << PAGE_SHIFT);
spin_unlock(&cli->cl_loi_list_lock);
return len;
@@ -583,6 +590,7 @@ static ssize_t max_pages_per_rpc_store(struct kobject *kobj,
}
spin_lock(&cli->cl_loi_list_lock);
cli->cl_max_pages_per_rpc = val;
+ client_adjust_max_dirty(cli);
spin_unlock(&cli->cl_loi_list_lock);
return count;
@@ -596,13 +604,14 @@ static ssize_t unstable_stats_show(struct kobject *kobj,
struct obd_device *dev = container_of(kobj, struct obd_device,
obd_kobj);
struct client_obd *cli = &dev->u.cli;
- int pages, mb;
+ long pages;
+ int mb;
- pages = atomic_read(&cli->cl_unstable_count);
+ pages = atomic_long_read(&cli->cl_unstable_count);
mb = (pages * PAGE_SIZE) >> 20;
- return sprintf(buf, "unstable_pages: %8d\n"
- "unstable_mb: %8d\n", pages, mb);
+ return sprintf(buf, "unstable_pages: %20ld\n"
+ "unstable_mb: %10d\n", pages, mb);
}
LUSTRE_RO_ATTR(unstable_stats);
diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c
index d011135802d5..4bbe219add98 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cache.c
+++ b/drivers/staging/lustre/lustre/osc/osc_cache.c
@@ -44,7 +44,7 @@ static int extent_debug; /* set it to be true for more debug */
static void osc_update_pending(struct osc_object *obj, int cmd, int delta);
static int osc_extent_wait(const struct lu_env *env, struct osc_extent *ext,
- int state);
+ enum osc_extent_state state);
static void osc_ap_completion(const struct lu_env *env, struct client_obd *cli,
struct osc_async_page *oap, int sent, int rc);
static int osc_make_ready(const struct lu_env *env, struct osc_async_page *oap,
@@ -177,7 +177,7 @@ static int osc_extent_sanity_check0(struct osc_extent *ext,
{
struct osc_object *obj = ext->oe_obj;
struct osc_async_page *oap;
- int page_count;
+ size_t page_count;
int rc = 0;
if (!osc_object_is_locked(obj)) {
@@ -632,7 +632,7 @@ static inline int overlapped(struct osc_extent *ex1, struct osc_extent *ex2)
*/
static struct osc_extent *osc_extent_find(const struct lu_env *env,
struct osc_object *obj, pgoff_t index,
- int *grants)
+ unsigned int *grants)
{
struct client_obd *cli = osc_cli(obj);
struct osc_lock *olck;
@@ -643,10 +643,10 @@ static struct osc_extent *osc_extent_find(const struct lu_env *env,
struct osc_extent *found = NULL;
pgoff_t chunk;
pgoff_t max_end;
- int max_pages; /* max_pages_per_rpc */
- int chunksize;
+ unsigned int max_pages; /* max_pages_per_rpc */
+ unsigned int chunksize;
int ppc_bits; /* pages per chunk bits */
- int chunk_mask;
+ pgoff_t chunk_mask;
int rc;
cur = osc_extent_alloc(obj);
@@ -700,8 +700,8 @@ restart:
if (!ext)
ext = first_extent(obj);
while (ext) {
- loff_t ext_chk_start = ext->oe_start >> ppc_bits;
- loff_t ext_chk_end = ext->oe_end >> ppc_bits;
+ pgoff_t ext_chk_start = ext->oe_start >> ppc_bits;
+ pgoff_t ext_chk_end = ext->oe_end >> ppc_bits;
LASSERT(sanity_check_nolock(ext) == 0);
if (chunk > ext_chk_end + 1)
@@ -913,7 +913,7 @@ int osc_extent_finish(const struct lu_env *env, struct osc_extent *ext,
return 0;
}
-static int extent_wait_cb(struct osc_extent *ext, int state)
+static int extent_wait_cb(struct osc_extent *ext, enum osc_extent_state state)
{
int ret;
@@ -928,7 +928,7 @@ static int extent_wait_cb(struct osc_extent *ext, int state)
* Wait for the extent's state to become @state.
*/
static int osc_extent_wait(const struct lu_env *env, struct osc_extent *ext,
- int state)
+ enum osc_extent_state state)
{
struct osc_object *obj = ext->oe_obj;
struct l_wait_info lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(600), NULL,
@@ -958,8 +958,8 @@ static int osc_extent_wait(const struct lu_env *env, struct osc_extent *ext,
rc = l_wait_event(ext->oe_waitq, extent_wait_cb(ext, state), &lwi);
if (rc == -ETIMEDOUT) {
OSC_EXTENT_DUMP(D_ERROR, ext,
- "%s: wait ext to %d timedout, recovery in progress?\n",
- osc_export(obj)->exp_obd->obd_name, state);
+ "%s: wait ext to %u timedout, recovery in progress?\n",
+ osc_export(obj)->exp_obd->obd_name, state);
lwi = LWI_INTR(NULL, NULL);
rc = l_wait_event(ext->oe_waitq, extent_wait_cb(ext, state),
@@ -1099,7 +1099,7 @@ static int osc_extent_make_ready(const struct lu_env *env,
struct osc_async_page *oap;
struct osc_async_page *last = NULL;
struct osc_object *obj = ext->oe_obj;
- int page_count = 0;
+ unsigned int page_count = 0;
int rc;
/* we're going to grab page lock, so object lock must not be taken. */
@@ -1140,9 +1140,11 @@ static int osc_extent_make_ready(const struct lu_env *env,
* the size of file.
*/
if (!(last->oap_async_flags & ASYNC_COUNT_STABLE)) {
- last->oap_count = osc_refresh_count(env, last, OBD_BRW_WRITE);
- LASSERT(last->oap_count > 0);
- LASSERT(last->oap_page_off + last->oap_count <= PAGE_SIZE);
+ int last_oap_count = osc_refresh_count(env, last, OBD_BRW_WRITE);
+
+ LASSERT(last_oap_count > 0);
+ LASSERT(last->oap_page_off + last_oap_count <= PAGE_SIZE);
+ last->oap_count = last_oap_count;
spin_lock(&last->oap_lock);
last->oap_async_flags |= ASYNC_COUNT_STABLE;
spin_unlock(&last->oap_lock);
@@ -1174,7 +1176,8 @@ static int osc_extent_make_ready(const struct lu_env *env,
* called to expand the extent for the same IO. To expand the extent, the
* page index must be in the same or next chunk of ext->oe_end.
*/
-static int osc_extent_expand(struct osc_extent *ext, pgoff_t index, int *grants)
+static int osc_extent_expand(struct osc_extent *ext, pgoff_t index,
+ unsigned int *grants)
{
struct osc_object *obj = ext->oe_obj;
struct client_obd *cli = osc_cli(obj);
@@ -1183,7 +1186,7 @@ static int osc_extent_expand(struct osc_extent *ext, pgoff_t index, int *grants)
pgoff_t chunk = index >> ppc_bits;
pgoff_t end_chunk;
pgoff_t end_index;
- int chunksize = 1 << cli->cl_chunkbits;
+ unsigned int chunksize = 1 << cli->cl_chunkbits;
int rc = 0;
LASSERT(ext->oe_max_end >= index && ext->oe_start <= index);
@@ -1361,7 +1364,7 @@ static int osc_completion(const struct lu_env *env, struct osc_async_page *oap,
if (rc == 0 && srvlock) {
struct lu_device *ld = opg->ops_cl.cpl_obj->co_lu.lo_dev;
struct osc_stats *stats = &lu2osc_dev(ld)->od_stats;
- int bytes = oap->oap_count;
+ size_t bytes = oap->oap_count;
if (crt == CRT_READ)
stats->os_lockless_reads += bytes;
@@ -1383,18 +1386,16 @@ static int osc_completion(const struct lu_env *env, struct osc_async_page *oap,
#define OSC_DUMP_GRANT(lvl, cli, fmt, args...) do { \
struct client_obd *__tmp = (cli); \
- CDEBUG(lvl, "%s: grant { dirty: %ld/%ld dirty_pages: %d/%d " \
- "unstable_pages: %d/%d dropped: %ld avail: %ld, " \
- "reserved: %ld, flight: %d } lru {in list: %d, " \
- "left: %d, waiters: %d }" fmt, \
+ CDEBUG(lvl, "%s: grant { dirty: %ld/%ld dirty_pages: %ld/%lu " \
+ "dropped: %ld avail: %ld, reserved: %ld, flight: %d }" \
+ "lru {in list: %ld, left: %ld, waiters: %d }" fmt "\n", \
__tmp->cl_import->imp_obd->obd_name, \
- __tmp->cl_dirty, __tmp->cl_dirty_max, \
- atomic_read(&obd_dirty_pages), obd_max_dirty_pages, \
- atomic_read(&obd_unstable_pages), obd_max_dirty_pages, \
+ __tmp->cl_dirty_pages, __tmp->cl_dirty_max_pages, \
+ atomic_long_read(&obd_dirty_pages), obd_max_dirty_pages, \
__tmp->cl_lost_grant, __tmp->cl_avail_grant, \
__tmp->cl_reserved_grant, __tmp->cl_w_in_flight, \
- atomic_read(&__tmp->cl_lru_in_list), \
- atomic_read(&__tmp->cl_lru_busy), \
+ atomic_long_read(&__tmp->cl_lru_in_list), \
+ atomic_long_read(&__tmp->cl_lru_busy), \
atomic_read(&__tmp->cl_lru_shrinkers), ##args); \
} while (0)
@@ -1404,8 +1405,8 @@ static void osc_consume_write_grant(struct client_obd *cli,
{
assert_spin_locked(&cli->cl_loi_list_lock);
LASSERT(!(pga->flag & OBD_BRW_FROM_GRANT));
- atomic_inc(&obd_dirty_pages);
- cli->cl_dirty += PAGE_SIZE;
+ atomic_long_inc(&obd_dirty_pages);
+ cli->cl_dirty_pages++;
pga->flag |= OBD_BRW_FROM_GRANT;
CDEBUG(D_CACHE, "using %lu grant credits for brw %p page %p\n",
PAGE_SIZE, pga, pga->pg);
@@ -1424,12 +1425,12 @@ static void osc_release_write_grant(struct client_obd *cli,
}
pga->flag &= ~OBD_BRW_FROM_GRANT;
- atomic_dec(&obd_dirty_pages);
- cli->cl_dirty -= PAGE_SIZE;
+ atomic_long_dec(&obd_dirty_pages);
+ cli->cl_dirty_pages--;
if (pga->flag & OBD_BRW_NOCACHE) {
pga->flag &= ~OBD_BRW_NOCACHE;
- atomic_dec(&obd_dirty_transit_pages);
- cli->cl_dirty_transit -= PAGE_SIZE;
+ atomic_long_dec(&obd_dirty_transit_pages);
+ cli->cl_dirty_transit--;
}
}
@@ -1494,11 +1495,11 @@ static void osc_unreserve_grant(struct client_obd *cli,
static void osc_free_grant(struct client_obd *cli, unsigned int nr_pages,
unsigned int lost_grant)
{
- int grant = (1 << cli->cl_chunkbits) + cli->cl_extent_tax;
+ unsigned long grant = (1 << cli->cl_chunkbits) + cli->cl_extent_tax;
spin_lock(&cli->cl_loi_list_lock);
- atomic_sub(nr_pages, &obd_dirty_pages);
- cli->cl_dirty -= nr_pages << PAGE_SHIFT;
+ atomic_long_sub(nr_pages, &obd_dirty_pages);
+ cli->cl_dirty_pages -= nr_pages;
cli->cl_lost_grant += lost_grant;
if (cli->cl_avail_grant < grant && cli->cl_lost_grant >= grant) {
/* borrow some grant from truncate to avoid the case that
@@ -1511,7 +1512,7 @@ static void osc_free_grant(struct client_obd *cli, unsigned int nr_pages,
spin_unlock(&cli->cl_loi_list_lock);
CDEBUG(D_CACHE, "lost %u grant: %lu avail: %lu dirty: %lu\n",
lost_grant, cli->cl_lost_grant,
- cli->cl_avail_grant, cli->cl_dirty);
+ cli->cl_avail_grant, cli->cl_dirty_pages << PAGE_SHIFT);
}
/**
@@ -1535,19 +1536,18 @@ static int osc_enter_cache_try(struct client_obd *cli,
{
int rc;
- OSC_DUMP_GRANT(D_CACHE, cli, "need:%d.\n", bytes);
+ OSC_DUMP_GRANT(D_CACHE, cli, "need:%d\n", bytes);
rc = osc_reserve_grant(cli, bytes);
if (rc < 0)
return 0;
- if (cli->cl_dirty + PAGE_SIZE <= cli->cl_dirty_max &&
- atomic_read(&obd_unstable_pages) + 1 +
- atomic_read(&obd_dirty_pages) <= obd_max_dirty_pages) {
+ if (cli->cl_dirty_pages <= cli->cl_dirty_max_pages &&
+ atomic_long_read(&obd_dirty_pages) + 1 <= obd_max_dirty_pages) {
osc_consume_write_grant(cli, &oap->oap_brw_page);
if (transient) {
- cli->cl_dirty_transit += PAGE_SIZE;
- atomic_inc(&obd_dirty_transit_pages);
+ cli->cl_dirty_transit++;
+ atomic_long_inc(&obd_dirty_transit_pages);
oap->oap_brw_flags |= OBD_BRW_NOCACHE;
}
rc = 1;
@@ -1581,11 +1581,13 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli,
struct osc_object *osc = oap->oap_obj;
struct lov_oinfo *loi = osc->oo_oinfo;
struct osc_cache_waiter ocw;
- struct l_wait_info lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(600), NULL,
- LWI_ON_SIGNAL_NOOP, NULL);
+ struct l_wait_info lwi;
int rc = -EDQUOT;
- OSC_DUMP_GRANT(D_CACHE, cli, "need:%d.\n", bytes);
+ lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(AT_OFF ? obd_timeout : at_max),
+ NULL, LWI_ON_SIGNAL_NOOP, NULL);
+
+ OSC_DUMP_GRANT(D_CACHE, cli, "need:%d\n", bytes);
spin_lock(&cli->cl_loi_list_lock);
@@ -1593,14 +1595,16 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli,
* of queued writes and create a discontiguous rpc stream
*/
if (OBD_FAIL_CHECK(OBD_FAIL_OSC_NO_GRANT) ||
- cli->cl_dirty_max < PAGE_SIZE ||
- cli->cl_ar.ar_force_sync || loi->loi_ar.ar_force_sync) {
+ !cli->cl_dirty_max_pages || cli->cl_ar.ar_force_sync ||
+ loi->loi_ar.ar_force_sync) {
+ OSC_DUMP_GRANT(D_CACHE, cli, "forced sync i/o\n");
rc = -EDQUOT;
goto out;
}
/* Hopefully normal case - cache space and write credits available */
if (osc_enter_cache_try(cli, oap, bytes, 0)) {
+ OSC_DUMP_GRANT(D_CACHE, cli, "granted from cache\n");
rc = 0;
goto out;
}
@@ -1615,7 +1619,7 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli,
init_waitqueue_head(&ocw.ocw_waitq);
ocw.ocw_oap = oap;
ocw.ocw_grant = bytes;
- while (cli->cl_dirty > 0 || cli->cl_w_in_flight > 0) {
+ while (cli->cl_dirty_pages > 0 || cli->cl_w_in_flight > 0) {
list_add_tail(&ocw.ocw_entry, &cli->cl_cache_waiters);
ocw.ocw_rc = 0;
spin_unlock(&cli->cl_loi_list_lock);
@@ -1629,32 +1633,49 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli,
spin_lock(&cli->cl_loi_list_lock);
- /* l_wait_event is interrupted by signal, or timed out */
if (rc < 0) {
- if (rc == -ETIMEDOUT) {
- OSC_DUMP_GRANT(D_ERROR, cli,
- "try to reserve %d.\n", bytes);
- osc_extent_tree_dump(D_ERROR, osc);
- rc = -EDQUOT;
- }
-
+ /* l_wait_event is interrupted by signal, or timed out */
list_del_init(&ocw.ocw_entry);
- goto out;
+ break;
}
-
LASSERT(list_empty(&ocw.ocw_entry));
rc = ocw.ocw_rc;
if (rc != -EDQUOT)
- goto out;
+ break;
if (osc_enter_cache_try(cli, oap, bytes, 0)) {
rc = 0;
- goto out;
+ break;
}
}
+
+ switch (rc) {
+ case 0:
+ OSC_DUMP_GRANT(D_CACHE, cli, "finally got grant space\n");
+ break;
+ case -ETIMEDOUT:
+ OSC_DUMP_GRANT(D_CACHE, cli,
+ "timeout, fall back to sync i/o\n");
+ osc_extent_tree_dump(D_CACHE, osc);
+ /* fall back to synchronous I/O */
+ rc = -EDQUOT;
+ break;
+ case -EINTR:
+ /* Ensures restartability - LU-3581 */
+ OSC_DUMP_GRANT(D_CACHE, cli, "interrupted\n");
+ rc = -ERESTARTSYS;
+ break;
+ case -EDQUOT:
+ OSC_DUMP_GRANT(D_CACHE, cli,
+ "no grant space, fall back to sync i/o\n");
+ break;
+ default:
+ CDEBUG(D_CACHE, "%s: event for cache space @ %p never arrived due to %d, fall back to sync i/o\n",
+ cli->cl_import->imp_obd->obd_name, &ocw, rc);
+ break;
+ }
out:
spin_unlock(&cli->cl_loi_list_lock);
- OSC_DUMP_GRANT(D_CACHE, cli, "returned %d.\n", rc);
return rc;
}
@@ -1670,19 +1691,17 @@ void osc_wake_cache_waiters(struct client_obd *cli)
ocw->ocw_rc = -EDQUOT;
/* we can't dirty more */
- if ((cli->cl_dirty + PAGE_SIZE > cli->cl_dirty_max) ||
- (atomic_read(&obd_unstable_pages) + 1 +
- atomic_read(&obd_dirty_pages) > obd_max_dirty_pages)) {
- CDEBUG(D_CACHE, "no dirty room: dirty: %ld osc max %ld, sys max %d\n",
- cli->cl_dirty,
- cli->cl_dirty_max, obd_max_dirty_pages);
+ if ((cli->cl_dirty_pages > cli->cl_dirty_max_pages) ||
+ (atomic_long_read(&obd_dirty_pages) + 1 >
+ obd_max_dirty_pages)) {
+ CDEBUG(D_CACHE, "no dirty room: dirty: %ld osc max %ld, sys max %ld\n",
+ cli->cl_dirty_pages, cli->cl_dirty_max_pages,
+ obd_max_dirty_pages);
goto wakeup;
}
- ocw->ocw_rc = 0;
- if (!osc_enter_cache_try(cli, ocw->ocw_oap, ocw->ocw_grant, 0))
- ocw->ocw_rc = -EDQUOT;
-
+ if (osc_enter_cache_try(cli, ocw->ocw_oap, ocw->ocw_grant, 0))
+ ocw->ocw_rc = 0;
wakeup:
CDEBUG(D_CACHE, "wake up %p for oap %p, avail grant %ld, %d\n",
ocw, ocw->ocw_oap, cli->cl_avail_grant, ocw->ocw_rc);
@@ -1843,97 +1862,6 @@ static void osc_process_ar(struct osc_async_rc *ar, __u64 xid,
ar->ar_force_sync = 0;
}
-/**
- * Performs "unstable" page accounting. This function balances the
- * increment operations performed in osc_inc_unstable_pages. It is
- * registered as the RPC request callback, and is executed when the
- * bulk RPC is committed on the server. Thus at this point, the pages
- * involved in the bulk transfer are no longer considered unstable.
- */
-void osc_dec_unstable_pages(struct ptlrpc_request *req)
-{
- struct client_obd *cli = &req->rq_import->imp_obd->u.cli;
- struct ptlrpc_bulk_desc *desc = req->rq_bulk;
- int page_count = desc->bd_iov_count;
- int i;
-
- /* No unstable page tracking */
- if (!cli->cl_cache)
- return;
-
- LASSERT(page_count >= 0);
-
- for (i = 0; i < page_count; i++)
- dec_node_page_state(desc->bd_iov[i].kiov_page,
- NR_UNSTABLE_NFS);
-
- atomic_sub(page_count, &cli->cl_cache->ccc_unstable_nr);
- LASSERT(atomic_read(&cli->cl_cache->ccc_unstable_nr) >= 0);
-
- atomic_sub(page_count, &cli->cl_unstable_count);
- LASSERT(atomic_read(&cli->cl_unstable_count) >= 0);
-
- atomic_sub(page_count, &obd_unstable_pages);
- LASSERT(atomic_read(&obd_unstable_pages) >= 0);
-
- spin_lock(&req->rq_lock);
- req->rq_committed = 1;
- req->rq_unstable = 0;
- spin_unlock(&req->rq_lock);
-
- wake_up_all(&cli->cl_cache->ccc_unstable_waitq);
-}
-
-/* "unstable" page accounting. See: osc_dec_unstable_pages. */
-void osc_inc_unstable_pages(struct ptlrpc_request *req)
-{
- struct client_obd *cli = &req->rq_import->imp_obd->u.cli;
- struct ptlrpc_bulk_desc *desc = req->rq_bulk;
- long page_count = desc->bd_iov_count;
- int i;
-
- /* No unstable page tracking */
- if (!cli->cl_cache)
- return;
-
- LASSERT(page_count >= 0);
-
- for (i = 0; i < page_count; i++)
- inc_node_page_state(desc->bd_iov[i].kiov_page,
- NR_UNSTABLE_NFS);
-
- LASSERT(atomic_read(&cli->cl_cache->ccc_unstable_nr) >= 0);
- atomic_add(page_count, &cli->cl_cache->ccc_unstable_nr);
-
- LASSERT(atomic_read(&cli->cl_unstable_count) >= 0);
- atomic_add(page_count, &cli->cl_unstable_count);
-
- LASSERT(atomic_read(&obd_unstable_pages) >= 0);
- atomic_add(page_count, &obd_unstable_pages);
-
- spin_lock(&req->rq_lock);
-
- /*
- * If the request has already been committed (i.e. brw_commit
- * called via rq_commit_cb), we need to undo the unstable page
- * increments we just performed because rq_commit_cb wont be
- * called again. Otherwise, just set the commit callback so the
- * unstable page accounting is properly updated when the request
- * is committed
- */
- if (req->rq_committed) {
- /* Drop lock before calling osc_dec_unstable_pages */
- spin_unlock(&req->rq_lock);
- osc_dec_unstable_pages(req);
- spin_lock(&req->rq_lock);
- } else {
- req->rq_unstable = 1;
- req->rq_commit_cb = osc_dec_unstable_pages;
- }
-
- spin_unlock(&req->rq_lock);
-}
-
/* this must be called holding the loi list lock to give coverage to exit_cache,
* async_flag maintenance, and oap_request
*/
@@ -1945,9 +1873,6 @@ static void osc_ap_completion(const struct lu_env *env, struct client_obd *cli,
__u64 xid = 0;
if (oap->oap_request) {
- if (!rc)
- osc_inc_unstable_pages(oap->oap_request);
-
xid = ptlrpc_req_xid(oap->oap_request);
ptlrpc_req_finished(oap->oap_request);
oap->oap_request = NULL;
@@ -1979,7 +1904,7 @@ static void osc_ap_completion(const struct lu_env *env, struct client_obd *cli,
*/
static int try_to_add_extent_for_io(struct client_obd *cli,
struct osc_extent *ext, struct list_head *rpclist,
- int *pc, unsigned int *max_pages)
+ unsigned int *pc, unsigned int *max_pages)
{
struct osc_extent *tmp;
struct osc_async_page *oap = list_first_entry(&ext->oe_pages,
@@ -2032,12 +1957,13 @@ static int try_to_add_extent_for_io(struct client_obd *cli,
* 5. Traverse the extent tree from the 1st extent;
* 6. Above steps exit if there is no space in this RPC.
*/
-static int get_write_extents(struct osc_object *obj, struct list_head *rpclist)
+static unsigned int get_write_extents(struct osc_object *obj,
+ struct list_head *rpclist)
{
struct client_obd *cli = osc_cli(obj);
struct osc_extent *ext;
struct osc_extent *temp;
- int page_count = 0;
+ unsigned int page_count = 0;
unsigned int max_pages = cli->cl_max_pages_per_rpc;
LASSERT(osc_object_is_locked(obj));
@@ -2175,7 +2101,7 @@ osc_send_read_rpc(const struct lu_env *env, struct client_obd *cli,
struct osc_extent *ext;
struct osc_extent *next;
LIST_HEAD(rpclist);
- int page_count = 0;
+ unsigned int page_count = 0;
unsigned int max_pages = cli->cl_max_pages_per_rpc;
int rc = 0;
@@ -2390,7 +2316,7 @@ int osc_queue_async_io(const struct lu_env *env, struct cl_io *io,
struct client_obd *cli = oap->oap_cli;
struct osc_object *osc = oap->oap_obj;
pgoff_t index;
- int grants = 0;
+ unsigned int grants = 0, tmp;
int brw_flags = OBD_BRW_ASYNC;
int cmd = OBD_BRW_WRITE;
int need_release = 0;
@@ -2434,9 +2360,6 @@ int osc_queue_async_io(const struct lu_env *env, struct cl_io *io,
return rc;
}
- if (osc_over_unstable_soft_limit(cli))
- brw_flags |= OBD_BRW_SOFT_SYNC;
-
oap->oap_cmd = cmd;
oap->oap_page_off = ops->ops_from;
oap->oap_count = ops->ops_to - ops->ops_from;
@@ -2476,7 +2399,7 @@ int osc_queue_async_io(const struct lu_env *env, struct cl_io *io,
grants = 0;
need_release = 1;
} else if (ext->oe_end < index) {
- int tmp = grants;
+ tmp = grants;
/* try to expand this extent */
rc = osc_extent_expand(ext, index, &tmp);
if (rc < 0) {
@@ -2501,7 +2424,7 @@ int osc_queue_async_io(const struct lu_env *env, struct cl_io *io,
}
if (!ext) {
- int tmp = (1 << cli->cl_chunkbits) + cli->cl_extent_tax;
+ tmp = (1 << cli->cl_chunkbits) + cli->cl_extent_tax;
/* try to find new extent to cover this page */
LASSERT(!oio->oi_active);
@@ -2645,7 +2568,7 @@ int osc_flush_async_page(const struct lu_env *env, struct cl_io *io,
goto out;
spin_lock(&oap->oap_lock);
- oap->oap_async_flags |= ASYNC_READY|ASYNC_URGENT;
+ oap->oap_async_flags |= ASYNC_READY | ASYNC_URGENT;
spin_unlock(&oap->oap_lock);
if (memory_pressure_get())
diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
index c8c3f1ca77be..9c8de15c309c 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
+++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
@@ -64,7 +64,7 @@ struct osc_io {
/** true if this io is lockless. */
unsigned int oi_lockless;
/** how many LRU pages are reserved for this IO */
- int oi_lru_reserved;
+ unsigned long oi_lru_reserved;
/** active extents, we know how many bytes is going to be written,
* so having an active extent will prevent it from being fragmented
@@ -389,7 +389,7 @@ extern struct lu_device_type osc_device_type;
extern struct lu_context_key osc_key;
extern struct lu_context_key osc_session_key;
-#define OSC_FLAGS (ASYNC_URGENT|ASYNC_READY)
+#define OSC_FLAGS (ASYNC_URGENT | ASYNC_READY)
int osc_lock_init(const struct lu_env *env,
struct cl_object *obj, struct cl_lock *lock,
@@ -608,7 +608,7 @@ struct osc_extent {
/** link list of osc_object's oo_{hp|urgent|locking}_exts. */
struct list_head oe_link;
/** state of this extent */
- unsigned int oe_state;
+ enum osc_extent_state oe_state;
/** flags for this extent. */
unsigned int oe_intree:1,
/** 0 is write, 1 is read */
diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h
index 7a27f0961955..67fe0a254991 100644
--- a/drivers/staging/lustre/lustre/osc/osc_internal.h
+++ b/drivers/staging/lustre/lustre/osc/osc_internal.h
@@ -71,7 +71,6 @@ struct osc_async_page {
struct client_obd *oap_cli;
struct osc_object *oap_obj;
- struct ldlm_lock *oap_ldlm_lock;
spinlock_t oap_lock;
};
@@ -134,9 +133,9 @@ int osc_sync_base(struct obd_export *exp, struct obd_info *oinfo,
int osc_process_config_base(struct obd_device *obd, struct lustre_cfg *cfg);
int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
struct list_head *ext_list, int cmd);
-int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
- int target, bool force);
-int osc_lru_reclaim(struct client_obd *cli);
+long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
+ long target, bool force);
+long osc_lru_reclaim(struct client_obd *cli);
unsigned long osc_ldlm_weigh_ast(struct ldlm_lock *dlmlock);
@@ -198,7 +197,7 @@ int osc_quotacheck(struct obd_device *unused, struct obd_export *exp,
int osc_quota_poll_check(struct obd_export *exp, struct if_quotacheck *qchk);
void osc_inc_unstable_pages(struct ptlrpc_request *req);
void osc_dec_unstable_pages(struct ptlrpc_request *req);
-int osc_over_unstable_soft_limit(struct client_obd *cli);
+bool osc_over_unstable_soft_limit(struct client_obd *cli);
struct ldlm_lock *osc_dlmlock_at_pgoff(const struct lu_env *env,
struct osc_object *obj, pgoff_t index,
diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c
index 6e3dcd38913f..8a559cbcdd0c 100644
--- a/drivers/staging/lustre/lustre/osc/osc_io.c
+++ b/drivers/staging/lustre/lustre/osc/osc_io.c
@@ -109,11 +109,11 @@ static int osc_io_submit(const struct lu_env *env,
struct cl_page_list *qin = &queue->c2_qin;
struct cl_page_list *qout = &queue->c2_qout;
- int queued = 0;
+ unsigned int queued = 0;
int result = 0;
int cmd;
int brw_flags;
- int max_pages;
+ unsigned int max_pages;
LASSERT(qin->pl_nr > 0);
@@ -163,14 +163,19 @@ static int osc_io_submit(const struct lu_env *env,
continue;
}
- cl_page_list_move(qout, qin, page);
spin_lock(&oap->oap_lock);
- oap->oap_async_flags = ASYNC_URGENT|ASYNC_READY;
+ oap->oap_async_flags = ASYNC_URGENT | ASYNC_READY;
oap->oap_async_flags |= ASYNC_COUNT_STABLE;
spin_unlock(&oap->oap_lock);
osc_page_submit(env, opg, crt, brw_flags);
list_add_tail(&oap->oap_pending_item, &list);
+
+ if (page->cp_sync_io)
+ cl_page_list_move(qout, qin, page);
+ else /* async IO */
+ cl_page_list_del(env, qin, page);
+
if (++queued == max_pages) {
queued = 0;
result = osc_queue_sync_pages(env, osc, &list, cmd,
@@ -195,7 +200,7 @@ static int osc_io_submit(const struct lu_env *env,
* Expand stripe KMS if necessary.
*/
static void osc_page_touch_at(const struct lu_env *env,
- struct cl_object *obj, pgoff_t idx, unsigned to)
+ struct cl_object *obj, pgoff_t idx, size_t to)
{
struct lov_oinfo *loi = cl2osc(obj)->oo_oinfo;
struct cl_attr *attr = &osc_env_info(env)->oti_attr;
@@ -228,7 +233,7 @@ static void osc_page_touch_at(const struct lu_env *env,
attr->cat_size = kms;
valid |= CAT_SIZE;
}
- cl_object_attr_set(env, obj, attr, valid);
+ cl_object_attr_update(env, obj, attr, valid);
cl_object_attr_unlock(obj);
}
@@ -314,8 +319,8 @@ static int osc_io_rw_iter_init(const struct lu_env *env,
struct osc_object *osc = cl2osc(ios->cis_obj);
struct client_obd *cli = osc_cli(osc);
unsigned long c;
- unsigned int npages;
- unsigned int max_pages;
+ unsigned long npages;
+ unsigned long max_pages;
if (cl_io_is_append(io))
return 0;
@@ -328,15 +333,15 @@ static int osc_io_rw_iter_init(const struct lu_env *env,
if (npages > max_pages)
npages = max_pages;
- c = atomic_read(cli->cl_lru_left);
+ c = atomic_long_read(cli->cl_lru_left);
if (c < npages && osc_lru_reclaim(cli) > 0)
- c = atomic_read(cli->cl_lru_left);
+ c = atomic_long_read(cli->cl_lru_left);
while (c >= npages) {
- if (c == atomic_cmpxchg(cli->cl_lru_left, c, c - npages)) {
+ if (c == atomic_long_cmpxchg(cli->cl_lru_left, c, c - npages)) {
oio->oi_lru_reserved = npages;
break;
}
- c = atomic_read(cli->cl_lru_left);
+ c = atomic_long_read(cli->cl_lru_left);
}
return 0;
@@ -350,7 +355,7 @@ static void osc_io_rw_iter_fini(const struct lu_env *env,
struct client_obd *cli = osc_cli(osc);
if (oio->oi_lru_reserved > 0) {
- atomic_add(oio->oi_lru_reserved, cli->cl_lru_left);
+ atomic_long_add(oio->oi_lru_reserved, cli->cl_lru_left);
oio->oi_lru_reserved = 0;
}
oio->oi_write_osclock = NULL;
@@ -364,7 +369,7 @@ static int osc_io_fault_start(const struct lu_env *env,
io = ios->cis_io;
fio = &io->u.ci_fault;
- CDEBUG(D_INFO, "%lu %d %d\n",
+ CDEBUG(D_INFO, "%lu %d %zu\n",
fio->ft_index, fio->ft_writable, fio->ft_nob);
/*
* If mapping is writeable, adjust kms to cover this page,
@@ -471,18 +476,21 @@ static int osc_io_setattr_start(const struct lu_env *env,
attr->cat_ctime = lvb->lvb_ctime;
cl_valid |= CAT_CTIME;
}
- result = cl_object_attr_set(env, obj, attr, cl_valid);
+ result = cl_object_attr_update(env, obj, attr,
+ cl_valid);
}
cl_object_attr_unlock(obj);
}
memset(oa, 0, sizeof(*oa));
if (result == 0) {
oa->o_oi = loi->loi_oi;
+ obdo_set_parent_fid(oa, io->u.ci_setattr.sa_parent_fid);
+ oa->o_stripe_idx = io->u.ci_setattr.sa_stripe_index;
oa->o_mtime = attr->cat_mtime;
oa->o_atime = attr->cat_atime;
oa->o_ctime = attr->cat_ctime;
- oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP | OBD_MD_FLATIME |
- OBD_MD_FLCTIME | OBD_MD_FLMTIME;
+ oa->o_valid |= OBD_MD_FLID | OBD_MD_FLGROUP | OBD_MD_FLATIME |
+ OBD_MD_FLCTIME | OBD_MD_FLMTIME;
if (ia_valid & ATTR_SIZE) {
oa->o_size = size;
oa->o_blocks = OBD_OBJECT_EOF;
@@ -559,7 +567,7 @@ static int osc_io_read_start(const struct lu_env *env,
if (!slice->cis_io->ci_noatime) {
cl_object_attr_lock(obj);
attr->cat_atime = ktime_get_real_seconds();
- rc = cl_object_attr_set(env, obj, attr, CAT_ATIME);
+ rc = cl_object_attr_update(env, obj, attr, CAT_ATIME);
cl_object_attr_unlock(obj);
}
return rc;
@@ -576,7 +584,7 @@ static int osc_io_write_start(const struct lu_env *env,
cl_object_attr_lock(obj);
attr->cat_ctime = ktime_get_real_seconds();
attr->cat_mtime = attr->cat_ctime;
- rc = cl_object_attr_set(env, obj, attr, CAT_MTIME | CAT_CTIME);
+ rc = cl_object_attr_update(env, obj, attr, CAT_MTIME | CAT_CTIME);
cl_object_attr_unlock(obj);
return rc;
diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c
index 717d3ffb6789..39a8a5851603 100644
--- a/drivers/staging/lustre/lustre/osc/osc_lock.c
+++ b/drivers/staging/lustre/lustre/osc/osc_lock.c
@@ -222,7 +222,7 @@ static void osc_lock_lvb_update(const struct lu_env *env,
ldlm_lock_allow_match_locked(dlmlock);
}
- cl_object_attr_set(env, obj, attr, valid);
+ cl_object_attr_update(env, obj, attr, valid);
cl_object_attr_unlock(obj);
}
@@ -467,7 +467,7 @@ static int osc_dlm_blocking_ast0(const struct lu_env *env,
*/
attr->cat_kms = ldlm_extent_shift_kms(dlmlock, old_kms);
- cl_object_attr_set(env, obj, attr, CAT_KMS);
+ cl_object_attr_update(env, obj, attr, CAT_KMS);
cl_object_attr_unlock(obj);
unlock_res_and_lock(dlmlock);
diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c
index d211d1905e83..aae3a2d4243f 100644
--- a/drivers/staging/lustre/lustre/osc/osc_object.c
+++ b/drivers/staging/lustre/lustre/osc/osc_object.c
@@ -159,8 +159,8 @@ static int osc_attr_get(const struct lu_env *env, struct cl_object *obj,
return 0;
}
-static int osc_attr_set(const struct lu_env *env, struct cl_object *obj,
- const struct cl_attr *attr, unsigned valid)
+static int osc_attr_update(const struct lu_env *env, struct cl_object *obj,
+ const struct cl_attr *attr, unsigned int valid)
{
struct lov_oinfo *oinfo = cl2osc(obj)->oo_oinfo;
struct ost_lvb *lvb = &oinfo->loi_lvb;
@@ -195,7 +195,6 @@ static int osc_object_glimpse(const struct lu_env *env,
static int osc_object_ast_clear(struct ldlm_lock *lock, void *data)
{
- LASSERT(lock->l_granted_mode == lock->l_req_mode);
if (lock->l_ast_data == data)
lock->l_ast_data = NULL;
return LDLM_ITER_CONTINUE;
@@ -262,7 +261,7 @@ static const struct cl_object_operations osc_ops = {
.coo_lock_init = osc_lock_init,
.coo_io_init = osc_io_init,
.coo_attr_get = osc_attr_get,
- .coo_attr_set = osc_attr_set,
+ .coo_attr_update = osc_attr_update,
.coo_glimpse = osc_object_glimpse,
.coo_prune = osc_object_prune
};
diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c
index 355f496a2093..2a7a70aa9e80 100644
--- a/drivers/staging/lustre/lustre/osc/osc_page.c
+++ b/drivers/staging/lustre/lustre/osc/osc_page.c
@@ -323,32 +323,6 @@ int osc_page_init(const struct lu_env *env, struct cl_object *obj,
return result;
}
-int osc_over_unstable_soft_limit(struct client_obd *cli)
-{
- long obd_upages, obd_dpages, osc_upages;
-
- /* Can't check cli->cl_unstable_count, therefore, no soft limit */
- if (!cli)
- return 0;
-
- obd_upages = atomic_read(&obd_unstable_pages);
- obd_dpages = atomic_read(&obd_dirty_pages);
-
- osc_upages = atomic_read(&cli->cl_unstable_count);
-
- /*
- * obd_max_dirty_pages is the max number of (dirty + unstable)
- * pages allowed at any given time. To simulate an unstable page
- * only limit, we subtract the current number of dirty pages
- * from this max. This difference is roughly the amount of pages
- * currently available for unstable pages. Thus, the soft limit
- * is half of that difference. Check osc_upages to ensure we don't
- * set SOFT_SYNC for OSCs without any outstanding unstable pages.
- */
- return osc_upages &&
- obd_upages >= (obd_max_dirty_pages - obd_dpages) / 2;
-}
-
/**
* Helper function called by osc_io_submit() for every page in an immediate
* transfer (i.e., transferred synchronously).
@@ -368,9 +342,6 @@ void osc_page_submit(const struct lu_env *env, struct osc_page *opg,
oap->oap_count = opg->ops_to - opg->ops_from;
oap->oap_brw_flags = brw_flags | OBD_BRW_SYNC;
- if (osc_over_unstable_soft_limit(oap->oap_cli))
- oap->oap_brw_flags |= OBD_BRW_SOFT_SYNC;
-
if (capable(CFS_CAP_SYS_RESOURCE)) {
oap->oap_brw_flags |= OBD_BRW_NOQUOTA;
oap->oap_cmd |= OBD_BRW_NOQUOTA;
@@ -409,7 +380,7 @@ static const int lru_shrink_max = 8 << (20 - PAGE_SHIFT); /* 8M */
static int osc_cache_too_much(struct client_obd *cli)
{
struct cl_client_cache *cache = cli->cl_cache;
- int pages = atomic_read(&cli->cl_lru_in_list);
+ long pages = atomic_long_read(&cli->cl_lru_in_list);
unsigned long budget;
budget = cache->ccc_lru_max / (atomic_read(&cache->ccc_users) - 2);
@@ -417,7 +388,7 @@ static int osc_cache_too_much(struct client_obd *cli)
/* if it's going to run out LRU slots, we should free some, but not
* too much to maintain fairness among OSCs.
*/
- if (atomic_read(cli->cl_lru_left) < cache->ccc_lru_max >> 4) {
+ if (atomic_long_read(cli->cl_lru_left) < cache->ccc_lru_max >> 4) {
if (pages >= budget)
return lru_shrink_max;
else if (pages >= budget / 2)
@@ -444,7 +415,7 @@ void osc_lru_add_batch(struct client_obd *cli, struct list_head *plist)
{
LIST_HEAD(lru);
struct osc_async_page *oap;
- int npages = 0;
+ long npages = 0;
list_for_each_entry(oap, plist, oap_pending_item) {
struct osc_page *opg = oap2osc_page(oap);
@@ -460,8 +431,8 @@ void osc_lru_add_batch(struct client_obd *cli, struct list_head *plist)
if (npages > 0) {
spin_lock(&cli->cl_lru_list_lock);
list_splice_tail(&lru, &cli->cl_lru_list);
- atomic_sub(npages, &cli->cl_lru_busy);
- atomic_add(npages, &cli->cl_lru_in_list);
+ atomic_long_sub(npages, &cli->cl_lru_busy);
+ atomic_long_add(npages, &cli->cl_lru_in_list);
spin_unlock(&cli->cl_lru_list_lock);
/* XXX: May set force to be true for better performance */
@@ -472,9 +443,9 @@ void osc_lru_add_batch(struct client_obd *cli, struct list_head *plist)
static void __osc_lru_del(struct client_obd *cli, struct osc_page *opg)
{
- LASSERT(atomic_read(&cli->cl_lru_in_list) > 0);
+ LASSERT(atomic_long_read(&cli->cl_lru_in_list) > 0);
list_del_init(&opg->ops_lru);
- atomic_dec(&cli->cl_lru_in_list);
+ atomic_long_dec(&cli->cl_lru_in_list);
}
/**
@@ -488,12 +459,12 @@ static void osc_lru_del(struct client_obd *cli, struct osc_page *opg)
if (!list_empty(&opg->ops_lru)) {
__osc_lru_del(cli, opg);
} else {
- LASSERT(atomic_read(&cli->cl_lru_busy) > 0);
- atomic_dec(&cli->cl_lru_busy);
+ LASSERT(atomic_long_read(&cli->cl_lru_busy) > 0);
+ atomic_long_dec(&cli->cl_lru_busy);
}
spin_unlock(&cli->cl_lru_list_lock);
- atomic_inc(cli->cl_lru_left);
+ atomic_long_inc(cli->cl_lru_left);
/* this is a great place to release more LRU pages if
* this osc occupies too many LRU pages and kernel is
* stealing one of them.
@@ -518,7 +489,7 @@ static void osc_lru_use(struct client_obd *cli, struct osc_page *opg)
spin_lock(&cli->cl_lru_list_lock);
__osc_lru_del(cli, opg);
spin_unlock(&cli->cl_lru_list_lock);
- atomic_inc(&cli->cl_lru_busy);
+ atomic_long_inc(&cli->cl_lru_busy);
}
}
@@ -540,10 +511,32 @@ static void discard_pagevec(const struct lu_env *env, struct cl_io *io,
}
/**
+ * Check if a cl_page can be released, i.e, it's not being used.
+ *
+ * If unstable account is turned on, bulk transfer may hold one refcount
+ * for recovery so we need to check vmpage refcount as well; otherwise,
+ * even we can destroy cl_page but the corresponding vmpage can't be reused.
+ */
+static inline bool lru_page_busy(struct client_obd *cli, struct cl_page *page)
+{
+ if (cl_page_in_use_noref(page))
+ return true;
+
+ if (cli->cl_cache->ccc_unstable_check) {
+ struct page *vmpage = cl_page_vmpage(page);
+
+ /* vmpage have two known users: cl_page and VM page cache */
+ if (page_count(vmpage) - page_mapcount(vmpage) > 2)
+ return true;
+ }
+ return false;
+}
+
+/**
* Drop @target of pages from LRU at most.
*/
-int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
- int target, bool force)
+long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
+ long target, bool force)
{
struct cl_io *io;
struct cl_object *clobj = NULL;
@@ -551,12 +544,12 @@ int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
struct osc_page *opg;
struct osc_page *temp;
int maxscan = 0;
- int count = 0;
+ long count = 0;
int index = 0;
int rc = 0;
- LASSERT(atomic_read(&cli->cl_lru_in_list) >= 0);
- if (atomic_read(&cli->cl_lru_in_list) == 0 || target <= 0)
+ LASSERT(atomic_long_read(&cli->cl_lru_in_list) >= 0);
+ if (atomic_long_read(&cli->cl_lru_in_list) == 0 || target <= 0)
return 0;
if (!force) {
@@ -575,7 +568,7 @@ int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
io = &osc_env_info(env)->oti_io;
spin_lock(&cli->cl_lru_list_lock);
- maxscan = min(target << 1, atomic_read(&cli->cl_lru_in_list));
+ maxscan = min(target << 1, atomic_long_read(&cli->cl_lru_in_list));
list_for_each_entry_safe(opg, temp, &cli->cl_lru_list, ops_lru) {
struct cl_page *page;
bool will_free = false;
@@ -584,7 +577,7 @@ int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
break;
page = opg->ops_cl.cpl_page;
- if (cl_page_in_use_noref(page)) {
+ if (lru_page_busy(cli, page)) {
list_move_tail(&opg->ops_lru, &cli->cl_lru_list);
continue;
}
@@ -620,7 +613,7 @@ int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
}
if (cl_page_own_try(env, io, page) == 0) {
- if (!cl_page_in_use_noref(page)) {
+ if (!lru_page_busy(cli, page)) {
/* remove it from lru list earlier to avoid
* lock contention
*/
@@ -663,24 +656,19 @@ int osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
atomic_dec(&cli->cl_lru_shrinkers);
if (count > 0) {
- atomic_add(count, cli->cl_lru_left);
+ atomic_long_add(count, cli->cl_lru_left);
wake_up_all(&osc_lru_waitq);
}
return count > 0 ? count : rc;
}
-static inline int max_to_shrink(struct client_obd *cli)
-{
- return min(atomic_read(&cli->cl_lru_in_list) >> 1, lru_shrink_max);
-}
-
-int osc_lru_reclaim(struct client_obd *cli)
+long osc_lru_reclaim(struct client_obd *cli)
{
struct cl_env_nest nest;
struct lu_env *env;
struct cl_client_cache *cache = cli->cl_cache;
int max_scans;
- int rc = 0;
+ long rc = 0;
LASSERT(cache);
@@ -693,15 +681,15 @@ int osc_lru_reclaim(struct client_obd *cli)
if (rc == -EBUSY)
rc = 0;
- CDEBUG(D_CACHE, "%s: Free %d pages from own LRU: %p.\n",
+ CDEBUG(D_CACHE, "%s: Free %ld pages from own LRU: %p.\n",
cli->cl_import->imp_obd->obd_name, rc, cli);
goto out;
}
- CDEBUG(D_CACHE, "%s: cli %p no free slots, pages: %d, busy: %d.\n",
+ CDEBUG(D_CACHE, "%s: cli %p no free slots, pages: %ld, busy: %ld.\n",
cli->cl_import->imp_obd->obd_name, cli,
- atomic_read(&cli->cl_lru_in_list),
- atomic_read(&cli->cl_lru_busy));
+ atomic_long_read(&cli->cl_lru_in_list),
+ atomic_long_read(&cli->cl_lru_busy));
/* Reclaim LRU slots from other client_obd as it can't free enough
* from its own. This should rarely happen.
@@ -717,10 +705,10 @@ int osc_lru_reclaim(struct client_obd *cli)
cli = list_entry(cache->ccc_lru.next, struct client_obd,
cl_lru_osc);
- CDEBUG(D_CACHE, "%s: cli %p LRU pages: %d, busy: %d.\n",
+ CDEBUG(D_CACHE, "%s: cli %p LRU pages: %ld, busy: %ld.\n",
cli->cl_import->imp_obd->obd_name, cli,
- atomic_read(&cli->cl_lru_in_list),
- atomic_read(&cli->cl_lru_busy));
+ atomic_long_read(&cli->cl_lru_in_list),
+ atomic_long_read(&cli->cl_lru_busy));
list_move_tail(&cli->cl_lru_osc, &cache->ccc_lru);
if (osc_cache_too_much(cli) > 0) {
@@ -737,11 +725,18 @@ int osc_lru_reclaim(struct client_obd *cli)
out:
cl_env_nested_put(&nest, env);
- CDEBUG(D_CACHE, "%s: cli %p freed %d pages.\n",
+ CDEBUG(D_CACHE, "%s: cli %p freed %ld pages.\n",
cli->cl_import->imp_obd->obd_name, cli, rc);
return rc;
}
+/**
+ * osc_lru_reserve() is called to reserve an LRU slot for a cl_page.
+ *
+ * Usually the LRU slots are reserved in osc_io_iter_rw_init().
+ * Only in the case that the LRU slots are in extreme shortage, it should
+ * have reserved enough slots for an IO.
+ */
static int osc_lru_reserve(const struct lu_env *env, struct osc_object *obj,
struct osc_page *opg)
{
@@ -758,8 +753,8 @@ static int osc_lru_reserve(const struct lu_env *env, struct osc_object *obj,
goto out;
}
- LASSERT(atomic_read(cli->cl_lru_left) >= 0);
- while (!atomic_add_unless(cli->cl_lru_left, -1, 0)) {
+ LASSERT(atomic_long_read(cli->cl_lru_left) >= 0);
+ while (!atomic_long_add_unless(cli->cl_lru_left, -1, 0)) {
/* run out of LRU spaces, try to drop some by itself */
rc = osc_lru_reclaim(cli);
if (rc < 0)
@@ -770,7 +765,7 @@ static int osc_lru_reserve(const struct lu_env *env, struct osc_object *obj,
cond_resched();
rc = l_wait_event(osc_lru_waitq,
- atomic_read(cli->cl_lru_left) > 0,
+ atomic_long_read(cli->cl_lru_left) > 0,
&lwi);
if (rc < 0)
@@ -779,7 +774,7 @@ static int osc_lru_reserve(const struct lu_env *env, struct osc_object *obj,
out:
if (rc >= 0) {
- atomic_inc(&cli->cl_lru_busy);
+ atomic_long_inc(&cli->cl_lru_busy);
opg->ops_in_lru = 1;
rc = 0;
}
@@ -787,4 +782,151 @@ out:
return rc;
}
+/**
+ * Atomic operations are expensive. We accumulate the accounting for the
+ * same page pgdat to get better performance.
+ * In practice this can work pretty good because the pages in the same RPC
+ * are likely from the same page zone.
+ */
+static inline void unstable_page_accounting(struct ptlrpc_bulk_desc *desc,
+ int factor)
+{
+ int page_count = desc->bd_iov_count;
+ pg_data_t *last = NULL;
+ int count = 0;
+ int i;
+
+ for (i = 0; i < page_count; i++) {
+ pg_data_t *pgdat = page_pgdat(desc->bd_iov[i].bv_page);
+
+ if (likely(pgdat == last)) {
+ ++count;
+ continue;
+ }
+
+ if (count > 0) {
+ mod_node_page_state(pgdat, NR_UNSTABLE_NFS,
+ factor * count);
+ count = 0;
+ }
+ last = pgdat;
+ ++count;
+ }
+ if (count > 0)
+ mod_node_page_state(last, NR_UNSTABLE_NFS, factor * count);
+}
+
+static inline void add_unstable_page_accounting(struct ptlrpc_bulk_desc *desc)
+{
+ unstable_page_accounting(desc, 1);
+}
+
+static inline void dec_unstable_page_accounting(struct ptlrpc_bulk_desc *desc)
+{
+ unstable_page_accounting(desc, -1);
+}
+
+/**
+ * Performs "unstable" page accounting. This function balances the
+ * increment operations performed in osc_inc_unstable_pages. It is
+ * registered as the RPC request callback, and is executed when the
+ * bulk RPC is committed on the server. Thus at this point, the pages
+ * involved in the bulk transfer are no longer considered unstable.
+ *
+ * If this function is called, the request should have been committed
+ * or req:rq_unstable must have been set; it implies that the unstable
+ * statistic have been added.
+ */
+void osc_dec_unstable_pages(struct ptlrpc_request *req)
+{
+ struct client_obd *cli = &req->rq_import->imp_obd->u.cli;
+ struct ptlrpc_bulk_desc *desc = req->rq_bulk;
+ int page_count = desc->bd_iov_count;
+ long unstable_count;
+
+ LASSERT(page_count >= 0);
+ dec_unstable_page_accounting(desc);
+
+ unstable_count = atomic_long_sub_return(page_count,
+ &cli->cl_unstable_count);
+ LASSERT(unstable_count >= 0);
+
+ unstable_count = atomic_long_sub_return(page_count,
+ &cli->cl_cache->ccc_unstable_nr);
+ LASSERT(unstable_count >= 0);
+ if (!unstable_count)
+ wake_up_all(&cli->cl_cache->ccc_unstable_waitq);
+
+ if (osc_cache_too_much(cli))
+ (void)ptlrpcd_queue_work(cli->cl_lru_work);
+}
+
+/**
+ * "unstable" page accounting. See: osc_dec_unstable_pages.
+ */
+void osc_inc_unstable_pages(struct ptlrpc_request *req)
+{
+ struct client_obd *cli = &req->rq_import->imp_obd->u.cli;
+ struct ptlrpc_bulk_desc *desc = req->rq_bulk;
+ long page_count = desc->bd_iov_count;
+
+ /* No unstable page tracking */
+ if (!cli->cl_cache || !cli->cl_cache->ccc_unstable_check)
+ return;
+
+ add_unstable_page_accounting(desc);
+ atomic_long_add(page_count, &cli->cl_unstable_count);
+ atomic_long_add(page_count, &cli->cl_cache->ccc_unstable_nr);
+
+ /*
+ * If the request has already been committed (i.e. brw_commit
+ * called via rq_commit_cb), we need to undo the unstable page
+ * increments we just performed because rq_commit_cb wont be
+ * called again.
+ */
+ spin_lock(&req->rq_lock);
+ if (unlikely(req->rq_committed)) {
+ spin_unlock(&req->rq_lock);
+
+ osc_dec_unstable_pages(req);
+ } else {
+ req->rq_unstable = 1;
+ spin_unlock(&req->rq_lock);
+ }
+}
+
+/**
+ * Check if it piggybacks SOFT_SYNC flag to OST from this OSC.
+ * This function will be called by every BRW RPC so it's critical
+ * to make this function fast.
+ */
+bool osc_over_unstable_soft_limit(struct client_obd *cli)
+{
+ long unstable_nr, osc_unstable_count;
+
+ /* Can't check cli->cl_unstable_count, therefore, no soft limit */
+ if (!cli->cl_cache || !cli->cl_cache->ccc_unstable_check)
+ return false;
+
+ osc_unstable_count = atomic_long_read(&cli->cl_unstable_count);
+ unstable_nr = atomic_long_read(&cli->cl_cache->ccc_unstable_nr);
+
+ CDEBUG(D_CACHE,
+ "%s: cli: %p unstable pages: %lu, osc unstable pages: %lu\n",
+ cli->cl_import->imp_obd->obd_name, cli,
+ unstable_nr, osc_unstable_count);
+
+ /*
+ * If the LRU slots are in shortage - 25% remaining AND this OSC
+ * has one full RPC window of unstable pages, it's a good chance
+ * to piggyback a SOFT_SYNC flag.
+ * Please notice that the OST won't take immediate response for the
+ * SOFT_SYNC request so active OSCs will have more chance to carry
+ * the flag, this is reasonable.
+ */
+ return unstable_nr > cli->cl_cache->ccc_lru_max >> 2 &&
+ osc_unstable_count > cli->cl_max_pages_per_rpc *
+ cli->cl_max_rpcs_in_flight;
+}
+
/** @} osc */
diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
index 536b868ff776..749781f022e2 100644
--- a/drivers/staging/lustre/lustre/osc/osc_request.c
+++ b/drivers/staging/lustre/lustre/osc/osc_request.c
@@ -41,6 +41,7 @@
#include "../include/lustre_ha.h"
#include "../include/lprocfs_status.h"
+#include "../include/lustre/lustre_ioctl.h"
#include "../include/lustre_debug.h"
#include "../include/lustre_param.h"
#include "../include/lustre_fid.h"
@@ -102,36 +103,6 @@ static void osc_release_ppga(struct brw_page **ppga, u32 count);
static int brw_interpret(const struct lu_env *env,
struct ptlrpc_request *req, void *data, int rc);
-/* Pack OSC object metadata for disk storage (LE byte order). */
-static int osc_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
- struct lov_stripe_md *lsm)
-{
- int lmm_size;
-
- lmm_size = sizeof(**lmmp);
- if (!lmmp)
- return lmm_size;
-
- if (*lmmp && !lsm) {
- kfree(*lmmp);
- *lmmp = NULL;
- return 0;
- } else if (unlikely(lsm && ostid_id(&lsm->lsm_oi) == 0)) {
- return -EBADF;
- }
-
- if (!*lmmp) {
- *lmmp = kzalloc(lmm_size, GFP_NOFS);
- if (!*lmmp)
- return -ENOMEM;
- }
-
- if (lsm)
- ostid_cpu_to_le(&lsm->lsm_oi, &(*lmmp)->lmm_oi);
-
- return lmm_size;
-}
-
/* Unpack OSC object metadata from disk storage (LE byte order). */
static int osc_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
struct lov_mds_md *lmm, int lmm_bytes)
@@ -189,7 +160,7 @@ static int osc_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
(imp->imp_connect_data.ocd_connect_flags & OBD_CONNECT_MAXBYTES))
(*lsmp)->lsm_maxbytes = imp->imp_connect_data.ocd_maxbytes;
else
- (*lsmp)->lsm_maxbytes = LUSTRE_STRIPE_MAXBYTES;
+ (*lsmp)->lsm_maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES;
return lsm_size;
}
@@ -427,24 +398,16 @@ static int osc_setattr_async(struct obd_export *exp, struct obd_info *oinfo,
oinfo->oi_cb_up, oinfo, rqset);
}
-static int osc_real_create(struct obd_export *exp, struct obdo *oa,
- struct lov_stripe_md **ea,
- struct obd_trans_info *oti)
+static int osc_create(const struct lu_env *env, struct obd_export *exp,
+ struct obdo *oa, struct obd_trans_info *oti)
{
struct ptlrpc_request *req;
struct ost_body *body;
- struct lov_stripe_md *lsm;
int rc;
LASSERT(oa);
- LASSERT(ea);
-
- lsm = *ea;
- if (!lsm) {
- rc = obd_alloc_memmd(exp, &lsm);
- if (rc < 0)
- return rc;
- }
+ LASSERT(oa->o_valid & OBD_MD_FLGROUP);
+ LASSERT(fid_seq_is_echo(ostid_seq(&oa->o_oi)));
req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_OST_CREATE);
if (!req) {
@@ -490,21 +453,10 @@ static int osc_real_create(struct obd_export *exp, struct obdo *oa,
oa->o_blksize = cli_brw_size(exp->exp_obd);
oa->o_valid |= OBD_MD_FLBLKSZ;
- /* XXX LOV STACKING: the lsm that is passed to us from LOV does not
- * have valid lsm_oinfo data structs, so don't go touching that.
- * This needs to be fixed in a big way.
- */
- lsm->lsm_oi = oa->o_oi;
- *ea = lsm;
-
- if (oti) {
- oti->oti_transno = lustre_msg_get_transno(req->rq_repmsg);
-
- if (oa->o_valid & OBD_MD_FLCOOKIE) {
- if (!oti->oti_logcookies)
- oti_alloc_cookies(oti, 1);
- *oti->oti_logcookies = oa->o_lcookie;
- }
+ if (oti && oa->o_valid & OBD_MD_FLCOOKIE) {
+ if (!oti->oti_logcookies)
+ oti->oti_logcookies = &oti->oti_onecookie;
+ *oti->oti_logcookies = oa->o_lcookie;
}
CDEBUG(D_HA, "transno: %lld\n",
@@ -512,8 +464,6 @@ static int osc_real_create(struct obd_export *exp, struct obdo *oa,
out_req:
ptlrpc_req_finished(req);
out:
- if (rc && !*ea)
- obd_free_memmd(exp, &lsm);
return rc;
}
@@ -649,7 +599,7 @@ static int osc_resource_get_unused(struct obd_export *exp, struct obdo *oa,
ostid_build_res_name(&oa->o_oi, &res_id);
res = ldlm_resource_get(ns, NULL, &res_id, 0, 0);
- if (!res)
+ if (IS_ERR(res))
return 0;
LDLM_RESOURCE_ADDREF(res);
@@ -689,30 +639,6 @@ static int osc_can_send_destroy(struct client_obd *cli)
return 0;
}
-static int osc_create(const struct lu_env *env, struct obd_export *exp,
- struct obdo *oa, struct lov_stripe_md **ea,
- struct obd_trans_info *oti)
-{
- int rc = 0;
-
- LASSERT(oa);
- LASSERT(ea);
- LASSERT(oa->o_valid & OBD_MD_FLGROUP);
-
- if ((oa->o_valid & OBD_MD_FLFLAGS) &&
- oa->o_flags == OBD_FL_RECREATE_OBJS) {
- return osc_real_create(exp, oa, ea, oti);
- }
-
- if (!fid_seq_is_mdt(ostid_seq(&oa->o_oi)))
- return osc_real_create(exp, oa, ea, oti);
-
- /* we should not get here anymore */
- LBUG();
-
- return rc;
-}
-
/* Destroy requests can be async always on the client, and we don't even really
* care about the return code since the client cannot do anything at all about
* a destroy failure.
@@ -725,8 +651,7 @@ static int osc_create(const struct lu_env *env, struct obd_export *exp,
* cookies to the MDS after committing destroy transactions.
*/
static int osc_destroy(const struct lu_env *env, struct obd_export *exp,
- struct obdo *oa, struct lov_stripe_md *ea,
- struct obd_trans_info *oti, struct obd_export *md_export)
+ struct obdo *oa, struct obd_trans_info *oti)
{
struct client_obd *cli = &exp->exp_obd->u.cli;
struct ptlrpc_request *req;
@@ -794,42 +719,44 @@ static int osc_destroy(const struct lu_env *env, struct obd_export *exp,
static void osc_announce_cached(struct client_obd *cli, struct obdo *oa,
long writing_bytes)
{
- u32 bits = OBD_MD_FLBLOCKS|OBD_MD_FLGRANT;
+ u32 bits = OBD_MD_FLBLOCKS | OBD_MD_FLGRANT;
LASSERT(!(oa->o_valid & bits));
oa->o_valid |= bits;
spin_lock(&cli->cl_loi_list_lock);
- oa->o_dirty = cli->cl_dirty;
- if (unlikely(cli->cl_dirty - cli->cl_dirty_transit >
- cli->cl_dirty_max)) {
+ oa->o_dirty = cli->cl_dirty_pages << PAGE_SHIFT;
+ if (unlikely(cli->cl_dirty_pages - cli->cl_dirty_transit >
+ cli->cl_dirty_max_pages)) {
CERROR("dirty %lu - %lu > dirty_max %lu\n",
- cli->cl_dirty, cli->cl_dirty_transit, cli->cl_dirty_max);
+ cli->cl_dirty_pages, cli->cl_dirty_transit,
+ cli->cl_dirty_max_pages);
oa->o_undirty = 0;
- } else if (unlikely(atomic_read(&obd_unstable_pages) +
- atomic_read(&obd_dirty_pages) -
- atomic_read(&obd_dirty_transit_pages) >
- (long)(obd_max_dirty_pages + 1))) {
+ } else if (unlikely(atomic_long_read(&obd_dirty_pages) -
+ atomic_long_read(&obd_dirty_transit_pages) >
+ (obd_max_dirty_pages + 1))) {
/* The atomic_read() allowing the atomic_inc() are
* not covered by a lock thus they may safely race and trip
* this CERROR() unless we add in a small fudge factor (+1).
*/
- CERROR("%s: dirty %d + %d - %d > system dirty_max %d\n",
+ CERROR("%s: dirty %ld + %ld > system dirty_max %lu\n",
cli->cl_import->imp_obd->obd_name,
- atomic_read(&obd_unstable_pages),
- atomic_read(&obd_dirty_pages),
- atomic_read(&obd_dirty_transit_pages),
+ atomic_long_read(&obd_dirty_pages),
+ atomic_long_read(&obd_dirty_transit_pages),
obd_max_dirty_pages);
oa->o_undirty = 0;
- } else if (unlikely(cli->cl_dirty_max - cli->cl_dirty > 0x7fffffff)) {
+ } else if (unlikely(cli->cl_dirty_max_pages - cli->cl_dirty_pages >
+ 0x7fffffff)) {
CERROR("dirty %lu - dirty_max %lu too big???\n",
- cli->cl_dirty, cli->cl_dirty_max);
+ cli->cl_dirty_pages, cli->cl_dirty_max_pages);
oa->o_undirty = 0;
} else {
- long max_in_flight = (cli->cl_max_pages_per_rpc <<
- PAGE_SHIFT)*
- (cli->cl_max_rpcs_in_flight + 1);
- oa->o_undirty = max(cli->cl_dirty_max, max_in_flight);
+ unsigned long max_in_flight;
+
+ max_in_flight = (cli->cl_max_pages_per_rpc << PAGE_SHIFT) *
+ (cli->cl_max_rpcs_in_flight + 1);
+ oa->o_undirty = max(cli->cl_dirty_max_pages << PAGE_SHIFT,
+ max_in_flight);
}
oa->o_grant = cli->cl_avail_grant + cli->cl_reserved_grant;
oa->o_dropped = cli->cl_lost_grant;
@@ -1029,22 +956,24 @@ static void osc_init_grant(struct client_obd *cli, struct obd_connect_data *ocd)
{
/*
* ocd_grant is the total grant amount we're expect to hold: if we've
- * been evicted, it's the new avail_grant amount, cl_dirty will drop
- * to 0 as inflight RPCs fail out; otherwise, it's avail_grant + dirty.
+ * been evicted, it's the new avail_grant amount, cl_dirty_pages will
+ * drop to 0 as inflight RPCs fail out; otherwise, it's avail_grant +
+ * dirty.
*
* race is tolerable here: if we're evicted, but imp_state already
- * left EVICTED state, then cl_dirty must be 0 already.
+ * left EVICTED state, then cl_dirty_pages must be 0 already.
*/
spin_lock(&cli->cl_loi_list_lock);
if (cli->cl_import->imp_state == LUSTRE_IMP_EVICTED)
cli->cl_avail_grant = ocd->ocd_grant;
else
- cli->cl_avail_grant = ocd->ocd_grant - cli->cl_dirty;
+ cli->cl_avail_grant = ocd->ocd_grant -
+ (cli->cl_dirty_pages << PAGE_SHIFT);
if (cli->cl_avail_grant < 0) {
CWARN("%s: available grant < 0: avail/ocd/dirty %ld/%u/%ld\n",
cli->cl_import->imp_obd->obd_name, cli->cl_avail_grant,
- ocd->ocd_grant, cli->cl_dirty);
+ ocd->ocd_grant, cli->cl_dirty_pages << PAGE_SHIFT);
/* workaround for servers which do not have the patch from
* LU-2679
*/
@@ -1181,7 +1110,7 @@ static u32 osc_checksum_bulk(int nob, u32 pg_count,
}
while (nob > 0 && pg_count > 0) {
- int count = pga[i]->count > nob ? nob : pga[i]->count;
+ unsigned int count = pga[i]->count > nob ? nob : pga[i]->count;
/* corrupt the data before we compute the checksum, to
* simulate an OST->client data error
@@ -1191,7 +1120,7 @@ static u32 osc_checksum_bulk(int nob, u32 pg_count,
unsigned char *ptr = kmap(pga[i]->pg);
int off = pga[i]->off & ~PAGE_MASK;
- memcpy(ptr + off, "bad1", min(4, nob));
+ memcpy(ptr + off, "bad1", min_t(typeof(nob), 4, nob));
kunmap(pga[i]->pg);
}
cfs_crypto_hash_update_page(hdesc, pga[i]->pg,
@@ -1335,11 +1264,11 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli,
if (i > 0 && can_merge_pages(pg_prev, pg)) {
niobuf--;
- niobuf->len += pg->count;
+ niobuf->rnb_len += pg->count;
} else {
- niobuf->offset = pg->off;
- niobuf->len = pg->count;
- niobuf->flags = pg->flag;
+ niobuf->rnb_offset = pg->off;
+ niobuf->rnb_len = pg->count;
+ niobuf->rnb_flags = pg->flag;
}
pg_prev = pg;
}
@@ -1418,6 +1347,11 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli,
INIT_LIST_HEAD(&aa->aa_oaps);
*reqp = req;
+ niobuf = req_capsule_client_get(pill, &RMF_NIOBUF_REMOTE);
+ CDEBUG(D_RPCTRACE, "brw rpc %p - object " DOSTID " offset %lld<>%lld\n",
+ req, POSTID(&oa->o_oi), niobuf[0].rnb_offset,
+ niobuf[niocount - 1].rnb_offset + niobuf[niocount - 1].rnb_len);
+
return 0;
out:
@@ -1463,7 +1397,8 @@ static int check_write_checksum(struct obdo *oa, const lnet_process_id_t *peer,
oa->o_valid & OBD_MD_FLFID ? oa->o_parent_oid : 0,
oa->o_valid & OBD_MD_FLFID ? oa->o_parent_ver : 0,
POSTID(&oa->o_oi), pga[0]->off,
- pga[page_count-1]->off + pga[page_count-1]->count - 1);
+ pga[page_count - 1]->off +
+ pga[page_count - 1]->count - 1);
CERROR("original client csum %x (type %x), server csum %x (type %x), client csum now %x\n",
client_cksum, client_cksum_type,
server_cksum, cksum_type, new_cksum);
@@ -1565,7 +1500,8 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
char *router = "";
enum cksum_type cksum_type;
- cksum_type = cksum_type_unpack(body->oa.o_valid&OBD_MD_FLFLAGS ?
+ cksum_type = cksum_type_unpack(body->oa.o_valid &
+ OBD_MD_FLFLAGS ?
body->oa.o_flags : 0);
client_cksum = osc_checksum_bulk(rc, aa->aa_page_count,
aa->aa_ppga, OST_READ,
@@ -1794,7 +1730,8 @@ static int brw_interpret(const struct lu_env *env,
if (lustre_msg_get_opc(req->rq_reqmsg) == OST_WRITE) {
struct lov_oinfo *loi = cl2osc(obj)->oo_oinfo;
- loff_t last_off = last->oap_count + last->oap_obj_off;
+ loff_t last_off = last->oap_count + last->oap_obj_off +
+ last->oap_page_off;
/* Change file size if this is an out of quota or
* direct IO write and it extends the file size
@@ -1812,11 +1749,14 @@ static int brw_interpret(const struct lu_env *env,
}
if (valid != 0)
- cl_object_attr_set(env, obj, attr, valid);
+ cl_object_attr_update(env, obj, attr, valid);
cl_object_attr_unlock(obj);
}
kmem_cache_free(obdo_cachep, aa->aa_oa);
+ if (lustre_msg_get_opc(req->rq_reqmsg) == OST_WRITE && rc == 0)
+ osc_inc_unstable_pages(req);
+
list_for_each_entry_safe(ext, tmp, &aa->aa_exts, oe_link) {
list_del_init(&ext->oe_link);
osc_extent_finish(env, ext, 1, rc);
@@ -1847,21 +1787,21 @@ static int brw_interpret(const struct lu_env *env,
static void brw_commit(struct ptlrpc_request *req)
{
- spin_lock(&req->rq_lock);
/*
* If osc_inc_unstable_pages (via osc_extent_finish) races with
* this called via the rq_commit_cb, I need to ensure
* osc_dec_unstable_pages is still called. Otherwise unstable
* pages may be leaked.
*/
- if (req->rq_unstable) {
+ spin_lock(&req->rq_lock);
+ if (unlikely(req->rq_unstable)) {
+ req->rq_unstable = 0;
spin_unlock(&req->rq_lock);
osc_dec_unstable_pages(req);
- spin_lock(&req->rq_lock);
} else {
req->rq_committed = 1;
+ spin_unlock(&req->rq_lock);
}
- spin_unlock(&req->rq_lock);
}
/**
@@ -1881,13 +1821,13 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
struct osc_async_page *tmp;
struct cl_req *clerq = NULL;
enum cl_req_type crt = (cmd & OBD_BRW_WRITE) ? CRT_WRITE : CRT_READ;
- struct ldlm_lock *lock = NULL;
struct cl_req_attr *crattr = NULL;
u64 starting_offset = OBD_OBJECT_EOF;
u64 ending_offset = 0;
int mpflag = 0;
int mem_tight = 0;
int page_count = 0;
+ bool soft_sync = false;
int i;
int rc;
struct ost_body *body;
@@ -1915,6 +1855,7 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
}
}
+ soft_sync = osc_over_unstable_soft_limit(cli);
if (mem_tight)
mpflag = cfs_memory_pressure_get_and_set();
@@ -1947,10 +1888,11 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
rc = PTR_ERR(clerq);
goto out;
}
- lock = oap->oap_ldlm_lock;
}
if (mem_tight)
oap->oap_brw_flags |= OBD_BRW_MEMALLOC;
+ if (soft_sync)
+ oap->oap_brw_flags |= OBD_BRW_SOFT_SYNC;
pga[i] = &oap->oap_brw_page;
pga[i]->off = oap->oap_obj_off + oap->oap_page_off;
CDEBUG(0, "put page %p index %lu oap %p flg %x to pga\n",
@@ -1964,10 +1906,6 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
LASSERT(clerq);
crattr->cra_oa = oa;
cl_req_attr_set(env, clerq, crattr, ~0ULL);
- if (lock) {
- oa->o_handle = lock->l_remote_handle;
- oa->o_valid |= OBD_MD_FLHANDLE;
- }
rc = cl_req_prep(env, clerq);
if (rc != 0) {
@@ -1998,7 +1936,7 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
body = req_capsule_client_get(&req->rq_pill, &RMF_OST_BODY);
crattr->cra_oa = &body->oa;
cl_req_attr_set(env, clerq, crattr,
- OBD_MD_FLMTIME|OBD_MD_FLCTIME|OBD_MD_FLATIME);
+ OBD_MD_FLMTIME | OBD_MD_FLCTIME | OBD_MD_FLATIME);
lustre_msg_set_jobid(req->rq_reqmsg, crattr->cra_jobid);
@@ -2044,7 +1982,7 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
}
spin_unlock(&cli->cl_loi_list_lock);
- DEBUG_REQ(D_INODE, req, "%d pages, aa %p. now %dr/%dw in flight",
+ DEBUG_REQ(D_INODE, req, "%d pages, aa %p. now %ur/%dw in flight",
page_count, aa, cli->cl_r_in_flight,
cli->cl_w_in_flight);
@@ -2116,27 +2054,6 @@ static int osc_set_data_with_check(struct lustre_handle *lockh,
return set;
}
-/* find any ldlm lock of the inode in osc
- * return 0 not find
- * 1 find one
- * < 0 error
- */
-static int osc_find_cbdata(struct obd_export *exp, struct lov_stripe_md *lsm,
- ldlm_iterator_t replace, void *data)
-{
- struct ldlm_res_id res_id;
- struct obd_device *obd = class_exp2obd(exp);
- int rc = 0;
-
- ostid_build_res_name(&lsm->lsm_oi, &res_id);
- rc = ldlm_resource_iterate(obd->obd_namespace, &res_id, replace, data);
- if (rc == LDLM_ITER_STOP)
- return 1;
- if (rc == LDLM_ITER_CONTINUE)
- return 0;
- return rc;
-}
-
static int osc_enqueue_fini(struct ptlrpc_request *req,
osc_enqueue_upcall_f upcall, void *cookie,
struct lustre_handle *lockh, enum ldlm_mode mode,
@@ -2586,71 +2503,6 @@ static int osc_statfs(const struct lu_env *env, struct obd_export *exp,
return rc;
}
-/* Retrieve object striping information.
- *
- * @lmmu is a pointer to an in-core struct with lmm_ost_count indicating
- * the maximum number of OST indices which will fit in the user buffer.
- * lmm_magic must be LOV_MAGIC (we only use 1 slot here).
- */
-static int osc_getstripe(struct lov_stripe_md *lsm,
- struct lov_user_md __user *lump)
-{
- /* we use lov_user_md_v3 because it is larger than lov_user_md_v1 */
- struct lov_user_md_v3 lum, *lumk;
- struct lov_user_ost_data_v1 *lmm_objects;
- int rc = 0, lum_size;
-
- if (!lsm)
- return -ENODATA;
-
- /* we only need the header part from user space to get lmm_magic and
- * lmm_stripe_count, (the header part is common to v1 and v3)
- */
- lum_size = sizeof(struct lov_user_md_v1);
- if (copy_from_user(&lum, lump, lum_size))
- return -EFAULT;
-
- if ((lum.lmm_magic != LOV_USER_MAGIC_V1) &&
- (lum.lmm_magic != LOV_USER_MAGIC_V3))
- return -EINVAL;
-
- /* lov_user_md_vX and lov_mds_md_vX must have the same size */
- LASSERT(sizeof(struct lov_user_md_v1) == sizeof(struct lov_mds_md_v1));
- LASSERT(sizeof(struct lov_user_md_v3) == sizeof(struct lov_mds_md_v3));
- LASSERT(sizeof(lum.lmm_objects[0]) == sizeof(lumk->lmm_objects[0]));
-
- /* we can use lov_mds_md_size() to compute lum_size
- * because lov_user_md_vX and lov_mds_md_vX have the same size
- */
- if (lum.lmm_stripe_count > 0) {
- lum_size = lov_mds_md_size(lum.lmm_stripe_count, lum.lmm_magic);
- lumk = kzalloc(lum_size, GFP_NOFS);
- if (!lumk)
- return -ENOMEM;
-
- if (lum.lmm_magic == LOV_USER_MAGIC_V1)
- lmm_objects =
- &(((struct lov_user_md_v1 *)lumk)->lmm_objects[0]);
- else
- lmm_objects = &(lumk->lmm_objects[0]);
- lmm_objects->l_ost_oi = lsm->lsm_oi;
- } else {
- lum_size = lov_mds_md_size(0, lum.lmm_magic);
- lumk = &lum;
- }
-
- lumk->lmm_oi = lsm->lsm_oi;
- lumk->lmm_stripe_count = 1;
-
- if (copy_to_user(lump, lumk, lum_size))
- rc = -EFAULT;
-
- if (lumk != &lum)
- kfree(lumk);
-
- return rc;
-}
-
static int osc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
void *karg, void __user *uarg)
{
@@ -2664,57 +2516,6 @@ static int osc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
return -EINVAL;
}
switch (cmd) {
- case OBD_IOC_LOV_GET_CONFIG: {
- char *buf;
- struct lov_desc *desc;
- struct obd_uuid uuid;
-
- buf = NULL;
- len = 0;
- if (obd_ioctl_getdata(&buf, &len, uarg)) {
- err = -EINVAL;
- goto out;
- }
-
- data = (struct obd_ioctl_data *)buf;
-
- if (sizeof(*desc) > data->ioc_inllen1) {
- obd_ioctl_freedata(buf, len);
- err = -EINVAL;
- goto out;
- }
-
- if (data->ioc_inllen2 < sizeof(uuid)) {
- obd_ioctl_freedata(buf, len);
- err = -EINVAL;
- goto out;
- }
-
- desc = (struct lov_desc *)data->ioc_inlbuf1;
- desc->ld_tgt_count = 1;
- desc->ld_active_tgt_count = 1;
- desc->ld_default_stripe_count = 1;
- desc->ld_default_stripe_size = 0;
- desc->ld_default_stripe_offset = 0;
- desc->ld_pattern = 0;
- memcpy(&desc->ld_uuid, &obd->obd_uuid, sizeof(uuid));
-
- memcpy(data->ioc_inlbuf2, &obd->obd_uuid, sizeof(uuid));
-
- err = copy_to_user(uarg, buf, len);
- if (err)
- err = -EFAULT;
- obd_ioctl_freedata(buf, len);
- goto out;
- }
- case LL_IOC_LOV_SETSTRIPE:
- err = obd_alloc_memmd(exp, karg);
- if (err > 0)
- err = 0;
- goto out;
- case LL_IOC_LOV_GETSTRIPE:
- err = osc_getstripe(karg, uarg);
- goto out;
case OBD_IOC_CLIENT_RECOVER:
err = ptlrpc_recover_import(obd->u.cli.cl_import,
data->ioc_inlbuf1, 0);
@@ -2749,51 +2550,7 @@ static int osc_get_info(const struct lu_env *env, struct obd_export *exp,
if (!vallen || !val)
return -EFAULT;
- if (KEY_IS(KEY_LOCK_TO_STRIPE)) {
- __u32 *stripe = val;
- *vallen = sizeof(*stripe);
- *stripe = 0;
- return 0;
- } else if (KEY_IS(KEY_LAST_ID)) {
- struct ptlrpc_request *req;
- u64 *reply;
- char *tmp;
- int rc;
-
- req = ptlrpc_request_alloc(class_exp2cliimp(exp),
- &RQF_OST_GET_INFO_LAST_ID);
- if (!req)
- return -ENOMEM;
-
- req_capsule_set_size(&req->rq_pill, &RMF_SETINFO_KEY,
- RCL_CLIENT, keylen);
- rc = ptlrpc_request_pack(req, LUSTRE_OST_VERSION, OST_GET_INFO);
- if (rc) {
- ptlrpc_request_free(req);
- return rc;
- }
-
- tmp = req_capsule_client_get(&req->rq_pill, &RMF_SETINFO_KEY);
- memcpy(tmp, key, keylen);
-
- req->rq_no_delay = 1;
- req->rq_no_resend = 1;
- ptlrpc_request_set_replen(req);
- rc = ptlrpc_queue_wait(req);
- if (rc)
- goto out;
-
- reply = req_capsule_server_get(&req->rq_pill, &RMF_OBD_ID);
- if (!reply) {
- rc = -EPROTO;
- goto out;
- }
-
- *((u64 *)val) = *reply;
-out:
- ptlrpc_req_finished(req);
- return rc;
- } else if (KEY_IS(KEY_FIEMAP)) {
+ if (KEY_IS(KEY_FIEMAP)) {
struct ll_fiemap_info_key *fm_key = key;
struct ldlm_res_id res_id;
ldlm_policy_data_t policy;
@@ -2931,11 +2688,11 @@ static int osc_set_info_async(const struct lu_env *env, struct obd_export *exp,
if (KEY_IS(KEY_CACHE_LRU_SHRINK)) {
struct client_obd *cli = &obd->u.cli;
- int nr = atomic_read(&cli->cl_lru_in_list) >> 1;
- int target = *(int *)val;
+ long nr = atomic_long_read(&cli->cl_lru_in_list) >> 1;
+ long target = *(long *)val;
nr = osc_lru_shrink(env, cli, min(nr, target), true);
- *(int *)val -= nr;
+ *(long *)val -= nr;
return 0;
}
@@ -3014,8 +2771,9 @@ static int osc_reconnect(const struct lu_env *env,
long lost_grant;
spin_lock(&cli->cl_loi_list_lock);
- data->ocd_grant = (cli->cl_avail_grant + cli->cl_dirty) ?:
- 2 * cli_brw_size(obd);
+ data->ocd_grant = (cli->cl_avail_grant +
+ (cli->cl_dirty_pages << PAGE_SHIFT)) ?:
+ 2 * cli_brw_size(obd);
lost_grant = cli->cl_lost_grant;
cli->cl_lost_grant = 0;
spin_unlock(&cli->cl_loi_list_lock);
@@ -3346,7 +3104,6 @@ static struct obd_ops osc_obd_ops = {
.disconnect = osc_disconnect,
.statfs = osc_statfs,
.statfs_async = osc_statfs_async,
- .packmd = osc_packmd,
.unpackmd = osc_unpackmd,
.create = osc_create,
.destroy = osc_destroy,
@@ -3354,7 +3111,6 @@ static struct obd_ops osc_obd_ops = {
.getattr_async = osc_getattr_async,
.setattr = osc_setattr,
.setattr_async = osc_setattr_async,
- .find_cbdata = osc_find_cbdata,
.iocontrol = osc_iocontrol,
.get_info = osc_get_info,
.set_info_async = osc_set_info_async,
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index d4463d7c81d2..8c51d51a678b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -45,6 +45,7 @@
static int ptlrpc_send_new_req(struct ptlrpc_request *req);
static int ptlrpcd_check_work(struct ptlrpc_request *req);
+static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async);
/**
* Initialize passed in client structure \a cl.
@@ -89,7 +90,6 @@ struct ptlrpc_connection *ptlrpc_uuid_to_connection(struct obd_uuid *uuid)
return c;
}
-EXPORT_SYMBOL(ptlrpc_uuid_to_connection);
/**
* Allocate and initialize new bulk descriptor on the sender.
@@ -202,7 +202,7 @@ void __ptlrpc_free_bulk(struct ptlrpc_bulk_desc *desc, int unpin)
if (unpin) {
for (i = 0; i < desc->bd_iov_count; i++)
- put_page(desc->bd_iov[i].kiov_page);
+ put_page(desc->bd_iov[i].bv_page);
}
kfree(desc);
@@ -283,8 +283,8 @@ int ptlrpc_at_get_net_latency(struct ptlrpc_request *req)
}
/* Adjust expected network latency */
-static void ptlrpc_at_adj_net_latency(struct ptlrpc_request *req,
- unsigned int service_time)
+void ptlrpc_at_adj_net_latency(struct ptlrpc_request *req,
+ unsigned int service_time)
{
unsigned int nl, oldnl;
struct imp_at *at;
@@ -364,31 +364,37 @@ static int ptlrpc_at_recv_early_reply(struct ptlrpc_request *req)
}
rc = unpack_reply(early_req);
- if (rc == 0) {
- /* Expecting to increase the service time estimate here */
- ptlrpc_at_adj_service(req,
- lustre_msg_get_timeout(early_req->rq_repmsg));
- ptlrpc_at_adj_net_latency(req,
- lustre_msg_get_service_time(early_req->rq_repmsg));
- }
-
- sptlrpc_cli_finish_early_reply(early_req);
-
- if (rc != 0) {
+ if (rc) {
+ sptlrpc_cli_finish_early_reply(early_req);
spin_lock(&req->rq_lock);
return rc;
}
- /* Adjust the local timeout for this req */
- ptlrpc_at_set_req_timeout(req);
+ /*
+ * Use new timeout value just to adjust the local value for this
+ * request, don't include it into at_history. It is unclear yet why
+ * service time increased and should it be counted or skipped, e.g.
+ * that can be recovery case or some error or server, the real reply
+ * will add all new data if it is worth to add.
+ */
+ req->rq_timeout = lustre_msg_get_timeout(early_req->rq_repmsg);
+ lustre_msg_set_timeout(req->rq_reqmsg, req->rq_timeout);
+
+ /* Network latency can be adjusted, it is pure network delays */
+ ptlrpc_at_adj_net_latency(req,
+ lustre_msg_get_service_time(early_req->rq_repmsg));
+
+ sptlrpc_cli_finish_early_reply(early_req);
spin_lock(&req->rq_lock);
olddl = req->rq_deadline;
/*
- * server assumes it now has rq_timeout from when it sent the
- * early reply, so client should give it at least that long.
+ * server assumes it now has rq_timeout from when the request
+ * arrived, so the client should give it at least that long.
+ * since we don't know the arrival time we'll use the original
+ * sent time
*/
- req->rq_deadline = ktime_get_real_seconds() + req->rq_timeout +
+ req->rq_deadline = req->rq_sent + req->rq_timeout +
ptlrpc_at_get_net_latency(req);
DEBUG_REQ(D_ADAPTTO, req,
@@ -884,7 +890,6 @@ struct ptlrpc_request_set *ptlrpc_prep_fcset(int max, set_producer_func func,
return set;
}
-EXPORT_SYMBOL(ptlrpc_prep_fcset);
/**
* Wind down and free request set structure previously allocated with
@@ -1004,7 +1009,6 @@ void ptlrpc_set_add_new_req(struct ptlrpcd_ctl *pc,
wake_up(&pc->pc_partners[i]->pc_set->set_waitq);
}
}
-EXPORT_SYMBOL(ptlrpc_set_add_new_req);
/**
* Based on the current state of the import, determine if the request
@@ -1035,8 +1039,8 @@ static int ptlrpc_import_delay_req(struct obd_import *imp,
*status = -EIO;
} else if (ptlrpc_send_limit_expired(req)) {
/* probably doesn't need to be a D_ERROR after initial testing */
- DEBUG_REQ(D_ERROR, req, "send limit expired ");
- *status = -EIO;
+ DEBUG_REQ(D_HA, req, "send limit expired ");
+ *status = -ETIMEDOUT;
} else if (req->rq_send_state == LUSTRE_IMP_CONNECTING &&
imp->imp_state == LUSTRE_IMP_CONNECTING) {
/* allow CONNECT even if import is invalid */
@@ -1073,36 +1077,42 @@ static int ptlrpc_import_delay_req(struct obd_import *imp,
}
/**
- * Decide if the error message regarding provided request \a req
- * should be printed to the console or not.
- * Makes it's decision on request status and other properties.
- * Returns 1 to print error on the system console or 0 if not.
+ * Decide if the error message should be printed to the console or not.
+ * Makes its decision based on request type, status, and failure frequency.
+ *
+ * \param[in] req request that failed and may need a console message
+ *
+ * \retval false if no message should be printed
+ * \retval true if console message should be printed
*/
-static int ptlrpc_console_allow(struct ptlrpc_request *req)
+static bool ptlrpc_console_allow(struct ptlrpc_request *req)
{
__u32 opc;
- int err;
LASSERT(req->rq_reqmsg);
opc = lustre_msg_get_opc(req->rq_reqmsg);
- /*
- * Suppress particular reconnect errors which are to be expected. No
- * errors are suppressed for the initial connection on an import
- */
- if ((lustre_handle_is_used(&req->rq_import->imp_remote_handle)) &&
- (opc == OST_CONNECT || opc == MDS_CONNECT || opc == MGS_CONNECT)) {
+ /* Suppress particular reconnect errors which are to be expected. */
+ if (opc == OST_CONNECT || opc == MDS_CONNECT || opc == MGS_CONNECT) {
+ int err;
+
/* Suppress timed out reconnect requests */
- if (req->rq_timedout)
- return 0;
+ if (lustre_handle_is_used(&req->rq_import->imp_remote_handle) ||
+ req->rq_timedout)
+ return false;
- /* Suppress unavailable/again reconnect requests */
+ /*
+ * Suppress most unavailable/again reconnect requests, but
+ * print occasionally so it is clear client is trying to
+ * connect to a server where no target is running.
+ */
err = lustre_msg_get_status(req->rq_repmsg);
- if (err == -ENODEV || err == -EAGAIN)
- return 0;
+ if ((err == -ENODEV || err == -EAGAIN) &&
+ req->rq_import->imp_conn_cnt % 30 != 20)
+ return false;
}
- return 1;
+ return true;
}
/**
@@ -1116,14 +1126,14 @@ static int ptlrpc_check_status(struct ptlrpc_request *req)
err = lustre_msg_get_status(req->rq_repmsg);
if (lustre_msg_get_type(req->rq_repmsg) == PTL_RPC_MSG_ERR) {
struct obd_import *imp = req->rq_import;
+ lnet_nid_t nid = imp->imp_connection->c_peer.nid;
__u32 opc = lustre_msg_get_opc(req->rq_reqmsg);
if (ptlrpc_console_allow(req))
- LCONSOLE_ERROR_MSG(0x011, "%s: Communicating with %s, operation %s failed with %d.\n",
+ LCONSOLE_ERROR_MSG(0x011, "%s: operation %s to node %s failed: rc = %d\n",
imp->imp_obd->obd_name,
- libcfs_nid2str(
- imp->imp_connection->c_peer.nid),
- ll_opcode2str(opc), err);
+ ll_opcode2str(opc),
+ libcfs_nid2str(nid), err);
return err < 0 ? err : -EINVAL;
}
@@ -1280,7 +1290,7 @@ static int after_reply(struct ptlrpc_request *req)
* some reason. Try to reconnect, and if that fails, punt to
* the upcall.
*/
- if (ll_rpc_recoverable_error(rc)) {
+ if (ptlrpc_recoverable_error(rc)) {
if (req->rq_send_state != LUSTRE_IMP_FULL ||
imp->imp_obd->obd_no_recov || imp->imp_dlm_fake) {
return rc;
@@ -1628,8 +1638,10 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set)
req->rq_waiting || req->rq_wait_ctx) {
int status;
- if (!ptlrpc_unregister_reply(req, 1))
+ if (!ptlrpc_unregister_reply(req, 1)) {
+ ptlrpc_unregister_bulk(req, 1);
continue;
+ }
spin_lock(&imp->imp_lock);
if (ptlrpc_import_delay_req(imp, req,
@@ -1995,7 +2007,6 @@ int ptlrpc_expired_set(void *data)
*/
return 1;
}
-EXPORT_SYMBOL(ptlrpc_expired_set);
/**
* Sets rq_intr flag in \a req under spinlock.
@@ -2012,7 +2023,7 @@ EXPORT_SYMBOL(ptlrpc_mark_interrupted);
* Interrupts (sets interrupted flag) all uncompleted requests in
* a set \a data. Callback for l_wait_event for interruptible waits.
*/
-void ptlrpc_interrupted_set(void *data)
+static void ptlrpc_interrupted_set(void *data)
{
struct ptlrpc_request_set *set = data;
struct list_head *tmp;
@@ -2030,7 +2041,6 @@ void ptlrpc_interrupted_set(void *data)
ptlrpc_mark_interrupted(req);
}
}
-EXPORT_SYMBOL(ptlrpc_interrupted_set);
/**
* Get the smallest timeout in the set; this does NOT set a timeout.
@@ -2074,7 +2084,6 @@ int ptlrpc_set_next_timeout(struct ptlrpc_request_set *set)
}
return timeout;
}
-EXPORT_SYMBOL(ptlrpc_set_next_timeout);
/**
* Send all unset request from the set and then wait until all
@@ -2325,7 +2334,7 @@ EXPORT_SYMBOL(ptlrpc_req_xid);
* The request owner (i.e. the thread doing the I/O) must call...
* Returns 0 on success or 1 if unregistering cannot be made.
*/
-int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async)
+static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async)
{
int rc;
wait_queue_head_t *wq;
@@ -2390,7 +2399,6 @@ int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async)
}
return 0;
}
-EXPORT_SYMBOL(ptlrpc_unregister_reply);
static void ptlrpc_free_request(struct ptlrpc_request *req)
{
@@ -2451,7 +2459,8 @@ void ptlrpc_free_committed(struct obd_import *imp)
imp->imp_obd->obd_name, imp->imp_peer_committed_transno,
imp->imp_generation);
- if (imp->imp_generation != imp->imp_last_generation_checked)
+ if (imp->imp_generation != imp->imp_last_generation_checked ||
+ !imp->imp_last_transno_checked)
skip_committed_list = false;
imp->imp_last_transno_checked = imp->imp_peer_committed_transno;
@@ -2499,6 +2508,9 @@ free_req:
if (req->rq_import_generation < imp->imp_generation) {
DEBUG_REQ(D_RPCTRACE, req, "free stale open request");
ptlrpc_free_request(req);
+ } else if (!req->rq_replay) {
+ DEBUG_REQ(D_RPCTRACE, req, "free closed open request");
+ ptlrpc_free_request(req);
}
}
}
@@ -2541,7 +2553,6 @@ void ptlrpc_resend_req(struct ptlrpc_request *req)
ptlrpc_client_wake_req(req);
spin_unlock(&req->rq_lock);
}
-EXPORT_SYMBOL(ptlrpc_resend_req);
/**
* Grab additional reference on a request \a req
@@ -2610,7 +2621,6 @@ void ptlrpc_retain_replayable_request(struct ptlrpc_request *req,
list_add(&req->rq_replay_list, &imp->imp_replay_list);
}
-EXPORT_SYMBOL(ptlrpc_retain_replayable_request);
/**
* Send request and wait until it completes.
@@ -2783,7 +2793,6 @@ int ptlrpc_replay_req(struct ptlrpc_request *req)
ptlrpcd_add_req(req);
return 0;
}
-EXPORT_SYMBOL(ptlrpc_replay_req);
/**
* Aborts all in-flight request on import \a imp sending and delayed lists
@@ -2843,7 +2852,6 @@ void ptlrpc_abort_inflight(struct obd_import *imp)
spin_unlock(&imp->imp_lock);
}
-EXPORT_SYMBOL(ptlrpc_abort_inflight);
/**
* Abort all uncompleted requests in request set \a set
@@ -2929,7 +2937,6 @@ __u64 ptlrpc_next_xid(void)
return next;
}
-EXPORT_SYMBOL(ptlrpc_next_xid);
/**
* Get a glimpse at what next xid value might have been.
diff --git a/drivers/staging/lustre/lustre/ptlrpc/connection.c b/drivers/staging/lustre/lustre/ptlrpc/connection.c
index 177a379da9fa..7b020d60c9e5 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/connection.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/connection.c
@@ -82,7 +82,6 @@ out:
libcfs_nid2str(conn->c_peer.nid));
return conn;
}
-EXPORT_SYMBOL(ptlrpc_connection_get);
int ptlrpc_connection_put(struct ptlrpc_connection *conn)
{
@@ -118,7 +117,6 @@ int ptlrpc_connection_put(struct ptlrpc_connection *conn)
return rc;
}
-EXPORT_SYMBOL(ptlrpc_connection_put);
struct ptlrpc_connection *
ptlrpc_connection_addref(struct ptlrpc_connection *conn)
@@ -130,7 +128,6 @@ ptlrpc_connection_addref(struct ptlrpc_connection *conn)
return conn;
}
-EXPORT_SYMBOL(ptlrpc_connection_addref);
int ptlrpc_connection_init(void)
{
@@ -146,13 +143,11 @@ int ptlrpc_connection_init(void)
return 0;
}
-EXPORT_SYMBOL(ptlrpc_connection_init);
void ptlrpc_connection_fini(void)
{
cfs_hash_putref(conn_hash);
}
-EXPORT_SYMBOL(ptlrpc_connection_fini);
/*
* Hash operations for net_peer<->connection
diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c
index b1ce72511509..283dfb296d35 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/events.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/events.c
@@ -543,7 +543,7 @@ static int ptlrpc_ni_init(void)
rc = LNetNIInit(pid);
if (rc < 0) {
CDEBUG(D_NET, "Can't init network interface: %d\n", rc);
- return -ENOENT;
+ return rc;
}
/* CAVEAT EMPTOR: how we process portals events is _radically_
@@ -561,7 +561,7 @@ static int ptlrpc_ni_init(void)
CERROR("Failed to allocate event queue: %d\n", rc);
LNetNIFini();
- return -ENOMEM;
+ return rc;
}
int ptlrpc_init_portals(void)
@@ -570,7 +570,7 @@ int ptlrpc_init_portals(void)
if (rc != 0) {
CERROR("network initialisation failed\n");
- return -EIO;
+ return rc;
}
rc = ptlrpcd_addref();
if (rc == 0)
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c
index 3292e6ea0102..a23d0a05b574 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -307,7 +307,8 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
*/
lwi = LWI_TIMEOUT_INTERVAL(
cfs_timeout_cap(cfs_time_seconds(timeout)),
- (timeout > 1)?cfs_time_seconds(1):cfs_time_seconds(1)/2,
+ (timeout > 1) ? cfs_time_seconds(1) :
+ cfs_time_seconds(1) / 2,
NULL, NULL);
rc = l_wait_event(imp->imp_recovery_waitq,
(atomic_read(&imp->imp_inflight) == 0),
@@ -424,7 +425,6 @@ void ptlrpc_fail_import(struct obd_import *imp, __u32 conn_cnt)
ptlrpc_pinger_force(imp);
}
}
-EXPORT_SYMBOL(ptlrpc_fail_import);
int ptlrpc_reconnect_import(struct obd_import *imp)
{
@@ -698,7 +698,8 @@ int ptlrpc_connect_import(struct obd_import *imp)
request->rq_send_state = LUSTRE_IMP_CONNECTING;
/* Allow a slightly larger reply for future growth compatibility */
req_capsule_set_size(&request->rq_pill, &RMF_CONNECT_DATA, RCL_SERVER,
- sizeof(struct obd_connect_data)+16*sizeof(__u64));
+ sizeof(struct obd_connect_data) +
+ 16 * sizeof(__u64));
ptlrpc_request_set_replen(request);
request->rq_interpret_reply = ptlrpc_connect_interpret;
@@ -750,6 +751,153 @@ static int ptlrpc_busy_reconnect(int rc)
return (rc == -EBUSY) || (rc == -EAGAIN);
}
+static int ptlrpc_connect_set_flags(struct obd_import *imp,
+ struct obd_connect_data *ocd,
+ u64 old_connect_flags,
+ struct obd_export *exp, int init_connect)
+{
+ struct client_obd *cli = &imp->imp_obd->u.cli;
+ static bool warned;
+
+ if ((imp->imp_connect_flags_orig & OBD_CONNECT_IBITS) &&
+ !(ocd->ocd_connect_flags & OBD_CONNECT_IBITS)) {
+ LCONSOLE_WARN("%s: MDS %s does not support ibits lock, either very old or invalid: requested %#llx, replied %#llx\n",
+ imp->imp_obd->obd_name,
+ imp->imp_connection->c_remote_uuid.uuid,
+ imp->imp_connect_flags_orig,
+ ocd->ocd_connect_flags);
+ return -EPROTO;
+ }
+
+ spin_lock(&imp->imp_lock);
+ list_del(&imp->imp_conn_current->oic_item);
+ list_add(&imp->imp_conn_current->oic_item, &imp->imp_conn_list);
+ imp->imp_last_success_conn = imp->imp_conn_current->oic_last_attempt;
+
+ spin_unlock(&imp->imp_lock);
+
+ if (!warned && (ocd->ocd_connect_flags & OBD_CONNECT_VERSION) &&
+ (ocd->ocd_version > LUSTRE_VERSION_CODE +
+ LUSTRE_VERSION_OFFSET_WARN ||
+ ocd->ocd_version < LUSTRE_VERSION_CODE -
+ LUSTRE_VERSION_OFFSET_WARN)) {
+ /*
+ * Sigh, some compilers do not like #ifdef in the middle
+ * of macro arguments
+ */
+ const char *older = "older than client. Consider upgrading server";
+ const char *newer = "newer than client. Consider recompiling application";
+
+ LCONSOLE_WARN("Server %s version (%d.%d.%d.%d) is much %s (%s)\n",
+ obd2cli_tgt(imp->imp_obd),
+ OBD_OCD_VERSION_MAJOR(ocd->ocd_version),
+ OBD_OCD_VERSION_MINOR(ocd->ocd_version),
+ OBD_OCD_VERSION_PATCH(ocd->ocd_version),
+ OBD_OCD_VERSION_FIX(ocd->ocd_version),
+ ocd->ocd_version > LUSTRE_VERSION_CODE ?
+ newer : older, LUSTRE_VERSION_STRING);
+ warned = true;
+ }
+
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
+ /*
+ * Check if server has LU-1252 fix applied to not always swab
+ * the IR MNE entries. Do this only once per connection. This
+ * fixup is version-limited, because we don't want to carry the
+ * OBD_CONNECT_MNE_SWAB flag around forever, just so long as we
+ * need interop with unpatched 2.2 servers. For newer servers,
+ * the client will do MNE swabbing only as needed. LU-1644
+ */
+ if (unlikely((ocd->ocd_connect_flags & OBD_CONNECT_VERSION) &&
+ !(ocd->ocd_connect_flags & OBD_CONNECT_MNE_SWAB) &&
+ OBD_OCD_VERSION_MAJOR(ocd->ocd_version) == 2 &&
+ OBD_OCD_VERSION_MINOR(ocd->ocd_version) == 2 &&
+ OBD_OCD_VERSION_PATCH(ocd->ocd_version) < 55 &&
+ !strcmp(imp->imp_obd->obd_type->typ_name,
+ LUSTRE_MGC_NAME)))
+ imp->imp_need_mne_swab = 1;
+ else /* clear if server was upgraded since last connect */
+ imp->imp_need_mne_swab = 0;
+#endif
+
+ if (ocd->ocd_connect_flags & OBD_CONNECT_CKSUM) {
+ /*
+ * We sent to the server ocd_cksum_types with bits set
+ * for algorithms we understand. The server masked off
+ * the checksum types it doesn't support
+ */
+ if (!(ocd->ocd_cksum_types & cksum_types_supported_client())) {
+ LCONSOLE_WARN("The negotiation of the checksum algorithm to use with server %s failed (%x/%x), disabling checksums\n",
+ obd2cli_tgt(imp->imp_obd),
+ ocd->ocd_cksum_types,
+ cksum_types_supported_client());
+ cli->cl_checksum = 0;
+ cli->cl_supp_cksum_types = OBD_CKSUM_ADLER;
+ } else {
+ cli->cl_supp_cksum_types = ocd->ocd_cksum_types;
+ }
+ } else {
+ /*
+ * The server does not support OBD_CONNECT_CKSUM.
+ * Enforce ADLER for backward compatibility
+ */
+ cli->cl_supp_cksum_types = OBD_CKSUM_ADLER;
+ }
+ cli->cl_cksum_type = cksum_type_select(cli->cl_supp_cksum_types);
+
+ if (ocd->ocd_connect_flags & OBD_CONNECT_BRW_SIZE)
+ cli->cl_max_pages_per_rpc =
+ min(ocd->ocd_brw_size >> PAGE_SHIFT,
+ cli->cl_max_pages_per_rpc);
+ else if (imp->imp_connect_op == MDS_CONNECT ||
+ imp->imp_connect_op == MGS_CONNECT)
+ cli->cl_max_pages_per_rpc = 1;
+
+ LASSERT((cli->cl_max_pages_per_rpc <= PTLRPC_MAX_BRW_PAGES) &&
+ (cli->cl_max_pages_per_rpc > 0));
+
+ client_adjust_max_dirty(cli);
+
+ /*
+ * Reset ns_connect_flags only for initial connect. It might be
+ * changed in while using FS and if we reset it in reconnect
+ * this leads to losing user settings done before such as
+ * disable lru_resize, etc.
+ */
+ if (old_connect_flags != exp_connect_flags(exp) || init_connect) {
+ CDEBUG(D_HA, "%s: Resetting ns_connect_flags to server flags: %#llx\n",
+ imp->imp_obd->obd_name, ocd->ocd_connect_flags);
+ imp->imp_obd->obd_namespace->ns_connect_flags =
+ ocd->ocd_connect_flags;
+ imp->imp_obd->obd_namespace->ns_orig_connect_flags =
+ ocd->ocd_connect_flags;
+ }
+
+ if ((ocd->ocd_connect_flags & OBD_CONNECT_AT) &&
+ (imp->imp_msg_magic == LUSTRE_MSG_MAGIC_V2))
+ /*
+ * We need a per-message support flag, because
+ * a. we don't know if the incoming connect reply
+ * supports AT or not (in reply_in_callback)
+ * until we unpack it.
+ * b. failovered server means export and flags are gone
+ * (in ptlrpc_send_reply).
+ * Can only be set when we know AT is supported at
+ * both ends
+ */
+ imp->imp_msghdr_flags |= MSGHDR_AT_SUPPORT;
+ else
+ imp->imp_msghdr_flags &= ~MSGHDR_AT_SUPPORT;
+
+ if ((ocd->ocd_connect_flags & OBD_CONNECT_FULL20) &&
+ (imp->imp_msg_magic == LUSTRE_MSG_MAGIC_V2))
+ imp->imp_msghdr_flags |= MSGHDR_CKSUM_INCOMPAT18;
+ else
+ imp->imp_msghdr_flags &= ~MSGHDR_CKSUM_INCOMPAT18;
+
+ return 0;
+}
+
/**
* interpret_reply callback for connect RPCs.
* Looks into returned status of connect operation and decides
@@ -762,7 +910,6 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
{
struct ptlrpc_connect_async_args *aa = data;
struct obd_import *imp = request->rq_import;
- struct client_obd *cli = &imp->imp_obd->u.cli;
struct lustre_handle old_hdl;
__u64 old_connect_flags;
int msg_flags;
@@ -842,7 +989,21 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
old_connect_flags = exp_connect_flags(exp);
exp->exp_connect_data = *ocd;
imp->imp_obd->obd_self_export->exp_connect_data = *ocd;
+
+ /*
+ * The net statistics after (re-)connect is not valid anymore,
+ * because may reflect other routing, etc.
+ */
+ at_init(&imp->imp_at.iat_net_latency, 0, 0);
+ ptlrpc_at_adj_net_latency(request,
+ lustre_msg_get_service_time(request->rq_repmsg));
+
+ /* Import flags should be updated before waking import at FULL state */
+ rc = ptlrpc_connect_set_flags(imp, ocd, old_connect_flags, exp,
+ aa->pcaa_initial_connect);
class_export_put(exp);
+ if (rc)
+ goto out;
obd_import_event(imp->imp_obd, imp, IMP_EVENT_OCD);
@@ -987,151 +1148,13 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
finish:
rc = ptlrpc_import_recovery_state_machine(imp);
- if (rc != 0) {
- if (rc == -ENOTCONN) {
- CDEBUG(D_HA, "evicted/aborted by %s@%s during recovery; invalidating and reconnecting\n",
- obd2cli_tgt(imp->imp_obd),
- imp->imp_connection->c_remote_uuid.uuid);
- ptlrpc_connect_import(imp);
- imp->imp_connect_tried = 1;
- return 0;
- }
- } else {
- static bool warned;
-
- spin_lock(&imp->imp_lock);
- list_del(&imp->imp_conn_current->oic_item);
- list_add(&imp->imp_conn_current->oic_item, &imp->imp_conn_list);
- imp->imp_last_success_conn =
- imp->imp_conn_current->oic_last_attempt;
-
- spin_unlock(&imp->imp_lock);
-
- if ((imp->imp_connect_flags_orig & OBD_CONNECT_IBITS) &&
- !(ocd->ocd_connect_flags & OBD_CONNECT_IBITS)) {
- LCONSOLE_WARN("%s: MDS %s does not support ibits lock, either very old or invalid: requested %llx, replied %llx\n",
- imp->imp_obd->obd_name,
- imp->imp_connection->c_remote_uuid.uuid,
- imp->imp_connect_flags_orig,
- ocd->ocd_connect_flags);
- rc = -EPROTO;
- goto out;
- }
-
- if (!warned && (ocd->ocd_connect_flags & OBD_CONNECT_VERSION) &&
- (ocd->ocd_version > LUSTRE_VERSION_CODE +
- LUSTRE_VERSION_OFFSET_WARN ||
- ocd->ocd_version < LUSTRE_VERSION_CODE -
- LUSTRE_VERSION_OFFSET_WARN)) {
- /* Sigh, some compilers do not like #ifdef in the middle
- * of macro arguments
- */
- const char *older = "older than client. Consider upgrading server";
- const char *newer = "newer than client. Consider recompiling application";
-
- LCONSOLE_WARN("Server %s version (%d.%d.%d.%d) is much %s (%s)\n",
- obd2cli_tgt(imp->imp_obd),
- OBD_OCD_VERSION_MAJOR(ocd->ocd_version),
- OBD_OCD_VERSION_MINOR(ocd->ocd_version),
- OBD_OCD_VERSION_PATCH(ocd->ocd_version),
- OBD_OCD_VERSION_FIX(ocd->ocd_version),
- ocd->ocd_version > LUSTRE_VERSION_CODE ?
- newer : older, LUSTRE_VERSION_STRING);
- warned = true;
- }
-
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 2, 50, 0)
- /* Check if server has LU-1252 fix applied to not always swab
- * the IR MNE entries. Do this only once per connection. This
- * fixup is version-limited, because we don't want to carry the
- * OBD_CONNECT_MNE_SWAB flag around forever, just so long as we
- * need interop with unpatched 2.2 servers. For newer servers,
- * the client will do MNE swabbing only as needed. LU-1644
- */
- if (unlikely((ocd->ocd_connect_flags & OBD_CONNECT_VERSION) &&
- !(ocd->ocd_connect_flags & OBD_CONNECT_MNE_SWAB) &&
- OBD_OCD_VERSION_MAJOR(ocd->ocd_version) == 2 &&
- OBD_OCD_VERSION_MINOR(ocd->ocd_version) == 2 &&
- OBD_OCD_VERSION_PATCH(ocd->ocd_version) < 55 &&
- strcmp(imp->imp_obd->obd_type->typ_name,
- LUSTRE_MGC_NAME) == 0))
- imp->imp_need_mne_swab = 1;
- else /* clear if server was upgraded since last connect */
- imp->imp_need_mne_swab = 0;
-#else
-#warning "LU-1644: Remove old OBD_CONNECT_MNE_SWAB fixup and imp_need_mne_swab"
-#endif
-
- if (ocd->ocd_connect_flags & OBD_CONNECT_CKSUM) {
- /* We sent to the server ocd_cksum_types with bits set
- * for algorithms we understand. The server masked off
- * the checksum types it doesn't support
- */
- if ((ocd->ocd_cksum_types &
- cksum_types_supported_client()) == 0) {
- LCONSOLE_WARN("The negotiation of the checksum algorithm to use with server %s failed (%x/%x), disabling checksums\n",
- obd2cli_tgt(imp->imp_obd),
- ocd->ocd_cksum_types,
- cksum_types_supported_client());
- cli->cl_checksum = 0;
- cli->cl_supp_cksum_types = OBD_CKSUM_ADLER;
- } else {
- cli->cl_supp_cksum_types = ocd->ocd_cksum_types;
- }
- } else {
- /* The server does not support OBD_CONNECT_CKSUM.
- * Enforce ADLER for backward compatibility
- */
- cli->cl_supp_cksum_types = OBD_CKSUM_ADLER;
- }
- cli->cl_cksum_type = cksum_type_select(cli->cl_supp_cksum_types);
-
- if (ocd->ocd_connect_flags & OBD_CONNECT_BRW_SIZE)
- cli->cl_max_pages_per_rpc =
- min(ocd->ocd_brw_size >> PAGE_SHIFT,
- cli->cl_max_pages_per_rpc);
- else if (imp->imp_connect_op == MDS_CONNECT ||
- imp->imp_connect_op == MGS_CONNECT)
- cli->cl_max_pages_per_rpc = 1;
-
- /* Reset ns_connect_flags only for initial connect. It might be
- * changed in while using FS and if we reset it in reconnect
- * this leads to losing user settings done before such as
- * disable lru_resize, etc.
- */
- if (old_connect_flags != exp_connect_flags(exp) ||
- aa->pcaa_initial_connect) {
- CDEBUG(D_HA, "%s: Resetting ns_connect_flags to server flags: %#llx\n",
- imp->imp_obd->obd_name, ocd->ocd_connect_flags);
- imp->imp_obd->obd_namespace->ns_connect_flags =
- ocd->ocd_connect_flags;
- imp->imp_obd->obd_namespace->ns_orig_connect_flags =
- ocd->ocd_connect_flags;
- }
-
- if ((ocd->ocd_connect_flags & OBD_CONNECT_AT) &&
- (imp->imp_msg_magic == LUSTRE_MSG_MAGIC_V2))
- /* We need a per-message support flag, because
- * a. we don't know if the incoming connect reply
- * supports AT or not (in reply_in_callback)
- * until we unpack it.
- * b. failovered server means export and flags are gone
- * (in ptlrpc_send_reply).
- * Can only be set when we know AT is supported at
- * both ends
- */
- imp->imp_msghdr_flags |= MSGHDR_AT_SUPPORT;
- else
- imp->imp_msghdr_flags &= ~MSGHDR_AT_SUPPORT;
-
- if ((ocd->ocd_connect_flags & OBD_CONNECT_FULL20) &&
- (imp->imp_msg_magic == LUSTRE_MSG_MAGIC_V2))
- imp->imp_msghdr_flags |= MSGHDR_CKSUM_INCOMPAT18;
- else
- imp->imp_msghdr_flags &= ~MSGHDR_CKSUM_INCOMPAT18;
-
- LASSERT((cli->cl_max_pages_per_rpc <= PTLRPC_MAX_BRW_PAGES) &&
- (cli->cl_max_pages_per_rpc > 0));
+ if (rc == -ENOTCONN) {
+ CDEBUG(D_HA, "evicted/aborted by %s@%s during recovery; invalidating and reconnecting\n",
+ obd2cli_tgt(imp->imp_obd),
+ imp->imp_connection->c_remote_uuid.uuid);
+ ptlrpc_connect_import(imp);
+ imp->imp_connect_tried = 1;
+ return 0;
}
out:
@@ -1497,10 +1520,13 @@ EXPORT_SYMBOL(ptlrpc_disconnect_import);
/* Adaptive Timeout utils */
extern unsigned int at_min, at_max, at_history;
-/* Bin into timeslices using AT_BINS bins.
- * This gives us a max of the last binlimit*AT_BINS secs without the storage,
- * but still smoothing out a return to normalcy from a slow response.
- * (E.g. remember the maximum latency in each minute of the last 4 minutes.)
+/*
+ *Update at_current with the specified value (bounded by at_min and at_max),
+ * as well as the AT history "bins".
+ * - Bin into timeslices using AT_BINS bins.
+ * - This gives us a max of the last at_history seconds without the storage,
+ * but still smoothing out a return to normalcy from a slow response.
+ * - (E.g. remember the maximum latency in each minute of the last 4 minutes.)
*/
int at_measured(struct adaptive_timeout *at, unsigned int val)
{
diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c
index ab5d85174245..839ef3e80c1a 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/layout.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c
@@ -667,11 +667,8 @@ static struct req_format *req_formats[] = {
&RQF_MDS_SYNC,
&RQF_MDS_CLOSE,
&RQF_MDS_RELEASE_CLOSE,
- &RQF_MDS_PIN,
- &RQF_MDS_UNPIN,
&RQF_MDS_READPAGE,
&RQF_MDS_WRITEPAGE,
- &RQF_MDS_IS_SUBDIR,
&RQF_MDS_DONE_WRITING,
&RQF_MDS_REINT,
&RQF_MDS_REINT_CREATE,
@@ -1116,9 +1113,9 @@ EXPORT_SYMBOL(RMF_SWAP_LAYOUTS);
struct req_format {
const char *rf_name;
- int rf_idx;
+ size_t rf_idx;
struct {
- int nr;
+ size_t nr;
const struct req_msg_field **d;
} rf_fields[RCL_NR];
};
@@ -1389,15 +1386,6 @@ struct req_format RQF_MDS_RELEASE_CLOSE =
mdt_release_close_client, mds_last_unlink_server);
EXPORT_SYMBOL(RQF_MDS_RELEASE_CLOSE);
-struct req_format RQF_MDS_PIN =
- DEFINE_REQ_FMT0("MDS_PIN",
- mdt_body_capa, mdt_body_only);
-EXPORT_SYMBOL(RQF_MDS_PIN);
-
-struct req_format RQF_MDS_UNPIN =
- DEFINE_REQ_FMT0("MDS_UNPIN", mdt_body_only, empty);
-EXPORT_SYMBOL(RQF_MDS_UNPIN);
-
struct req_format RQF_MDS_DONE_WRITING =
DEFINE_REQ_FMT0("MDS_DONE_WRITING",
mdt_close_client, mdt_body_only);
@@ -1448,11 +1436,6 @@ struct req_format RQF_MDS_WRITEPAGE =
mdt_body_capa, mdt_body_only);
EXPORT_SYMBOL(RQF_MDS_WRITEPAGE);
-struct req_format RQF_MDS_IS_SUBDIR =
- DEFINE_REQ_FMT0("MDS_IS_SUBDIR",
- mdt_body_only, mdt_body_only);
-EXPORT_SYMBOL(RQF_MDS_IS_SUBDIR);
-
struct req_format RQF_LLOG_ORIGIN_HANDLE_CREATE =
DEFINE_REQ_FMT0("LLOG_ORIGIN_HANDLE_CREATE",
llog_origin_handle_create_client, llogd_body_only);
@@ -1572,9 +1555,9 @@ EXPORT_SYMBOL(RQF_OST_GET_INFO_FIEMAP);
*/
int req_layout_init(void)
{
- int i;
- int j;
- int k;
+ size_t i;
+ size_t j;
+ size_t k;
struct req_format *rf = NULL;
for (i = 0; i < ARRAY_SIZE(req_formats); ++i) {
@@ -1616,7 +1599,7 @@ EXPORT_SYMBOL(req_layout_fini);
*/
static void req_capsule_init_area(struct req_capsule *pill)
{
- int i;
+ size_t i;
for (i = 0; i < ARRAY_SIZE(pill->rc_area[RCL_CLIENT]); i++) {
pill->rc_area[RCL_CLIENT][i] = -1;
@@ -1667,8 +1650,7 @@ EXPORT_SYMBOL(req_capsule_fini);
static int __req_format_is_sane(const struct req_format *fmt)
{
- return
- 0 <= fmt->rf_idx && fmt->rf_idx < ARRAY_SIZE(req_formats) &&
+ return fmt->rf_idx < ARRAY_SIZE(req_formats) &&
req_formats[fmt->rf_idx] == fmt;
}
@@ -1702,11 +1684,11 @@ EXPORT_SYMBOL(req_capsule_set);
* variable-sized fields. The field sizes come from the declared \a rmf_size
* field of a \a pill's \a rc_fmt's RMF's.
*/
-int req_capsule_filled_sizes(struct req_capsule *pill,
- enum req_location loc)
+size_t req_capsule_filled_sizes(struct req_capsule *pill,
+ enum req_location loc)
{
const struct req_format *fmt = pill->rc_fmt;
- int i;
+ size_t i;
for (i = 0; i < fmt->rf_fields[loc].nr; ++i) {
if (pill->rc_area[loc][i] == -1) {
@@ -1761,11 +1743,11 @@ EXPORT_SYMBOL(req_capsule_server_pack);
* Returns the PTLRPC request or reply (\a loc) buffer offset of a \a pill
* corresponding to the given RMF (\a field).
*/
-static int __req_capsule_offset(const struct req_capsule *pill,
+static u32 __req_capsule_offset(const struct req_capsule *pill,
const struct req_msg_field *field,
enum req_location loc)
{
- int offset;
+ u32 offset;
offset = field->rmf_offset[pill->rc_fmt->rf_idx][loc];
LASSERTF(offset > 0, "%s:%s, off=%d, loc=%d\n", pill->rc_fmt->rf_name,
@@ -1869,10 +1851,10 @@ static void *__req_capsule_get(struct req_capsule *pill,
const struct req_format *fmt;
struct lustre_msg *msg;
void *value;
- int len;
- int offset;
+ u32 len;
+ u32 offset;
- void *(*getter)(struct lustre_msg *m, int n, int minlen);
+ void *(*getter)(struct lustre_msg *m, u32 n, u32 minlen);
static const char *rcl_names[RCL_NR] = {
[RCL_CLIENT] = "client",
@@ -1899,20 +1881,20 @@ static void *__req_capsule_get(struct req_capsule *pill,
*/
len = lustre_msg_buflen(msg, offset);
if ((len % field->rmf_size) != 0) {
- CERROR("%s: array field size mismatch %d modulo %d != 0 (%d)\n",
+ CERROR("%s: array field size mismatch %d modulo %u != 0 (%d)\n",
field->rmf_name, len, field->rmf_size, loc);
return NULL;
}
} else if (pill->rc_area[loc][offset] != -1) {
len = pill->rc_area[loc][offset];
} else {
- len = max(field->rmf_size, 0);
+ len = max_t(typeof(field->rmf_size), field->rmf_size, 0);
}
value = getter(msg, offset, len);
if (!value) {
DEBUG_REQ(D_ERROR, pill->rc_req,
- "Wrong buffer for field `%s' (%d of %d) in format `%s': %d vs. %d (%s)\n",
+ "Wrong buffer for field `%s' (%u of %u) in format `%s': %u vs. %u (%s)\n",
field->rmf_name, offset, lustre_msg_bufcount(msg),
fmt->rf_name, lustre_msg_buflen(msg, offset), len,
rcl_names[loc]);
@@ -1958,7 +1940,7 @@ EXPORT_SYMBOL(req_capsule_client_swab_get);
*/
void *req_capsule_client_sized_get(struct req_capsule *pill,
const struct req_msg_field *field,
- int len)
+ u32 len)
{
req_capsule_set_size(pill, field, RCL_CLIENT, len);
return __req_capsule_get(pill, field, RCL_CLIENT, NULL, 0);
@@ -1999,7 +1981,7 @@ EXPORT_SYMBOL(req_capsule_server_swab_get);
*/
void *req_capsule_server_sized_get(struct req_capsule *pill,
const struct req_msg_field *field,
- int len)
+ u32 len)
{
req_capsule_set_size(pill, field, RCL_SERVER, len);
return __req_capsule_get(pill, field, RCL_SERVER, NULL, 0);
@@ -2008,7 +1990,7 @@ EXPORT_SYMBOL(req_capsule_server_sized_get);
void *req_capsule_server_sized_swab_get(struct req_capsule *pill,
const struct req_msg_field *field,
- int len, void *swabber)
+ u32 len, void *swabber)
{
req_capsule_set_size(pill, field, RCL_SERVER, len);
return __req_capsule_get(pill, field, RCL_SERVER, swabber, 0);
@@ -2024,23 +2006,25 @@ EXPORT_SYMBOL(req_capsule_server_sized_swab_get);
*/
void req_capsule_set_size(struct req_capsule *pill,
const struct req_msg_field *field,
- enum req_location loc, int size)
+ enum req_location loc, u32 size)
{
LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
- if ((size != field->rmf_size) &&
+ if ((size != (u32)field->rmf_size) &&
(field->rmf_size != -1) &&
!(field->rmf_flags & RMF_F_NO_SIZE_CHECK) &&
(size > 0)) {
+ u32 rmf_size = (u32)field->rmf_size;
+
if ((field->rmf_flags & RMF_F_STRUCT_ARRAY) &&
- (size % field->rmf_size != 0)) {
- CERROR("%s: array field size mismatch %d %% %d != 0 (%d)\n",
- field->rmf_name, size, field->rmf_size, loc);
+ (size % rmf_size != 0)) {
+ CERROR("%s: array field size mismatch %u %% %u != 0 (%d)\n",
+ field->rmf_name, size, rmf_size, loc);
LBUG();
} else if (!(field->rmf_flags & RMF_F_STRUCT_ARRAY) &&
- size < field->rmf_size) {
- CERROR("%s: field size mismatch %d != %d (%d)\n",
- field->rmf_name, size, field->rmf_size, loc);
+ size < rmf_size) {
+ CERROR("%s: field size mismatch %u != %u (%d)\n",
+ field->rmf_name, size, rmf_size, loc);
LBUG();
}
}
@@ -2057,7 +2041,7 @@ EXPORT_SYMBOL(req_capsule_set_size);
* actually sets the size in pill.rc_area[loc][offset], but this function
* returns the message buflen[offset], maybe we should use another name.
*/
-int req_capsule_get_size(const struct req_capsule *pill,
+u32 req_capsule_get_size(const struct req_capsule *pill,
const struct req_msg_field *field,
enum req_location loc)
{
@@ -2075,7 +2059,7 @@ EXPORT_SYMBOL(req_capsule_get_size);
*
* See also req_capsule_set_size().
*/
-int req_capsule_msg_size(struct req_capsule *pill, enum req_location loc)
+u32 req_capsule_msg_size(struct req_capsule *pill, enum req_location loc)
{
return lustre_msg_size(pill->rc_req->rq_import->imp_msg_magic,
pill->rc_fmt->rf_fields[loc].nr,
@@ -2090,10 +2074,11 @@ int req_capsule_msg_size(struct req_capsule *pill, enum req_location loc)
* This function should not be used for formats which contain variable size
* fields.
*/
-int req_capsule_fmt_size(__u32 magic, const struct req_format *fmt,
+u32 req_capsule_fmt_size(__u32 magic, const struct req_format *fmt,
enum req_location loc)
{
- int size, i = 0;
+ size_t i = 0;
+ u32 size;
/*
* This function should probably LASSERT() that fmt has no fields with
@@ -2103,7 +2088,7 @@ int req_capsule_fmt_size(__u32 magic, const struct req_format *fmt,
* we do.
*/
size = lustre_msg_hdr_size(magic, fmt->rf_fields[loc].nr);
- if (size < 0)
+ if (!size)
return size;
for (; i < fmt->rf_fields[loc].nr; ++i)
@@ -2135,7 +2120,7 @@ int req_capsule_fmt_size(__u32 magic, const struct req_format *fmt,
void req_capsule_extend(struct req_capsule *pill, const struct req_format *fmt)
{
int i;
- int j;
+ size_t j;
const struct req_format *old;
@@ -2193,7 +2178,7 @@ static int req_capsule_field_present(const struct req_capsule *pill,
const struct req_msg_field *field,
enum req_location loc)
{
- int offset;
+ u32 offset;
LASSERT(loc == RCL_SERVER || loc == RCL_CLIENT);
LASSERT(req_capsule_has_field(pill, field, loc));
@@ -2210,12 +2195,11 @@ static int req_capsule_field_present(const struct req_capsule *pill,
*/
void req_capsule_shrink(struct req_capsule *pill,
const struct req_msg_field *field,
- unsigned int newlen,
- enum req_location loc)
+ u32 newlen, enum req_location loc)
{
const struct req_format *fmt;
struct lustre_msg *msg;
- int len;
+ u32 len;
int offset;
fmt = pill->rc_fmt;
@@ -2228,7 +2212,7 @@ void req_capsule_shrink(struct req_capsule *pill,
msg = __req_msg(pill, loc);
len = lustre_msg_buflen(msg, offset);
- LASSERTF(newlen <= len, "%s:%s, oldlen=%d, newlen=%d\n",
+ LASSERTF(newlen <= len, "%s:%s, oldlen=%u, newlen=%u\n",
fmt->rf_name, field->rmf_name, len, newlen);
if (loc == RCL_CLIENT)
diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
index bc93b75744e1..9bad57d65db4 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
@@ -191,7 +191,7 @@ ptlrpc_ldebugfs_register(struct dentry *root, char *dir,
LASSERT(!*debugfs_root_ret);
LASSERT(!*stats_ret);
- svc_stats = lprocfs_alloc_stats(EXTRA_MAX_OPCODES+LUSTRE_MAX_OPCODES,
+ svc_stats = lprocfs_alloc_stats(EXTRA_MAX_OPCODES + LUSTRE_MAX_OPCODES,
0);
if (!svc_stats)
return;
@@ -937,7 +937,7 @@ static int ptlrpc_lprocfs_svc_req_history_show(struct seq_file *s, void *iter)
static int
ptlrpc_lprocfs_svc_req_history_open(struct inode *inode, struct file *file)
{
- static struct seq_operations sops = {
+ static const struct seq_operations sops = {
.start = ptlrpc_lprocfs_svc_req_history_start,
.stop = ptlrpc_lprocfs_svc_req_history_stop,
.next = ptlrpc_lprocfs_svc_req_history_next,
diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
index 11ec82545347..9c937398a085 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
@@ -295,7 +295,6 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int async)
}
return 0;
}
-EXPORT_SYMBOL(ptlrpc_unregister_bulk);
static void ptlrpc_at_set_reply(struct ptlrpc_request *req, int flags)
{
@@ -398,7 +397,8 @@ int ptlrpc_send_reply(struct ptlrpc_request *req, int flags)
lustre_msg_set_status(req->rq_repmsg,
ptlrpc_status_hton(req->rq_status));
lustre_msg_set_opc(req->rq_repmsg,
- req->rq_reqmsg ? lustre_msg_get_opc(req->rq_reqmsg) : 0);
+ req->rq_reqmsg ?
+ lustre_msg_get_opc(req->rq_reqmsg) : 0);
target_pack_pool_reply(req);
@@ -433,7 +433,6 @@ out:
ptlrpc_connection_put(conn);
return rc;
}
-EXPORT_SYMBOL(ptlrpc_send_reply);
int ptlrpc_reply(struct ptlrpc_request *req)
{
@@ -441,7 +440,6 @@ int ptlrpc_reply(struct ptlrpc_request *req)
return 0;
return ptlrpc_send_reply(req, 0);
}
-EXPORT_SYMBOL(ptlrpc_reply);
/**
* For request \a req send an error reply back. Create empty
@@ -468,13 +466,11 @@ int ptlrpc_send_error(struct ptlrpc_request *req, int may_be_difficult)
rc = ptlrpc_send_reply(req, may_be_difficult);
return rc;
}
-EXPORT_SYMBOL(ptlrpc_send_error);
int ptlrpc_error(struct ptlrpc_request *req)
{
return ptlrpc_send_error(req, 0);
}
-EXPORT_SYMBOL(ptlrpc_error);
/**
* Send request \a request.
@@ -490,7 +486,8 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply)
struct ptlrpc_connection *connection;
lnet_handle_me_t reply_me_h;
lnet_md_t reply_md;
- struct obd_device *obd = request->rq_import->imp_obd;
+ struct obd_import *imp = request->rq_import;
+ struct obd_device *obd = imp->imp_obd;
if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_DROP_RPC))
return 0;
@@ -503,7 +500,7 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply)
*/
LASSERT(!request->rq_receiving_reply);
LASSERT(!((lustre_msg_get_flags(request->rq_reqmsg) & MSG_REPLAY) &&
- (request->rq_import->imp_state == LUSTRE_IMP_FULL)));
+ (imp->imp_state == LUSTRE_IMP_FULL)));
if (unlikely(obd && obd->obd_fail)) {
CDEBUG(D_HA, "muting rpc for failed imp obd %s\n",
@@ -516,15 +513,22 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply)
return -ENODEV;
}
- connection = request->rq_import->imp_connection;
+ connection = imp->imp_connection;
lustre_msg_set_handle(request->rq_reqmsg,
- &request->rq_import->imp_remote_handle);
+ &imp->imp_remote_handle);
lustre_msg_set_type(request->rq_reqmsg, PTL_RPC_MSG_REQUEST);
- lustre_msg_set_conn_cnt(request->rq_reqmsg,
- request->rq_import->imp_conn_cnt);
- lustre_msghdr_set_flags(request->rq_reqmsg,
- request->rq_import->imp_msghdr_flags);
+ lustre_msg_set_conn_cnt(request->rq_reqmsg, imp->imp_conn_cnt);
+ lustre_msghdr_set_flags(request->rq_reqmsg, imp->imp_msghdr_flags);
+
+ /**
+ * For enabled AT all request should have AT_SUPPORT in the
+ * FULL import state when OBD_CONNECT_AT is set
+ */
+ LASSERT(AT_OFF || imp->imp_state != LUSTRE_IMP_FULL ||
+ (imp->imp_msghdr_flags & MSGHDR_AT_SUPPORT) ||
+ !(imp->imp_connect_data.ocd_connect_flags &
+ OBD_CONNECT_AT));
if (request->rq_resend)
lustre_msg_add_flags(request->rq_reqmsg, MSG_RESENT);
@@ -628,7 +632,7 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply)
ptlrpc_request_addref(request);
if (obd && obd->obd_svc_stats)
lprocfs_counter_add(obd->obd_svc_stats, PTLRPC_REQACTIVE_CNTR,
- atomic_read(&request->rq_import->imp_inflight));
+ atomic_read(&imp->imp_inflight));
OBD_FAIL_TIMEOUT(OBD_FAIL_PTLRPC_DELAY_SEND, request->rq_timeout + 5);
@@ -640,7 +644,7 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply)
request->rq_deadline = request->rq_sent + request->rq_timeout +
ptlrpc_at_get_net_latency(request);
- ptlrpc_pinger_sending_on_import(request->rq_import);
+ ptlrpc_pinger_sending_on_import(imp);
DEBUG_REQ(D_INFO, request, "send flg=%x",
lustre_msg_get_flags(request->rq_reqmsg));
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
index b514f18fae50..871768511e8c 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
@@ -50,36 +50,34 @@
#include "ptlrpc_internal.h"
-static inline int lustre_msg_hdr_size_v2(int count)
+static inline u32 lustre_msg_hdr_size_v2(u32 count)
{
return cfs_size_round(offsetof(struct lustre_msg_v2,
lm_buflens[count]));
}
-int lustre_msg_hdr_size(__u32 magic, int count)
+u32 lustre_msg_hdr_size(__u32 magic, u32 count)
{
switch (magic) {
case LUSTRE_MSG_MAGIC_V2:
return lustre_msg_hdr_size_v2(count);
default:
LASSERTF(0, "incorrect message magic: %08x\n", magic);
- return -EINVAL;
+ return 0;
}
}
-EXPORT_SYMBOL(lustre_msg_hdr_size);
void ptlrpc_buf_set_swabbed(struct ptlrpc_request *req, const int inout,
- int index)
+ u32 index)
{
if (inout)
lustre_set_req_swabbed(req, index);
else
lustre_set_rep_swabbed(req, index);
}
-EXPORT_SYMBOL(ptlrpc_buf_set_swabbed);
int ptlrpc_buf_need_swab(struct ptlrpc_request *req, const int inout,
- int index)
+ u32 index)
{
if (inout)
return (ptlrpc_req_need_swab(req) &&
@@ -88,12 +86,11 @@ int ptlrpc_buf_need_swab(struct ptlrpc_request *req, const int inout,
return (ptlrpc_rep_need_swab(req) &&
!lustre_rep_swabbed(req, index));
}
-EXPORT_SYMBOL(ptlrpc_buf_need_swab);
/* early reply size */
-int lustre_msg_early_size(void)
+u32 lustre_msg_early_size(void)
{
- static int size;
+ static u32 size;
if (!size) {
/* Always reply old ptlrpc_body_v2 to keep interoperability
@@ -111,9 +108,9 @@ int lustre_msg_early_size(void)
}
EXPORT_SYMBOL(lustre_msg_early_size);
-int lustre_msg_size_v2(int count, __u32 *lengths)
+u32 lustre_msg_size_v2(int count, __u32 *lengths)
{
- int size;
+ u32 size;
int i;
size = lustre_msg_hdr_size_v2(count);
@@ -131,7 +128,7 @@ EXPORT_SYMBOL(lustre_msg_size_v2);
* target then the first buffer will be stripped because the ptlrpc
* data is part of the lustre_msg_v1 header. b=14043
*/
-int lustre_msg_size(__u32 magic, int count, __u32 *lens)
+u32 lustre_msg_size(__u32 magic, int count, __u32 *lens)
{
__u32 size[] = { sizeof(struct ptlrpc_body) };
@@ -148,15 +145,14 @@ int lustre_msg_size(__u32 magic, int count, __u32 *lens)
return lustre_msg_size_v2(count, lens);
default:
LASSERTF(0, "incorrect message magic: %08x\n", magic);
- return -EINVAL;
+ return 0;
}
}
-EXPORT_SYMBOL(lustre_msg_size);
/* This is used to determine the size of a buffer that was already packed
* and will correctly handle the different message formats.
*/
-int lustre_packed_msg_size(struct lustre_msg *msg)
+u32 lustre_packed_msg_size(struct lustre_msg *msg)
{
switch (msg->lm_magic) {
case LUSTRE_MSG_MAGIC_V2:
@@ -166,7 +162,6 @@ int lustre_packed_msg_size(struct lustre_msg *msg)
return 0;
}
}
-EXPORT_SYMBOL(lustre_packed_msg_size);
void lustre_init_msg_v2(struct lustre_msg_v2 *msg, int count, __u32 *lens,
char **bufs)
@@ -227,7 +222,6 @@ int lustre_pack_request(struct ptlrpc_request *req, __u32 magic, int count,
/* only use new format, we don't need to be compatible with 1.4 */
return lustre_pack_request_v2(req, count, lens, bufs);
}
-EXPORT_SYMBOL(lustre_pack_request);
#if RS_DEBUG
LIST_HEAD(ptlrpc_rs_debug_lru);
@@ -369,7 +363,6 @@ int lustre_pack_reply_flags(struct ptlrpc_request *req, int count, __u32 *lens,
lustre_msg_size(req->rq_reqmsg->lm_magic, count, lens));
return rc;
}
-EXPORT_SYMBOL(lustre_pack_reply_flags);
int lustre_pack_reply(struct ptlrpc_request *req, int count, __u32 *lens,
char **bufs)
@@ -378,11 +371,9 @@ int lustre_pack_reply(struct ptlrpc_request *req, int count, __u32 *lens,
}
EXPORT_SYMBOL(lustre_pack_reply);
-void *lustre_msg_buf_v2(struct lustre_msg_v2 *m, int n, int min_size)
+void *lustre_msg_buf_v2(struct lustre_msg_v2 *m, u32 n, u32 min_size)
{
- int i, offset, buflen, bufcount;
-
- LASSERT(n >= 0);
+ u32 i, offset, buflen, bufcount;
bufcount = m->lm_bufcount;
if (unlikely(n >= bufcount)) {
@@ -406,7 +397,7 @@ void *lustre_msg_buf_v2(struct lustre_msg_v2 *m, int n, int min_size)
return (char *)m + offset;
}
-void *lustre_msg_buf(struct lustre_msg *m, int n, int min_size)
+void *lustre_msg_buf(struct lustre_msg *m, u32 n, u32 min_size)
{
switch (m->lm_magic) {
case LUSTRE_MSG_MAGIC_V2:
@@ -419,7 +410,7 @@ void *lustre_msg_buf(struct lustre_msg *m, int n, int min_size)
}
EXPORT_SYMBOL(lustre_msg_buf);
-static int lustre_shrink_msg_v2(struct lustre_msg_v2 *msg, int segment,
+static int lustre_shrink_msg_v2(struct lustre_msg_v2 *msg, u32 segment,
unsigned int newlen, int move_data)
{
char *tail = NULL, *newpos;
@@ -493,7 +484,6 @@ void lustre_free_reply_state(struct ptlrpc_reply_state *rs)
sptlrpc_svc_free_rs(rs);
}
-EXPORT_SYMBOL(lustre_free_reply_state);
static int lustre_unpack_msg_v2(struct lustre_msg_v2 *m, int len)
{
@@ -581,7 +571,6 @@ int ptlrpc_unpack_req_msg(struct ptlrpc_request *req, int len)
}
return rc;
}
-EXPORT_SYMBOL(ptlrpc_unpack_req_msg);
int ptlrpc_unpack_rep_msg(struct ptlrpc_request *req, int len)
{
@@ -594,7 +583,6 @@ int ptlrpc_unpack_rep_msg(struct ptlrpc_request *req, int len)
}
return rc;
}
-EXPORT_SYMBOL(ptlrpc_unpack_rep_msg);
static inline int lustre_unpack_ptlrpc_body_v2(struct ptlrpc_request *req,
const int inout, int offset)
@@ -647,7 +635,7 @@ int lustre_unpack_rep_ptlrpc_body(struct ptlrpc_request *req, int offset)
}
}
-static inline int lustre_msg_buflen_v2(struct lustre_msg_v2 *m, int n)
+static inline u32 lustre_msg_buflen_v2(struct lustre_msg_v2 *m, u32 n)
{
if (n >= m->lm_bufcount)
return 0;
@@ -662,14 +650,14 @@ static inline int lustre_msg_buflen_v2(struct lustre_msg_v2 *m, int n)
*
* returns zero for non-existent message indices
*/
-int lustre_msg_buflen(struct lustre_msg *m, int n)
+u32 lustre_msg_buflen(struct lustre_msg *m, u32 n)
{
switch (m->lm_magic) {
case LUSTRE_MSG_MAGIC_V2:
return lustre_msg_buflen_v2(m, n);
default:
CERROR("incorrect message magic: %08x\n", m->lm_magic);
- return -EINVAL;
+ return 0;
}
}
EXPORT_SYMBOL(lustre_msg_buflen);
@@ -677,23 +665,22 @@ EXPORT_SYMBOL(lustre_msg_buflen);
/* NB return the bufcount for lustre_msg_v2 format, so if message is packed
* in V1 format, the result is one bigger. (add struct ptlrpc_body).
*/
-int lustre_msg_bufcount(struct lustre_msg *m)
+u32 lustre_msg_bufcount(struct lustre_msg *m)
{
switch (m->lm_magic) {
case LUSTRE_MSG_MAGIC_V2:
return m->lm_bufcount;
default:
CERROR("incorrect message magic: %08x\n", m->lm_magic);
- return -EINVAL;
+ return 0;
}
}
-EXPORT_SYMBOL(lustre_msg_bufcount);
-char *lustre_msg_string(struct lustre_msg *m, int index, int max_len)
+char *lustre_msg_string(struct lustre_msg *m, u32 index, u32 max_len)
{
/* max_len == 0 means the string should fill the buffer */
char *str;
- int slen, blen;
+ u32 slen, blen;
switch (m->lm_magic) {
case LUSTRE_MSG_MAGIC_V2:
@@ -731,11 +718,10 @@ char *lustre_msg_string(struct lustre_msg *m, int index, int max_len)
return str;
}
-EXPORT_SYMBOL(lustre_msg_string);
/* Wrap up the normal fixed length cases */
-static inline void *__lustre_swab_buf(struct lustre_msg *msg, int index,
- int min_size, void *swabber)
+static inline void *__lustre_swab_buf(struct lustre_msg *msg, u32 index,
+ u32 min_size, void *swabber)
{
void *ptr = NULL;
@@ -804,7 +790,7 @@ __u32 lustre_msg_get_flags(struct lustre_msg *msg)
}
EXPORT_SYMBOL(lustre_msg_get_flags);
-void lustre_msg_add_flags(struct lustre_msg *msg, int flags)
+void lustre_msg_add_flags(struct lustre_msg *msg, u32 flags)
{
switch (msg->lm_magic) {
case LUSTRE_MSG_MAGIC_V2: {
@@ -820,7 +806,7 @@ void lustre_msg_add_flags(struct lustre_msg *msg, int flags)
}
EXPORT_SYMBOL(lustre_msg_add_flags);
-void lustre_msg_set_flags(struct lustre_msg *msg, int flags)
+void lustre_msg_set_flags(struct lustre_msg *msg, u32 flags)
{
switch (msg->lm_magic) {
case LUSTRE_MSG_MAGIC_V2: {
@@ -834,9 +820,8 @@ void lustre_msg_set_flags(struct lustre_msg *msg, int flags)
LASSERTF(0, "incorrect message magic: %08x\n", msg->lm_magic);
}
}
-EXPORT_SYMBOL(lustre_msg_set_flags);
-void lustre_msg_clear_flags(struct lustre_msg *msg, int flags)
+void lustre_msg_clear_flags(struct lustre_msg *msg, u32 flags)
{
switch (msg->lm_magic) {
case LUSTRE_MSG_MAGIC_V2: {
@@ -868,9 +853,8 @@ __u32 lustre_msg_get_op_flags(struct lustre_msg *msg)
return 0;
}
}
-EXPORT_SYMBOL(lustre_msg_get_op_flags);
-void lustre_msg_add_op_flags(struct lustre_msg *msg, int flags)
+void lustre_msg_add_op_flags(struct lustre_msg *msg, u32 flags)
{
switch (msg->lm_magic) {
case LUSTRE_MSG_MAGIC_V2: {
@@ -903,7 +887,6 @@ struct lustre_handle *lustre_msg_get_handle(struct lustre_msg *msg)
return NULL;
}
}
-EXPORT_SYMBOL(lustre_msg_get_handle);
__u32 lustre_msg_get_type(struct lustre_msg *msg)
{
@@ -924,7 +907,7 @@ __u32 lustre_msg_get_type(struct lustre_msg *msg)
}
EXPORT_SYMBOL(lustre_msg_get_type);
-void lustre_msg_add_version(struct lustre_msg *msg, int version)
+void lustre_msg_add_version(struct lustre_msg *msg, u32 version)
{
switch (msg->lm_magic) {
case LUSTRE_MSG_MAGIC_V2: {
@@ -938,7 +921,6 @@ void lustre_msg_add_version(struct lustre_msg *msg, int version)
LASSERTF(0, "incorrect message magic: %08x\n", msg->lm_magic);
}
}
-EXPORT_SYMBOL(lustre_msg_add_version);
__u32 lustre_msg_get_opc(struct lustre_msg *msg)
{
@@ -1055,7 +1037,6 @@ __u64 lustre_msg_get_slv(struct lustre_msg *msg)
return -EINVAL;
}
}
-EXPORT_SYMBOL(lustre_msg_get_slv);
void lustre_msg_set_slv(struct lustre_msg *msg, __u64 slv)
{
@@ -1075,7 +1056,6 @@ void lustre_msg_set_slv(struct lustre_msg *msg, __u64 slv)
return;
}
}
-EXPORT_SYMBOL(lustre_msg_set_slv);
__u32 lustre_msg_get_limit(struct lustre_msg *msg)
{
@@ -1094,7 +1074,6 @@ __u32 lustre_msg_get_limit(struct lustre_msg *msg)
return -EINVAL;
}
}
-EXPORT_SYMBOL(lustre_msg_get_limit);
void lustre_msg_set_limit(struct lustre_msg *msg, __u64 limit)
{
@@ -1114,7 +1093,6 @@ void lustre_msg_set_limit(struct lustre_msg *msg, __u64 limit)
return;
}
}
-EXPORT_SYMBOL(lustre_msg_set_limit);
__u32 lustre_msg_get_conn_cnt(struct lustre_msg *msg)
{
@@ -1145,7 +1123,6 @@ __u32 lustre_msg_get_magic(struct lustre_msg *msg)
return 0;
}
}
-EXPORT_SYMBOL(lustre_msg_get_magic);
__u32 lustre_msg_get_timeout(struct lustre_msg *msg)
{
@@ -1203,8 +1180,9 @@ __u32 lustre_msg_calc_cksum(struct lustre_msg *msg)
unsigned int hsize = 4;
cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32, (unsigned char *)pb,
- lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF),
- NULL, 0, (unsigned char *)&crc, &hsize);
+ lustre_msg_buflen(msg,
+ MSG_PTLRPC_BODY_OFF),
+ NULL, 0, (unsigned char *)&crc, &hsize);
return crc;
}
default:
@@ -1227,7 +1205,6 @@ void lustre_msg_set_handle(struct lustre_msg *msg, struct lustre_handle *handle)
LASSERTF(0, "incorrect message magic: %08x\n", msg->lm_magic);
}
}
-EXPORT_SYMBOL(lustre_msg_set_handle);
void lustre_msg_set_type(struct lustre_msg *msg, __u32 type)
{
@@ -1243,7 +1220,6 @@ void lustre_msg_set_type(struct lustre_msg *msg, __u32 type)
LASSERTF(0, "incorrect message magic: %08x\n", msg->lm_magic);
}
}
-EXPORT_SYMBOL(lustre_msg_set_type);
void lustre_msg_set_opc(struct lustre_msg *msg, __u32 opc)
{
@@ -1259,7 +1235,6 @@ void lustre_msg_set_opc(struct lustre_msg *msg, __u32 opc)
LASSERTF(0, "incorrect message magic: %08x\n", msg->lm_magic);
}
}
-EXPORT_SYMBOL(lustre_msg_set_opc);
void lustre_msg_set_versions(struct lustre_msg *msg, __u64 *versions)
{
@@ -1326,7 +1301,6 @@ void lustre_msg_set_conn_cnt(struct lustre_msg *msg, __u32 conn_cnt)
LASSERTF(0, "incorrect message magic: %08x\n", msg->lm_magic);
}
}
-EXPORT_SYMBOL(lustre_msg_set_conn_cnt);
void lustre_msg_set_timeout(struct lustre_msg *msg, __u32 timeout)
{
@@ -1377,7 +1351,7 @@ void lustre_msg_set_jobid(struct lustre_msg *msg, char *jobid)
LASSERTF(pb, "invalid msg %p: no ptlrpc body!\n", msg);
if (jobid)
- memcpy(pb->pb_jobid, jobid, JOBSTATS_JOBID_SIZE);
+ memcpy(pb->pb_jobid, jobid, LUSTRE_JOBID_SIZE);
else if (pb->pb_jobid[0] == '\0')
lustre_get_jobid(pb->pb_jobid);
return;
@@ -1491,7 +1465,6 @@ void lustre_swab_ptlrpc_body(struct ptlrpc_body *b)
*/
CLASSERT(offsetof(typeof(*b), pb_jobid) != 0);
}
-EXPORT_SYMBOL(lustre_swab_ptlrpc_body);
void lustre_swab_connect(struct obd_connect_data *ocd)
{
@@ -1591,7 +1564,6 @@ void lustre_swab_obd_statfs(struct obd_statfs *os)
CLASSERT(offsetof(typeof(*os), os_spare8) != 0);
CLASSERT(offsetof(typeof(*os), os_spare9) != 0);
}
-EXPORT_SYMBOL(lustre_swab_obd_statfs);
void lustre_swab_obd_ioobj(struct obd_ioobj *ioo)
{
@@ -1599,33 +1571,28 @@ void lustre_swab_obd_ioobj(struct obd_ioobj *ioo)
__swab32s(&ioo->ioo_max_brw);
__swab32s(&ioo->ioo_bufcnt);
}
-EXPORT_SYMBOL(lustre_swab_obd_ioobj);
void lustre_swab_niobuf_remote(struct niobuf_remote *nbr)
{
- __swab64s(&nbr->offset);
- __swab32s(&nbr->len);
- __swab32s(&nbr->flags);
+ __swab64s(&nbr->rnb_offset);
+ __swab32s(&nbr->rnb_len);
+ __swab32s(&nbr->rnb_flags);
}
-EXPORT_SYMBOL(lustre_swab_niobuf_remote);
void lustre_swab_ost_body(struct ost_body *b)
{
lustre_swab_obdo(&b->oa);
}
-EXPORT_SYMBOL(lustre_swab_ost_body);
void lustre_swab_ost_last_id(u64 *id)
{
__swab64s(id);
}
-EXPORT_SYMBOL(lustre_swab_ost_last_id);
void lustre_swab_generic_32s(__u32 *val)
{
__swab32s(val);
}
-EXPORT_SYMBOL(lustre_swab_generic_32s);
void lustre_swab_gl_desc(union ldlm_gl_desc *desc)
{
@@ -1674,37 +1641,36 @@ EXPORT_SYMBOL(lustre_swab_lquota_lvb);
void lustre_swab_mdt_body(struct mdt_body *b)
{
- lustre_swab_lu_fid(&b->fid1);
- lustre_swab_lu_fid(&b->fid2);
+ lustre_swab_lu_fid(&b->mbo_fid1);
+ lustre_swab_lu_fid(&b->mbo_fid2);
/* handle is opaque */
- __swab64s(&b->valid);
- __swab64s(&b->size);
- __swab64s(&b->mtime);
- __swab64s(&b->atime);
- __swab64s(&b->ctime);
- __swab64s(&b->blocks);
- __swab64s(&b->ioepoch);
- __swab64s(&b->t_state);
- __swab32s(&b->fsuid);
- __swab32s(&b->fsgid);
- __swab32s(&b->capability);
- __swab32s(&b->mode);
- __swab32s(&b->uid);
- __swab32s(&b->gid);
- __swab32s(&b->flags);
- __swab32s(&b->rdev);
- __swab32s(&b->nlink);
- CLASSERT(offsetof(typeof(*b), unused2) != 0);
- __swab32s(&b->suppgid);
- __swab32s(&b->eadatasize);
- __swab32s(&b->aclsize);
- __swab32s(&b->max_mdsize);
- __swab32s(&b->max_cookiesize);
- __swab32s(&b->uid_h);
- __swab32s(&b->gid_h);
- CLASSERT(offsetof(typeof(*b), padding_5) != 0);
-}
-EXPORT_SYMBOL(lustre_swab_mdt_body);
+ __swab64s(&b->mbo_valid);
+ __swab64s(&b->mbo_size);
+ __swab64s(&b->mbo_mtime);
+ __swab64s(&b->mbo_atime);
+ __swab64s(&b->mbo_ctime);
+ __swab64s(&b->mbo_blocks);
+ __swab64s(&b->mbo_ioepoch);
+ __swab64s(&b->mbo_t_state);
+ __swab32s(&b->mbo_fsuid);
+ __swab32s(&b->mbo_fsgid);
+ __swab32s(&b->mbo_capability);
+ __swab32s(&b->mbo_mode);
+ __swab32s(&b->mbo_uid);
+ __swab32s(&b->mbo_gid);
+ __swab32s(&b->mbo_flags);
+ __swab32s(&b->mbo_rdev);
+ __swab32s(&b->mbo_nlink);
+ CLASSERT(offsetof(typeof(*b), mbo_unused2) != 0);
+ __swab32s(&b->mbo_suppgid);
+ __swab32s(&b->mbo_eadatasize);
+ __swab32s(&b->mbo_aclsize);
+ __swab32s(&b->mbo_max_mdsize);
+ __swab32s(&b->mbo_max_cookiesize);
+ __swab32s(&b->mbo_uid_h);
+ __swab32s(&b->mbo_gid_h);
+ CLASSERT(offsetof(typeof(*b), mbo_padding_5) != 0);
+}
void lustre_swab_mdt_ioepoch(struct mdt_ioepoch *b)
{
@@ -1713,7 +1679,6 @@ void lustre_swab_mdt_ioepoch(struct mdt_ioepoch *b)
__swab32s(&b->flags);
CLASSERT(offsetof(typeof(*b), padding) != 0);
}
-EXPORT_SYMBOL(lustre_swab_mdt_ioepoch);
void lustre_swab_mgs_target_info(struct mgs_target_info *mti)
{
@@ -1729,11 +1694,10 @@ void lustre_swab_mgs_target_info(struct mgs_target_info *mti)
for (i = 0; i < MTI_NIDS_MAX; i++)
__swab64s(&mti->mti_nids[i]);
}
-EXPORT_SYMBOL(lustre_swab_mgs_target_info);
void lustre_swab_mgs_nidtbl_entry(struct mgs_nidtbl_entry *entry)
{
- int i;
+ __u8 i;
__swab64s(&entry->mne_version);
__swab32s(&entry->mne_instance);
@@ -1760,14 +1724,12 @@ void lustre_swab_mgs_config_body(struct mgs_config_body *body)
__swab32s(&body->mcb_units);
__swab16s(&body->mcb_type);
}
-EXPORT_SYMBOL(lustre_swab_mgs_config_body);
void lustre_swab_mgs_config_res(struct mgs_config_res *body)
{
__swab64s(&body->mcr_offset);
__swab64s(&body->mcr_size);
}
-EXPORT_SYMBOL(lustre_swab_mgs_config_res);
static void lustre_swab_obd_dqinfo(struct obd_dqinfo *i)
{
@@ -1800,7 +1762,6 @@ void lustre_swab_obd_quotactl(struct obd_quotactl *q)
lustre_swab_obd_dqinfo(&q->qc_dqinfo);
lustre_swab_obd_dqblk(&q->qc_dqblk);
}
-EXPORT_SYMBOL(lustre_swab_obd_quotactl);
void lustre_swab_fid2path(struct getinfo_fid2path *gf)
{
@@ -1822,7 +1783,7 @@ static void lustre_swab_fiemap_extent(struct ll_fiemap_extent *fm_extent)
void lustre_swab_fiemap(struct ll_user_fiemap *fiemap)
{
- int i;
+ __u32 i;
__swab64s(&fiemap->fm_start);
__swab64s(&fiemap->fm_length);
@@ -1834,7 +1795,6 @@ void lustre_swab_fiemap(struct ll_user_fiemap *fiemap)
for (i = 0; i < fiemap->fm_mapped_extents; i++)
lustre_swab_fiemap_extent(&fiemap->fm_extents[i]);
}
-EXPORT_SYMBOL(lustre_swab_fiemap);
void lustre_swab_mdt_rec_reint (struct mdt_rec_reint *rr)
{
@@ -1863,7 +1823,6 @@ void lustre_swab_mdt_rec_reint (struct mdt_rec_reint *rr)
CLASSERT(offsetof(typeof(*rr), rr_padding_4) != 0);
};
-EXPORT_SYMBOL(lustre_swab_mdt_rec_reint);
void lustre_swab_lov_desc(struct lov_desc *ld)
{
@@ -1878,18 +1837,42 @@ void lustre_swab_lov_desc(struct lov_desc *ld)
}
EXPORT_SYMBOL(lustre_swab_lov_desc);
-static void print_lum(struct lov_user_md *lum)
+/* This structure is always in little-endian */
+static void lustre_swab_lmv_mds_md_v1(struct lmv_mds_md_v1 *lmm1)
+{
+ int i;
+
+ __swab32s(&lmm1->lmv_magic);
+ __swab32s(&lmm1->lmv_stripe_count);
+ __swab32s(&lmm1->lmv_master_mdt_index);
+ __swab32s(&lmm1->lmv_hash_type);
+ __swab32s(&lmm1->lmv_layout_version);
+ for (i = 0; i < lmm1->lmv_stripe_count; i++)
+ lustre_swab_lu_fid(&lmm1->lmv_stripe_fids[i]);
+}
+
+void lustre_swab_lmv_mds_md(union lmv_mds_md *lmm)
+{
+ switch (lmm->lmv_magic) {
+ case LMV_MAGIC_V1:
+ lustre_swab_lmv_mds_md_v1(&lmm->lmv_md_v1);
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(lustre_swab_lmv_mds_md);
+
+void lustre_swab_lmv_user_md(struct lmv_user_md *lum)
{
- CDEBUG(D_OTHER, "lov_user_md %p:\n", lum);
- CDEBUG(D_OTHER, "\tlmm_magic: %#x\n", lum->lmm_magic);
- CDEBUG(D_OTHER, "\tlmm_pattern: %#x\n", lum->lmm_pattern);
- CDEBUG(D_OTHER, "\tlmm_object_id: %llu\n", lmm_oi_id(&lum->lmm_oi));
- CDEBUG(D_OTHER, "\tlmm_object_gr: %llu\n", lmm_oi_seq(&lum->lmm_oi));
- CDEBUG(D_OTHER, "\tlmm_stripe_size: %#x\n", lum->lmm_stripe_size);
- CDEBUG(D_OTHER, "\tlmm_stripe_count: %#x\n", lum->lmm_stripe_count);
- CDEBUG(D_OTHER, "\tlmm_stripe_offset/lmm_layout_gen: %#x\n",
- lum->lmm_stripe_offset);
+ __swab32s(&lum->lum_magic);
+ __swab32s(&lum->lum_stripe_count);
+ __swab32s(&lum->lum_stripe_offset);
+ __swab32s(&lum->lum_hash_type);
+ __swab32s(&lum->lum_type);
+ CLASSERT(offsetof(typeof(*lum), lum_padding1));
}
+EXPORT_SYMBOL(lustre_swab_lmv_user_md);
static void lustre_swab_lmm_oi(struct ost_id *oi)
{
@@ -1905,7 +1888,6 @@ static void lustre_swab_lov_user_md_common(struct lov_user_md_v1 *lum)
__swab32s(&lum->lmm_stripe_size);
__swab16s(&lum->lmm_stripe_count);
__swab16s(&lum->lmm_stripe_offset);
- print_lum(lum);
}
void lustre_swab_lov_user_md_v1(struct lov_user_md_v1 *lum)
@@ -1941,9 +1923,9 @@ void lustre_swab_lov_user_md_objects(struct lov_user_ost_data *lod,
int i;
for (i = 0; i < stripe_count; i++) {
- lustre_swab_ost_id(&(lod[i].l_ost_oi));
- __swab32s(&(lod[i].l_ost_gen));
- __swab32s(&(lod[i].l_ost_idx));
+ lustre_swab_ost_id(&lod[i].l_ost_oi);
+ __swab32s(&lod[i].l_ost_gen);
+ __swab32s(&lod[i].l_ost_idx);
}
}
EXPORT_SYMBOL(lustre_swab_lov_user_md_objects);
@@ -1973,7 +1955,6 @@ void lustre_swab_ldlm_intent(struct ldlm_intent *i)
{
__swab64s(&i->opc);
}
-EXPORT_SYMBOL(lustre_swab_ldlm_intent);
static void lustre_swab_ldlm_resource_desc(struct ldlm_resource_desc *r)
{
@@ -1997,7 +1978,6 @@ void lustre_swab_ldlm_request(struct ldlm_request *rq)
__swab32s(&rq->lock_count);
/* lock_handle[] opaque */
}
-EXPORT_SYMBOL(lustre_swab_ldlm_request);
void lustre_swab_ldlm_reply(struct ldlm_reply *r)
{
@@ -2008,7 +1988,6 @@ void lustre_swab_ldlm_reply(struct ldlm_reply *r)
__swab64s(&r->lock_policy_res1);
__swab64s(&r->lock_policy_res2);
}
-EXPORT_SYMBOL(lustre_swab_ldlm_reply);
/* Dump functions */
void dump_ioo(struct obd_ioobj *ioo)
@@ -2018,14 +1997,12 @@ void dump_ioo(struct obd_ioobj *ioo)
POSTID(&ioo->ioo_oid), ioo->ioo_max_brw,
ioo->ioo_bufcnt);
}
-EXPORT_SYMBOL(dump_ioo);
void dump_rniobuf(struct niobuf_remote *nb)
{
CDEBUG(D_RPCTRACE, "niobuf_remote: offset=%llu, len=%d, flags=%x\n",
- nb->offset, nb->len, nb->flags);
+ nb->rnb_offset, nb->rnb_len, nb->rnb_flags);
}
-EXPORT_SYMBOL(dump_rniobuf);
static void dump_obdo(struct obdo *oa)
{
@@ -2093,13 +2070,11 @@ void dump_ost_body(struct ost_body *ob)
{
dump_obdo(&ob->oa);
}
-EXPORT_SYMBOL(dump_ost_body);
void dump_rcs(__u32 *rc)
{
CDEBUG(D_RPCTRACE, "rmf_rcs: %d\n", *rc);
}
-EXPORT_SYMBOL(dump_rcs);
static inline int req_ptlrpc_body_swabbed(struct ptlrpc_request *req)
{
@@ -2184,14 +2159,12 @@ void lustre_swab_lustre_capa(struct lustre_capa *c)
__swab32s(&c->lc_timeout);
__swab32s(&c->lc_expiry);
}
-EXPORT_SYMBOL(lustre_swab_lustre_capa);
void lustre_swab_hsm_user_state(struct hsm_user_state *state)
{
__swab32s(&state->hus_states);
__swab32s(&state->hus_archive_id);
}
-EXPORT_SYMBOL(lustre_swab_hsm_user_state);
void lustre_swab_hsm_state_set(struct hsm_state_set *hss)
{
@@ -2214,14 +2187,12 @@ void lustre_swab_hsm_current_action(struct hsm_current_action *action)
__swab32s(&action->hca_action);
lustre_swab_hsm_extent(&action->hca_location);
}
-EXPORT_SYMBOL(lustre_swab_hsm_current_action);
void lustre_swab_hsm_user_item(struct hsm_user_item *hui)
{
lustre_swab_lu_fid(&hui->hui_fid);
lustre_swab_hsm_extent(&hui->hui_extent);
}
-EXPORT_SYMBOL(lustre_swab_hsm_user_item);
void lustre_swab_layout_intent(struct layout_intent *li)
{
@@ -2230,7 +2201,6 @@ void lustre_swab_layout_intent(struct layout_intent *li)
__swab64s(&li->li_start);
__swab64s(&li->li_end);
}
-EXPORT_SYMBOL(lustre_swab_layout_intent);
void lustre_swab_hsm_progress_kernel(struct hsm_progress_kernel *hpk)
{
@@ -2241,7 +2211,6 @@ void lustre_swab_hsm_progress_kernel(struct hsm_progress_kernel *hpk)
__swab16s(&hpk->hpk_flags);
__swab16s(&hpk->hpk_errval);
}
-EXPORT_SYMBOL(lustre_swab_hsm_progress_kernel);
void lustre_swab_hsm_request(struct hsm_request *hr)
{
@@ -2251,7 +2220,6 @@ void lustre_swab_hsm_request(struct hsm_request *hr)
__swab32s(&hr->hr_itemcount);
__swab32s(&hr->hr_data_len);
}
-EXPORT_SYMBOL(lustre_swab_hsm_request);
void lustre_swab_swap_layouts(struct mdc_swap_layouts *msl)
{
@@ -2264,4 +2232,3 @@ void lustre_swab_close_data(struct close_data *cd)
lustre_swab_lu_fid(&cd->cd_fid);
__swab64s(&cd->cd_data_version);
}
-EXPORT_SYMBOL(lustre_swab_close_data);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pers.c b/drivers/staging/lustre/lustre/ptlrpc/pers.c
index 6c820e944171..5b9fb11c0b6b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pers.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pers.c
@@ -64,9 +64,9 @@ void ptlrpc_add_bulk_page(struct ptlrpc_bulk_desc *desc, struct page *page,
{
lnet_kiov_t *kiov = &desc->bd_iov[desc->bd_iov_count];
- kiov->kiov_page = page;
- kiov->kiov_offset = pageoffset;
- kiov->kiov_len = len;
+ kiov->bv_page = page;
+ kiov->bv_offset = pageoffset;
+ kiov->bv_len = len;
desc->bd_iov_count++;
}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
index c0529d808d81..5504fc2363ac 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
@@ -340,7 +340,6 @@ void ptlrpc_pinger_sending_on_import(struct obd_import *imp)
{
ptlrpc_update_next_ping(imp, 0);
}
-EXPORT_SYMBOL(ptlrpc_pinger_sending_on_import);
void ptlrpc_pinger_commit_expected(struct obd_import *imp)
{
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
index a9831fab80f3..f14d193287da 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
@@ -53,6 +53,8 @@ int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait);
int ptlrpcd_start(struct ptlrpcd_ctl *pc);
/* client.c */
+void ptlrpc_at_adj_net_latency(struct ptlrpc_request *req,
+ unsigned int service_time);
struct ptlrpc_bulk_desc *ptlrpc_new_bulk(unsigned npages, unsigned max_brw,
unsigned type, unsigned portal);
int ptlrpc_request_cache_init(void);
@@ -60,6 +62,11 @@ void ptlrpc_request_cache_fini(void);
struct ptlrpc_request *ptlrpc_request_cache_alloc(gfp_t flags);
void ptlrpc_request_cache_free(struct ptlrpc_request *req);
void ptlrpc_init_xid(void);
+void ptlrpc_set_add_new_req(struct ptlrpcd_ctl *pc,
+ struct ptlrpc_request *req);
+int ptlrpc_expired_set(void *data);
+int ptlrpc_set_next_timeout(struct ptlrpc_request_set *);
+void ptlrpc_resend_req(struct ptlrpc_request *request);
/* events.c */
int ptlrpc_init_portals(void);
@@ -268,7 +275,7 @@ void sptlrpc_conf_fini(void);
int sptlrpc_init(void);
void sptlrpc_fini(void);
-static inline int ll_rpc_recoverable_error(int rc)
+static inline bool ptlrpc_recoverable_error(int rc)
{
return (rc == -ENOTCONN || rc == -ENODEV);
}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index 0a374b6c2f71..1f55d642aa75 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -412,7 +412,7 @@ static int ptlrpcd(void *arg)
* an argument, describing its "scope".
*/
rc = lu_context_init(&env.le_ctx,
- LCT_CL_THREAD|LCT_REMEMBER|LCT_NOREF);
+ LCT_CL_THREAD | LCT_REMEMBER | LCT_NOREF);
if (rc == 0) {
rc = lu_context_init(env.le_ses,
LCT_SESSION | LCT_REMEMBER | LCT_NOREF);
@@ -567,7 +567,7 @@ int ptlrpcd_start(struct ptlrpcd_ctl *pc)
* ptlrpcd thread (or a thread-set) has to be given an argument,
* describing its "scope".
*/
- rc = lu_context_init(&pc->pc_env.le_ctx, LCT_CL_THREAD|LCT_REMEMBER);
+ rc = lu_context_init(&pc->pc_env.le_ctx, LCT_CL_THREAD | LCT_REMEMBER);
if (rc != 0)
goto out;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/recover.c b/drivers/staging/lustre/lustre/ptlrpc/recover.c
index 718b3a8d61c6..405faf0dc9fc 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/recover.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/recover.c
@@ -201,7 +201,6 @@ int ptlrpc_resend(struct obd_import *imp)
return 0;
}
-EXPORT_SYMBOL(ptlrpc_resend);
/**
* Go through all requests in delayed list and wake their threads
@@ -221,7 +220,6 @@ void ptlrpc_wake_delayed(struct obd_import *imp)
}
spin_unlock(&imp->imp_lock);
}
-EXPORT_SYMBOL(ptlrpc_wake_delayed);
void ptlrpc_request_handle_notconn(struct ptlrpc_request *failed_req)
{
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c b/drivers/staging/lustre/lustre/ptlrpc/sec.c
index dbd819fa6b75..5d3995d5c69a 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c
@@ -311,6 +311,19 @@ static int import_sec_check_expire(struct obd_import *imp)
return sptlrpc_import_sec_adapt(imp, NULL, NULL);
}
+/**
+ * Get and validate the client side ptlrpc security facilities from
+ * \a imp. There is a race condition on client reconnect when the import is
+ * being destroyed while there are outstanding client bound requests. In
+ * this case do not output any error messages if import secuity is not
+ * found.
+ *
+ * \param[in] imp obd import associated with client
+ * \param[out] sec client side ptlrpc security
+ *
+ * \retval 0 if security retrieved successfully
+ * \retval -ve errno if there was a problem
+ */
static int import_sec_validate_get(struct obd_import *imp,
struct ptlrpc_sec **sec)
{
@@ -323,9 +336,11 @@ static int import_sec_validate_get(struct obd_import *imp,
}
*sec = sptlrpc_import_sec_ref(imp);
+ /* Only output an error when the import is still active */
if (!*sec) {
- CERROR("import %p (%s) with no sec\n",
- imp, ptlrpc_import_state_name(imp->imp_state));
+ if (list_empty(&imp->imp_zombie_chain))
+ CERROR("import %p (%s) with no sec\n",
+ imp, ptlrpc_import_state_name(imp->imp_state));
return -EACCES;
}
@@ -499,7 +514,7 @@ static int sptlrpc_req_replace_dead_ctx(struct ptlrpc_request *req)
newctx, newctx->cc_flags);
set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ);
+ schedule_timeout(msecs_to_jiffies(MSEC_PER_SEC));
} else {
/*
* it's possible newctx == oldctx if we're switching
@@ -718,8 +733,9 @@ again:
req->rq_restart = 0;
spin_unlock(&req->rq_lock);
- lwi = LWI_TIMEOUT_INTR(timeout * HZ, ctx_refresh_timeout,
- ctx_refresh_interrupt, req);
+ lwi = LWI_TIMEOUT_INTR(msecs_to_jiffies(timeout * MSEC_PER_SEC),
+ ctx_refresh_timeout, ctx_refresh_interrupt,
+ req);
rc = l_wait_event(req->rq_reply_waitq, ctx_check_refresh(ctx), &lwi);
/*
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
index 5f4d79718589..b2cc5ea6cb93 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
@@ -139,7 +139,7 @@ int sptlrpc_proc_enc_pool_seq_show(struct seq_file *m, void *v)
"cache missing: %lu\n"
"low free mark: %lu\n"
"max waitqueue depth: %u\n"
- "max wait time: %ld/%u\n",
+ "max wait time: %ld/%lu\n",
totalram_pages,
PAGES_PER_POOL,
page_pools.epp_max_pages,
@@ -158,7 +158,7 @@ int sptlrpc_proc_enc_pool_seq_show(struct seq_file *m, void *v)
page_pools.epp_st_lowfree,
page_pools.epp_st_max_wqlen,
page_pools.epp_st_max_wait,
- HZ);
+ msecs_to_jiffies(MSEC_PER_SEC));
spin_unlock(&page_pools.epp_lock);
@@ -326,12 +326,12 @@ void sptlrpc_enc_pool_put_pages(struct ptlrpc_bulk_desc *desc)
LASSERT(page_pools.epp_pools[p_idx]);
for (i = 0; i < desc->bd_iov_count; i++) {
- LASSERT(desc->bd_enc_iov[i].kiov_page);
+ LASSERT(desc->bd_enc_iov[i].bv_page);
LASSERT(g_idx != 0 || page_pools.epp_pools[p_idx]);
LASSERT(!page_pools.epp_pools[p_idx][g_idx]);
page_pools.epp_pools[p_idx][g_idx] =
- desc->bd_enc_iov[i].kiov_page;
+ desc->bd_enc_iov[i].bv_page;
if (++g_idx == PAGES_PER_POOL) {
p_idx++;
@@ -348,7 +348,6 @@ void sptlrpc_enc_pool_put_pages(struct ptlrpc_bulk_desc *desc)
kfree(desc->bd_enc_iov);
desc->bd_enc_iov = NULL;
}
-EXPORT_SYMBOL(sptlrpc_enc_pool_put_pages);
static inline void enc_pools_alloc(void)
{
@@ -432,12 +431,13 @@ void sptlrpc_enc_pool_fini(void)
if (page_pools.epp_st_access > 0) {
CDEBUG(D_SEC,
- "max pages %lu, grows %u, grow fails %u, shrinks %u, access %lu, missing %lu, max qlen %u, max wait %ld/%d\n",
+ "max pages %lu, grows %u, grow fails %u, shrinks %u, access %lu, missing %lu, max qlen %u, max wait %ld/%ld\n",
page_pools.epp_st_max_pages, page_pools.epp_st_grows,
page_pools.epp_st_grow_fails,
page_pools.epp_st_shrinks, page_pools.epp_st_access,
page_pools.epp_st_missings, page_pools.epp_st_max_wqlen,
- page_pools.epp_st_max_wait, HZ);
+ page_pools.epp_st_max_wait,
+ msecs_to_jiffies(MSEC_PER_SEC));
}
}
@@ -456,13 +456,11 @@ const char *sptlrpc_get_hash_name(__u8 hash_alg)
{
return cfs_crypto_hash_name(cfs_hash_alg_id[hash_alg]);
}
-EXPORT_SYMBOL(sptlrpc_get_hash_name);
__u8 sptlrpc_get_hash_alg(const char *algname)
{
return cfs_crypto_hash_alg(algname);
}
-EXPORT_SYMBOL(sptlrpc_get_hash_alg);
int bulk_sec_desc_unpack(struct lustre_msg *msg, int offset, int swabbed)
{
@@ -522,9 +520,10 @@ int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg,
hashsize = cfs_crypto_hash_digestsize(cfs_hash_alg_id[alg]);
for (i = 0; i < desc->bd_iov_count; i++) {
- cfs_crypto_hash_update_page(hdesc, desc->bd_iov[i].kiov_page,
- desc->bd_iov[i].kiov_offset & ~PAGE_MASK,
- desc->bd_iov[i].kiov_len);
+ cfs_crypto_hash_update_page(hdesc, desc->bd_iov[i].bv_page,
+ desc->bd_iov[i].bv_offset &
+ ~PAGE_MASK,
+ desc->bd_iov[i].bv_len);
}
if (hashsize > buflen) {
@@ -542,4 +541,3 @@ int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg,
return err;
}
-EXPORT_SYMBOL(sptlrpc_get_bulk_checksum);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c
index c14035479c5f..2181a85efd49 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c
@@ -58,7 +58,6 @@ enum lustre_sec_part sptlrpc_target_sec_part(struct obd_device *obd)
CERROR("unknown target %p(%s)\n", obd, type);
return LUSTRE_SP_ANY;
}
-EXPORT_SYMBOL(sptlrpc_target_sec_part);
/****************************************
* user supplied flavor string parsing *
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index 9b9801ece582..8ffd000eafac 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -71,7 +71,6 @@ void sptlrpc_gc_add_sec(struct ptlrpc_sec *sec)
CDEBUG(D_SEC, "added sec %p(%s)\n", sec, sec->ps_policy->sp_name);
}
-EXPORT_SYMBOL(sptlrpc_gc_add_sec);
void sptlrpc_gc_del_sec(struct ptlrpc_sec *sec)
{
@@ -95,7 +94,6 @@ void sptlrpc_gc_del_sec(struct ptlrpc_sec *sec)
CDEBUG(D_SEC, "del sec %p(%s)\n", sec, sec->ps_policy->sp_name);
}
-EXPORT_SYMBOL(sptlrpc_gc_del_sec);
static void sec_process_ctx_list(void)
{
@@ -182,7 +180,8 @@ again:
/* check ctx list again before sleep */
sec_process_ctx_list();
- lwi = LWI_TIMEOUT(SEC_GC_INTERVAL * HZ, NULL, NULL);
+ lwi = LWI_TIMEOUT(msecs_to_jiffies(SEC_GC_INTERVAL * MSEC_PER_SEC),
+ NULL, NULL);
l_wait_event(thread->t_ctl_waitq,
thread_is_stopping(thread) ||
thread_is_signal(thread),
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c
index 5c4590b0c521..cd305bcb334a 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c
@@ -154,13 +154,13 @@ static void corrupt_bulk_data(struct ptlrpc_bulk_desc *desc)
unsigned int off, i;
for (i = 0; i < desc->bd_iov_count; i++) {
- if (desc->bd_iov[i].kiov_len == 0)
+ if (desc->bd_iov[i].bv_len == 0)
continue;
- ptr = kmap(desc->bd_iov[i].kiov_page);
- off = desc->bd_iov[i].kiov_offset & ~PAGE_MASK;
+ ptr = kmap(desc->bd_iov[i].bv_page);
+ off = desc->bd_iov[i].bv_offset & ~PAGE_MASK;
ptr[off] ^= 0x1;
- kunmap(desc->bd_iov[i].kiov_page);
+ kunmap(desc->bd_iov[i].bv_page);
return;
}
}
@@ -249,9 +249,12 @@ int plain_ctx_verify(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req)
unsigned int hsize = 4;
cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32,
- lustre_msg_buf(msg, PLAIN_PACK_MSG_OFF, 0),
- lustre_msg_buflen(msg, PLAIN_PACK_MSG_OFF),
- NULL, 0, (unsigned char *)&cksum, &hsize);
+ lustre_msg_buf(msg, PLAIN_PACK_MSG_OFF,
+ 0),
+ lustre_msg_buflen(msg,
+ PLAIN_PACK_MSG_OFF),
+ NULL, 0, (unsigned char *)&cksum,
+ &hsize);
if (cksum != msg->lm_cksum) {
CDEBUG(D_SEC,
"early reply checksum mismatch: %08x != %08x\n",
@@ -349,11 +352,11 @@ int plain_cli_unwrap_bulk(struct ptlrpc_cli_ctx *ctx,
/* fix the actual data size */
for (i = 0, nob = 0; i < desc->bd_iov_count; i++) {
- if (desc->bd_iov[i].kiov_len + nob > desc->bd_nob_transferred) {
- desc->bd_iov[i].kiov_len =
+ if (desc->bd_iov[i].bv_len + nob > desc->bd_nob_transferred) {
+ desc->bd_iov[i].bv_len =
desc->bd_nob_transferred - nob;
}
- nob += desc->bd_iov[i].kiov_len;
+ nob += desc->bd_iov[i].bv_len;
}
rc = plain_verify_bulk_csum(desc, req->rq_flvr.u_bulk.hash.hash_alg,
@@ -869,9 +872,12 @@ int plain_authorize(struct ptlrpc_request *req)
unsigned int hsize = 4;
cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32,
- lustre_msg_buf(msg, PLAIN_PACK_MSG_OFF, 0),
- lustre_msg_buflen(msg, PLAIN_PACK_MSG_OFF),
- NULL, 0, (unsigned char *)&msg->lm_cksum, &hsize);
+ lustre_msg_buf(msg, PLAIN_PACK_MSG_OFF,
+ 0),
+ lustre_msg_buflen(msg,
+ PLAIN_PACK_MSG_OFF),
+ NULL, 0, (unsigned char *)&msg->lm_cksum,
+ &hsize);
req->rq_reply_off = 0;
}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 4788c4940c2a..72f39308eebb 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -1005,6 +1005,10 @@ ptlrpc_at_remove_timed(struct ptlrpc_request *req)
array->paa_count--;
}
+/*
+ * Attempt to extend the request deadline by sending an early reply to the
+ * client.
+ */
static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
{
struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt;
@@ -1039,24 +1043,26 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
return -ENOSYS;
}
- /* Fake our processing time into the future to ask the clients
- * for some extra amount of time
+ /*
+ * We want to extend the request deadline by at_extra seconds,
+ * so we set our service estimate to reflect how much time has
+ * passed since this request arrived plus an additional
+ * at_extra seconds. The client will calculate the new deadline
+ * based on this service estimate (plus some additional time to
+ * account for network latency). See ptlrpc_at_recv_early_reply
*/
at_measured(&svcpt->scp_at_estimate, at_extra +
ktime_get_real_seconds() - req->rq_arrival_time.tv_sec);
+ newdl = req->rq_arrival_time.tv_sec + at_get(&svcpt->scp_at_estimate);
/* Check to see if we've actually increased the deadline -
* we may be past adaptive_max
*/
- if (req->rq_deadline >= req->rq_arrival_time.tv_sec +
- at_get(&svcpt->scp_at_estimate)) {
+ if (req->rq_deadline >= newdl) {
DEBUG_REQ(D_WARNING, req, "Couldn't add any time (%ld/%lld), not sending early reply\n",
- olddl, req->rq_arrival_time.tv_sec +
- at_get(&svcpt->scp_at_estimate) -
- ktime_get_real_seconds());
+ olddl, newdl - ktime_get_real_seconds());
return -ETIMEDOUT;
}
- newdl = ktime_get_real_seconds() + at_get(&svcpt->scp_at_estimate);
reqcopy = ptlrpc_request_cache_alloc(GFP_NOFS);
if (!reqcopy)
@@ -1982,11 +1988,12 @@ ptlrpc_wait_event(struct ptlrpc_service_part *svcpt,
cond_resched();
l_wait_event_exclusive_head(svcpt->scp_waitq,
- ptlrpc_thread_stopping(thread) ||
- ptlrpc_server_request_incoming(svcpt) ||
- ptlrpc_server_request_pending(svcpt, false) ||
- ptlrpc_rqbd_pending(svcpt) ||
- ptlrpc_at_check(svcpt), &lwi);
+ ptlrpc_thread_stopping(thread) ||
+ ptlrpc_server_request_incoming(svcpt) ||
+ ptlrpc_server_request_pending(svcpt,
+ false) ||
+ ptlrpc_rqbd_pending(svcpt) ||
+ ptlrpc_at_check(svcpt), &lwi);
if (ptlrpc_thread_stopping(thread))
return -EINTR;
@@ -2049,7 +2056,7 @@ static int ptlrpc_main(void *arg)
}
rc = lu_context_init(&env->le_ctx,
- svc->srv_ctx_tags|LCT_REMEMBER|LCT_NOREF);
+ svc->srv_ctx_tags | LCT_REMEMBER | LCT_NOREF);
if (rc)
goto out_srv_fini;
@@ -2349,7 +2356,7 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt)
while (!list_empty(&zombie)) {
thread = list_entry(zombie.next,
- struct ptlrpc_thread, t_link);
+ struct ptlrpc_thread, t_link);
list_del(&thread->t_link);
kfree(thread);
}
@@ -2398,7 +2405,6 @@ int ptlrpc_start_threads(struct ptlrpc_service *svc)
ptlrpc_stop_all_threads(svc);
return rc;
}
-EXPORT_SYMBOL(ptlrpc_start_threads);
int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait)
{
@@ -2539,8 +2545,8 @@ int ptlrpc_hr_init(void)
LASSERT(hrp->hrp_nthrs > 0);
hrp->hrp_thrs =
kzalloc_node(hrp->hrp_nthrs * sizeof(*hrt), GFP_NOFS,
- cfs_cpt_spread_node(ptlrpc_hr.hr_cpt_table,
- i));
+ cfs_cpt_spread_node(ptlrpc_hr.hr_cpt_table,
+ i));
if (!hrp->hrp_thrs) {
rc = -ENOMEM;
goto out;
@@ -2593,7 +2599,8 @@ static void ptlrpc_wait_replies(struct ptlrpc_service_part *svcpt)
NULL, NULL);
rc = l_wait_event(svcpt->scp_waitq,
- atomic_read(&svcpt->scp_nreps_difficult) == 0, &lwi);
+ atomic_read(&svcpt->scp_nreps_difficult) == 0,
+ &lwi);
if (rc == 0)
break;
CWARN("Unexpectedly long timeout %s %p\n",
@@ -2639,7 +2646,7 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc)
* event with its 'unlink' flag set for each posted rqbd
*/
list_for_each_entry(rqbd, &svcpt->scp_rqbd_posted,
- rqbd_list) {
+ rqbd_list) {
rc = LNetMDUnlink(rqbd->rqbd_md_h);
LASSERT(rc == 0 || rc == -ENOENT);
}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c
index 6cc2b2edf3fc..e5945e2ccc49 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c
@@ -190,28 +190,30 @@ void lustre_assert_wire_constants(void)
(long long)REINT_SETXATTR);
LASSERTF(REINT_RMENTRY == 8, "found %lld\n",
(long long)REINT_RMENTRY);
- LASSERTF(REINT_MAX == 9, "found %lld\n",
+ LASSERTF(REINT_MIGRATE == 9, "found %lld\n",
+ (long long)REINT_MIGRATE);
+ LASSERTF(REINT_MAX == 10, "found %lld\n",
(long long)REINT_MAX);
LASSERTF(DISP_IT_EXECD == 0x00000001UL, "found 0x%.8xUL\n",
- (unsigned)DISP_IT_EXECD);
+ (unsigned)DISP_IT_EXECD);
LASSERTF(DISP_LOOKUP_EXECD == 0x00000002UL, "found 0x%.8xUL\n",
- (unsigned)DISP_LOOKUP_EXECD);
+ (unsigned)DISP_LOOKUP_EXECD);
LASSERTF(DISP_LOOKUP_NEG == 0x00000004UL, "found 0x%.8xUL\n",
- (unsigned)DISP_LOOKUP_NEG);
+ (unsigned)DISP_LOOKUP_NEG);
LASSERTF(DISP_LOOKUP_POS == 0x00000008UL, "found 0x%.8xUL\n",
- (unsigned)DISP_LOOKUP_POS);
+ (unsigned)DISP_LOOKUP_POS);
LASSERTF(DISP_OPEN_CREATE == 0x00000010UL, "found 0x%.8xUL\n",
- (unsigned)DISP_OPEN_CREATE);
+ (unsigned)DISP_OPEN_CREATE);
LASSERTF(DISP_OPEN_OPEN == 0x00000020UL, "found 0x%.8xUL\n",
- (unsigned)DISP_OPEN_OPEN);
+ (unsigned)DISP_OPEN_OPEN);
LASSERTF(DISP_ENQ_COMPLETE == 0x00400000UL, "found 0x%.8xUL\n",
- (unsigned)DISP_ENQ_COMPLETE);
+ (unsigned)DISP_ENQ_COMPLETE);
LASSERTF(DISP_ENQ_OPEN_REF == 0x00800000UL, "found 0x%.8xUL\n",
- (unsigned)DISP_ENQ_OPEN_REF);
+ (unsigned)DISP_ENQ_OPEN_REF);
LASSERTF(DISP_ENQ_CREATE_REF == 0x01000000UL, "found 0x%.8xUL\n",
- (unsigned)DISP_ENQ_CREATE_REF);
+ (unsigned)DISP_ENQ_CREATE_REF);
LASSERTF(DISP_OPEN_LOCK == 0x02000000UL, "found 0x%.8xUL\n",
- (unsigned)DISP_OPEN_LOCK);
+ (unsigned)DISP_OPEN_LOCK);
LASSERTF(MDS_STATUS_CONN == 1, "found %lld\n",
(long long)MDS_STATUS_CONN);
LASSERTF(MDS_STATUS_LOV == 2, "found %lld\n",
@@ -219,55 +221,55 @@ void lustre_assert_wire_constants(void)
LASSERTF(LUSTRE_BFLAG_UNCOMMITTED_WRITES == 1, "found %lld\n",
(long long)LUSTRE_BFLAG_UNCOMMITTED_WRITES);
LASSERTF(MF_SOM_CHANGE == 0x00000001UL, "found 0x%.8xUL\n",
- (unsigned)MF_SOM_CHANGE);
+ (unsigned)MF_SOM_CHANGE);
LASSERTF(MF_EPOCH_OPEN == 0x00000002UL, "found 0x%.8xUL\n",
- (unsigned)MF_EPOCH_OPEN);
+ (unsigned)MF_EPOCH_OPEN);
LASSERTF(MF_EPOCH_CLOSE == 0x00000004UL, "found 0x%.8xUL\n",
- (unsigned)MF_EPOCH_CLOSE);
+ (unsigned)MF_EPOCH_CLOSE);
LASSERTF(MF_MDC_CANCEL_FID1 == 0x00000008UL, "found 0x%.8xUL\n",
- (unsigned)MF_MDC_CANCEL_FID1);
+ (unsigned)MF_MDC_CANCEL_FID1);
LASSERTF(MF_MDC_CANCEL_FID2 == 0x00000010UL, "found 0x%.8xUL\n",
- (unsigned)MF_MDC_CANCEL_FID2);
+ (unsigned)MF_MDC_CANCEL_FID2);
LASSERTF(MF_MDC_CANCEL_FID3 == 0x00000020UL, "found 0x%.8xUL\n",
- (unsigned)MF_MDC_CANCEL_FID3);
+ (unsigned)MF_MDC_CANCEL_FID3);
LASSERTF(MF_MDC_CANCEL_FID4 == 0x00000040UL, "found 0x%.8xUL\n",
- (unsigned)MF_MDC_CANCEL_FID4);
+ (unsigned)MF_MDC_CANCEL_FID4);
LASSERTF(MF_SOM_AU == 0x00000080UL, "found 0x%.8xUL\n",
- (unsigned)MF_SOM_AU);
+ (unsigned)MF_SOM_AU);
LASSERTF(MF_GETATTR_LOCK == 0x00000100UL, "found 0x%.8xUL\n",
- (unsigned)MF_GETATTR_LOCK);
+ (unsigned)MF_GETATTR_LOCK);
LASSERTF(MDS_ATTR_MODE == 0x0000000000000001ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_MODE);
+ (long long)MDS_ATTR_MODE);
LASSERTF(MDS_ATTR_UID == 0x0000000000000002ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_UID);
+ (long long)MDS_ATTR_UID);
LASSERTF(MDS_ATTR_GID == 0x0000000000000004ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_GID);
+ (long long)MDS_ATTR_GID);
LASSERTF(MDS_ATTR_SIZE == 0x0000000000000008ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_SIZE);
+ (long long)MDS_ATTR_SIZE);
LASSERTF(MDS_ATTR_ATIME == 0x0000000000000010ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_ATIME);
+ (long long)MDS_ATTR_ATIME);
LASSERTF(MDS_ATTR_MTIME == 0x0000000000000020ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_MTIME);
+ (long long)MDS_ATTR_MTIME);
LASSERTF(MDS_ATTR_CTIME == 0x0000000000000040ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_CTIME);
+ (long long)MDS_ATTR_CTIME);
LASSERTF(MDS_ATTR_ATIME_SET == 0x0000000000000080ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_ATIME_SET);
+ (long long)MDS_ATTR_ATIME_SET);
LASSERTF(MDS_ATTR_MTIME_SET == 0x0000000000000100ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_MTIME_SET);
+ (long long)MDS_ATTR_MTIME_SET);
LASSERTF(MDS_ATTR_FORCE == 0x0000000000000200ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_FORCE);
+ (long long)MDS_ATTR_FORCE);
LASSERTF(MDS_ATTR_ATTR_FLAG == 0x0000000000000400ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_ATTR_FLAG);
+ (long long)MDS_ATTR_ATTR_FLAG);
LASSERTF(MDS_ATTR_KILL_SUID == 0x0000000000000800ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_KILL_SUID);
+ (long long)MDS_ATTR_KILL_SUID);
LASSERTF(MDS_ATTR_KILL_SGID == 0x0000000000001000ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_KILL_SGID);
+ (long long)MDS_ATTR_KILL_SGID);
LASSERTF(MDS_ATTR_CTIME_SET == 0x0000000000002000ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_CTIME_SET);
+ (long long)MDS_ATTR_CTIME_SET);
LASSERTF(MDS_ATTR_FROM_OPEN == 0x0000000000004000ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_FROM_OPEN);
+ (long long)MDS_ATTR_FROM_OPEN);
LASSERTF(MDS_ATTR_BLOCKS == 0x0000000000008000ULL, "found 0x%.16llxULL\n",
- (long long)MDS_ATTR_BLOCKS);
+ (long long)MDS_ATTR_BLOCKS);
LASSERTF(FLD_QUERY == 900, "found %lld\n",
(long long)FLD_QUERY);
LASSERTF(FLD_FIRST_OPC == 900, "found %lld\n",
@@ -418,15 +420,15 @@ void lustre_assert_wire_constants(void)
LASSERTF((int)sizeof(((struct lustre_mdt_attrs *)0)->lma_self_fid) == 16, "found %lld\n",
(long long)(int)sizeof(((struct lustre_mdt_attrs *)0)->lma_self_fid));
LASSERTF(LMAI_RELEASED == 0x00000001UL, "found 0x%.8xUL\n",
- (unsigned)LMAI_RELEASED);
+ (unsigned)LMAI_RELEASED);
LASSERTF(LMAC_HSM == 0x00000001UL, "found 0x%.8xUL\n",
- (unsigned)LMAC_HSM);
+ (unsigned)LMAC_HSM);
LASSERTF(LMAC_SOM == 0x00000002UL, "found 0x%.8xUL\n",
- (unsigned)LMAC_SOM);
+ (unsigned)LMAC_SOM);
LASSERTF(LMAC_NOT_IN_OI == 0x00000004UL, "found 0x%.8xUL\n",
- (unsigned)LMAC_NOT_IN_OI);
+ (unsigned)LMAC_NOT_IN_OI);
LASSERTF(LMAC_FID_ON_OST == 0x00000008UL, "found 0x%.8xUL\n",
- (unsigned)LMAC_FID_ON_OST);
+ (unsigned)LMAC_FID_ON_OST);
/* Checks for struct ost_id */
LASSERTF((int)sizeof(struct ost_id) == 16, "found %lld\n",
@@ -452,35 +454,35 @@ void lustre_assert_wire_constants(void)
LASSERTF(FID_SEQ_IGIF == 12, "found %lld\n",
(long long)FID_SEQ_IGIF);
LASSERTF(FID_SEQ_IGIF_MAX == 0x00000000ffffffffULL, "found 0x%.16llxULL\n",
- (long long)FID_SEQ_IGIF_MAX);
+ (long long)FID_SEQ_IGIF_MAX);
LASSERTF(FID_SEQ_IDIF == 0x0000000100000000ULL, "found 0x%.16llxULL\n",
- (long long)FID_SEQ_IDIF);
+ (long long)FID_SEQ_IDIF);
LASSERTF(FID_SEQ_IDIF_MAX == 0x00000001ffffffffULL, "found 0x%.16llxULL\n",
- (long long)FID_SEQ_IDIF_MAX);
+ (long long)FID_SEQ_IDIF_MAX);
LASSERTF(FID_SEQ_START == 0x0000000200000000ULL, "found 0x%.16llxULL\n",
- (long long)FID_SEQ_START);
+ (long long)FID_SEQ_START);
LASSERTF(FID_SEQ_LOCAL_FILE == 0x0000000200000001ULL, "found 0x%.16llxULL\n",
- (long long)FID_SEQ_LOCAL_FILE);
+ (long long)FID_SEQ_LOCAL_FILE);
LASSERTF(FID_SEQ_DOT_LUSTRE == 0x0000000200000002ULL, "found 0x%.16llxULL\n",
- (long long)FID_SEQ_DOT_LUSTRE);
+ (long long)FID_SEQ_DOT_LUSTRE);
LASSERTF(FID_SEQ_SPECIAL == 0x0000000200000004ULL, "found 0x%.16llxULL\n",
- (long long)FID_SEQ_SPECIAL);
+ (long long)FID_SEQ_SPECIAL);
LASSERTF(FID_SEQ_QUOTA == 0x0000000200000005ULL, "found 0x%.16llxULL\n",
- (long long)FID_SEQ_QUOTA);
+ (long long)FID_SEQ_QUOTA);
LASSERTF(FID_SEQ_QUOTA_GLB == 0x0000000200000006ULL, "found 0x%.16llxULL\n",
- (long long)FID_SEQ_QUOTA_GLB);
+ (long long)FID_SEQ_QUOTA_GLB);
LASSERTF(FID_SEQ_ROOT == 0x0000000200000007ULL, "found 0x%.16llxULL\n",
- (long long)FID_SEQ_ROOT);
+ (long long)FID_SEQ_ROOT);
LASSERTF(FID_SEQ_NORMAL == 0x0000000200000400ULL, "found 0x%.16llxULL\n",
- (long long)FID_SEQ_NORMAL);
+ (long long)FID_SEQ_NORMAL);
LASSERTF(FID_SEQ_LOV_DEFAULT == 0xffffffffffffffffULL, "found 0x%.16llxULL\n",
- (long long)FID_SEQ_LOV_DEFAULT);
+ (long long)FID_SEQ_LOV_DEFAULT);
LASSERTF(FID_OID_SPECIAL_BFL == 0x00000001UL, "found 0x%.8xUL\n",
- (unsigned)FID_OID_SPECIAL_BFL);
+ (unsigned)FID_OID_SPECIAL_BFL);
LASSERTF(FID_OID_DOT_LUSTRE == 0x00000001UL, "found 0x%.8xUL\n",
- (unsigned)FID_OID_DOT_LUSTRE);
+ (unsigned)FID_OID_DOT_LUSTRE);
LASSERTF(FID_OID_DOT_LUSTRE_OBF == 0x00000002UL, "found 0x%.8xUL\n",
- (unsigned)FID_OID_DOT_LUSTRE_OBF);
+ (unsigned)FID_OID_DOT_LUSTRE_OBF);
/* Checks for struct lu_dirent */
LASSERTF((int)sizeof(struct lu_dirent) == 32, "found %lld\n",
@@ -510,11 +512,11 @@ void lustre_assert_wire_constants(void)
LASSERTF((int)sizeof(((struct lu_dirent *)0)->lde_name[0]) == 1, "found %lld\n",
(long long)(int)sizeof(((struct lu_dirent *)0)->lde_name[0]));
LASSERTF(LUDA_FID == 0x00000001UL, "found 0x%.8xUL\n",
- (unsigned)LUDA_FID);
+ (unsigned)LUDA_FID);
LASSERTF(LUDA_TYPE == 0x00000002UL, "found 0x%.8xUL\n",
- (unsigned)LUDA_TYPE);
+ (unsigned)LUDA_TYPE);
LASSERTF(LUDA_64BITHASH == 0x00000004UL, "found 0x%.8xUL\n",
- (unsigned)LUDA_64BITHASH);
+ (unsigned)LUDA_64BITHASH);
/* Checks for struct luda_type */
LASSERTF((int)sizeof(struct luda_type) == 2, "found %lld\n",
@@ -602,9 +604,9 @@ void lustre_assert_wire_constants(void)
LASSERTF((int)sizeof(((struct lustre_msg_v2 *)0)->lm_buflens[0]) == 4, "found %lld\n",
(long long)(int)sizeof(((struct lustre_msg_v2 *)0)->lm_buflens[0]));
LASSERTF(LUSTRE_MSG_MAGIC_V2 == 0x0BD00BD3, "found 0x%.8x\n",
- LUSTRE_MSG_MAGIC_V2);
+ LUSTRE_MSG_MAGIC_V2);
LASSERTF(LUSTRE_MSG_MAGIC_V2_SWABBED == 0xD30BD00B, "found 0x%.8x\n",
- LUSTRE_MSG_MAGIC_V2_SWABBED);
+ LUSTRE_MSG_MAGIC_V2_SWABBED);
/* Checks for struct ptlrpc_body */
LASSERTF((int)sizeof(struct ptlrpc_body_v3) == 184, "found %lld\n",
@@ -682,7 +684,7 @@ void lustre_assert_wire_constants(void)
(long long)(int)offsetof(struct ptlrpc_body_v3, pb_padding));
LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding) == 32, "found %lld\n",
(long long)(int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding));
- CLASSERT(JOBSTATS_JOBID_SIZE == 32);
+ CLASSERT(LUSTRE_JOBID_SIZE == 32);
LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_jobid) == 152, "found %lld\n",
(long long)(int)offsetof(struct ptlrpc_body_v3, pb_jobid));
LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_jobid) == 32, "found %lld\n",
@@ -780,61 +782,61 @@ void lustre_assert_wire_constants(void)
LASSERTF(MSG_PTLRPC_HEADER_OFF == 31, "found %lld\n",
(long long)MSG_PTLRPC_HEADER_OFF);
LASSERTF(PTLRPC_MSG_VERSION == 0x00000003, "found 0x%.8x\n",
- PTLRPC_MSG_VERSION);
+ PTLRPC_MSG_VERSION);
LASSERTF(LUSTRE_VERSION_MASK == 0xffff0000, "found 0x%.8x\n",
- LUSTRE_VERSION_MASK);
+ LUSTRE_VERSION_MASK);
LASSERTF(LUSTRE_OBD_VERSION == 0x00010000, "found 0x%.8x\n",
- LUSTRE_OBD_VERSION);
+ LUSTRE_OBD_VERSION);
LASSERTF(LUSTRE_MDS_VERSION == 0x00020000, "found 0x%.8x\n",
- LUSTRE_MDS_VERSION);
+ LUSTRE_MDS_VERSION);
LASSERTF(LUSTRE_OST_VERSION == 0x00030000, "found 0x%.8x\n",
- LUSTRE_OST_VERSION);
+ LUSTRE_OST_VERSION);
LASSERTF(LUSTRE_DLM_VERSION == 0x00040000, "found 0x%.8x\n",
- LUSTRE_DLM_VERSION);
+ LUSTRE_DLM_VERSION);
LASSERTF(LUSTRE_LOG_VERSION == 0x00050000, "found 0x%.8x\n",
- LUSTRE_LOG_VERSION);
+ LUSTRE_LOG_VERSION);
LASSERTF(LUSTRE_MGS_VERSION == 0x00060000, "found 0x%.8x\n",
- LUSTRE_MGS_VERSION);
+ LUSTRE_MGS_VERSION);
LASSERTF(MSGHDR_AT_SUPPORT == 1, "found %lld\n",
(long long)MSGHDR_AT_SUPPORT);
LASSERTF(MSGHDR_CKSUM_INCOMPAT18 == 2, "found %lld\n",
(long long)MSGHDR_CKSUM_INCOMPAT18);
LASSERTF(MSG_OP_FLAG_MASK == 0xffff0000UL, "found 0x%.8xUL\n",
- (unsigned)MSG_OP_FLAG_MASK);
+ (unsigned)MSG_OP_FLAG_MASK);
LASSERTF(MSG_OP_FLAG_SHIFT == 16, "found %lld\n",
(long long)MSG_OP_FLAG_SHIFT);
LASSERTF(MSG_GEN_FLAG_MASK == 0x0000ffffUL, "found 0x%.8xUL\n",
- (unsigned)MSG_GEN_FLAG_MASK);
+ (unsigned)MSG_GEN_FLAG_MASK);
LASSERTF(MSG_LAST_REPLAY == 0x00000001UL, "found 0x%.8xUL\n",
- (unsigned)MSG_LAST_REPLAY);
+ (unsigned)MSG_LAST_REPLAY);
LASSERTF(MSG_RESENT == 0x00000002UL, "found 0x%.8xUL\n",
- (unsigned)MSG_RESENT);
+ (unsigned)MSG_RESENT);
LASSERTF(MSG_REPLAY == 0x00000004UL, "found 0x%.8xUL\n",
- (unsigned)MSG_REPLAY);
+ (unsigned)MSG_REPLAY);
LASSERTF(MSG_DELAY_REPLAY == 0x00000010UL, "found 0x%.8xUL\n",
- (unsigned)MSG_DELAY_REPLAY);
+ (unsigned)MSG_DELAY_REPLAY);
LASSERTF(MSG_VERSION_REPLAY == 0x00000020UL, "found 0x%.8xUL\n",
- (unsigned)MSG_VERSION_REPLAY);
+ (unsigned)MSG_VERSION_REPLAY);
LASSERTF(MSG_REQ_REPLAY_DONE == 0x00000040UL, "found 0x%.8xUL\n",
- (unsigned)MSG_REQ_REPLAY_DONE);
+ (unsigned)MSG_REQ_REPLAY_DONE);
LASSERTF(MSG_LOCK_REPLAY_DONE == 0x00000080UL, "found 0x%.8xUL\n",
- (unsigned)MSG_LOCK_REPLAY_DONE);
+ (unsigned)MSG_LOCK_REPLAY_DONE);
LASSERTF(MSG_CONNECT_RECOVERING == 0x00000001UL, "found 0x%.8xUL\n",
- (unsigned)MSG_CONNECT_RECOVERING);
+ (unsigned)MSG_CONNECT_RECOVERING);
LASSERTF(MSG_CONNECT_RECONNECT == 0x00000002UL, "found 0x%.8xUL\n",
- (unsigned)MSG_CONNECT_RECONNECT);
+ (unsigned)MSG_CONNECT_RECONNECT);
LASSERTF(MSG_CONNECT_REPLAYABLE == 0x00000004UL, "found 0x%.8xUL\n",
- (unsigned)MSG_CONNECT_REPLAYABLE);
+ (unsigned)MSG_CONNECT_REPLAYABLE);
LASSERTF(MSG_CONNECT_LIBCLIENT == 0x00000010UL, "found 0x%.8xUL\n",
- (unsigned)MSG_CONNECT_LIBCLIENT);
+ (unsigned)MSG_CONNECT_LIBCLIENT);
LASSERTF(MSG_CONNECT_INITIAL == 0x00000020UL, "found 0x%.8xUL\n",
- (unsigned)MSG_CONNECT_INITIAL);
+ (unsigned)MSG_CONNECT_INITIAL);
LASSERTF(MSG_CONNECT_ASYNC == 0x00000040UL, "found 0x%.8xUL\n",
- (unsigned)MSG_CONNECT_ASYNC);
+ (unsigned)MSG_CONNECT_ASYNC);
LASSERTF(MSG_CONNECT_NEXT_VER == 0x00000080UL, "found 0x%.8xUL\n",
- (unsigned)MSG_CONNECT_NEXT_VER);
+ (unsigned)MSG_CONNECT_NEXT_VER);
LASSERTF(MSG_CONNECT_TRANSNO == 0x00000100UL, "found 0x%.8xUL\n",
- (unsigned)MSG_CONNECT_TRANSNO);
+ (unsigned)MSG_CONNECT_TRANSNO);
/* Checks for struct obd_connect_data */
LASSERTF((int)sizeof(struct obd_connect_data) == 192, "found %lld\n",
@@ -1069,12 +1071,18 @@ void lustre_assert_wire_constants(void)
"found 0x%.16llxULL\n", OBD_CONNECT_FLOCK_DEAD);
LASSERTF(OBD_CONNECT_OPEN_BY_FID == 0x20000000000000ULL,
"found 0x%.16llxULL\n", OBD_CONNECT_OPEN_BY_FID);
+ LASSERTF(OBD_CONNECT_LFSCK == 0x40000000000000ULL, "found 0x%.16llxULL\n",
+ OBD_CONNECT_LFSCK);
+ LASSERTF(OBD_CONNECT_UNLINK_CLOSE == 0x100000000000000ULL, "found 0x%.16llxULL\n",
+ OBD_CONNECT_UNLINK_CLOSE);
+ LASSERTF(OBD_CONNECT_DIR_STRIPE == 0x400000000000000ULL, "found 0x%.16llxULL\n",
+ OBD_CONNECT_DIR_STRIPE);
LASSERTF(OBD_CKSUM_CRC32 == 0x00000001UL, "found 0x%.8xUL\n",
- (unsigned)OBD_CKSUM_CRC32);
+ (unsigned)OBD_CKSUM_CRC32);
LASSERTF(OBD_CKSUM_ADLER == 0x00000002UL, "found 0x%.8xUL\n",
- (unsigned)OBD_CKSUM_ADLER);
+ (unsigned)OBD_CKSUM_ADLER);
LASSERTF(OBD_CKSUM_CRC32C == 0x00000004UL, "found 0x%.8xUL\n",
- (unsigned)OBD_CKSUM_CRC32C);
+ (unsigned)OBD_CKSUM_CRC32C);
/* Checks for struct obdo */
LASSERTF((int)sizeof(struct obdo) == 208, "found %lld\n",
@@ -1346,7 +1354,7 @@ void lustre_assert_wire_constants(void)
(long long)(int)offsetof(struct lov_mds_md_v1, lmm_objects[0]));
LASSERTF((int)sizeof(((struct lov_mds_md_v1 *)0)->lmm_objects[0]) == 24, "found %lld\n",
(long long)(int)sizeof(((struct lov_mds_md_v1 *)0)->lmm_objects[0]));
- CLASSERT(LOV_MAGIC_V1 == 0x0BD10BD0);
+ CLASSERT(LOV_MAGIC_V1 == (0x0BD10000 | 0x0BD0));
/* Checks for struct lov_mds_md_v3 */
LASSERTF((int)sizeof(struct lov_mds_md_v3) == 48, "found %lld\n",
@@ -1375,7 +1383,7 @@ void lustre_assert_wire_constants(void)
(long long)(int)offsetof(struct lov_mds_md_v3, lmm_layout_gen));
LASSERTF((int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_layout_gen) == 2, "found %lld\n",
(long long)(int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_layout_gen));
- CLASSERT(LOV_MAXPOOLNAME == 16);
+ CLASSERT(LOV_MAXPOOLNAME == 15);
LASSERTF((int)offsetof(struct lov_mds_md_v3, lmm_pool_name[16]) == 48, "found %lld\n",
(long long)(int)offsetof(struct lov_mds_md_v3, lmm_pool_name[16]));
LASSERTF((int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_pool_name[16]) == 1, "found %lld\n",
@@ -1384,15 +1392,64 @@ void lustre_assert_wire_constants(void)
(long long)(int)offsetof(struct lov_mds_md_v3, lmm_objects[0]));
LASSERTF((int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_objects[0]) == 24, "found %lld\n",
(long long)(int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_objects[0]));
- CLASSERT(LOV_MAGIC_V3 == 0x0BD30BD0);
+ CLASSERT(LOV_MAGIC_V3 == (0x0BD30000 | 0x0BD0));
LASSERTF(LOV_PATTERN_RAID0 == 0x00000001UL, "found 0x%.8xUL\n",
- (unsigned)LOV_PATTERN_RAID0);
+ (unsigned)LOV_PATTERN_RAID0);
LASSERTF(LOV_PATTERN_RAID1 == 0x00000002UL, "found 0x%.8xUL\n",
- (unsigned)LOV_PATTERN_RAID1);
+ (unsigned)LOV_PATTERN_RAID1);
LASSERTF(LOV_PATTERN_FIRST == 0x00000100UL, "found 0x%.8xUL\n",
- (unsigned)LOV_PATTERN_FIRST);
+ (unsigned)LOV_PATTERN_FIRST);
LASSERTF(LOV_PATTERN_CMOBD == 0x00000200UL, "found 0x%.8xUL\n",
- (unsigned)LOV_PATTERN_CMOBD);
+ (unsigned)LOV_PATTERN_CMOBD);
+
+ /* Checks for struct lmv_mds_md_v1 */
+ LASSERTF((int)sizeof(struct lmv_mds_md_v1) == 56, "found %lld\n",
+ (long long)(int)sizeof(struct lmv_mds_md_v1));
+ LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_magic) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_magic));
+ LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_magic) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_magic));
+ LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_stripe_count) == 4, "found %lld\n",
+ (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_stripe_count));
+ LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_count) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_count));
+ LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_master_mdt_index) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_master_mdt_index));
+ LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_master_mdt_index) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_master_mdt_index));
+ LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_hash_type) == 12, "found %lld\n",
+ (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_hash_type));
+ LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_hash_type) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_hash_type));
+ LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_layout_version) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_layout_version));
+ LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_layout_version) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_layout_version));
+ LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_padding1) == 20, "found %lld\n",
+ (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_padding1));
+ LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding1) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding1));
+ LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_padding2) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_padding2));
+ LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding2) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding2));
+ LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_padding3) == 32, "found %lld\n",
+ (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_padding3));
+ LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding3) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_padding3));
+ LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_pool_name[16]) == 56, "found %lld\n",
+ (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_pool_name[16]));
+ LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_pool_name[16]) == 1, "found %lld\n",
+ (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_pool_name[16]));
+ LASSERTF((int)offsetof(struct lmv_mds_md_v1, lmv_stripe_fids[0]) == 56, "found %lld\n",
+ (long long)(int)offsetof(struct lmv_mds_md_v1, lmv_stripe_fids[0]));
+ LASSERTF((int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_fids[0]) == 16, "found %lld\n",
+ (long long)(int)sizeof(((struct lmv_mds_md_v1 *)0)->lmv_stripe_fids[0]));
+ CLASSERT(LMV_MAGIC_V1 == 0x0CD20CD0);
+ CLASSERT(LMV_MAGIC_STRIPE == 0x0CD40CD0);
+ CLASSERT(LMV_HASH_TYPE_MASK == 0x0000ffff);
+ CLASSERT(LMV_HASH_FLAG_MIGRATION == 0x80000000);
+ CLASSERT(LMV_HASH_FLAG_DEAD == 0x40000000);
/* Checks for struct obd_statfs */
LASSERTF((int)sizeof(struct obd_statfs) == 144, "found %lld\n",
@@ -1582,53 +1639,53 @@ void lustre_assert_wire_constants(void)
LASSERTF((int)sizeof(((struct obd_dqblk *)0)->dqb_padding) == 4, "found %lld\n",
(long long)(int)sizeof(((struct obd_dqblk *)0)->dqb_padding));
LASSERTF(Q_QUOTACHECK == 0x800100, "found 0x%.8x\n",
- Q_QUOTACHECK);
+ Q_QUOTACHECK);
LASSERTF(Q_INITQUOTA == 0x800101, "found 0x%.8x\n",
- Q_INITQUOTA);
+ Q_INITQUOTA);
LASSERTF(Q_GETOINFO == 0x800102, "found 0x%.8x\n",
- Q_GETOINFO);
+ Q_GETOINFO);
LASSERTF(Q_GETOQUOTA == 0x800103, "found 0x%.8x\n",
- Q_GETOQUOTA);
+ Q_GETOQUOTA);
LASSERTF(Q_FINVALIDATE == 0x800104, "found 0x%.8x\n",
- Q_FINVALIDATE);
+ Q_FINVALIDATE);
/* Checks for struct niobuf_remote */
LASSERTF((int)sizeof(struct niobuf_remote) == 16, "found %lld\n",
(long long)(int)sizeof(struct niobuf_remote));
- LASSERTF((int)offsetof(struct niobuf_remote, offset) == 0, "found %lld\n",
- (long long)(int)offsetof(struct niobuf_remote, offset));
- LASSERTF((int)sizeof(((struct niobuf_remote *)0)->offset) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct niobuf_remote *)0)->offset));
- LASSERTF((int)offsetof(struct niobuf_remote, len) == 8, "found %lld\n",
- (long long)(int)offsetof(struct niobuf_remote, len));
- LASSERTF((int)sizeof(((struct niobuf_remote *)0)->len) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct niobuf_remote *)0)->len));
- LASSERTF((int)offsetof(struct niobuf_remote, flags) == 12, "found %lld\n",
- (long long)(int)offsetof(struct niobuf_remote, flags));
- LASSERTF((int)sizeof(((struct niobuf_remote *)0)->flags) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct niobuf_remote *)0)->flags));
+ LASSERTF((int)offsetof(struct niobuf_remote, rnb_offset) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct niobuf_remote, rnb_offset));
+ LASSERTF((int)sizeof(((struct niobuf_remote *)0)->rnb_offset) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct niobuf_remote *)0)->rnb_offset));
+ LASSERTF((int)offsetof(struct niobuf_remote, rnb_len) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct niobuf_remote, rnb_len));
+ LASSERTF((int)sizeof(((struct niobuf_remote *)0)->rnb_len) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct niobuf_remote *)0)->rnb_len));
+ LASSERTF((int)offsetof(struct niobuf_remote, rnb_flags) == 12, "found %lld\n",
+ (long long)(int)offsetof(struct niobuf_remote, rnb_flags));
+ LASSERTF((int)sizeof(((struct niobuf_remote *)0)->rnb_flags) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct niobuf_remote *)0)->rnb_flags));
LASSERTF(OBD_BRW_READ == 0x01, "found 0x%.8x\n",
- OBD_BRW_READ);
+ OBD_BRW_READ);
LASSERTF(OBD_BRW_WRITE == 0x02, "found 0x%.8x\n",
- OBD_BRW_WRITE);
+ OBD_BRW_WRITE);
LASSERTF(OBD_BRW_SYNC == 0x08, "found 0x%.8x\n",
- OBD_BRW_SYNC);
+ OBD_BRW_SYNC);
LASSERTF(OBD_BRW_CHECK == 0x10, "found 0x%.8x\n",
- OBD_BRW_CHECK);
+ OBD_BRW_CHECK);
LASSERTF(OBD_BRW_FROM_GRANT == 0x20, "found 0x%.8x\n",
- OBD_BRW_FROM_GRANT);
+ OBD_BRW_FROM_GRANT);
LASSERTF(OBD_BRW_GRANTED == 0x40, "found 0x%.8x\n",
- OBD_BRW_GRANTED);
+ OBD_BRW_GRANTED);
LASSERTF(OBD_BRW_NOCACHE == 0x80, "found 0x%.8x\n",
- OBD_BRW_NOCACHE);
+ OBD_BRW_NOCACHE);
LASSERTF(OBD_BRW_NOQUOTA == 0x100, "found 0x%.8x\n",
- OBD_BRW_NOQUOTA);
+ OBD_BRW_NOQUOTA);
LASSERTF(OBD_BRW_SRVLOCK == 0x200, "found 0x%.8x\n",
- OBD_BRW_SRVLOCK);
+ OBD_BRW_SRVLOCK);
LASSERTF(OBD_BRW_ASYNC == 0x400, "found 0x%.8x\n",
- OBD_BRW_ASYNC);
+ OBD_BRW_ASYNC);
LASSERTF(OBD_BRW_MEMALLOC == 0x800, "found 0x%.8x\n",
- OBD_BRW_MEMALLOC);
+ OBD_BRW_MEMALLOC);
LASSERTF(OBD_BRW_OVER_USRQUOTA == 0x1000, "found 0x%.8x\n",
OBD_BRW_OVER_USRQUOTA);
LASSERTF(OBD_BRW_OVER_GRPQUOTA == 0x2000, "found 0x%.8x\n",
@@ -1663,203 +1720,203 @@ void lustre_assert_wire_constants(void)
/* Checks for struct mdt_body */
LASSERTF((int)sizeof(struct mdt_body) == 216, "found %lld\n",
(long long)(int)sizeof(struct mdt_body));
- LASSERTF((int)offsetof(struct mdt_body, fid1) == 0, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, fid1));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->fid1) == 16, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->fid1));
- LASSERTF((int)offsetof(struct mdt_body, fid2) == 16, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, fid2));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->fid2) == 16, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->fid2));
- LASSERTF((int)offsetof(struct mdt_body, handle) == 32, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, handle));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->handle) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->handle));
- LASSERTF((int)offsetof(struct mdt_body, valid) == 40, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, valid));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->valid) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->valid));
- LASSERTF((int)offsetof(struct mdt_body, size) == 48, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, size));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->size) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->size));
- LASSERTF((int)offsetof(struct mdt_body, mtime) == 56, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, mtime));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->mtime) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->mtime));
- LASSERTF((int)offsetof(struct mdt_body, atime) == 64, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, atime));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->atime) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->atime));
- LASSERTF((int)offsetof(struct mdt_body, ctime) == 72, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, ctime));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->ctime) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->ctime));
- LASSERTF((int)offsetof(struct mdt_body, blocks) == 80, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, blocks));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->blocks) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->blocks));
- LASSERTF((int)offsetof(struct mdt_body, t_state) == 96, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, t_state));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->t_state) == 8,
+ LASSERTF((int)offsetof(struct mdt_body, mbo_fid1) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_fid1));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_fid1) == 16, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_fid1));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_fid2) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_fid2));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_fid2) == 16, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_fid2));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_handle) == 32, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_handle));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_handle) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_handle));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_valid) == 40, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_valid));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_valid) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_valid));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_size) == 48, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_size));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_size) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_size));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_mtime) == 56, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_mtime));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_mtime) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_mtime));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_atime) == 64, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_atime));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_atime) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_atime));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_ctime) == 72, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_ctime));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_ctime) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_ctime));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_blocks) == 80, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_blocks));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_blocks) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_blocks));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_t_state) == 96, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_t_state));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_t_state) == 8,
"found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->t_state));
- LASSERTF((int)offsetof(struct mdt_body, fsuid) == 104, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, fsuid));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->fsuid) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->fsuid));
- LASSERTF((int)offsetof(struct mdt_body, fsgid) == 108, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, fsgid));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->fsgid) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->fsgid));
- LASSERTF((int)offsetof(struct mdt_body, capability) == 112, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, capability));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->capability) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->capability));
- LASSERTF((int)offsetof(struct mdt_body, mode) == 116, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, mode));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->mode) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->mode));
- LASSERTF((int)offsetof(struct mdt_body, uid) == 120, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, uid));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->uid) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->uid));
- LASSERTF((int)offsetof(struct mdt_body, gid) == 124, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, gid));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->gid) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->gid));
- LASSERTF((int)offsetof(struct mdt_body, flags) == 128, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, flags));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->flags) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->flags));
- LASSERTF((int)offsetof(struct mdt_body, rdev) == 132, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, rdev));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->rdev) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->rdev));
- LASSERTF((int)offsetof(struct mdt_body, nlink) == 136, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, nlink));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->nlink) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->nlink));
- LASSERTF((int)offsetof(struct mdt_body, unused2) == 140, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, unused2));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->unused2) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->unused2));
- LASSERTF((int)offsetof(struct mdt_body, suppgid) == 144, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, suppgid));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->suppgid) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->suppgid));
- LASSERTF((int)offsetof(struct mdt_body, eadatasize) == 148, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, eadatasize));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->eadatasize) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->eadatasize));
- LASSERTF((int)offsetof(struct mdt_body, aclsize) == 152, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, aclsize));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->aclsize) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->aclsize));
- LASSERTF((int)offsetof(struct mdt_body, max_mdsize) == 156, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, max_mdsize));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->max_mdsize) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->max_mdsize));
- LASSERTF((int)offsetof(struct mdt_body, max_cookiesize) == 160, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, max_cookiesize));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->max_cookiesize) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->max_cookiesize));
- LASSERTF((int)offsetof(struct mdt_body, uid_h) == 164, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, uid_h));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->uid_h) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->uid_h));
- LASSERTF((int)offsetof(struct mdt_body, gid_h) == 168, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, gid_h));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->gid_h) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->gid_h));
- LASSERTF((int)offsetof(struct mdt_body, padding_5) == 172, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, padding_5));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->padding_5) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->padding_5));
- LASSERTF((int)offsetof(struct mdt_body, padding_6) == 176, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, padding_6));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->padding_6) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->padding_6));
- LASSERTF((int)offsetof(struct mdt_body, padding_7) == 184, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, padding_7));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->padding_7) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->padding_7));
- LASSERTF((int)offsetof(struct mdt_body, padding_8) == 192, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, padding_8));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->padding_8) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->padding_8));
- LASSERTF((int)offsetof(struct mdt_body, padding_9) == 200, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, padding_9));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->padding_9) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->padding_9));
- LASSERTF((int)offsetof(struct mdt_body, padding_10) == 208, "found %lld\n",
- (long long)(int)offsetof(struct mdt_body, padding_10));
- LASSERTF((int)sizeof(((struct mdt_body *)0)->padding_10) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_body *)0)->padding_10));
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_t_state));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_fsuid) == 104, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_fsuid));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_fsuid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_fsuid));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_fsgid) == 108, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_fsgid));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_fsgid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_fsgid));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_capability) == 112, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_capability));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_capability) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_capability));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_mode) == 116, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_mode));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_mode) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_mode));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_uid) == 120, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_uid));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_uid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_uid));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_gid) == 124, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_gid));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_gid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_gid));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_flags) == 128, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_flags));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_flags) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_flags));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_rdev) == 132, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_rdev));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_rdev) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_rdev));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_nlink) == 136, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_nlink));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_nlink) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_nlink));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_unused2) == 140, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_unused2));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_unused2) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_unused2));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_suppgid) == 144, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_suppgid));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_suppgid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_suppgid));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_eadatasize) == 148, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_eadatasize));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_eadatasize) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_eadatasize));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_aclsize) == 152, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_aclsize));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_aclsize) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_aclsize));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_max_mdsize) == 156, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_max_mdsize));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_max_mdsize) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_max_mdsize));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_max_cookiesize) == 160, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_max_cookiesize));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_max_cookiesize) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_max_cookiesize));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_uid_h) == 164, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_uid_h));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_uid_h) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_uid_h));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_gid_h) == 168, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_gid_h));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_gid_h) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_gid_h));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_padding_5) == 172, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_padding_5));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_5) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_padding_5));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_padding_6) == 176, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_padding_6));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_6) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_padding_6));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_padding_7) == 184, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_padding_7));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_7) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_padding_7));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_padding_8) == 192, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_padding_8));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_8) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_padding_8));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_padding_9) == 200, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_padding_9));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_9) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_padding_9));
+ LASSERTF((int)offsetof(struct mdt_body, mbo_padding_10) == 208, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_body, mbo_padding_10));
+ LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_10) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_body *)0)->mbo_padding_10));
LASSERTF(MDS_FMODE_CLOSED == 000000000000UL, "found 0%.11oUL\n",
- MDS_FMODE_CLOSED);
+ MDS_FMODE_CLOSED);
LASSERTF(MDS_FMODE_EXEC == 000000000004UL, "found 0%.11oUL\n",
- MDS_FMODE_EXEC);
+ MDS_FMODE_EXEC);
LASSERTF(MDS_FMODE_EPOCH == 000001000000UL, "found 0%.11oUL\n",
- MDS_FMODE_EPOCH);
+ MDS_FMODE_EPOCH);
LASSERTF(MDS_FMODE_TRUNC == 000002000000UL, "found 0%.11oUL\n",
- MDS_FMODE_TRUNC);
+ MDS_FMODE_TRUNC);
LASSERTF(MDS_FMODE_SOM == 000004000000UL, "found 0%.11oUL\n",
- MDS_FMODE_SOM);
+ MDS_FMODE_SOM);
LASSERTF(MDS_OPEN_CREATED == 000000000010UL, "found 0%.11oUL\n",
- MDS_OPEN_CREATED);
+ MDS_OPEN_CREATED);
LASSERTF(MDS_OPEN_CROSS == 000000000020UL, "found 0%.11oUL\n",
- MDS_OPEN_CROSS);
+ MDS_OPEN_CROSS);
LASSERTF(MDS_OPEN_CREAT == 000000000100UL, "found 0%.11oUL\n",
- MDS_OPEN_CREAT);
+ MDS_OPEN_CREAT);
LASSERTF(MDS_OPEN_EXCL == 000000000200UL, "found 0%.11oUL\n",
- MDS_OPEN_EXCL);
+ MDS_OPEN_EXCL);
LASSERTF(MDS_OPEN_TRUNC == 000000001000UL, "found 0%.11oUL\n",
- MDS_OPEN_TRUNC);
+ MDS_OPEN_TRUNC);
LASSERTF(MDS_OPEN_APPEND == 000000002000UL, "found 0%.11oUL\n",
- MDS_OPEN_APPEND);
+ MDS_OPEN_APPEND);
LASSERTF(MDS_OPEN_SYNC == 000000010000UL, "found 0%.11oUL\n",
- MDS_OPEN_SYNC);
+ MDS_OPEN_SYNC);
LASSERTF(MDS_OPEN_DIRECTORY == 000000200000UL, "found 0%.11oUL\n",
- MDS_OPEN_DIRECTORY);
+ MDS_OPEN_DIRECTORY);
LASSERTF(MDS_OPEN_BY_FID == 000040000000UL, "found 0%.11oUL\n",
- MDS_OPEN_BY_FID);
+ MDS_OPEN_BY_FID);
LASSERTF(MDS_OPEN_DELAY_CREATE == 000100000000UL, "found 0%.11oUL\n",
- MDS_OPEN_DELAY_CREATE);
+ MDS_OPEN_DELAY_CREATE);
LASSERTF(MDS_OPEN_OWNEROVERRIDE == 000200000000UL, "found 0%.11oUL\n",
- MDS_OPEN_OWNEROVERRIDE);
+ MDS_OPEN_OWNEROVERRIDE);
LASSERTF(MDS_OPEN_JOIN_FILE == 000400000000UL, "found 0%.11oUL\n",
- MDS_OPEN_JOIN_FILE);
+ MDS_OPEN_JOIN_FILE);
LASSERTF(MDS_OPEN_LOCK == 004000000000UL, "found 0%.11oUL\n",
- MDS_OPEN_LOCK);
+ MDS_OPEN_LOCK);
LASSERTF(MDS_OPEN_HAS_EA == 010000000000UL, "found 0%.11oUL\n",
- MDS_OPEN_HAS_EA);
+ MDS_OPEN_HAS_EA);
LASSERTF(MDS_OPEN_HAS_OBJS == 020000000000UL, "found 0%.11oUL\n",
- MDS_OPEN_HAS_OBJS);
+ MDS_OPEN_HAS_OBJS);
LASSERTF(MDS_OPEN_NORESTORE == 00000000000100000000000ULL, "found 0%.22lloULL\n",
- (long long)MDS_OPEN_NORESTORE);
+ (long long)MDS_OPEN_NORESTORE);
LASSERTF(MDS_OPEN_NEWSTRIPE == 00000000000200000000000ULL, "found 0%.22lloULL\n",
- (long long)MDS_OPEN_NEWSTRIPE);
+ (long long)MDS_OPEN_NEWSTRIPE);
LASSERTF(MDS_OPEN_VOLATILE == 00000000000400000000000ULL, "found 0%.22lloULL\n",
- (long long)MDS_OPEN_VOLATILE);
+ (long long)MDS_OPEN_VOLATILE);
LASSERTF(LUSTRE_SYNC_FL == 0x00000008, "found 0x%.8x\n",
- LUSTRE_SYNC_FL);
+ LUSTRE_SYNC_FL);
LASSERTF(LUSTRE_IMMUTABLE_FL == 0x00000010, "found 0x%.8x\n",
- LUSTRE_IMMUTABLE_FL);
+ LUSTRE_IMMUTABLE_FL);
LASSERTF(LUSTRE_APPEND_FL == 0x00000020, "found 0x%.8x\n",
- LUSTRE_APPEND_FL);
+ LUSTRE_APPEND_FL);
LASSERTF(LUSTRE_NOATIME_FL == 0x00000080, "found 0x%.8x\n",
- LUSTRE_NOATIME_FL);
+ LUSTRE_NOATIME_FL);
LASSERTF(LUSTRE_DIRSYNC_FL == 0x00010000, "found 0x%.8x\n",
- LUSTRE_DIRSYNC_FL);
+ LUSTRE_DIRSYNC_FL);
LASSERTF(MDS_INODELOCK_LOOKUP == 0x000001, "found 0x%.8x\n",
- MDS_INODELOCK_LOOKUP);
+ MDS_INODELOCK_LOOKUP);
LASSERTF(MDS_INODELOCK_UPDATE == 0x000002, "found 0x%.8x\n",
- MDS_INODELOCK_UPDATE);
+ MDS_INODELOCK_UPDATE);
LASSERTF(MDS_INODELOCK_OPEN == 0x000004, "found 0x%.8x\n",
- MDS_INODELOCK_OPEN);
+ MDS_INODELOCK_OPEN);
LASSERTF(MDS_INODELOCK_LAYOUT == 0x000008, "found 0x%.8x\n",
- MDS_INODELOCK_LAYOUT);
+ MDS_INODELOCK_LAYOUT);
/* Checks for struct mdt_ioepoch */
LASSERTF((int)sizeof(struct mdt_ioepoch) == 24, "found %lld\n",
@@ -2617,35 +2674,6 @@ void lustre_assert_wire_constants(void)
LASSERTF((int)sizeof(((struct lmv_desc *)0)->ld_uuid) == 40, "found %lld\n",
(long long)(int)sizeof(((struct lmv_desc *)0)->ld_uuid));
- /* Checks for struct lmv_stripe_md */
- LASSERTF((int)sizeof(struct lmv_stripe_md) == 32, "found %lld\n",
- (long long)(int)sizeof(struct lmv_stripe_md));
- LASSERTF((int)offsetof(struct lmv_stripe_md, mea_magic) == 0, "found %lld\n",
- (long long)(int)offsetof(struct lmv_stripe_md, mea_magic));
- LASSERTF((int)sizeof(((struct lmv_stripe_md *)0)->mea_magic) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct lmv_stripe_md *)0)->mea_magic));
- LASSERTF((int)offsetof(struct lmv_stripe_md, mea_count) == 4, "found %lld\n",
- (long long)(int)offsetof(struct lmv_stripe_md, mea_count));
- LASSERTF((int)sizeof(((struct lmv_stripe_md *)0)->mea_count) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct lmv_stripe_md *)0)->mea_count));
- LASSERTF((int)offsetof(struct lmv_stripe_md, mea_master) == 8, "found %lld\n",
- (long long)(int)offsetof(struct lmv_stripe_md, mea_master));
- LASSERTF((int)sizeof(((struct lmv_stripe_md *)0)->mea_master) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct lmv_stripe_md *)0)->mea_master));
- LASSERTF((int)offsetof(struct lmv_stripe_md, mea_padding) == 12, "found %lld\n",
- (long long)(int)offsetof(struct lmv_stripe_md, mea_padding));
- LASSERTF((int)sizeof(((struct lmv_stripe_md *)0)->mea_padding) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct lmv_stripe_md *)0)->mea_padding));
- CLASSERT(LOV_MAXPOOLNAME == 16);
- LASSERTF((int)offsetof(struct lmv_stripe_md, mea_pool_name[16]) == 32, "found %lld\n",
- (long long)(int)offsetof(struct lmv_stripe_md, mea_pool_name[16]));
- LASSERTF((int)sizeof(((struct lmv_stripe_md *)0)->mea_pool_name[16]) == 1, "found %lld\n",
- (long long)(int)sizeof(((struct lmv_stripe_md *)0)->mea_pool_name[16]));
- LASSERTF((int)offsetof(struct lmv_stripe_md, mea_ids[0]) == 32, "found %lld\n",
- (long long)(int)offsetof(struct lmv_stripe_md, mea_ids[0]));
- LASSERTF((int)sizeof(((struct lmv_stripe_md *)0)->mea_ids[0]) == 16, "found %lld\n",
- (long long)(int)sizeof(((struct lmv_stripe_md *)0)->mea_ids[0]));
-
/* Checks for struct lov_desc */
LASSERTF((int)sizeof(struct lov_desc) == 88, "found %lld\n",
(long long)(int)sizeof(struct lov_desc));
@@ -3195,10 +3223,10 @@ void lustre_assert_wire_constants(void)
(long long)(int)offsetof(struct llog_setattr64_rec, lsr_gid_h));
LASSERTF((int)sizeof(((struct llog_setattr64_rec *)0)->lsr_gid_h) == 4, "found %lld\n",
(long long)(int)sizeof(((struct llog_setattr64_rec *)0)->lsr_gid_h));
- LASSERTF((int)offsetof(struct llog_setattr64_rec, lsr_padding) == 48, "found %lld\n",
- (long long)(int)offsetof(struct llog_setattr64_rec, lsr_padding));
- LASSERTF((int)sizeof(((struct llog_setattr64_rec *)0)->lsr_padding) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct llog_setattr64_rec *)0)->lsr_padding));
+ LASSERTF((int)offsetof(struct llog_setattr64_rec, lsr_valid) == 48, "found %lld\n",
+ (long long)(int)offsetof(struct llog_setattr64_rec, lsr_valid));
+ LASSERTF((int)sizeof(((struct llog_setattr64_rec *)0)->lsr_valid) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct llog_setattr64_rec *)0)->lsr_valid));
LASSERTF((int)offsetof(struct llog_setattr64_rec, lsr_tail) == 56, "found %lld\n",
(long long)(int)offsetof(struct llog_setattr64_rec, lsr_tail));
LASSERTF((int)sizeof(((struct llog_setattr64_rec *)0)->lsr_tail) == 8, "found %lld\n",
@@ -3272,50 +3300,6 @@ void lustre_assert_wire_constants(void)
LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_pfid) == 16, "found %lld\n",
(long long)(int)sizeof(((struct changelog_rec *)0)->cr_pfid));
- /* Checks for struct changelog_ext_rec */
- LASSERTF((int)sizeof(struct changelog_ext_rec) == 96, "found %lld\n",
- (long long)(int)sizeof(struct changelog_ext_rec));
- LASSERTF((int)offsetof(struct changelog_ext_rec, cr_namelen) == 0, "found %lld\n",
- (long long)(int)offsetof(struct changelog_ext_rec, cr_namelen));
- LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_namelen) == 2, "found %lld\n",
- (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_namelen));
- LASSERTF((int)offsetof(struct changelog_ext_rec, cr_flags) == 2, "found %lld\n",
- (long long)(int)offsetof(struct changelog_ext_rec, cr_flags));
- LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_flags) == 2, "found %lld\n",
- (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_flags));
- LASSERTF((int)offsetof(struct changelog_ext_rec, cr_type) == 4, "found %lld\n",
- (long long)(int)offsetof(struct changelog_ext_rec, cr_type));
- LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_type) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_type));
- LASSERTF((int)offsetof(struct changelog_ext_rec, cr_index) == 8, "found %lld\n",
- (long long)(int)offsetof(struct changelog_ext_rec, cr_index));
- LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_index) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_index));
- LASSERTF((int)offsetof(struct changelog_ext_rec, cr_prev) == 16, "found %lld\n",
- (long long)(int)offsetof(struct changelog_ext_rec, cr_prev));
- LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_prev) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_prev));
- LASSERTF((int)offsetof(struct changelog_ext_rec, cr_time) == 24, "found %lld\n",
- (long long)(int)offsetof(struct changelog_ext_rec, cr_time));
- LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_time) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_time));
- LASSERTF((int)offsetof(struct changelog_ext_rec, cr_tfid) == 32, "found %lld\n",
- (long long)(int)offsetof(struct changelog_ext_rec, cr_tfid));
- LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_tfid) == 16, "found %lld\n",
- (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_tfid));
- LASSERTF((int)offsetof(struct changelog_ext_rec, cr_pfid) == 48, "found %lld\n",
- (long long)(int)offsetof(struct changelog_ext_rec, cr_pfid));
- LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_pfid) == 16, "found %lld\n",
- (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_pfid));
- LASSERTF((int)offsetof(struct changelog_ext_rec, cr_sfid) == 64, "found %lld\n",
- (long long)(int)offsetof(struct changelog_ext_rec, cr_sfid));
- LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_sfid) == 16, "found %lld\n",
- (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_sfid));
- LASSERTF((int)offsetof(struct changelog_ext_rec, cr_spfid) == 80, "found %lld\n",
- (long long)(int)offsetof(struct changelog_ext_rec, cr_spfid));
- LASSERTF((int)sizeof(((struct changelog_ext_rec *)0)->cr_spfid) == 16, "found %lld\n",
- (long long)(int)sizeof(((struct changelog_ext_rec *)0)->cr_spfid));
-
/* Checks for struct changelog_setinfo */
LASSERTF((int)sizeof(struct changelog_setinfo) == 12, "found %lld\n",
(long long)(int)sizeof(struct changelog_setinfo));
@@ -3339,10 +3323,10 @@ void lustre_assert_wire_constants(void)
(long long)(int)offsetof(struct llog_changelog_rec, cr));
LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr) == 64, "found %lld\n",
(long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr));
- LASSERTF((int)offsetof(struct llog_changelog_rec, cr_tail) == 80, "found %lld\n",
- (long long)(int)offsetof(struct llog_changelog_rec, cr_tail));
- LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_tail) == 8, "found %lld\n",
- (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_tail));
+ LASSERTF((int)offsetof(struct llog_changelog_rec, cr_do_not_use) == 80, "found %lld\n",
+ (long long)(int)offsetof(struct llog_changelog_rec, cr_do_not_use));
+ LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_do_not_use) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_do_not_use));
/* Checks for struct llog_changelog_user_rec */
LASSERTF((int)sizeof(struct llog_changelog_user_rec) == 40, "found %lld\n",
@@ -3506,6 +3490,19 @@ void lustre_assert_wire_constants(void)
CLASSERT(LLOG_ORIGIN_HANDLE_DESTROY == 509);
CLASSERT(LLOG_FIRST_OPC == 501);
CLASSERT(LLOG_LAST_OPC == 510);
+ CLASSERT(LLOG_CONFIG_ORIG_CTXT == 0);
+ CLASSERT(LLOG_CONFIG_REPL_CTXT == 1);
+ CLASSERT(LLOG_MDS_OST_ORIG_CTXT == 2);
+ CLASSERT(LLOG_MDS_OST_REPL_CTXT == 3);
+ CLASSERT(LLOG_SIZE_ORIG_CTXT == 4);
+ CLASSERT(LLOG_SIZE_REPL_CTXT == 5);
+ CLASSERT(LLOG_TEST_ORIG_CTXT == 8);
+ CLASSERT(LLOG_TEST_REPL_CTXT == 9);
+ CLASSERT(LLOG_CHANGELOG_ORIG_CTXT == 12);
+ CLASSERT(LLOG_CHANGELOG_REPL_CTXT == 13);
+ CLASSERT(LLOG_CHANGELOG_USER_ORIG_CTXT == 14);
+ CLASSERT(LLOG_AGENT_ORIG_CTXT == 15);
+ CLASSERT(LLOG_MAX_CTXTS == 16);
/* Checks for struct llogd_conn_body */
LASSERTF((int)sizeof(struct llogd_conn_body) == 40, "found %lld\n",
@@ -3943,9 +3940,9 @@ void lustre_assert_wire_constants(void)
LASSERTF((int)sizeof(((struct hsm_progress *)0)->padding) == 4, "found %lld\n",
(long long)(int)sizeof(((struct hsm_progress *)0)->padding));
LASSERTF(HP_FLAG_COMPLETED == 0x01, "found 0x%.8x\n",
- HP_FLAG_COMPLETED);
+ HP_FLAG_COMPLETED);
LASSERTF(HP_FLAG_RETRY == 0x02, "found 0x%.8x\n",
- HP_FLAG_RETRY);
+ HP_FLAG_RETRY);
LASSERTF((int)offsetof(struct hsm_copy, hc_data_version) == 0, "found %lld\n",
(long long)(int)offsetof(struct hsm_copy, hc_data_version));
@@ -4100,9 +4097,9 @@ void lustre_assert_wire_constants(void)
LASSERTF((int)sizeof(((struct hsm_request *)0)->hr_data_len) == 4, "found %lld\n",
(long long)(int)sizeof(((struct hsm_request *)0)->hr_data_len));
LASSERTF(HSM_FORCE_ACTION == 0x00000001UL, "found 0x%.8xUL\n",
- (unsigned)HSM_FORCE_ACTION);
+ (unsigned)HSM_FORCE_ACTION);
LASSERTF(HSM_GHOST_COPY == 0x00000002UL, "found 0x%.8xUL\n",
- (unsigned)HSM_GHOST_COPY);
+ (unsigned)HSM_GHOST_COPY);
/* Checks for struct hsm_user_request */
LASSERTF((int)sizeof(struct hsm_user_request) == 24, "found %lld\n",
diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c
index 8dade197f053..ea15cc638097 100644
--- a/drivers/staging/media/bcm2048/radio-bcm2048.c
+++ b/drivers/staging/media/bcm2048/radio-bcm2048.c
@@ -483,10 +483,8 @@ static int bcm2048_set_rds_no_lock(struct bcm2048_device *bdev, u8 rds_on)
memset(&bdev->rds_info, 0, sizeof(bdev->rds_info));
}
- err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM,
- bdev->cache_fm_rds_system);
-
- return err;
+ return bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM,
+ bdev->cache_fm_rds_system);
}
static int bcm2048_get_rds_no_lock(struct bcm2048_device *bdev)
@@ -1834,9 +1832,7 @@ static int bcm2048_deinit(struct bcm2048_device *bdev)
if (err < 0)
return err;
- err = bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
-
- return err;
+ return bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
}
/*
@@ -1995,9 +1991,7 @@ static ssize_t bcm2048_##prop##_read(struct device *dev, \
\
value = bcm2048_get_##prop(bdev); \
\
- value = sprintf(buf, mask "\n", value); \
- \
- return value; \
+ return sprintf(buf, mask "\n", value); \
}
#define DEFINE_SYSFS_PROPERTY(prop, signal, size, mask, check) \
diff --git a/drivers/staging/media/cxd2099/cxd2099.c b/drivers/staging/media/cxd2099/cxd2099.c
index 692ba3e63e14..fedeb3c3549e 100644
--- a/drivers/staging/media/cxd2099/cxd2099.c
+++ b/drivers/staging/media/cxd2099/cxd2099.c
@@ -660,7 +660,7 @@ static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
struct cxd *ci = ca->data;
mutex_lock(&ci->lock);
- printk(kern_INFO "write_data %d\n", ecount);
+ dev_info(&ci->i2c->dev, "write_data %d\n", ecount);
write_reg(ci, 0x0d, ecount>>8);
write_reg(ci, 0x0e, ecount&0xff);
write_block(ci, 0x11, ebuf, ecount);
diff --git a/drivers/staging/media/davinci_vpfe/davinci_vpfe_user.h b/drivers/staging/media/davinci_vpfe/davinci_vpfe_user.h
index f4f35c9ad1ab..d3f34f9bf712 100644
--- a/drivers/staging/media/davinci_vpfe/davinci_vpfe_user.h
+++ b/drivers/staging/media/davinci_vpfe/davinci_vpfe_user.h
@@ -544,41 +544,41 @@ struct vpfe_isif_raw_config {
/* IPIPE module configurations */
/* IPIPE input configuration */
-#define VPFE_IPIPE_INPUT_CONFIG (1 << 0)
+#define VPFE_IPIPE_INPUT_CONFIG BIT(0)
/* LUT based Defect Pixel Correction */
-#define VPFE_IPIPE_LUTDPC (1 << 1)
+#define VPFE_IPIPE_LUTDPC BIT(1)
/* On the fly (OTF) Defect Pixel Correction */
-#define VPFE_IPIPE_OTFDPC (1 << 2)
+#define VPFE_IPIPE_OTFDPC BIT(2)
/* Noise Filter - 1 */
-#define VPFE_IPIPE_NF1 (1 << 3)
+#define VPFE_IPIPE_NF1 BIT(3)
/* Noise Filter - 2 */
-#define VPFE_IPIPE_NF2 (1 << 4)
+#define VPFE_IPIPE_NF2 BIT(4)
/* White Balance. Also a control ID */
-#define VPFE_IPIPE_WB (1 << 5)
+#define VPFE_IPIPE_WB BIT(5)
/* 1st RGB to RBG Blend module */
-#define VPFE_IPIPE_RGB2RGB_1 (1 << 6)
+#define VPFE_IPIPE_RGB2RGB_1 BIT(6)
/* 2nd RGB to RBG Blend module */
-#define VPFE_IPIPE_RGB2RGB_2 (1 << 7)
+#define VPFE_IPIPE_RGB2RGB_2 BIT(7)
/* Gamma Correction */
-#define VPFE_IPIPE_GAMMA (1 << 8)
+#define VPFE_IPIPE_GAMMA BIT(8)
/* 3D LUT color conversion */
-#define VPFE_IPIPE_3D_LUT (1 << 9)
+#define VPFE_IPIPE_3D_LUT BIT(9)
/* RGB to YCbCr module */
-#define VPFE_IPIPE_RGB2YUV (1 << 10)
+#define VPFE_IPIPE_RGB2YUV BIT(10)
/* YUV 422 conversion module */
-#define VPFE_IPIPE_YUV422_CONV (1 << 11)
+#define VPFE_IPIPE_YUV422_CONV BIT(11)
/* Edge Enhancement */
-#define VPFE_IPIPE_YEE (1 << 12)
+#define VPFE_IPIPE_YEE BIT(12)
/* Green Imbalance Correction */
-#define VPFE_IPIPE_GIC (1 << 13)
+#define VPFE_IPIPE_GIC BIT(13)
/* CFA Interpolation */
-#define VPFE_IPIPE_CFA (1 << 14)
+#define VPFE_IPIPE_CFA BIT(14)
/* Chroma Artifact Reduction */
-#define VPFE_IPIPE_CAR (1 << 15)
+#define VPFE_IPIPE_CAR BIT(15)
/* Chroma Gain Suppression */
-#define VPFE_IPIPE_CGS (1 << 16)
+#define VPFE_IPIPE_CGS BIT(16)
/* Global brightness and contrast control */
-#define VPFE_IPIPE_GBCE (1 << 17)
+#define VPFE_IPIPE_GBCE BIT(17)
#define VPFE_IPIPE_MAX_MODULES 18
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index ae9202ded59f..569bcdc9ce2f 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -146,9 +146,8 @@ enum v4l2_field vpfe_isif_get_fid(struct vpfe_device *vpfe_dev)
u32 field_status;
field_status = isif_read(isif->isif_cfg.base_addr, MODESET);
- field_status = (field_status >> DM365_ISIF_MDFS_OFFSET) &
- DM365_ISIF_MDFS_MASK;
- return field_status;
+ return (field_status >> DM365_ISIF_MDFS_OFFSET) &
+ DM365_ISIF_MDFS_MASK;
}
static int
@@ -594,8 +593,7 @@ isif_validate_raw_params(struct vpfe_isif_raw_config *params)
ret = isif_validate_dfc_params(&params->dfc);
if (ret)
return ret;
- ret = isif_validate_bclamp_params(&params->bclamp);
- return ret;
+ return isif_validate_bclamp_params(&params->bclamp);
}
static int isif_set_params(struct v4l2_subdev *sd, void *params)
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index 3cd56cc132c7..128662623ea8 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -128,7 +128,7 @@ resizer_configure_passthru(struct vpfe_resizer_device *resizer, int bypass)
static void
configure_resizer_out_params(struct vpfe_resizer_device *resizer, int index,
void *output_spec, unsigned char partial,
- unsigned flag)
+ unsigned int flag)
{
struct resizer_params *param = &resizer->config;
struct v4l2_mbus_framefmt *outformat;
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index 3319fb8f7d01..8be9f854510f 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -37,7 +37,7 @@ static struct media_entity *vpfe_get_input_entity
struct media_pad *remote;
remote = media_entity_remote_pad(&vpfe_dev->vpfe_isif.pads[0]);
- if (remote == NULL) {
+ if (!remote) {
pr_err("Invalid media connection to isif/ccdc\n");
return NULL;
}
@@ -54,7 +54,7 @@ static int vpfe_update_current_ext_subdev(struct vpfe_video_device *video)
int i;
remote = media_entity_remote_pad(&vpfe_dev->vpfe_isif.pads[0]);
- if (remote == NULL) {
+ if (!remote) {
pr_err("Invalid media connection to isif/ccdc\n");
return -EINVAL;
}
@@ -107,7 +107,7 @@ __vpfe_video_get_format(struct vpfe_video_device *video,
int ret;
subdev = vpfe_video_remote_subdev(video, &pad);
- if (subdev == NULL)
+ if (!subdev)
return -EINVAL;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
@@ -236,7 +236,7 @@ static int vpfe_video_validate_pipeline(struct vpfe_pipeline *pipe)
* format of the connected pad.
*/
subdev = vpfe_video_remote_subdev(pipe->outputs[0], NULL);
- if (subdev == NULL)
+ if (!subdev)
return -EPIPE;
while (1) {
@@ -413,7 +413,7 @@ static int vpfe_open(struct file *file)
/* Allocate memory for the file handle object */
handle = kzalloc(sizeof(struct vpfe_fh), GFP_KERNEL);
- if (handle == NULL)
+ if (!handle)
return -ENOMEM;
v4l2_fh_init(&handle->vfh, &video->video_dev);
@@ -683,14 +683,14 @@ static int vpfe_enum_fmt(struct file *file, void *priv,
}
/* get the remote pad */
remote = media_entity_remote_pad(&video->pad);
- if (remote == NULL) {
+ if (!remote) {
v4l2_err(&vpfe_dev->v4l2_dev,
"invalid remote pad for video node\n");
return -EINVAL;
}
/* get the remote subdev */
subdev = vpfe_video_remote_subdev(video, NULL);
- if (subdev == NULL) {
+ if (!subdev) {
v4l2_err(&vpfe_dev->v4l2_dev,
"invalid remote subdev for video node\n");
return -EINVAL;
diff --git a/drivers/staging/media/lirc/lirc_bt829.c b/drivers/staging/media/lirc/lirc_bt829.c
index 44f565547179..04d881b391c7 100644
--- a/drivers/staging/media/lirc/lirc_bt829.c
+++ b/drivers/staging/media/lirc/lirc_bt829.c
@@ -120,7 +120,7 @@ int init_module(void)
int rc;
pdev = do_pci_probe();
- if (pdev == NULL)
+ if (!pdev)
return -ENODEV;
rc = pci_enable_device(pdev);
@@ -163,7 +163,6 @@ err_put_dev:
return rc;
}
-
void cleanup_module(void)
{
struct pci_dev *pdev = to_pci_dev(atir_driver.dev);
@@ -174,7 +173,6 @@ void cleanup_module(void)
pci_dev_put(pdev);
}
-
static int atir_init_start(void)
{
pci_addr_lin = ioremap(pci_addr_phys + DATA_PCI_OFF, 0x400);
@@ -187,10 +185,9 @@ static int atir_init_start(void)
static void cycle_delay(int cycle)
{
- udelay(WAIT_CYCLE*cycle);
+ udelay(WAIT_CYCLE * cycle);
}
-
static int poll_main(void)
{
unsigned char status_high, status_low;
diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c
index ff1926ca1f96..198a8057f2f1 100644
--- a/drivers/staging/media/lirc/lirc_imon.c
+++ b/drivers/staging/media/lirc/lirc_imon.c
@@ -32,7 +32,6 @@
#include <media/lirc.h>
#include <media/lirc_dev.h>
-
#define MOD_AUTHOR "Venky Raju <dev@venky.ws>"
#define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display"
#define MOD_NAME "lirc_imon"
@@ -212,7 +211,6 @@ static void deregister_from_lirc(struct imon_context *context)
else
dev_info(&context->usbdev->dev,
"Deregistered iMON driver (minor:%d)\n", minor);
-
}
/**
@@ -429,7 +427,7 @@ static ssize_t vfd_write(struct file *file, const char __user *buf,
do {
memcpy(context->usb_tx_buf, context->tx.data_buf + offset, 7);
- context->usb_tx_buf[7] = (unsigned char) seq;
+ context->usb_tx_buf[7] = (unsigned char)seq;
retval = send_packet(context);
if (retval) {
@@ -447,7 +445,7 @@ static ssize_t vfd_write(struct file *file, const char __user *buf,
if (context->vfd_proto_6p) {
/* Send packet #6 */
memcpy(context->usb_tx_buf, &vfd_packet6, sizeof(vfd_packet6));
- context->usb_tx_buf[7] = (unsigned char) seq;
+ context->usb_tx_buf[7] = (unsigned char)seq;
retval = send_packet(context);
if (retval)
dev_err(&context->usbdev->dev,
@@ -563,7 +561,7 @@ static void submit_data(struct imon_context *context)
value |= PULSE_BIT;
for (i = 0; i < 4; ++i)
- buf[i] = value>>(i*8);
+ buf[i] = value >> (i * 8);
lirc_buffer_write(context->driver->rbuf, buf);
wake_up(&context->driver->rbuf->wait_poll);
@@ -589,7 +587,7 @@ static void imon_incoming_packet(struct imon_context *context,
if (len != 8) {
dev_warn(dev, "imon %s: invalid incoming packet size (len = %d, intf%d)\n",
- __func__, len, intf);
+ __func__, len, intf);
return;
}
@@ -704,7 +702,7 @@ static int imon_probe(struct usb_interface *interface,
/* prevent races probing devices w/multiple interfaces */
mutex_lock(&driver_lock);
- context = kzalloc(sizeof(struct imon_context), GFP_KERNEL);
+ context = kzalloc(sizeof(*context), GFP_KERNEL);
if (!context)
goto driver_unlock;
@@ -784,11 +782,11 @@ static int imon_probe(struct usb_interface *interface,
__func__, vfd_proto_6p);
}
- driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
+ driver = kzalloc(sizeof(*driver), GFP_KERNEL);
if (!driver)
goto free_context;
- rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
+ rbuf = kmalloc(sizeof(*rbuf), GFP_KERNEL);
if (!rbuf)
goto free_driver;
@@ -797,16 +795,11 @@ static int imon_probe(struct usb_interface *interface,
goto free_rbuf;
}
rx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!rx_urb) {
- dev_err(dev, "%s: usb_alloc_urb failed for IR urb\n", __func__);
+ if (!rx_urb)
goto free_lirc_buf;
- }
tx_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!tx_urb) {
- dev_err(dev, "%s: usb_alloc_urb failed for display urb\n",
- __func__);
+ if (!tx_urb)
goto free_rx_urb;
- }
mutex_init(&context->ctx_lock);
context->vfd_proto_6p = vfd_proto_6p;
@@ -835,7 +828,7 @@ static int imon_probe(struct usb_interface *interface,
}
dev_info(dev, "Registered iMON driver (lirc minor: %d)\n",
- lirc_minor);
+ lirc_minor);
/* Needed while unregistering! */
driver->minor = lirc_minor;
@@ -856,8 +849,8 @@ static int imon_probe(struct usb_interface *interface,
context->display = 1;
usb_fill_int_urb(context->rx_urb, context->usbdev,
- usb_rcvintpipe(context->usbdev,
- context->rx_endpoint->bEndpointAddress),
+ usb_rcvintpipe(context->usbdev,
+ context->rx_endpoint->bEndpointAddress),
context->usb_rx_buf, sizeof(context->usb_rx_buf),
usb_rx_callback, context,
context->rx_endpoint->bInterval);
@@ -882,7 +875,7 @@ static int imon_probe(struct usb_interface *interface,
}
dev_info(dev, "iMON device (%04x:%04x, intf%d) on usb<%d:%d> initialized\n",
- vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum);
+ vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum);
/* Everything went fine. Just unlock and return retval (with is 0) */
mutex_unlock(&context->ctx_lock);
@@ -973,8 +966,8 @@ static int imon_resume(struct usb_interface *intf)
struct imon_context *context = usb_get_intfdata(intf);
usb_fill_int_urb(context->rx_urb, context->usbdev,
- usb_rcvintpipe(context->usbdev,
- context->rx_endpoint->bEndpointAddress),
+ usb_rcvintpipe(context->usbdev,
+ context->rx_endpoint->bEndpointAddress),
context->usb_rx_buf, sizeof(context->usb_rx_buf),
usb_rx_callback, context,
context->rx_endpoint->bInterval);
diff --git a/drivers/staging/media/lirc/lirc_parallel.c b/drivers/staging/media/lirc/lirc_parallel.c
index 3906ac6e686d..64d99ec292e5 100644
--- a/drivers/staging/media/lirc/lirc_parallel.c
+++ b/drivers/staging/media/lirc/lirc_parallel.c
@@ -163,12 +163,12 @@ static unsigned int init_lirc_timer(void)
if (count >= 1000 && timeelapsed > 0) {
if (default_timer == 0) {
/* autodetect timer */
- newtimer = (1000000*count)/timeelapsed;
+ newtimer = (1000000 * count) / timeelapsed;
pr_info("%u Hz timer detected\n", newtimer);
return newtimer;
}
- newtimer = (1000000*count)/timeelapsed;
- if (abs(newtimer - default_timer) > default_timer/10) {
+ newtimer = (1000000 * count) / timeelapsed;
+ if (abs(newtimer - default_timer) > default_timer / 10) {
/* bad timer */
pr_notice("bad timer: %u Hz\n", newtimer);
pr_notice("using default timer: %u Hz\n",
diff --git a/drivers/staging/media/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c
index 2218d0042030..4678ae10b030 100644
--- a/drivers/staging/media/lirc/lirc_sasem.c
+++ b/drivers/staging/media/lirc/lirc_sasem.c
@@ -47,7 +47,6 @@
#include <media/lirc.h>
#include <media/lirc_dev.h>
-
#define MOD_AUTHOR "Oliver Stabel <oliver.stabel@gmx.de>, " \
"Tim Davies <tim@opensystems.net.au>"
#define MOD_DESC "USB Driver for Sasem Remote Controller V1.1"
@@ -73,7 +72,7 @@ static void usb_tx_callback(struct urb *urb);
/* VFD file_operations function prototypes */
static int vfd_open(struct inode *inode, struct file *file);
-static long vfd_ioctl(struct file *file, unsigned cmd, unsigned long arg);
+static long vfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static int vfd_close(struct inode *inode, struct file *file);
static ssize_t vfd_write(struct file *file, const char __user *buf,
size_t n_bytes, loff_t *pos);
@@ -86,7 +85,6 @@ static void ir_close(void *data);
#define SASEM_DATA_BUF_SZ 32
struct sasem_context {
-
struct usb_device *dev;
int vfd_isopen; /* VFD port has been opened */
unsigned int vfd_contrast; /* VFD contrast */
@@ -156,7 +154,6 @@ static int debug;
/*** M O D U L E C O D E ***/
-
MODULE_AUTHOR(MOD_AUTHOR);
MODULE_DESCRIPTION(MOD_DESC);
MODULE_LICENSE("GPL");
@@ -186,7 +183,6 @@ static void deregister_from_lirc(struct sasem_context *context)
else
dev_info(&context->dev->dev,
"Deregistered Sasem driver (minor:%d)\n", minor);
-
}
/**
@@ -243,7 +239,7 @@ exit:
* Called when the VFD device (e.g. /dev/usb/lcd)
* is closed by the application.
*/
-static long vfd_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+static long vfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct sasem_context *context;
@@ -297,7 +293,6 @@ static int vfd_close(struct inode *inode, struct file *file)
context->vfd_isopen = 0;
dev_info(&context->dev->dev, "VFD port closed\n");
if (!context->dev_present && !context->ir_isopen) {
-
/* Device disconnected before close and IR port is
* not open. If IR port is open, context will be
* deleted by ir_close. */
@@ -546,9 +541,7 @@ static void ir_close(void *data)
* at disconnect time, so do it now.
*/
deregister_from_lirc(context);
-
if (!context->vfd_isopen) {
-
mutex_unlock(&context->ctx_lock);
delete_context(context);
return;
@@ -633,7 +626,6 @@ static void usb_rx_callback(struct urb *urb)
return;
switch (urb->status) {
-
case -ENOENT: /* usbcore unlink successful! */
return;
@@ -651,8 +643,6 @@ static void usb_rx_callback(struct urb *urb)
usb_submit_urb(context->rx_urb, GFP_ATOMIC);
}
-
-
/**
* Callback function for USB core API: Probe
*/
@@ -709,7 +699,6 @@ static int sasem_probe(struct usb_interface *interface,
} else if (!vfd_ep_found &&
usb_endpoint_is_int_out(ep)) {
-
tx_endpoint = ep;
vfd_ep_found = 1;
if (debug)
@@ -735,17 +724,17 @@ static int sasem_probe(struct usb_interface *interface,
/* Allocate memory */
alloc_status = 0;
- context = kzalloc(sizeof(struct sasem_context), GFP_KERNEL);
+ context = kzalloc(sizeof(*context), GFP_KERNEL);
if (!context) {
alloc_status = 1;
goto alloc_status_switch;
}
- driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
+ driver = kzalloc(sizeof(*driver), GFP_KERNEL);
if (!driver) {
alloc_status = 2;
goto alloc_status_switch;
}
- rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
+ rbuf = kmalloc(sizeof(*rbuf), GFP_KERNEL);
if (!rbuf) {
alloc_status = 3;
goto alloc_status_switch;
@@ -758,17 +747,12 @@ static int sasem_probe(struct usb_interface *interface,
}
rx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!rx_urb) {
- dev_err(&interface->dev,
- "%s: usb_alloc_urb failed for IR urb\n", __func__);
alloc_status = 5;
goto alloc_status_switch;
}
if (vfd_ep_found) {
tx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!tx_urb) {
- dev_err(&interface->dev,
- "%s: usb_alloc_urb failed for VFD urb",
- __func__);
alloc_status = 6;
goto alloc_status_switch;
}
diff --git a/drivers/staging/most/Documentation/ABI/sysfs-class-most.txt b/drivers/staging/most/Documentation/ABI/sysfs-class-most.txt
index 42ff0d8b2ead..48aa45acc953 100644
--- a/drivers/staging/most/Documentation/ABI/sysfs-class-most.txt
+++ b/drivers/staging/most/Documentation/ABI/sysfs-class-most.txt
@@ -51,6 +51,140 @@ Description:
uses.
Users:
+What: /sys/class/most/mostcore/devices/<mdev>/dci
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ If the network interface controller is attached via USB, a dci
+ directory is created that allows applications to use the
+ controller's direct communication interface (DCI) to exchange
+ information.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/arb_address
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ This is used to set an arbitrary DCI register address an
+ application wants to read from or write to.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/arb_value
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ This is used to read from or write to the arbitrary DCI register
+ whose address is stored in arb_address.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/mep_eui48_hi
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ This is used to check and configure the MAC address.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/mep_eui48_lo
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ This is used to check and configure the MAC address.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/mep_eui48_mi
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ This is used to check and configure the MAC address.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/mep_filter
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ This is used to check and configure the MEP filter address.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/mep_hash0
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ This is used to check and configure the MEP hash table.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/mep_hash1
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ This is used to check and configure the MEP hash table.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/mep_hash2
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ This is used to check and configure the MEP hash table.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/mep_hash3
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ This is used to check and configure the MEP hash table.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/ni_state
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ Indicates the current network interface state.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/node_address
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ Indicates the current node address.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/node_position
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ Indicates the current node position.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/packet_bandwidth
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ Indicates the configured packet bandwidth.
+Users:
+
+What: /sys/class/most/mostcore/devices/<mdev>/dci/sync_ep
+Date: June 2016
+KernelVersion: 4.9
+Contact: Christian Gromm <christian.gromm@microchip.com>
+Description:
+ Triggers the controller's synchronization process for a certain
+ endpoint.
+Users:
+
What: /sys/class/most/mostcore/devices/<mdev>/<channel>/
Date: June 2015
KernelVersion: 4.3
diff --git a/drivers/staging/most/aim-cdev/cdev.c b/drivers/staging/most/aim-cdev/cdev.c
index de4f76abfb47..7f51024dc5eb 100644
--- a/drivers/staging/most/aim-cdev/cdev.c
+++ b/drivers/staging/most/aim-cdev/cdev.c
@@ -57,7 +57,11 @@ static inline bool ch_has_mbo(struct aim_channel *c)
static inline bool ch_get_mbo(struct aim_channel *c, struct mbo **mbo)
{
- *mbo = most_get_mbo(c->iface, c->channel_id, &cdev_aim);
+ if (!kfifo_peek(&c->fifo, mbo)) {
+ *mbo = most_get_mbo(c->iface, c->channel_id, &cdev_aim);
+ if (*mbo)
+ kfifo_in(&c->fifo, mbo, 1);
+ }
return *mbo;
}
@@ -130,7 +134,7 @@ static int aim_open(struct inode *inode, struct file *filp)
if (!c->dev) {
pr_info("WARN: Device is destroyed\n");
mutex_unlock(&c->io_mutex);
- return -EBUSY;
+ return -ENODEV;
}
if (c->access_ref) {
@@ -184,8 +188,7 @@ static ssize_t aim_write(struct file *filp, const char __user *buf,
size_t count, loff_t *offset)
{
int ret;
- size_t actual_len;
- size_t max_len;
+ size_t to_copy, left;
struct mbo *mbo = NULL;
struct aim_channel *c = filp->private_data;
@@ -201,27 +204,28 @@ static ssize_t aim_write(struct file *filp, const char __user *buf,
}
if (unlikely(!c->dev)) {
- ret = -EPIPE;
+ ret = -ENODEV;
goto unlock;
}
- max_len = c->cfg->buffer_size;
- actual_len = min(count, max_len);
- mbo->buffer_length = actual_len;
-
- if (copy_from_user(mbo->virt_address, buf, mbo->buffer_length)) {
+ to_copy = min(count, c->cfg->buffer_size - c->mbo_offs);
+ left = copy_from_user(mbo->virt_address + c->mbo_offs, buf, to_copy);
+ if (left == to_copy) {
ret = -EFAULT;
- goto put_mbo;
+ goto unlock;
}
- ret = most_submit_mbo(mbo);
- if (ret)
- goto put_mbo;
+ c->mbo_offs += to_copy - left;
+ if (c->mbo_offs >= c->cfg->buffer_size ||
+ c->cfg->data_type == MOST_CH_CONTROL ||
+ c->cfg->data_type == MOST_CH_ASYNC) {
+ kfifo_skip(&c->fifo);
+ mbo->buffer_length = c->mbo_offs;
+ c->mbo_offs = 0;
+ most_submit_mbo(mbo);
+ }
- mutex_unlock(&c->io_mutex);
- return actual_len;
-put_mbo:
- most_put_mbo(mbo);
+ ret = to_copy - left;
unlock:
mutex_unlock(&c->io_mutex);
return ret;
@@ -256,7 +260,7 @@ aim_read(struct file *filp, char __user *buf, size_t count, loff_t *offset)
/* make sure we don't submit to gone devices */
if (unlikely(!c->dev)) {
mutex_unlock(&c->io_mutex);
- return -EIO;
+ return -ENODEV;
}
to_copy = min_t(size_t,
@@ -290,7 +294,7 @@ static unsigned int aim_poll(struct file *filp, poll_table *wait)
if (!kfifo_is_empty(&c->fifo))
mask |= POLLIN | POLLRDNORM;
} else {
- if (ch_has_mbo(c))
+ if (!kfifo_is_empty(&c->fifo) || ch_has_mbo(c))
mask |= POLLOUT | POLLWRNORM;
}
return mask;
@@ -366,7 +370,7 @@ static int aim_rx_completion(struct mbo *mbo)
spin_lock(&c->unlink);
if (!c->access_ref || !c->dev) {
spin_unlock(&c->unlink);
- return -EFAULT;
+ return -ENODEV;
}
kfifo_in(&c->fifo, &mbo, 1);
spin_unlock(&c->unlink);
@@ -499,23 +503,27 @@ static struct most_aim cdev_aim = {
static int __init mod_init(void)
{
+ int err;
+
pr_info("init()\n");
INIT_LIST_HEAD(&channel_list);
spin_lock_init(&ch_list_lock);
ida_init(&minor_id);
- if (alloc_chrdev_region(&aim_devno, 0, 50, "cdev") < 0)
- return -EIO;
+ err = alloc_chrdev_region(&aim_devno, 0, 50, "cdev");
+ if (err < 0)
+ goto dest_ida;
major = MAJOR(aim_devno);
aim_class = class_create(THIS_MODULE, "most_cdev_aim");
if (IS_ERR(aim_class)) {
pr_err("no udev support\n");
+ err = PTR_ERR(aim_class);
goto free_cdev;
}
-
- if (most_register_aim(&cdev_aim))
+ err = most_register_aim(&cdev_aim);
+ if (err)
goto dest_class;
return 0;
@@ -523,7 +531,9 @@ dest_class:
class_destroy(aim_class);
free_cdev:
unregister_chrdev_region(aim_devno, 1);
- return -EIO;
+dest_ida:
+ ida_destroy(&minor_id);
+ return err;
}
static void __exit mod_exit(void)
diff --git a/drivers/staging/most/aim-network/networking.c b/drivers/staging/most/aim-network/networking.c
index 2f42de44d051..4659a6450c04 100644
--- a/drivers/staging/most/aim-network/networking.c
+++ b/drivers/staging/most/aim-network/networking.c
@@ -298,15 +298,16 @@ static struct net_dev_context *get_net_dev_context(
struct most_interface *iface)
{
struct net_dev_context *nd, *tmp;
+ unsigned long flags;
- spin_lock(&list_lock);
+ spin_lock_irqsave(&list_lock, flags);
list_for_each_entry_safe(nd, tmp, &net_devices, list) {
if (nd->iface == iface) {
- spin_unlock(&list_lock);
+ spin_unlock_irqrestore(&list_lock, flags);
return nd;
}
}
- spin_unlock(&list_lock);
+ spin_unlock_irqrestore(&list_lock, flags);
return NULL;
}
@@ -316,6 +317,7 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx,
{
struct net_dev_context *nd;
struct net_dev_channel *ch;
+ unsigned long flags;
if (!iface)
return -EINVAL;
@@ -332,9 +334,9 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx,
nd->iface = iface;
- spin_lock(&list_lock);
+ spin_lock_irqsave(&list_lock, flags);
list_add(&nd->list, &net_devices);
- spin_unlock(&list_lock);
+ spin_unlock_irqrestore(&list_lock, flags);
}
ch = ccfg->direction == MOST_CH_TX ? &nd->tx : &nd->rx;
@@ -377,6 +379,7 @@ static int aim_disconnect_channel(struct most_interface *iface,
{
struct net_dev_context *nd;
struct net_dev_channel *ch;
+ unsigned long flags;
nd = get_net_dev_context(iface);
if (!nd)
@@ -398,9 +401,9 @@ static int aim_disconnect_channel(struct most_interface *iface,
most_net_rm_netdev_safe(nd);
if (!nd->rx.linked && !nd->tx.linked) {
- spin_lock(&list_lock);
+ spin_lock_irqsave(&list_lock, flags);
list_del(&nd->list);
- spin_unlock(&list_lock);
+ spin_unlock_irqrestore(&list_lock, flags);
kfree(nd);
}
@@ -514,20 +517,21 @@ static int __init most_net_init(void)
static void __exit most_net_exit(void)
{
struct net_dev_context *nd, *tmp;
+ unsigned long flags;
- spin_lock(&list_lock);
+ spin_lock_irqsave(&list_lock, flags);
list_for_each_entry_safe(nd, tmp, &net_devices, list) {
list_del(&nd->list);
- spin_unlock(&list_lock);
+ spin_unlock_irqrestore(&list_lock, flags);
/*
* do not call most_stop_channel() here, because channels are
* going to be closed in ndo_stop() after unregister_netdev()
*/
most_net_rm_netdev_safe(nd);
kfree(nd);
- spin_lock(&list_lock);
+ spin_lock_irqsave(&list_lock, flags);
}
- spin_unlock(&list_lock);
+ spin_unlock_irqrestore(&list_lock, flags);
most_deregister_aim(&aim);
pr_info("most_net_exit()\n");
diff --git a/drivers/staging/most/aim-sound/sound.c b/drivers/staging/most/aim-sound/sound.c
index 9c645801cff4..e4198e5e064b 100644
--- a/drivers/staging/most/aim-sound/sound.c
+++ b/drivers/staging/most/aim-sound/sound.c
@@ -234,7 +234,6 @@ static int playback_thread(void *data)
while (!kthread_should_stop()) {
struct mbo *mbo = NULL;
bool period_elapsed = false;
- int ret;
wait_event_interruptible(
channel->playback_waitq,
@@ -250,10 +249,7 @@ static int playback_thread(void *data)
else
memset(mbo->virt_address, 0, mbo->buffer_length);
- ret = most_submit_mbo(mbo);
- if (ret)
- channel->is_stream_running = false;
-
+ most_submit_mbo(mbo);
if (period_elapsed)
snd_pcm_period_elapsed(channel->substream);
}
@@ -457,7 +453,7 @@ static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream)
/**
* Initialization of struct snd_pcm_ops
*/
-static struct snd_pcm_ops pcm_ops = {
+static const struct snd_pcm_ops pcm_ops = {
.open = pcm_open,
.close = pcm_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -611,7 +607,8 @@ static int audio_probe_channel(struct most_interface *iface, int channel_id,
channel->id = channel_id;
init_waitqueue_head(&channel->playback_waitq);
- if (audio_set_hw_params(&channel->pcm_hardware, pcm_format, cfg))
+ ret = audio_set_hw_params(&channel->pcm_hardware, pcm_format, cfg);
+ if (ret)
goto err_free_card;
snprintf(card->driver, sizeof(card->driver), "%s", DRIVER_NAME);
diff --git a/drivers/staging/most/aim-v4l2/video.c b/drivers/staging/most/aim-v4l2/video.c
index 13abf7c275a4..e0748416aee5 100644
--- a/drivers/staging/most/aim-v4l2/video.c
+++ b/drivers/staging/most/aim-v4l2/video.c
@@ -79,7 +79,7 @@ static int aim_vdev_open(struct file *filp)
struct most_video_dev *mdev = video_drvdata(filp);
struct aim_fh *fh;
- pr_info("aim_vdev_open()\n");
+ v4l2_info(&mdev->v4l2_dev, "aim_vdev_open()\n");
switch (vdev->vfl_type) {
case VFL_TYPE_GRABBER:
@@ -93,7 +93,7 @@ static int aim_vdev_open(struct file *filp)
return -ENOMEM;
if (!atomic_inc_and_test(&mdev->access_ref)) {
- pr_err("too many clients\n");
+ v4l2_err(&mdev->v4l2_dev, "too many clients\n");
ret = -EBUSY;
goto err_dec;
}
@@ -106,7 +106,7 @@ static int aim_vdev_open(struct file *filp)
ret = most_start_channel(mdev->iface, mdev->ch_idx, &aim_info);
if (ret) {
- pr_err("most_start_channel() failed\n");
+ v4l2_err(&mdev->v4l2_dev, "most_start_channel() failed\n");
goto err_rm;
}
@@ -128,7 +128,7 @@ static int aim_vdev_close(struct file *filp)
struct most_video_dev *mdev = fh->mdev;
struct mbo *mbo, *tmp;
- pr_info("aim_vdev_close()\n");
+ v4l2_info(&mdev->v4l2_dev, "aim_vdev_close()\n");
/*
* We need to put MBOs back before we call most_stop_channel()
@@ -139,15 +139,15 @@ static int aim_vdev_close(struct file *filp)
* This must be implemented in core.
*/
- spin_lock(&mdev->list_lock);
+ spin_lock_irq(&mdev->list_lock);
mdev->mute = true;
list_for_each_entry_safe(mbo, tmp, &mdev->pending_mbos, list) {
list_del(&mbo->list);
- spin_unlock(&mdev->list_lock);
+ spin_unlock_irq(&mdev->list_lock);
most_put_mbo(mbo);
- spin_lock(&mdev->list_lock);
+ spin_lock_irq(&mdev->list_lock);
}
- spin_unlock(&mdev->list_lock);
+ spin_unlock_irq(&mdev->list_lock);
most_stop_channel(mdev->iface, mdev->ch_idx, &aim_info);
mdev->mute = false;
@@ -187,7 +187,7 @@ static ssize_t aim_vdev_read(struct file *filp, char __user *buf,
int const cnt = rem < count ? rem : count;
if (copy_to_user(buf, mbo->virt_address + fh->offs, cnt)) {
- pr_err("read: copy_to_user failed\n");
+ v4l2_err(&mdev->v4l2_dev, "read: copy_to_user failed\n");
if (!ret)
ret = -EFAULT;
return ret;
@@ -200,9 +200,9 @@ static ssize_t aim_vdev_read(struct file *filp, char __user *buf,
if (cnt >= rem) {
fh->offs = 0;
- spin_lock(&mdev->list_lock);
+ spin_lock_irq(&mdev->list_lock);
list_del(&mbo->list);
- spin_unlock(&mdev->list_lock);
+ spin_unlock_irq(&mdev->list_lock);
most_put_mbo(mbo);
}
}
@@ -250,16 +250,16 @@ static int aim_set_format(struct most_video_dev *mdev, unsigned int cmd,
return 0;
}
-static int vidioc_querycap(struct file *file, void *priv,
+static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
struct aim_fh *fh = priv;
struct most_video_dev *mdev = fh->mdev;
- pr_info("vidioc_querycap()\n");
+ v4l2_info(&mdev->v4l2_dev, "vidioc_querycap()\n");
strlcpy(cap->driver, "v4l2_most_aim", sizeof(cap->driver));
- strlcpy(cap->card, "my_card", sizeof(cap->card));
+ strlcpy(cap->card, "MOST", sizeof(cap->card));
snprintf(cap->bus_info, sizeof(cap->bus_info),
"%s", mdev->iface->description);
@@ -270,10 +270,13 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0;
}
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- pr_info("vidioc_enum_fmt_vid_cap() %d\n", f->index);
+ struct aim_fh *fh = priv;
+ struct most_video_dev *mdev = fh->mdev;
+
+ v4l2_info(&mdev->v4l2_dev, "vidioc_enum_fmt_vid_cap() %d\n", f->index);
if (f->index)
return -EINVAL;
@@ -289,7 +292,10 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- pr_info("vidioc_g_fmt_vid_cap()\n");
+ struct aim_fh *fh = priv;
+ struct most_video_dev *mdev = fh->mdev;
+
+ v4l2_info(&mdev->v4l2_dev, "vidioc_g_fmt_vid_cap()\n");
aim_set_format_struct(f);
return 0;
@@ -298,7 +304,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct aim_fh *fh = priv;
+ struct aim_fh *fh = priv;
struct most_video_dev *mdev = fh->mdev;
return aim_set_format(mdev, VIDIOC_TRY_FMT, f);
@@ -307,7 +313,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct aim_fh *fh = priv;
+ struct aim_fh *fh = priv;
struct most_video_dev *mdev = fh->mdev;
return aim_set_format(mdev, VIDIOC_S_FMT, f);
@@ -315,7 +321,10 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
{
- pr_info("vidioc_g_std()\n");
+ struct aim_fh *fh = priv;
+ struct most_video_dev *mdev = fh->mdev;
+
+ v4l2_info(&mdev->v4l2_dev, "vidioc_g_std()\n");
*norm = V4L2_STD_UNKNOWN;
return 0;
@@ -352,7 +361,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
struct aim_fh *fh = priv;
struct most_video_dev *mdev = fh->mdev;
- pr_info("vidioc_s_input(%d)\n", index);
+ v4l2_info(&mdev->v4l2_dev, "vidioc_s_input(%d)\n", index);
if (index >= V4L2_AIM_MAX_INPUT)
return -EINVAL;
@@ -360,7 +369,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
return 0;
}
-static struct v4l2_file_operations aim_fops = {
+static const struct v4l2_file_operations aim_fops = {
.owner = THIS_MODULE,
.open = aim_vdev_open,
.release = aim_vdev_close,
@@ -393,45 +402,46 @@ static const struct video_device aim_videodev_template = {
static struct most_video_dev *get_aim_dev(
struct most_interface *iface, int channel_idx)
{
- struct most_video_dev *mdev, *tmp;
+ struct most_video_dev *mdev;
+ unsigned long flags;
- spin_lock(&list_lock);
- list_for_each_entry_safe(mdev, tmp, &video_devices, list) {
+ spin_lock_irqsave(&list_lock, flags);
+ list_for_each_entry(mdev, &video_devices, list) {
if (mdev->iface == iface && mdev->ch_idx == channel_idx) {
- spin_unlock(&list_lock);
+ spin_unlock_irqrestore(&list_lock, flags);
return mdev;
}
}
- spin_unlock(&list_lock);
+ spin_unlock_irqrestore(&list_lock, flags);
return NULL;
}
static int aim_rx_data(struct mbo *mbo)
{
+ unsigned long flags;
struct most_video_dev *mdev =
get_aim_dev(mbo->ifp, mbo->hdm_channel_id);
if (!mdev)
return -EIO;
- spin_lock(&mdev->list_lock);
+ spin_lock_irqsave(&mdev->list_lock, flags);
if (unlikely(mdev->mute)) {
- spin_unlock(&mdev->list_lock);
+ spin_unlock_irqrestore(&mdev->list_lock, flags);
return -EIO;
}
list_add_tail(&mbo->list, &mdev->pending_mbos);
- spin_unlock(&mdev->list_lock);
+ spin_unlock_irqrestore(&mdev->list_lock, flags);
wake_up_interruptible(&mdev->wait_data);
return 0;
}
static int aim_register_videodev(struct most_video_dev *mdev)
{
- int retval = -ENOMEM;
int ret;
- pr_info("aim_register_videodev()\n");
+ v4l2_info(&mdev->v4l2_dev, "aim_register_videodev()\n");
init_waitqueue_head(&mdev->wait_data);
@@ -444,27 +454,24 @@ static int aim_register_videodev(struct most_video_dev *mdev)
*mdev->vdev = aim_videodev_template;
mdev->vdev->v4l2_dev = &mdev->v4l2_dev;
mdev->vdev->lock = &mdev->lock;
- strcpy(mdev->vdev->name, "most v4l2 aim video");
+ snprintf(mdev->vdev->name, sizeof(mdev->vdev->name), "MOST: %s",
+ mdev->v4l2_dev.name);
/* Register the v4l2 device */
video_set_drvdata(mdev->vdev, mdev);
- retval = video_register_device(mdev->vdev, VFL_TYPE_GRABBER, -1);
- if (retval != 0) {
- pr_err("video_register_device failed (%d)\n", retval);
- ret = -ENODEV;
- goto err_vbi_dev;
+ ret = video_register_device(mdev->vdev, VFL_TYPE_GRABBER, -1);
+ if (ret) {
+ v4l2_err(&mdev->v4l2_dev, "video_register_device failed (%d)\n",
+ ret);
+ video_device_release(mdev->vdev);
}
- return 0;
-
-err_vbi_dev:
- video_device_release(mdev->vdev);
return ret;
}
static void aim_unregister_videodev(struct most_video_dev *mdev)
{
- pr_info("aim_unregister_videodev()\n");
+ v4l2_info(&mdev->v4l2_dev, "aim_unregister_videodev()\n");
video_unregister_device(mdev->vdev);
}
@@ -485,7 +492,7 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx,
int ret;
struct most_video_dev *mdev = get_aim_dev(iface, channel_idx);
- pr_info("aim_probe_channel()\n");
+ pr_info("aim_probe_channel(%s)\n", name);
if (mdev) {
pr_err("channel already linked\n");
@@ -498,8 +505,8 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx,
}
if (ccfg->data_type != MOST_CH_SYNC &&
- ccfg->data_type != MOST_CH_ISOC_AVP) {
- pr_err("wrong channel type, expect sync or isoc_avp\n");
+ ccfg->data_type != MOST_CH_ISOC) {
+ pr_err("wrong channel type, expect sync or isoc\n");
return -EINVAL;
}
@@ -516,8 +523,7 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx,
mdev->v4l2_dev.release = aim_v4l2_dev_release;
/* Create the v4l2_device */
- strlcpy(mdev->v4l2_dev.name, "most_video_device",
- sizeof(mdev->v4l2_dev.name));
+ strlcpy(mdev->v4l2_dev.name, name, sizeof(mdev->v4l2_dev.name));
ret = v4l2_device_register(NULL, &mdev->v4l2_dev);
if (ret) {
pr_err("v4l2_device_register() failed\n");
@@ -529,9 +535,10 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx,
if (ret)
goto err_unreg;
- spin_lock(&list_lock);
+ spin_lock_irq(&list_lock);
list_add(&mdev->list, &video_devices);
- spin_unlock(&list_lock);
+ spin_unlock_irq(&list_lock);
+ v4l2_info(&mdev->v4l2_dev, "aim_probe_channel() done\n");
return 0;
err_unreg:
@@ -545,16 +552,16 @@ static int aim_disconnect_channel(struct most_interface *iface,
{
struct most_video_dev *mdev = get_aim_dev(iface, channel_idx);
- pr_info("aim_disconnect_channel()\n");
-
if (!mdev) {
pr_err("no such channel is linked\n");
return -ENOENT;
}
- spin_lock(&list_lock);
+ v4l2_info(&mdev->v4l2_dev, "aim_disconnect_channel()\n");
+
+ spin_lock_irq(&list_lock);
list_del(&mdev->list);
- spin_unlock(&list_lock);
+ spin_unlock_irq(&list_lock);
aim_unregister_videodev(mdev);
v4l2_device_disconnect(&mdev->v4l2_dev);
@@ -585,17 +592,17 @@ static void __exit aim_exit(void)
* we simulate this call here.
* This must be fixed in core.
*/
- spin_lock(&list_lock);
+ spin_lock_irq(&list_lock);
list_for_each_entry_safe(mdev, tmp, &video_devices, list) {
list_del(&mdev->list);
- spin_unlock(&list_lock);
+ spin_unlock_irq(&list_lock);
aim_unregister_videodev(mdev);
v4l2_device_disconnect(&mdev->v4l2_dev);
v4l2_device_put(&mdev->v4l2_dev);
- spin_lock(&list_lock);
+ spin_lock_irq(&list_lock);
}
- spin_unlock(&list_lock);
+ spin_unlock_irq(&list_lock);
most_deregister_aim(&aim_info);
BUG_ON(!list_empty(&video_devices));
diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c
index 3c524506ee22..0b9816ce1761 100644
--- a/drivers/staging/most/hdm-dim2/dim2_hal.c
+++ b/drivers/staging/most/hdm-dim2/dim2_hal.c
@@ -2,7 +2,7 @@
* dim2_hal.c - DIM2 HAL implementation
* (MediaLB, Device Interface Macro IP, OS62420)
*
- * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG
+ * Copyright (C) 2015-2016, Microchip Technology Germany II GmbH & Co. KG
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -20,18 +20,6 @@
#include <linux/stddef.h>
/*
- * The number of frames per sub-buffer for synchronous channels.
- * Allowed values: 1, 2, 4, 8, 16, 32, 64.
- */
-#define FRAMES_PER_SUBBUFF 16
-
-/*
- * Size factor for synchronous DBR buffer.
- * Minimal value is 4*FRAMES_PER_SUBBUFF.
- */
-#define SYNC_DBR_FACTOR (4u * (u16)FRAMES_PER_SUBBUFF)
-
-/*
* Size factor for isochronous DBR buffer.
* Minimal value is 3.
*/
@@ -61,12 +49,11 @@
#define DBR_SIZE (16 * 1024) /* specified by IP */
#define DBR_BLOCK_SIZE (DBR_SIZE / 32 / DBR_MAP_SIZE)
+#define ROUND_UP_TO(x, d) (((x) + (d) - 1) / (d) * (d))
+
/* -------------------------------------------------------------------------- */
/* generic helper functions and macros */
-#define MLBC0_FCNT_VAL_MACRO(n) MLBC0_FCNT_VAL_ ## n ## FPSB
-#define MLBC0_FCNT_VAL(fpsb) MLBC0_FCNT_VAL_MACRO(fpsb)
-
static inline u32 bit_mask(u8 position)
{
return (u32)1 << position;
@@ -81,10 +68,20 @@ static inline bool dim_on_error(u8 error_id, const char *error_message)
/* -------------------------------------------------------------------------- */
/* types and local variables */
+struct async_tx_dbr {
+ u8 ch_addr;
+ u16 rpc;
+ u16 wpc;
+ u16 rest_size;
+ u16 sz_queue[CDT0_RPC_MASK + 1];
+};
+
struct lld_global_vars_t {
bool dim_is_initialized;
bool mcm_is_initialized;
struct dim2_regs __iomem *dim2; /* DIM2 core base address */
+ struct async_tx_dbr atx_dbr;
+ u32 fcnt;
u32 dbr_map[DBR_MAP_SIZE];
};
@@ -149,15 +146,34 @@ static void free_dbr(int offs, int size)
/* -------------------------------------------------------------------------- */
-static u32 dim2_read_ctr(u32 ctr_addr, u16 mdat_idx)
+static void dim2_transfer_madr(u32 val)
{
- dimcb_io_write(&g.dim2->MADR, ctr_addr);
+ dimcb_io_write(&g.dim2->MADR, val);
- /* wait till transfer is completed */
+ /* wait for transfer completion */
while ((dimcb_io_read(&g.dim2->MCTL) & 1) != 1)
continue;
dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */
+}
+
+static void dim2_clear_dbr(u16 addr, u16 size)
+{
+ enum { MADR_TB_BIT = 30, MADR_WNR_BIT = 31 };
+
+ u16 const end_addr = addr + size;
+ u32 const cmd = bit_mask(MADR_WNR_BIT) | bit_mask(MADR_TB_BIT);
+
+ dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */
+ dimcb_io_write(&g.dim2->MDAT0, 0);
+
+ for (; addr < end_addr; addr++)
+ dim2_transfer_madr(cmd | addr);
+}
+
+static u32 dim2_read_ctr(u32 ctr_addr, u16 mdat_idx)
+{
+ dim2_transfer_madr(ctr_addr);
return dimcb_io_read((&g.dim2->MDAT0) + mdat_idx);
}
@@ -182,13 +198,7 @@ static void dim2_write_ctr_mask(u32 ctr_addr, const u32 *mask, const u32 *value)
dimcb_io_write(&g.dim2->MDWE2, mask[2]);
dimcb_io_write(&g.dim2->MDWE3, mask[3]);
- dimcb_io_write(&g.dim2->MADR, bit_mask(MADR_WNR_BIT) | ctr_addr);
-
- /* wait till transfer is completed */
- while ((dimcb_io_read(&g.dim2->MCTL) & 1) != 1)
- continue;
-
- dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */
+ dim2_transfer_madr(bit_mask(MADR_WNR_BIT) | ctr_addr);
}
static inline void dim2_write_ctr(u32 ctr_addr, const u32 *value)
@@ -252,6 +262,13 @@ static void dim2_configure_cdt(u8 ch_addr, u16 dbr_address, u16 hw_buffer_size,
dim2_write_ctr(CDT + ch_addr, cdt);
}
+static u16 dim2_rpc(u8 ch_addr)
+{
+ u32 cdt0 = dim2_read_ctr(CDT + ch_addr, 0);
+
+ return (cdt0 >> CDT0_RPC_SHIFT) & CDT0_RPC_MASK;
+}
+
static void dim2_clear_cdt(u8 ch_addr)
{
u32 cdt[4] = { 0, 0, 0, 0 };
@@ -356,6 +373,52 @@ static void dim2_clear_channel(u8 ch_addr)
dim2_clear_cat(MLB_CAT, ch_addr);
dim2_clear_cdt(ch_addr);
+
+ /* clear channel status bit */
+ dimcb_io_write(&g.dim2->ACSR0, bit_mask(ch_addr));
+}
+
+/* -------------------------------------------------------------------------- */
+/* trace async tx dbr fill state */
+
+static inline u16 norm_pc(u16 pc)
+{
+ return pc & CDT0_RPC_MASK;
+}
+
+static void dbrcnt_init(u8 ch_addr, u16 dbr_size)
+{
+ g.atx_dbr.rest_size = dbr_size;
+ g.atx_dbr.rpc = dim2_rpc(ch_addr);
+ g.atx_dbr.wpc = g.atx_dbr.rpc;
+}
+
+static void dbrcnt_enq(int buf_sz)
+{
+ g.atx_dbr.rest_size -= buf_sz;
+ g.atx_dbr.sz_queue[norm_pc(g.atx_dbr.wpc)] = buf_sz;
+ g.atx_dbr.wpc++;
+}
+
+u16 dim_dbr_space(struct dim_channel *ch)
+{
+ u16 cur_rpc;
+ struct async_tx_dbr *dbr = &g.atx_dbr;
+
+ if (ch->addr != dbr->ch_addr)
+ return 0xFFFF;
+
+ cur_rpc = dim2_rpc(ch->addr);
+
+ while (norm_pc(dbr->rpc) != cur_rpc) {
+ dbr->rest_size += dbr->sz_queue[norm_pc(dbr->rpc)];
+ dbr->rpc++;
+ }
+
+ if ((u16)(dbr->wpc - dbr->rpc) >= CDT0_RPC_MASK)
+ return 0;
+
+ return dbr->rest_size;
}
/* -------------------------------------------------------------------------- */
@@ -398,7 +461,8 @@ static inline bool check_packet_length(u32 packet_length)
static inline bool check_bytes_per_frame(u32 bytes_per_frame)
{
- u16 const max_size = ((u16)CDT3_BD_MASK + 1u) / SYNC_DBR_FACTOR;
+ u16 const bd_factor = g.fcnt + 2;
+ u16 const max_size = ((u16)CDT3_BD_MASK + 1u) >> bd_factor;
if (bytes_per_frame <= 0)
return false; /* too small */
@@ -439,7 +503,7 @@ static inline u16 norm_sync_buffer_size(u16 buf_size, u16 bytes_per_frame)
{
u16 n;
u16 const max_size = (u16)ADT1_ISOC_SYNC_BD_MASK + 1u;
- u32 const unit = bytes_per_frame * (u16)FRAMES_PER_SUBBUFF;
+ u32 const unit = bytes_per_frame << g.fcnt;
if (buf_size > max_size)
buf_size = max_size;
@@ -479,7 +543,7 @@ static void dim2_initialize(bool enable_6pin, u8 mlb_clock)
dimcb_io_write(&g.dim2->MLBC0,
enable_6pin << MLBC0_MLBPEN_BIT |
mlb_clock << MLBC0_MLBCLK_SHIFT |
- MLBC0_FCNT_VAL(FRAMES_PER_SUBBUFF) << MLBC0_FCNT_SHIFT |
+ g.fcnt << MLBC0_FCNT_SHIFT |
true << MLBC0_MLBEN_BIT);
/* activate all HBI channels */
@@ -515,20 +579,17 @@ static inline bool service_channel(u8 ch_addr, u8 idx)
{
u8 const shift = idx * 16;
u32 const adt1 = dim2_read_ctr(ADT + ch_addr, 1);
+ u32 mask[4] = { 0, 0, 0, 0 };
+ u32 adt_w[4] = { 0, 0, 0, 0 };
if (((adt1 >> (ADT1_DNE_BIT + shift)) & 1) == 0)
return false;
- {
- u32 mask[4] = { 0, 0, 0, 0 };
- u32 adt_w[4] = { 0, 0, 0, 0 };
-
- mask[1] =
- bit_mask(ADT1_DNE_BIT + shift) |
- bit_mask(ADT1_ERR_BIT + shift) |
- bit_mask(ADT1_RDY_BIT + shift);
- dim2_write_ctr_mask(ADT + ch_addr, mask, adt_w);
- }
+ mask[1] =
+ bit_mask(ADT1_DNE_BIT + shift) |
+ bit_mask(ADT1_ERR_BIT + shift) |
+ bit_mask(ADT1_RDY_BIT + shift);
+ dim2_write_ctr_mask(ADT + ch_addr, mask, adt_w);
/* clear channel status bit */
dimcb_io_write(&g.dim2->ACSR0, bit_mask(ch_addr));
@@ -612,6 +673,9 @@ static bool channel_start(struct dim_channel *ch, u32 buf_addr, u16 buf_size)
++state->level;
+ if (ch->addr == g.atx_dbr.ch_addr)
+ dbrcnt_enq(buf_size);
+
if (ch->packet_length || ch->bytes_per_frame)
dim2_start_isoc_sync(ch->addr, state->idx1, buf_addr, buf_size);
else
@@ -650,7 +714,8 @@ static bool channel_detach_buffers(struct dim_channel *ch, u16 buffers_number)
/* -------------------------------------------------------------------------- */
/* API */
-u8 dim_startup(struct dim2_regs __iomem *dim_base_address, u32 mlb_clock)
+u8 dim_startup(struct dim2_regs __iomem *dim_base_address, u32 mlb_clock,
+ u32 fcnt)
{
g.dim_is_initialized = false;
@@ -662,7 +727,11 @@ u8 dim_startup(struct dim2_regs __iomem *dim_base_address, u32 mlb_clock)
if (mlb_clock >= 8)
return DIM_INIT_ERR_MLB_CLOCK;
+ if (fcnt > MLBC0_FCNT_MAX_VAL)
+ return DIM_INIT_ERR_MLB_CLOCK;
+
g.dim2 = dim_base_address;
+ g.fcnt = fcnt;
g.dbr_map[0] = 0;
g.dbr_map[1] = 0;
@@ -693,7 +762,7 @@ static u8 init_ctrl_async(struct dim_channel *ch, u8 type, u8 is_tx,
if (!check_channel_address(ch_address))
return DIM_INIT_ERR_CHANNEL_ADDRESS;
- ch->dbr_size = hw_buffer_size;
+ ch->dbr_size = ROUND_UP_TO(hw_buffer_size, DBR_BLOCK_SIZE);
ch->dbr_addr = alloc_dbr(ch->dbr_size);
if (ch->dbr_addr >= DBR_SIZE)
return DIM_INIT_ERR_OUT_OF_MEMORY;
@@ -706,6 +775,12 @@ static u8 init_ctrl_async(struct dim_channel *ch, u8 type, u8 is_tx,
return DIM_NO_ERROR;
}
+void dim_service_mlb_int_irq(void)
+{
+ dimcb_io_write(&g.dim2->MS0, 0);
+ dimcb_io_write(&g.dim2->MS1, 0);
+}
+
u16 dim_norm_ctrl_async_buffer_size(u16 buf_size)
{
return norm_ctrl_async_buffer_size(buf_size);
@@ -749,8 +824,16 @@ u8 dim_init_control(struct dim_channel *ch, u8 is_tx, u16 ch_address,
u8 dim_init_async(struct dim_channel *ch, u8 is_tx, u16 ch_address,
u16 max_buffer_size)
{
- return init_ctrl_async(ch, CAT_CT_VAL_ASYNC, is_tx, ch_address,
- max_buffer_size);
+ u8 ret = init_ctrl_async(ch, CAT_CT_VAL_ASYNC, is_tx, ch_address,
+ max_buffer_size);
+
+ if (is_tx && !g.atx_dbr.ch_addr) {
+ g.atx_dbr.ch_addr = ch->addr;
+ dbrcnt_init(ch->addr, ch->dbr_size);
+ dimcb_io_write(&g.dim2->MIEN, bit_mask(20));
+ }
+
+ return ret;
}
u8 dim_init_isoc(struct dim_channel *ch, u8 is_tx, u16 ch_address,
@@ -781,6 +864,8 @@ u8 dim_init_isoc(struct dim_channel *ch, u8 is_tx, u16 ch_address,
u8 dim_init_sync(struct dim_channel *ch, u8 is_tx, u16 ch_address,
u16 bytes_per_frame)
{
+ u16 bd_factor = g.fcnt + 2;
+
if (!g.dim_is_initialized || !ch)
return DIM_ERR_DRIVER_NOT_INITIALIZED;
@@ -790,13 +875,14 @@ u8 dim_init_sync(struct dim_channel *ch, u8 is_tx, u16 ch_address,
if (!check_bytes_per_frame(bytes_per_frame))
return DIM_ERR_BAD_CONFIG;
- ch->dbr_size = bytes_per_frame * SYNC_DBR_FACTOR;
+ ch->dbr_size = bytes_per_frame << bd_factor;
ch->dbr_addr = alloc_dbr(ch->dbr_size);
if (ch->dbr_addr >= DBR_SIZE)
return DIM_INIT_ERR_OUT_OF_MEMORY;
sync_init(ch, ch_address / 2, bytes_per_frame);
+ dim2_clear_dbr(ch->dbr_addr, ch->dbr_size);
dim2_configure_channel(ch->addr, CAT_CT_VAL_SYNC, is_tx,
ch->dbr_addr, ch->dbr_size, 0, true);
@@ -808,6 +894,11 @@ u8 dim_destroy_channel(struct dim_channel *ch)
if (!g.dim_is_initialized || !ch)
return DIM_ERR_DRIVER_NOT_INITIALIZED;
+ if (ch->addr == g.atx_dbr.ch_addr) {
+ dimcb_io_write(&g.dim2->MIEN, 0);
+ g.atx_dbr.ch_addr = 0;
+ }
+
dim2_clear_channel(ch->addr);
if (ch->dbr_addr < DBR_SIZE)
free_dbr(ch->dbr_addr, ch->dbr_size);
@@ -816,7 +907,7 @@ u8 dim_destroy_channel(struct dim_channel *ch)
return DIM_NO_ERROR;
}
-void dim_service_irq(struct dim_channel *const *channels)
+void dim_service_ahb_int_irq(struct dim_channel *const *channels)
{
bool state_changed;
@@ -848,10 +939,6 @@ void dim_service_irq(struct dim_channel *const *channels)
++ch;
}
} while (state_changed);
-
- /* clear pending Interrupts */
- dimcb_io_write(&g.dim2->MS0, 0);
- dimcb_io_write(&g.dim2->MS1, 0);
}
u8 dim_service_channel(struct dim_channel *ch)
diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/hdm-dim2/dim2_hal.h
index 1c924e869de7..6df6ea5f7da4 100644
--- a/drivers/staging/most/hdm-dim2/dim2_hal.h
+++ b/drivers/staging/most/hdm-dim2/dim2_hal.h
@@ -60,7 +60,8 @@ struct dim_channel {
u16 done_sw_buffers_number; /*< Done software buffers number. */
};
-u8 dim_startup(struct dim2_regs __iomem *dim_base_address, u32 mlb_clock);
+u8 dim_startup(struct dim2_regs __iomem *dim_base_address, u32 mlb_clock,
+ u32 fcnt);
void dim_shutdown(void);
@@ -86,13 +87,17 @@ u8 dim_init_sync(struct dim_channel *ch, u8 is_tx, u16 ch_address,
u8 dim_destroy_channel(struct dim_channel *ch);
-void dim_service_irq(struct dim_channel *const *channels);
+void dim_service_mlb_int_irq(void);
+
+void dim_service_ahb_int_irq(struct dim_channel *const *channels);
u8 dim_service_channel(struct dim_channel *ch);
struct dim_ch_state_t *dim_get_channel_state(struct dim_channel *ch,
struct dim_ch_state_t *state_ptr);
+u16 dim_dbr_space(struct dim_channel *ch);
+
bool dim_enqueue_buffer(struct dim_channel *ch, u32 buffer_addr,
u16 buffer_size);
diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c
index a36449551513..78b2c3dd9bb3 100644
--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
+++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
@@ -1,7 +1,7 @@
/*
* dim2_hdm.c - MediaLB DIM2 Hardware Dependent Module
*
- * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG
+ * Copyright (C) 2015-2016, Microchip Technology Germany II GmbH & Co. KG
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -45,15 +45,15 @@ module_param(clock_speed, charp, 0);
MODULE_PARM_DESC(clock_speed, "MediaLB Clock Speed");
/*
- * #############################################################################
+ * The parameter representing the number of frames per sub-buffer for
+ * synchronous channels. Valid values: [0 .. 6].
*
- * The define below activates an utility function used by HAL-simu
- * for calling DIM interrupt handler.
- * It is used only for TEST PURPOSE and shall be commented before release.
- *
- * #############################################################################
+ * The values 0, 1, 2, 3, 4, 5, 6 represent corresponding number of frames per
+ * sub-buffer 1, 2, 4, 8, 16, 32, 64.
*/
-/* #define ENABLE_HDM_TEST */
+static u8 fcnt = 4; /* (1 << fcnt) frames per subbuffer */
+module_param(fcnt, byte, 0);
+MODULE_PARM_DESC(fcnt, "Num of frames per sub-buffer for sync channels as a power of 2");
static DEFINE_SPINLOCK(dim_lock);
@@ -85,7 +85,6 @@ struct hdm_channel {
* @most_iface: most interface structure
* @capabilities: an array of channel capability data
* @io_base: I/O register base address
- * @irq_ahb0: dim2 AHB0 irq number
* @clk_speed: user selectable (through command line parameter) clock speed
* @netinfo_task: thread to deliver network status
* @netinfo_waitq: waitq for the thread to sleep
@@ -100,7 +99,6 @@ struct dim2_hdm {
struct most_interface most_iface;
char name[16 + sizeof "dim2-"];
void __iomem *io_base;
- unsigned int irq_ahb0;
int clk_speed;
struct task_struct *netinfo_task;
wait_queue_head_t netinfo_waitq;
@@ -118,10 +116,6 @@ struct dim2_hdm {
(((p)[1] == 0x18) && ((p)[2] == 0x05) && ((p)[3] == 0x0C) && \
((p)[13] == 0x3C) && ((p)[14] == 0x00) && ((p)[15] == 0x0A))
-#if defined(ENABLE_HDM_TEST)
-static struct dim2_hdm *test_dev;
-#endif
-
bool dim2_sysfs_get_state_cb(void)
{
bool state;
@@ -212,7 +206,8 @@ static int startup_dim(struct platform_device *pdev)
return ret;
}
- hal_ret = dim_startup(dev->io_base, dev->clk_speed);
+ pr_info("sync: num of frames per sub-buffer: %u\n", fcnt);
+ hal_ret = dim_startup(dev->io_base, dev->clk_speed, fcnt);
if (hal_ret != DIM_NO_ERROR) {
pr_err("dim_startup failed: %d\n", hal_ret);
if (pdata && pdata->destroy)
@@ -254,6 +249,11 @@ static int try_start_dim_transfer(struct hdm_channel *hdm_ch)
mbo = list_first_entry(head, struct mbo, list);
buf_size = mbo->buffer_length;
+ if (dim_dbr_space(&hdm_ch->ch) < buf_size) {
+ spin_unlock_irqrestore(&dim_lock, flags);
+ return -EAGAIN;
+ }
+
BUG_ON(mbo->bus_address == 0);
if (!dim_enqueue_buffer(&hdm_ch->ch, mbo->bus_address, buf_size)) {
list_del(head->next);
@@ -411,6 +411,22 @@ static struct dim_channel **get_active_channels(struct dim2_hdm *dev,
return buffer;
}
+static irqreturn_t dim2_mlb_isr(int irq, void *_dev)
+{
+ struct dim2_hdm *dev = _dev;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dim_lock, flags);
+ dim_service_mlb_int_irq();
+ spin_unlock_irqrestore(&dim_lock, flags);
+
+ if (dev->atx_idx >= 0 && dev->hch[dev->atx_idx].is_initialized)
+ while (!try_start_dim_transfer(dev->hch + dev->atx_idx))
+ continue;
+
+ return IRQ_HANDLED;
+}
+
/**
* dim2_tasklet_fn - tasklet function
* @data: private data
@@ -452,30 +468,14 @@ static irqreturn_t dim2_ahb_isr(int irq, void *_dev)
unsigned long flags;
spin_lock_irqsave(&dim_lock, flags);
- dim_service_irq(get_active_channels(dev, buffer));
+ dim_service_ahb_int_irq(get_active_channels(dev, buffer));
spin_unlock_irqrestore(&dim_lock, flags);
-#if !defined(ENABLE_HDM_TEST)
dim2_tasklet.data = (unsigned long)dev;
tasklet_schedule(&dim2_tasklet);
-#else
- dim2_tasklet_fn((unsigned long)dev);
-#endif
return IRQ_HANDLED;
}
-#if defined(ENABLE_HDM_TEST)
-
-/*
- * Utility function used by HAL-simu for calling DIM interrupt handler.
- * It is used only for TEST PURPOSE.
- */
-void raise_dim_interrupt(void)
-{
- (void)dim2_ahb_isr(0, test_dev);
-}
-#endif
-
/**
* complete_all_mbos - complete MBO's in a list
* @head: list head
@@ -545,7 +545,7 @@ static int configure_channel(struct most_interface *most_iface, int ch_idx,
hdm_ch->name, buf_size, new_size);
spin_lock_irqsave(&dim_lock, flags);
hal_ret = dim_init_control(&hdm_ch->ch, is_tx, ch_addr,
- buf_size);
+ is_tx ? new_size * 2 : new_size);
break;
case MOST_CH_ASYNC:
new_size = dim_norm_ctrl_async_buffer_size(buf_size);
@@ -558,9 +558,10 @@ static int configure_channel(struct most_interface *most_iface, int ch_idx,
pr_warn("%s: fixed buffer size (%d -> %d)\n",
hdm_ch->name, buf_size, new_size);
spin_lock_irqsave(&dim_lock, flags);
- hal_ret = dim_init_async(&hdm_ch->ch, is_tx, ch_addr, buf_size);
+ hal_ret = dim_init_async(&hdm_ch->ch, is_tx, ch_addr,
+ is_tx ? new_size * 2 : new_size);
break;
- case MOST_CH_ISOC_AVP:
+ case MOST_CH_ISOC:
new_size = dim_norm_isoc_buffer_size(buf_size, sub_size);
if (new_size == 0) {
pr_err("%s: invalid sub-buffer size or too small buffer size\n",
@@ -705,12 +706,14 @@ static int poison_channel(struct most_interface *most_iface, int ch_idx)
if (!hdm_ch->is_initialized)
return -EPERM;
+ tasklet_disable(&dim2_tasklet);
spin_lock_irqsave(&dim_lock, flags);
hal_ret = dim_destroy_channel(&hdm_ch->ch);
hdm_ch->is_initialized = false;
if (ch_idx == dev->atx_idx)
dev->atx_idx = -1;
spin_unlock_irqrestore(&dim_lock, flags);
+ tasklet_enable(&dim2_tasklet);
if (hal_ret != DIM_NO_ERROR) {
pr_err("HAL Failed to close channel %s\n", hdm_ch->name);
ret = -EFAULT;
@@ -735,6 +738,7 @@ static int dim2_probe(struct platform_device *pdev)
struct resource *res;
int ret, i;
struct kobject *kobj;
+ int irq;
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
if (!dev)
@@ -743,29 +747,37 @@ static int dim2_probe(struct platform_device *pdev)
dev->atx_idx = -1;
platform_set_drvdata(pdev, dev);
-#if defined(ENABLE_HDM_TEST)
- test_dev = dev;
-#else
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dev->io_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(dev->io_base))
return PTR_ERR(dev->io_base);
- ret = platform_get_irq(pdev, 0);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to get irq\n");
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "failed to get ahb0_int irq\n");
return -ENODEV;
}
- dev->irq_ahb0 = ret;
- ret = devm_request_irq(&pdev->dev, dev->irq_ahb0, dim2_ahb_isr, 0,
- "mlb_ahb0", dev);
+ ret = devm_request_irq(&pdev->dev, irq, dim2_ahb_isr, 0,
+ "dim2_ahb0_int", dev);
if (ret) {
- dev_err(&pdev->dev, "failed to request IRQ: %d, err: %d\n",
- dev->irq_ahb0, ret);
+ dev_err(&pdev->dev, "failed to request ahb0_int irq %d\n", irq);
return ret;
}
-#endif
+
+ irq = platform_get_irq(pdev, 1);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "failed to get mlb_int irq\n");
+ return -ENODEV;
+ }
+
+ ret = devm_request_irq(&pdev->dev, irq, dim2_mlb_isr, 0,
+ "dim2_mlb_int", dev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to request mlb_int irq %d\n", irq);
+ return ret;
+ }
+
init_waitqueue_head(&dev->netinfo_waitq);
dev->deliver_netinfo = 0;
dev->netinfo_task = kthread_run(&deliver_netinfo_thread, (void *)dev,
@@ -785,7 +797,7 @@ static int dim2_probe(struct platform_device *pdev)
cap->name_suffix = hdm_ch->name;
cap->direction = MOST_CH_RX | MOST_CH_TX;
cap->data_type = MOST_CH_CONTROL | MOST_CH_ASYNC |
- MOST_CH_ISOC_AVP | MOST_CH_SYNC;
+ MOST_CH_ISOC | MOST_CH_SYNC;
cap->num_buffers_packet = MAX_BUFFERS_PACKET;
cap->buffer_size_packet = MAX_BUF_SIZE_PACKET;
cap->num_buffers_streaming = MAX_BUFFERS_STREAMING;
diff --git a/drivers/staging/most/hdm-dim2/dim2_reg.h b/drivers/staging/most/hdm-dim2/dim2_reg.h
index e0837b6b9ae1..01fe499411ff 100644
--- a/drivers/staging/most/hdm-dim2/dim2_reg.h
+++ b/drivers/staging/most/hdm-dim2/dim2_reg.h
@@ -77,13 +77,7 @@ enum {
MLBC0_FCNT_SHIFT = 15,
MLBC0_FCNT_MASK = 7,
- MLBC0_FCNT_VAL_1FPSB = 0,
- MLBC0_FCNT_VAL_2FPSB = 1,
- MLBC0_FCNT_VAL_4FPSB = 2,
- MLBC0_FCNT_VAL_8FPSB = 3,
- MLBC0_FCNT_VAL_16FPSB = 4,
- MLBC0_FCNT_VAL_32FPSB = 5,
- MLBC0_FCNT_VAL_64FPSB = 6,
+ MLBC0_FCNT_MAX_VAL = 6,
MLBC0_MLBEN_BIT = 0,
@@ -123,6 +117,9 @@ enum {
};
enum {
+ CDT0_RPC_SHIFT = 16 + 11,
+ CDT0_RPC_MASK = DIM2_MASK(5),
+
CDT1_BS_ISOC_SHIFT = 0,
CDT1_BS_ISOC_MASK = DIM2_MASK(9),
diff --git a/drivers/staging/most/hdm-dim2/dim2_sysfs.c b/drivers/staging/most/hdm-dim2/dim2_sysfs.c
index 2b28e4a51131..d8b22f91d2c3 100644
--- a/drivers/staging/most/hdm-dim2/dim2_sysfs.c
+++ b/drivers/staging/most/hdm-dim2/dim2_sysfs.c
@@ -39,7 +39,7 @@ static struct attribute *bus_default_attrs[] = {
NULL,
};
-static struct attribute_group bus_attr_group = {
+static const struct attribute_group bus_attr_group = {
.attrs = bus_default_attrs,
};
diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c
index aeae071f2823..26c9adb29308 100644
--- a/drivers/staging/most/hdm-usb/hdm_usb.c
+++ b/drivers/staging/most/hdm-usb/hdm_usb.c
@@ -43,8 +43,9 @@
#define USB_VENDOR_ID_SMSC 0x0424 /* VID: SMSC */
#define USB_DEV_ID_BRDG 0xC001 /* PID: USB Bridge */
-#define USB_DEV_ID_INIC 0xCF18 /* PID: USB INIC */
-#define HW_RESYNC 0x0000
+#define USB_DEV_ID_OS81118 0xCF18 /* PID: USB OS81118 */
+#define USB_DEV_ID_OS81119 0xCF19 /* PID: USB OS81119 */
+#define USB_DEV_ID_OS81210 0xCF30 /* PID: USB OS81210 */
/* DRCI Addresses */
#define DRCI_REG_NI_STATE 0x0100
#define DRCI_REG_PACKET_BW 0x0101
@@ -64,33 +65,30 @@
#define DRCI_WRITE_REQ 0xA1
/**
- * struct buf_anchor - used to create a list of pending URBs
- * @urb: pointer to USB request block
- * @clear_work_obj:
- * @list: linked list
- * @urb_completion:
- */
-struct buf_anchor {
- struct urb *urb;
- struct work_struct clear_work_obj;
- struct list_head list;
- struct completion urb_compl;
-};
-
-#define to_buf_anchor(w) container_of(w, struct buf_anchor, clear_work_obj)
-
-/**
* struct most_dci_obj - Direct Communication Interface
* @kobj:position in sysfs
* @usb_device: pointer to the usb device
+ * @reg_addr: register address for arbitrary DCI access
*/
struct most_dci_obj {
struct kobject kobj;
struct usb_device *usb_device;
+ u16 reg_addr;
};
#define to_dci_obj(p) container_of(p, struct most_dci_obj, kobj)
+struct most_dev;
+
+struct clear_hold_work {
+ struct work_struct ws;
+ struct most_dev *mdev;
+ unsigned int channel;
+ int pipe;
+};
+
+#define to_clear_hold_work(w) container_of(w, struct clear_hold_work, ws)
+
/**
* struct most_dev - holds all usb interface specific stuff
* @parent: parent object in sysfs
@@ -104,10 +102,10 @@ struct most_dci_obj {
* @link_stat: link status of hardware
* @description: device description
* @suffix: suffix for channel name
- * @anchor_list_lock: locks list access
+ * @channel_lock: synchronize channel access
* @padding_active: indicates channel uses padding
* @is_channel_healthy: health status table of each channel
- * @anchor_list: list of anchored items
+ * @busy_urbs: list of anchored items
* @io_mutex: synchronize I/O with disconnect
* @link_stat_timer: timer for link status reports
* @poll_work_obj: work for polling link status
@@ -124,10 +122,11 @@ struct most_dev {
u16 link_stat;
char description[MAX_STRING_LEN];
char suffix[MAX_NUM_ENDPOINTS][MAX_SUFFIX_LEN];
- spinlock_t anchor_list_lock[MAX_NUM_ENDPOINTS];
+ spinlock_t channel_lock[MAX_NUM_ENDPOINTS]; /* sync channel access */
bool padding_active[MAX_NUM_ENDPOINTS];
bool is_channel_healthy[MAX_NUM_ENDPOINTS];
- struct list_head *anchor_list;
+ struct clear_hold_work clear_work[MAX_NUM_ENDPOINTS];
+ struct usb_anchor *busy_urbs;
struct mutex io_mutex;
struct timer_list link_stat_timer;
struct work_struct poll_work_obj;
@@ -191,40 +190,24 @@ static inline int drci_wr_reg(struct usb_device *dev, u16 reg, u16 data)
* free_anchored_buffers - free device's anchored items
* @mdev: the device
* @channel: channel ID
+ * @status: status of MBO termination
*/
-static void free_anchored_buffers(struct most_dev *mdev, unsigned int channel)
+static void free_anchored_buffers(struct most_dev *mdev, unsigned int channel,
+ enum mbo_status_flags status)
{
struct mbo *mbo;
- struct buf_anchor *anchor, *tmp;
- unsigned long flags;
+ struct urb *urb;
- spin_lock_irqsave(&mdev->anchor_list_lock[channel], flags);
- list_for_each_entry_safe(anchor, tmp, &mdev->anchor_list[channel],
- list) {
- struct urb *urb = anchor->urb;
-
- spin_unlock_irqrestore(&mdev->anchor_list_lock[channel], flags);
- if (likely(urb)) {
- mbo = urb->context;
- if (!irqs_disabled()) {
- usb_kill_urb(urb);
- } else {
- usb_unlink_urb(urb);
- wait_for_completion(&anchor->urb_compl);
- }
- if ((mbo) && (mbo->complete)) {
- mbo->status = MBO_E_CLOSE;
- mbo->processed_length = 0;
- mbo->complete(mbo);
- }
- usb_free_urb(urb);
+ while ((urb = usb_get_from_anchor(&mdev->busy_urbs[channel]))) {
+ mbo = urb->context;
+ usb_kill_urb(urb);
+ if (mbo && mbo->complete) {
+ mbo->status = status;
+ mbo->processed_length = 0;
+ mbo->complete(mbo);
}
- spin_lock_irqsave(&mdev->anchor_list_lock[channel], flags);
- list_del(&anchor->list);
- cancel_work_sync(&anchor->clear_work_obj);
- kfree(anchor);
+ usb_free_urb(urb);
}
- spin_unlock_irqrestore(&mdev->anchor_list_lock[channel], flags);
}
/**
@@ -241,7 +224,7 @@ static unsigned int get_stream_frame_size(struct most_channel_config *cfg)
return frame_size;
}
switch (cfg->data_type) {
- case MOST_CH_ISOC_AVP:
+ case MOST_CH_ISOC:
frame_size = AV_PACKETS_PER_XACT * sub_size;
break;
case MOST_CH_SYNC:
@@ -274,22 +257,28 @@ static unsigned int get_stream_frame_size(struct most_channel_config *cfg)
*/
static int hdm_poison_channel(struct most_interface *iface, int channel)
{
- struct most_dev *mdev;
+ struct most_dev *mdev = to_mdev(iface);
+ unsigned long flags;
+ spinlock_t *lock; /* temp. lock */
- mdev = to_mdev(iface);
if (unlikely(!iface)) {
dev_warn(&mdev->usb_device->dev, "Poison: Bad interface.\n");
return -EIO;
}
- if (unlikely((channel < 0) || (channel >= iface->num_channels))) {
+ if (unlikely(channel < 0 || channel >= iface->num_channels)) {
dev_warn(&mdev->usb_device->dev, "Channel ID out of range.\n");
return -ECHRNG;
}
+ lock = mdev->channel_lock + channel;
+ spin_lock_irqsave(lock, flags);
mdev->is_channel_healthy[channel] = false;
+ spin_unlock_irqrestore(lock, flags);
+
+ cancel_work_sync(&mdev->clear_work[channel].ws);
mutex_lock(&mdev->io_mutex);
- free_anchored_buffers(mdev, channel);
+ free_anchored_buffers(mdev, channel, MBO_E_CLOSE);
if (mdev->padding_active[channel])
mdev->padding_active[channel] = false;
@@ -313,10 +302,10 @@ static int hdm_poison_channel(struct most_interface *iface, int channel)
static int hdm_add_padding(struct most_dev *mdev, int channel, struct mbo *mbo)
{
struct most_channel_config *conf = &mdev->conf[channel];
- unsigned int j, num_frames, frame_size;
+ unsigned int frame_size = get_stream_frame_size(conf);
+ unsigned int j, num_frames;
u16 rd_addr, wr_addr;
- frame_size = get_stream_frame_size(conf);
if (!frame_size)
return -EIO;
num_frames = mbo->buffer_length / frame_size;
@@ -350,10 +339,10 @@ static int hdm_add_padding(struct most_dev *mdev, int channel, struct mbo *mbo)
static int hdm_remove_padding(struct most_dev *mdev, int channel,
struct mbo *mbo)
{
- unsigned int j, num_frames, frame_size;
struct most_channel_config *const conf = &mdev->conf[channel];
+ unsigned int frame_size = get_stream_frame_size(conf);
+ unsigned int j, num_frames;
- frame_size = get_stream_frame_size(conf);
if (!frame_size)
return -EIO;
num_frames = mbo->processed_length / USB_MTU;
@@ -380,37 +369,29 @@ static int hdm_remove_padding(struct most_dev *mdev, int channel,
*/
static void hdm_write_completion(struct urb *urb)
{
- struct mbo *mbo;
- struct buf_anchor *anchor;
- struct most_dev *mdev;
- struct device *dev;
- unsigned int channel;
+ struct mbo *mbo = urb->context;
+ struct most_dev *mdev = to_mdev(mbo->ifp);
+ unsigned int channel = mbo->hdm_channel_id;
+ struct device *dev = &mdev->usb_device->dev;
+ spinlock_t *lock = mdev->channel_lock + channel;
unsigned long flags;
- mbo = urb->context;
- anchor = mbo->priv;
- mdev = to_mdev(mbo->ifp);
- channel = mbo->hdm_channel_id;
- dev = &mdev->usb_device->dev;
-
- if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) ||
- (!mdev->is_channel_healthy[channel])) {
- complete(&anchor->urb_compl);
+ spin_lock_irqsave(lock, flags);
+ if (urb->status == -ENOENT || urb->status == -ECONNRESET ||
+ !mdev->is_channel_healthy[channel]) {
+ spin_unlock_irqrestore(lock, flags);
return;
}
- if (unlikely(urb->status && !(urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN))) {
+ if (unlikely(urb->status && urb->status != -ESHUTDOWN)) {
mbo->processed_length = 0;
switch (urb->status) {
case -EPIPE:
dev_warn(dev, "Broken OUT pipe detected\n");
- most_stop_enqueue(&mdev->iface, channel);
- mbo->status = MBO_E_INVAL;
- usb_unlink_urb(urb);
- INIT_WORK(&anchor->clear_work_obj, wq_clear_halt);
- schedule_work(&anchor->clear_work_obj);
+ mdev->is_channel_healthy[channel] = false;
+ spin_unlock_irqrestore(lock, flags);
+ mdev->clear_work[channel].pipe = urb->pipe;
+ schedule_work(&mdev->clear_work[channel].ws);
return;
case -ENODEV:
case -EPROTO:
@@ -425,10 +406,7 @@ static void hdm_write_completion(struct urb *urb)
mbo->processed_length = urb->actual_length;
}
- spin_lock_irqsave(&mdev->anchor_list_lock[channel], flags);
- list_del(&anchor->list);
- spin_unlock_irqrestore(&mdev->anchor_list_lock[channel], flags);
- kfree(anchor);
+ spin_unlock_irqrestore(lock, flags);
if (likely(mbo->complete))
mbo->complete(mbo);
@@ -545,36 +523,29 @@ static void hdm_write_completion(struct urb *urb)
*/
static void hdm_read_completion(struct urb *urb)
{
- struct mbo *mbo;
- struct buf_anchor *anchor;
- struct most_dev *mdev;
- struct device *dev;
+ struct mbo *mbo = urb->context;
+ struct most_dev *mdev = to_mdev(mbo->ifp);
+ unsigned int channel = mbo->hdm_channel_id;
+ struct device *dev = &mdev->usb_device->dev;
+ spinlock_t *lock = mdev->channel_lock + channel;
unsigned long flags;
- unsigned int channel;
-
- mbo = urb->context;
- anchor = mbo->priv;
- mdev = to_mdev(mbo->ifp);
- channel = mbo->hdm_channel_id;
- dev = &mdev->usb_device->dev;
- if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) ||
- (!mdev->is_channel_healthy[channel])) {
- complete(&anchor->urb_compl);
+ spin_lock_irqsave(lock, flags);
+ if (urb->status == -ENOENT || urb->status == -ECONNRESET ||
+ !mdev->is_channel_healthy[channel]) {
+ spin_unlock_irqrestore(lock, flags);
return;
}
- if (unlikely(urb->status && !(urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN))) {
+ if (unlikely(urb->status && urb->status != -ESHUTDOWN)) {
mbo->processed_length = 0;
switch (urb->status) {
case -EPIPE:
dev_warn(dev, "Broken IN pipe detected\n");
- mbo->status = MBO_E_INVAL;
- usb_unlink_urb(urb);
- INIT_WORK(&anchor->clear_work_obj, wq_clear_halt);
- schedule_work(&anchor->clear_work_obj);
+ mdev->is_channel_healthy[channel] = false;
+ spin_unlock_irqrestore(lock, flags);
+ mdev->clear_work[channel].pipe = urb->pipe;
+ schedule_work(&mdev->clear_work[channel].ws);
return;
case -ENODEV:
case -EPROTO:
@@ -588,21 +559,15 @@ static void hdm_read_completion(struct urb *urb)
}
} else {
mbo->processed_length = urb->actual_length;
- if (!mdev->padding_active[channel]) {
- mbo->status = MBO_SUCCESS;
- } else {
- if (hdm_remove_padding(mdev, channel, mbo)) {
- mbo->processed_length = 0;
- mbo->status = MBO_E_INVAL;
- } else {
- mbo->status = MBO_SUCCESS;
- }
+ mbo->status = MBO_SUCCESS;
+ if (mdev->padding_active[channel] &&
+ hdm_remove_padding(mdev, channel, mbo)) {
+ mbo->processed_length = 0;
+ mbo->status = MBO_E_INVAL;
}
}
- spin_lock_irqsave(&mdev->anchor_list_lock[channel], flags);
- list_del(&anchor->list);
- spin_unlock_irqrestore(&mdev->anchor_list_lock[channel], flags);
- kfree(anchor);
+
+ spin_unlock_irqrestore(lock, flags);
if (likely(mbo->complete))
mbo->complete(mbo);
@@ -628,18 +593,16 @@ static int hdm_enqueue(struct most_interface *iface, int channel,
struct mbo *mbo)
{
struct most_dev *mdev;
- struct buf_anchor *anchor;
struct most_channel_config *conf;
struct device *dev;
int retval = 0;
struct urb *urb;
- unsigned long flags;
unsigned long length;
void *virt_address;
if (unlikely(!iface || !mbo))
return -EIO;
- if (unlikely(iface->num_channels <= channel) || (channel < 0))
+ if (unlikely(iface->num_channels <= channel || channel < 0))
return -ECHRNG;
mdev = to_mdev(iface);
@@ -650,32 +613,15 @@ static int hdm_enqueue(struct most_interface *iface, int channel,
return -ENODEV;
urb = usb_alloc_urb(NO_ISOCHRONOUS_URB, GFP_ATOMIC);
- if (!urb) {
- dev_err(dev, "Failed to allocate URB\n");
+ if (!urb)
return -ENOMEM;
- }
- anchor = kzalloc(sizeof(*anchor), GFP_ATOMIC);
- if (!anchor) {
- retval = -ENOMEM;
+ if ((conf->direction & MOST_CH_TX) && mdev->padding_active[channel] &&
+ hdm_add_padding(mdev, channel, mbo)) {
+ retval = -EIO;
goto _error;
}
- anchor->urb = urb;
- init_completion(&anchor->urb_compl);
- mbo->priv = anchor;
-
- spin_lock_irqsave(&mdev->anchor_list_lock[channel], flags);
- list_add_tail(&anchor->list, &mdev->anchor_list[channel]);
- spin_unlock_irqrestore(&mdev->anchor_list_lock[channel], flags);
-
- if ((mdev->padding_active[channel]) &&
- (conf->direction & MOST_CH_TX))
- if (hdm_add_padding(mdev, channel, mbo)) {
- retval = -EIO;
- goto _error_1;
- }
-
urb->transfer_dma = mbo->bus_address;
virt_address = mbo->virt_address;
length = mbo->buffer_length;
@@ -688,7 +634,7 @@ static int hdm_enqueue(struct most_interface *iface, int channel,
length,
hdm_write_completion,
mbo);
- if (conf->data_type != MOST_CH_ISOC_AVP)
+ if (conf->data_type != MOST_CH_ISOC)
urb->transfer_flags |= URB_ZERO_PACKET;
} else {
usb_fill_bulk_urb(urb, mdev->usb_device,
@@ -701,6 +647,8 @@ static int hdm_enqueue(struct most_interface *iface, int channel,
}
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ usb_anchor_urb(urb, &mdev->busy_urbs[channel]);
+
retval = usb_submit_urb(urb, GFP_KERNEL);
if (retval) {
dev_err(dev, "URB submit failed with error %d.\n", retval);
@@ -709,10 +657,7 @@ static int hdm_enqueue(struct most_interface *iface, int channel,
return 0;
_error_1:
- spin_lock_irqsave(&mdev->anchor_list_lock[channel], flags);
- list_del(&anchor->list);
- spin_unlock_irqrestore(&mdev->anchor_list_lock[channel], flags);
- kfree(anchor);
+ usb_unanchor_urb(urb);
_error:
usb_free_urb(urb);
return retval;
@@ -731,29 +676,30 @@ static int hdm_configure_channel(struct most_interface *iface, int channel,
unsigned int frame_size;
unsigned int temp_size;
unsigned int tail_space;
- struct most_dev *mdev;
- struct device *dev;
+ struct most_dev *mdev = to_mdev(iface);
+ struct device *dev = &mdev->usb_device->dev;
- mdev = to_mdev(iface);
mdev->is_channel_healthy[channel] = true;
- dev = &mdev->usb_device->dev;
+ mdev->clear_work[channel].channel = channel;
+ mdev->clear_work[channel].mdev = mdev;
+ INIT_WORK(&mdev->clear_work[channel].ws, wq_clear_halt);
if (unlikely(!iface || !conf)) {
dev_err(dev, "Bad interface or config pointer.\n");
return -EINVAL;
}
- if (unlikely((channel < 0) || (channel >= iface->num_channels))) {
+ if (unlikely(channel < 0 || channel >= iface->num_channels)) {
dev_err(dev, "Channel ID out of range.\n");
return -EINVAL;
}
- if ((!conf->num_buffers) || (!conf->buffer_size)) {
+ if (!conf->num_buffers || !conf->buffer_size) {
dev_err(dev, "Misconfig: buffer size or #buffers zero.\n");
return -EINVAL;
}
- if (!(conf->data_type == MOST_CH_SYNC) &&
- !((conf->data_type == MOST_CH_ISOC_AVP) &&
- (conf->packets_per_xact != 0xFF))) {
+ if (conf->data_type != MOST_CH_SYNC &&
+ !(conf->data_type == MOST_CH_ISOC &&
+ conf->packets_per_xact != 0xFF)) {
mdev->padding_active[channel] = false;
goto exit;
}
@@ -762,7 +708,7 @@ static int hdm_configure_channel(struct most_interface *iface, int channel,
temp_size = conf->buffer_size;
frame_size = get_stream_frame_size(conf);
- if ((frame_size == 0) || (frame_size > USB_MTU)) {
+ if (frame_size == 0 || frame_size > USB_MTU) {
dev_warn(dev, "Misconfig: frame size wrong\n");
return -EINVAL;
}
@@ -807,17 +753,17 @@ static int hdm_update_netinfo(struct most_dev *mdev)
if (!is_valid_ether_addr(mdev->hw_addr)) {
if (drci_rd_reg(usb_device, DRCI_REG_HW_ADDR_HI, &hi) < 0) {
dev_err(dev, "Vendor request \"hw_addr_hi\" failed\n");
- return -1;
+ return -EFAULT;
}
if (drci_rd_reg(usb_device, DRCI_REG_HW_ADDR_MI, &mi) < 0) {
dev_err(dev, "Vendor request \"hw_addr_mid\" failed\n");
- return -1;
+ return -EFAULT;
}
if (drci_rd_reg(usb_device, DRCI_REG_HW_ADDR_LO, &lo) < 0) {
dev_err(dev, "Vendor request \"hw_addr_low\" failed\n");
- return -1;
+ return -EFAULT;
}
mutex_lock(&mdev->io_mutex);
@@ -832,7 +778,7 @@ static int hdm_update_netinfo(struct most_dev *mdev)
if (drci_rd_reg(usb_device, DRCI_REG_NI_STATE, &link) < 0) {
dev_err(dev, "Vendor request \"link status\" failed\n");
- return -1;
+ return -EFAULT;
}
mutex_lock(&mdev->io_mutex);
@@ -886,25 +832,22 @@ static void link_stat_timer_handler(unsigned long data)
*/
static void wq_netinfo(struct work_struct *wq_obj)
{
- struct most_dev *mdev;
- int i, prev_link_stat;
+ struct most_dev *mdev = to_mdev_from_work(wq_obj);
+ int i, prev_link_stat = mdev->link_stat;
u8 prev_hw_addr[6];
- mdev = to_mdev_from_work(wq_obj);
- prev_link_stat = mdev->link_stat;
-
for (i = 0; i < 6; i++)
prev_hw_addr[i] = mdev->hw_addr[i];
if (hdm_update_netinfo(mdev) < 0)
return;
- if ((prev_link_stat != mdev->link_stat) ||
- (prev_hw_addr[0] != mdev->hw_addr[0]) ||
- (prev_hw_addr[1] != mdev->hw_addr[1]) ||
- (prev_hw_addr[2] != mdev->hw_addr[2]) ||
- (prev_hw_addr[3] != mdev->hw_addr[3]) ||
- (prev_hw_addr[4] != mdev->hw_addr[4]) ||
- (prev_hw_addr[5] != mdev->hw_addr[5]))
+ if (prev_link_stat != mdev->link_stat ||
+ prev_hw_addr[0] != mdev->hw_addr[0] ||
+ prev_hw_addr[1] != mdev->hw_addr[1] ||
+ prev_hw_addr[2] != mdev->hw_addr[2] ||
+ prev_hw_addr[3] != mdev->hw_addr[3] ||
+ prev_hw_addr[4] != mdev->hw_addr[4] ||
+ prev_hw_addr[5] != mdev->hw_addr[5])
most_deliver_netinfo(&mdev->iface, mdev->link_stat,
&mdev->hw_addr[0]);
}
@@ -917,33 +860,20 @@ static void wq_netinfo(struct work_struct *wq_obj)
*/
static void wq_clear_halt(struct work_struct *wq_obj)
{
- struct buf_anchor *anchor;
- struct most_dev *mdev;
- struct mbo *mbo;
- struct urb *urb;
- unsigned int channel;
- unsigned long flags;
+ struct clear_hold_work *clear_work = to_clear_hold_work(wq_obj);
+ struct most_dev *mdev = clear_work->mdev;
+ unsigned int channel = clear_work->channel;
+ int pipe = clear_work->pipe;
- anchor = to_buf_anchor(wq_obj);
- urb = anchor->urb;
- mbo = urb->context;
- mdev = to_mdev(mbo->ifp);
- channel = mbo->hdm_channel_id;
-
- if (usb_clear_halt(urb->dev, urb->pipe))
+ mutex_lock(&mdev->io_mutex);
+ most_stop_enqueue(&mdev->iface, channel);
+ free_anchored_buffers(mdev, channel, MBO_E_INVAL);
+ if (usb_clear_halt(mdev->usb_device, pipe))
dev_warn(&mdev->usb_device->dev, "Failed to reset endpoint.\n");
- usb_free_urb(urb);
- spin_lock_irqsave(&mdev->anchor_list_lock[channel], flags);
- list_del(&anchor->list);
- spin_unlock_irqrestore(&mdev->anchor_list_lock[channel], flags);
-
- if (likely(mbo->complete))
- mbo->complete(mbo);
- if (mdev->conf[channel].direction & MOST_CH_TX)
- most_resume_enqueue(&mdev->iface, channel);
-
- kfree(anchor);
+ mdev->is_channel_healthy[channel] = true;
+ most_resume_enqueue(&mdev->iface, channel);
+ mutex_unlock(&mdev->io_mutex);
}
/**
@@ -958,7 +888,9 @@ static const struct file_operations hdm_usb_fops = {
*/
static struct usb_device_id usbid[] = {
{ USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_BRDG), },
- { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_INIC), },
+ { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81118), },
+ { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81119), },
+ { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81210), },
{ } /* Terminating entry */
};
@@ -970,6 +902,10 @@ static struct usb_device_id usbid[] = {
struct most_dci_attribute most_dci_attr_##_name = \
__ATTR(_name, S_IRUGO | S_IWUSR, show_value, store_value)
+#define MOST_DCI_WO_ATTR(_name) \
+ struct most_dci_attribute most_dci_attr_##_name = \
+ __ATTR(_name, S_IWUSR, NULL, store_value)
+
/**
* struct most_dci_attribute - to access the attributes of a dci object
* @attr: attributes of a dci object
@@ -1046,45 +982,68 @@ static void most_dci_release(struct kobject *kobj)
kfree(dci_obj);
}
+struct regs {
+ const char *name;
+ u16 reg;
+};
+
+static const struct regs ro_regs[] = {
+ { "ni_state", DRCI_REG_NI_STATE },
+ { "packet_bandwidth", DRCI_REG_PACKET_BW },
+ { "node_address", DRCI_REG_NODE_ADDR },
+ { "node_position", DRCI_REG_NODE_POS },
+};
+
+static const struct regs rw_regs[] = {
+ { "mep_filter", DRCI_REG_MEP_FILTER },
+ { "mep_hash0", DRCI_REG_HASH_TBL0 },
+ { "mep_hash1", DRCI_REG_HASH_TBL1 },
+ { "mep_hash2", DRCI_REG_HASH_TBL2 },
+ { "mep_hash3", DRCI_REG_HASH_TBL3 },
+ { "mep_eui48_hi", DRCI_REG_HW_ADDR_HI },
+ { "mep_eui48_mi", DRCI_REG_HW_ADDR_MI },
+ { "mep_eui48_lo", DRCI_REG_HW_ADDR_LO },
+};
+
+static int get_stat_reg_addr(const struct regs *regs, int size,
+ const char *name, u16 *reg_addr)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (!strcmp(name, regs[i].name)) {
+ *reg_addr = regs[i].reg;
+ return 0;
+ }
+ }
+ return -EFAULT;
+}
+
+#define get_static_reg_addr(regs, name, reg_addr) \
+ get_stat_reg_addr(regs, ARRAY_SIZE(regs), name, reg_addr)
+
static ssize_t show_value(struct most_dci_obj *dci_obj,
struct most_dci_attribute *attr, char *buf)
{
- u16 tmp_val;
+ const char *name = attr->attr.name;
+ u16 val;
u16 reg_addr;
int err;
- if (!strcmp(attr->attr.name, "ni_state"))
- reg_addr = DRCI_REG_NI_STATE;
- else if (!strcmp(attr->attr.name, "packet_bandwidth"))
- reg_addr = DRCI_REG_PACKET_BW;
- else if (!strcmp(attr->attr.name, "node_address"))
- reg_addr = DRCI_REG_NODE_ADDR;
- else if (!strcmp(attr->attr.name, "node_position"))
- reg_addr = DRCI_REG_NODE_POS;
- else if (!strcmp(attr->attr.name, "mep_filter"))
- reg_addr = DRCI_REG_MEP_FILTER;
- else if (!strcmp(attr->attr.name, "mep_hash0"))
- reg_addr = DRCI_REG_HASH_TBL0;
- else if (!strcmp(attr->attr.name, "mep_hash1"))
- reg_addr = DRCI_REG_HASH_TBL1;
- else if (!strcmp(attr->attr.name, "mep_hash2"))
- reg_addr = DRCI_REG_HASH_TBL2;
- else if (!strcmp(attr->attr.name, "mep_hash3"))
- reg_addr = DRCI_REG_HASH_TBL3;
- else if (!strcmp(attr->attr.name, "mep_eui48_hi"))
- reg_addr = DRCI_REG_HW_ADDR_HI;
- else if (!strcmp(attr->attr.name, "mep_eui48_mi"))
- reg_addr = DRCI_REG_HW_ADDR_MI;
- else if (!strcmp(attr->attr.name, "mep_eui48_lo"))
- reg_addr = DRCI_REG_HW_ADDR_LO;
- else
- return -EIO;
+ if (!strcmp(name, "arb_address"))
+ return snprintf(buf, PAGE_SIZE, "%04x\n", dci_obj->reg_addr);
+
+ if (!strcmp(name, "arb_value"))
+ reg_addr = dci_obj->reg_addr;
+ else if (get_static_reg_addr(ro_regs, name, &reg_addr) &&
+ get_static_reg_addr(rw_regs, name, &reg_addr))
+ return -EFAULT;
- err = drci_rd_reg(dci_obj->usb_device, reg_addr, &tmp_val);
+ err = drci_rd_reg(dci_obj->usb_device, reg_addr, &val);
if (err < 0)
return err;
- return snprintf(buf, PAGE_SIZE, "%04x\n", tmp_val);
+ return snprintf(buf, PAGE_SIZE, "%04x\n", val);
}
static ssize_t store_value(struct most_dci_obj *dci_obj,
@@ -1093,31 +1052,28 @@ static ssize_t store_value(struct most_dci_obj *dci_obj,
{
u16 val;
u16 reg_addr;
- int err;
-
- if (!strcmp(attr->attr.name, "mep_filter"))
- reg_addr = DRCI_REG_MEP_FILTER;
- else if (!strcmp(attr->attr.name, "mep_hash0"))
- reg_addr = DRCI_REG_HASH_TBL0;
- else if (!strcmp(attr->attr.name, "mep_hash1"))
- reg_addr = DRCI_REG_HASH_TBL1;
- else if (!strcmp(attr->attr.name, "mep_hash2"))
- reg_addr = DRCI_REG_HASH_TBL2;
- else if (!strcmp(attr->attr.name, "mep_hash3"))
- reg_addr = DRCI_REG_HASH_TBL3;
- else if (!strcmp(attr->attr.name, "mep_eui48_hi"))
- reg_addr = DRCI_REG_HW_ADDR_HI;
- else if (!strcmp(attr->attr.name, "mep_eui48_mi"))
- reg_addr = DRCI_REG_HW_ADDR_MI;
- else if (!strcmp(attr->attr.name, "mep_eui48_lo"))
- reg_addr = DRCI_REG_HW_ADDR_LO;
- else
- return -EIO;
+ const char *name = attr->attr.name;
+ int err = kstrtou16(buf, 16, &val);
- err = kstrtou16(buf, 16, &val);
if (err)
return err;
+ if (!strcmp(name, "arb_address")) {
+ dci_obj->reg_addr = val;
+ return count;
+ }
+
+ if (!strcmp(name, "arb_value")) {
+ reg_addr = dci_obj->reg_addr;
+ } else if (!strcmp(name, "sync_ep")) {
+ u16 ep = val;
+
+ reg_addr = DRCI_REG_BASE + DRCI_COMMAND + ep * 16;
+ val = 1;
+ } else if (get_static_reg_addr(ro_regs, name, &reg_addr)) {
+ return -EFAULT;
+ }
+
err = drci_wr_reg(dci_obj->usb_device, reg_addr, val);
if (err < 0)
return err;
@@ -1129,6 +1085,7 @@ static MOST_DCI_RO_ATTR(ni_state);
static MOST_DCI_RO_ATTR(packet_bandwidth);
static MOST_DCI_RO_ATTR(node_address);
static MOST_DCI_RO_ATTR(node_position);
+static MOST_DCI_WO_ATTR(sync_ep);
static MOST_DCI_ATTR(mep_filter);
static MOST_DCI_ATTR(mep_hash0);
static MOST_DCI_ATTR(mep_hash1);
@@ -1137,6 +1094,8 @@ static MOST_DCI_ATTR(mep_hash3);
static MOST_DCI_ATTR(mep_eui48_hi);
static MOST_DCI_ATTR(mep_eui48_mi);
static MOST_DCI_ATTR(mep_eui48_lo);
+static MOST_DCI_ATTR(arb_address);
+static MOST_DCI_ATTR(arb_value);
/**
* most_dci_def_attrs - array of default attribute files of the dci object
@@ -1146,6 +1105,7 @@ static struct attribute *most_dci_def_attrs[] = {
&most_dci_attr_packet_bandwidth.attr,
&most_dci_attr_node_address.attr,
&most_dci_attr_node_position.attr,
+ &most_dci_attr_sync_ep.attr,
&most_dci_attr_mep_filter.attr,
&most_dci_attr_mep_hash0.attr,
&most_dci_attr_mep_hash1.attr,
@@ -1154,6 +1114,8 @@ static struct attribute *most_dci_def_attrs[] = {
&most_dci_attr_mep_eui48_hi.attr,
&most_dci_attr_mep_eui48_mi.attr,
&most_dci_attr_mep_eui48_lo.attr,
+ &most_dci_attr_arb_address.attr,
+ &most_dci_attr_arb_value.attr,
NULL,
};
@@ -1176,10 +1138,9 @@ static struct kobj_type most_dci_ktype = {
static struct
most_dci_obj *create_most_dci_obj(struct kobject *parent)
{
- struct most_dci_obj *most_dci;
+ struct most_dci_obj *most_dci = kzalloc(sizeof(*most_dci), GFP_KERNEL);
int retval;
- most_dci = kzalloc(sizeof(*most_dci), GFP_KERNEL);
if (!most_dci)
return NULL;
@@ -1216,21 +1177,17 @@ static void destroy_most_dci_obj(struct most_dci_obj *p)
static int
hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
+ struct usb_host_interface *usb_iface_desc = interface->cur_altsetting;
+ struct usb_device *usb_dev = interface_to_usbdev(interface);
+ struct device *dev = &usb_dev->dev;
+ struct most_dev *mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
unsigned int i;
unsigned int num_endpoints;
struct most_channel_capability *tmp_cap;
- struct most_dev *mdev;
- struct usb_device *usb_dev;
- struct device *dev;
- struct usb_host_interface *usb_iface_desc;
struct usb_endpoint_descriptor *ep_desc;
int ret = 0;
int err;
- usb_iface_desc = interface->cur_altsetting;
- usb_dev = interface_to_usbdev(interface);
- dev = &usb_dev->dev;
- mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
if (!mdev)
goto exit_ENOMEM;
@@ -1276,9 +1233,9 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
if (!mdev->ep_address)
goto exit_free2;
- mdev->anchor_list =
- kcalloc(num_endpoints, sizeof(*mdev->anchor_list), GFP_KERNEL);
- if (!mdev->anchor_list)
+ mdev->busy_urbs =
+ kcalloc(num_endpoints, sizeof(*mdev->busy_urbs), GFP_KERNEL);
+ if (!mdev->busy_urbs)
goto exit_free3;
tmp_cap = mdev->cap;
@@ -1297,21 +1254,21 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
tmp_cap->num_buffers_packet = BUF_CHAIN_SIZE;
tmp_cap->num_buffers_streaming = BUF_CHAIN_SIZE;
tmp_cap->data_type = MOST_CH_CONTROL | MOST_CH_ASYNC |
- MOST_CH_ISOC_AVP | MOST_CH_SYNC;
+ MOST_CH_ISOC | MOST_CH_SYNC;
if (usb_endpoint_dir_in(ep_desc))
tmp_cap->direction = MOST_CH_RX;
else
tmp_cap->direction = MOST_CH_TX;
tmp_cap++;
- INIT_LIST_HEAD(&mdev->anchor_list[i]);
- spin_lock_init(&mdev->anchor_list_lock[i]);
+ init_usb_anchor(&mdev->busy_urbs[i]);
+ spin_lock_init(&mdev->channel_lock[i]);
err = drci_wr_reg(usb_dev,
DRCI_REG_BASE + DRCI_COMMAND +
ep_desc->bEndpointAddress * 16,
1);
if (err < 0)
- pr_warn("DCI Sync for EP %02x failed",
- ep_desc->bEndpointAddress);
+ dev_warn(dev, "DCI Sync for EP %02x failed",
+ ep_desc->bEndpointAddress);
}
dev_notice(dev, "claimed gadget: Vendor=%4.4x ProdID=%4.4x Bus=%02x Device=%02x\n",
le16_to_cpu(usb_dev->descriptor.idVendor),
@@ -1332,7 +1289,9 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
}
mutex_lock(&mdev->io_mutex);
- if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_INIC) {
+ if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 ||
+ le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81119 ||
+ le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81210) {
/* this increments the reference count of the instance
* object of the core
*/
@@ -1351,7 +1310,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
return 0;
exit_free4:
- kfree(mdev->anchor_list);
+ kfree(mdev->busy_urbs);
exit_free3:
kfree(mdev->ep_address);
exit_free2:
@@ -1379,9 +1338,8 @@ exit_ENOMEM:
*/
static void hdm_disconnect(struct usb_interface *interface)
{
- struct most_dev *mdev;
+ struct most_dev *mdev = usb_get_intfdata(interface);
- mdev = usb_get_intfdata(interface);
mutex_lock(&mdev->io_mutex);
usb_set_intfdata(interface, NULL);
mdev->usb_device = NULL;
@@ -1393,7 +1351,7 @@ static void hdm_disconnect(struct usb_interface *interface)
destroy_most_dci_obj(mdev->dci);
most_deregister_interface(&mdev->iface);
- kfree(mdev->anchor_list);
+ kfree(mdev->busy_urbs);
kfree(mdev->cap);
kfree(mdev->conf);
kfree(mdev->ep_address);
diff --git a/drivers/staging/most/mostcore/core.c b/drivers/staging/most/mostcore/core.c
index 7c619feb12d3..329109c0024f 100644
--- a/drivers/staging/most/mostcore/core.c
+++ b/drivers/staging/most/mostcore/core.c
@@ -33,7 +33,7 @@
#define STRING_SIZE 80
static struct class *most_class;
-static struct device *class_glue_dir;
+static struct device *core_dev;
static struct ida mdev_id;
static int dummy_num_buffers;
@@ -51,6 +51,7 @@ struct most_c_obj {
u16 channel_id;
bool is_poisoned;
struct mutex start_mutex;
+ struct mutex nq_mutex; /* nq thread synchronization */
int is_starving;
struct most_interface *iface;
struct most_inst_obj *inst;
@@ -82,10 +83,13 @@ struct most_inst_obj {
static const struct {
int most_ch_data_type;
char *name;
-} ch_data_type[] = { { MOST_CH_CONTROL, "control\n" },
+} ch_data_type[] = {
+ { MOST_CH_CONTROL, "control\n" },
{ MOST_CH_ASYNC, "async\n" },
{ MOST_CH_SYNC, "sync\n" },
- { MOST_CH_ISOC_AVP, "isoc_avp\n"} };
+ { MOST_CH_ISOC, "isoc\n"},
+ { MOST_CH_ISOC, "isoc_avp\n"},
+};
#define to_inst_obj(d) container_of(d, struct most_inst_obj, kobj)
@@ -260,11 +264,11 @@ static ssize_t show_available_directions(struct most_c_obj *c,
strcpy(buf, "");
if (c->iface->channel_vector[i].direction & MOST_CH_RX)
- strcat(buf, "dir_rx ");
+ strcat(buf, "rx ");
if (c->iface->channel_vector[i].direction & MOST_CH_TX)
- strcat(buf, "dir_tx ");
+ strcat(buf, "tx ");
strcat(buf, "\n");
- return strlen(buf) + 1;
+ return strlen(buf);
}
static ssize_t show_available_datatypes(struct most_c_obj *c,
@@ -280,10 +284,10 @@ static ssize_t show_available_datatypes(struct most_c_obj *c,
strcat(buf, "async ");
if (c->iface->channel_vector[i].data_type & MOST_CH_SYNC)
strcat(buf, "sync ");
- if (c->iface->channel_vector[i].data_type & MOST_CH_ISOC_AVP)
- strcat(buf, "isoc_avp ");
+ if (c->iface->channel_vector[i].data_type & MOST_CH_ISOC)
+ strcat(buf, "isoc ");
strcat(buf, "\n");
- return strlen(buf) + 1;
+ return strlen(buf);
}
static
@@ -391,9 +395,9 @@ static ssize_t show_set_direction(struct most_c_obj *c,
char *buf)
{
if (c->cfg.direction & MOST_CH_TX)
- return snprintf(buf, PAGE_SIZE, "dir_tx\n");
+ return snprintf(buf, PAGE_SIZE, "tx\n");
else if (c->cfg.direction & MOST_CH_RX)
- return snprintf(buf, PAGE_SIZE, "dir_rx\n");
+ return snprintf(buf, PAGE_SIZE, "rx\n");
return snprintf(buf, PAGE_SIZE, "unconfigured\n");
}
@@ -404,8 +408,12 @@ static ssize_t store_set_direction(struct most_c_obj *c,
{
if (!strcmp(buf, "dir_rx\n")) {
c->cfg.direction = MOST_CH_RX;
+ } else if (!strcmp(buf, "rx\n")) {
+ c->cfg.direction = MOST_CH_RX;
} else if (!strcmp(buf, "dir_tx\n")) {
c->cfg.direction = MOST_CH_TX;
+ } else if (!strcmp(buf, "tx\n")) {
+ c->cfg.direction = MOST_CH_TX;
} else {
pr_info("WARN: invalid attribute settings\n");
return -EINVAL;
@@ -847,7 +855,23 @@ static ssize_t show_add_link(struct most_aim_obj *aim_obj,
struct most_aim_attribute *attr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%s\n", aim_obj->add_link);
+ struct most_c_obj *c;
+ struct most_inst_obj *i;
+ int offs = 0;
+
+ list_for_each_entry(i, &instance_list, list) {
+ list_for_each_entry(c, &i->channel_list, list) {
+ if (c->aim0.ptr == aim_obj->driver ||
+ c->aim1.ptr == aim_obj->driver) {
+ offs += snprintf(buf + offs, PAGE_SIZE - offs,
+ "%s:%s\n",
+ kobject_name(&i->kobj),
+ kobject_name(&c->kobj));
+ }
+ }
+ }
+
+ return offs;
}
/**
@@ -1131,18 +1155,18 @@ static inline void trash_mbo(struct mbo *mbo)
spin_unlock_irqrestore(&c->fifo_lock, flags);
}
-static struct mbo *get_hdm_mbo(struct most_c_obj *c)
+static bool hdm_mbo_ready(struct most_c_obj *c)
{
- unsigned long flags;
- struct mbo *mbo;
+ bool empty;
- spin_lock_irqsave(&c->fifo_lock, flags);
- if (c->enqueue_halt || list_empty(&c->halt_fifo))
- mbo = NULL;
- else
- mbo = list_pop_mbo(&c->halt_fifo);
- spin_unlock_irqrestore(&c->fifo_lock, flags);
- return mbo;
+ if (c->enqueue_halt)
+ return false;
+
+ spin_lock_irq(&c->fifo_lock);
+ empty = list_empty(&c->halt_fifo);
+ spin_unlock_irq(&c->fifo_lock);
+
+ return !empty;
}
static void nq_hdm_mbo(struct mbo *mbo)
@@ -1160,20 +1184,32 @@ static int hdm_enqueue_thread(void *data)
{
struct most_c_obj *c = data;
struct mbo *mbo;
+ int ret;
typeof(c->iface->enqueue) enqueue = c->iface->enqueue;
while (likely(!kthread_should_stop())) {
wait_event_interruptible(c->hdm_fifo_wq,
- (mbo = get_hdm_mbo(c)) ||
+ hdm_mbo_ready(c) ||
kthread_should_stop());
- if (unlikely(!mbo))
+ mutex_lock(&c->nq_mutex);
+ spin_lock_irq(&c->fifo_lock);
+ if (unlikely(c->enqueue_halt || list_empty(&c->halt_fifo))) {
+ spin_unlock_irq(&c->fifo_lock);
+ mutex_unlock(&c->nq_mutex);
continue;
+ }
+
+ mbo = list_pop_mbo(&c->halt_fifo);
+ spin_unlock_irq(&c->fifo_lock);
if (c->cfg.direction == MOST_CH_RX)
mbo->buffer_length = c->cfg.buffer_size;
- if (unlikely(enqueue(mbo->ifp, mbo->hdm_channel_id, mbo))) {
+ ret = enqueue(mbo->ifp, mbo->hdm_channel_id, mbo);
+ mutex_unlock(&c->nq_mutex);
+
+ if (unlikely(ret)) {
pr_err("hdm enqueue failed\n");
nq_hdm_mbo(mbo);
c->hdm_enqueue_task = NULL;
@@ -1294,17 +1330,14 @@ _exit:
/**
* most_submit_mbo - submits an MBO to fifo
* @mbo: pointer to the MBO
- *
*/
-int most_submit_mbo(struct mbo *mbo)
+void most_submit_mbo(struct mbo *mbo)
{
- if (unlikely((!mbo) || (!mbo->context))) {
- pr_err("Bad MBO or missing channel reference\n");
- return -EINVAL;
- }
+ if (WARN_ONCE(!mbo || !mbo->context,
+ "bad mbo or missing channel reference\n"))
+ return;
nq_hdm_mbo(mbo);
- return 0;
}
EXPORT_SYMBOL_GPL(most_submit_mbo);
@@ -1468,10 +1501,8 @@ static void most_read_completion(struct mbo *mbo)
return;
}
- if (atomic_sub_and_test(1, &c->mbo_nq_level)) {
- pr_info("WARN: rx device out of buffers\n");
+ if (atomic_sub_and_test(1, &c->mbo_nq_level))
c->is_starving = 1;
- }
if (c->aim0.refs && c->aim0.ptr->rx_completion &&
c->aim0.ptr->rx_completion(mbo) == 0)
@@ -1761,6 +1792,7 @@ struct kobject *most_register_interface(struct most_interface *iface)
init_completion(&c->cleanup);
atomic_set(&c->mbo_ref, 0);
mutex_init(&c->start_mutex);
+ mutex_init(&c->nq_mutex);
list_add_tail(&c->list, &inst->channel_list);
}
pr_info("registered new MOST device mdev%d (%s)\n",
@@ -1826,8 +1858,12 @@ void most_stop_enqueue(struct most_interface *iface, int id)
{
struct most_c_obj *c = get_channel_by_iface(iface, id);
- if (likely(c))
- c->enqueue_halt = true;
+ if (!c)
+ return;
+
+ mutex_lock(&c->nq_mutex);
+ c->enqueue_halt = true;
+ mutex_unlock(&c->nq_mutex);
}
EXPORT_SYMBOL_GPL(most_stop_enqueue);
@@ -1843,9 +1879,12 @@ void most_resume_enqueue(struct most_interface *iface, int id)
{
struct most_c_obj *c = get_channel_by_iface(iface, id);
- if (unlikely(!c))
+ if (!c)
return;
+
+ mutex_lock(&c->nq_mutex);
c->enqueue_halt = false;
+ mutex_unlock(&c->nq_mutex);
wake_up_interruptible(&c->hdm_fifo_wq);
}
@@ -1879,22 +1918,19 @@ static int __init most_init(void)
goto exit_class;
}
- class_glue_dir =
- device_create(most_class, NULL, 0, NULL, "mostcore");
- if (IS_ERR(class_glue_dir)) {
- err = PTR_ERR(class_glue_dir);
+ core_dev = device_create(most_class, NULL, 0, NULL, "mostcore");
+ if (IS_ERR(core_dev)) {
+ err = PTR_ERR(core_dev);
goto exit_driver;
}
- most_aim_kset =
- kset_create_and_add("aims", NULL, &class_glue_dir->kobj);
+ most_aim_kset = kset_create_and_add("aims", NULL, &core_dev->kobj);
if (!most_aim_kset) {
err = -ENOMEM;
goto exit_class_container;
}
- most_inst_kset =
- kset_create_and_add("devices", NULL, &class_glue_dir->kobj);
+ most_inst_kset = kset_create_and_add("devices", NULL, &core_dev->kobj);
if (!most_inst_kset) {
err = -ENOMEM;
goto exit_driver_kset;
diff --git a/drivers/staging/most/mostcore/mostcore.h b/drivers/staging/most/mostcore/mostcore.h
index 60e018e499ef..5f8339bd046f 100644
--- a/drivers/staging/most/mostcore/mostcore.h
+++ b/drivers/staging/most/mostcore/mostcore.h
@@ -56,7 +56,7 @@ enum most_channel_direction {
enum most_channel_data_type {
MOST_CH_CONTROL = 1 << 0,
MOST_CH_ASYNC = 1 << 1,
- MOST_CH_ISOC_AVP = 1 << 2,
+ MOST_CH_ISOC = 1 << 2,
MOST_CH_SYNC = 1 << 5,
};
@@ -112,7 +112,7 @@ struct most_channel_capability {
u16 buffer_size_packet;
u16 num_buffers_streaming;
u16 buffer_size_streaming;
- char *name_suffix;
+ const char *name_suffix;
};
/**
@@ -287,7 +287,7 @@ struct kobject *most_register_interface(struct most_interface *iface);
* @intf_instance Pointer to the interface instance description.
*/
void most_deregister_interface(struct most_interface *iface);
-int most_submit_mbo(struct mbo *mbo);
+void most_submit_mbo(struct mbo *mbo);
/**
* most_stop_enqueue - prevents core from enqueing MBOs
diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c
index 99445d0fcf9c..552a7dcbf50b 100644
--- a/drivers/staging/netlogic/xlr_net.c
+++ b/drivers/staging/netlogic/xlr_net.c
@@ -192,7 +192,7 @@ static int xlr_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd)
return phy_ethtool_sset(phydev, ecmd);
}
-static struct ethtool_ops xlr_ethtool_ops = {
+static const struct ethtool_ops xlr_ethtool_ops = {
.get_settings = xlr_get_settings,
.set_settings = xlr_set_settings,
};
@@ -269,16 +269,6 @@ static void xlr_make_tx_desc(struct nlm_fmn_msg *msg, unsigned long addr,
msg->msg3 = 0;
}
-static void __maybe_unused xlr_wakeup_queue(unsigned long dev)
-{
- struct net_device *ndev = (struct net_device *)dev;
- struct xlr_net_priv *priv = netdev_priv(ndev);
- struct phy_device *phydev = xlr_get_phydev(priv);
-
- if (phydev->link)
- netif_tx_wake_queue(netdev_get_tx_queue(ndev, priv->wakeup_q));
-}
-
static netdev_tx_t xlr_net_start_xmit(struct sk_buff *skb,
struct net_device *ndev)
{
@@ -413,7 +403,7 @@ static struct rtnl_link_stats64 *xlr_get_stats64(struct net_device *ndev,
return stats;
}
-static struct net_device_ops xlr_netdev_ops = {
+static const struct net_device_ops xlr_netdev_ops = {
.ndo_open = xlr_net_open,
.ndo_stop = xlr_net_stop,
.ndo_start_xmit = xlr_net_start_xmit,
diff --git a/drivers/staging/octeon-usb/Kconfig b/drivers/staging/octeon-usb/Kconfig
index 16ea17ff3fd2..0b8f1d9c7056 100644
--- a/drivers/staging/octeon-usb/Kconfig
+++ b/drivers/staging/octeon-usb/Kconfig
@@ -6,5 +6,5 @@ config OCTEON_USB
Networks' products in the Octeon family.
To compile this driver as a module, choose M here. The module
- will be called octeon-usb.
+ will be called octeon-hcd.
diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c
index 17442b3ed849..9a7858a300fd 100644
--- a/drivers/staging/octeon-usb/octeon-hcd.c
+++ b/drivers/staging/octeon-usb/octeon-hcd.c
@@ -3292,7 +3292,6 @@ static int octeon_usb_hub_status_data(struct usb_hcd *hcd, char *buf)
spin_lock_irqsave(&usb->lock, flags);
port_status = cvmx_usb_get_status(usb);
spin_unlock_irqrestore(&usb->lock, flags);
- buf[0] = 0;
buf[0] = port_status.connect_change << 1;
return buf[0] != 0;
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index 1fde9c824948..691e4a51ace4 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -168,6 +168,7 @@ int cvm_oct_phy_setup_device(struct net_device *dev)
phydev = of_phy_connect(dev, phy_node, cvm_oct_adjust_link, 0,
PHY_INTERFACE_MODE_GMII);
+ of_node_put(phy_node);
if (!phydev)
return -ENODEV;
diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c
index 48846dffc8e1..4e7304210bb9 100644
--- a/drivers/staging/octeon/ethernet-rgmii.c
+++ b/drivers/staging/octeon/ethernet-rgmii.c
@@ -117,7 +117,10 @@ static void cvm_oct_rgmii_poll(struct net_device *dev)
cvmx_helper_link_info_t link_info;
bool status_change;
- link_info = cvmx_helper_link_autoconf(priv->port);
+ link_info = cvmx_helper_link_get(priv->port);
+ if (priv->link_info != link_info.u64 &&
+ cvmx_helper_link_set(priv->port, link_info))
+ link_info.u64 = priv->link_info;
status_change = priv->link_info != link_info.u64;
priv->link_info = link_info.u64;
diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c
index a10fe3af9a9c..f0900d1c4d7b 100644
--- a/drivers/staging/octeon/ethernet-rx.c
+++ b/drivers/staging/octeon/ethernet-rx.c
@@ -43,21 +43,27 @@
#include <asm/octeon/cvmx-gmxx-defs.h>
-static struct napi_struct cvm_oct_napi;
+static atomic_t oct_rx_ready = ATOMIC_INIT(0);
+
+static struct oct_rx_group {
+ int irq;
+ int group;
+ struct napi_struct napi;
+} oct_rx_group[16];
/**
* cvm_oct_do_interrupt - interrupt handler.
- * @cpl: Interrupt number. Unused
- * @dev_id: Cookie to identify the device. Unused
+ * @irq: Interrupt number.
+ * @napi_id: Cookie to identify the NAPI instance.
*
* The interrupt occurs whenever the POW has packets in our group.
*
*/
-static irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id)
+static irqreturn_t cvm_oct_do_interrupt(int irq, void *napi_id)
{
/* Disable the IRQ and start napi_poll. */
- disable_irq_nosync(OCTEON_IRQ_WORKQ0 + pow_receive_group);
- napi_schedule(&cvm_oct_napi);
+ disable_irq_nosync(irq);
+ napi_schedule(napi_id);
return IRQ_HANDLED;
}
@@ -143,14 +149,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
return 0;
}
-/**
- * cvm_oct_napi_poll - the NAPI poll function.
- * @napi: The NAPI instance, or null if called from cvm_oct_poll_controller
- * @budget: Maximum number of packets to receive.
- *
- * Returns the number of packets processed.
- */
-static int cvm_oct_napi_poll(struct napi_struct *napi, int budget)
+static int cvm_oct_poll(struct oct_rx_group *rx_group, int budget)
{
const int coreid = cvmx_get_core_num();
u64 old_group_mask;
@@ -172,13 +171,13 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget)
if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
old_group_mask = cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid));
cvmx_write_csr(CVMX_SSO_PPX_GRP_MSK(coreid),
- 1ull << pow_receive_group);
+ BIT(rx_group->group));
cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid)); /* Flush */
} else {
old_group_mask = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(coreid));
cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid),
(old_group_mask & ~0xFFFFull) |
- 1 << pow_receive_group);
+ BIT(rx_group->group));
}
if (USE_ASYNC_IOBDMA) {
@@ -203,15 +202,15 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget)
if (!work) {
if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
cvmx_write_csr(CVMX_SSO_WQ_IQ_DIS,
- 1ull << pow_receive_group);
+ BIT(rx_group->group));
cvmx_write_csr(CVMX_SSO_WQ_INT,
- 1ull << pow_receive_group);
+ BIT(rx_group->group));
} else {
union cvmx_pow_wq_int wq_int;
wq_int.u64 = 0;
- wq_int.s.iq_dis = 1 << pow_receive_group;
- wq_int.s.wq_int = 1 << pow_receive_group;
+ wq_int.s.iq_dis = BIT(rx_group->group);
+ wq_int.s.wq_int = BIT(rx_group->group);
cvmx_write_csr(CVMX_POW_WQ_INT, wq_int.u64);
}
break;
@@ -410,10 +409,28 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget)
}
cvm_oct_rx_refill_pool(0);
- if (rx_count < budget && napi) {
+ return rx_count;
+}
+
+/**
+ * cvm_oct_napi_poll - the NAPI poll function.
+ * @napi: The NAPI instance.
+ * @budget: Maximum number of packets to receive.
+ *
+ * Returns the number of packets processed.
+ */
+static int cvm_oct_napi_poll(struct napi_struct *napi, int budget)
+{
+ struct oct_rx_group *rx_group = container_of(napi, struct oct_rx_group,
+ napi);
+ int rx_count;
+
+ rx_count = cvm_oct_poll(rx_group, budget);
+
+ if (rx_count < budget) {
/* No more work */
napi_complete(napi);
- enable_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group);
+ enable_irq(rx_group->irq);
}
return rx_count;
}
@@ -427,7 +444,17 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget)
*/
void cvm_oct_poll_controller(struct net_device *dev)
{
- cvm_oct_napi_poll(NULL, 16);
+ int i;
+
+ if (!atomic_read(&oct_rx_ready))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(oct_rx_group); i++) {
+ if (!(pow_receive_groups & BIT(i)))
+ continue;
+
+ cvm_oct_poll(&oct_rx_group[i], 16);
+ }
}
#endif
@@ -446,54 +473,80 @@ void cvm_oct_rx_initialize(void)
if (!dev_for_napi)
panic("No net_devices were allocated.");
- netif_napi_add(dev_for_napi, &cvm_oct_napi, cvm_oct_napi_poll,
- rx_napi_weight);
- napi_enable(&cvm_oct_napi);
+ for (i = 0; i < ARRAY_SIZE(oct_rx_group); i++) {
+ int ret;
- /* Register an IRQ handler to receive POW interrupts */
- i = request_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group,
- cvm_oct_do_interrupt, 0, "Ethernet", cvm_oct_device);
+ if (!(pow_receive_groups & BIT(i)))
+ continue;
- if (i)
- panic("Could not acquire Ethernet IRQ %d\n",
- OCTEON_IRQ_WORKQ0 + pow_receive_group);
+ netif_napi_add(dev_for_napi, &oct_rx_group[i].napi,
+ cvm_oct_napi_poll, rx_napi_weight);
+ napi_enable(&oct_rx_group[i].napi);
- disable_irq_nosync(OCTEON_IRQ_WORKQ0 + pow_receive_group);
+ oct_rx_group[i].irq = OCTEON_IRQ_WORKQ0 + i;
+ oct_rx_group[i].group = i;
- /* Enable POW interrupt when our port has at least one packet */
- if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
- union cvmx_sso_wq_int_thrx int_thr;
- union cvmx_pow_wq_int_pc int_pc;
-
- int_thr.u64 = 0;
- int_thr.s.tc_en = 1;
- int_thr.s.tc_thr = 1;
- cvmx_write_csr(CVMX_SSO_WQ_INT_THRX(pow_receive_group),
- int_thr.u64);
-
- int_pc.u64 = 0;
- int_pc.s.pc_thr = 5;
- cvmx_write_csr(CVMX_SSO_WQ_INT_PC, int_pc.u64);
- } else {
- union cvmx_pow_wq_int_thrx int_thr;
- union cvmx_pow_wq_int_pc int_pc;
-
- int_thr.u64 = 0;
- int_thr.s.tc_en = 1;
- int_thr.s.tc_thr = 1;
- cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group),
- int_thr.u64);
-
- int_pc.u64 = 0;
- int_pc.s.pc_thr = 5;
- cvmx_write_csr(CVMX_POW_WQ_INT_PC, int_pc.u64);
- }
+ /* Register an IRQ handler to receive POW interrupts */
+ ret = request_irq(oct_rx_group[i].irq, cvm_oct_do_interrupt, 0,
+ "Ethernet", &oct_rx_group[i].napi);
+ if (ret)
+ panic("Could not acquire Ethernet IRQ %d\n",
+ oct_rx_group[i].irq);
+
+ disable_irq_nosync(oct_rx_group[i].irq);
+
+ /* Enable POW interrupt when our port has at least one packet */
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
+ union cvmx_sso_wq_int_thrx int_thr;
+ union cvmx_pow_wq_int_pc int_pc;
+
+ int_thr.u64 = 0;
+ int_thr.s.tc_en = 1;
+ int_thr.s.tc_thr = 1;
+ cvmx_write_csr(CVMX_SSO_WQ_INT_THRX(i), int_thr.u64);
+
+ int_pc.u64 = 0;
+ int_pc.s.pc_thr = 5;
+ cvmx_write_csr(CVMX_SSO_WQ_INT_PC, int_pc.u64);
+ } else {
+ union cvmx_pow_wq_int_thrx int_thr;
+ union cvmx_pow_wq_int_pc int_pc;
+
+ int_thr.u64 = 0;
+ int_thr.s.tc_en = 1;
+ int_thr.s.tc_thr = 1;
+ cvmx_write_csr(CVMX_POW_WQ_INT_THRX(i), int_thr.u64);
- /* Schedule NAPI now. This will indirectly enable the interrupt. */
- napi_schedule(&cvm_oct_napi);
+ int_pc.u64 = 0;
+ int_pc.s.pc_thr = 5;
+ cvmx_write_csr(CVMX_POW_WQ_INT_PC, int_pc.u64);
+ }
+
+ /* Schedule NAPI now. This will indirectly enable the
+ * interrupt.
+ */
+ napi_schedule(&oct_rx_group[i].napi);
+ }
+ atomic_inc(&oct_rx_ready);
}
void cvm_oct_rx_shutdown(void)
{
- netif_napi_del(&cvm_oct_napi);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(oct_rx_group); i++) {
+ if (!(pow_receive_groups & BIT(i)))
+ continue;
+
+ /* Disable POW interrupt */
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ cvmx_write_csr(CVMX_SSO_WQ_INT_THRX(i), 0);
+ else
+ cvmx_write_csr(CVMX_POW_WQ_INT_THRX(i), 0);
+
+ /* Free the interrupt handler */
+ free_irq(oct_rx_group[i].irq, cvm_oct_device);
+
+ netif_napi_del(&oct_rx_group[i].napi);
+ }
}
diff --git a/drivers/staging/octeon/ethernet-util.h b/drivers/staging/octeon/ethernet-util.h
index 45f024bc5e33..617da8037a4d 100644
--- a/drivers/staging/octeon/ethernet-util.h
+++ b/drivers/staging/octeon/ethernet-util.h
@@ -32,12 +32,13 @@ static inline void *cvm_oct_get_buffer_ptr(union cvmx_buf_ptr packet_ptr)
*/
static inline int INTERFACE(int ipd_port)
{
- int interface = cvmx_helper_get_interface_num(ipd_port);
+ int interface;
+ if (ipd_port == CVMX_PIP_NUM_INPUT_PORTS)
+ return 10;
+ interface = cvmx_helper_get_interface_num(ipd_port);
if (interface >= 0)
return interface;
- else if (ipd_port == CVMX_PIP_NUM_INPUT_PORTS)
- return 10;
panic("Illegal ipd_port %d passed to INTERFACE\n", ipd_port);
}
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index 45d576361319..d02e3e31ed29 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -17,6 +17,8 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/of_net.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
#include <net/dst.h>
@@ -35,17 +37,19 @@
#include <asm/octeon/cvmx-fau.h>
#include <asm/octeon/cvmx-ipd.h>
#include <asm/octeon/cvmx-helper.h>
-
+#include <asm/octeon/cvmx-asxx-defs.h>
#include <asm/octeon/cvmx-gmxx-defs.h>
#include <asm/octeon/cvmx-smix-defs.h>
+#define OCTEON_MAX_MTU 65392
+
static int num_packet_buffers = 1024;
module_param(num_packet_buffers, int, 0444);
MODULE_PARM_DESC(num_packet_buffers, "\n"
"\tNumber of packet buffers to allocate and store in the\n"
"\tFPA. By default, 1024 packet buffers are used.\n");
-int pow_receive_group = 15;
+static int pow_receive_group = 15;
module_param(pow_receive_group, int, 0444);
MODULE_PARM_DESC(pow_receive_group, "\n"
"\tPOW group to receive packets from. All ethernet hardware\n"
@@ -53,6 +57,15 @@ MODULE_PARM_DESC(pow_receive_group, "\n"
"\tgroup. Also any other software can submit packets to this\n"
"\tgroup for the kernel to process.");
+static int receive_group_order;
+module_param(receive_group_order, int, 0444);
+MODULE_PARM_DESC(receive_group_order, "\n"
+ "\tOrder (0..4) of receive groups to take into use. Ethernet hardware\n"
+ "\twill be configured to send incoming packets to multiple POW\n"
+ "\tgroups. pow_receive_group parameter is ignored when multiple\n"
+ "\tgroups are taken into use and groups are allocated starting\n"
+ "\tfrom 0. By default, a single group is used.\n");
+
int pow_send_group = -1;
module_param(pow_send_group, int, 0644);
MODULE_PARM_DESC(pow_send_group, "\n"
@@ -86,6 +99,8 @@ int rx_napi_weight = 32;
module_param(rx_napi_weight, int, 0444);
MODULE_PARM_DESC(rx_napi_weight, "The NAPI WEIGHT parameter.");
+/* Mask indicating which receive groups are in use. */
+int pow_receive_groups;
/*
* cvm_oct_poll_queue_stopping - flag to indicate polling should stop.
@@ -237,21 +252,22 @@ static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu)
{
struct octeon_ethernet *priv = netdev_priv(dev);
int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
- int vlan_bytes = 4;
+#if IS_ENABLED(CONFIG_VLAN_8021Q)
+ int vlan_bytes = VLAN_HLEN;
#else
int vlan_bytes = 0;
#endif
+ int mtu_overhead = ETH_HLEN + ETH_FCS_LEN + vlan_bytes;
/*
* Limit the MTU to make sure the ethernet packets are between
* 64 bytes and 65535 bytes.
*/
- if ((new_mtu + 14 + 4 + vlan_bytes < 64) ||
- (new_mtu + 14 + 4 + vlan_bytes > 65392)) {
+ if ((new_mtu + mtu_overhead < VLAN_ETH_ZLEN) ||
+ (new_mtu + mtu_overhead > OCTEON_MAX_MTU)) {
pr_err("MTU must be between %d and %d.\n",
- 64 - 14 - 4 - vlan_bytes, 65392 - 14 - 4 - vlan_bytes);
+ VLAN_ETH_ZLEN - mtu_overhead,
+ OCTEON_MAX_MTU - mtu_overhead);
return -EINVAL;
}
dev->mtu = new_mtu;
@@ -259,8 +275,9 @@ static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu)
if ((interface < 2) &&
(cvmx_helper_interface_get_mode(interface) !=
CVMX_HELPER_INTERFACE_MODE_SPI)) {
+ int index = INDEX(priv->port);
/* Add ethernet header and FCS, and VLAN if configured. */
- int max_packet = new_mtu + 14 + 4 + vlan_bytes;
+ int max_packet = new_mtu + mtu_overhead;
if (OCTEON_IS_MODEL(OCTEON_CN3XXX) ||
OCTEON_IS_MODEL(OCTEON_CN58XX)) {
@@ -275,7 +292,7 @@ static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu)
union cvmx_pip_frm_len_chkx frm_len_chk;
frm_len_chk.u64 = 0;
- frm_len_chk.s.minlen = 64;
+ frm_len_chk.s.minlen = VLAN_ETH_ZLEN;
frm_len_chk.s.maxlen = max_packet;
cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface),
frm_len_chk.u64);
@@ -300,12 +317,12 @@ static void cvm_oct_common_set_multicast_list(struct net_device *dev)
union cvmx_gmxx_prtx_cfg gmx_cfg;
struct octeon_ethernet *priv = netdev_priv(dev);
int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
if ((interface < 2) &&
(cvmx_helper_interface_get_mode(interface) !=
CVMX_HELPER_INTERFACE_MODE_SPI)) {
union cvmx_gmxx_rxx_adr_ctl control;
+ int index = INDEX(priv->port);
control.u64 = 0;
control.s.bcst = 1; /* Allow broadcast MAC addresses */
@@ -352,7 +369,6 @@ static int cvm_oct_set_mac_filter(struct net_device *dev)
struct octeon_ethernet *priv = netdev_priv(dev);
union cvmx_gmxx_prtx_cfg gmx_cfg;
int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
if ((interface < 2) &&
(cvmx_helper_interface_get_mode(interface) !=
@@ -360,6 +376,7 @@ static int cvm_oct_set_mac_filter(struct net_device *dev)
int i;
u8 *ptr = dev->dev_addr;
u64 mac = 0;
+ int index = INDEX(priv->port);
for (i = 0; i < 6; i++)
mac = (mac << 8) | (u64)ptr[i];
@@ -477,6 +494,8 @@ int cvm_oct_common_open(struct net_device *dev,
gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
gmx_cfg.s.en = 1;
+ if (octeon_has_feature(OCTEON_FEATURE_PKND))
+ gmx_cfg.s.pknd = priv->port;
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
if (octeon_is_simulation())
@@ -508,8 +527,10 @@ void cvm_oct_link_poll(struct net_device *dev)
if (link_info.u64 == priv->link_info)
return;
- link_info = cvmx_helper_link_autoconf(priv->port);
- priv->link_info = link_info.u64;
+ if (cvmx_helper_link_set(priv->port, link_info))
+ link_info.u64 = priv->link_info;
+ else
+ priv->link_info = link_info.u64;
if (link_info.s.link_up) {
if (!netif_carrier_ok(dev))
@@ -647,6 +668,16 @@ static struct device_node *cvm_oct_node_for_port(struct device_node *pip,
return np;
}
+static void cvm_set_rgmii_delay(struct device_node *np, int iface, int port)
+{
+ u32 delay_value;
+
+ if (!of_property_read_u32(np, "rx-delay", &delay_value))
+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, iface), delay_value);
+ if (!of_property_read_u32(np, "tx-delay", &delay_value))
+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, iface), delay_value);
+}
+
static int cvm_oct_probe(struct platform_device *pdev)
{
int num_interfaces;
@@ -663,11 +694,18 @@ static int cvm_oct_probe(struct platform_device *pdev)
return -EINVAL;
}
-
cvm_oct_configure_common_hw();
cvmx_helper_initialize_packet_io_global();
+ if (receive_group_order) {
+ if (receive_group_order > 4)
+ receive_group_order = 4;
+ pow_receive_groups = (1 << (1 << receive_group_order)) - 1;
+ } else {
+ pow_receive_groups = BIT(pow_receive_group);
+ }
+
/* Change the input group for all ports before input is enabled */
num_interfaces = cvmx_helper_get_number_of_interfaces();
for (interface = 0; interface < num_interfaces; interface++) {
@@ -681,7 +719,37 @@ static int cvm_oct_probe(struct platform_device *pdev)
pip_prt_tagx.u64 =
cvmx_read_csr(CVMX_PIP_PRT_TAGX(port));
- pip_prt_tagx.s.grp = pow_receive_group;
+
+ if (receive_group_order) {
+ int tag_mask;
+
+ /* We support only 16 groups at the moment, so
+ * always disable the two additional "hidden"
+ * tag_mask bits on CN68XX.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ pip_prt_tagx.u64 |= 0x3ull << 44;
+
+ tag_mask = ~((1 << receive_group_order) - 1);
+ pip_prt_tagx.s.grptagbase = 0;
+ pip_prt_tagx.s.grptagmask = tag_mask;
+ pip_prt_tagx.s.grptag = 1;
+ pip_prt_tagx.s.tag_mode = 0;
+ pip_prt_tagx.s.inc_prt_flag = 1;
+ pip_prt_tagx.s.ip6_dprt_flag = 1;
+ pip_prt_tagx.s.ip4_dprt_flag = 1;
+ pip_prt_tagx.s.ip6_sprt_flag = 1;
+ pip_prt_tagx.s.ip4_sprt_flag = 1;
+ pip_prt_tagx.s.ip6_dst_flag = 1;
+ pip_prt_tagx.s.ip4_dst_flag = 1;
+ pip_prt_tagx.s.ip6_src_flag = 1;
+ pip_prt_tagx.s.ip4_src_flag = 1;
+ pip_prt_tagx.s.grp = 0;
+ } else {
+ pip_prt_tagx.s.grptag = 0;
+ pip_prt_tagx.s.grp = pow_receive_group;
+ }
+
cvmx_write_csr(CVMX_PIP_PRT_TAGX(port),
pip_prt_tagx.u64);
}
@@ -703,7 +771,6 @@ static int cvm_oct_probe(struct platform_device *pdev)
if ((pow_send_group != -1)) {
struct net_device *dev;
- pr_info("\tConfiguring device for POW only access\n");
dev = alloc_etherdev(sizeof(struct octeon_ethernet));
if (dev) {
/* Initialize the device private structure. */
@@ -806,6 +873,8 @@ static int cvm_oct_probe(struct platform_device *pdev)
case CVMX_HELPER_INTERFACE_MODE_GMII:
dev->netdev_ops = &cvm_oct_rgmii_netdev_ops;
strcpy(dev->name, "eth%d");
+ cvm_set_rgmii_delay(priv->of_node, interface,
+ port_index);
break;
}
@@ -842,17 +911,8 @@ static int cvm_oct_remove(struct platform_device *pdev)
{
int port;
- /* Disable POW interrupt */
- if (OCTEON_IS_MODEL(OCTEON_CN68XX))
- cvmx_write_csr(CVMX_SSO_WQ_INT_THRX(pow_receive_group), 0);
- else
- cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0);
-
cvmx_ipd_disable();
- /* Free the interrupt handler */
- free_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group, cvm_oct_device);
-
atomic_inc_return(&cvm_oct_poll_queue_stopping);
cancel_delayed_work_sync(&cvm_oct_rx_refill_work);
@@ -876,7 +936,6 @@ static int cvm_oct_remove(struct platform_device *pdev)
}
}
-
cvmx_pko_shutdown();
cvmx_ipd_free_ptr();
diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h
index d533aefe085a..9c6852d61c0d 100644
--- a/drivers/staging/octeon/octeon-ethernet.h
+++ b/drivers/staging/octeon/octeon-ethernet.h
@@ -72,7 +72,7 @@ void cvm_oct_link_poll(struct net_device *dev);
extern int always_use_pow;
extern int pow_send_group;
-extern int pow_receive_group;
+extern int pow_receive_groups;
extern char pow_send_list[];
extern struct net_device *cvm_oct_device[];
extern atomic_t cvm_oct_poll_queue_stopping;
diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
index 6a4d379c16a3..1e23ef15b263 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
@@ -49,7 +49,7 @@ static void dcon_clear_irq(void)
static int dcon_was_irq(void)
{
- u_int8_t tmp;
+ u8 tmp;
/* irq status will appear in PMIO_Rx50[6] on gpio12 */
tmp = inb(VX855_GPI_STATUS_CHG);
diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c
index a5755358cc5d..553e8d50352f 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ap.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ap.c
@@ -78,9 +78,9 @@ static void update_BCNTIM(struct adapter *padapter)
/* update TIM IE */
p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen,
pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);
- if (p != NULL && tim_ielen > 0) {
+ if (p && tim_ielen > 0) {
tim_ielen += 2;
- premainder_ie = p+tim_ielen;
+ premainder_ie = p + tim_ielen;
tim_ie_offset = (int)(p - pie);
remainder_ielen = pnetwork_mlmeext->IELength -
tim_ie_offset - tim_ielen;
@@ -98,7 +98,7 @@ static void update_BCNTIM(struct adapter *padapter)
_SUPPORTEDRATES_IE_, &tmp_len,
(pnetwork_mlmeext->IELength -
_BEACON_IE_OFFSET_));
- if (p != NULL)
+ if (p)
offset += tmp_len+2;
/* DS Parameter Set IE, len = 3 */
@@ -183,10 +183,10 @@ void rtw_add_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork,
i += (pIE->Length + 2);
}
- if (p != NULL && ielen > 0) {
+ if (p && ielen > 0) {
ielen += 2;
- premainder_ie = p+ielen;
+ premainder_ie = p + ielen;
ie_offset = (int)(p - pie);
@@ -195,7 +195,7 @@ void rtw_add_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork,
if (bmatch)
dst_ie = p;
else
- dst_ie = p+ielen;
+ dst_ie = p + ielen;
}
if (remainder_ielen > 0) {
@@ -232,10 +232,10 @@ void rtw_remove_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork,
p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, index, &ielen,
pnetwork->IELength - _FIXED_IE_LENGTH_);
- if (p != NULL && ielen > 0) {
+ if (p && ielen > 0) {
ielen += 2;
- premainder_ie = p+ielen;
+ premainder_ie = p + ielen;
ie_offset = (int)(p - pie);
@@ -385,8 +385,8 @@ void expire_timeout_chk(struct adapter *padapter)
updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
} else {
/* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */
- if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt) &&
- padapter->xmitpriv.free_xmitframe_cnt < (NR_XMITFRAME/pstapriv->asoc_list_cnt/2)) {
+ if (psta->sleepq_len > (NR_XMITFRAME / pstapriv->asoc_list_cnt) &&
+ padapter->xmitpriv.free_xmitframe_cnt < (NR_XMITFRAME / pstapriv->asoc_list_cnt / 2)) {
DBG_88E("%s sta:%pM, sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__,
(psta->hwaddr), psta->sleepq_len,
padapter->xmitpriv.free_xmitframe_cnt,
@@ -470,7 +470,7 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
/* b/g mode ra_bitmap */
for (i = 0; i < sizeof(psta->bssrateset); i++) {
if (psta->bssrateset[i])
- tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
+ tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
}
/* n mode ra_bitmap */
if (psta_ht->ht_option) {
@@ -481,8 +481,8 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
limit = 8;/* 1R */
for (i = 0; i < limit; i++) {
- if (psta_ht->ht_cap.supp_mcs_set[i/8] & BIT(i%8))
- tx_ra_bitmap |= BIT(i+12);
+ if (psta_ht->ht_cap.mcs.rx_mask[i / 8] & BIT(i % 8))
+ tx_ra_bitmap |= BIT(i + 12);
}
/* max short GI rate */
@@ -507,19 +507,19 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
psta->wireless_mode = sta_band;
raid = networktype_to_raid(sta_band);
- init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f;
+ init_rate = get_highest_rate_idx(tx_ra_bitmap & 0x0fffffff) & 0x3f;
if (psta->aid < NUM_STA) {
u8 arg = 0;
- arg = psta->mac_id&0x1f;
+ arg = psta->mac_id & 0x1f;
arg |= BIT(7);/* support entry 2~31 */
if (shortGIrate)
arg |= BIT(5);
- tx_ra_bitmap |= ((raid<<28)&0xf0000000);
+ tx_ra_bitmap |= ((raid << 28) & 0xf0000000);
DBG_88E("%s => mac_id:%d , raid:%d , bitmap = 0x%x, arg = 0x%x\n",
__func__, psta->mac_id, raid, tx_ra_bitmap, arg);
@@ -573,7 +573,7 @@ static void update_bmc_sta(struct adapter *padapter)
/* b/g mode ra_bitmap */
for (i = 0; i < supportRateNum; i++) {
if (psta->bssrateset[i])
- tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
+ tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
}
if (pcur_network->Configuration.DSConfig > 14) {
@@ -587,7 +587,7 @@ static void update_bmc_sta(struct adapter *padapter)
}
raid = networktype_to_raid(network_type);
- init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f;
+ init_rate = get_highest_rate_idx(tx_ra_bitmap & 0x0fffffff) & 0x3f;
/* ap mode */
rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
@@ -597,7 +597,7 @@ static void update_bmc_sta(struct adapter *padapter)
arg = psta->mac_id&0x1f;
arg |= BIT(7);
- tx_ra_bitmap |= ((raid<<28)&0xf0000000);
+ tx_ra_bitmap |= ((raid << 28) & 0xf0000000);
DBG_88E("update_bmc_sta, mask = 0x%x, arg = 0x%x\n", tx_ra_bitmap, arg);
/* bitmap[0:27] = tx_rate_bitmap */
@@ -636,7 +636,7 @@ void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta)
struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
struct ht_priv *phtpriv_sta = &psta->htpriv;
- psta->mac_id = psta->aid+1;
+ psta->mac_id = psta->aid + 1;
DBG_88E("%s\n", __func__);
/* ap mode */
@@ -658,11 +658,15 @@ void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta)
phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
/* check if sta support s Short GI */
- if ((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40))
+ if (le16_to_cpu(phtpriv_sta->ht_cap.cap_info &
+ phtpriv_ap->ht_cap.cap_info) &
+ (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40))
phtpriv_sta->sgi = true;
/* bwmode */
- if ((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & IEEE80211_HT_CAP_SUP_WIDTH) {
+ if (le16_to_cpu(phtpriv_sta->ht_cap.cap_info &
+ phtpriv_ap->ht_cap.cap_info) &
+ IEEE80211_HT_CAP_SUP_WIDTH) {
phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
}
@@ -702,12 +706,12 @@ static void update_hw_ht_param(struct adapter *padapter)
/* handle A-MPDU parameter field */
/*
- AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
- AMPDU_para [4:2]:Min MPDU Start Spacing
+ ampdu_params_info [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
+ ampdu_params_info [4:2]:Min MPDU Start Spacing
*/
- max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
+ max_AMPDU_len = pmlmeinfo->HT_caps.ampdu_params_info & 0x03;
- min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
+ min_MPDU_spacing = (pmlmeinfo->HT_caps.ampdu_params_info & 0x1c) >> 2;
rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
@@ -716,7 +720,7 @@ static void update_hw_ht_param(struct adapter *padapter)
/* */
/* Config SM Power Save setting */
/* */
- pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & 0x0C) >> 2;
+ pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.cap_info) & 0x0C) >> 2;
if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
}
@@ -746,7 +750,7 @@ static void start_bss_network(struct adapter *padapter, u8 *pbuf)
/* check if there is wps ie, */
/* if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, */
/* and at first time the security ie (RSN/WPA IE) will not include in beacon. */
- if (!rtw_get_wps_ie(pnetwork->IEs+_FIXED_IE_LENGTH_, pnetwork->IELength-_FIXED_IE_LENGTH_, NULL, NULL))
+ if (!rtw_get_wps_ie(pnetwork->IEs + _FIXED_IE_LENGTH_, pnetwork->IELength - _FIXED_IE_LENGTH_, NULL, NULL))
pmlmeext->bstart_bss = true;
/* todo: update wmm, ht cap */
@@ -799,7 +803,7 @@ static void start_bss_network(struct adapter *padapter, u8 *pbuf)
/* set channel, bwmode */
p = rtw_get_ie((pnetwork->IEs + sizeof(struct ndis_802_11_fixed_ie)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(struct ndis_802_11_fixed_ie)));
if (p && ie_len) {
- pht_info = (struct HT_info_element *)(p+2);
+ pht_info = (struct HT_info_element *)(p + 2);
if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2))) {
/* switch to the 40M Hz mode */
@@ -930,15 +934,15 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
/* get supported rates */
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
- if (p != NULL) {
- memcpy(supportRate, p+2, ie_len);
+ if (p) {
+ memcpy(supportRate, p + 2, ie_len);
supportRateNum = ie_len;
}
/* get ext_supported rates */
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_);
- if (p != NULL) {
- memcpy(supportRate+supportRateNum, p+2, ie_len);
+ if (p) {
+ memcpy(supportRate + supportRateNum, p + 2, ie_len);
supportRateNum += ie_len;
}
@@ -966,7 +970,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
if (p && ie_len > 0) {
- if (rtw_parse_wpa2_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
+ if (rtw_parse_wpa2_ie(p, ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
psecuritypriv->dot8021xalg = 1;/* psk, todo:802.1x */
@@ -985,8 +989,8 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) {
p = rtw_get_ie(p, _SSN_IE_1_, &ie_len,
(pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
- if ((p) && (!memcmp(p+2, OUI1, 4))) {
- if (rtw_parse_wpa_ie(p, ie_len+2, &group_cipher,
+ if ((p) && (!memcmp(p + 2, OUI1, 4))) {
+ if (rtw_parse_wpa_ie(p, ie_len + 2, &group_cipher,
&pairwise_cipher, NULL) == _SUCCESS) {
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
@@ -1010,10 +1014,10 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) {
p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len,
(pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
- if ((p) && !memcmp(p+2, WMM_PARA_IE, 6)) {
+ if ((p) && !memcmp(p + 2, WMM_PARA_IE, 6)) {
pmlmepriv->qospriv.qos_option = 1;
- *(p+8) |= BIT(7);/* QoS Info, support U-APSD */
+ *(p + 8) |= BIT(7);/* QoS Info, support U-APSD */
/* disable all ACM bits since the WMM admission control is not supported */
*(p + 10) &= ~BIT(4); /* BE */
@@ -1032,7 +1036,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
(pbss_network->IELength - _BEACON_IE_OFFSET_));
if (p && ie_len > 0) {
u8 rf_type;
- struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p+2);
+ struct ieee80211_ht_cap *pht_cap = (struct ieee80211_ht_cap *)(p + 2);
pHT_caps_ie = p;
ht_cap = true;
@@ -1042,7 +1046,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
(psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))
- pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
+ pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & (0x07 << 2));
else
pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
@@ -1050,8 +1054,8 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03);
if (rf_type == RF_1T1R) {
- pht_cap->supp_mcs_set[0] = 0xff;
- pht_cap->supp_mcs_set[1] = 0x0;
+ pht_cap->mcs.rx_mask[0] = 0xff;
+ pht_cap->mcs.rx_mask[1] = 0x0;
}
memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len);
}
@@ -1143,7 +1147,7 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
DBG_88E("%s(acl_num =%d) =%pM\n", __func__, pacl_list->num, (addr));
- if ((NUM_ACL-1) < pacl_list->num)
+ if ((NUM_ACL - 1) < pacl_list->num)
return -1;
spin_lock_bh(&(pacl_node_q->lock));
@@ -1422,7 +1426,8 @@ static int rtw_ht_operation_update(struct adapter *padapter)
if (pmlmepriv->num_sta_no_ht ||
(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
new_op_mode = OP_MODE_MIXED;
- else if ((phtpriv_ap->ht_cap.cap_info & IEEE80211_HT_CAP_SUP_WIDTH) &&
+ else if ((le16_to_cpu(phtpriv_ap->ht_cap.cap_info) &
+ IEEE80211_HT_CAP_SUP_WIDTH) &&
pmlmepriv->num_sta_ht_20mhz)
new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
else if (pmlmepriv->olbc_ht)
@@ -1552,7 +1557,7 @@ void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta)
}
if (psta->flags & WLAN_STA_HT) {
- u16 ht_capab = psta->htpriv.ht_cap.cap_info;
+ u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);
DBG_88E("HT: STA %pM HT Capabilities Info: 0x%04x\n",
(psta->hwaddr), ht_capab);
@@ -1710,40 +1715,6 @@ u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta,
return beacon_updated;
}
-int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset)
-{
- struct list_head *phead, *plist;
- struct sta_info *psta = NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
- if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
- return 0;
-
- DBG_88E(FUNC_NDEV_FMT" with ch:%u, offset:%u\n",
- FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset);
-
- spin_lock_bh(&pstapriv->asoc_list_lock);
- phead = &pstapriv->asoc_list;
- plist = phead->next;
-
- /* for each sta in asoc_queue */
- while (phead != plist) {
- psta = container_of(plist, struct sta_info, asoc_list);
- plist = plist->next;
-
- issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset);
- psta->expire_to = min_t(unsigned int, pstapriv->expire_to * 2, 5);
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
-
- issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset);
-
- return 0;
-}
-
int rtw_sta_flush(struct adapter *padapter)
{
struct list_head *phead, *plist;
@@ -1856,9 +1827,6 @@ void start_ap_mode(struct adapter *padapter)
pmlmepriv->wps_probe_resp_ie = NULL;
pmlmepriv->wps_assoc_resp_ie = NULL;
- pmlmepriv->p2p_beacon_ie = NULL;
- pmlmepriv->p2p_probe_resp_ie = NULL;
-
/* for ACL */
INIT_LIST_HEAD(&(pacl_list->acl_node_q.queue));
pacl_list->num = 0;
diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c
index 77485235c615..f1f4788dbd86 100644
--- a/drivers/staging/rtl8188eu/core/rtw_cmd.c
+++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c
@@ -27,8 +27,8 @@ No irqsave is necessary.
int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
{
- sema_init(&(pcmdpriv->cmd_queue_sema), 0);
- sema_init(&(pcmdpriv->terminate_cmdthread_sema), 0);
+ init_completion(&pcmdpriv->cmd_queue_comp);
+ init_completion(&pcmdpriv->terminate_cmdthread_comp);
_rtw_init_queue(&(pcmdpriv->cmd_queue));
return _SUCCESS;
@@ -85,7 +85,7 @@ static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
/* To decide allow or not */
if ((pcmdpriv->padapter->pwrctrlpriv.bHWPwrPindetect) &&
(!pcmdpriv->padapter->registrypriv.usbss_enable)) {
- if (cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) {
+ if (cmd_obj->cmdcode == _Set_Drv_Extra_CMD_) {
struct drvextra_cmd_parm *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf;
if (pdrvextra_cmd_parm->ec_id == POWER_SAVING_CTRL_WK_CID)
@@ -93,7 +93,7 @@ static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
}
}
- if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan))
+ if (cmd_obj->cmdcode == _SetChannelPlan_CMD_)
bAllow = true;
if ((!pcmdpriv->padapter->hw_init_completed && !bAllow) ||
@@ -122,7 +122,7 @@ u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
res = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, cmd_obj);
if (res == _SUCCESS)
- up(&pcmdpriv->cmd_queue_sema);
+ complete(&pcmdpriv->cmd_queue_comp);
exit:
@@ -162,12 +162,12 @@ int rtw_cmd_thread(void *context)
allow_signal(SIGTERM);
pcmdpriv->cmdthd_running = true;
- up(&pcmdpriv->terminate_cmdthread_sema);
+ complete(&pcmdpriv->terminate_cmdthread_comp);
RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("start r871x rtw_cmd_thread !!!!\n"));
while (1) {
- if (_rtw_down_sema(&pcmdpriv->cmd_queue_sema) == _FAIL)
+ if (wait_for_completion_interruptible(&pcmdpriv->cmd_queue_comp))
break;
if (padapter->bDriverStopped ||
@@ -234,7 +234,7 @@ _next:
rtw_free_cmd_obj(pcmd);
}
- up(&pcmdpriv->terminate_cmdthread_sema);
+ complete(&pcmdpriv->terminate_cmdthread_comp);
complete_and_exit(NULL, 0);
@@ -271,7 +271,7 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid,
RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("%s: flush network queue\n", __func__));
- init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
+ init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, _SiteSurvey_CMD_);
/* psurveyPara->bsslimit = 48; */
psurveyPara->scan_mode = pmlmepriv->scan_mode;
@@ -305,8 +305,6 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid,
res = rtw_enqueue_cmd(pcmdpriv, ph2c);
if (res == _SUCCESS) {
- pmlmepriv->scan_start_time = jiffies;
-
mod_timer(&pmlmepriv->scan_to_timer,
jiffies + msecs_to_jiffies(SCANNING_TIMEOUT));
@@ -491,7 +489,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork)
pcmd->cmdsz = get_wlan_bssid_ex_sz(psecnetwork);/* get cmdsz before endian conversion */
INIT_LIST_HEAD(&pcmd->list);
- pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */
+ pcmd->cmdcode = _JoinBss_CMD_;
pcmd->parmbuf = (unsigned char *)psecnetwork;
pcmd->rsp = NULL;
pcmd->rspsz = 0;
@@ -670,13 +668,13 @@ u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr)
u8 res = _SUCCESS;
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (!ph2c) {
res = _FAIL;
goto exit;
}
- paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_KERNEL);
+ paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_ATOMIC);
if (!paddbareq_parm) {
kfree(ph2c);
res = _FAIL;
@@ -686,7 +684,7 @@ u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr)
paddbareq_parm->tid = tid;
memcpy(paddbareq_parm->addr, addr, ETH_ALEN);
- init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq));
+ init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, _AddBAReq_CMD_);
/* DBG_88E("rtw_addbareq_cmd, tid =%d\n", tid); */
@@ -724,7 +722,7 @@ u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter)
pdrvextra_cmd_parm->type_size = 0;
pdrvextra_cmd_parm->pbuf = (u8 *)padapter;
- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
+ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, _Set_Drv_Extra_CMD_);
/* rtw_enqueue_cmd(pcmdpriv, ph2c); */
@@ -767,7 +765,7 @@ u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue)
goto exit;
}
- init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, GEN_CMD_CODE(_SetChannelPlan));
+ init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, _SetChannelPlan_CMD_);
res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
} else {
/* no need to enqueue, do the cmd hdl directly and free cmd parameter */
@@ -936,7 +934,7 @@ u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue)
pdrvextra_cmd_parm->type_size = lps_ctrl_type;
pdrvextra_cmd_parm->pbuf = NULL;
- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
+ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, _Set_Drv_Extra_CMD_);
res = rtw_enqueue_cmd(pcmdpriv, ph2c);
} else {
@@ -978,7 +976,7 @@ u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 min_time)
pdrvextra_cmd_parm->ec_id = RTP_TIMER_CFG_WK_CID;
pdrvextra_cmd_parm->type_size = min_time;
pdrvextra_cmd_parm->pbuf = NULL;
- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
+ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, _Set_Drv_Extra_CMD_);
res = rtw_enqueue_cmd(pcmdpriv, ph2c);
exit:
@@ -1020,7 +1018,7 @@ u8 rtw_antenna_select_cmd(struct adapter *padapter, u8 antenna, u8 enqueue)
pdrvextra_cmd_parm->ec_id = ANT_SELECT_WK_CID;
pdrvextra_cmd_parm->type_size = antenna;
pdrvextra_cmd_parm->pbuf = NULL;
- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
+ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, _Set_Drv_Extra_CMD_);
res = rtw_enqueue_cmd(pcmdpriv, ph2c);
} else {
@@ -1048,7 +1046,7 @@ u8 rtw_ps_cmd(struct adapter *padapter)
pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID;
pdrvextra_cmd_parm->pbuf = NULL;
- init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
+ init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, _Set_Drv_Extra_CMD_);
return rtw_enqueue_cmd(pcmdpriv, ppscmd);
}
@@ -1119,7 +1117,7 @@ u8 rtw_chk_hi_queue_cmd(struct adapter *padapter)
pdrvextra_cmd_parm->type_size = 0;
pdrvextra_cmd_parm->pbuf = NULL;
- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
+ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, _Set_Drv_Extra_CMD_);
res = rtw_enqueue_cmd(pcmdpriv, ph2c);
exit:
diff --git a/drivers/staging/rtl8188eu/core/rtw_debug.c b/drivers/staging/rtl8188eu/core/rtw_debug.c
index db5c952ac852..60d8c7b9f458 100644
--- a/drivers/staging/rtl8188eu/core/rtw_debug.c
+++ b/drivers/staging/rtl8188eu/core/rtw_debug.c
@@ -138,144 +138,6 @@ int proc_set_read_reg(struct file *file, const char __user *buffer,
return count;
}
-int proc_get_fwstate(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- int len = 0;
-
- len += snprintf(page + len, count - len, "fwstate=0x%x\n", get_fwstate(pmlmepriv));
-
- *eof = 1;
- return len;
-}
-
-int proc_get_sec_info(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct security_priv *psecuritypriv = &padapter->securitypriv;
-
- int len = 0;
-
- len += snprintf(page + len, count - len, "auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",
- psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
- psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
-
- *eof = 1;
- return len;
-}
-
-int proc_get_mlmext_state(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- int len = 0;
-
- len += snprintf(page + len, count - len, "pmlmeinfo->state=0x%x\n", pmlmeinfo->state);
-
- *eof = 1;
- return len;
-}
-
-int proc_get_qos_option(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- int len = 0;
-
- len += snprintf(page + len, count - len, "qos_option=%d\n", pmlmepriv->qospriv.qos_option);
-
- *eof = 1;
- return len;
-}
-
-int proc_get_ht_option(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- int len = 0;
-
- len += snprintf(page + len, count - len, "ht_option=%d\n", pmlmepriv->htpriv.ht_option);
- *eof = 1;
- return len;
-}
-
-int proc_get_rf_info(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- int len = 0;
-
- len += snprintf(page + len, count - len, "cur_ch=%d, cur_bw=%d, cur_ch_offset=%d\n",
- pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
- *eof = 1;
- return len;
-}
-
-int proc_get_ap_info(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct sta_info *psta;
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct wlan_network *cur_network = &pmlmepriv->cur_network;
- struct sta_priv *pstapriv = &padapter->stapriv;
- int len = 0;
-
- psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
- if (psta) {
- int i;
- struct recv_reorder_ctrl *preorder_ctrl;
-
- len += snprintf(page + len, count - len, "SSID=%s\n", cur_network->network.Ssid.Ssid);
- len += snprintf(page + len, count - len, "sta's macaddr:%pM\n", psta->hwaddr);
- len += snprintf(page + len, count - len, "cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
- len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
- len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
- len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
- len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
- len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
- len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
-
- for (i = 0; i < 16; i++) {
- preorder_ctrl = &psta->recvreorder_ctrl[i];
- if (preorder_ctrl->enable)
- len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", i, preorder_ctrl->indicate_seq);
- }
- } else {
- len += snprintf(page + len, count - len, "can't get sta's macaddr, cur_network's macaddr: %pM\n", cur_network->network.MacAddress);
- }
-
- *eof = 1;
- return len;
-}
-
int proc_get_adapter_state(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
@@ -291,599 +153,6 @@ int proc_get_adapter_state(char *page, char **start,
return len;
}
-int proc_get_trx_info(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct recv_priv *precvpriv = &padapter->recvpriv;
- int len = 0;
-
- len += snprintf(page + len, count - len, "free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d, free_ext_xmitbuf_cnt=%d, free_recvframe_cnt=%d\n",
- pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmit_extbuf_cnt, precvpriv->free_recvframe_cnt);
- len += snprintf(page + len, count - len, "rx_urb_pending_cn=%d\n", precvpriv->rx_pending_cnt);
-
- *eof = 1;
- return len;
-}
-
-int proc_get_mac_reg_dump1(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- int len = 0;
- int i, j = 1;
-
- len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
-
- for (i = 0x0; i < 0x300; i += 4) {
- if (j%4 == 1)
- len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", usb_read32(padapter, i));
- if ((j++)%4 == 0)
- len += snprintf(page + len, count - len, "\n");
- }
-
- *eof = 1;
- return len;
-}
-
-int proc_get_mac_reg_dump2(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- int len = 0;
- int i, j = 1;
-
- len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
- memset(page, 0, count);
- for (i = 0x300; i < 0x600; i += 4) {
- if (j%4 == 1)
- len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", usb_read32(padapter, i));
- if ((j++)%4 == 0)
- len += snprintf(page + len, count - len, "\n");
- }
-
- *eof = 1;
- return len;
-}
-
-int proc_get_mac_reg_dump3(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- int len = 0;
- int i, j = 1;
-
- len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
-
- for (i = 0x600; i < 0x800; i += 4) {
- if (j%4 == 1)
- len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", usb_read32(padapter, i));
- if ((j++)%4 == 0)
- len += snprintf(page + len, count - len, "\n");
- }
-
- *eof = 1;
- return len;
-}
-
-int proc_get_bb_reg_dump1(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- int len = 0;
- int i, j = 1;
-
- len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
- for (i = 0x800; i < 0xB00; i += 4) {
- if (j%4 == 1)
- len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", usb_read32(padapter, i));
- if ((j++)%4 == 0)
- len += snprintf(page + len, count - len, "\n");
- }
- *eof = 1;
- return len;
-}
-
-int proc_get_bb_reg_dump2(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- int len = 0;
- int i, j = 1;
-
- len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
- for (i = 0xB00; i < 0xE00; i += 4) {
- if (j%4 == 1)
- len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", usb_read32(padapter, i));
- if ((j++)%4 == 0)
- len += snprintf(page + len, count - len, "\n");
- }
- *eof = 1;
- return len;
-}
-
-int proc_get_bb_reg_dump3(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- int len = 0;
- int i, j = 1;
-
- len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
- for (i = 0xE00; i < 0x1000; i += 4) {
- if (j%4 == 1)
- len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", usb_read32(padapter, i));
- if ((j++)%4 == 0)
- len += snprintf(page + len, count - len, "\n");
- }
- *eof = 1;
- return len;
-}
-
-int proc_get_rf_reg_dump1(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- int len = 0;
- int i, j = 1, path;
- u32 value;
-
- len += snprintf(page + len, count - len, "\n======= RF REG =======\n");
- path = 1;
- len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path);
- for (i = 0; i < 0xC0; i++) {
- value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
- if (j%4 == 1)
- len += snprintf(page + len, count - len, "0x%02x ", i);
- len += snprintf(page + len, count - len, " 0x%08x ", value);
- if ((j++)%4 == 0)
- len += snprintf(page + len, count - len, "\n");
- }
- *eof = 1;
- return len;
-}
-
-int proc_get_rf_reg_dump2(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- int len = 0;
- int i, j = 1, path;
- u32 value;
-
- len += snprintf(page + len, count - len, "\n======= RF REG =======\n");
- path = 1;
- len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path);
- for (i = 0xC0; i < 0x100; i++) {
- value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
- if (j%4 == 1)
- len += snprintf(page + len, count - len, "0x%02x ", i);
- len += snprintf(page + len, count - len, " 0x%08x ", value);
- if ((j++)%4 == 0)
- len += snprintf(page + len, count - len, "\n");
- }
- *eof = 1;
- return len;
-}
-
-int proc_get_rf_reg_dump3(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- int len = 0;
- int i, j = 1, path;
- u32 value;
-
- len += snprintf(page + len, count - len, "\n======= RF REG =======\n");
- path = 2;
- len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path);
- for (i = 0; i < 0xC0; i++) {
- value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
- if (j%4 == 1)
- len += snprintf(page + len, count - len, "0x%02x ", i);
- len += snprintf(page + len, count - len, " 0x%08x ", value);
- if ((j++)%4 == 0)
- len += snprintf(page + len, count - len, "\n");
- }
-
- *eof = 1;
- return len;
-}
-
-
-int proc_get_rf_reg_dump4(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- int len = 0;
- int i, j = 1, path;
- u32 value;
-
- len += snprintf(page + len, count - len, "\n======= RF REG =======\n");
- path = 2;
- len += snprintf(page + len, count - len, "\nRF_Path(%x)\n", path);
- for (i = 0xC0; i < 0x100; i++) {
- value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
- if (j%4 == 1)
- len += snprintf(page + len, count - len, "0x%02x ", i);
- len += snprintf(page + len, count - len, " 0x%08x ", value);
- if ((j++)%4 == 0)
- len += snprintf(page + len, count - len, "\n");
- }
- *eof = 1;
- return len;
-}
-
-
-
-int proc_get_rx_signal(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- int len = 0;
-
- len = snprintf(page + len, count,
- "rssi:%d\n"
- "rxpwdb:%d\n"
- "signal_strength:%u\n"
- "signal_qual:%u\n"
- "noise:%u\n",
- padapter->recvpriv.rssi,
- padapter->recvpriv.rxpwdb,
- padapter->recvpriv.signal_strength,
- padapter->recvpriv.signal_qual,
- padapter->recvpriv.noise
- );
-
- *eof = 1;
- return len;
-}
-
-int proc_set_rx_signal(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- char tmp[32];
- u32 is_signal_dbg;
- s32 signal_strength;
-
- if (count < 1)
- return -EFAULT;
-
- if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
- int num = sscanf(tmp, "%u %u", &is_signal_dbg, &signal_strength);
-
- is_signal_dbg = is_signal_dbg == 0 ? 0 : 1;
- if (is_signal_dbg && num != 2)
- return count;
-
- signal_strength = clamp(signal_strength, 0, 100);
-
- padapter->recvpriv.is_signal_dbg = is_signal_dbg;
- padapter->recvpriv.signal_strength_dbg = signal_strength;
-
- if (is_signal_dbg)
- DBG_88E("set %s %u\n", "DBG_SIGNAL_STRENGTH", signal_strength);
- else
- DBG_88E("set %s\n", "HW_SIGNAL_STRENGTH");
- }
- return count;
-}
-
-int proc_get_ht_enable(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct registry_priv *pregpriv = &padapter->registrypriv;
- int len = 0;
-
- if (pregpriv)
- len += snprintf(page + len, count - len,
- "%d\n",
- pregpriv->ht_enable
- );
- *eof = 1;
- return len;
-}
-
-int proc_set_ht_enable(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct registry_priv *pregpriv = &padapter->registrypriv;
- char tmp[32];
- s32 mode = 0;
-
- if (count < 1)
- return -EFAULT;
-
- if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
- if (pregpriv) {
- pregpriv->ht_enable = mode;
- pr_info("ht_enable=%d\n", pregpriv->ht_enable);
- }
- }
-
- return count;
-}
-
-int proc_get_cbw40_enable(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct registry_priv *pregpriv = &padapter->registrypriv;
-
- int len = 0;
-
- if (pregpriv)
- len += snprintf(page + len, count - len,
- "%d\n",
- pregpriv->cbw40_enable
- );
-
- *eof = 1;
- return len;
-}
-
-int proc_set_cbw40_enable(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct registry_priv *pregpriv = &padapter->registrypriv;
- char tmp[32];
- s32 mode = 0;
-
- if (count < 1)
- return -EFAULT;
-
- if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
- if (pregpriv) {
- pregpriv->cbw40_enable = mode;
- pr_info("cbw40_enable=%d\n", mode);
- }
- }
- return count;
-}
-
-int proc_get_ampdu_enable(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct registry_priv *pregpriv = &padapter->registrypriv;
-
- int len = 0;
-
- if (pregpriv)
- len += snprintf(page + len, count - len,
- "%d\n",
- pregpriv->ampdu_enable
- );
-
- *eof = 1;
- return len;
-}
-
-int proc_set_ampdu_enable(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct registry_priv *pregpriv = &padapter->registrypriv;
- char tmp[32];
- s32 mode = 0;
-
- if (count < 1)
- return -EFAULT;
-
- if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
- if (pregpriv) {
- pregpriv->ampdu_enable = mode;
- pr_info("ampdu_enable=%d\n", mode);
- }
- }
- return count;
-}
-
-int proc_get_two_path_rssi(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
- int len = 0;
-
- if (padapter)
- len += snprintf(page + len, count - len,
- "%d %d\n",
- padapter->recvpriv.RxRssi[0],
- padapter->recvpriv.RxRssi[1]
- );
-
- *eof = 1;
- return len;
-}
-
-int proc_get_rx_stbc(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct registry_priv *pregpriv = &padapter->registrypriv;
-
- int len = 0;
-
- if (pregpriv)
- len += snprintf(page + len, count - len,
- "%d\n",
- pregpriv->rx_stbc
- );
-
- *eof = 1;
- return len;
-}
-
-int proc_set_rx_stbc(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct registry_priv *pregpriv = &padapter->registrypriv;
- char tmp[32];
- u32 mode = 0;
-
- if (count < 1)
- return -EFAULT;
-
- if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
- if (pregpriv) {
- pregpriv->rx_stbc = mode;
- netdev_info(dev, "rx_stbc=%d\n", mode);
- }
- }
- return count;
-}
-
-int proc_get_rssi_disp(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- *eof = 1;
- return 0;
-}
-
-int proc_set_rssi_disp(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
-{
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- char tmp[32];
- u32 enable = 0;
-
- if (count < 1) {
- DBG_88E("argument size is less than 1\n");
- return -EFAULT;
- }
-
- if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
- int num = sscanf(tmp, "%x", &enable);
-
- if (num != 1) {
- DBG_88E("invalid set_rssi_disp parameter!\n");
- return count;
- }
-
- if (enable) {
- DBG_88E("Turn On Rx RSSI Display Function\n");
- padapter->bRxRSSIDisplay = enable;
- } else {
- DBG_88E("Turn Off Rx RSSI Display Function\n");
- padapter->bRxRSSIDisplay = 0;
- }
- }
- return count;
-}
-
-#ifdef CONFIG_88EU_AP_MODE
-
-int proc_get_all_sta_info(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data)
-{
- struct sta_info *psta;
- struct net_device *dev = data;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct sta_priv *pstapriv = &padapter->stapriv;
- int i, j;
- struct list_head *plist, *phead;
- struct recv_reorder_ctrl *preorder_ctrl;
- int len = 0;
-
-
- len += snprintf(page + len, count - len, "sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
-
- spin_lock_bh(&pstapriv->sta_hash_lock);
-
- for (i = 0; i < NUM_STA; i++) {
- phead = &pstapriv->sta_hash[i];
- plist = phead->next;
-
- while (phead != plist) {
- psta = container_of(plist, struct sta_info, hash_list);
-
- plist = plist->next;
-
- len += snprintf(page + len, count - len, "sta's macaddr: %pM\n", psta->hwaddr);
- len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
- len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
- len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
- len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
- len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
- len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
- len += snprintf(page + len, count - len, "sleepq_len=%d\n", psta->sleepq_len);
- len += snprintf(page + len, count - len, "capability=0x%x\n", psta->capability);
- len += snprintf(page + len, count - len, "flags=0x%x\n", psta->flags);
- len += snprintf(page + len, count - len, "wpa_psk=0x%x\n", psta->wpa_psk);
- len += snprintf(page + len, count - len, "wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);
- len += snprintf(page + len, count - len, "wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);
- len += snprintf(page + len, count - len, "qos_info=0x%x\n", psta->qos_info);
- len += snprintf(page + len, count - len, "dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);
-
- for (j = 0; j < 16; j++) {
- preorder_ctrl = &psta->recvreorder_ctrl[j];
- if (preorder_ctrl->enable)
- len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", j, preorder_ctrl->indicate_seq);
- }
- }
- }
- spin_unlock_bh(&pstapriv->sta_hash_lock);
-
- *eof = 1;
- return len;
-}
-#endif
-
int proc_get_best_channel(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c
index fbce1f7e68ca..16cc7706a1e6 100644
--- a/drivers/staging/rtl8188eu/core/rtw_efuse.c
+++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c
@@ -317,69 +317,6 @@ void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _si
}
}
-/* Do not support BT */
-void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut)
-{
- switch (type) {
- case TYPE_EFUSE_MAX_SECTION:
- {
- u8 *pMax_section;
- pMax_section = pOut;
- *pMax_section = EFUSE_MAX_SECTION_88E;
- }
- break;
- case TYPE_EFUSE_REAL_CONTENT_LEN:
- {
- u16 *pu2Tmp;
- pu2Tmp = pOut;
- *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
- }
- break;
- case TYPE_EFUSE_CONTENT_LEN_BANK:
- {
- u16 *pu2Tmp;
- pu2Tmp = pOut;
- *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
- }
- break;
- case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
- {
- u16 *pu2Tmp;
- pu2Tmp = pOut;
- *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
- }
- break;
- case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
- {
- u16 *pu2Tmp;
- pu2Tmp = pOut;
- *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
- }
- break;
- case TYPE_EFUSE_MAP_LEN:
- {
- u16 *pu2Tmp;
- pu2Tmp = pOut;
- *pu2Tmp = (u16)EFUSE_MAP_LEN_88E;
- }
- break;
- case TYPE_EFUSE_PROTECT_BYTES_BANK:
- {
- u8 *pu1Tmp;
- pu1Tmp = pOut;
- *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
- }
- break;
- default:
- {
- u8 *pu1Tmp;
- pu1Tmp = pOut;
- *pu1Tmp = 0;
- }
- break;
- }
-}
-
u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data)
{
u16 tmpaddr = 0;
@@ -483,14 +420,11 @@ int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data)
u8 hoffset = 0, hworden = 0;
u8 tmpidx = 0;
u8 tmpdata[8];
- u8 max_section = 0;
u8 tmp_header = 0;
- EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, (void *)&max_section);
-
if (!data)
return false;
- if (offset > max_section)
+ if (offset > EFUSE_MAX_SECTION_88E)
return false;
memset(data, 0xff, sizeof(u8) * PGPKT_DATA_SIZE);
@@ -591,12 +525,12 @@ static bool hal_EfuseFixHeaderProcess(struct adapter *pAdapter, u8 efuseType, st
static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt)
{
bool bRet = false;
- u16 efuse_addr = *pAddr, efuse_max_available_len = 0;
+ u16 efuse_addr = *pAddr;
+ u16 efuse_max_available_len =
+ EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E;
u8 pg_header = 0, tmp_header = 0, pg_header_temp = 0;
u8 repeatcnt = 0;
- EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len);
-
while (efuse_addr < efuse_max_available_len) {
pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
efuse_OneByteWrite(pAdapter, efuse_addr, pg_header);
@@ -769,12 +703,11 @@ static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u
bool bRet = false;
u8 i, efuse_data = 0, cur_header = 0;
u8 matched_wden = 0, badworden = 0;
- u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0;
+ u16 startAddr = 0;
+ u16 efuse_max_available_len =
+ EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E;
struct pgpkt curPkt;
- EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len);
- EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&efuse_max);
-
rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);
startAddr %= EFUSE_REAL_CONTENT_LEN;
@@ -846,12 +779,7 @@ hal_EfusePgCheckAvailableAddr(
u8 efuseType
)
{
- u16 efuse_max_available_len = 0;
-
- /* Change to check TYPE_EFUSE_MAP_LEN , because 8188E raw 256, logic map over 256. */
- EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&efuse_max_available_len);
-
- if (Efuse_GetCurrentSize(pAdapter) >= efuse_max_available_len)
+ if (Efuse_GetCurrentSize(pAdapter) >= EFUSE_MAP_LEN_88E)
return false;
return true;
}
@@ -977,13 +905,9 @@ void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata)
*/
static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse)
{
- u16 mapLen = 0;
-
Efuse_PowerSwitch(pAdapter, false, true);
- EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
-
- efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse);
+ efuse_ReadEFuse(pAdapter, efuseType, 0, EFUSE_MAP_LEN_88E, Efuse);
Efuse_PowerSwitch(pAdapter, false, false);
}
@@ -996,12 +920,9 @@ void EFUSE_ShadowMapUpdate(
u8 efuseType)
{
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
- u16 mapLen = 0;
-
- EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
if (pEEPROM->bautoload_fail_flag)
- memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
+ memset(pEEPROM->efuse_eeprom_data, 0xFF, EFUSE_MAP_LEN_88E);
else
Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data);
}
diff --git a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
index 0b0d78fe83ed..914c4923421b 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
@@ -155,59 +155,6 @@ u8 *rtw_set_ie
return pbuf + len + 2;
}
-inline u8 *rtw_set_ie_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode,
- u8 new_ch, u8 ch_switch_cnt)
-{
- u8 ie_data[3];
-
- ie_data[0] = ch_switch_mode;
- ie_data[1] = new_ch;
- ie_data[2] = ch_switch_cnt;
- return rtw_set_ie(buf, WLAN_EID_CHANNEL_SWITCH, 3, ie_data, buf_len);
-}
-
-inline u8 secondary_ch_offset_to_hal_ch_offset(u8 ch_offset)
-{
- if (ch_offset == SCN)
- return HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- else if (ch_offset == SCA)
- return HAL_PRIME_CHNL_OFFSET_UPPER;
- else if (ch_offset == SCB)
- return HAL_PRIME_CHNL_OFFSET_LOWER;
-
- return HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-}
-
-inline u8 hal_ch_offset_to_secondary_ch_offset(u8 ch_offset)
-{
- if (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
- return SCN;
- else if (ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
- return SCB;
- else if (ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
- return SCA;
-
- return SCN;
-}
-
-inline u8 *rtw_set_ie_secondary_ch_offset(u8 *buf, u32 *buf_len, u8 secondary_ch_offset)
-{
- return rtw_set_ie(buf, WLAN_EID_SECONDARY_CHANNEL_OFFSET, 1, &secondary_ch_offset, buf_len);
-}
-
-inline u8 *rtw_set_ie_mesh_ch_switch_parm(u8 *buf, u32 *buf_len, u8 ttl,
- u8 flags, u16 reason, u16 precedence)
-{
- u8 ie_data[6];
-
- ie_data[0] = ttl;
- ie_data[1] = flags;
- *(u16 *)(ie_data + 2) = cpu_to_le16(reason);
- *(u16 *)(ie_data + 4) = cpu_to_le16(precedence);
-
- return rtw_set_ie(buf, 0x118, 6, ie_data, buf_len);
-}
-
/*----------------------------------------------------------------------------
index: the information element id index, limit is the limit for search
-----------------------------------------------------------------------------*/
@@ -236,97 +183,6 @@ u8 *rtw_get_ie(u8 *pbuf, int index, int *len, int limit)
return NULL;
}
-/**
- * rtw_get_ie_ex - Search specific IE from a series of IEs
- * @in_ie: Address of IEs to search
- * @in_len: Length limit from in_ie
- * @eid: Element ID to match
- * @oui: OUI to match
- * @oui_len: OUI length
- * @ie: If not NULL and the specific IE is found, the IE will be copied to the buf starting from the specific IE
- * @ielen: If not NULL and the specific IE is found, will set to the length of the entire IE
- *
- * Returns: The address of the specific IE found, or NULL
- */
-u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len, u8 *ie, uint *ielen)
-{
- uint cnt;
- u8 *target_ie = NULL;
-
-
- if (ielen)
- *ielen = 0;
-
- if (!in_ie || in_len <= 0)
- return target_ie;
-
- cnt = 0;
-
- while (cnt < in_len) {
- if (eid == in_ie[cnt] && (!oui || !memcmp(&in_ie[cnt + 2], oui, oui_len))) {
- target_ie = &in_ie[cnt];
-
- if (ie)
- memcpy(ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
-
- if (ielen)
- *ielen = in_ie[cnt + 1] + 2;
-
- break;
- } else {
- cnt += in_ie[cnt + 1] + 2; /* goto next */
- }
- }
- return target_ie;
-}
-
-/**
- * rtw_ies_remove_ie - Find matching IEs and remove
- * @ies: Address of IEs to search
- * @ies_len: Pointer of length of ies, will update to new length
- * @offset: The offset to start scarch
- * @eid: Element ID to match
- * @oui: OUI to match
- * @oui_len: OUI length
- *
- * Returns: _SUCCESS: ies is updated, _FAIL: not updated
- */
-int rtw_ies_remove_ie(u8 *ies, uint *ies_len, uint offset, u8 eid, u8 *oui, u8 oui_len)
-{
- int ret = _FAIL;
- u8 *target_ie;
- u32 target_ielen;
- u8 *start;
- uint search_len;
-
- if (!ies || !ies_len || *ies_len <= offset)
- goto exit;
-
- start = ies + offset;
- search_len = *ies_len - offset;
-
- while (1) {
- target_ie = rtw_get_ie_ex(start, search_len, eid, oui, oui_len, NULL, &target_ielen);
- if (target_ie && target_ielen) {
- u8 buf[MAX_IE_SZ] = {0};
- u8 *remain_ies = target_ie + target_ielen;
- uint remain_len = search_len - (remain_ies - start);
-
- memcpy(buf, remain_ies, remain_len);
- memcpy(target_ie, buf, remain_len);
- *ies_len = *ies_len - target_ielen;
- ret = _SUCCESS;
-
- start = target_ie;
- search_len = remain_len;
- } else {
- break;
- }
- }
-exit:
- return ret;
-}
-
void rtw_set_supported_rate(u8 *SupportedRates, uint mode)
{
@@ -1096,43 +952,6 @@ void rtw_macaddr_cfg(u8 *mac_addr)
DBG_88E("rtw_macaddr_cfg MAC Address = %pM\n", (mac_addr));
}
-void dump_ies(u8 *buf, u32 buf_len)
-{
- u8 *pos = buf;
- u8 id, len;
-
- while (pos - buf <= buf_len) {
- id = *pos;
- len = *(pos + 1);
-
- DBG_88E("%s ID:%u, LEN:%u\n", __func__, id, len);
- dump_wps_ie(pos, len);
-
- pos += (2 + len);
- }
-}
-
-void dump_wps_ie(u8 *ie, u32 ie_len)
-{
- u8 *pos = ie;
- u16 id;
- u16 len;
- u8 *wps_ie;
- uint wps_ielen;
-
- wps_ie = rtw_get_wps_ie(ie, ie_len, NULL, &wps_ielen);
- if (wps_ie != ie || wps_ielen == 0)
- return;
-
- pos += 6;
- while (pos - ie < ie_len) {
- id = get_unaligned_be16(pos);
- len = get_unaligned_be16(pos + 2);
- DBG_88E("%s ID:0x%04x, LEN:%u\n", __func__, id, len);
- pos += (4 + len);
- }
-}
-
/* Baron adds to avoid FreeBSD warning */
int ieee80211_is_empty_essid(const char *essid, int essid_len)
{
@@ -1223,7 +1042,6 @@ void rtw_get_bcn_info(struct wlan_network *pnetwork)
__le16 le_tmp;
u16 wpa_len = 0, rsn_len = 0;
struct HT_info_element *pht_info = NULL;
- struct rtw_ieee80211_ht_cap *pht_cap = NULL;
unsigned int len;
unsigned char *p;
@@ -1259,10 +1077,12 @@ void rtw_get_bcn_info(struct wlan_network *pnetwork)
/* parsing HT_CAP_IE */
p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_);
if (p && len > 0) {
- pht_cap = (struct rtw_ieee80211_ht_cap *)(p + 2);
- pnetwork->BcnInfo.ht_cap_info = pht_cap->cap_info;
+ struct ieee80211_ht_cap *ht_cap =
+ (struct ieee80211_ht_cap *)(p + 2);
+
+ pnetwork->BcnInfo.ht_cap_info = le16_to_cpu(ht_cap->cap_info);
} else {
- pnetwork->BcnInfo.ht_cap_info = 0;
+ pnetwork->BcnInfo.ht_cap_info = 0;
}
/* parsing HT_INFO_IE */
p = rtw_get_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, pnetwork->network.IELength - _FIXED_IE_LENGTH_);
@@ -1335,58 +1155,3 @@ u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40, unsign
}
return max_rate;
}
-
-int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, u8 *action)
-{
- const u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr);
- u16 fc;
- u8 c, a = 0;
-
- fc = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)frame)->frame_ctl);
-
- if ((fc & (RTW_IEEE80211_FCTL_FTYPE | RTW_IEEE80211_FCTL_STYPE)) !=
- (RTW_IEEE80211_FTYPE_MGMT | RTW_IEEE80211_STYPE_ACTION))
- return false;
-
- c = frame_body[0];
-
- switch (c) {
- case RTW_WLAN_CATEGORY_P2P: /* vendor-specific */
- break;
- default:
- a = frame_body[1];
- }
-
- if (category)
- *category = c;
- if (action)
- *action = a;
-
- return true;
-}
-
-static const char *_action_public_str[] = {
- "ACT_PUB_BSSCOEXIST",
- "ACT_PUB_DSE_ENABLE",
- "ACT_PUB_DSE_DEENABLE",
- "ACT_PUB_DSE_REG_LOCATION",
- "ACT_PUB_EXT_CHL_SWITCH",
- "ACT_PUB_DSE_MSR_REQ",
- "ACT_PUB_DSE_MSR_RPRT",
- "ACT_PUB_MP",
- "ACT_PUB_DSE_PWR_CONSTRAINT",
- "ACT_PUB_VENDOR",
- "ACT_PUB_GAS_INITIAL_REQ",
- "ACT_PUB_GAS_INITIAL_RSP",
- "ACT_PUB_GAS_COMEBACK_REQ",
- "ACT_PUB_GAS_COMEBACK_RSP",
- "ACT_PUB_TDLS_DISCOVERY_RSP",
- "ACT_PUB_LOCATION_TRACK",
- "ACT_PUB_RSVD",
-};
-
-const char *action_public_str(u8 action)
-{
- action = min_t(u8, action, ACT_PUBLIC_MAX);
- return _action_public_str[action];
-}
diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c
index f85a6abec3a3..6ed23f4db38c 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c
@@ -14,7 +14,6 @@
******************************************************************************/
#define _RTW_IOCTL_SET_C_
-
#include <osdep_service.h>
#include <drv_types.h>
#include <rtw_ioctl_set.h>
@@ -570,10 +569,8 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter)
struct registry_priv *pregistrypriv = &adapter->registrypriv;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
- struct rtw_ieee80211_ht_cap *pht_capie;
u8 rf_type = 0;
u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0;
- u16 mcs_rate = 0;
u32 ht_ielen = 0;
if (adapter->registrypriv.mp_mode == 1) {
@@ -588,15 +585,11 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter)
if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N|WIRELESS_11_5N)) {
p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
if (p && ht_ielen > 0) {
- pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
-
- memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
-
/* cur_bwmod is updated by beacon, pmlmeinfo is updated by association response */
bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1 : 0;
- short_GI_20 = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & IEEE80211_HT_CAP_SGI_20) ? 1 : 0;
- short_GI_40 = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & IEEE80211_HT_CAP_SGI_40) ? 1 : 0;
+ short_GI_20 = (le16_to_cpu(pmlmeinfo->HT_caps.cap_info) & IEEE80211_HT_CAP_SGI_20) ? 1 : 0;
+ short_GI_40 = (le16_to_cpu(pmlmeinfo->HT_caps.cap_info) & IEEE80211_HT_CAP_SGI_40) ? 1 : 0;
rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
max_rate = rtw_mcs_rate(
@@ -604,7 +597,7 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter)
bw_40MHz & (pregistrypriv->cbw40_enable),
short_GI_20,
short_GI_40,
- pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate
+ pmlmeinfo->HT_caps.mcs.rx_mask
);
}
} else {
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c
index 1456499b84bf..ee2dcd05010f 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c
@@ -52,8 +52,6 @@ int rtw_init_mlme_priv(struct adapter *padapter)
_rtw_init_queue(&(pmlmepriv->free_bss_pool));
_rtw_init_queue(&(pmlmepriv->scanned_queue));
- set_scanned_network_val(pmlmepriv, 0);
-
memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
pbuf = vzalloc(MAX_BSS_CNT * (sizeof(struct wlan_network)));
@@ -100,12 +98,6 @@ void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len);
rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len);
rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len);
-
- rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len);
}
#else
void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
@@ -143,8 +135,6 @@ struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv)
pnetwork->aid = 0;
pnetwork->join_res = 0;
- pmlmepriv->num_of_scanned++;
-
exit:
spin_unlock_bh(&free_queue->lock);
@@ -175,7 +165,6 @@ static void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *
spin_lock_bh(&free_queue->lock);
list_del_init(&(pnetwork->list));
list_add_tail(&(pnetwork->list), &(free_queue->queue));
- pmlmepriv->num_of_scanned--;
spin_unlock_bh(&free_queue->lock);
}
@@ -189,7 +178,6 @@ void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *
return;
list_del_init(&(pnetwork->list));
list_add_tail(&(pnetwork->list), get_list_head(free_queue));
- pmlmepriv->num_of_scanned--;
}
/*
@@ -271,7 +259,6 @@ void rtw_generate_random_ibss(u8 *pibss)
pibss[3] = (u8)(curtime & 0xff);/* p[0]; */
pibss[4] = (u8)((curtime>>8) & 0xff);/* p[1]; */
pibss[5] = (u8)((curtime>>16) & 0xff);/* p[2]; */
- return;
}
u8 *rtw_get_capability_from_ie(u8 *ie)
@@ -569,7 +556,6 @@ static int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *
void rtw_atimdone_event_callback(struct adapter *adapter, u8 *pbuf)
{
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("receive atimdone_evet\n"));
- return;
}
@@ -732,7 +718,6 @@ static void free_scanqueue(struct mlme_priv *pmlmepriv)
list_del_init(plist);
list_add_tail(plist, &free_queue->queue);
plist = ptemp;
- pmlmepriv->num_of_scanned--;
}
spin_unlock_bh(&free_queue->lock);
@@ -1935,7 +1920,6 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_
u32 ielen, out_len;
enum ht_cap_ampdu_factor max_rx_ampdu_factor;
unsigned char *p;
- struct rtw_ieee80211_ht_cap ht_capie;
unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct qos_priv *pqospriv = &pmlmepriv->qospriv;
@@ -1948,6 +1932,8 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_
p = rtw_get_ie(in_ie+12, _HT_CAPABILITY_IE_, &ielen, in_len-12);
if (p && ielen > 0) {
+ struct ieee80211_ht_cap ht_cap;
+
if (pqospriv->qos_option == 0) {
out_len = *pout_len;
rtw_set_ie(out_ie+out_len, _VENDOR_SPECIFIC_IE_,
@@ -1958,33 +1944,33 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_
out_len = *pout_len;
- memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap));
+ memset(&ht_cap, 0, sizeof(struct ieee80211_ht_cap));
- ht_capie.cap_info = IEEE80211_HT_CAP_SUP_WIDTH |
- IEEE80211_HT_CAP_SGI_20 |
- IEEE80211_HT_CAP_SGI_40 |
- IEEE80211_HT_CAP_TX_STBC |
- IEEE80211_HT_CAP_DSSSCCK40;
+ ht_cap.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH |
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_TX_STBC |
+ IEEE80211_HT_CAP_DSSSCCK40);
rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset);
rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz);
/*
- AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
- AMPDU_para [4:2]:Min MPDU Start Spacing
+ ampdu_params_info [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
+ ampdu_params_info [4:2]:Min MPDU Start Spacing
*/
rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
- ht_capie.ampdu_params_info = (max_rx_ampdu_factor&0x03);
+ ht_cap.ampdu_params_info = max_rx_ampdu_factor & 0x03;
if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
- ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
+ ht_cap.ampdu_params_info |= IEEE80211_HT_CAP_AMPDU_DENSITY & (0x07 << 2);
else
- ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
-
+ ht_cap.ampdu_params_info |= IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00;
rtw_set_ie(out_ie+out_len, _HT_CAPABILITY_IE_,
- sizeof(struct rtw_ieee80211_ht_cap), (unsigned char *)&ht_capie, pout_len);
+ sizeof(struct ieee80211_ht_cap),
+ (unsigned char *)&ht_cap, pout_len);
phtpriv->ht_option = true;
@@ -2000,9 +1986,6 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_
/* the function is > passive_level (in critical_section) */
void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len)
{
- u8 *p, max_ampdu_sz;
- int len;
- struct rtw_ieee80211_ht_cap *pht_capie;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct ht_priv *phtpriv = &pmlmepriv->htpriv;
struct registry_priv *pregistrypriv = &padapter->registrypriv;
@@ -2027,34 +2010,21 @@ void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len)
phtpriv->ampdu_enable = true;
}
-
- /* check Max Rx A-MPDU Size */
- len = 0;
- p = rtw_get_ie(pie+sizeof(struct ndis_802_11_fixed_ie), _HT_CAPABILITY_IE_, &len, ie_len-sizeof(struct ndis_802_11_fixed_ie));
- if (p && len > 0) {
- pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
- max_ampdu_sz = pht_capie->ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR;
- max_ampdu_sz = 1 << (max_ampdu_sz+3); /* max_ampdu_sz (kbytes); */
- phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
- }
- len = 0;
- p = rtw_get_ie(pie+sizeof(struct ndis_802_11_fixed_ie), _HT_ADD_INFO_IE_, &len, ie_len-sizeof(struct ndis_802_11_fixed_ie));
-
/* update cur_bwmode & cur_ch_offset */
if ((pregistrypriv->cbw40_enable) &&
- (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & BIT(1)) &&
+ (le16_to_cpu(pmlmeinfo->HT_caps.cap_info) & BIT(1)) &&
(pmlmeinfo->HT_info.infos[0] & BIT(2))) {
int i;
u8 rf_type;
- padapter->HalFunc.GetHwRegHandler(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
+ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
/* update the MCS rates */
for (i = 0; i < 16; i++) {
if ((rf_type == RF_1T1R) || (rf_type == RF_1T2R))
- pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
+ ((u8 *)&pmlmeinfo->HT_caps.mcs)[i] &= MCS_rate_1R[i];
else
- pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i];
+ ((u8 *)&pmlmeinfo->HT_caps.mcs)[i] &= MCS_rate_2R[i];
}
/* switch to the 40M Hz mode according to the AP */
pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
@@ -2072,7 +2042,7 @@ void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len)
}
/* Config SM Power Save setting */
- pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & 0x0C) >> 2;
+ pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.cap_info) & 0x0C) >> 2;
if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
index 7f32b39e5869..fb13df586441 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
@@ -320,7 +320,7 @@ static void issue_beacon(struct adapter *padapter, int timeout_ms)
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
unsigned int rate_len;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
@@ -347,22 +347,22 @@ static void issue_beacon(struct adapter *padapter, int timeout_ms)
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
- memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, cur_network->MacAddress, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, bc_addr);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3, cur_network->MacAddress);
SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
/* pmlmeext->mgnt_seq++; */
SetFrameSubType(pframe, WIFI_BEACON);
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += sizeof(struct ieee80211_hdr_3addr);
+ pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
int len_diff;
@@ -377,8 +377,8 @@ static void issue_beacon(struct adapter *padapter, int timeout_ms)
);
pframe += (cur_network->IELength+len_diff);
pattrib->pktlen += (cur_network->IELength+len_diff);
- wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
- pattrib->pktlen-sizeof(struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
+ wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
+ pattrib->pktlen-sizeof(struct ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
if (wps_ie && wps_ielen > 0)
rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
if (sr != 0)
@@ -461,7 +461,7 @@ static void issue_probersp(struct adapter *padapter, unsigned char *da)
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
unsigned char *mac, *bssid;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
@@ -488,22 +488,22 @@ static void issue_probersp(struct adapter *padapter, unsigned char *da)
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
mac = myid(&(padapter->eeprompriv));
bssid = cur_network->MacAddress;
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
- memcpy(pwlanhdr->addr1, da, ETH_ALEN);
- memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
- memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, da);
+ ether_addr_copy(pwlanhdr->addr2, mac);
+ ether_addr_copy(pwlanhdr->addr3, bssid);
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
pmlmeext->mgnt_seq++;
SetFrameSubType(fctrl, WIFI_PROBERSP);
- pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
pattrib->pktlen = pattrib->hdrlen;
pframe += pattrib->hdrlen;
@@ -609,7 +609,7 @@ static int issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pss
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
unsigned char *mac;
unsigned char bssrate[NumRates];
@@ -633,31 +633,31 @@ static int issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pss
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
mac = myid(&(padapter->eeprompriv));
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
if (da) {
/* unicast probe request frame */
- memcpy(pwlanhdr->addr1, da, ETH_ALEN);
- memcpy(pwlanhdr->addr3, da, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, da);
+ ether_addr_copy(pwlanhdr->addr3, da);
} else {
/* broadcast probe request frame */
- memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
- memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, bc_addr);
+ ether_addr_copy(pwlanhdr->addr3, bc_addr);
}
- memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr2, mac);
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
pmlmeext->mgnt_seq++;
SetFrameSubType(pframe, WIFI_PROBEREQ);
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += sizeof(struct ieee80211_hdr_3addr);
+ pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
if (pssid)
pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
@@ -745,7 +745,7 @@ static void issue_auth(struct adapter *padapter, struct sta_info *psta,
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
unsigned int val32;
u16 val16;
@@ -769,25 +769,27 @@ static void issue_auth(struct adapter *padapter, struct sta_info *psta,
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
pmlmeext->mgnt_seq++;
SetFrameSubType(pframe, WIFI_AUTH);
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += sizeof(struct ieee80211_hdr_3addr);
+ pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
if (psta) {/* for AP mode */
#ifdef CONFIG_88EU_AP_MODE
- memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, psta->hwaddr);
+ ether_addr_copy(pwlanhdr->addr2,
+ myid(&(padapter->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3,
+ myid(&(padapter->eeprompriv)));
/* setting auth algo number */
@@ -825,9 +827,9 @@ static void issue_auth(struct adapter *padapter, struct sta_info *psta,
} else {
__le32 le_tmp32;
__le16 le_tmp16;
- memcpy(pwlanhdr->addr1, pnetwork->MacAddress, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
- memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, pnetwork->MacAddress);
+ ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
+ ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
/* setting auth algo number */
val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;/* 0:OPEN System, 1:Shared key */
@@ -866,7 +868,7 @@ static void issue_auth(struct adapter *padapter, struct sta_info *psta,
SetPrivacy(fctrl);
- pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
pattrib->encrypt = _WEP40_;
@@ -889,7 +891,7 @@ static void issue_asocrsp(struct adapter *padapter, unsigned short status,
struct sta_info *pstat, int pkt_type)
{
struct xmit_frame *pmgntframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
struct pkt_attrib *pattrib;
unsigned char *pbuf, *pframe;
unsigned short val;
@@ -916,14 +918,15 @@ static void issue_asocrsp(struct adapter *padapter, unsigned short status,
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
- memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
- memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy((void *)GetAddr3Ptr(pwlanhdr), pnetwork->MacAddress, ETH_ALEN);
+ ether_addr_copy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr);
+ ether_addr_copy((void *)GetAddr2Ptr(pwlanhdr),
+ myid(&(padapter->eeprompriv)));
+ ether_addr_copy((void *)GetAddr3Ptr(pwlanhdr), pnetwork->MacAddress);
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
@@ -933,7 +936,7 @@ static void issue_asocrsp(struct adapter *padapter, unsigned short status,
else
return;
- pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
pattrib->pktlen += pattrib->hdrlen;
pframe += pattrib->hdrlen;
@@ -1017,7 +1020,7 @@ static void issue_assocreq(struct adapter *padapter)
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe, *p;
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
unsigned int i, j, ie_len, index = 0;
unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
@@ -1040,20 +1043,20 @@ static void issue_assocreq(struct adapter *padapter)
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
- memcpy(pwlanhdr->addr1, pnetwork->MacAddress, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, pnetwork->MacAddress);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
pmlmeext->mgnt_seq++;
SetFrameSubType(pframe, WIFI_ASSOCREQ);
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += sizeof(struct ieee80211_hdr_3addr);
+ pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
/* caps */
@@ -1132,23 +1135,23 @@ static void issue_assocreq(struct adapter *padapter)
if (padapter->mlmepriv.htpriv.ht_option) {
p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ie)), _HT_CAPABILITY_IE_, &ie_len, (pmlmeinfo->network.IELength - sizeof(struct ndis_802_11_fixed_ie)));
if ((p != NULL) && (!(is_ap_in_tkip(padapter)))) {
- memcpy(&(pmlmeinfo->HT_caps), (p + 2), sizeof(struct HT_caps_element));
+ memcpy(&pmlmeinfo->HT_caps, p + 2, sizeof(struct ieee80211_ht_cap));
/* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
if (pregpriv->cbw40_enable == 0)
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= cpu_to_le16(~(BIT(6) | BIT(1)));
+ pmlmeinfo->HT_caps.cap_info &= cpu_to_le16(~(BIT(6) | BIT(1)));
else
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(BIT(1));
+ pmlmeinfo->HT_caps.cap_info |= cpu_to_le16(BIT(1));
/* todo: disable SM power save mode */
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x000c);
+ pmlmeinfo->HT_caps.cap_info |= cpu_to_le16(0x000c);
rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
switch (rf_type) {
case RF_1T1R:
if (pregpriv->rx_stbc)
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);/* RX STBC One spatial stream */
- memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
+ pmlmeinfo->HT_caps.cap_info |= cpu_to_le16(0x0100);/* RX STBC One spatial stream */
+ memcpy((u8 *)&pmlmeinfo->HT_caps.mcs, MCS_rate_1R, 16);
break;
case RF_2T2R:
case RF_1T2R:
@@ -1157,9 +1160,9 @@ static void issue_assocreq(struct adapter *padapter)
((pmlmeext->cur_wireless_mode & WIRELESS_11_24N) && (pregpriv->rx_stbc == 0x1)) || /* enable for 2.4GHz */
(pregpriv->wifi_spec == 1)) {
DBG_88E("declare supporting RX STBC\n");
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
+ pmlmeinfo->HT_caps.cap_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
}
- memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16);
+ memcpy(&pmlmeinfo->HT_caps.mcs, MCS_rate_2R, 16);
break;
}
pframe = rtw_set_ie(pframe, _HT_CAPABILITY_IE_, ie_len , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
@@ -1212,7 +1215,7 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
struct xmit_priv *pxmitpriv;
struct mlme_ext_priv *pmlmeext;
@@ -1239,9 +1242,9 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
@@ -1252,16 +1255,16 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned
if (power_mode)
SetPwrMgt(fctrl);
- memcpy(pwlanhdr->addr1, da, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, da);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
pmlmeext->mgnt_seq++;
SetFrameSubType(pframe, WIFI_DATA_NULL);
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += sizeof(struct ieee80211_hdr_3addr);
+ pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
pattrib->last_txcmdsz = pattrib->pktlen;
@@ -1332,7 +1335,7 @@ static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
unsigned short *qc;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
@@ -1359,9 +1362,9 @@ static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
@@ -1380,16 +1383,16 @@ static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16
SetAckpolicy(qc, pattrib->ack_policy);
- memcpy(pwlanhdr->addr1, da, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, da);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
pmlmeext->mgnt_seq++;
SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
+ pframe += sizeof(struct ieee80211_qos_hdr);
+ pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
pattrib->last_txcmdsz = pattrib->pktlen;
@@ -1457,7 +1460,7 @@ static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned s
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
@@ -1478,21 +1481,21 @@ static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned s
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
- memcpy(pwlanhdr->addr1, da, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, da);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
pmlmeext->mgnt_seq++;
SetFrameSubType(pframe, WIFI_DEAUTH);
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += sizeof(struct ieee80211_hdr_3addr);
+ pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
le_tmp = cpu_to_le16(reason);
pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_, &le_tmp,
@@ -1559,66 +1562,6 @@ exit:
return ret;
}
-void issue_action_spct_ch_switch(struct adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
-
-
- DBG_88E(FUNC_NDEV_FMT" ra =%pM, ch:%u, offset:%u\n",
- FUNC_NDEV_ARG(padapter->pnetdev), ra, new_ch, ch_offset);
-
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
- return;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-
- memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); /* TA */
- memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
-
- /* category, action */
- {
- u8 category, action;
- category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
- action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
-
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- }
-
- pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
- pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
- hal_ch_offset_to_secondary_ch_offset(ch_offset));
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe(padapter, pmgntframe);
-}
-
static void issue_action_BA(struct adapter *padapter, unsigned char *raddr,
unsigned char action, unsigned short status)
{
@@ -1633,7 +1576,7 @@ static void issue_action_BA(struct adapter *padapter, unsigned char *raddr,
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
u8 *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
@@ -1656,21 +1599,21 @@ static void issue_action_BA(struct adapter *padapter, unsigned char *raddr,
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
- memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, raddr);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
pmlmeext->mgnt_seq++;
SetFrameSubType(pframe, WIFI_ACTION);
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += sizeof(struct ieee80211_hdr_3addr);
+ pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
@@ -1779,7 +1722,7 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
struct wlan_network *pnetwork = NULL;
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
@@ -1815,21 +1758,21 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
- memcpy(pwlanhdr->addr1, cur_network->MacAddress, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, cur_network->MacAddress, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, cur_network->MacAddress);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3, cur_network->MacAddress);
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
pmlmeext->mgnt_seq++;
SetFrameSubType(pframe, WIFI_ACTION);
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += sizeof(struct ieee80211_hdr_3addr);
+ pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
@@ -2112,7 +2055,7 @@ static u8 collect_bss_info(struct adapter *padapter,
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
+ len = packet_len - sizeof(struct ieee80211_hdr_3addr);
if (len > MAX_IE_SZ)
return _FAIL;
@@ -2142,7 +2085,7 @@ static u8 collect_bss_info(struct adapter *padapter,
/* below is to copy the information element */
bssid->IELength = len;
- memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
+ memcpy(bssid->IEs, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->IELength);
/* get the signal strength in dBM.raw data */
bssid->Rssi = precv_frame->attrib.phy_info.recvpower;
@@ -2219,7 +2162,7 @@ static u8 collect_bss_info(struct adapter *padapter,
if (subtype == WIFI_PROBEREQ) {
/* FIXME */
bssid->InfrastructureMode = Ndis802_11Infrastructure;
- memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
+ ether_addr_copy(bssid->MacAddress, GetAddr2Ptr(pframe));
bssid->Privacy = 1;
return _SUCCESS;
}
@@ -2231,10 +2174,10 @@ static u8 collect_bss_info(struct adapter *padapter,
if (val16 & BIT(0)) {
bssid->InfrastructureMode = Ndis802_11Infrastructure;
- memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
+ ether_addr_copy(bssid->MacAddress, GetAddr2Ptr(pframe));
} else {
bssid->InfrastructureMode = Ndis802_11IBSS;
- memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
+ ether_addr_copy(bssid->MacAddress, GetAddr3Ptr(pframe));
}
if (val16 & BIT(4))
@@ -2249,10 +2192,10 @@ static u8 collect_bss_info(struct adapter *padapter,
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
if (p && len > 0) {
- struct HT_caps_element *pHT_caps;
- pHT_caps = (struct HT_caps_element *)(p + 2);
+ struct ieee80211_ht_cap *pHT_caps =
+ (struct ieee80211_ht_cap *)(p + 2);
- if (le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info)&BIT(14))
+ if (le16_to_cpu(pHT_caps->cap_info) & BIT(14))
pmlmepriv->num_FortyMHzIntolerant++;
} else {
pmlmepriv->num_sta_no_ht++;
@@ -2684,7 +2627,7 @@ static unsigned int OnBeacon(struct adapter *padapter,
}
/* check the vendor of the assoc AP */
- pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr));
+ pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct ieee80211_hdr_3addr), len-sizeof(struct ieee80211_hdr_3addr));
/* update TSF Value */
update_TSF(pmlmeext, pframe, len);
@@ -3296,13 +3239,15 @@ static unsigned int OnAssocReq(struct adapter *padapter,
}
/* save HT capabilities in the sta object */
- memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
- if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap)) {
+ memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
+ if (elems.ht_capabilities &&
+ elems.ht_capabilities_len >= sizeof(struct ieee80211_ht_cap)) {
pstat->flags |= WLAN_STA_HT;
pstat->flags |= WLAN_STA_WME;
- memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
+ memcpy(&pstat->htpriv.ht_cap,
+ elems.ht_capabilities, sizeof(struct ieee80211_ht_cap));
} else {
pstat->flags &= ~WLAN_STA_HT;
}
@@ -3639,7 +3584,7 @@ static unsigned int on_action_spct(struct adapter *padapter,
struct sta_info *psta = NULL;
struct sta_priv *pstapriv = &padapter->stapriv;
u8 *pframe = precv_frame->rx_data;
- u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
+ u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
u8 category;
u8 action;
@@ -3713,7 +3658,7 @@ static unsigned int OnAction_back(struct adapter *padapter,
if (psta == NULL)
return _SUCCESS;
- frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
+ frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
category = frame_body[0];
if (category == RTW_WLAN_CATEGORY_BACK) { /* representing Block Ack */
@@ -3800,7 +3745,7 @@ static unsigned int on_action_public_p2p(struct recv_frame *precv_frame)
u8 *pframe = precv_frame->rx_data;
u8 *frame_body;
u8 dialogToken = 0;
- frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
+ frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
dialogToken = frame_body[7];
@@ -3814,7 +3759,7 @@ static unsigned int on_action_public_vendor(struct recv_frame *precv_frame)
{
unsigned int ret = _FAIL;
u8 *pframe = precv_frame->rx_data;
- u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
+ u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
if (!memcmp(frame_body + 2, P2P_OUI, 4))
ret = on_action_public_p2p(precv_frame);
@@ -3826,7 +3771,7 @@ static unsigned int on_action_public_default(struct recv_frame *precv_frame, u8
{
unsigned int ret = _FAIL;
u8 *pframe = precv_frame->rx_data;
- u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
+ u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
u8 token;
token = frame_body[2];
@@ -3845,7 +3790,7 @@ static unsigned int on_action_public(struct adapter *padapter,
{
unsigned int ret = _FAIL;
u8 *pframe = precv_frame->rx_data;
- u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
+ u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
u8 category, action;
/* check RA matches or not */
@@ -3917,7 +3862,7 @@ static unsigned int OnAction(struct adapter *padapter,
unsigned char *frame_body;
u8 *pframe = precv_frame->rx_data;
- frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
+ frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
category = frame_body[0];
@@ -4295,7 +4240,7 @@ void report_survey_event(struct adapter *padapter,
INIT_LIST_HEAD(&pcmd_obj->list);
- pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
+ pcmd_obj->cmdcode = _Set_MLME_EVT_CMD_;
pcmd_obj->cmdsz = cmdsz;
pcmd_obj->parmbuf = pevtcmd;
@@ -4304,7 +4249,7 @@ void report_survey_event(struct adapter *padapter,
pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
pc2h_evt_hdr->len = sizeof(struct survey_event);
- pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
+ pc2h_evt_hdr->ID = _Survey_EVT_;
pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
@@ -4345,7 +4290,7 @@ void report_surveydone_event(struct adapter *padapter)
INIT_LIST_HEAD(&pcmd_obj->list);
- pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
+ pcmd_obj->cmdcode = _Set_MLME_EVT_CMD_;
pcmd_obj->cmdsz = cmdsz;
pcmd_obj->parmbuf = pevtcmd;
@@ -4354,7 +4299,7 @@ void report_surveydone_event(struct adapter *padapter)
pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
pc2h_evt_hdr->len = sizeof(struct surveydone_event);
- pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
+ pc2h_evt_hdr->ID = _SurveyDone_EVT_;
pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
@@ -4389,7 +4334,7 @@ void report_join_res(struct adapter *padapter, int res)
INIT_LIST_HEAD(&pcmd_obj->list);
- pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
+ pcmd_obj->cmdcode = _Set_MLME_EVT_CMD_;
pcmd_obj->cmdsz = cmdsz;
pcmd_obj->parmbuf = pevtcmd;
@@ -4398,7 +4343,7 @@ void report_join_res(struct adapter *padapter, int res)
pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
pc2h_evt_hdr->len = sizeof(struct joinbss_event);
- pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
+ pc2h_evt_hdr->ID = _JoinBss_EVT_;
pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
@@ -4440,7 +4385,7 @@ void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsi
INIT_LIST_HEAD(&pcmd_obj->list);
- pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
+ pcmd_obj->cmdcode = _Set_MLME_EVT_CMD_;
pcmd_obj->cmdsz = cmdsz;
pcmd_obj->parmbuf = pevtcmd;
@@ -4449,11 +4394,11 @@ void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsi
pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
pc2h_evt_hdr->len = sizeof(struct stadel_event);
- pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
+ pc2h_evt_hdr->ID = _DelSTA_EVT_;
pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
- memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
+ ether_addr_copy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr);
memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
@@ -4493,7 +4438,7 @@ void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int
INIT_LIST_HEAD(&pcmd_obj->list);
- pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
+ pcmd_obj->cmdcode = _Set_MLME_EVT_CMD_;
pcmd_obj->cmdsz = cmdsz;
pcmd_obj->parmbuf = pevtcmd;
@@ -4502,11 +4447,11 @@ void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int
pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
pc2h_evt_hdr->len = sizeof(struct stassoc_event);
- pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
+ pc2h_evt_hdr->ID = _AddSTA_EVT_;
pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
- memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
+ ether_addr_copy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr);
padd_sta_evt->cam_id = cam_idx;
DBG_88E("report_add_sta_event: add STA\n");
@@ -4537,7 +4482,7 @@ void update_sta_info(struct adapter *padapter, struct sta_info *psta)
psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
- if (support_short_GI(padapter, &(pmlmeinfo->HT_caps)))
+ if (support_short_GI(padapter, &pmlmeinfo->HT_caps))
psta->htpriv.sgi = true;
psta->qos_option = true;
@@ -4904,7 +4849,7 @@ void survey_timer_hdl(unsigned long data)
goto exit_survey_timer_hdl;
}
- init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
+ init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, _SiteSurvey_CMD_);
rtw_enqueue_cmd(pcmdpriv, ph2c);
}
@@ -5480,7 +5425,7 @@ u8 set_tx_beacon_cmd(struct adapter *padapter)
pmlmeinfo->hidden_ssid_mode);
ptxBeacon_parm->IELength += len_diff;
- init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
+ init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, _TX_Beacon_CMD_);
res = rtw_enqueue_cmd(pcmdpriv, ph2c);
diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
index 59c6d8ab60f6..0b70fe7d3b72 100644
--- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
+++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
@@ -38,7 +38,7 @@ static int rtw_hw_suspend(struct adapter *padapter)
LeaveAllPowerSaveMode(padapter);
DBG_88E("==> rtw_hw_suspend\n");
- _enter_pwrlock(&pwrpriv->lock);
+ mutex_lock(&pwrpriv->mutex_lock);
pwrpriv->bips_processing = true;
/* s1. */
if (pnetdev) {
@@ -73,7 +73,7 @@ static int rtw_hw_suspend(struct adapter *padapter)
pwrpriv->rf_pwrstate = rf_off;
pwrpriv->bips_processing = false;
- _exit_pwrlock(&pwrpriv->lock);
+ mutex_unlock(&pwrpriv->mutex_lock);
return 0;
@@ -90,12 +90,12 @@ static int rtw_hw_resume(struct adapter *padapter)
/* system resume */
DBG_88E("==> rtw_hw_resume\n");
- _enter_pwrlock(&pwrpriv->lock);
+ mutex_lock(&pwrpriv->mutex_lock);
pwrpriv->bips_processing = true;
rtw_reset_drv_sw(padapter);
if (pm_netdev_open(pnetdev, false) != 0) {
- _exit_pwrlock(&pwrpriv->lock);
+ mutex_unlock(&pwrpriv->mutex_lock);
goto error_exit;
}
@@ -113,7 +113,7 @@ static int rtw_hw_resume(struct adapter *padapter)
pwrpriv->rf_pwrstate = rf_on;
pwrpriv->bips_processing = false;
- _exit_pwrlock(&pwrpriv->lock);
+ mutex_unlock(&pwrpriv->mutex_lock);
return 0;
@@ -138,7 +138,7 @@ void ips_enter(struct adapter *padapter)
return;
}
- _enter_pwrlock(&pwrpriv->lock);
+ mutex_lock(&pwrpriv->mutex_lock);
pwrpriv->bips_processing = true;
@@ -159,7 +159,7 @@ void ips_enter(struct adapter *padapter)
}
pwrpriv->bips_processing = false;
- _exit_pwrlock(&pwrpriv->lock);
+ mutex_unlock(&pwrpriv->mutex_lock);
}
int ips_leave(struct adapter *padapter)
@@ -171,7 +171,7 @@ int ips_leave(struct adapter *padapter)
int keyid;
- _enter_pwrlock(&pwrpriv->lock);
+ mutex_lock(&pwrpriv->mutex_lock);
if ((pwrpriv->rf_pwrstate == rf_off) && (!pwrpriv->bips_processing)) {
pwrpriv->bips_processing = true;
@@ -205,7 +205,7 @@ int ips_leave(struct adapter *padapter)
pwrpriv->bpower_saving = false;
}
- _exit_pwrlock(&pwrpriv->lock);
+ mutex_unlock(&pwrpriv->mutex_lock);
return result;
}
@@ -504,7 +504,7 @@ void rtw_init_pwrctrl_priv(struct adapter *padapter)
{
struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
- _init_pwrlock(&pwrctrlpriv->lock);
+ mutex_init(&pwrctrlpriv->mutex_lock);
pwrctrlpriv->rf_pwrstate = rf_on;
pwrctrlpriv->ips_enter_cnts = 0;
pwrctrlpriv->ips_leave_cnts = 0;
diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c
index 977bb2532c3e..b87cbbbee054 100644
--- a/drivers/staging/rtl8188eu/core/rtw_recv.c
+++ b/drivers/staging/rtl8188eu/core/rtw_recv.c
@@ -39,7 +39,7 @@ static u8 rtw_rfc1042_header[] = {
0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00
};
-void rtw_signal_stat_timer_hdl(unsigned long data);
+static void rtw_signal_stat_timer_hdl(unsigned long data);
void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
{
@@ -73,7 +73,7 @@ int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter)
if (!precvpriv->pallocated_frame_buf)
return _FAIL;
- precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ);
+ precvpriv->precv_frame_buf = PTR_ALIGN(precvpriv->pallocated_frame_buf, RXFRAME_ALIGN_SZ);
precvframe = (struct recv_frame *)precvpriv->precv_frame_buf;
@@ -2088,7 +2088,7 @@ _recv_entry_drop:
return ret;
}
-void rtw_signal_stat_timer_hdl(unsigned long data)
+static void rtw_signal_stat_timer_hdl(unsigned long data)
{
struct adapter *adapter = (struct adapter *)data;
struct recv_priv *recvpriv = &adapter->recvpriv;
diff --git a/drivers/staging/rtl8188eu/core/rtw_rf.c b/drivers/staging/rtl8188eu/core/rtw_rf.c
index 3fc1a8fd367c..e47be87fb402 100644
--- a/drivers/staging/rtl8188eu/core/rtw_rf.c
+++ b/drivers/staging/rtl8188eu/core/rtw_rf.c
@@ -19,7 +19,6 @@
#include <recv_osdep.h>
#include <xmit_osdep.h>
-
struct ch_freq {
u32 channel;
u32 frequency;
diff --git a/drivers/staging/rtl8188eu/core/rtw_security.c b/drivers/staging/rtl8188eu/core/rtw_security.c
index 442a614a3726..85bb441a7214 100644
--- a/drivers/staging/rtl8188eu/core/rtw_security.c
+++ b/drivers/staging/rtl8188eu/core/rtw_security.c
@@ -233,7 +233,6 @@ void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe)
&crc, &payload[length-4]));
}
}
- return;
}
/* 3 ===== TKIP related ===== */
diff --git a/drivers/staging/rtl8188eu/core/rtw_sreset.c b/drivers/staging/rtl8188eu/core/rtw_sreset.c
index 13a5bf4730ab..a198c5779d50 100644
--- a/drivers/staging/rtl8188eu/core/rtw_sreset.c
+++ b/drivers/staging/rtl8188eu/core/rtw_sreset.c
@@ -16,18 +16,16 @@
#include <rtw_sreset.h>
#include <usb_ops_linux.h>
-void sreset_init_value(struct adapter *padapter)
+void rtw_hal_sreset_init(struct adapter *padapter)
{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
+ struct sreset_priv *psrtpriv = &padapter->HalData->srestpriv;
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
}
u8 sreset_get_wifi_status(struct adapter *padapter)
{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
+ struct sreset_priv *psrtpriv = &padapter->HalData->srestpriv;
u8 status = WIFI_STATUS_SUCCESS;
u32 val32 = 0;
@@ -54,6 +52,5 @@ u8 sreset_get_wifi_status(struct adapter *padapter)
void sreset_set_wifi_error_status(struct adapter *padapter, u32 status)
{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
- pHalData->srestpriv.Wifi_Error_Status = status;
+ padapter->HalData->srestpriv.Wifi_Error_Status = status;
}
diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
index 4410fe8d7c68..2a65ac702129 100644
--- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
@@ -341,9 +341,6 @@ void set_channel_bwmode(struct adapter *padapter, unsigned char channel, unsigne
{
u8 center_ch;
- if (padapter->bNotifyChannelChange)
- DBG_88E("[%s] ch = %d, offset = %d, bwmode = %d\n", __func__, channel, channel_offset, bwmode);
-
if ((bwmode == HT_CHANNEL_WIDTH_20) ||
(channel_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)) {
/* SelectChannel(padapter, channel); */
@@ -716,6 +713,7 @@ void HT_caps_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct ht_priv *phtpriv = &pmlmepriv->htpriv;
+ u8 *HT_cap = (u8 *)(&pmlmeinfo->HT_caps);
if (pIE == NULL)
return;
@@ -728,20 +726,20 @@ void HT_caps_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
for (i = 0; i < (pIE->Length); i++) {
if (i != 2) {
/* Got the endian issue here. */
- pmlmeinfo->HT_caps.u.HT_cap[i] &= (pIE->data[i]);
+ HT_cap[i] &= (pIE->data[i]);
} else {
/* modify from fw by Thomas 2010/11/17 */
- if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (pIE->data[i] & 0x3))
+ if ((pmlmeinfo->HT_caps.ampdu_params_info & 0x3) > (pIE->data[i] & 0x3))
max_AMPDU_len = pIE->data[i] & 0x3;
else
- max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3;
+ max_AMPDU_len = pmlmeinfo->HT_caps.ampdu_params_info & 0x3;
- if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) > (pIE->data[i] & 0x1c))
- min_MPDU_spacing = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c;
+ if ((pmlmeinfo->HT_caps.ampdu_params_info & 0x1c) > (pIE->data[i] & 0x1c))
+ min_MPDU_spacing = pmlmeinfo->HT_caps.ampdu_params_info & 0x1c;
else
min_MPDU_spacing = pIE->data[i] & 0x1c;
- pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para = max_AMPDU_len | min_MPDU_spacing;
+ pmlmeinfo->HT_caps.ampdu_params_info = max_AMPDU_len | min_MPDU_spacing;
}
}
@@ -750,9 +748,9 @@ void HT_caps_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
/* update the MCS rates */
for (i = 0; i < 16; i++) {
if ((rf_type == RF_1T1R) || (rf_type == RF_1T2R))
- pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
+ ((u8 *)&pmlmeinfo->HT_caps.mcs)[i] &= MCS_rate_1R[i];
else
- pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i];
+ ((u8 *)&pmlmeinfo->HT_caps.mcs)[i] &= MCS_rate_2R[i];
}
}
@@ -798,9 +796,9 @@ void HTOnAssocRsp(struct adapter *padapter)
AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
AMPDU_para [4:2]:Min MPDU Start Spacing
*/
- max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
+ max_AMPDU_len = pmlmeinfo->HT_caps.ampdu_params_info & 0x03;
- min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
+ min_MPDU_spacing = (pmlmeinfo->HT_caps.ampdu_params_info & 0x1c) >> 2;
rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
@@ -872,7 +870,6 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len)
u32 wpa_ielen = 0;
u8 *pbssid = GetAddr3Ptr(pframe);
struct HT_info_element *pht_info = NULL;
- struct rtw_ieee80211_ht_cap *pht_cap = NULL;
u32 bcn_channel;
unsigned short ht_cap_info;
unsigned char ht_info_infos_0;
@@ -881,7 +878,7 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len)
if (is_client_associated_to_ap(Adapter) == false)
return true;
- len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
+ len = packet_len - sizeof(struct ieee80211_hdr_3addr);
if (len > MAX_IE_SZ) {
DBG_88E("%s IE too long for survey event\n", __func__);
@@ -907,14 +904,16 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len)
/* below is to copy the information element */
bssid->IELength = len;
- memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
+ memcpy(bssid->IEs, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->IELength);
/* check bw and channel offset */
/* parsing HT_CAP_IE */
p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
if (p && len > 0) {
- pht_cap = (struct rtw_ieee80211_ht_cap *)(p + 2);
- ht_cap_info = pht_cap->cap_info;
+ struct ieee80211_ht_cap *ht_cap =
+ (struct ieee80211_ht_cap *)(p + 2);
+
+ ht_cap_info = le16_to_cpu(ht_cap->cap_info);
} else {
ht_cap_info = 0;
}
@@ -1243,16 +1242,17 @@ unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz)
return mask;
}
-unsigned int update_MSC_rate(struct HT_caps_element *pHT_caps)
+unsigned int update_MSC_rate(struct ieee80211_ht_cap *pHT_caps)
{
unsigned int mask = 0;
- mask = (pHT_caps->u.HT_cap_element.MCS_rate[0] << 12) | (pHT_caps->u.HT_cap_element.MCS_rate[1] << 20);
+ mask = (pHT_caps->mcs.rx_mask[0] << 12) |
+ (pHT_caps->mcs.rx_mask[1] << 20);
return mask;
}
-int support_short_GI(struct adapter *padapter, struct HT_caps_element *pHT_caps)
+int support_short_GI(struct adapter *padapter, struct ieee80211_ht_cap *pHT_caps)
{
unsigned char bit_offset;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
@@ -1266,7 +1266,7 @@ int support_short_GI(struct adapter *padapter, struct HT_caps_element *pHT_caps)
bit_offset = (pmlmeext->cur_bwmode & HT_CHANNEL_WIDTH_40) ? 6 : 5;
- if (__le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info) & (0x1 << bit_offset))
+ if (__le16_to_cpu(pHT_caps->cap_info) & (0x1 << bit_offset))
return _SUCCESS;
else
return _FAIL;
@@ -1508,7 +1508,7 @@ void update_wireless_mode(struct adapter *padapter)
SIFS_Timer = 0x0a0a0808;/* 0x0808 -> for CCK, 0x0a0a -> for OFDM */
/* change this value if having IOT issues. */
- padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_RESP_SIFS, (u8 *)&SIFS_Timer);
+ rtw_hal_set_hwreg(padapter, HW_VAR_RESP_SIFS, (u8 *)&SIFS_Timer);
if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
@@ -1584,7 +1584,7 @@ void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len)
u8 *pIE;
__le32 *pbuf;
- pIE = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
+ pIE = pframe + sizeof(struct ieee80211_hdr_3addr);
pbuf = (__le32 *)pIE;
pmlmeext->TSFValue = le32_to_cpu(*(pbuf+1));
diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c
index e0a5567f5942..0f8b8e0bffdf 100644
--- a/drivers/staging/rtl8188eu/core/rtw_xmit.c
+++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c
@@ -57,8 +57,6 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
/* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */
spin_lock_init(&pxmitpriv->lock);
- sema_init(&pxmitpriv->xmit_sema, 0);
- sema_init(&pxmitpriv->terminate_xmitthread_sema, 0);
/*
Please insert all the queue initializaiton using _rtw_init_queue below
@@ -88,7 +86,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
res = _FAIL;
goto exit;
}
- pxmitpriv->pxmit_frame_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_frame_buf), 4);
+ pxmitpriv->pxmit_frame_buf = PTR_ALIGN(pxmitpriv->pallocated_frame_buf, 4);
/* pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - */
/* ((size_t) (pxmitpriv->pallocated_frame_buf) &3); */
@@ -126,7 +124,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
goto exit;
}
- pxmitpriv->pxmitbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmitbuf), 4);
+ pxmitpriv->pxmitbuf = PTR_ALIGN(pxmitpriv->pallocated_xmitbuf, 4);
/* pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - */
/* ((size_t) (pxmitpriv->pallocated_xmitbuf) &3); */
@@ -144,9 +142,8 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
if (res == _FAIL) {
msleep(10);
res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
- if (res == _FAIL) {
+ if (res == _FAIL)
goto exit;
- }
}
pxmitbuf->flags = XMIT_VO_QUEUE;
@@ -168,7 +165,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
goto exit;
}
- pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4);
+ pxmitpriv->pxmit_extbuf = PTR_ALIGN(pxmitpriv->pallocated_xmit_extbuf, 4);
pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
@@ -199,8 +196,6 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
pxmitpriv->txirp_cnt = 1;
- sema_init(&(pxmitpriv->tx_retevt), 0);
-
/* per AC pending irp */
pxmitpriv->beq_cnt = 0;
pxmitpriv->bkq_cnt = 0;
@@ -252,9 +247,8 @@ void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv)
pxmitbuf++;
}
- if (pxmitpriv->pallocated_xmit_extbuf) {
+ if (pxmitpriv->pallocated_xmit_extbuf)
vfree(pxmitpriv->pallocated_xmit_extbuf);
- }
rtw_free_hwxmits(padapter);
@@ -408,7 +402,7 @@ static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
_rtw_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr));
/* user_prio = (ntohs(ip_hdr.tos) >> 5) & 0x3; */
user_prio = ip_hdr.tos >> 5;
- } else if (pattrib->ether_type == 0x888e) {
+ } else if (pattrib->ether_type == ETH_P_PAE) {
/* "When priority processing of data frames is supported, */
/* a STA's SME should send EAPOL-Key frames at the highest priority." */
user_prio = 7;
@@ -457,14 +451,14 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p
pattrib->pktlen = pktfile.pkt_len;
- if (ETH_P_IP == pattrib->ether_type) {
+ if (pattrib->ether_type == ETH_P_IP) {
/* The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time */
/* to prevent DHCP protocol fail */
u8 tmp[24];
_rtw_pktfile_read(&pktfile, &tmp[0], 24);
pattrib->dhcp_pkt = 0;
if (pktfile.pkt_len > 282) {/* MINIMUM_DHCP_PACKET_SIZE) { */
- if (ETH_P_IP == pattrib->ether_type) {/* IP header */
+ if (pattrib->ether_type == ETH_P_IP) {/* IP header */
if (((tmp[21] == 68) && (tmp[23] == 67)) ||
((tmp[21] == 67) && (tmp[23] == 68))) {
/* 68 : UDP BOOTP client */
@@ -475,15 +469,15 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p
}
}
}
- } else if (0x888e == pattrib->ether_type) {
+ } else if (pattrib->ether_type == ETH_P_PAE) {
DBG_88E_LEVEL(_drv_info_, "send eapol packet\n");
}
- if ((pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
+ if ((pattrib->ether_type == ETH_P_PAE) || (pattrib->dhcp_pkt == 1))
rtw_set_scan_deny(padapter, 3000);
/* If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */
- if ((pattrib->ether_type == 0x0806) || (pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
+ if ((pattrib->ether_type == ETH_P_ARP) || (pattrib->ether_type == ETH_P_PAE) || (pattrib->dhcp_pkt == 1))
rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
bmcast = IS_MCAST(pattrib->ra);
@@ -515,8 +509,6 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p
}
pattrib->ack_policy = 0;
- /* get ether_hdr_len */
- pattrib->pkt_hdrlen = ETH_HLEN;/* pattrib->ether_type == 0x8100) ? (14 + 4): 14; vlan tag */
pattrib->hdrlen = WLAN_HDR_A3_LEN;
pattrib->subtype = WIFI_DATA_TYPE;
@@ -539,8 +531,8 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p
pattrib->encrypt = 0;
- if ((pattrib->ether_type != 0x888e) && !check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("\npsta->ieee8021x_blocked == true, pattrib->ether_type(%.4x) != 0x888e\n", pattrib->ether_type));
+ if ((pattrib->ether_type != ETH_P_PAE) && !check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
+ RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("\npsta->ieee8021x_blocked == true, pattrib->ether_type(%.4x) != ETH_P_PAE\n", pattrib->ether_type));
res = _FAIL;
goto exit;
}
@@ -769,13 +761,13 @@ s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattr
{
u16 *qc;
- struct rtw_ieee80211_hdr *pwlanhdr = (struct rtw_ieee80211_hdr *)hdr;
+ struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct qos_priv *pqospriv = &pmlmepriv->qospriv;
u8 qos_option = false;
int res = _SUCCESS;
- __le16 *fctrl = &pwlanhdr->frame_ctl;
+ __le16 *fctrl = &pwlanhdr->frame_control;
struct sta_info *psta;
@@ -785,11 +777,10 @@ s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattr
if (pattrib->psta) {
psta = pattrib->psta;
} else {
- if (bmcst) {
+ if (bmcst)
psta = rtw_get_bcmc_stainfo(padapter);
- } else {
+ else
psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
- }
}
memset(hdr, 0, WLANHDR_OFFSET);
@@ -999,7 +990,7 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct
}
_rtw_open_pktfile(pkt, &pktfile);
- _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
+ _rtw_pktfile_read(&pktfile, NULL, ETH_HLEN);
frg_inx = 0;
frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */
@@ -1054,9 +1045,8 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct
mpdu_len -= llc_sz;
}
- if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
+ if ((pattrib->icv_len > 0) && (pattrib->bswenc))
mpdu_len -= pattrib->icv_len;
- }
if (bmcst) {
/* don't do fragment to broadcat/multicast packets */
@@ -1560,11 +1550,10 @@ s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)
int res = _SUCCESS;
- if (pattrib->psta) {
+ if (pattrib->psta)
psta = pattrib->psta;
- } else {
+ else
psta = rtw_get_stainfo(pstapriv, pattrib->ra);
- }
if (psta == NULL) {
res = _FAIL;
@@ -1658,16 +1647,6 @@ u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
return addr;
}
-static void do_queue_select(struct adapter *padapter, struct pkt_attrib *pattrib)
-{
- u8 qsel;
-
- qsel = pattrib->priority;
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("### do_queue_select priority=%d , qsel = %d\n", pattrib->priority, qsel));
-
- pattrib->qsel = qsel;
-}
-
/*
* The main transmit(tx) entry
*
@@ -1700,7 +1679,7 @@ s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt)
rtw_led_control(padapter, LED_CTL_TX);
- do_queue_select(padapter, &pxmitframe->attrib);
+ pxmitframe->attrib.qsel = pxmitframe->attrib.priority;
#ifdef CONFIG_88EU_AP_MODE
spin_lock_bh(&pxmitpriv->lock);
diff --git a/drivers/staging/rtl8188eu/hal/bb_cfg.c b/drivers/staging/rtl8188eu/hal/bb_cfg.c
index cce1ea259b76..134fa6c595a8 100644
--- a/drivers/staging/rtl8188eu/hal/bb_cfg.c
+++ b/drivers/staging/rtl8188eu/hal/bb_cfg.c
@@ -498,7 +498,7 @@ static u32 array_phy_reg_pg_8188e[] = {
static void store_pwrindex_offset(struct adapter *adapter,
u32 regaddr, u32 bitmask, u32 data)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapter);
+ struct hal_data_8188e *hal_data = adapter->HalData;
u32 * const power_level_offset =
hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt];
@@ -518,8 +518,7 @@ static void store_pwrindex_offset(struct adapter *adapter,
power_level_offset[4] = data;
if (regaddr == rTxAGC_A_Mcs15_Mcs12) {
power_level_offset[5] = data;
- if (hal_data->rf_type == RF_1T1R)
- hal_data->pwrGroupCnt++;
+ hal_data->pwrGroupCnt++;
}
if (regaddr == rTxAGC_B_Rate18_06)
power_level_offset[8] = data;
@@ -537,8 +536,6 @@ static void store_pwrindex_offset(struct adapter *adapter,
power_level_offset[12] = data;
if (regaddr == rTxAGC_B_Mcs15_Mcs12) {
power_level_offset[13] = data;
- if (hal_data->rf_type != RF_1T1R)
- hal_data->pwrGroupCnt++;
}
}
@@ -588,11 +585,10 @@ static bool config_bb_with_pgheader(struct adapter *adapt)
static void rtl88e_phy_init_bb_rf_register_definition(struct adapter *adapter)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapter);
struct bb_reg_def *reg[4];
- reg[RF_PATH_A] = &hal_data->PHYRegDef[RF_PATH_A];
- reg[RF_PATH_B] = &hal_data->PHYRegDef[RF_PATH_B];
+ reg[RF_PATH_A] = &adapter->HalData->PHYRegDef[RF_PATH_A];
+ reg[RF_PATH_B] = &adapter->HalData->PHYRegDef[RF_PATH_B];
reg[RF_PATH_A]->rfintfs = rFPGA0_XAB_RFInterfaceSW;
reg[RF_PATH_B]->rfintfs = rFPGA0_XAB_RFInterfaceSW;
@@ -652,13 +648,12 @@ static void rtl88e_phy_init_bb_rf_register_definition(struct adapter *adapter)
static bool config_parafile(struct adapter *adapt)
{
struct eeprom_priv *eeprom = GET_EEPROM_EFUSE_PRIV(adapt);
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
set_baseband_phy_config(adapt);
/* If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */
if (!eeprom->bautoload_fail_flag) {
- hal_data->pwrGroupCnt = 0;
+ adapt->HalData->pwrGroupCnt = 0;
config_bb_with_pgheader(adapt);
}
set_baseband_agc_config(adapt);
@@ -668,7 +663,6 @@ static bool config_parafile(struct adapter *adapt)
bool rtl88eu_phy_bb_config(struct adapter *adapt)
{
int rtstatus = true;
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
u32 regval;
u8 crystal_cap;
@@ -688,7 +682,7 @@ bool rtl88eu_phy_bb_config(struct adapter *adapt)
rtstatus = config_parafile(adapt);
/* write 0x24[16:11] = 0x24[22:17] = crystal_cap */
- crystal_cap = hal_data->CrystalCap & 0x3F;
+ crystal_cap = adapt->HalData->CrystalCap & 0x3F;
phy_set_bb_reg(adapt, REG_AFE_XTAL_CTRL, 0x7ff800,
(crystal_cap | (crystal_cap << 6)));
diff --git a/drivers/staging/rtl8188eu/hal/hal_intf.c b/drivers/staging/rtl8188eu/hal/hal_intf.c
index 085f0fbd0c43..a11c7b4254f6 100644
--- a/drivers/staging/rtl8188eu/hal/hal_intf.c
+++ b/drivers/staging/rtl8188eu/hal/hal_intf.c
@@ -17,62 +17,6 @@
#include <osdep_service.h>
#include <drv_types.h>
#include <hal_intf.h>
-#include <usb_hal.h>
-
-void rtw_hal_chip_configure(struct adapter *adapt)
-{
- if (adapt->HalFunc.intf_chip_configure)
- adapt->HalFunc.intf_chip_configure(adapt);
-}
-
-void rtw_hal_read_chip_info(struct adapter *adapt)
-{
- if (adapt->HalFunc.read_adapter_info)
- adapt->HalFunc.read_adapter_info(adapt);
-}
-
-void rtw_hal_read_chip_version(struct adapter *adapt)
-{
- if (adapt->HalFunc.read_chip_version)
- adapt->HalFunc.read_chip_version(adapt);
-}
-
-void rtw_hal_def_value_init(struct adapter *adapt)
-{
- if (adapt->HalFunc.init_default_value)
- adapt->HalFunc.init_default_value(adapt);
-}
-
-void rtw_hal_free_data(struct adapter *adapt)
-{
- if (adapt->HalFunc.free_hal_data)
- adapt->HalFunc.free_hal_data(adapt);
-}
-
-void rtw_hal_dm_init(struct adapter *adapt)
-{
- if (adapt->HalFunc.dm_init)
- adapt->HalFunc.dm_init(adapt);
-}
-
-void rtw_hal_sw_led_init(struct adapter *adapt)
-{
- if (adapt->HalFunc.InitSwLeds)
- adapt->HalFunc.InitSwLeds(adapt);
-}
-
-void rtw_hal_sw_led_deinit(struct adapter *adapt)
-{
- if (adapt->HalFunc.DeInitSwLeds)
- adapt->HalFunc.DeInitSwLeds(adapt);
-}
-
-u32 rtw_hal_power_on(struct adapter *adapt)
-{
- if (adapt->HalFunc.hal_power_on)
- return adapt->HalFunc.hal_power_on(adapt);
- return _FAIL;
-}
uint rtw_hal_init(struct adapter *adapt)
{
@@ -80,15 +24,13 @@ uint rtw_hal_init(struct adapter *adapt)
adapt->hw_init_completed = false;
- status = adapt->HalFunc.hal_init(adapt);
+ status = rtl8188eu_hal_init(adapt);
if (status == _SUCCESS) {
adapt->hw_init_completed = true;
if (adapt->registrypriv.notch_filter == 1)
rtw_hal_notch_filter(adapt, 1);
-
- rtw_hal_reset_security_engine(adapt);
} else {
adapt->hw_init_completed = false;
DBG_88E("rtw_hal_init: hal__init fail\n");
@@ -104,7 +46,7 @@ uint rtw_hal_deinit(struct adapter *adapt)
{
uint status = _SUCCESS;
- status = adapt->HalFunc.hal_deinit(adapt);
+ status = rtl8188eu_hal_deinit(adapt);
if (status == _SUCCESS)
adapt->hw_init_completed = false;
@@ -114,92 +56,6 @@ uint rtw_hal_deinit(struct adapter *adapt)
return status;
}
-void rtw_hal_set_hwreg(struct adapter *adapt, u8 variable, u8 *val)
-{
- if (adapt->HalFunc.SetHwRegHandler)
- adapt->HalFunc.SetHwRegHandler(adapt, variable, val);
-}
-
-void rtw_hal_get_hwreg(struct adapter *adapt, u8 variable, u8 *val)
-{
- if (adapt->HalFunc.GetHwRegHandler)
- adapt->HalFunc.GetHwRegHandler(adapt, variable, val);
-}
-
-u8 rtw_hal_get_def_var(struct adapter *adapt,
- enum hal_def_variable var, void *val)
-{
- if (adapt->HalFunc.GetHalDefVarHandler)
- return adapt->HalFunc.GetHalDefVarHandler(adapt, var, val);
- return _FAIL;
-}
-
-void rtw_hal_set_odm_var(struct adapter *adapt,
- enum hal_odm_variable var, void *val1,
- bool set)
-{
- if (adapt->HalFunc.SetHalODMVarHandler)
- adapt->HalFunc.SetHalODMVarHandler(adapt, var,
- val1, set);
-}
-
-u32 rtw_hal_inirp_init(struct adapter *adapt)
-{
- u32 rst = _FAIL;
-
- if (adapt->HalFunc.inirp_init)
- rst = adapt->HalFunc.inirp_init(adapt);
- else
- DBG_88E(" %s HalFunc.inirp_init is NULL!!!\n", __func__);
- return rst;
-}
-
-u32 rtw_hal_inirp_deinit(struct adapter *adapt)
-{
- if (adapt->HalFunc.inirp_deinit)
- return adapt->HalFunc.inirp_deinit(adapt);
-
- return _FAIL;
-}
-
-s32 rtw_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe)
-{
- if (adapt->HalFunc.hal_xmit)
- return adapt->HalFunc.hal_xmit(adapt, pxmitframe);
-
- return false;
-}
-
-s32 rtw_hal_mgnt_xmit(struct adapter *adapt, struct xmit_frame *pmgntframe)
-{
- s32 ret = _FAIL;
-
- if (adapt->HalFunc.mgnt_xmit)
- ret = adapt->HalFunc.mgnt_xmit(adapt, pmgntframe);
- return ret;
-}
-
-s32 rtw_hal_init_xmit_priv(struct adapter *adapt)
-{
- if (adapt->HalFunc.init_xmit_priv)
- return adapt->HalFunc.init_xmit_priv(adapt);
- return _FAIL;
-}
-
-s32 rtw_hal_init_recv_priv(struct adapter *adapt)
-{
- if (adapt->HalFunc.init_recv_priv)
- return adapt->HalFunc.init_recv_priv(adapt);
-
- return _FAIL;
-}
-
-void rtw_hal_free_recv_priv(struct adapter *adapt)
-{
- if (adapt->HalFunc.free_recv_priv)
- adapt->HalFunc.free_recv_priv(adapt);
-}
-
void rtw_hal_update_ra_mask(struct adapter *adapt, u32 mac_id, u8 rssi_level)
{
struct mlme_priv *pmlmepriv = &(adapt->mlmepriv);
@@ -215,86 +71,6 @@ void rtw_hal_update_ra_mask(struct adapter *adapt, u32 mac_id, u8 rssi_level)
add_RATid(adapt, psta, 0);/* todo: based on rssi_level*/
#endif
} else {
- if (adapt->HalFunc.UpdateRAMaskHandler)
- adapt->HalFunc.UpdateRAMaskHandler(adapt, mac_id,
- rssi_level);
+ UpdateHalRAMask8188EUsb(adapt, mac_id, rssi_level);
}
}
-
-void rtw_hal_add_ra_tid(struct adapter *adapt, u32 bitmap, u8 arg,
- u8 rssi_level)
-{
- if (adapt->HalFunc.Add_RateATid)
- adapt->HalFunc.Add_RateATid(adapt, bitmap, arg,
- rssi_level);
-}
-
-u32 rtw_hal_read_rfreg(struct adapter *adapt, enum rf_radio_path rfpath,
- u32 regaddr, u32 bitmask)
-{
- u32 data = 0;
-
- if (adapt->HalFunc.read_rfreg)
- data = adapt->HalFunc.read_rfreg(adapt, rfpath, regaddr,
- bitmask);
- return data;
-}
-
-void rtw_hal_set_bwmode(struct adapter *adapt,
- enum ht_channel_width bandwidth, u8 offset)
-{
- if (adapt->HalFunc.set_bwmode_handler)
- adapt->HalFunc.set_bwmode_handler(adapt, bandwidth,
- offset);
-}
-
-void rtw_hal_set_chan(struct adapter *adapt, u8 channel)
-{
- if (adapt->HalFunc.set_channel_handler)
- adapt->HalFunc.set_channel_handler(adapt, channel);
-}
-
-void rtw_hal_dm_watchdog(struct adapter *adapt)
-{
- if (adapt->HalFunc.hal_dm_watchdog)
- adapt->HalFunc.hal_dm_watchdog(adapt);
-}
-
-void rtw_hal_bcn_related_reg_setting(struct adapter *adapt)
-{
- if (adapt->HalFunc.SetBeaconRelatedRegistersHandler)
- adapt->HalFunc.SetBeaconRelatedRegistersHandler(adapt);
-}
-
-u8 rtw_hal_antdiv_before_linked(struct adapter *adapt)
-{
- if (adapt->HalFunc.AntDivBeforeLinkHandler)
- return adapt->HalFunc.AntDivBeforeLinkHandler(adapt);
- return false;
-}
-
-void rtw_hal_antdiv_rssi_compared(struct adapter *adapt,
- struct wlan_bssid_ex *dst,
- struct wlan_bssid_ex *src)
-{
- if (adapt->HalFunc.AntDivCompareHandler)
- adapt->HalFunc.AntDivCompareHandler(adapt, dst, src);
-}
-
-void rtw_hal_sreset_init(struct adapter *adapt)
-{
- if (adapt->HalFunc.sreset_init_value)
- adapt->HalFunc.sreset_init_value(adapt);
-}
-
-void rtw_hal_notch_filter(struct adapter *adapter, bool enable)
-{
- if (adapter->HalFunc.hal_notch_filter)
- adapter->HalFunc.hal_notch_filter(adapter, enable);
-}
-
-void rtw_hal_reset_security_engine(struct adapter *adapter)
-{
- if (adapter->HalFunc.hal_reset_security_engine)
- adapter->HalFunc.hal_reset_security_engine(adapter);
-}
diff --git a/drivers/staging/rtl8188eu/hal/odm.c b/drivers/staging/rtl8188eu/hal/odm.c
index 57a127501694..d983a8029f4c 100644
--- a/drivers/staging/rtl8188eu/hal/odm.c
+++ b/drivers/staging/rtl8188eu/hal/odm.c
@@ -226,150 +226,6 @@ void ODM_DMWatchdog(struct odm_dm_struct *pDM_Odm)
odm_EdcaTurboCheck(pDM_Odm);
}
-/* Init /.. Fixed HW value. Only init time. */
-void ODM_CmnInfoInit(struct odm_dm_struct *pDM_Odm, enum odm_common_info_def CmnInfo, u32 Value)
-{
- /* This section is used for init value */
- switch (CmnInfo) {
- /* Fixed ODM value. */
- case ODM_CMNINFO_ABILITY:
- pDM_Odm->SupportAbility = (u32)Value;
- break;
- case ODM_CMNINFO_PLATFORM:
- pDM_Odm->SupportPlatform = (u8)Value;
- break;
- case ODM_CMNINFO_INTERFACE:
- pDM_Odm->SupportInterface = (u8)Value;
- break;
- case ODM_CMNINFO_MP_TEST_CHIP:
- pDM_Odm->bIsMPChip = (u8)Value;
- break;
- case ODM_CMNINFO_IC_TYPE:
- pDM_Odm->SupportICType = Value;
- break;
- case ODM_CMNINFO_CUT_VER:
- pDM_Odm->CutVersion = (u8)Value;
- break;
- case ODM_CMNINFO_RF_TYPE:
- pDM_Odm->RFType = (u8)Value;
- break;
- case ODM_CMNINFO_RF_ANTENNA_TYPE:
- pDM_Odm->AntDivType = (u8)Value;
- break;
- case ODM_CMNINFO_BOARD_TYPE:
- pDM_Odm->BoardType = (u8)Value;
- break;
- case ODM_CMNINFO_EXT_LNA:
- pDM_Odm->ExtLNA = (u8)Value;
- break;
- case ODM_CMNINFO_EXT_PA:
- pDM_Odm->ExtPA = (u8)Value;
- break;
- case ODM_CMNINFO_EXT_TRSW:
- pDM_Odm->ExtTRSW = (u8)Value;
- break;
- case ODM_CMNINFO_PATCH_ID:
- pDM_Odm->PatchID = (u8)Value;
- break;
- case ODM_CMNINFO_BINHCT_TEST:
- pDM_Odm->bInHctTest = (bool)Value;
- break;
- case ODM_CMNINFO_BWIFI_TEST:
- pDM_Odm->bWIFITest = (bool)Value;
- break;
- case ODM_CMNINFO_SMART_CONCURRENT:
- pDM_Odm->bDualMacSmartConcurrent = (bool)Value;
- break;
- /* To remove the compiler warning, must add an empty default statement to handle the other values. */
- default:
- /* do nothing */
- break;
- }
-
- /* Tx power tracking BB swing table. */
- /* The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */
- pDM_Odm->BbSwingIdxOfdm = 12; /* Set defalut value as index 12. */
- pDM_Odm->BbSwingIdxOfdmCurrent = 12;
- pDM_Odm->BbSwingFlagOfdm = false;
-}
-
-void ODM_CmnInfoHook(struct odm_dm_struct *pDM_Odm, enum odm_common_info_def CmnInfo, void *pValue)
-{
- /* */
- /* Hook call by reference pointer. */
- /* */
- switch (CmnInfo) {
- /* Dynamic call by reference pointer. */
- case ODM_CMNINFO_MAC_PHY_MODE:
- pDM_Odm->pMacPhyMode = (u8 *)pValue;
- break;
- case ODM_CMNINFO_TX_UNI:
- pDM_Odm->pNumTxBytesUnicast = (u64 *)pValue;
- break;
- case ODM_CMNINFO_RX_UNI:
- pDM_Odm->pNumRxBytesUnicast = (u64 *)pValue;
- break;
- case ODM_CMNINFO_WM_MODE:
- pDM_Odm->pWirelessMode = (u8 *)pValue;
- break;
- case ODM_CMNINFO_BAND:
- pDM_Odm->pBandType = (u8 *)pValue;
- break;
- case ODM_CMNINFO_SEC_CHNL_OFFSET:
- pDM_Odm->pSecChOffset = (u8 *)pValue;
- break;
- case ODM_CMNINFO_SEC_MODE:
- pDM_Odm->pSecurity = (u8 *)pValue;
- break;
- case ODM_CMNINFO_BW:
- pDM_Odm->pBandWidth = (u8 *)pValue;
- break;
- case ODM_CMNINFO_CHNL:
- pDM_Odm->pChannel = (u8 *)pValue;
- break;
- case ODM_CMNINFO_DMSP_GET_VALUE:
- pDM_Odm->pbGetValueFromOtherMac = (bool *)pValue;
- break;
- case ODM_CMNINFO_BUDDY_ADAPTOR:
- pDM_Odm->pBuddyAdapter = (struct adapter **)pValue;
- break;
- case ODM_CMNINFO_DMSP_IS_MASTER:
- pDM_Odm->pbMasterOfDMSP = (bool *)pValue;
- break;
- case ODM_CMNINFO_SCAN:
- pDM_Odm->pbScanInProcess = (bool *)pValue;
- break;
- case ODM_CMNINFO_POWER_SAVING:
- pDM_Odm->pbPowerSaving = (bool *)pValue;
- break;
- case ODM_CMNINFO_ONE_PATH_CCA:
- pDM_Odm->pOnePathCCA = (u8 *)pValue;
- break;
- case ODM_CMNINFO_DRV_STOP:
- pDM_Odm->pbDriverStopped = (bool *)pValue;
- break;
- case ODM_CMNINFO_PNP_IN:
- pDM_Odm->pbDriverIsGoingToPnpSetPowerSleep = (bool *)pValue;
- break;
- case ODM_CMNINFO_INIT_ON:
- pDM_Odm->pinit_adpt_in_progress = (bool *)pValue;
- break;
- case ODM_CMNINFO_ANT_TEST:
- pDM_Odm->pAntennaTest = (u8 *)pValue;
- break;
- case ODM_CMNINFO_NET_CLOSED:
- pDM_Odm->pbNet_closed = (bool *)pValue;
- break;
- case ODM_CMNINFO_MP_MODE:
- pDM_Odm->mp_mode = (u8 *)pValue;
- break;
- /* To remove the compiler warning, must add an empty default statement to handle the other values. */
- default:
- /* do nothing */
- break;
- }
-}
-
void ODM_CmnInfoPtrArrayHook(struct odm_dm_struct *pDM_Odm, enum odm_common_info_def CmnInfo, u16 Index, void *pValue)
{
/* Hook call by reference pointer. */
@@ -385,46 +241,6 @@ void ODM_CmnInfoPtrArrayHook(struct odm_dm_struct *pDM_Odm, enum odm_common_info
}
}
-/* Update Band/CHannel/.. The values are dynamic but non-per-packet. */
-void ODM_CmnInfoUpdate(struct odm_dm_struct *pDM_Odm, u32 CmnInfo, u64 Value)
-{
- /* */
- /* This init variable may be changed in run time. */
- /* */
- switch (CmnInfo) {
- case ODM_CMNINFO_ABILITY:
- pDM_Odm->SupportAbility = (u32)Value;
- break;
- case ODM_CMNINFO_RF_TYPE:
- pDM_Odm->RFType = (u8)Value;
- break;
- case ODM_CMNINFO_WIFI_DIRECT:
- pDM_Odm->bWIFI_Direct = (bool)Value;
- break;
- case ODM_CMNINFO_WIFI_DISPLAY:
- pDM_Odm->bWIFI_Display = (bool)Value;
- break;
- case ODM_CMNINFO_LINK:
- pDM_Odm->bLinked = (bool)Value;
- break;
- case ODM_CMNINFO_RSSI_MIN:
- pDM_Odm->RSSI_Min = (u8)Value;
- break;
- case ODM_CMNINFO_DBG_COMP:
- pDM_Odm->DebugComponents = Value;
- break;
- case ODM_CMNINFO_DBG_LEVEL:
- pDM_Odm->DebugLevel = (u32)Value;
- break;
- case ODM_CMNINFO_RA_THRESHOLD_HIGH:
- pDM_Odm->RateAdaptive.HighRSSIThresh = (u8)Value;
- break;
- case ODM_CMNINFO_RA_THRESHOLD_LOW:
- pDM_Odm->RateAdaptive.LowRSSIThresh = (u8)Value;
- break;
- }
-}
-
void odm_CommonInfoSelfInit(struct odm_dm_struct *pDM_Odm)
{
struct adapter *adapter = pDM_Odm->Adapter;
@@ -469,7 +285,6 @@ void odm_CmnInfoInit_Debug(struct odm_dm_struct *pDM_Odm)
ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportInterface=%d\n", pDM_Odm->SupportInterface));
ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportICType=0x%x\n", pDM_Odm->SupportICType));
ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("CutVersion=%d\n", pDM_Odm->CutVersion));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("RFType=%d\n", pDM_Odm->RFType));
ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("BoardType=%d\n", pDM_Odm->BoardType));
ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtLNA=%d\n", pDM_Odm->ExtLNA));
ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtPA=%d\n", pDM_Odm->ExtPA));
@@ -947,37 +762,21 @@ u32 ODM_Get_Rate_Bitmap(struct odm_dm_struct *pDM_Odm, u32 macid, u32 ra_mask, u
break;
case (ODM_WM_B|ODM_WM_G|ODM_WM_N24G):
case (ODM_WM_A|ODM_WM_B|ODM_WM_G|ODM_WM_N24G):
- if (pDM_Odm->RFType == ODM_1T2R || pDM_Odm->RFType == ODM_1T1R) {
- if (rssi_level == DM_RATR_STA_HIGH) {
- rate_bitmap = 0x000f0000;
- } else if (rssi_level == DM_RATR_STA_MIDDLE) {
- rate_bitmap = 0x000ff000;
- } else {
- if (*(pDM_Odm->pBandWidth) == ODM_BW40M)
- rate_bitmap = 0x000ff015;
- else
- rate_bitmap = 0x000ff005;
- }
+ if (rssi_level == DM_RATR_STA_HIGH) {
+ rate_bitmap = 0x000f0000;
+ } else if (rssi_level == DM_RATR_STA_MIDDLE) {
+ rate_bitmap = 0x000ff000;
} else {
- if (rssi_level == DM_RATR_STA_HIGH) {
- rate_bitmap = 0x0f8f0000;
- } else if (rssi_level == DM_RATR_STA_MIDDLE) {
- rate_bitmap = 0x0f8ff000;
- } else {
- if (*(pDM_Odm->pBandWidth) == ODM_BW40M)
- rate_bitmap = 0x0f8ff015;
- else
- rate_bitmap = 0x0f8ff005;
- }
+ if (*(pDM_Odm->pBandWidth) == ODM_BW40M)
+ rate_bitmap = 0x000ff015;
+ else
+ rate_bitmap = 0x000ff005;
}
break;
default:
/* case WIRELESS_11_24N: */
/* case WIRELESS_11_5N: */
- if (pDM_Odm->RFType == RF_1T2R)
- rate_bitmap = 0x000fffff;
- else
- rate_bitmap = 0x0fffffff;
+ rate_bitmap = 0x0fffffff;
break;
}
@@ -1096,8 +895,7 @@ bool ODM_RAStateCheck(struct odm_dm_struct *pDM_Odm, s32 RSSI, bool bForceUpdate
void odm_DynamicTxPowerInit(struct odm_dm_struct *pDM_Odm)
{
struct adapter *Adapter = pDM_Odm->Adapter;
- struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
+ struct dm_priv *pdmpriv = &Adapter->HalData->dmpriv;
pdmpriv->bDynamicTxPowerEnable = false;
pdmpriv->LastDTPLvl = TxHighPwrLevel_Normal;
pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal;
@@ -1122,8 +920,7 @@ void odm_RSSIMonitorCheck(struct odm_dm_struct *pDM_Odm)
static void FindMinimumRSSI(struct adapter *pAdapter)
{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
+ struct dm_priv *pdmpriv = &pAdapter->HalData->dmpriv;
/* 1 1.Unconditionally set RSSI */
pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB;
@@ -1132,8 +929,7 @@ static void FindMinimumRSSI(struct adapter *pAdapter)
void odm_RSSIMonitorCheckCE(struct odm_dm_struct *pDM_Odm)
{
struct adapter *Adapter = pDM_Odm->Adapter;
- struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
+ struct dm_priv *pdmpriv = &Adapter->HalData->dmpriv;
int i;
int tmpEntryMaxPWDB = 0, tmpEntryMinPWDB = 0xff;
u8 sta_cnt = 0;
@@ -1162,7 +958,7 @@ void odm_RSSIMonitorCheckCE(struct odm_dm_struct *pDM_Odm)
for (i = 0; i < sta_cnt; i++) {
if (PWDB_rssi[i] != 0) {
- ODM_RA_SetRSSI_8188E(&pHalData->odmpriv,
+ ODM_RA_SetRSSI_8188E(&Adapter->HalData->odmpriv,
PWDB_rssi[i] & 0xFF,
(PWDB_rssi[i] >> 16) & 0xFF);
}
@@ -1179,8 +975,7 @@ void odm_RSSIMonitorCheckCE(struct odm_dm_struct *pDM_Odm)
pdmpriv->EntryMinUndecoratedSmoothedPWDB = 0;
FindMinimumRSSI(Adapter);
- ODM_CmnInfoUpdate(&pHalData->odmpriv, ODM_CMNINFO_RSSI_MIN,
- pdmpriv->MinUndecoratedPWDBForDM);
+ Adapter->HalData->odmpriv.RSSI_Min = pdmpriv->MinUndecoratedPWDBForDM;
}
/* 3============================================================ */
@@ -1290,7 +1085,6 @@ void odm_EdcaTurboCheckCE(struct odm_dm_struct *pDM_Odm)
u64 cur_tx_bytes = 0;
u64 cur_rx_bytes = 0;
u8 bbtchange = false;
- struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv);
struct recv_priv *precvpriv = &(Adapter->recvpriv);
struct registry_priv *pregpriv = &Adapter->registrypriv;
@@ -1344,7 +1138,8 @@ void odm_EdcaTurboCheckCE(struct odm_dm_struct *pDM_Odm)
/* Turn Off EDCA turbo here. */
/* Restore original EDCA according to the declaration of AP. */
if (pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) {
- usb_write32(Adapter, REG_EDCA_BE_PARAM, pHalData->AcParam_BE);
+ usb_write32(Adapter, REG_EDCA_BE_PARAM,
+ Adapter->HalData->AcParam_BE);
pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false;
}
}
diff --git a/drivers/staging/rtl8188eu/hal/phy.c b/drivers/staging/rtl8188eu/hal/phy.c
index a83bbea9be93..5192ef70bcfc 100644
--- a/drivers/staging/rtl8188eu/hal/phy.c
+++ b/drivers/staging/rtl8188eu/hal/phy.c
@@ -65,8 +65,7 @@ static u32 rf_serial_read(struct adapter *adapt,
enum rf_radio_path rfpath, u32 offset)
{
u32 ret = 0;
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
- struct bb_reg_def *phyreg = &hal_data->PHYRegDef[rfpath];
+ struct bb_reg_def *phyreg = &adapt->HalData->PHYRegDef[rfpath];
u32 tmplong, tmplong2;
u8 rfpi_enable = 0;
@@ -110,15 +109,14 @@ static void rf_serial_write(struct adapter *adapt,
u32 data)
{
u32 data_and_addr = 0;
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
- struct bb_reg_def *phyreg = &hal_data->PHYRegDef[rfpath];
+ struct bb_reg_def *phyreg = &adapt->HalData->PHYRegDef[rfpath];
offset &= 0xff;
data_and_addr = ((offset<<20) | (data&0x000fffff)) & 0x0fffffff;
phy_set_bb_reg(adapt, phyreg->rf3wireOffset, bMaskDWord, data_and_addr);
}
-u32 phy_query_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path,
+u32 rtw_hal_read_rfreg(struct adapter *adapt, enum rf_radio_path rf_path,
u32 reg_addr, u32 bit_mask)
{
u32 original_value, readback_value, bit_shift;
@@ -147,14 +145,11 @@ void phy_set_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path,
static void get_tx_power_index(struct adapter *adapt, u8 channel, u8 *cck_pwr,
u8 *ofdm_pwr, u8 *bw20_pwr, u8 *bw40_pwr)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *hal_data = adapt->HalData;
u8 index = (channel - 1);
u8 TxCount = 0, path_nums;
- if ((RF_1T2R == hal_data->rf_type) || (RF_1T1R == hal_data->rf_type))
- path_nums = 1;
- else
- path_nums = 2;
+ path_nums = 1;
for (TxCount = 0; TxCount < path_nums; TxCount++) {
if (TxCount == RF_PATH_A) {
@@ -183,7 +178,7 @@ static void phy_power_index_check(struct adapter *adapt, u8 channel,
u8 *cck_pwr, u8 *ofdm_pwr, u8 *bw20_pwr,
u8 *bw40_pwr)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *hal_data = adapt->HalData;
hal_data->CurrentCckTxPwrIdx = cck_pwr[0];
hal_data->CurrentOfdm24GTxPwrIdx = ofdm_pwr[0];
@@ -211,7 +206,7 @@ void phy_set_tx_power_level(struct adapter *adapt, u8 channel)
static void phy_set_bw_mode_callback(struct adapter *adapt)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *hal_data = adapt->HalData;
u8 reg_bw_opmode;
u8 reg_prsr_rsc;
@@ -274,10 +269,10 @@ static void phy_set_bw_mode_callback(struct adapter *adapt)
rtl88eu_phy_rf6052_set_bandwidth(adapt, hal_data->CurrentChannelBW);
}
-void phy_set_bw_mode(struct adapter *adapt, enum ht_channel_width bandwidth,
+void rtw_hal_set_bwmode(struct adapter *adapt, enum ht_channel_width bandwidth,
unsigned char offset)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *hal_data = adapt->HalData;
enum ht_channel_width tmp_bw = hal_data->CurrentChannelBW;
hal_data->CurrentChannelBW = bandwidth;
@@ -293,10 +288,7 @@ static void phy_sw_chnl_callback(struct adapter *adapt, u8 channel)
{
u8 rf_path;
u32 param1, param2;
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
-
- if (adapt->bNotifyChannelChange)
- DBG_88E("[%s] ch = %d\n", __func__, channel);
+ struct hal_data_8188e *hal_data = adapt->HalData;
phy_set_tx_power_level(adapt, channel);
@@ -310,9 +302,9 @@ static void phy_sw_chnl_callback(struct adapter *adapt, u8 channel)
}
}
-void phy_sw_chnl(struct adapter *adapt, u8 channel)
+void rtw_hal_set_chan(struct adapter *adapt, u8 channel)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *hal_data = adapt->HalData;
u8 tmpchannel = hal_data->CurrentChannel;
if (hal_data->rf_chip == RF_PSEUDO_11N)
@@ -407,7 +399,7 @@ static void dm_txpwr_track_setpwr(struct odm_dm_struct *dm_odm)
void rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter *adapt)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *hal_data = adapt->HalData;
u8 thermal_val = 0, delta, delta_lck, delta_iqk, offset;
u8 thermal_avg_count = 0;
u32 thermal_avg = 0;
@@ -439,7 +431,7 @@ void rtl88eu_dm_txpower_tracking_callback_thermalmeter(struct adapter *adapt)
dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317;
- thermal_val = (u8)phy_query_rf_reg(adapt, RF_PATH_A,
+ thermal_val = (u8)rtw_hal_read_rfreg(adapt, RF_PATH_A,
RF_T_METER_88E, 0xfc00);
if (is2t)
@@ -632,8 +624,7 @@ static u8 phy_path_a_rx_iqk(struct adapter *adapt, bool configPathB)
{
u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u4tmp;
u8 result = 0x00;
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
- struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
+ struct odm_dm_struct *dm_odm = &adapt->HalData->odmpriv;
/* 1 Get TXIMR setting */
/* modify RXIQK mode table */
@@ -737,8 +728,7 @@ static u8 phy_path_b_iqk(struct adapter *adapt)
{
u32 regeac, regeb4, regebc, regec4, regecc;
u8 result = 0x00;
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
- struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
+ struct odm_dm_struct *dm_odm = &adapt->HalData->odmpriv;
/* One shot, path B LOK & IQK */
phy_set_bb_reg(adapt, rIQK_AGC_Cont, bMaskDWord, 0x00000002);
@@ -954,17 +944,11 @@ static bool simularity_compare(struct adapter *adapt, s32 resulta[][8],
u8 c1, u8 c2)
{
u32 i, j, diff, sim_bitmap = 0, bound;
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
- struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
bool result = true;
s32 tmp1 = 0, tmp2 = 0;
- if ((dm_odm->RFType == ODM_2T2R) || (dm_odm->RFType == ODM_2T3R) ||
- (dm_odm->RFType == ODM_2T4R))
- bound = 8;
- else
- bound = 4;
+ bound = 4;
for (i = 0; i < bound; i++) {
if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
@@ -1033,8 +1017,7 @@ static bool simularity_compare(struct adapter *adapt, s32 resulta[][8],
static void phy_iq_calibrate(struct adapter *adapt, s32 result[][8],
u8 t, bool is2t)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
- struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
+ struct odm_dm_struct *dm_odm = &adapt->HalData->odmpriv;
u32 i;
u8 path_a_ok, path_b_ok;
u32 adda_reg[IQK_ADDA_REG_NUM] = {
@@ -1232,12 +1215,12 @@ static void phy_lc_calibrate(struct adapter *adapt, bool is2t)
if ((tmpreg&0x70) != 0) {
/* 1. Read original RF mode */
/* Path-A */
- rf_a_mode = phy_query_rf_reg(adapt, RF_PATH_A, RF_AC,
+ rf_a_mode = rtw_hal_read_rfreg(adapt, RF_PATH_A, RF_AC,
bMask12Bits);
/* Path-B */
if (is2t)
- rf_b_mode = phy_query_rf_reg(adapt, RF_PATH_B, RF_AC,
+ rf_b_mode = rtw_hal_read_rfreg(adapt, RF_PATH_B, RF_AC,
bMask12Bits);
/* 2. Set RF mode = standby mode */
@@ -1252,7 +1235,7 @@ static void phy_lc_calibrate(struct adapter *adapt, bool is2t)
}
/* 3. Read RF reg18 */
- lc_cal = phy_query_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits);
+ lc_cal = rtw_hal_read_rfreg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits);
/* 4. Set LC calibration begin bit15 */
phy_set_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bMask12Bits,
@@ -1279,8 +1262,7 @@ static void phy_lc_calibrate(struct adapter *adapt, bool is2t)
void rtl88eu_phy_iq_calibrate(struct adapter *adapt, bool recovery)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
- struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
+ struct odm_dm_struct *dm_odm = &adapt->HalData->odmpriv;
s32 result[4][8];
u8 i, final, chn_index;
bool pathaok, pathbok;
@@ -1295,7 +1277,7 @@ void rtl88eu_phy_iq_calibrate(struct adapter *adapt, bool recovery)
rOFDM0_RxIQExtAnta};
bool is2t;
- is2t = (dm_odm->RFType == ODM_2T2R) ? true : false;
+ is2t = false;
if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
return;
@@ -1391,7 +1373,7 @@ void rtl88eu_phy_iq_calibrate(struct adapter *adapt, bool recovery)
(reg_ec4 == 0));
}
- chn_index = get_right_chnl_for_iqk(hal_data->CurrentChannel);
+ chn_index = get_right_chnl_for_iqk(adapt->HalData->CurrentChannel);
if (final < 4) {
for (i = 0; i < IQK_Matrix_REG_NUM; i++)
@@ -1407,8 +1389,7 @@ void rtl88eu_phy_lc_calibrate(struct adapter *adapt)
{
bool singletone = false, carrier_sup = false;
u32 timeout = 2000, timecount = 0;
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
- struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
+ struct odm_dm_struct *dm_odm = &adapt->HalData->odmpriv;
if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
return;
@@ -1422,12 +1403,7 @@ void rtl88eu_phy_lc_calibrate(struct adapter *adapt)
dm_odm->RFCalibrateInfo.bLCKInProgress = true;
- if (dm_odm->RFType == ODM_2T2R) {
- phy_lc_calibrate(adapt, true);
- } else {
- /* For 88C 1T1R */
- phy_lc_calibrate(adapt, false);
- }
+ phy_lc_calibrate(adapt, false);
dm_odm->RFCalibrateInfo.bLCKInProgress = false;
}
diff --git a/drivers/staging/rtl8188eu/hal/rf.c b/drivers/staging/rtl8188eu/hal/rf.c
index 1596274eefc5..2f3edf0f850a 100644
--- a/drivers/staging/rtl8188eu/hal/rf.c
+++ b/drivers/staging/rtl8188eu/hal/rf.c
@@ -22,7 +22,7 @@
void rtl88eu_phy_rf6052_set_bandwidth(struct adapter *adapt,
enum ht_channel_width bandwidth)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *hal_data = adapt->HalData;
switch (bandwidth) {
case HT_CHANNEL_WIDTH_20:
@@ -44,7 +44,7 @@ void rtl88eu_phy_rf6052_set_bandwidth(struct adapter *adapt,
void rtl88eu_phy_rf6052_set_cck_txpower(struct adapter *adapt, u8 *powerlevel)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *hal_data = adapt->HalData;
struct dm_priv *pdmpriv = &hal_data->dmpriv;
struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
u32 tx_agc[2] = {0, 0}, tmpval = 0, pwrtrac_value;
@@ -129,7 +129,6 @@ static void getpowerbase88e(struct adapter *adapt, u8 *pwr_level_ofdm,
u8 *pwr_level_bw20, u8 *pwr_level_bw40,
u8 channel, u32 *ofdmbase, u32 *mcs_base)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
u32 powerbase0, powerbase1;
u8 i, powerlevel[2];
@@ -140,9 +139,9 @@ static void getpowerbase88e(struct adapter *adapt, u8 *pwr_level_ofdm,
(powerbase0<<8) | powerbase0;
*(ofdmbase+i) = powerbase0;
}
- for (i = 0; i < hal_data->NumTotalRFPath; i++) {
+ for (i = 0; i < adapt->HalData->NumTotalRFPath; i++) {
/* Check HT20 to HT40 diff */
- if (hal_data->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
+ if (adapt->HalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
powerlevel[i] = pwr_level_bw20[i];
else
powerlevel[i] = pwr_level_bw40[i];
@@ -156,7 +155,7 @@ static void get_rx_power_val_by_reg(struct adapter *adapt, u8 channel,
u8 index, u32 *powerbase0, u32 *powerbase1,
u32 *out_val)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *hal_data = adapt->HalData;
struct dm_priv *pdmpriv = &hal_data->dmpriv;
u8 i, chnlGroup = 0, pwr_diff_limit[4], customer_pwr_limit;
s8 pwr_diff = 0;
@@ -286,7 +285,6 @@ void rtl88eu_phy_rf6052_set_ofdm_txpower(struct adapter *adapt,
u8 *pwr_level_bw20,
u8 *pwr_level_bw40, u8 channel)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
u32 write_val[2], powerbase0[2], powerbase1[2], pwrtrac_value;
u8 direction;
u8 index = 0;
@@ -294,8 +292,8 @@ void rtl88eu_phy_rf6052_set_ofdm_txpower(struct adapter *adapt,
getpowerbase88e(adapt, pwr_level_ofdm, pwr_level_bw20, pwr_level_bw40,
channel, &powerbase0[0], &powerbase1[0]);
- rtl88eu_dm_txpower_track_adjust(&hal_data->odmpriv, 0, &direction,
- &pwrtrac_value);
+ rtl88eu_dm_txpower_track_adjust(&adapt->HalData->odmpriv, 0,
+ &direction, &pwrtrac_value);
for (index = 0; index < 6; index++) {
get_rx_power_val_by_reg(adapt, channel, index,
diff --git a/drivers/staging/rtl8188eu/hal/rf_cfg.c b/drivers/staging/rtl8188eu/hal/rf_cfg.c
index 453f9e729067..dde64417e66a 100644
--- a/drivers/staging/rtl8188eu/hal/rf_cfg.c
+++ b/drivers/staging/rtl8188eu/hal/rf_cfg.c
@@ -19,7 +19,7 @@
static bool check_condition(struct adapter *adapt, const u32 condition)
{
- struct odm_dm_struct *odm = &GET_HAL_DATA(adapt)->odmpriv;
+ struct odm_dm_struct *odm = &adapt->HalData->odmpriv;
u32 _board = odm->BoardType;
u32 _platform = odm->SupportPlatform;
u32 _interface = odm->SupportInterface;
@@ -228,7 +228,7 @@ static bool rtl88e_phy_config_rf_with_headerfile(struct adapter *adapt)
static bool rf6052_conf_para(struct adapter *adapt)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *hal_data = adapt->HalData;
u32 u4val = 0;
u8 rfpath;
bool rtstatus = true;
@@ -299,12 +299,9 @@ static bool rf6052_conf_para(struct adapter *adapt)
static bool rtl88e_phy_rf6052_config(struct adapter *adapt)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *hal_data = adapt->HalData;
- if (hal_data->rf_type == RF_1T1R)
- hal_data->NumTotalRFPath = 1;
- else
- hal_data->NumTotalRFPath = 2;
+ hal_data->NumTotalRFPath = 1;
return rf6052_conf_para(adapt);
}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
index 2422c0297a50..d0f59b7836f1 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
@@ -60,7 +60,6 @@ static s32 FillH2CCmd_88E(struct adapter *adapt, u8 ElementID, u32 CmdLen, u8 *p
u8 h2c_box_num;
u32 msgbox_addr;
u32 msgbox_ex_addr;
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
u8 cmd_idx, ext_cmd_len;
u32 h2c_cmd = 0;
u32 h2c_cmd_ex = 0;
@@ -81,7 +80,7 @@ static s32 FillH2CCmd_88E(struct adapter *adapt, u8 ElementID, u32 CmdLen, u8 *p
/* pay attention to if race condition happened in H2C cmd setting. */
do {
- h2c_box_num = haldata->LastHMEBoxNum;
+ h2c_box_num = adapt->HalData->LastHMEBoxNum;
if (!_is_fw_read_cmd_down(adapt, h2c_box_num)) {
DBG_88E(" fw read cmd failed...\n");
@@ -110,7 +109,8 @@ static s32 FillH2CCmd_88E(struct adapter *adapt, u8 ElementID, u32 CmdLen, u8 *p
}
bcmd_down = true;
- haldata->LastHMEBoxNum = (h2c_box_num+1) % RTL88E_MAX_H2C_BOX_NUMS;
+ adapt->HalData->LastHMEBoxNum =
+ (h2c_box_num+1) % RTL88E_MAX_H2C_BOX_NUMS;
} while ((!bcmd_down) && (retry_cnts--));
@@ -126,9 +126,9 @@ exit:
/* bitmap[28:31]= Rate Adaptive id */
/* arg[0:4] = macid */
/* arg[5] = Short GI */
-void rtl8188e_Add_RateATid(struct adapter *pAdapter, u32 bitmap, u8 arg, u8 rssi_level)
+void rtw_hal_add_ra_tid(struct adapter *pAdapter, u32 bitmap, u8 arg, u8 rssi_level)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(pAdapter);
+ struct odm_dm_struct *odmpriv = &pAdapter->HalData->odmpriv;
u8 macid, init_rate, raid, shortGIrate = false;
@@ -138,7 +138,7 @@ void rtl8188e_Add_RateATid(struct adapter *pAdapter, u32 bitmap, u8 arg, u8 rssi
bitmap &= 0x0fffffff;
if (rssi_level != DM_RATR_STA_INIT)
- bitmap = ODM_Get_Rate_Bitmap(&haldata->odmpriv, macid, bitmap, rssi_level);
+ bitmap = ODM_Get_Rate_Bitmap(odmpriv, macid, bitmap, rssi_level);
bitmap |= ((raid<<28)&0xf0000000);
@@ -156,7 +156,7 @@ void rtl8188e_Add_RateATid(struct adapter *pAdapter, u32 bitmap, u8 arg, u8 rssi
DBG_88E("%s=> mac_id:%d, raid:%d, ra_bitmap=0x%x, shortGIrate=0x%02x\n",
__func__, macid, raid, bitmap, shortGIrate);
- ODM_RA_UpdateRateInfo_8188E(&(haldata->odmpriv), macid, raid, bitmap, shortGIrate);
+ ODM_RA_UpdateRateInfo_8188E(odmpriv, macid, raid, bitmap, shortGIrate);
}
void rtl8188e_set_FwPwrMode_cmd(struct adapter *adapt, u8 Mode)
@@ -219,7 +219,7 @@ void rtl8188e_set_FwMediaStatus_cmd(struct adapter *adapt, __le16 mstatus_rpt)
static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength)
{
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
u32 rate_len, pktlen;
struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv);
@@ -227,20 +227,20 @@ static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength)
struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
- memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, cur_network->MacAddress, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, bc_addr);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3, cur_network->MacAddress);
SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
SetFrameSubType(pframe, WIFI_BEACON);
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += sizeof(struct ieee80211_hdr_3addr);
+ pktlen = sizeof(struct ieee80211_hdr_3addr);
/* timestamp will be inserted by hardware */
pframe += 8;
@@ -304,16 +304,16 @@ _ConstructBeacon:
static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength)
{
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
__le16 *fctrl;
struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
/* Frame control. */
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
SetPwrMgt(fctrl);
SetFrameSubType(pframe, WIFI_PSPOLL);
@@ -322,10 +322,10 @@ static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength)
SetDuration(pframe, (pmlmeinfo->aid | 0xc000));
/* BSSID. */
- memcpy(pwlanhdr->addr1, pnetwork->MacAddress, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, pnetwork->MacAddress);
/* TA. */
- memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)));
*pLength = 16;
}
@@ -338,7 +338,7 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe,
u8 bEosp,
u8 bForcePowerSave)
{
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
u32 pktlen;
struct mlme_priv *pmlmepriv = &adapt->mlmepriv;
@@ -347,9 +347,9 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe,
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
- fctrl = &pwlanhdr->frame_ctl;
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
if (bForcePowerSave)
SetPwrMgt(fctrl);
@@ -357,40 +357,40 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe,
switch (cur_network->network.InfrastructureMode) {
case Ndis802_11Infrastructure:
SetToDs(fctrl);
- memcpy(pwlanhdr->addr1, pnetwork->MacAddress, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, pnetwork->MacAddress);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3, StaAddr);
break;
case Ndis802_11APMode:
SetFrDs(fctrl);
- memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, pnetwork->MacAddress, ETH_ALEN);
- memcpy(pwlanhdr->addr3, myid(&(adapt->eeprompriv)), ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, StaAddr);
+ ether_addr_copy(pwlanhdr->addr2, pnetwork->MacAddress);
+ ether_addr_copy(pwlanhdr->addr3, myid(&(adapt->eeprompriv)));
break;
case Ndis802_11IBSS:
default:
- memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, StaAddr);
+ ether_addr_copy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)));
+ ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
break;
}
SetSeqNum(pwlanhdr, 0);
if (bQoS) {
- struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
+ struct ieee80211_qos_hdr *pwlanqoshdr;
SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
- pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
- SetPriority(&pwlanqoshdr->qc, AC);
- SetEOSP(&pwlanqoshdr->qc, bEosp);
+ pwlanqoshdr = (struct ieee80211_qos_hdr *)pframe;
+ SetPriority(&pwlanqoshdr->qos_ctrl, AC);
+ SetEOSP(&pwlanqoshdr->qos_ctrl, bEosp);
- pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
+ pktlen = sizeof(struct ieee80211_qos_hdr);
} else {
SetFrameSubType(pframe, WIFI_DATA_NULL);
- pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pktlen = sizeof(struct ieee80211_hdr_3addr);
}
*pLength = pktlen;
@@ -398,7 +398,7 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe,
static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u8 *StaAddr, bool bHideSSID)
{
- struct rtw_ieee80211_hdr *pwlanhdr;
+ struct ieee80211_hdr *pwlanhdr;
__le16 *fctrl;
u8 *mac, *bssid;
u32 pktlen;
@@ -406,21 +406,21 @@ static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ pwlanhdr = (struct ieee80211_hdr *)pframe;
mac = myid(&(adapt->eeprompriv));
bssid = cur_network->MacAddress;
- fctrl = &(pwlanhdr->frame_ctl);
+ fctrl = &pwlanhdr->frame_control;
*(fctrl) = 0;
- memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
- memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
+ ether_addr_copy(pwlanhdr->addr1, StaAddr);
+ ether_addr_copy(pwlanhdr->addr2, mac);
+ ether_addr_copy(pwlanhdr->addr3, bssid);
SetSeqNum(pwlanhdr, 0);
SetFrameSubType(fctrl, WIFI_PROBERSP);
- pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ pktlen = sizeof(struct ieee80211_hdr_3addr);
pframe += pktlen;
if (cur_network->IELength > MAX_IE_SZ)
@@ -445,7 +445,6 @@ static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u
/* 2009.10.15 by tynli. */
static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
{
- struct hal_data_8188e *haldata;
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
struct xmit_priv *pxmitpriv;
@@ -467,7 +466,6 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
return;
}
- haldata = GET_HAL_DATA(adapt);
pxmitpriv = &adapt->xmitpriv;
pmlmeext = &adapt->mlmeextpriv;
pmlmeinfo = &pmlmeext->mlmext_info;
@@ -487,7 +485,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
if (PageNeed == 1)
PageNeed += 1;
PageNum += PageNeed;
- haldata->FwRsvdPageStartOffset = PageNum;
+ adapt->HalData->FwRsvdPageStartOffset = PageNum;
BufIndex += PageNeed*128;
@@ -554,7 +552,7 @@ exit:
void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *haldata = adapt->HalData;
struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
bool bSendBeacon = false;
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c
index 81f2931876f8..d04b7fbb71e1 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c
@@ -42,43 +42,33 @@ static void dm_InitGPIOSetting(struct adapter *Adapter)
/* */
static void Init_ODM_ComInfo_88E(struct adapter *Adapter)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
+ struct hal_data_8188e *hal_data = Adapter->HalData;
struct dm_priv *pdmpriv = &hal_data->dmpriv;
struct odm_dm_struct *dm_odm = &(hal_data->odmpriv);
- u8 cut_ver;
/* Init Value */
memset(dm_odm, 0, sizeof(*dm_odm));
dm_odm->Adapter = Adapter;
+ dm_odm->SupportPlatform = ODM_CE;
+ dm_odm->SupportICType = ODM_RTL8188E;
+ dm_odm->CutVersion = ODM_CUT_A;
+ dm_odm->bIsMPChip = hal_data->VersionID.ChipType == NORMAL_CHIP;
+ dm_odm->PatchID = hal_data->CustomerID;
+ dm_odm->bWIFITest = Adapter->registrypriv.wifi_spec;
- ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_PLATFORM, ODM_CE);
+ dm_odm->AntDivType = hal_data->TRxAntDivType;
- ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_IC_TYPE, ODM_RTL8188E);
-
- cut_ver = ODM_CUT_A;
-
- ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_CUT_VER, cut_ver);
-
- ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_MP_TEST_CHIP, hal_data->VersionID.ChipType == NORMAL_CHIP ? true : false);
-
- ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_PATCH_ID, hal_data->CustomerID);
- ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_BWIFI_TEST, Adapter->registrypriv.wifi_spec);
-
-
- if (hal_data->rf_type == RF_1T1R)
- ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_RF_TYPE, ODM_1T1R);
- else if (hal_data->rf_type == RF_2T2R)
- ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R);
- else if (hal_data->rf_type == RF_1T2R)
- ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_RF_TYPE, ODM_1T2R);
-
- ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_RF_ANTENNA_TYPE, hal_data->TRxAntDivType);
+ /* Tx power tracking BB swing table. */
+ /* The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */
+ dm_odm->BbSwingIdxOfdm = 12; /* Set defalut value as index 12. */
+ dm_odm->BbSwingIdxOfdmCurrent = 12;
+ dm_odm->BbSwingFlagOfdm = false;
pdmpriv->InitODMFlag = ODM_RF_CALIBRATION |
ODM_RF_TX_PWR_TRACK;
- ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_ABILITY, pdmpriv->InitODMFlag);
+ dm_odm->SupportAbility = pdmpriv->InitODMFlag;
}
static void Update_ODM_ComInfo_88E(struct adapter *Adapter)
@@ -86,7 +76,7 @@ static void Update_ODM_ComInfo_88E(struct adapter *Adapter)
struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
- struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
+ struct hal_data_8188e *hal_data = Adapter->HalData;
struct odm_dm_struct *dm_odm = &(hal_data->odmpriv);
struct dm_priv *pdmpriv = &hal_data->dmpriv;
int i;
@@ -109,20 +99,26 @@ static void Update_ODM_ComInfo_88E(struct adapter *Adapter)
ODM_RF_TX_PWR_TRACK;
}
- ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_ABILITY, pdmpriv->InitODMFlag);
-
- ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_TX_UNI, &(Adapter->xmitpriv.tx_bytes));
- ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_RX_UNI, &(Adapter->recvpriv.rx_bytes));
- ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_WM_MODE, &(pmlmeext->cur_wireless_mode));
- ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_SEC_CHNL_OFFSET, &(hal_data->nCur40MhzPrimeSC));
- ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_SEC_MODE, &(Adapter->securitypriv.dot11PrivacyAlgrthm));
- ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_BW, &(hal_data->CurrentChannelBW));
- ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_CHNL, &(hal_data->CurrentChannel));
- ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_NET_CLOSED, &(Adapter->net_closed));
- ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_MP_MODE, &(Adapter->registrypriv.mp_mode));
- ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_SCAN, &(pmlmepriv->bScanInProcess));
- ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_POWER_SAVING, &(pwrctrlpriv->bpower_saving));
- ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_RF_ANTENNA_TYPE, hal_data->TRxAntDivType);
+ dm_odm->SupportAbility = pdmpriv->InitODMFlag;
+
+ dm_odm->pNumTxBytesUnicast = &Adapter->xmitpriv.tx_bytes;
+ dm_odm->pNumRxBytesUnicast = &Adapter->recvpriv.rx_bytes;
+ dm_odm->pWirelessMode = &pmlmeext->cur_wireless_mode;
+ dm_odm->pSecChOffset = &hal_data->nCur40MhzPrimeSC;
+ dm_odm->pSecurity = (u8 *)&Adapter->securitypriv.dot11PrivacyAlgrthm;
+ dm_odm->pBandWidth = (u8 *)&hal_data->CurrentChannelBW;
+ dm_odm->pChannel = &hal_data->CurrentChannel;
+ dm_odm->pbNet_closed = (bool *)&Adapter->net_closed;
+ dm_odm->mp_mode = &Adapter->registrypriv.mp_mode;
+ dm_odm->pbScanInProcess = (bool *)&pmlmepriv->bScanInProcess;
+ dm_odm->pbPowerSaving = (bool *)&pwrctrlpriv->bpower_saving;
+ dm_odm->AntDivType = hal_data->TRxAntDivType;
+
+ /* Tx power tracking BB swing table. */
+ /* The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */
+ dm_odm->BbSwingIdxOfdm = 12; /* Set defalut value as index 12. */
+ dm_odm->BbSwingIdxOfdmCurrent = 12;
+ dm_odm->BbSwingFlagOfdm = false;
for (i = 0; i < NUM_STA; i++)
ODM_CmnInfoPtrArrayHook(dm_odm, ODM_CMNINFO_STA_STATUS, i, NULL);
@@ -130,23 +126,19 @@ static void Update_ODM_ComInfo_88E(struct adapter *Adapter)
void rtl8188e_InitHalDm(struct adapter *Adapter)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &hal_data->dmpriv;
- struct odm_dm_struct *dm_odm = &(hal_data->odmpriv);
+ struct dm_priv *pdmpriv = &Adapter->HalData->dmpriv;
+ struct odm_dm_struct *dm_odm = &(Adapter->HalData->odmpriv);
dm_InitGPIOSetting(Adapter);
pdmpriv->DM_Type = DM_Type_ByDriver;
pdmpriv->DMFlag = DYNAMIC_FUNC_DISABLE;
Update_ODM_ComInfo_88E(Adapter);
ODM_DMInit(dm_odm);
- Adapter->fix_rate = 0xFF;
}
-void rtl8188e_HalDmWatchDog(struct adapter *Adapter)
+void rtw_hal_dm_watchdog(struct adapter *Adapter)
{
- bool fw_ps_awake = true;
u8 hw_init_completed = false;
- struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
struct mlme_priv *pmlmepriv = NULL;
u8 bLinked = false;
@@ -155,13 +147,6 @@ void rtl8188e_HalDmWatchDog(struct adapter *Adapter)
if (!hw_init_completed)
goto skip_dm;
- rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&fw_ps_awake));
-
- /* Fw is under p2p powersaving mode, driver should stop dynamic mechanism. */
- /* modifed by thomas. 2011.06.11. */
- if (Adapter->wdinfo.p2p_ps_mode)
- fw_ps_awake = false;
-
/* ODM */
pmlmepriv = &Adapter->mlmepriv;
@@ -175,19 +160,18 @@ void rtl8188e_HalDmWatchDog(struct adapter *Adapter)
bLinked = true;
}
- ODM_CmnInfoUpdate(&hal_data->odmpriv, ODM_CMNINFO_LINK, bLinked);
- ODM_DMWatchdog(&hal_data->odmpriv);
+ Adapter->HalData->odmpriv.bLinked = bLinked;
+ ODM_DMWatchdog(&Adapter->HalData->odmpriv);
skip_dm:
/* Check GPIO to determine current RF on/off and Pbc status. */
/* Check Hardware Radio ON/OFF or not */
return;
}
-void rtl8188e_init_dm_priv(struct adapter *Adapter)
+void rtw_hal_dm_init(struct adapter *Adapter)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &hal_data->dmpriv;
- struct odm_dm_struct *podmpriv = &hal_data->odmpriv;
+ struct dm_priv *pdmpriv = &Adapter->HalData->dmpriv;
+ struct odm_dm_struct *podmpriv = &Adapter->HalData->odmpriv;
memset(pdmpriv, 0, sizeof(struct dm_priv));
Init_ODM_ComInfo_88E(Adapter);
@@ -196,11 +180,9 @@ void rtl8188e_init_dm_priv(struct adapter *Adapter)
/* Add new function to reset the state of antenna diversity before link. */
/* Compare RSSI for deciding antenna */
-void AntDivCompare8188E(struct adapter *Adapter, struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src)
+void rtw_hal_antdiv_rssi_compared(struct adapter *Adapter, struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
-
- if (0 != hal_data->AntDivCfg) {
+ if (0 != Adapter->HalData->AntDivCfg) {
/* select optimum_antenna for before linked =>For antenna diversity */
if (dst->Rssi >= src->Rssi) {/* keep org parameter */
src->Rssi = dst->Rssi;
@@ -210,15 +192,14 @@ void AntDivCompare8188E(struct adapter *Adapter, struct wlan_bssid_ex *dst, stru
}
/* Add new function to reset the state of antenna diversity before link. */
-u8 AntDivBeforeLink8188E(struct adapter *Adapter)
+u8 rtw_hal_antdiv_before_linked(struct adapter *Adapter)
{
- struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
- struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
+ struct odm_dm_struct *dm_odm = &Adapter->HalData->odmpriv;
struct sw_ant_switch *dm_swat_tbl = &dm_odm->DM_SWAT_Table;
struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
/* Condition that does not need to use antenna diversity. */
- if (hal_data->AntDivCfg == 0)
+ if (Adapter->HalData->AntDivCfg == 0)
return false;
if (check_fwstate(pmlmepriv, _FW_LINKED))
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
index 0b444fd3e550..385bc2f56f2f 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
@@ -108,28 +108,24 @@ void _8051Reset88E(struct adapter *padapter)
void rtl8188e_InitializeFirmwareVars(struct adapter *padapter)
{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
-
/* Init Fw LPS related. */
padapter->pwrctrlpriv.bFwCurrentInPSMode = false;
/* Init H2C counter. by tynli. 2009.12.09. */
- pHalData->LastHMEBoxNum = 0;
+ padapter->HalData->LastHMEBoxNum = 0;
}
-static void rtl8188e_free_hal_data(struct adapter *padapter)
+void rtw_hal_free_data(struct adapter *padapter)
{
kfree(padapter->HalData);
padapter->HalData = NULL;
}
-static void ReadChipVersion8188E(struct adapter *padapter)
+void rtw_hal_read_chip_version(struct adapter *padapter)
{
u32 value32;
struct HAL_VERSION ChipVersion;
- struct hal_data_8188e *pHalData;
-
- pHalData = GET_HAL_DATA(padapter);
+ struct hal_data_8188e *pHalData = padapter->HalData;
value32 = usb_read32(padapter, REG_SYS_CFG);
ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
@@ -139,16 +135,13 @@ static void ReadChipVersion8188E(struct adapter *padapter)
dump_chip_info(ChipVersion);
pHalData->VersionID = ChipVersion;
- pHalData->rf_type = RF_1T1R;
pHalData->NumTotalRFPath = 1;
-
- MSG_88E("RF_Type is %x!!\n", pHalData->rf_type);
}
-static void rtl8188e_SetHalODMVar(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet)
+void rtw_hal_set_odm_var(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet)
{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
- struct odm_dm_struct *podmpriv = &pHalData->odmpriv;
+ struct odm_dm_struct *podmpriv = &Adapter->HalData->odmpriv;
+
switch (eVariable) {
case HAL_ODM_STA_INFO:
{
@@ -165,17 +158,17 @@ static void rtl8188e_SetHalODMVar(struct adapter *Adapter, enum hal_odm_variable
}
break;
case HAL_ODM_P2P_STATE:
- ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet);
+ podmpriv->bWIFI_Direct = bSet;
break;
case HAL_ODM_WIFI_DISPLAY_STATE:
- ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet);
+ podmpriv->bWIFI_Display = bSet;
break;
default:
break;
}
}
-static void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
+void rtw_hal_notch_filter(struct adapter *adapter, bool enable)
{
if (enable) {
DBG_88E("Enable notch filter\n");
@@ -185,32 +178,6 @@ static void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
usb_write8(adapter, rOFDM0_RxDSP+1, usb_read8(adapter, rOFDM0_RxDSP+1) & ~BIT(1));
}
}
-void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
-{
- pHalFunc->free_hal_data = &rtl8188e_free_hal_data;
-
- pHalFunc->dm_init = &rtl8188e_init_dm_priv;
-
- pHalFunc->read_chip_version = &ReadChipVersion8188E;
-
- pHalFunc->set_bwmode_handler = &phy_set_bw_mode;
- pHalFunc->set_channel_handler = &phy_sw_chnl;
-
- pHalFunc->hal_dm_watchdog = &rtl8188e_HalDmWatchDog;
-
- pHalFunc->Add_RateATid = &rtl8188e_Add_RateATid;
-
- pHalFunc->AntDivBeforeLinkHandler = &AntDivBeforeLink8188E;
- pHalFunc->AntDivCompareHandler = &AntDivCompare8188E;
- pHalFunc->read_rfreg = &phy_query_rf_reg;
-
- pHalFunc->sreset_init_value = &sreset_init_value;
- pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status;
-
- pHalFunc->SetHalODMVarHandler = &rtl8188e_SetHalODMVar;
-
- pHalFunc->hal_notch_filter = &hal_notch_filter_8188e;
-}
/* */
/* */
@@ -501,7 +468,7 @@ void Hal_ReadPowerSavingMode88E(struct adapter *padapter, u8 *hwinfo, bool AutoL
void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool AutoLoadFail)
{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
+ struct hal_data_8188e *pHalData = padapter->HalData;
struct txpowerinfo24g pwrInfo24G;
u8 rfPath, ch, group;
u8 bIn24G, TxCount;
@@ -553,7 +520,7 @@ void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool Auto
void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail)
{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
+ struct hal_data_8188e *pHalData = pAdapter->HalData;
if (!AutoLoadFail) {
pHalData->CrystalCap = hwinfo[EEPROM_XTAL_88E];
@@ -567,7 +534,7 @@ void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoa
void Hal_EfuseParseBoardType88E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail)
{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
+ struct hal_data_8188e *pHalData = pAdapter->HalData;
if (!AutoLoadFail)
pHalData->BoardType = (hwinfo[EEPROM_RF_BOARD_OPTION_88E]
@@ -579,7 +546,7 @@ void Hal_EfuseParseBoardType88E(struct adapter *pAdapter, u8 *hwinfo, bool AutoL
void Hal_EfuseParseEEPROMVer88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
+ struct hal_data_8188e *pHalData = padapter->HalData;
if (!AutoLoadFail) {
pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_88E];
@@ -606,7 +573,7 @@ void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, bool Auto
void Hal_EfuseParseCustomerID88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
+ struct hal_data_8188e *pHalData = padapter->HalData;
if (!AutoLoadFail) {
pHalData->EEPROMCustomerID = hwinfo[EEPROM_CUSTOMERID_88E];
@@ -619,7 +586,7 @@ void Hal_EfuseParseCustomerID88E(struct adapter *padapter, u8 *hwinfo, bool Auto
void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool AutoLoadFail)
{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
+ struct hal_data_8188e *pHalData = pAdapter->HalData;
struct registry_priv *registry_par = &pAdapter->registrypriv;
if (!AutoLoadFail) {
@@ -652,7 +619,7 @@ void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool
void Hal_ReadThermalMeter_88E(struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail)
{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
+ struct hal_data_8188e *pHalData = Adapter->HalData;
/* ThermalMeter from EEPROM */
if (!AutoloadFail)
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c
index f110c961df70..fa2cfd5768de 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c
@@ -57,10 +57,9 @@ static void process_link_qual(struct adapter *padapter,
signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
}
-void rtl8188e_process_phy_info(struct adapter *padapter, void *prframe)
+void rtl8188e_process_phy_info(struct adapter *padapter,
+ struct recv_frame *precvframe)
{
- struct recv_frame *precvframe = prframe;
-
/* Check RSSI */
process_rssi(padapter, precvframe);
/* Check EVM */
@@ -140,7 +139,6 @@ void update_recvframe_phyinfo_88e(struct recv_frame *precvframe,
{
struct adapter *padapter = precvframe->adapter;
struct rx_pkt_attrib *pattrib = &precvframe->attrib;
- struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
struct odm_phy_status_info *pPHYInfo = (struct odm_phy_status_info *)(&pattrib->phy_info);
u8 *wlanhdr;
struct odm_per_pkt_info pkt_info;
@@ -181,7 +179,8 @@ void update_recvframe_phyinfo_88e(struct recv_frame *precvframe,
pkt_info.StationID = psta->mac_id;
pkt_info.Rate = pattrib->mcs_rate;
- ODM_PhyStatusQuery(&pHalData->odmpriv, pPHYInfo, (u8 *)pphy_status, &(pkt_info));
+ ODM_PhyStatusQuery(&padapter->HalData->odmpriv, pPHYInfo,
+ (u8 *)pphy_status, &(pkt_info));
precvframe->psta = NULL;
if (pkt_info.bPacketMatchBSSID &&
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c
index d9e677ef8f84..780666a755ee 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c
@@ -40,14 +40,13 @@ void SwLedOn(struct adapter *padapter, struct LED_871x *pLed)
void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
{
u8 LedCfg;
- struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
goto exit;
LedCfg = usb_read8(padapter, REG_LEDCFG2);/* 0x4E */
- if (pHalData->bLedOpenDrain) {
+ if (padapter->HalData->bLedOpenDrain) {
/* Open-drain arrangement for controlling the LED) */
LedCfg &= 0x90; /* Set to software control. */
usb_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3)));
@@ -66,21 +65,20 @@ exit:
/* Description: */
/* Initialize all LED_871x objects. */
-void rtl8188eu_InitSwLeds(struct adapter *padapter)
+void rtw_hal_sw_led_init(struct adapter *padapter)
{
struct led_priv *pledpriv = &(padapter->ledpriv);
- struct hal_data_8188e *haldata = GET_HAL_DATA(padapter);
pledpriv->bRegUseLed = true;
pledpriv->LedControlHandler = LedControl8188eu;
- haldata->bLedOpenDrain = true;
+ padapter->HalData->bLedOpenDrain = true;
InitLed871x(padapter, &(pledpriv->SwLed0));
}
/* Description: */
/* DeInitialize all LED_819xUsb objects. */
-void rtl8188eu_DeInitSwLeds(struct adapter *padapter)
+void rtw_hal_sw_led_deinit(struct adapter *padapter)
{
struct led_priv *ledpriv = &(padapter->ledpriv);
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c
index 255d6f215091..d0495a16ff79 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c
@@ -13,6 +13,7 @@
*
******************************************************************************/
#define _RTL8188EU_RECV_C_
+#include <linux/kmemleak.h>
#include <osdep_service.h>
#include <drv_types.h>
#include <recv_osdep.h>
@@ -23,7 +24,7 @@
#include <rtl8188e_hal.h>
-int rtl8188eu_init_recv_priv(struct adapter *padapter)
+int rtw_hal_init_recv_priv(struct adapter *padapter)
{
struct recv_priv *precvpriv = &padapter->recvpriv;
int i, res = _SUCCESS;
@@ -72,6 +73,7 @@ int rtl8188eu_init_recv_priv(struct adapter *padapter)
MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ,
GFP_KERNEL);
if (pskb) {
+ kmemleak_not_leak(pskb);
pskb->dev = padapter->pnetdev;
tmpaddr = (size_t)pskb->data;
alignm = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
@@ -87,7 +89,7 @@ exit:
return res;
}
-void rtl8188eu_free_recv_priv(struct adapter *padapter)
+void rtw_hal_free_recv_priv(struct adapter *padapter)
{
int i;
struct recv_buf *precvbuf;
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
index ec21d8c82eba..85650b2663ec 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
@@ -21,7 +21,7 @@
#include <usb_ops_linux.h>
#include <rtl8188e_hal.h>
-s32 rtl8188eu_init_xmit_priv(struct adapter *adapt)
+s32 rtw_hal_init_xmit_priv(struct adapter *adapt)
{
struct xmit_priv *pxmitpriv = &adapt->xmitpriv;
@@ -33,11 +33,7 @@ s32 rtl8188eu_init_xmit_priv(struct adapter *adapt)
static u8 urb_zero_packet_chk(struct adapter *adapt, int sz)
{
- u8 set_tx_desc_offset;
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
- set_tx_desc_offset = (((sz + TXDESC_SIZE) % haldata->UsbBulkOutSize) == 0) ? 1 : 0;
-
- return set_tx_desc_offset;
+ return !((sz + TXDESC_SIZE) % adapt->HalData->UsbBulkOutSize);
}
static void rtl8188eu_cal_txdesc_chksum(struct tx_desc *ptxdesc)
@@ -175,7 +171,7 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bag
u8 data_rate, pwr_status, offset;
struct adapter *adapt = pxmitframe->padapter;
struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ struct odm_dm_struct *odmpriv = &adapt->HalData->odmpriv;
struct tx_desc *ptxdesc = (struct tx_desc *)pmem;
struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
@@ -259,12 +255,12 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bag
ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);/* DATA/RTS Rate FB LMT */
if (pattrib->ht_en) {
- if (ODM_RA_GetShortGI_8188E(&haldata->odmpriv, pattrib->mac_id))
+ if (ODM_RA_GetShortGI_8188E(odmpriv, pattrib->mac_id))
ptxdesc->txdw5 |= cpu_to_le32(SGI);/* SGI */
}
- data_rate = ODM_RA_GetDecisionRate_8188E(&haldata->odmpriv, pattrib->mac_id);
+ data_rate = ODM_RA_GetDecisionRate_8188E(odmpriv, pattrib->mac_id);
ptxdesc->txdw5 |= cpu_to_le32(data_rate & 0x3F);
- pwr_status = ODM_RA_GetHwPwrStatus_8188E(&haldata->odmpriv, pattrib->mac_id);
+ pwr_status = ODM_RA_GetHwPwrStatus_8188E(odmpriv, pattrib->mac_id);
ptxdesc->txdw4 |= cpu_to_le32((pwr_status & 0x7) << PWR_STATUS_SHT);
} else {
/* EAP data packet and ARP packet and DHCP. */
@@ -332,8 +328,7 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bag
ptxdesc->txdw4 |= cpu_to_le32(HW_SSN); /* Hw set sequence number */
}
- rtl88eu_dm_set_tx_ant_by_tx_info(&haldata->odmpriv, pmem,
- pattrib->mac_id);
+ rtl88eu_dm_set_tx_ant_by_tx_info(odmpriv, pmem, pattrib->mac_id);
rtl8188eu_cal_txdesc_chksum(ptxdesc);
_dbg_dump_tx_info(adapt, pxmitframe->frame_tag, ptxdesc);
@@ -387,7 +382,7 @@ static s32 rtw_dump_xframe(struct adapter *adapt, struct xmit_frame *pxmitframe)
}
ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
- inner_ret = usb_write_port(adapt, ff_hwaddr, w_sz, (unsigned char *)pxmitbuf);
+ inner_ret = usb_write_port(adapt, ff_hwaddr, w_sz, pxmitbuf);
rtw_count_tx_stats(adapt, pxmitframe, sz);
@@ -424,11 +419,11 @@ static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
return len;
}
-s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
+s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitpriv)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
struct xmit_frame *pxmitframe = NULL;
struct xmit_frame *pfirstframe = NULL;
+ struct xmit_buf *pxmitbuf;
/* aggregate variable */
struct hw_xmit *phwxmit;
@@ -441,7 +436,7 @@ s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitp
u32 pbuf_tail; /* last pkt tail */
u32 len; /* packet length, except TXDESC_SIZE and PKT_OFFSET */
- u32 bulksize = haldata->UsbBulkOutSize;
+ u32 bulksize = adapt->HalData->UsbBulkOutSize;
u8 desc_cnt;
u32 bulkptr;
@@ -450,12 +445,9 @@ s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitp
RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n"));
- /* check xmitbuffer is ok */
- if (pxmitbuf == NULL) {
- pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
- if (pxmitbuf == NULL)
- return false;
- }
+ pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
+ if (pxmitbuf == NULL)
+ return false;
/* 3 1. pick up first frame */
rtw_free_xmitframe(pxmitpriv, pxmitframe);
@@ -565,7 +557,7 @@ s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitp
if (pbuf < bulkptr) {
desc_cnt++;
- if (desc_cnt == haldata->UsbTxAggDescNum)
+ if (desc_cnt == adapt->HalData->UsbTxAggDescNum)
break;
} else {
desc_cnt = 0;
@@ -594,7 +586,7 @@ s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitp
/* 3 4. write xmit buffer to USB FIFO */
ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
- usb_write_port(adapt, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf);
+ usb_write_port(adapt, ff_hwaddr, pbuf_tail, pxmitbuf);
/* 3 5. update statisitc */
pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
@@ -607,24 +599,12 @@ s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitp
return true;
}
-static s32 xmitframe_direct(struct adapter *adapt, struct xmit_frame *pxmitframe)
-{
- s32 res;
-
- res = rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe);
- if (res == _SUCCESS)
- rtw_dump_xframe(adapt, pxmitframe);
- else
- DBG_88E("==> %s xmitframe_coalsece failed\n", __func__);
- return res;
-}
-
/*
* Return
* true dump packet directly
* false enqueue packet
*/
-static s32 pre_xmitframe(struct adapter *adapt, struct xmit_frame *pxmitframe)
+s32 rtw_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe)
{
s32 res;
struct xmit_buf *pxmitbuf = NULL;
@@ -650,7 +630,12 @@ static s32 pre_xmitframe(struct adapter *adapt, struct xmit_frame *pxmitframe)
pxmitframe->buf_addr = pxmitbuf->pbuf;
pxmitbuf->priv_data = pxmitframe;
- if (xmitframe_direct(adapt, pxmitframe) != _SUCCESS) {
+ res = rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe);
+
+ if (res == _SUCCESS) {
+ rtw_dump_xframe(adapt, pxmitframe);
+ } else {
+ DBG_88E("==> %s xmitframe_coalsece failed\n", __func__);
rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
rtw_free_xmitframe(pxmitpriv, pxmitframe);
}
@@ -674,20 +659,10 @@ enqueue:
return false;
}
-s32 rtl8188eu_mgnt_xmit(struct adapter *adapt, struct xmit_frame *pmgntframe)
+s32 rtw_hal_mgnt_xmit(struct adapter *adapt, struct xmit_frame *pmgntframe)
{
struct xmit_priv *xmitpriv = &adapt->xmitpriv;
rtl88eu_mon_xmit_hook(adapt->pmondev, pmgntframe, xmitpriv->frag_len);
return rtw_dump_xframe(adapt, pmgntframe);
}
-
-/*
- * Return
- * true dump packet directly ok
- * false temporary can't transmit packets to hardware
- */
-s32 rtl8188eu_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe)
-{
- return pre_xmitframe(adapt, pxmitframe);
-}
diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c
index 363f3a34ddce..7692ca495ee5 100644
--- a/drivers/staging/rtl8188eu/hal/usb_halinit.c
+++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c
@@ -21,14 +21,13 @@
#include <rtl8188e_hal.h>
#include <rtl8188e_led.h>
#include <rtw_iol.h>
-#include <usb_hal.h>
#include <phy.h>
#define HAL_BB_ENABLE 1
static void _ConfigNormalChipOutEP_8188E(struct adapter *adapt, u8 NumOutPipe)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *haldata = adapt->HalData;
switch (NumOutPipe) {
case 3:
@@ -51,13 +50,12 @@ static void _ConfigNormalChipOutEP_8188E(struct adapter *adapt, u8 NumOutPipe)
static bool HalUsbSetQueuePipeMapping8188EUsb(struct adapter *adapt, u8 NumInPipe, u8 NumOutPipe)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
bool result = false;
_ConfigNormalChipOutEP_8188E(adapt, NumOutPipe);
/* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */
- if (haldata->OutEpNumber == 1) {
+ if (adapt->HalData->OutEpNumber == 1) {
if (NumInPipe != 1)
return result;
}
@@ -69,9 +67,9 @@ static bool HalUsbSetQueuePipeMapping8188EUsb(struct adapter *adapt, u8 NumInPip
return result;
}
-static void rtl8188eu_interface_configure(struct adapter *adapt)
+void rtw_hal_chip_configure(struct adapter *adapt)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *haldata = adapt->HalData;
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(adapt);
if (pdvobjpriv->ishighspeed)
@@ -94,12 +92,11 @@ static void rtl8188eu_interface_configure(struct adapter *adapt)
pdvobjpriv->RtNumInPipes, pdvobjpriv->RtNumOutPipes);
}
-static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
+u32 rtw_hal_power_on(struct adapter *adapt)
{
u16 value16;
/* HW Power on sequence */
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
- if (haldata->bMacPwrCtrlOn)
+ if (adapt->HalData->bMacPwrCtrlOn)
return _SUCCESS;
if (!rtl88eu_pwrseqcmdparsing(adapt, PWR_CUT_ALL_MSK,
@@ -119,7 +116,7 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
/* for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
usb_write16(adapt, REG_CR, value16);
- haldata->bMacPwrCtrlOn = true;
+ adapt->HalData->bMacPwrCtrlOn = true;
return _SUCCESS;
}
@@ -129,18 +126,17 @@ static void _InitInterrupt(struct adapter *Adapter)
{
u32 imr, imr_ex;
u8 usb_opt;
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
/* HISR write one to clear */
usb_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF);
/* HIMR - */
imr = IMR_PSTIMEOUT_88E | IMR_TBDER_88E | IMR_CPWM_88E | IMR_CPWM2_88E;
usb_write32(Adapter, REG_HIMR_88E, imr);
- haldata->IntrMask[0] = imr;
+ Adapter->HalData->IntrMask[0] = imr;
imr_ex = IMR_TXERR_88E | IMR_RXERR_88E | IMR_TXFOVW_88E | IMR_RXFOVW_88E;
usb_write32(Adapter, REG_HIMRE_88E, imr_ex);
- haldata->IntrMask[1] = imr_ex;
+ Adapter->HalData->IntrMask[1] = imr_ex;
/* REG_USB_SPECIAL_OPTION - BIT(4) */
/* 0; Use interrupt endpoint to upload interrupt pkt */
@@ -157,7 +153,6 @@ static void _InitInterrupt(struct adapter *Adapter)
static void _InitQueueReservedPage(struct adapter *Adapter)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
struct registry_priv *pregistrypriv = &Adapter->registrypriv;
u32 numHQ = 0;
u32 numLQ = 0;
@@ -168,14 +163,14 @@ static void _InitQueueReservedPage(struct adapter *Adapter)
bool bWiFiConfig = pregistrypriv->wifi_spec;
if (bWiFiConfig) {
- if (haldata->OutEpQueueSel & TX_SELE_HQ)
+ if (Adapter->HalData->OutEpQueueSel & TX_SELE_HQ)
numHQ = 0x29;
- if (haldata->OutEpQueueSel & TX_SELE_LQ)
+ if (Adapter->HalData->OutEpQueueSel & TX_SELE_LQ)
numLQ = 0x1C;
/* NOTE: This step shall be proceed before writing REG_RQPN. */
- if (haldata->OutEpQueueSel & TX_SELE_NQ)
+ if (Adapter->HalData->OutEpQueueSel & TX_SELE_NQ)
numNQ = 0x1C;
value8 = (u8)_NPQ(numNQ);
usb_write8(Adapter, REG_RQPN_NPQ, value8);
@@ -225,10 +220,9 @@ static void _InitNormalChipRegPriority(struct adapter *Adapter, u16 beQ,
static void _InitNormalChipOneOutEpPriority(struct adapter *Adapter)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
-
u16 value = 0;
- switch (haldata->OutEpQueueSel) {
+
+ switch (Adapter->HalData->OutEpQueueSel) {
case TX_SELE_HQ:
value = QUEUE_HIGH;
break;
@@ -247,13 +241,12 @@ static void _InitNormalChipOneOutEpPriority(struct adapter *Adapter)
static void _InitNormalChipTwoOutEpPriority(struct adapter *Adapter)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
struct registry_priv *pregistrypriv = &Adapter->registrypriv;
u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
u16 valueHi = 0;
u16 valueLow = 0;
- switch (haldata->OutEpQueueSel) {
+ switch (Adapter->HalData->OutEpQueueSel) {
case (TX_SELE_HQ | TX_SELE_LQ):
valueHi = QUEUE_HIGH;
valueLow = QUEUE_LOW;
@@ -313,9 +306,7 @@ static void _InitNormalChipThreeOutEpPriority(struct adapter *Adapter)
static void _InitQueuePriority(struct adapter *Adapter)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
-
- switch (haldata->OutEpNumber) {
+ switch (Adapter->HalData->OutEpNumber) {
case 1:
_InitNormalChipOneOutEpPriority(Adapter);
break;
@@ -357,7 +348,7 @@ static void _InitDriverInfoSize(struct adapter *Adapter, u8 drvInfoSize)
static void _InitWMACSetting(struct adapter *Adapter)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ struct hal_data_8188e *haldata = Adapter->HalData;
haldata->ReceiveConfig = RCR_AAP | RCR_APM | RCR_AM | RCR_AB |
RCR_CBSSID_DATA | RCR_CBSSID_BCN |
@@ -456,7 +447,7 @@ static void _InitRetryFunction(struct adapter *Adapter)
*/
static void usb_AggSettingTxUpdate(struct adapter *Adapter)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ struct hal_data_8188e *haldata = Adapter->HalData;
u32 value32;
if (Adapter->registrypriv.wifi_spec)
@@ -492,7 +483,7 @@ usb_AggSettingRxUpdate(
struct adapter *Adapter
)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ struct hal_data_8188e *haldata = Adapter->HalData;
u8 valueDMA;
u8 valueUSB;
@@ -566,8 +557,6 @@ usb_AggSettingRxUpdate(
static void InitUsbAggregationSetting(struct adapter *Adapter)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
-
/* Tx aggregation setting */
usb_AggSettingTxUpdate(Adapter);
@@ -575,12 +564,12 @@ static void InitUsbAggregationSetting(struct adapter *Adapter)
usb_AggSettingRxUpdate(Adapter);
/* 201/12/10 MH Add for USB agg mode dynamic switch. */
- haldata->UsbRxHighSpeedMode = false;
+ Adapter->HalData->UsbRxHighSpeedMode = false;
}
static void _InitBeaconParameters(struct adapter *Adapter)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ struct hal_data_8188e *haldata = Adapter->HalData;
usb_write16(Adapter, REG_BCN_CTRL, 0x1010);
@@ -622,7 +611,7 @@ enum {
static void _InitAntenna_Selection(struct adapter *Adapter)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ struct hal_data_8188e *haldata = Adapter->HalData;
if (haldata->AntDivCfg == 0)
return;
@@ -672,13 +661,13 @@ enum rt_rf_power_state RfOnOffDetect(struct adapter *adapt)
return rfpowerstate;
} /* HalDetectPwrDownMode */
-static u32 rtl8188eu_hal_init(struct adapter *Adapter)
+u32 rtl8188eu_hal_init(struct adapter *Adapter)
{
u8 value8 = 0;
u16 value16;
u8 txpktbuf_bndy;
u32 status = _SUCCESS;
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ struct hal_data_8188e *haldata = Adapter->HalData;
struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
struct registry_priv *pregistrypriv = &Adapter->registrypriv;
unsigned long init_start_time = jiffies;
@@ -702,7 +691,7 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
}
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PW_ON);
- status = rtl8188eu_InitPowerOn(Adapter);
+ status = rtw_hal_power_on(Adapter);
if (status == _FAIL) {
RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("Failed to init power on!\n"));
goto exit;
@@ -810,8 +799,8 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
usb_write16(Adapter, REG_PKT_BE_BK_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */
/* Keep RfRegChnlVal for later use. */
- haldata->RfRegChnlVal[0] = phy_query_rf_reg(Adapter, (enum rf_radio_path)0, RF_CHNLBW, bRFRegOffsetMask);
- haldata->RfRegChnlVal[1] = phy_query_rf_reg(Adapter, (enum rf_radio_path)1, RF_CHNLBW, bRFRegOffsetMask);
+ haldata->RfRegChnlVal[0] = rtw_hal_read_rfreg(Adapter, (enum rf_radio_path)0, RF_CHNLBW, bRFRegOffsetMask);
+ haldata->RfRegChnlVal[1] = rtw_hal_read_rfreg(Adapter, (enum rf_radio_path)1, RF_CHNLBW, bRFRegOffsetMask);
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_TURN_ON_BLOCK);
_BBTurnOnBlock(Adapter);
@@ -905,7 +894,6 @@ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END);
static void CardDisableRTL8188EU(struct adapter *Adapter)
{
u8 val8;
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("CardDisableRTL8188EU\n"));
@@ -958,7 +946,7 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
val8 = usb_read8(Adapter, REG_GPIO_IO_SEL+1);
usb_write8(Adapter, REG_GPIO_IO_SEL+1, val8|0x0F);/* Reg0x43 */
usb_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */
- haldata->bMacPwrCtrlOn = false;
+ Adapter->HalData->bMacPwrCtrlOn = false;
Adapter->bFWReady = false;
}
@@ -972,7 +960,7 @@ static void rtl8192cu_hw_power_down(struct adapter *adapt)
usb_write16(adapt, REG_APS_FSMCO, 0x8812);
}
-static u32 rtl8188eu_hal_deinit(struct adapter *Adapter)
+u32 rtl8188eu_hal_deinit(struct adapter *Adapter)
{
DBG_88E("==> %s\n", __func__);
@@ -994,7 +982,7 @@ static u32 rtl8188eu_hal_deinit(struct adapter *Adapter)
return _SUCCESS;
}
-static unsigned int rtl8188eu_inirp_init(struct adapter *Adapter)
+u32 rtw_hal_inirp_init(struct adapter *Adapter)
{
u8 i;
struct recv_buf *precvbuf;
@@ -1029,17 +1017,6 @@ exit:
return status;
}
-static unsigned int rtl8188eu_inirp_deinit(struct adapter *Adapter)
-{
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("\n ===> usb_rx_deinit\n"));
-
- usb_read_port_cancel(Adapter);
-
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("\n <=== usb_rx_deinit\n"));
-
- return _SUCCESS;
-}
-
/* */
/* */
/* EEPROM/EFUSE Content Parsing */
@@ -1047,7 +1024,7 @@ static unsigned int rtl8188eu_inirp_deinit(struct adapter *Adapter)
/* */
static void Hal_EfuseParsePIDVID_8188EU(struct adapter *adapt, u8 *hwinfo, bool AutoLoadFail)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *haldata = adapt->HalData;
if (!AutoLoadFail) {
/* VID, PID */
@@ -1132,12 +1109,10 @@ static void _ReadPROMContent(
static void _ReadRFType(struct adapter *Adapter)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
-
- haldata->rf_chip = RF_6052;
+ Adapter->HalData->rf_chip = RF_6052;
}
-static void _ReadAdapterInfo8188EU(struct adapter *Adapter)
+void rtw_hal_read_chip_info(struct adapter *Adapter)
{
unsigned long start = jiffies;
@@ -1157,7 +1132,7 @@ static void rtl8192cu_trigger_gpio_0(struct adapter *adapt)
static void ResumeTxBeacon(struct adapter *adapt)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *haldata = adapt->HalData;
/* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
/* which should be read from register to a global variable. */
@@ -1171,7 +1146,7 @@ static void ResumeTxBeacon(struct adapter *adapt)
static void StopTxBeacon(struct adapter *adapt)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *haldata = adapt->HalData;
/* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
/* which should be read from register to a global variable. */
@@ -1276,9 +1251,9 @@ static void hw_var_set_bcn_func(struct adapter *Adapter, u8 variable, u8 *val)
usb_write8(Adapter, bcn_ctrl_reg, usb_read8(Adapter, bcn_ctrl_reg)&(~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
}
-static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
+void rtw_hal_set_hwreg(struct adapter *Adapter, u8 variable, u8 *val)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ struct hal_data_8188e *haldata = Adapter->HalData;
struct dm_priv *pdmpriv = &haldata->dmpriv;
struct odm_dm_struct *podmpriv = &haldata->odmpriv;
@@ -1426,17 +1401,8 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
/* enable update TSF */
usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL)&(~BIT(4)));
}
- if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
- usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN);
- } else {
- if (Adapter->in_cta_test) {
- u32 v = usb_read32(Adapter, REG_RCR);
- v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
- usb_write32(Adapter, REG_RCR, v);
- } else {
- usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN);
- }
- }
+
+ usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN);
}
break;
case HW_VAR_MLME_JOIN:
@@ -1449,13 +1415,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
/* enable to rx data frame.Accept all data frame */
usb_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
- if (Adapter->in_cta_test) {
- u32 v = usb_read32(Adapter, REG_RCR);
- v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
- usb_write32(Adapter, REG_RCR, v);
- } else {
- usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
- }
+ usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
RetryLimit = (haldata->CustomerID == RT_CID_CCX) ? 7 : 48;
@@ -1525,9 +1485,6 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
case HW_VAR_SEC_CFG:
usb_write8(Adapter, REG_SECCFG, *((u8 *)val));
break;
- case HW_VAR_DM_FLAG:
- podmpriv->SupportAbility = *((u8 *)val);
- break;
case HW_VAR_DM_FUNC_OP:
if (val[0])
podmpriv->BK_SupportAbility = podmpriv->SupportAbility;
@@ -1793,14 +1750,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
}
}
-static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
+void rtw_hal_get_hwreg(struct adapter *Adapter, u8 variable, u8 *val)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
- struct odm_dm_struct *podmpriv = &haldata->odmpriv;
-
switch (variable) {
case HW_VAR_BASIC_RATE:
- *((u16 *)(val)) = haldata->BasicRateSet;
+ *((u16 *)(val)) = Adapter->HalData->BasicRateSet;
case HW_VAR_TXPAUSE:
val[0] = usb_read8(Adapter, REG_TXPAUSE);
break;
@@ -1808,11 +1762,8 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
/* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 */
val[0] = (BIT(0) & usb_read8(Adapter, REG_TDECTRL+2)) ? true : false;
break;
- case HW_VAR_DM_FLAG:
- val[0] = podmpriv->SupportAbility;
- break;
case HW_VAR_RF_TYPE:
- val[0] = haldata->rf_type;
+ val[0] = RF_1T1R;
break;
case HW_VAR_FWLPS_RF_ON:
{
@@ -1833,13 +1784,13 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
}
break;
case HW_VAR_CURRENT_ANTENNA:
- val[0] = haldata->CurAntenna;
+ val[0] = Adapter->HalData->CurAntenna;
break;
case HW_VAR_EFUSE_BYTES: /* To get EFUE total used bytes, added by Roger, 2008.12.22. */
- *((u16 *)(val)) = haldata->EfuseUsedBytes;
+ *((u16 *)(val)) = Adapter->HalData->EfuseUsedBytes;
break;
case HW_VAR_APFM_ON_MAC:
- *val = haldata->bMacPwrCtrlOn;
+ *val = Adapter->HalData->bMacPwrCtrlOn;
break;
case HW_VAR_CHK_HI_QUEUE_EMPTY:
*val = ((usb_read32(Adapter, REG_HGQ_INFORMATION)&0x0000ff00) == 0) ? true : false;
@@ -1853,14 +1804,13 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
/* Description: */
/* Query setting of specified variable. */
/* */
-static u8
-GetHalDefVar8188EUsb(
+u8 rtw_hal_get_def_var(
struct adapter *Adapter,
enum hal_def_variable eVariable,
void *pValue
)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
+ struct hal_data_8188e *haldata = Adapter->HalData;
u8 bResult = _SUCCESS;
switch (eVariable) {
@@ -1948,7 +1898,7 @@ GetHalDefVar8188EUsb(
return bResult;
}
-static void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_level)
+void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_level)
{
u8 init_rate = 0;
u8 networkType, raid;
@@ -1956,7 +1906,7 @@ static void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_l
u8 shortGIrate = false;
int supportRateNum = 0;
struct sta_info *psta;
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ struct odm_dm_struct *odmpriv = &adapt->HalData->odmpriv;
struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
@@ -1995,7 +1945,7 @@ static void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_l
break;
}
- rate_bitmap = ODM_Get_Rate_Bitmap(&haldata->odmpriv, mac_id, mask, rssi_level);
+ rate_bitmap = ODM_Get_Rate_Bitmap(odmpriv, mac_id, mask, rssi_level);
DBG_88E("%s => mac_id:%d, networkType:0x%02x, mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n",
__func__, mac_id, networkType, mask, rssi_level, rate_bitmap);
@@ -2003,15 +1953,14 @@ static void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_l
init_rate = get_highest_rate_idx(mask)&0x3f;
- ODM_RA_UpdateRateInfo_8188E(&haldata->odmpriv, mac_id,
- raid, mask, shortGIrate);
+ ODM_RA_UpdateRateInfo_8188E(odmpriv, mac_id, raid, mask, shortGIrate);
/* set ra_id */
psta->raid = raid;
psta->init_rate = init_rate;
}
-static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
+void rtw_hal_bcn_related_reg_setting(struct adapter *adapt)
{
u32 value32;
struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
@@ -2045,13 +1994,12 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
usb_write8(adapt, bcn_ctrl_reg, usb_read8(adapt, bcn_ctrl_reg) | BIT(1));
}
-static void rtl8188eu_init_default_value(struct adapter *adapt)
+void rtw_hal_def_value_init(struct adapter *adapt)
{
- struct hal_data_8188e *haldata;
+ struct hal_data_8188e *haldata = adapt->HalData;
struct pwrctrl_priv *pwrctrlpriv;
u8 i;
- haldata = GET_HAL_DATA(adapt);
pwrctrlpriv = &adapt->pwrctrlpriv;
/* init default value */
@@ -2067,43 +2015,3 @@ static void rtl8188eu_init_default_value(struct adapter *adapt)
for (i = 0; i < HP_THERMAL_NUM; i++)
haldata->odmpriv.RFCalibrateInfo.ThermalValue_HP[i] = 0;
}
-
-void rtl8188eu_set_hal_ops(struct adapter *adapt)
-{
- struct hal_ops *halfunc = &adapt->HalFunc;
-
-
- adapt->HalData = kzalloc(sizeof(struct hal_data_8188e), GFP_KERNEL);
- if (!adapt->HalData)
- DBG_88E("cant not alloc memory for HAL DATA\n");
-
- halfunc->hal_power_on = rtl8188eu_InitPowerOn;
- halfunc->hal_init = &rtl8188eu_hal_init;
- halfunc->hal_deinit = &rtl8188eu_hal_deinit;
-
- halfunc->inirp_init = &rtl8188eu_inirp_init;
- halfunc->inirp_deinit = &rtl8188eu_inirp_deinit;
-
- halfunc->init_xmit_priv = &rtl8188eu_init_xmit_priv;
-
- halfunc->init_recv_priv = &rtl8188eu_init_recv_priv;
- halfunc->free_recv_priv = &rtl8188eu_free_recv_priv;
- halfunc->InitSwLeds = &rtl8188eu_InitSwLeds;
- halfunc->DeInitSwLeds = &rtl8188eu_DeInitSwLeds;
-
- halfunc->init_default_value = &rtl8188eu_init_default_value;
- halfunc->intf_chip_configure = &rtl8188eu_interface_configure;
- halfunc->read_adapter_info = &_ReadAdapterInfo8188EU;
-
- halfunc->SetHwRegHandler = &SetHwReg8188EU;
- halfunc->GetHwRegHandler = &GetHwReg8188EU;
- halfunc->GetHalDefVarHandler = &GetHalDefVar8188EUsb;
-
- halfunc->UpdateRAMaskHandler = &UpdateHalRAMask8188EUsb;
- halfunc->SetBeaconRelatedRegistersHandler = &SetBeaconRelatedRegisters8188EUsb;
-
- halfunc->hal_xmit = &rtl8188eu_hal_xmit;
- halfunc->mgnt_xmit = &rtl8188eu_mgnt_xmit;
-
- rtl8188e_set_hal_ops(halfunc);
-}
diff --git a/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h b/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h
index 8990748a1919..0976a761b280 100644
--- a/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h
+++ b/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h
@@ -158,24 +158,6 @@ struct bb_reg_def {
* Path A and B */
};
-struct ant_sel_ofdm {
- u32 r_tx_antenna:4;
- u32 r_ant_l:4;
- u32 r_ant_non_ht:4;
- u32 r_ant_ht1:4;
- u32 r_ant_ht2:4;
- u32 r_ant_ht_s1:4;
- u32 r_ant_non_ht_s1:4;
- u32 OFDM_TXSC:2;
- u32 reserved:2;
-};
-
-struct ant_sel_cck {
- u8 r_cckrx_enable_2:2;
- u8 r_cckrx_enable:2;
- u8 r_ccktx_enable:4;
-};
-
/*------------------------------Define structure----------------------------*/
diff --git a/drivers/staging/rtl8188eu/include/HalHWImg8188E_FW.h b/drivers/staging/rtl8188eu/include/HalHWImg8188E_FW.h
deleted file mode 100644
index dbb55247b0c6..000000000000
--- a/drivers/staging/rtl8188eu/include/HalHWImg8188E_FW.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/******************************************************************************
-*
-* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of version 2 of the GNU General Public License 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.
-*
-******************************************************************************/
-
-#ifndef __INC_FW_8188E_HW_IMG_H
-#define __INC_FW_8188E_HW_IMG_H
-
-
-/******************************************************************************
-* FW_AP.TXT
-******************************************************************************/
-/******************************************************************************
-* FW_WoWLAN.TXT
-******************************************************************************/
-#define ArrayLength_8188E_FW_WoWLAN 15764
-extern const u8 Array_8188E_FW_WoWLAN[ArrayLength_8188E_FW_WoWLAN];
-
-#endif
diff --git a/drivers/staging/rtl8188eu/include/basic_types.h b/drivers/staging/rtl8188eu/include/basic_types.h
index 2c1676d2ac6e..69c4d49f43ab 100644
--- a/drivers/staging/rtl8188eu/include/basic_types.h
+++ b/drivers/staging/rtl8188eu/include/basic_types.h
@@ -137,8 +137,4 @@ value to host byte ordering.*/
((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \
)
-/* Get the N-bytes aligment offset from the current length */
-#define N_BYTE_ALIGMENT(__value, __aligment) ((__aligment == 1) ? \
- (__value) : (((__value + __aligment - 1) / __aligment) * __aligment))
-
#endif /* __BASIC_TYPES_H__ */
diff --git a/drivers/staging/rtl8188eu/include/drv_types.h b/drivers/staging/rtl8188eu/include/drv_types.h
index 55506a7da1a4..32326fd1dd24 100644
--- a/drivers/staging/rtl8188eu/include/drv_types.h
+++ b/drivers/staging/rtl8188eu/include/drv_types.h
@@ -53,30 +53,17 @@
#define SPEC_DEV_ID_ASSIGN_IFNAME BIT(5)
struct registry_priv {
- u8 chip_version;
- u8 rfintfs;
- u8 lbkmode;
- u8 hci;
struct ndis_802_11_ssid ssid;
- u8 network_mode; /* infra, ad-hoc, auto */
u8 channel;/* ad-hoc support requirement */
u8 wireless_mode;/* A, B, G, auto */
- u8 scan_mode;/* active, passive */
- u8 radio_enable;
u8 preamble;/* long, short, auto */
u8 vrtl_carrier_sense;/* Enable, Disable, Auto */
u8 vcs_type;/* RTS/CTS, CTS-to-self */
u16 rts_thresh;
u16 frag_thresh;
- u8 adhoc_tx_pwr;
- u8 soft_ap;
u8 power_mgnt;
u8 ips_mode;
u8 smart_ps;
- u8 long_retry_lmt;
- u8 short_retry_lmt;
- u16 busy_thresh;
- u8 ack_policy;
u8 mp_mode;
u8 software_encrypt;
u8 software_decrypt;
@@ -84,11 +71,6 @@ struct registry_priv {
/* UAPSD */
u8 wmm_enable;
u8 uapsd_enable;
- u8 uapsd_max_sp;
- u8 uapsd_acbk_en;
- u8 uapsd_acbe_en;
- u8 uapsd_acvi_en;
- u8 uapsd_acvo_en;
struct wlan_bssid_ex dev_network;
@@ -97,10 +79,6 @@ struct registry_priv {
u8 ampdu_enable;/* for tx */
u8 rx_stbc;
u8 ampdu_amsdu;/* A-MPDU Supports A-MSDU is permitted */
- u8 lowrate_two_xmit;
-
- u8 rf_config;
- u8 low_power;
u8 wifi_spec;/* !turbo_mode */
@@ -112,9 +90,6 @@ struct registry_priv {
u8 usbss_enable;/* 0:disable,1:enable */
u8 hwpdn_mode;/* 0:disable,1:enable,2:decide by EFUSE config */
- u8 hwpwrp_detect;/* 0:disable,1:enable */
-
- u8 hw_wps_pbc;/* 0:disable,1:enable */
u8 max_roaming_times; /* the max number driver will try */
@@ -129,12 +104,6 @@ struct registry_priv {
bool monitor_enable;
};
-/* For registry parameters */
-#define RGTRY_OFT(field) ((u32)offsetof(struct registry_priv, field))
-#define RGTRY_SZ(field) sizeof(((struct registry_priv *)0)->field)
-#define BSSID_OFT(field) ((u32)offsetofT(struct wlan_bssid_ex, field))
-#define BSSID_SZ(field) sizeof(((struct wlan_bssid_ex *)0)->field)
-
#define MAX_CONTINUAL_URB_ERR 4
struct dvobj_priv {
@@ -149,16 +118,11 @@ struct dvobj_priv {
u8 Queue2Pipe[HW_QUEUE_ENTRY];/* for out pipe mapping */
/*-------- below is for USB INTERFACE --------*/
-
- u8 nr_endpoint;
u8 ishighspeed;
u8 RtNumInPipes;
u8 RtNumOutPipes;
- int ep_num[5]; /* endpoint number */
struct mutex usb_vendor_req_mutex;
- u8 *usb_vendor_req_buf;
-
struct usb_interface *pusbintf;
struct usb_device *pusbdev;
};
@@ -184,14 +148,7 @@ struct adapter {
struct eeprom_priv eeprompriv;
struct led_priv ledpriv;
-#ifdef CONFIG_88EU_AP_MODE
- struct hostapd_priv *phostapdpriv;
-#endif
-
- struct wifidirect_info wdinfo;
-
- void *HalData;
- struct hal_ops HalFunc;
+ struct hal_data_8188e *HalData;
s32 bDriverStopped;
s32 bSurpriseRemoved;
@@ -199,20 +156,11 @@ struct adapter {
u8 hw_init_completed;
void *cmdThread;
- void *evtThread;
void (*intf_start)(struct adapter *adapter);
void (*intf_stop)(struct adapter *adapter);
struct net_device *pnetdev;
struct net_device *pmondev;
- /* used by rtw_rereg_nd_name related function */
- struct rereg_nd_name_data {
- struct net_device *old_pnetdev;
- char old_ifname[IFNAMSIZ];
- u8 old_ips_mode;
- u8 old_bRegUseLed;
- } rereg_nd_name_priv;
-
int bup;
struct net_device_stats stats;
struct iw_statistics iwstats;
@@ -223,23 +171,12 @@ struct adapter {
u8 bReadPortCancel;
u8 bWritePortCancel;
u8 bRxRSSIDisplay;
- /* The driver will show up the desired channel number
- * when this flag is 1. */
- u8 bNotifyChannelChange;
struct mutex hw_init_mutex;
-
- spinlock_t br_ext_lock;
-
- u8 fix_rate;
-
- unsigned char in_cta_test;
};
#define adapter_to_dvobj(adapter) (adapter->dvobj)
-int rtw_handle_dualmac(struct adapter *adapter, bool init);
-
static inline u8 *myid(struct eeprom_priv *peepriv)
{
return peepriv->mac_addr;
diff --git a/drivers/staging/rtl8188eu/include/hal_intf.h b/drivers/staging/rtl8188eu/include/hal_intf.h
index eaf939bd4103..fa032b0c12ff 100644
--- a/drivers/staging/rtl8188eu/include/hal_intf.h
+++ b/drivers/staging/rtl8188eu/include/hal_intf.h
@@ -58,7 +58,6 @@ enum hw_variables {
HW_VAR_SEC_CFG,
HW_VAR_BCN_VALID,
HW_VAR_RF_TYPE,
- HW_VAR_DM_FLAG,
HW_VAR_DM_FUNC_OP,
HW_VAR_DM_FUNC_SET,
HW_VAR_DM_FUNC_CLR,
@@ -139,81 +138,6 @@ enum hal_intf_ps_func {
HAL_MAX_ID,
};
-struct hal_ops {
- u32 (*hal_power_on)(struct adapter *padapter);
- u32 (*hal_init)(struct adapter *padapter);
- u32 (*hal_deinit)(struct adapter *padapter);
-
- void (*free_hal_data)(struct adapter *padapter);
-
- u32 (*inirp_init)(struct adapter *padapter);
- u32 (*inirp_deinit)(struct adapter *padapter);
-
- s32 (*init_xmit_priv)(struct adapter *padapter);
-
- s32 (*init_recv_priv)(struct adapter *padapter);
- void (*free_recv_priv)(struct adapter *padapter);
-
- void (*InitSwLeds)(struct adapter *padapter);
- void (*DeInitSwLeds)(struct adapter *padapter);
-
- void (*dm_init)(struct adapter *padapter);
- void (*read_chip_version)(struct adapter *padapter);
-
- void (*init_default_value)(struct adapter *padapter);
-
- void (*intf_chip_configure)(struct adapter *padapter);
-
- void (*read_adapter_info)(struct adapter *padapter);
-
- s32 (*interrupt_handler)(struct adapter *padapter);
-
- void (*set_bwmode_handler)(struct adapter *padapter,
- enum ht_channel_width Bandwidth,
- u8 Offset);
- void (*set_channel_handler)(struct adapter *padapter, u8 channel);
-
- void (*hal_dm_watchdog)(struct adapter *padapter);
-
- void (*SetHwRegHandler)(struct adapter *padapter, u8 variable,
- u8 *val);
- void (*GetHwRegHandler)(struct adapter *padapter, u8 variable,
- u8 *val);
-
- u8 (*GetHalDefVarHandler)(struct adapter *padapter,
- enum hal_def_variable eVariable,
- void *pValue);
-
- void (*SetHalODMVarHandler)(struct adapter *padapter,
- enum hal_odm_variable eVariable,
- void *pValue1, bool bSet);
-
- void (*UpdateRAMaskHandler)(struct adapter *padapter,
- u32 mac_id, u8 rssi_level);
- void (*SetBeaconRelatedRegistersHandler)(struct adapter *padapter);
-
- void (*Add_RateATid)(struct adapter *adapter, u32 bitmap, u8 arg,
- u8 rssi_level);
-
- u8 (*AntDivBeforeLinkHandler)(struct adapter *adapter);
- void (*AntDivCompareHandler)(struct adapter *adapter,
- struct wlan_bssid_ex *dst,
- struct wlan_bssid_ex *src);
- s32 (*hal_xmit)(struct adapter *padapter,
- struct xmit_frame *pxmitframe);
- s32 (*mgnt_xmit)(struct adapter *padapter,
- struct xmit_frame *pmgntframe);
- u32 (*read_rfreg)(struct adapter *padapter,
- enum rf_radio_path eRFPath, u32 RegAddr,
- u32 BitMask);
-
- void (*sreset_init_value)(struct adapter *padapter);
- u8 (*sreset_get_wifi_status)(struct adapter *padapter);
-
- void (*hal_notch_filter)(struct adapter *adapter, bool enable);
- void (*hal_reset_security_engine)(struct adapter *adapter);
-};
-
enum rt_eeprom_type {
EEPROM_93C46,
EEPROM_93C56,
@@ -235,6 +159,9 @@ enum hardware_type {
#define is_boot_from_eeprom(adapter) (adapter->eeprompriv.EepromOrEfuse)
+void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_level);
+u32 rtl8188eu_hal_deinit(struct adapter *Adapter);
+u32 rtl8188eu_hal_init(struct adapter *Adapter);
void rtw_hal_def_value_init(struct adapter *padapter);
void rtw_hal_free_data(struct adapter *padapter);
@@ -262,7 +189,7 @@ void rtw_hal_set_odm_var(struct adapter *padapter,
bool bSet);
u32 rtw_hal_inirp_init(struct adapter *padapter);
-u32 rtw_hal_inirp_deinit(struct adapter *padapter);
+void rtw_hal_inirp_deinit(struct adapter *padapter);
s32 rtw_hal_xmit(struct adapter *padapter, struct xmit_frame *pxmitframe);
s32 rtw_hal_mgnt_xmit(struct adapter *padapter,
@@ -270,7 +197,7 @@ s32 rtw_hal_mgnt_xmit(struct adapter *padapter,
s32 rtw_hal_init_xmit_priv(struct adapter *padapter);
-s32 rtw_hal_init_recv_priv(struct adapter *padapter);
+int rtw_hal_init_recv_priv(struct adapter *padapter);
void rtw_hal_free_recv_priv(struct adapter *padapter);
void rtw_hal_update_ra_mask(struct adapter *padapter, u32 mac_id, u8 level);
@@ -296,7 +223,6 @@ void rtw_hal_antdiv_rssi_compared(struct adapter *padapter,
void rtw_hal_sreset_init(struct adapter *padapter);
void rtw_hal_notch_filter(struct adapter *adapter, bool enable);
-void rtw_hal_reset_security_engine(struct adapter *adapter);
void indicate_wx_scan_complete_event(struct adapter *padapter);
u8 rtw_do_join(struct adapter *padapter);
diff --git a/drivers/staging/rtl8188eu/include/ieee80211.h b/drivers/staging/rtl8188eu/include/ieee80211.h
index d8284c84f09c..fc58621368c1 100644
--- a/drivers/staging/rtl8188eu/include/ieee80211.h
+++ b/drivers/staging/rtl8188eu/include/ieee80211.h
@@ -239,7 +239,7 @@ struct ieee_param {
u16 capability;
int flags;
u8 tx_supp_rates[16];
- struct rtw_ieee80211_ht_cap ht_cap;
+ struct ieee80211_ht_cap ht_cap;
} add_sta;
struct {
u8 reserved[2];/* for set max_num_sta */
@@ -264,7 +264,7 @@ struct sta_data {
u32 sta_set;
u8 tx_supp_rates[16];
u32 tx_supp_rates_len;
- struct rtw_ieee80211_ht_cap ht_cap;
+ struct ieee80211_ht_cap ht_cap;
u64 rx_pkts;
u64 rx_bytes;
u64 rx_drops;
@@ -291,62 +291,6 @@ struct sta_data {
/* this is stolen from ipw2200 driver */
#define IEEE_IBSS_MAC_HASH_SIZE 31
-struct ieee_ibss_seq {
- u8 mac[ETH_ALEN];
- u16 seq_num;
- u16 frag_num;
- unsigned long packet_time;
- struct list_head list;
-};
-
-struct rtw_ieee80211_hdr {
- __le16 frame_ctl;
- __le16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- u16 seq_ctl;
- u8 addr4[ETH_ALEN];
-} __packed;
-
-struct rtw_ieee80211_hdr_3addr {
- __le16 frame_ctl;
- __le16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- u16 seq_ctl;
-} __packed;
-
-struct rtw_ieee80211_hdr_qos {
- __le16 frame_ctl;
- __le16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- u16 seq_ctl;
- u8 addr4[ETH_ALEN];
- u16 qc;
-} __packed;
-
-struct rtw_ieee80211_hdr_3addr_qos {
- __le16 frame_ctl;
- __le16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- u16 seq_ctl;
- u16 qc;
-} __packed;
-
-struct eapol {
- u8 snap[6];
- u16 ethertype;
- u8 version;
- u8 type;
- u16 length;
-} __packed;
-
enum eap_type {
EAP_PACKET = 0,
EAPOL_START,
@@ -552,83 +496,12 @@ struct ieee80211_snap_hdr {
#define IEEE80211_NUM_CCK_RATES 4
#define IEEE80211_OFDM_SHIFT_MASK_A 4
-/* NOTE: This data is for statistical purposes; not all hardware provides this
- * information for frames received. Not setting these will not cause
- * any adverse affects. */
-struct ieee80211_rx_stats {
- /* u32 mac_time[2]; */
- s8 rssi;
- u8 signal;
- u8 noise;
- u8 received_channel;
- u16 rate; /* in 100 kbps */
- /* u8 control; */
- u8 mask;
- u8 freq;
- u16 len;
-};
-
/* IEEE 802.11 requires that STA supports concurrent reception of at least
* three fragmented frames. This define can be increased to support more
* concurrent frames, but it should be noted that each entry can consume about
* 2 kB of RAM and increasing cache size will slow down frame reassembly. */
#define IEEE80211_FRAG_CACHE_LEN 4
-struct ieee80211_frag_entry {
- u32 first_frag_time;
- uint seq;
- uint last_frag;
- uint qos; /* jackson */
- uint tid; /* jackson */
- struct sk_buff *skb;
- u8 src_addr[ETH_ALEN];
- u8 dst_addr[ETH_ALEN];
-};
-
-struct ieee80211_stats {
- uint tx_unicast_frames;
- uint tx_multicast_frames;
- uint tx_fragments;
- uint tx_unicast_octets;
- uint tx_multicast_octets;
- uint tx_deferred_transmissions;
- uint tx_single_retry_frames;
- uint tx_multiple_retry_frames;
- uint tx_retry_limit_exceeded;
- uint tx_discards;
- uint rx_unicast_frames;
- uint rx_multicast_frames;
- uint rx_fragments;
- uint rx_unicast_octets;
- uint rx_multicast_octets;
- uint rx_fcs_errors;
- uint rx_discards_no_buffer;
- uint tx_discards_wrong_sa;
- uint rx_discards_undecryptable;
- uint rx_message_in_msg_fragments;
- uint rx_message_in_bad_msg_fragments;
-};
-
-struct ieee80211_softmac_stats {
- uint rx_ass_ok;
- uint rx_ass_err;
- uint rx_probe_rq;
- uint tx_probe_rs;
- uint tx_beacons;
- uint rx_auth_rq;
- uint rx_auth_rs_ok;
- uint rx_auth_rs_err;
- uint tx_auth_rq;
- uint no_auth_rs;
- uint no_ass_rs;
- uint tx_ass_rq;
- uint rx_ass_rq;
- uint tx_probe_rq;
- uint reassoc;
- uint swtxstop;
- uint swtxawake;
-};
-
#define SEC_KEY_1 (1<<0)
#define SEC_KEY_2 (1<<1)
#define SEC_KEY_3 (1<<2)
@@ -648,42 +521,6 @@ struct ieee80211_softmac_stats {
#define WEP_KEYS 4
#define WEP_KEY_LEN 13
-struct ieee80211_security {
- u16 active_key:2,
- enabled:1,
- auth_mode:2,
- auth_algo:4,
- unicast_uses_group:1;
- u8 key_sizes[WEP_KEYS];
- u8 keys[WEP_KEYS][WEP_KEY_LEN];
- u8 level;
- u16 flags;
-} __packed;
-
-/*
-
- 802.11 data frame from AP
-
- ,-------------------------------------------------------------------.
-Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
- |------|------|---------|---------|---------|------|---------|------|
-Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
- | | tion | (BSSID) | | | ence | data | |
- `-------------------------------------------------------------------'
-
-Total: 28-2340 bytes
-
-*/
-
-struct ieee80211_header_data {
- u16 frame_ctl;
- u16 duration_id;
- u8 addr1[6];
- u8 addr2[6];
- u8 addr3[6];
- u16 seq_ctrl;
-};
-
#define BEACON_PROBE_SSID_ID_POSITION 12
/* Management Frame Information Element Types */
@@ -700,81 +537,9 @@ struct ieee80211_header_data {
#define MFIE_TYPE_RATES_EX 50
#define MFIE_TYPE_GENERIC 221
-struct ieee80211_info_element_hdr {
- u8 id;
- u8 len;
-} __packed;
-
-struct ieee80211_info_element {
- u8 id;
- u8 len;
- u8 data[0];
-} __packed;
-
-/*
- * These are the data types that can make up management packets
- *
- u16 auth_algorithm;
- u16 auth_sequence;
- u16 beacon_interval;
- u16 capability;
- u8 current_ap[ETH_ALEN];
- u16 listen_interval;
- struct {
- u16 association_id:14, reserved:2;
- } __packed;
- u32 time_stamp[2];
- u16 reason;
- u16 status;
-*/
-
#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
#define IEEE80211_DEFAULT_BASIC_RATE 10
-struct ieee80211_authentication {
- struct ieee80211_header_data header;
- u16 algorithm;
- u16 transaction;
- u16 status;
- /* struct ieee80211_info_element_hdr info_element; */
-} __packed;
-
-struct ieee80211_probe_response {
- struct ieee80211_header_data header;
- u32 time_stamp[2];
- u16 beacon_interval;
- u16 capability;
- struct ieee80211_info_element info_element;
-} __packed;
-
-struct ieee80211_probe_request {
- struct ieee80211_header_data header;
-} __packed;
-
-struct ieee80211_assoc_request_frame {
- struct rtw_ieee80211_hdr_3addr header;
- u16 capability;
- u16 listen_interval;
- struct ieee80211_info_element_hdr info_element;
-} __packed;
-
-struct ieee80211_assoc_response_frame {
- struct rtw_ieee80211_hdr_3addr header;
- u16 capability;
- u16 status;
- u16 aid;
-} __packed;
-
-struct ieee80211_txb {
- u8 nr_frags;
- u8 encrypted;
- u16 reserved;
- u16 frag_size;
- u16 payload_size;
- struct sk_buff *fragments[0];
-};
-
-
/* SWEEP TABLE ENTRIES NUMBER*/
#define MAX_SWEEP_TAB_ENTRIES 42
#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
@@ -872,11 +637,6 @@ static inline int is_broadcast_mac_addr(const u8 *addr)
#define CFG_IEEE80211_RESERVE_FCS (1<<0)
#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
-struct tx_pending {
- int frag;
- struct ieee80211_txb *txb;
-};
-
#define MAXTID 16
#define IEEE_A (1<<0)
@@ -1096,20 +856,8 @@ enum secondary_ch_offset {
SCA = 1, /* secondary channel above */
SCB = 3, /* secondary channel below */
};
-u8 secondary_ch_offset_to_hal_ch_offset(u8 ch_offset);
-u8 hal_ch_offset_to_secondary_ch_offset(u8 ch_offset);
-u8 *rtw_set_ie_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode,
- u8 new_ch, u8 ch_switch_cnt);
-u8 *rtw_set_ie_secondary_ch_offset(u8 *buf, u32 *buf_len,
- u8 secondary_ch_offset);
-u8 *rtw_set_ie_mesh_ch_switch_parm(u8 *buf, u32 *buf_len, u8 ttl,
- u8 flags, u16 reason, u16 precedence);
u8 *rtw_get_ie(u8 *pbuf, int index, int *len, int limit);
-u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui,
- u8 oui_len, u8 *ie, uint *ielen);
-int rtw_ies_remove_ie(u8 *ies, uint *ies_len, uint offset,
- u8 eid, u8 *oui, u8 oui_len);
void rtw_set_supported_rate(u8 *SupportedRates, uint mode);
@@ -1133,19 +881,6 @@ u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id,
u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id,
u8 *buf_content, uint *len_content);
-/**
- * for_each_ie - iterate over continuous IEs
- * @ie:
- * @buf:
- * @buf_len:
- */
-#define for_each_ie(ie, buf, buf_len) \
- for (ie = (void *)buf; (((u8 *)ie) - ((u8 *)buf) + 1) < buf_len; \
- ie = (void *)(((u8 *)ie) + *(((u8 *)ie)+1) + 2))
-
-void dump_ies(u8 *buf, u32 buf_len);
-void dump_wps_ie(u8 *ie, u32 ie_len);
-
uint rtw_get_rateset_len(u8 *rateset);
struct registry_priv;
@@ -1167,8 +902,4 @@ void rtw_macaddr_cfg(u8 *mac_addr);
u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40,
unsigned char *MCS_rate);
-int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category,
- u8 *action);
-const char *action_public_str(u8 action);
-
#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8188eu/include/odm.h b/drivers/staging/rtl8188eu/include/odm.h
index dbebf17f36d3..805f52e108b2 100644
--- a/drivers/staging/rtl8188eu/include/odm.h
+++ b/drivers/staging/rtl8188eu/include/odm.h
@@ -315,22 +315,6 @@ enum odm_ability {
ODM_PSD2AFH = 0x00000800
};
-/* 2011/20/20 MH For MP driver RT_WLAN_STA = struct sta_info */
-/* Please declare below ODM relative info in your STA info structure. */
-
-struct odm_sta_info {
- /* Driver Write */
- bool bUsed; /* record the sta status link or not? */
- u8 IOTPeer; /* Enum value. HT_IOT_PEER_E */
-
- /* ODM Write */
- /* 1 PHY_STATUS_INFO */
- u8 RSSI_Path[4]; /* */
- u8 RSSI_Ave;
- u8 RXEVM[4];
- u8 RXSNR[4];
-};
-
/* 2011/10/20 MH Define Common info enum for all team. */
enum odm_common_info_def {
@@ -740,8 +724,6 @@ struct odm_dm_struct {
u32 SupportICType;
/* Cut Version TestChip/A-cut/B-cut... = 0/1/2/3/... */
u8 CutVersion;
- /* RF Type 4T4R/3T3R/2T2R/1T2R/1T1R/... */
- u8 RFType;
/* Board Type Normal/HighPower/MiniCard/SLIM/Combo/. = 0/1/2/3/4/. */
u8 BoardType;
/* with external LNA NO/Yes = 0/1 */
diff --git a/drivers/staging/rtl8188eu/include/osdep_intf.h b/drivers/staging/rtl8188eu/include/osdep_intf.h
index 54fca79827e3..dbd7dc4f87dd 100644
--- a/drivers/staging/rtl8188eu/include/osdep_intf.h
+++ b/drivers/staging/rtl8188eu/include/osdep_intf.h
@@ -34,7 +34,6 @@ int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname);
struct net_device *rtw_init_netdev(struct adapter *padapter);
u16 rtw_recv_select_queue(struct sk_buff *skb);
-void rtw_proc_remove_one(struct net_device *dev);
int pm_netdev_open(struct net_device *pnetdev, u8 bnormal);
void rtw_ips_dev_unload(struct adapter *padapter);
diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h
index 5475956c5ee5..9047b6dec9ed 100644
--- a/drivers/staging/rtl8188eu/include/osdep_service.h
+++ b/drivers/staging/rtl8188eu/include/osdep_service.h
@@ -35,7 +35,7 @@
#include <asm/byteorder.h>
#include <linux/atomic.h>
#include <linux/io.h>
-#include <linux/semaphore.h>
+#include <linux/mutex.h>
#include <linux/sem.h>
#include <linux/sched.h>
#include <linux/etherdevice.h>
@@ -44,7 +44,6 @@
#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
#include <linux/delay.h>
-#include <linux/proc_fs.h> /* Necessary because we use the proc fs */
#include <linux/interrupt.h> /* for struct tasklet_struct */
#include <linux/ip.h>
#include <linux/kthread.h>
@@ -78,16 +77,12 @@ u8 *_rtw_malloc(u32 sz);
void *rtw_malloc2d(int h, int w, int size);
-u32 _rtw_down_sema(struct semaphore *sema);
-
void _rtw_init_queue(struct __queue *pqueue);
struct rtw_netdev_priv_indicator {
void *priv;
- u32 sizeof_priv;
};
-struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv,
- void *old_priv);
+struct net_device *rtw_alloc_etherdev_with_old_priv(void *old_priv);
#define rtw_netdev_priv(netdev) \
(((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv)
diff --git a/drivers/staging/rtl8188eu/include/phy.h b/drivers/staging/rtl8188eu/include/phy.h
index 9a9ab82a8ed3..cd387e998574 100644
--- a/drivers/staging/rtl8188eu/include/phy.h
+++ b/drivers/staging/rtl8188eu/include/phy.h
@@ -11,17 +11,13 @@ bool rtl88eu_phy_bb_config(struct adapter *adapt);
u32 phy_query_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask);
void phy_set_bb_reg(struct adapter *adapt, u32 regaddr, u32 bitmask, u32 data);
-u32 phy_query_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path,
+u32 rtw_hal_read_rfreg(struct adapter *adapt, enum rf_radio_path rf_path,
u32 reg_addr, u32 bit_mask);
void phy_set_rf_reg(struct adapter *adapt, enum rf_radio_path rf_path,
u32 reg_addr, u32 bit_mask, u32 data);
void phy_set_tx_power_level(struct adapter *adapt, u8 channel);
-void phy_set_bw_mode(struct adapter *adapt, enum ht_channel_width bandwidth,
- unsigned char offset);
-void phy_sw_chnl(struct adapter *adapt, u8 channel);
-
void rtl88eu_dm_txpower_track_adjust(struct odm_dm_struct *dm_odm,
u8 type, u8 *dir, u32 *out_write);
diff --git a/drivers/staging/rtl8188eu/include/recv_osdep.h b/drivers/staging/rtl8188eu/include/recv_osdep.h
index cad31587c30a..7550d58f6b5b 100644
--- a/drivers/staging/rtl8188eu/include/recv_osdep.h
+++ b/drivers/staging/rtl8188eu/include/recv_osdep.h
@@ -26,13 +26,9 @@ void _rtw_free_recv_priv(struct recv_priv *precvpriv);
s32 rtw_recv_entry(struct recv_frame *precv_frame);
int rtw_recv_indicatepkt(struct adapter *adapter,
struct recv_frame *recv_frame);
-void rtw_recv_returnpacket(struct net_device *cnxt, struct sk_buff *retpkt);
void rtw_handle_tkip_mic_err(struct adapter *padapter, u8 bgroup);
-int rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter);
-void rtw_free_recv_priv(struct recv_priv *precvpriv);
-
void rtw_os_recv_resource_alloc(struct recv_frame *recvfr);
int rtw_os_recvbuf_resource_alloc(struct adapter *adapt, struct recv_buf *buf);
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h b/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h
index 4d7d804658c2..042b4ec656c8 100644
--- a/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h
+++ b/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h
@@ -49,12 +49,6 @@ enum RTL8188E_H2C_CMD_ID {
H2C_RESET_TSF = 0xc0,
};
-struct cmd_msg_parm {
- u8 eid; /* element id */
- u8 sz; /* sz */
- u8 buf[6];
-};
-
enum {
PWRS
};
@@ -67,15 +61,6 @@ struct setpwrmode_parm {
u8 PwrState;/* AllON(0x0c),RFON(0x04),RFOFF(0x00) */
};
-struct H2C_SS_RFOFF_PARAM {
- u8 ROFOn; /* 1: on, 0:off */
- u16 gpio_period; /* unit: 1024 us */
-} __packed;
-
-struct joinbssrpt_parm {
- u8 OpMode; /* RT_MEDIA_STATUS */
-};
-
struct rsvdpage_loc {
u8 LocProbeRsp;
u8 LocPsPoll;
@@ -84,26 +69,9 @@ struct rsvdpage_loc {
u8 LocBTQosNull;
};
-struct P2P_PS_Offload_t {
- u8 Offload_En:1;
- u8 role:1; /* 1: Owner, 0: Client */
- u8 CTWindow_En:1;
- u8 NoA0_En:1;
- u8 NoA1_En:1;
- u8 AllStaSleep:1; /* Only valid in Owner */
- u8 discovery:1;
- u8 rsvd:1;
-};
-
-struct P2P_PS_CTWPeriod_t {
- u8 CTWPeriod; /* TU */
-};
-
/* host message to firmware cmd */
void rtl8188e_set_FwPwrMode_cmd(struct adapter *padapter, u8 Mode);
void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *padapter, u8 mstatus);
-void rtl8188e_Add_RateATid(struct adapter *padapter, u32 bitmap, u8 arg,
- u8 rssi_level);
void rtl8188e_set_FwMediaStatus_cmd(struct adapter *adapt, __le16 mstatus_rpt);
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_dm.h b/drivers/staging/rtl8188eu/include/rtl8188e_dm.h
index 4190112a50bf..c0ffd98d7617 100644
--- a/drivers/staging/rtl8188eu/include/rtl8188e_dm.h
+++ b/drivers/staging/rtl8188eu/include/rtl8188e_dm.h
@@ -45,12 +45,9 @@ struct dm_priv {
u8 PowerIndex_backup[6];
};
-void rtl8188e_init_dm_priv(struct adapter *adapt);
void rtl8188e_InitHalDm(struct adapter *adapt);
-void rtl8188e_HalDmWatchDog(struct adapter *adapt);
void AntDivCompare8188E(struct adapter *adapt, struct wlan_bssid_ex *dst,
struct wlan_bssid_ex *src);
-u8 AntDivBeforeLink8188E(struct adapter *adapt);
#endif
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h
index 9dd5c293a54b..7c81e3f3d12e 100644
--- a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h
+++ b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h
@@ -202,7 +202,6 @@ struct hal_data_8188e {
/* rf_ctrl */
u8 rf_chip;
- u8 rf_type;
u8 NumTotalRFPath;
u8 BoardType;
@@ -351,10 +350,6 @@ struct hal_data_8188e {
u8 UsbRxAggPageTimeout;
};
-#define GET_HAL_DATA(__pAdapter) \
- ((struct hal_data_8188e *)((__pAdapter)->HalData))
-#define GET_RF_TYPE(priv) (GET_HAL_DATA(priv)->rf_type)
-
/* rtl8188e_hal_init.c */
void _8051Reset88E(struct adapter *padapter);
void rtl8188e_InitializeFirmwareVars(struct adapter *padapter);
@@ -385,8 +380,6 @@ void Hal_EfuseParseBoardType88E(struct adapter *pAdapter, u8 *hwinfo,
void Hal_ReadPowerSavingMode88E(struct adapter *pAdapter, u8 *hwinfo,
bool AutoLoadFail);
-void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc);
-
/* register */
void rtl8188e_start_thread(struct adapter *padapter);
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_led.h b/drivers/staging/rtl8188eu/include/rtl8188e_led.h
index fca6d8c81e90..d1ad6aa8c1e0 100644
--- a/drivers/staging/rtl8188eu/include/rtl8188e_led.h
+++ b/drivers/staging/rtl8188eu/include/rtl8188e_led.h
@@ -22,8 +22,6 @@
/* */
/* Interface to manipulate LED objects. */
/* */
-void rtl8188eu_InitSwLeds(struct adapter *padapter);
-void rtl8188eu_DeInitSwLeds(struct adapter *padapter);
void SwLedOn(struct adapter *padapter, struct LED_871x *pLed);
void SwLedOff(struct adapter *padapter, struct LED_871x *pLed);
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_recv.h b/drivers/staging/rtl8188eu/include/rtl8188e_recv.h
index 54048bc826e5..80832a5f0732 100644
--- a/drivers/staging/rtl8188eu/include/rtl8188e_recv.h
+++ b/drivers/staging/rtl8188eu/include/rtl8188e_recv.h
@@ -51,12 +51,11 @@ enum rx_packet_type {
};
#define INTERRUPT_MSG_FORMAT_LEN 60
-s32 rtl8188eu_init_recv_priv(struct adapter *padapter);
-void rtl8188eu_free_recv_priv(struct adapter *padapter);
void rtl8188eu_recv_hdl(struct adapter *padapter, struct recv_buf *precvbuf);
void rtl8188eu_recv_tasklet(void *priv);
void rtl8188e_query_rx_phy_status(struct recv_frame *fr, struct phy_stat *phy);
-void rtl8188e_process_phy_info(struct adapter *padapter, void *prframe);
+void rtl8188e_process_phy_info(struct adapter *padapter,
+ struct recv_frame *prframe);
void update_recvframe_phyinfo_88e(struct recv_frame *fra, struct phy_stat *phy);
void update_recvframe_attrib_88e(struct recv_frame *fra,
struct recv_stat *stat);
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h b/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h
index 65a63df2077f..66205b782721 100644
--- a/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h
+++ b/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h
@@ -154,14 +154,11 @@ struct txrpt_ccx_88e {
void rtl8188e_fill_fake_txdesc(struct adapter *padapter, u8 *pDesc,
u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull);
s32 rtl8188eu_init_xmit_priv(struct adapter *padapter);
-s32 rtl8188eu_hal_xmit(struct adapter *padapter, struct xmit_frame *frame);
-s32 rtl8188eu_mgnt_xmit(struct adapter *padapter, struct xmit_frame *frame);
s32 rtl8188eu_xmit_buf_handler(struct adapter *padapter);
#define hal_xmit_handler rtl8188eu_xmit_buf_handler
void rtl8188eu_xmit_tasklet(void *priv);
s32 rtl8188eu_xmitframe_complete(struct adapter *padapter,
- struct xmit_priv *pxmitpriv,
- struct xmit_buf *pxmitbuf);
+ struct xmit_priv *pxmitpriv);
void dump_txrpt_ccx_88e(void *buf);
void handle_txrpt_ccx_88e(struct adapter *adapter, u8 *buf);
diff --git a/drivers/staging/rtl8188eu/include/rtw_ap.h b/drivers/staging/rtl8188eu/include/rtw_ap.h
index b820684bc3fe..e8dd6d4407aa 100644
--- a/drivers/staging/rtl8188eu/include/rtw_ap.h
+++ b/drivers/staging/rtl8188eu/include/rtw_ap.h
@@ -50,7 +50,6 @@ void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta);
u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta,
bool active, u16 reason);
int rtw_sta_flush(struct adapter *padapter);
-int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset);
void start_ap_mode(struct adapter *padapter);
void stop_ap_mode(struct adapter *padapter);
#endif /* end of CONFIG_88EU_AP_MODE */
diff --git a/drivers/staging/rtl8188eu/include/rtw_cmd.h b/drivers/staging/rtl8188eu/include/rtw_cmd.h
index 08ca59217cb7..18a6530c9dde 100644
--- a/drivers/staging/rtl8188eu/include/rtw_cmd.h
+++ b/drivers/staging/rtl8188eu/include/rtw_cmd.h
@@ -39,8 +39,8 @@ struct cmd_obj {
};
struct cmd_priv {
- struct semaphore cmd_queue_sema;
- struct semaphore terminate_cmdthread_sema;
+ struct completion cmd_queue_comp;
+ struct completion terminate_cmdthread_comp;
struct __queue cmd_queue;
u8 cmdthd_running;
struct adapter *padapter;
@@ -210,34 +210,6 @@ struct set_assocsta_rsp {
};
/*
- Caller Ad-Hoc/AP
-
- Command mode
-
- This is to force fw to del an sta_data entry per driver's request
-
- FW will invalidate the cam entry associated with it.
-
-*/
-struct del_assocsta_parm {
- u8 addr[ETH_ALEN];
-};
-
-/*
-Caller Mode: AP/Ad-HoC(M)
-
-Notes: To notify fw that given staid has changed its power state
-
-Command Mode
-
-*/
-struct setstapwrstate_parm {
- u8 staid;
- u8 status;
- u8 hwaddr[6];
-};
-
-/*
Notes: This command is used for H2C/C2H loopback testing
mac[0] == 0
@@ -312,8 +284,6 @@ struct SetChannelPlan_param {
u8 channel_plan;
};
-#define GEN_CMD_CODE(cmd) cmd ## _CMD_
-
/*
Result:
@@ -376,42 +346,42 @@ struct _cmd_callback {
};
enum rtw_h2c_cmd {
- GEN_CMD_CODE(_JoinBss),
- GEN_CMD_CODE(_DisConnect),
- GEN_CMD_CODE(_CreateBss),
- GEN_CMD_CODE(_SetOpMode),
- GEN_CMD_CODE(_SiteSurvey),
- GEN_CMD_CODE(_SetAuth),
- GEN_CMD_CODE(_SetKey),
- GEN_CMD_CODE(_SetStaKey),
- GEN_CMD_CODE(_SetAssocSta),
- GEN_CMD_CODE(_AddBAReq),
- GEN_CMD_CODE(_SetChannel),
- GEN_CMD_CODE(_TX_Beacon),
- GEN_CMD_CODE(_Set_MLME_EVT),
- GEN_CMD_CODE(_Set_Drv_Extra),
- GEN_CMD_CODE(_SetChannelPlan),
+ _JoinBss_CMD_,
+ _DisConnect_CMD_,
+ _CreateBss_CMD_,
+ _SetOpMode_CMD_,
+ _SiteSurvey_CMD_,
+ _SetAuth_CMD_,
+ _SetKey_CMD_,
+ _SetStaKey_CMD_,
+ _SetAssocSta_CMD_,
+ _AddBAReq_CMD_,
+ _SetChannel_CMD_,
+ _TX_Beacon_CMD_,
+ _Set_MLME_EVT_CMD_,
+ _Set_Drv_Extra_CMD_,
+ _SetChannelPlan_CMD_,
MAX_H2CCMD
};
#ifdef _RTW_CMD_C_
static struct _cmd_callback rtw_cmd_callback[] = {
- {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd_callback},
- {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd_callback},
- {GEN_CMD_CODE(_CreateBss), &rtw_createbss_cmd_callback},
- {GEN_CMD_CODE(_SetOpMode), NULL},
- {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback},
- {GEN_CMD_CODE(_SetAuth), NULL},
- {GEN_CMD_CODE(_SetKey), NULL},
- {GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback},
- {GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback},
- {GEN_CMD_CODE(_AddBAReq), NULL},
- {GEN_CMD_CODE(_SetChannel), NULL},
- {GEN_CMD_CODE(_TX_Beacon), NULL},
- {GEN_CMD_CODE(_Set_MLME_EVT), NULL},
- {GEN_CMD_CODE(_Set_Drv_Extra), NULL},
- {GEN_CMD_CODE(_SetChannelPlan), NULL},
+ {_JoinBss_CMD_, &rtw_joinbss_cmd_callback},
+ {_DisConnect_CMD_, &rtw_disassoc_cmd_callback},
+ {_CreateBss_CMD_, &rtw_createbss_cmd_callback},
+ {_SetOpMode_CMD_, NULL},
+ {_SiteSurvey_CMD_, &rtw_survey_cmd_callback},
+ {_SetAuth_CMD_, NULL},
+ {_SetKey_CMD_, NULL},
+ {_SetStaKey_CMD_, &rtw_setstaKey_cmdrsp_callback},
+ {_SetAssocSta_CMD_, &rtw_setassocsta_cmdrsp_callback},
+ {_AddBAReq_CMD_, NULL},
+ {_SetChannel_CMD_, NULL},
+ {_TX_Beacon_CMD_, NULL},
+ {_Set_MLME_EVT_CMD_, NULL},
+ {_Set_Drv_Extra_CMD_, NULL},
+ {_SetChannelPlan_CMD_, NULL},
};
#endif
diff --git a/drivers/staging/rtl8188eu/include/rtw_debug.h b/drivers/staging/rtl8188eu/include/rtw_debug.h
index 7ed4cada7efa..95590a1a7b1b 100644
--- a/drivers/staging/rtl8188eu/include/rtw_debug.h
+++ b/drivers/staging/rtl8188eu/include/rtw_debug.h
@@ -129,133 +129,12 @@ int proc_get_read_reg(char *page, char **start,
int proc_set_read_reg(struct file *file, const char __user *buffer,
unsigned long count, void *data);
-int proc_get_fwstate(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-int proc_get_sec_info(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-int proc_get_mlmext_state(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_get_qos_option(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-int proc_get_ht_option(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-int proc_get_rf_info(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-int proc_get_ap_info(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
int proc_get_adapter_state(char *page, char **start,
off_t offset, int count,
int *eof, void *data);
-int proc_get_trx_info(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_get_mac_reg_dump1(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_get_mac_reg_dump2(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_get_mac_reg_dump3(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_get_bb_reg_dump1(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_get_bb_reg_dump2(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_get_bb_reg_dump3(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_get_rf_reg_dump1(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_get_rf_reg_dump2(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_get_rf_reg_dump3(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_get_rf_reg_dump4(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-#ifdef CONFIG_88EU_AP_MODE
-
-int proc_get_all_sta_info(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-#endif
-
int proc_get_best_channel(char *page, char **start,
off_t offset, int count,
int *eof, void *data);
-int proc_get_rx_signal(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_set_rx_signal(struct file *file, const char __user *buffer,
- unsigned long count, void *data);
-
-int proc_get_ht_enable(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_set_ht_enable(struct file *file, const char __user *buffer,
- unsigned long count, void *data);
-
-int proc_get_cbw40_enable(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_set_cbw40_enable(struct file *file, const char __user *buffer,
- unsigned long count, void *data);
-
-int proc_get_ampdu_enable(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_set_ampdu_enable(struct file *file, const char __user *buffer,
- unsigned long count, void *data);
-
-int proc_get_rx_stbc(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_set_rx_stbc(struct file *file, const char __user *buffer,
- unsigned long count, void *data);
-
-int proc_get_two_path_rssi(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_get_rssi_disp(char *page, char **start,
- off_t offset, int count,
- int *eof, void *data);
-
-int proc_set_rssi_disp(struct file *file, const char __user *buffer,
- unsigned long count, void *data);
-
#endif /* __RTW_DEBUG_H__ */
diff --git a/drivers/staging/rtl8188eu/include/rtw_efuse.h b/drivers/staging/rtl8188eu/include/rtw_efuse.h
index 9bfb10c302b5..168c12d3c0b4 100644
--- a/drivers/staging/rtl8188eu/include/rtw_efuse.h
+++ b/drivers/staging/rtl8188eu/include/rtw_efuse.h
@@ -34,16 +34,6 @@
#define EFUSE_WIFI 0
#define EFUSE_BT 1
-enum _EFUSE_DEF_TYPE {
- TYPE_EFUSE_MAX_SECTION = 0,
- TYPE_EFUSE_REAL_CONTENT_LEN = 1,
- TYPE_AVAILABLE_EFUSE_BYTES_BANK = 2,
- TYPE_AVAILABLE_EFUSE_BYTES_TOTAL = 3,
- TYPE_EFUSE_MAP_LEN = 4,
- TYPE_EFUSE_PROTECT_BYTES_BANK = 5,
- TYPE_EFUSE_CONTENT_LEN_BANK = 6,
-};
-
/* E-Fuse */
#define EFUSE_MAP_SIZE 512
#define EFUSE_MAX_SIZE 256
@@ -95,8 +85,6 @@ struct efuse_hal {
};
u8 Efuse_CalculateWordCnts(u8 word_en);
-void EFUSE_GetEfuseDefinition(struct adapter *adapt, u8 type, u8 type1,
- void *out);
u8 efuse_OneByteRead(struct adapter *adapter, u16 addr, u8 *data);
u8 efuse_OneByteWrite(struct adapter *adapter, u16 addr, u8 data);
diff --git a/drivers/staging/rtl8188eu/include/rtw_event.h b/drivers/staging/rtl8188eu/include/rtw_event.h
index 5c34e567d341..1c5ebde97091 100644
--- a/drivers/staging/rtl8188eu/include/rtw_event.h
+++ b/drivers/staging/rtl8188eu/include/rtw_event.h
@@ -18,7 +18,7 @@
#include <osdep_service.h>
#include <wlan_bssdef.h>
-#include <linux/semaphore.h>
+#include <linux/mutex.h>
#include <linux/sem.h>
/*
@@ -71,12 +71,6 @@ struct stadel_event {
int mac_id;
};
-struct addba_event {
- unsigned int tid;
-};
-
-#define GEN_EVT_CODE(event) event ## _EVT_
-
struct fwevent {
u32 parmsize;
void (*event_callback)(struct adapter *dev, u8 *pbuf);
@@ -84,21 +78,6 @@ struct fwevent {
#define C2HEVENT_SZ 32
-struct event_node {
- unsigned char *node;
- unsigned char evt_code;
- unsigned short evt_sz;
- int *caller_ff_tail;
- int caller_ff_sz;
-};
-
-struct c2hevent_queue {
- int head;
- int tail;
- struct event_node nodes[C2HEVENT_SZ];
- unsigned char seq;
-};
-
#define NETWORK_QUEUE_SZ 4
struct network_queue {
diff --git a/drivers/staging/rtl8188eu/include/rtw_ht.h b/drivers/staging/rtl8188eu/include/rtw_ht.h
index b45483fd069f..d842eade7f57 100644
--- a/drivers/staging/rtl8188eu/include/rtw_ht.h
+++ b/drivers/staging/rtl8188eu/include/rtw_ht.h
@@ -15,16 +15,11 @@
#ifndef _RTW_HT_H_
#define _RTW_HT_H_
-#include <osdep_service.h>
-#include "wifi.h"
+#include <linux/ieee80211.h>
struct ht_priv {
u32 ht_option;
u32 ampdu_enable;/* for enable Tx A-MPDU */
- u32 tx_amsdu_enable;/* for enable Tx A-MSDU */
- u32 tx_amdsu_maxlen; /* 1: 8k, 0:4k ; default:8k, for tx */
- u32 rx_ampdu_maxlen; /* for rx reordering ctrl win_sz,
- * updated when join_callback. */
u8 bwmode;/* */
u8 ch_offset;/* PRIME_CHNL_OFFSET */
u8 sgi;/* short GI */
@@ -33,7 +28,7 @@ struct ht_priv {
u8 agg_enable_bitmap;
u8 candidate_tid_bitmap;
- struct rtw_ieee80211_ht_cap ht_cap;
+ struct ieee80211_ht_cap ht_cap;
};
#endif /* _RTL871X_HT_H_ */
diff --git a/drivers/staging/rtl8188eu/include/rtw_ioctl.h b/drivers/staging/rtl8188eu/include/rtw_ioctl.h
index 3a652df4b26c..a6b1c854a061 100644
--- a/drivers/staging/rtl8188eu/include/rtw_ioctl.h
+++ b/drivers/staging/rtl8188eu/include/rtw_ioctl.h
@@ -69,15 +69,6 @@ enum oid_type {
SET_OID
};
-struct oid_funs_node {
- unsigned int oid_start; /* the starting number for OID */
- unsigned int oid_end; /* the ending number for OID */
- struct oid_obj_priv *node_array;
- unsigned int array_sz; /* the size of node_array */
- int query_counter; /* count the number of query hits for this segment */
- int set_counter; /* count the number of set hits for this segment */
-};
-
struct oid_par_priv {
void *adapter_context;
NDIS_OID oid;
@@ -89,12 +80,6 @@ struct oid_par_priv {
u32 dbg;
};
-struct oid_obj_priv {
- unsigned char dbg; /* 0: without OID debug message
- * 1: with OID debug message */
- int (*oidfuns)(struct oid_par_priv *poid_par_priv);
-};
-
#if defined(_RTW_MP_IOCTL_C_)
static int oid_null_function(struct oid_par_priv *poid_par_priv) {
return NDIS_STATUS_SUCCESS;
diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme.h b/drivers/staging/rtl8188eu/include/rtw_mlme.h
index 5d8bce0f58db..9434b869c5e9 100644
--- a/drivers/staging/rtl8188eu/include/rtw_mlme.h
+++ b/drivers/staging/rtl8188eu/include/rtw_mlme.h
@@ -301,12 +301,10 @@ struct mlme_priv {
u8 *nic_hdl;
- u8 not_indic_disco;
struct list_head *pscanned;
struct __queue free_bss_pool;
struct __queue scanned_queue;
u8 *free_bss_buf;
- u32 num_of_scanned;
struct ndis_802_11_ssid assoc_ssid;
u8 assoc_bssid[6];
@@ -318,10 +316,8 @@ struct mlme_priv {
struct timer_list assoc_timer;
uint assoc_by_bssid;
- uint assoc_by_rssi;
struct timer_list scan_to_timer; /* driver itself handles scan_timeout status. */
- u32 scan_start_time; /* used to evaluate the time spent in scanning */
struct qos_priv qospriv;
@@ -387,17 +383,6 @@ struct mlme_priv {
u32 wps_probe_resp_ie_len;
u32 wps_assoc_resp_ie_len;
- u8 *p2p_beacon_ie;
- u8 *p2p_probe_req_ie;
- u8 *p2p_probe_resp_ie;
- u8 *p2p_go_probe_resp_ie; /* for GO */
- u8 *p2p_assoc_req_ie;
-
- u32 p2p_beacon_ie_len;
- u32 p2p_probe_req_ie_len;
- u32 p2p_probe_resp_ie_len;
- u32 p2p_go_probe_resp_ie_len; /* for GO */
- u32 p2p_assoc_req_ie_len;
spinlock_t bcn_update_lock;
u8 update_bcn;
#endif /* if defined (CONFIG_88EU_AP_MODE) */
@@ -500,27 +485,6 @@ static inline void clr_fwstate_ex(struct mlme_priv *pmlmepriv, int state)
spin_unlock_bh(&pmlmepriv->lock);
}
-static inline void up_scanned_network(struct mlme_priv *pmlmepriv)
-{
- spin_lock_bh(&pmlmepriv->lock);
- pmlmepriv->num_of_scanned++;
- spin_unlock_bh(&pmlmepriv->lock);
-}
-
-static inline void down_scanned_network(struct mlme_priv *pmlmepriv)
-{
- spin_lock_bh(&pmlmepriv->lock);
- pmlmepriv->num_of_scanned--;
- spin_unlock_bh(&pmlmepriv->lock);
-}
-
-static inline void set_scanned_network_val(struct mlme_priv *pmlmepriv, int val)
-{
- spin_lock_bh(&pmlmepriv->lock);
- pmlmepriv->num_of_scanned = val;
- spin_unlock_bh(&pmlmepriv->lock);
-}
-
u16 rtw_get_capability(struct wlan_bssid_ex *bss);
void rtw_update_scanned_network(struct adapter *adapter,
struct wlan_bssid_ex *target);
diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
index 27382ff24a84..1b1caaf583c9 100644
--- a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
+++ b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
@@ -349,7 +349,7 @@ struct mlme_ext_info {
struct ADDBA_request ADDBA_req;
struct WMM_para_element WMM_param;
- struct HT_caps_element HT_caps;
+ struct ieee80211_ht_cap HT_caps;
struct HT_info_element HT_info;
struct wlan_bssid_ex network;/* join network or bss_network,
* if in ap mode, it is the same
@@ -529,12 +529,12 @@ int update_sta_support_rate(struct adapter *padapter, u8 *pvar_ie,
void update_sta_info(struct adapter *padapter, struct sta_info *psta);
unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz);
unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz);
-unsigned int update_MSC_rate(struct HT_caps_element *pHT_caps);
+unsigned int update_MSC_rate(struct ieee80211_ht_cap *pHT_caps);
void Update_RA_Entry(struct adapter *padapter, u32 mac_id);
void set_sta_rate(struct adapter *padapter, struct sta_info *psta);
unsigned char get_highest_rate_idx(u32 mask);
-int support_short_GI(struct adapter *padapter, struct HT_caps_element *caps);
+int support_short_GI(struct adapter *padapter, struct ieee80211_ht_cap *caps);
unsigned int is_ap_in_tkip(struct adapter *padapter);
unsigned int is_ap_in_wep(struct adapter *padapter);
unsigned int should_forbid_n_rate(struct adapter *padapter);
@@ -562,8 +562,6 @@ int issue_qos_nulldata(struct adapter *padapter, unsigned char *da,
u16 tid, int try_cnt, int wait_ms);
int issue_deauth(struct adapter *padapter, unsigned char *da,
unsigned short reason);
-void issue_action_spct_ch_switch(struct adapter *padapter, u8 *ra, u8 new_ch,
- u8 ch_offset);
unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr);
unsigned int send_beacon(struct adapter *padapter);
@@ -627,27 +625,24 @@ u8 led_blink_hdl(struct adapter *padapter, unsigned char *pbuf);
u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf);
u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf);
-#define GEN_DRV_CMD_HANDLER(size, cmd) {size, &cmd ## _hdl},
-#define GEN_MLME_EXT_HANDLER(size, cmd) {size, cmd},
-
#ifdef _RTW_CMD_C_
static struct cmd_hdl wlancmds[] = {
- GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), join_cmd_hdl)
- GEN_MLME_EXT_HANDLER(sizeof(struct disconnect_parm), disconnect_hdl)
- GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), createbss_hdl)
- GEN_MLME_EXT_HANDLER(sizeof(struct setopmode_parm), setopmode_hdl)
- GEN_MLME_EXT_HANDLER(sizeof(struct sitesurvey_parm), sitesurvey_cmd_hdl)
- GEN_MLME_EXT_HANDLER(sizeof(struct setauth_parm), setauth_hdl)
- GEN_MLME_EXT_HANDLER(sizeof(struct setkey_parm), setkey_hdl)
- GEN_MLME_EXT_HANDLER(sizeof(struct set_stakey_parm), set_stakey_hdl)
- GEN_MLME_EXT_HANDLER(sizeof(struct set_assocsta_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl)
- GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl)
- GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), tx_beacon_hdl)
- GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl)
- GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl)
- GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), set_chplan_hdl)
+ {sizeof(struct wlan_bssid_ex), join_cmd_hdl},
+ {sizeof(struct disconnect_parm), disconnect_hdl},
+ {sizeof(struct wlan_bssid_ex), createbss_hdl},
+ {sizeof(struct setopmode_parm), setopmode_hdl},
+ {sizeof(struct sitesurvey_parm), sitesurvey_cmd_hdl},
+ {sizeof(struct setauth_parm), setauth_hdl},
+ {sizeof(struct setkey_parm), setkey_hdl},
+ {sizeof(struct set_stakey_parm), set_stakey_hdl},
+ {sizeof(struct set_assocsta_parm), NULL},
+ {sizeof(struct addBaReq_parm), add_ba_hdl},
+ {sizeof(struct set_ch_parm), set_ch_hdl},
+ {sizeof(struct wlan_bssid_ex), tx_beacon_hdl},
+ {0, mlme_evt_hdl},
+ {0, rtw_drvextra_cmd_hdl},
+ {sizeof(struct SetChannelPlan_param), set_chplan_hdl}
};
#endif
@@ -669,32 +664,32 @@ void rtw_dummy_event_callback(struct adapter *adapter, u8 *pbuf);
void rtw_fwdbg_event_callback(struct adapter *adapter, u8 *pbuf);
enum rtw_c2h_event {
- GEN_EVT_CODE(_Read_MACREG) = 0, /*0*/
- GEN_EVT_CODE(_Read_BBREG),
- GEN_EVT_CODE(_Read_RFREG),
- GEN_EVT_CODE(_Read_EEPROM),
- GEN_EVT_CODE(_Read_EFUSE),
- GEN_EVT_CODE(_Read_CAM), /*5*/
- GEN_EVT_CODE(_Get_BasicRate),
- GEN_EVT_CODE(_Get_DataRate),
- GEN_EVT_CODE(_Survey), /*8*/
- GEN_EVT_CODE(_SurveyDone), /*9*/
-
- GEN_EVT_CODE(_JoinBss), /*10*/
- GEN_EVT_CODE(_AddSTA),
- GEN_EVT_CODE(_DelSTA),
- GEN_EVT_CODE(_AtimDone),
- GEN_EVT_CODE(_TX_Report),
- GEN_EVT_CODE(_CCX_Report), /*15*/
- GEN_EVT_CODE(_DTM_Report),
- GEN_EVT_CODE(_TX_Rate_Statistics),
- GEN_EVT_CODE(_C2HLBK),
- GEN_EVT_CODE(_FWDBG),
- GEN_EVT_CODE(_C2HFEEDBACK), /*20*/
- GEN_EVT_CODE(_ADDBA),
- GEN_EVT_CODE(_C2HBCN),
- GEN_EVT_CODE(_ReportPwrState), /* filen: only for PCIE, USB */
- GEN_EVT_CODE(_CloseRF), /* filen: only for PCIE,
+ _Read_MACREG_EVT_ = 0, /*0*/
+ _Read_BBREG_EVT_,
+ _Read_RFREG_EVT_,
+ _Read_EEPROM_EVT_,
+ _Read_EFUSE_EVT_,
+ _Read_CAM_EVT_, /*5*/
+ _Get_BasicRate_EVT_,
+ _Get_DataRate_EVT_,
+ _Survey_EVT_, /*8*/
+ _SurveyDone_EVT_, /*9*/
+
+ _JoinBss_EVT_, /*10*/
+ _AddSTA_EVT_,
+ _DelSTA_EVT_,
+ _AtimDone_EVT_,
+ _TX_Report_EVT_,
+ _CCX_Report_EVT_, /*15*/
+ _DTM_Report_EVT_,
+ _TX_Rate_Statistics_EVT_,
+ _C2HLBK_EVT_,
+ _FWDBG_EVT_,
+ _C2HFEEDBACK_EVT_, /*20*/
+ _ADDBA_EVT_,
+ _C2HBCN_EVT_,
+ _ReportPwrState_EVT_, /* filen: only for PCIE, USB */
+ _CloseRF_EVT_, /* filen: only for PCIE,
* work around ASPM */
MAX_C2HEVT
};
diff --git a/drivers/staging/rtl8188eu/include/rtw_pwrctrl.h b/drivers/staging/rtl8188eu/include/rtw_pwrctrl.h
index 9680e2eab62f..18a9e744fcbe 100644
--- a/drivers/staging/rtl8188eu/include/rtw_pwrctrl.h
+++ b/drivers/staging/rtl8188eu/include/rtw_pwrctrl.h
@@ -92,21 +92,6 @@ struct reportpwrstate_parm {
unsigned short rsvd;
};
-static inline void _init_pwrlock(struct semaphore *plock)
-{
- sema_init(plock, 1);
-}
-
-static inline void _enter_pwrlock(struct semaphore *plock)
-{
- _rtw_down_sema(plock);
-}
-
-static inline void _exit_pwrlock(struct semaphore *plock)
-{
- up(plock);
-}
-
#define LPS_DELAY_TIME 1*HZ /* 1 sec */
#define EXE_PWR_NONE 0x01
@@ -157,7 +142,7 @@ enum { /* for ips_mode */
};
struct pwrctrl_priv {
- struct semaphore lock;
+ struct mutex mutex_lock;
volatile u8 rpwm; /* requested power state for fw */
volatile u8 cpwm; /* fw current power state. updated when
* 1. read from HCPWM 2. driver lowers power level */
diff --git a/drivers/staging/rtl8188eu/include/rtw_recv.h b/drivers/staging/rtl8188eu/include/rtw_recv.h
index b0373b6216d6..49d973881a04 100644
--- a/drivers/staging/rtl8188eu/include/rtw_recv.h
+++ b/drivers/staging/rtl8188eu/include/rtw_recv.h
@@ -65,13 +65,6 @@ struct stainfo_rxcache {
*/
};
-struct smooth_rssi_data {
- u32 elements[100]; /* array to store values */
- u32 index; /* index to current array to store */
- u32 total_num; /* num of valid elements */
- u32 total_val; /* sum of valid elements */
-};
-
struct signal_stat {
u8 update_req; /* used to indicate */
u8 avg_val; /* avg of valid elements */
@@ -246,7 +239,6 @@ struct recv_buf {
struct recv_frame {
struct list_head list;
struct sk_buff *pkt;
- struct sk_buff *pkt_newalloc;
struct adapter *adapter;
struct rx_pkt_attrib attrib;
uint len;
diff --git a/drivers/staging/rtl8188eu/include/rtw_security.h b/drivers/staging/rtl8188eu/include/rtw_security.h
index ca1247bce6e3..2663e60bb6c6 100644
--- a/drivers/staging/rtl8188eu/include/rtw_security.h
+++ b/drivers/staging/rtl8188eu/include/rtw_security.h
@@ -164,12 +164,6 @@ struct security_priv {
u8 bWepDefaultKeyIdxSet;
};
-struct sha256_state {
- u64 length;
- u32 state[8], curlen;
- u8 buf[64];
-};
-
#define GET_ENCRY_ALGO(psecuritypriv, psta, encry_algo, bmcst) \
do { \
switch (psecuritypriv->dot11AuthAlgrthm) { \
diff --git a/drivers/staging/rtl8188eu/include/rtw_sreset.h b/drivers/staging/rtl8188eu/include/rtw_sreset.h
index ce027dfdecc5..4c4ccd564863 100644
--- a/drivers/staging/rtl8188eu/include/rtw_sreset.h
+++ b/drivers/staging/rtl8188eu/include/rtw_sreset.h
@@ -33,7 +33,6 @@ struct sreset_priv {
#define WIFI_RX_HANG BIT(5)
#define WIFI_IF_NOT_EXIST BIT(6)
-void sreset_init_value(struct adapter *padapter);
u8 sreset_get_wifi_status(struct adapter *padapter);
void sreset_set_wifi_error_status(struct adapter *padapter, u32 status);
diff --git a/drivers/staging/rtl8188eu/include/rtw_xmit.h b/drivers/staging/rtl8188eu/include/rtw_xmit.h
index a0853bab3edb..dd6b7a9a8d4a 100644
--- a/drivers/staging/rtl8188eu/include/rtw_xmit.h
+++ b/drivers/staging/rtl8188eu/include/rtw_xmit.h
@@ -113,7 +113,6 @@ struct pkt_attrib {
u8 dhcp_pkt;
u16 ether_type;
u16 seqnum;
- u16 pkt_hdrlen; /* the original 802.3 pkt header len */
u16 hdrlen; /* the WLAN Header Len */
u32 pktlen; /* the original 802.3 pkt raw_data len (not include
* ether_hdr data) */
@@ -256,15 +255,8 @@ struct hw_txqueue {
int ac_tag;
};
-struct agg_pkt_info {
- u16 offset;
- u16 pkt_len;
-};
-
struct xmit_priv {
spinlock_t lock;
- struct semaphore xmit_sema;
- struct semaphore terminate_xmitthread_sema;
struct __queue be_pending;
struct __queue bk_pending;
struct __queue vi_pending;
@@ -289,7 +281,6 @@ struct xmit_priv {
u8 wmm_para_seq[4];/* sequence for wmm ac parameter strength
* from large to small. it's value is 0->vo,
* 1->vi, 2->be, 3->bk. */
- struct semaphore tx_retevt;/* all tx return event; */
u8 txirp_cnt;/* */
struct tasklet_struct xmit_tasklet;
/* per AC pending irp */
diff --git a/drivers/staging/rtl8188eu/include/usb_hal.h b/drivers/staging/rtl8188eu/include/usb_hal.h
deleted file mode 100644
index b1bf07a9013e..000000000000
--- a/drivers/staging/rtl8188eu/include/usb_hal.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __USB_HAL_H__
-#define __USB_HAL_H__
-
-void rtl8188eu_set_hal_ops(struct adapter *padapter);
-#define hal_set_hal_ops rtl8188eu_set_hal_ops
-
-#endif /* __USB_HAL_H__ */
diff --git a/drivers/staging/rtl8188eu/include/usb_ops_linux.h b/drivers/staging/rtl8188eu/include/usb_ops_linux.h
index 220733314f8b..78d9b6e035bf 100644
--- a/drivers/staging/rtl8188eu/include/usb_ops_linux.h
+++ b/drivers/staging/rtl8188eu/include/usb_ops_linux.h
@@ -47,21 +47,6 @@
#define usb_read_interrupt_complete(purb, regs) \
usb_read_interrupt_complete(purb)
-static inline u8 rtw_usb_bulk_size_boundary(struct adapter *padapter,
- int buf_len)
-{
- u8 rst = true;
- struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
-
- if (pdvobjpriv->ishighspeed)
- rst = (0 == (buf_len) % USB_HIGH_SPEED_BULK_SIZE) ?
- true : false;
- else
- rst = (0 == (buf_len) % USB_FULL_SPEED_BULK_SIZE) ?
- true : false;
- return rst;
-}
-
unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr);
u8 usb_read8(struct adapter *adapter, u32 addr);
@@ -75,7 +60,7 @@ int usb_write8(struct adapter *adapter, u32 addr, u8 val);
int usb_write16(struct adapter *adapter, u32 addr, u16 val);
int usb_write32(struct adapter *adapter, u32 addr, u32 val);
-u32 usb_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
+u32 usb_write_port(struct adapter *adapter, u32 addr, u32 cnt, struct xmit_buf *pmem);
void usb_write_port_cancel(struct adapter *adapter);
#endif
diff --git a/drivers/staging/rtl8188eu/include/wifi.h b/drivers/staging/rtl8188eu/include/wifi.h
index e7c512183619..9e08e6842eca 100644
--- a/drivers/staging/rtl8188eu/include/wifi.h
+++ b/drivers/staging/rtl8188eu/include/wifi.h
@@ -508,22 +508,6 @@ struct rtw_ieee80211_bar {
#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000
#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004
- /**
- * struct rtw_ieee80211_ht_cap - HT capabilities
- *
- * This structure refers to "HT capabilities element" as
- * described in 802.11n draft section 7.3.2.52
- */
-
-struct rtw_ieee80211_ht_cap {
- unsigned short cap_info;
- unsigned char ampdu_params_info;
- unsigned char supp_mcs_set[16];
- unsigned short extended_ht_cap_info;
- unsigned int tx_BF_cap_info;
- unsigned char antenna_selection_info;
-} __packed;
-
/**
* struct rtw_ieee80211_ht_cap - HT additional information
*
@@ -538,20 +522,6 @@ struct ieee80211_ht_addt_info {
unsigned char basic_set[16];
} __packed;
-struct HT_caps_element {
- union {
- struct {
- __le16 HT_caps_info;
- unsigned char AMPDU_para;
- unsigned char MCS_rate[16];
- unsigned short HT_ext_caps;
- unsigned int Beamforming_caps;
- unsigned char ASEL_caps;
- } HT_cap_element;
- unsigned char HT_cap[26];
- } u;
-} __packed;
-
struct HT_info_element {
unsigned char primary_channel;
unsigned char infos[5];
diff --git a/drivers/staging/rtl8188eu/include/wlan_bssdef.h b/drivers/staging/rtl8188eu/include/wlan_bssdef.h
index 560966cd7dfe..e1931dd04da0 100644
--- a/drivers/staging/rtl8188eu/include/wlan_bssdef.h
+++ b/drivers/staging/rtl8188eu/include/wlan_bssdef.h
@@ -123,40 +123,10 @@ enum ndis_802_11_wep_status {
#define NDIS_802_11_AI_RESFI_STATUSCODE 2
#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4
-struct ndis_802_11_ai_reqfi {
- u16 Capabilities;
- u16 ListenInterval;
- unsigned char CurrentAPAddress[ETH_ALEN];
-};
-
-struct ndis_802_11_ai_resfi {
- u16 Capabilities;
- u16 StatusCode;
- u16 AssociationId;
-};
-
-struct ndis_802_11_assoc_info {
- u32 Length;
- u16 AvailableRequestFixedIEs;
- struct ndis_802_11_ai_reqfi RequestFixedIEs;
- u32 RequestIELength;
- u32 OffsetRequestIEs;
- u16 AvailableResponseFixedIEs;
- struct ndis_802_11_ai_resfi ResponseFixedIEs;
- u32 ResponseIELength;
- u32 OffsetResponseIEs;
-};
-
enum ndis_802_11_reload_def {
Ndis802_11ReloadWEPKeys
};
-struct ndis_802_11_remove_key {
- u32 Length; /* Length */
- u32 KeyIndex;
- unsigned char BSSID[ETH_ALEN];
-};
-
struct ndis_802_11_wep {
u32 Length; /* Length of this structure */
u32 KeyIndex; /* 0 is the per-client key,
@@ -165,12 +135,6 @@ struct ndis_802_11_wep {
u8 KeyMaterial[16];/* variable len depending on above field */
};
-struct ndis_802_11_auth_req {
- u32 Length; /* Length of structure */
- unsigned char Bssid[ETH_ALEN];
- u32 Flags;
-};
-
enum ndis_802_11_status_type {
Ndis802_11StatusType_Authentication,
Ndis802_11StatusType_MediaStreamMode,
@@ -179,10 +143,6 @@ enum ndis_802_11_status_type {
* an upper bound */
};
-struct ndis_802_11_status_ind {
- enum ndis_802_11_status_type StatusType;
-};
-
/* mask for authentication/integrity fields */
#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f
#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01
@@ -193,21 +153,6 @@ struct ndis_802_11_status_ind {
/* MIC check time, 60 seconds. */
#define MIC_CHECK_TIME 60000000
-struct ndis_802_11_auth_evt {
- struct ndis_802_11_status_ind Status;
- struct ndis_802_11_auth_req Request[1];
-};
-
-struct ndis_802_11_test {
- u32 Length;
- u32 Type;
- union {
- struct ndis_802_11_auth_evt AuthenticationEvent;
- NDIS_802_11_RSSI RssiTrigger;
- } tt;
-};
-
-
#ifndef Ndis802_11APMode
#define Ndis802_11APMode (Ndis802_11InfrastructureMax+1)
#endif
@@ -297,32 +242,4 @@ enum UAPSD_MAX_SP {
#define NUM_PRE_AUTH_KEY 16
#define NUM_PMKID_CACHE NUM_PRE_AUTH_KEY
-/*
-* WPA2
-*/
-
-struct pmkid_candidate {
- unsigned char BSSID[ETH_ALEN];
- u32 Flags;
-};
-
-struct ndis_802_11_pmkid_list {
- u32 Version; /* Version of the structure */
- u32 NumCandidates; /* No. of pmkid candidates */
- struct pmkid_candidate CandidateList[1];
-};
-
-struct ndis_802_11_auth_encrypt {
- enum ndis_802_11_auth_mode AuthModeSupported;
- enum ndis_802_11_wep_status EncryptStatusSupported;
-};
-
-struct ndis_802_11_cap {
- u32 Length;
- u32 Version;
- u32 NoOfPMKIDs;
- u32 NoOfAuthEncryptPairsSupported;
- struct ndis_802_11_auth_encrypt AuthenticationEncryptionSupported[1];
-};
-
#endif /* ifndef WLAN_BSSDEF_H_ */
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
index 5672f014cc46..4de9dbc93380 100644
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -132,12 +132,15 @@ static char *translate_scan(struct adapter *padapter,
p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-12);
if (p && ht_ielen > 0) {
- struct rtw_ieee80211_ht_cap *pht_capie;
+ struct ieee80211_ht_cap *pht_capie;
ht_cap = true;
- pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
- memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
- bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
- short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
+ pht_capie = (struct ieee80211_ht_cap *)(p + 2);
+ memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2);
+ bw_40MHz = !!(le16_to_cpu(pht_capie->cap_info) &
+ IEEE80211_HT_CAP_SUP_WIDTH);
+ short_GI = !!(le16_to_cpu(pht_capie->cap_info) &
+ (IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_SGI_40));
}
/* Add the protocol name */
@@ -400,7 +403,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
wep_key_len = wep_key_len <= 5 ? 5 : 13;
wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial);
pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len);
- if (pwep == NULL) {
+ if (!pwep) {
RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, (" wpa_set_encryption: pwep allocate fail !!!\n"));
goto exit;
}
@@ -441,7 +444,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE)) { /* sta mode */
psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
- if (psta == NULL) {
+ if (!psta) {
;
} else {
if (strcmp(param->u.crypt.alg, "none") != 0)
@@ -476,7 +479,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
}
}
pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
- if (pbcmc_sta == NULL) {
+ if (!pbcmc_sta) {
;
} else {
/* Jeff: don't disable ieee8021x_blocked while clearing key */
@@ -502,9 +505,9 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie
int group_cipher = 0, pairwise_cipher = 0;
int ret = 0;
- if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {
+ if ((ielen > MAX_WPA_IE_LEN) || (!pie)) {
_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
- if (pie == NULL)
+ if (!pie)
return ret;
else
return -EINVAL;
@@ -512,7 +515,7 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie
if (ielen) {
buf = kmemdup(pie, ielen, GFP_KERNEL);
- if (buf == NULL) {
+ if (!buf) {
ret = -ENOMEM;
goto exit;
}
@@ -1049,7 +1052,7 @@ static int rtw_wx_set_mlme(struct net_device *dev,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct iw_mlme *mlme = (struct iw_mlme *)extra;
- if (mlme == NULL)
+ if (!mlme)
return -1;
DBG_88E("%s\n", __func__);
@@ -1896,7 +1899,7 @@ static int rtw_wx_set_enc_ext(struct net_device *dev,
param_len = sizeof(struct ieee_param) + pext->key_len;
param = (struct ieee_param *)rtw_malloc(param_len);
- if (param == NULL)
+ if (!param)
return -1;
memset(param, 0, param_len);
@@ -2061,7 +2064,7 @@ static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
}
param = (struct ieee_param *)rtw_malloc(p->length);
- if (param == NULL) {
+ if (!param) {
ret = -ENOMEM;
goto out;
}
@@ -2254,13 +2257,13 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
}
}
- if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
+ if (strcmp(param->u.crypt.alg, "none") == 0 && (!psta)) {
/* todo:clear default encryption keys */
DBG_88E("clear default encryption keys, keyid =%d\n", param->u.crypt.idx);
goto exit;
}
- if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
+ if (strcmp(param->u.crypt.alg, "WEP") == 0 && (!psta)) {
DBG_88E("r871x_set_encryption, crypt.alg = WEP\n");
wep_key_idx = param->u.crypt.idx;
wep_key_len = param->u.crypt.key_len;
@@ -2274,7 +2277,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
wep_key_len = wep_key_len <= 5 ? 5 : 13;
wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial);
pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len);
- if (pwep == NULL) {
+ if (!pwep) {
DBG_88E(" r871x_set_encryption: pwep allocate fail !!!\n");
goto exit;
}
@@ -2528,7 +2531,8 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
if (WLAN_STA_HT&flags) {
psta->htpriv.ht_option = true;
psta->qos_option = 1;
- memcpy((void *)&psta->htpriv.ht_cap, (void *)&param->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
+ memcpy(&psta->htpriv.ht_cap, &param->u.add_sta.ht_cap,
+ sizeof(struct ieee80211_ht_cap));
} else {
psta->htpriv.ht_option = false;
}
@@ -2624,7 +2628,8 @@ static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *par
(psta->ht_20mhz_set << 5));
psta_data->tx_supp_rates_len = psta->bssratelen;
memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
- memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
+ memcpy(&psta_data->ht_cap,
+ &psta->htpriv.ht_cap, sizeof(struct ieee80211_ht_cap));
psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
psta_data->rx_bytes = psta->sta_stats.rx_bytes;
psta_data->rx_drops = psta->sta_stats.rx_drops;
@@ -2699,7 +2704,7 @@ static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param,
if (ie_len > 0) {
pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
pmlmepriv->wps_beacon_ie_len = ie_len;
- if (pmlmepriv->wps_beacon_ie == NULL) {
+ if (!pmlmepriv->wps_beacon_ie) {
DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
return -EINVAL;
}
@@ -2734,7 +2739,7 @@ static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *par
if (ie_len > 0) {
pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
pmlmepriv->wps_probe_resp_ie_len = ie_len;
- if (pmlmepriv->wps_probe_resp_ie == NULL) {
+ if (!pmlmepriv->wps_probe_resp_ie) {
DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
return -EINVAL;
}
@@ -2764,7 +2769,7 @@ static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *par
if (ie_len > 0) {
pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
pmlmepriv->wps_assoc_resp_ie_len = ie_len;
- if (pmlmepriv->wps_assoc_resp_ie == NULL) {
+ if (!pmlmepriv->wps_assoc_resp_ie) {
DBG_88E("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
return -EINVAL;
}
@@ -2866,7 +2871,7 @@ static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
}
param = (struct ieee_param *)rtw_malloc(p->length);
- if (param == NULL) {
+ if (!param) {
ret = -ENOMEM;
goto out;
}
@@ -2976,7 +2981,7 @@ static int rtw_wx_set_priv(struct net_device *dev,
pmlmepriv->wps_probe_req_ie = NULL;
pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
- if (pmlmepriv->wps_probe_req_ie == NULL) {
+ if (!pmlmepriv->wps_probe_req_ie) {
pr_info("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
ret = -EINVAL;
goto FREE_EXT;
diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c
index ae2caff030f1..40691f1ec507 100644
--- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c
+++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c
@@ -23,8 +23,6 @@
#include <rtw_ioctl.h>
#include <rtl8188e_hal.h>
-#include <usb_hal.h>
-
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek Wireless Lan Driver");
MODULE_AUTHOR("Realtek Semiconductor Corp.");
@@ -33,11 +31,7 @@ MODULE_VERSION(DRIVERVERSION);
#define RTW_NOTCH_FILTER 0 /* 0:Disable, 1:Enable, */
/* module param defaults */
-static int rtw_chip_version;
-static int rtw_rfintfs = HWPI;
-static int rtw_lbkmode;/* RTL8712_AIR_TRX; */
/* Ndis802_11Infrastructure; infra, ad-hoc, auto */
-static int rtw_network_mode = Ndis802_11IBSS;
static int rtw_channel = 1;/* ad-hoc support requirement */
static int rtw_wireless_mode = WIRELESS_11BG_24N;
static int rtw_vrtl_carrier_sense = AUTO_VCS;
@@ -45,9 +39,6 @@ static int rtw_vcs_type = RTS_CTS;/* */
static int rtw_rts_thresh = 2347;/* */
static int rtw_frag_thresh = 2346;/* */
static int rtw_preamble = PREAMBLE_LONG;/* long, short, auto */
-static int rtw_scan_mode = 1;/* active, passive */
-static int rtw_adhoc_tx_pwr = 1;
-static int rtw_soft_ap;
static int rtw_power_mgnt = 1;
static int rtw_ips_mode = IPS_NORMAL;
@@ -57,11 +48,6 @@ module_param(rtw_ips_mode, int, 0644);
MODULE_PARM_DESC(rtw_ips_mode, "The default IPS mode");
static int rtw_debug = 1;
-static int rtw_radio_enable = 1;
-static int rtw_long_retry_lmt = 7;
-static int rtw_short_retry_lmt = 7;
-static int rtw_busy_thresh = 40;
-static int rtw_ack_policy = NORMAL_ACK;
static int rtw_software_encrypt;
static int rtw_software_decrypt;
@@ -70,11 +56,6 @@ static int rtw_acm_method;/* 0:By SW 1:By HW. */
static int rtw_wmm_enable = 1;/* default is set to enable the wmm. */
static int rtw_uapsd_enable;
-static int rtw_uapsd_max_sp = NO_LIMIT;
-static int rtw_uapsd_acbk_en;
-static int rtw_uapsd_acbe_en;
-static int rtw_uapsd_acvi_en;
-static int rtw_uapsd_acvo_en;
static int rtw_ht_enable = 1;
/* 0 :disable, bit(0): enable 2.4g, bit(1): enable 5g */
@@ -89,11 +70,6 @@ static int rtw_ampdu_enable = 1;/* for enable tx_ampdu */
static int rtw_rx_stbc = 1;
static int rtw_ampdu_amsdu;/* 0: disabled, 1:enabled, 2:auto */
-/* Use 2 path Tx to transmit MCS0~7 and legacy mode */
-static int rtw_lowrate_two_xmit = 1;
-
-static int rtw_rf_config = RF_819X_MAX_TYPE; /* auto */
-static int rtw_low_power;
static int rtw_wifi_spec;
static int rtw_channel_plan = RT_CHANNEL_DOMAIN_MAX;
@@ -111,10 +87,6 @@ static int rtw_enusbss;/* 0:disable, 1:enable */
static int rtw_hwpdn_mode = 2;/* 0:disable, 1:enable, 2: by EFUSE config */
-static int rtw_hwpwrp_detect; /* HW power ping detect 0:disable , 1:enable */
-
-static int rtw_hw_wps_pbc = 1;
-
int rtw_mc2u_disable;
static int rtw_80211d;
@@ -132,32 +104,22 @@ char *rtw_initmac;
module_param(rtw_initmac, charp, 0644);
module_param(rtw_channel_plan, int, 0644);
-module_param(rtw_chip_version, int, 0644);
-module_param(rtw_rfintfs, int, 0644);
-module_param(rtw_lbkmode, int, 0644);
-module_param(rtw_network_mode, int, 0644);
module_param(rtw_channel, int, 0644);
module_param(rtw_wmm_enable, int, 0644);
module_param(rtw_vrtl_carrier_sense, int, 0644);
module_param(rtw_vcs_type, int, 0644);
-module_param(rtw_busy_thresh, int, 0644);
module_param(rtw_ht_enable, int, 0644);
module_param(rtw_cbw40_enable, int, 0644);
module_param(rtw_ampdu_enable, int, 0644);
module_param(rtw_rx_stbc, int, 0644);
module_param(rtw_ampdu_amsdu, int, 0644);
-module_param(rtw_lowrate_two_xmit, int, 0644);
-module_param(rtw_rf_config, int, 0644);
module_param(rtw_power_mgnt, int, 0644);
module_param(rtw_smart_ps, int, 0644);
-module_param(rtw_low_power, int, 0644);
module_param(rtw_wifi_spec, int, 0644);
module_param(rtw_antdiv_cfg, int, 0644);
module_param(rtw_antdiv_type, int, 0644);
module_param(rtw_enusbss, int, 0644);
module_param(rtw_hwpdn_mode, int, 0644);
-module_param(rtw_hwpwrp_detect, int, 0644);
-module_param(rtw_hw_wps_pbc, int, 0644);
static uint rtw_max_roaming_times = 2;
module_param(rtw_max_roaming_times, uint, 0644);
@@ -185,361 +147,11 @@ MODULE_PARM_DESC(monitor_enable, "Enable monitor inferface (default: false)");
static int netdev_open(struct net_device *pnetdev);
static int netdev_close(struct net_device *pnetdev);
-/* dummy routines */
-void rtw_proc_remove_one(struct net_device *dev)
-{
-}
-
-static void rtw_proc_init_one(struct net_device *dev)
-{
-}
-
-#if 0 /* TODO: Convert these to /sys */
-static void rtw_proc_init_one(struct net_device *dev)
-{
- struct proc_dir_entry *dir_dev = NULL;
- struct proc_dir_entry *entry = NULL;
- struct adapter *padapter = rtw_netdev_priv(dev);
- u8 rf_type;
-
- if (rtw_proc == NULL) {
- memcpy(rtw_proc_name, DRV_NAME, sizeof(DRV_NAME));
-
- rtw_proc = create_proc_entry(rtw_proc_name, S_IFDIR,
- init_net.proc_net);
- if (rtw_proc == NULL) {
- DBG_88E(KERN_ERR "Unable to create rtw_proc directory\n");
- return;
- }
-
- entry = create_proc_read_entry("ver_info", S_IFREG | S_IRUGO,
- rtw_proc, proc_get_drv_version,
- dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
- }
-
- if (padapter->dir_dev == NULL) {
- padapter->dir_dev = create_proc_entry(dev->name,
- S_IFDIR | S_IRUGO | S_IXUGO,
- rtw_proc);
- dir_dev = padapter->dir_dev;
- if (dir_dev == NULL) {
- if (rtw_proc_cnt == 0 && rtw_proc) {
- remove_proc_entry(rtw_proc_name, init_net.proc_net);
- rtw_proc = NULL;
- }
-
- pr_info("Unable to create dir_dev directory\n");
- return;
- }
- } else {
- return;
- }
-
- rtw_proc_cnt++;
-
- entry = create_proc_read_entry("write_reg", S_IFREG | S_IRUGO,
- dir_dev, proc_get_write_reg, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
- entry->write_proc = proc_set_write_reg;
-
- entry = create_proc_read_entry("read_reg", S_IFREG | S_IRUGO,
- dir_dev, proc_get_read_reg, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
- entry->write_proc = proc_set_read_reg;
-
-
- entry = create_proc_read_entry("fwstate", S_IFREG | S_IRUGO,
- dir_dev, proc_get_fwstate, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("sec_info", S_IFREG | S_IRUGO,
- dir_dev, proc_get_sec_info, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("mlmext_state", S_IFREG | S_IRUGO,
- dir_dev, proc_get_mlmext_state, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("qos_option", S_IFREG | S_IRUGO,
- dir_dev, proc_get_qos_option, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("ht_option", S_IFREG | S_IRUGO,
- dir_dev, proc_get_ht_option, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("rf_info", S_IFREG | S_IRUGO,
- dir_dev, proc_get_rf_info, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("ap_info", S_IFREG | S_IRUGO,
- dir_dev, proc_get_ap_info, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("adapter_state", S_IFREG | S_IRUGO,
- dir_dev, proc_getstruct adapter_state, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("trx_info", S_IFREG | S_IRUGO,
- dir_dev, proc_get_trx_info, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("mac_reg_dump1", S_IFREG | S_IRUGO,
- dir_dev, proc_get_mac_reg_dump1, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("mac_reg_dump2", S_IFREG | S_IRUGO,
- dir_dev, proc_get_mac_reg_dump2, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("mac_reg_dump3", S_IFREG | S_IRUGO,
- dir_dev, proc_get_mac_reg_dump3, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("bb_reg_dump1", S_IFREG | S_IRUGO,
- dir_dev, proc_get_bb_reg_dump1, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("bb_reg_dump2", S_IFREG | S_IRUGO,
- dir_dev, proc_get_bb_reg_dump2, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("bb_reg_dump3", S_IFREG | S_IRUGO,
- dir_dev, proc_get_bb_reg_dump3, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("rf_reg_dump1", S_IFREG | S_IRUGO,
- dir_dev, proc_get_rf_reg_dump1, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("rf_reg_dump2", S_IFREG | S_IRUGO,
- dir_dev, proc_get_rf_reg_dump2, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
- if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type)) {
- entry = create_proc_read_entry("rf_reg_dump3",
- S_IFREG | S_IRUGO, dir_dev,
- proc_get_rf_reg_dump3, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("rf_reg_dump4",
- S_IFREG | S_IRUGO, dir_dev,
- proc_get_rf_reg_dump4, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
- }
-
-#ifdef CONFIG_88EU_AP_MODE
-
- entry = create_proc_read_entry("all_sta_info", S_IFREG | S_IRUGO,
- dir_dev, proc_get_all_sta_info, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-#endif
-
- entry = create_proc_read_entry("best_channel", S_IFREG | S_IRUGO,
- dir_dev, proc_get_best_channel, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
-
- entry = create_proc_read_entry("rx_signal", S_IFREG | S_IRUGO,
- dir_dev, proc_get_rx_signal, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
- entry->write_proc = proc_set_rx_signal;
- entry = create_proc_read_entry("ht_enable", S_IFREG | S_IRUGO,
- dir_dev, proc_get_ht_enable, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
- entry->write_proc = proc_set_ht_enable;
-
- entry = create_proc_read_entry("cbw40_enable", S_IFREG | S_IRUGO,
- dir_dev, proc_get_cbw40_enable, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
- entry->write_proc = proc_set_cbw40_enable;
-
- entry = create_proc_read_entry("ampdu_enable", S_IFREG | S_IRUGO,
- dir_dev, proc_get_ampdu_enable, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
- entry->write_proc = proc_set_ampdu_enable;
-
- entry = create_proc_read_entry("rx_stbc", S_IFREG | S_IRUGO,
- dir_dev, proc_get_rx_stbc, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
- entry->write_proc = proc_set_rx_stbc;
-
- entry = create_proc_read_entry("path_rssi", S_IFREG | S_IRUGO,
- dir_dev, proc_get_two_path_rssi, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
- entry = create_proc_read_entry("rssi_disp", S_IFREG | S_IRUGO,
- dir_dev, proc_get_rssi_disp, dev);
- if (!entry) {
- pr_info("Unable to create_proc_read_entry!\n");
- return;
- }
- entry->write_proc = proc_set_rssi_disp;
-}
-
-void rtw_proc_remove_one(struct net_device *dev)
-{
- struct proc_dir_entry *dir_dev = NULL;
- struct adapter *padapter = rtw_netdev_priv(dev);
- u8 rf_type;
-
- dir_dev = padapter->dir_dev;
- padapter->dir_dev = NULL;
-
- if (dir_dev) {
- remove_proc_entry("write_reg", dir_dev);
- remove_proc_entry("read_reg", dir_dev);
- remove_proc_entry("fwstate", dir_dev);
- remove_proc_entry("sec_info", dir_dev);
- remove_proc_entry("mlmext_state", dir_dev);
- remove_proc_entry("qos_option", dir_dev);
- remove_proc_entry("ht_option", dir_dev);
- remove_proc_entry("rf_info", dir_dev);
- remove_proc_entry("ap_info", dir_dev);
- remove_proc_entry("adapter_state", dir_dev);
- remove_proc_entry("trx_info", dir_dev);
- remove_proc_entry("mac_reg_dump1", dir_dev);
- remove_proc_entry("mac_reg_dump2", dir_dev);
- remove_proc_entry("mac_reg_dump3", dir_dev);
- remove_proc_entry("bb_reg_dump1", dir_dev);
- remove_proc_entry("bb_reg_dump2", dir_dev);
- remove_proc_entry("bb_reg_dump3", dir_dev);
- remove_proc_entry("rf_reg_dump1", dir_dev);
- remove_proc_entry("rf_reg_dump2", dir_dev);
- rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
- if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type)) {
- remove_proc_entry("rf_reg_dump3", dir_dev);
- remove_proc_entry("rf_reg_dump4", dir_dev);
- }
-#ifdef CONFIG_88EU_AP_MODE
- remove_proc_entry("all_sta_info", dir_dev);
-#endif
-
- remove_proc_entry("best_channel", dir_dev);
- remove_proc_entry("rx_signal", dir_dev);
- remove_proc_entry("cbw40_enable", dir_dev);
- remove_proc_entry("ht_enable", dir_dev);
- remove_proc_entry("ampdu_enable", dir_dev);
- remove_proc_entry("rx_stbc", dir_dev);
- remove_proc_entry("path_rssi", dir_dev);
- remove_proc_entry("rssi_disp", dir_dev);
- remove_proc_entry(dev->name, rtw_proc);
- dir_dev = NULL;
- } else {
- return;
- }
- rtw_proc_cnt--;
-
- if (rtw_proc_cnt == 0) {
- if (rtw_proc) {
- remove_proc_entry("ver_info", rtw_proc);
-
- remove_proc_entry(rtw_proc_name, init_net.proc_net);
- rtw_proc = NULL;
- }
- }
-}
-#endif
-
static void loadparam(struct adapter *padapter, struct net_device *pnetdev)
{
struct registry_priv *registry_par = &padapter->registrypriv;
GlobalDebugLevel = rtw_debug;
- registry_par->chip_version = (u8)rtw_chip_version;
- registry_par->rfintfs = (u8)rtw_rfintfs;
- registry_par->lbkmode = (u8)rtw_lbkmode;
- registry_par->network_mode = (u8)rtw_network_mode;
memcpy(registry_par->ssid.Ssid, "ANY", 3);
registry_par->ssid.SsidLength = 3;
@@ -551,17 +163,9 @@ static void loadparam(struct adapter *padapter, struct net_device *pnetdev)
registry_par->rts_thresh = (u16)rtw_rts_thresh;
registry_par->frag_thresh = (u16)rtw_frag_thresh;
registry_par->preamble = (u8)rtw_preamble;
- registry_par->scan_mode = (u8)rtw_scan_mode;
- registry_par->adhoc_tx_pwr = (u8)rtw_adhoc_tx_pwr;
- registry_par->soft_ap = (u8)rtw_soft_ap;
registry_par->smart_ps = (u8)rtw_smart_ps;
registry_par->power_mgnt = (u8)rtw_power_mgnt;
registry_par->ips_mode = (u8)rtw_ips_mode;
- registry_par->radio_enable = (u8)rtw_radio_enable;
- registry_par->long_retry_lmt = (u8)rtw_long_retry_lmt;
- registry_par->short_retry_lmt = (u8)rtw_short_retry_lmt;
- registry_par->busy_thresh = (u16)rtw_busy_thresh;
- registry_par->ack_policy = (u8)rtw_ack_policy;
registry_par->mp_mode = 0;
registry_par->software_encrypt = (u8)rtw_software_encrypt;
registry_par->software_decrypt = (u8)rtw_software_decrypt;
@@ -570,28 +174,18 @@ static void loadparam(struct adapter *padapter, struct net_device *pnetdev)
/* UAPSD */
registry_par->wmm_enable = (u8)rtw_wmm_enable;
registry_par->uapsd_enable = (u8)rtw_uapsd_enable;
- registry_par->uapsd_max_sp = (u8)rtw_uapsd_max_sp;
- registry_par->uapsd_acbk_en = (u8)rtw_uapsd_acbk_en;
- registry_par->uapsd_acbe_en = (u8)rtw_uapsd_acbe_en;
- registry_par->uapsd_acvi_en = (u8)rtw_uapsd_acvi_en;
- registry_par->uapsd_acvo_en = (u8)rtw_uapsd_acvo_en;
registry_par->ht_enable = (u8)rtw_ht_enable;
registry_par->cbw40_enable = (u8)rtw_cbw40_enable;
registry_par->ampdu_enable = (u8)rtw_ampdu_enable;
registry_par->rx_stbc = (u8)rtw_rx_stbc;
registry_par->ampdu_amsdu = (u8)rtw_ampdu_amsdu;
- registry_par->lowrate_two_xmit = (u8)rtw_lowrate_two_xmit;
- registry_par->rf_config = (u8)rtw_rf_config;
- registry_par->low_power = (u8)rtw_low_power;
registry_par->wifi_spec = (u8)rtw_wifi_spec;
registry_par->channel_plan = (u8)rtw_channel_plan;
registry_par->accept_addba_req = true;
registry_par->antdiv_cfg = (u8)rtw_antdiv_cfg;
registry_par->antdiv_type = (u8)rtw_antdiv_type;
registry_par->hwpdn_mode = (u8)rtw_hwpdn_mode;
- registry_par->hwpwrp_detect = (u8)rtw_hwpwrp_detect;
- registry_par->hw_wps_pbc = (u8)rtw_hw_wps_pbc;
registry_par->max_roaming_times = (u8)rtw_max_roaming_times;
@@ -732,7 +326,7 @@ struct net_device *rtw_init_netdev(struct adapter *old_padapter)
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+init_net_dev\n"));
if (old_padapter != NULL)
- pnetdev = rtw_alloc_etherdev_with_old_priv(sizeof(struct adapter), (void *)old_padapter);
+ pnetdev = rtw_alloc_etherdev_with_old_priv((void *)old_padapter);
if (!pnetdev)
return NULL;
@@ -762,7 +356,7 @@ static int rtw_start_drv_threads(struct adapter *padapter)
err = PTR_ERR(padapter->cmdThread);
else
/* wait for cmd_thread to run */
- _rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema);
+ wait_for_completion_interruptible(&padapter->cmdpriv.terminate_cmdthread_comp);
return err;
}
@@ -772,9 +366,9 @@ void rtw_stop_drv_threads(struct adapter *padapter)
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_stop_drv_threads\n"));
/* Below is to terminate rtw_cmd_thread & event_thread... */
- up(&padapter->cmdpriv.cmd_queue_sema);
+ complete(&padapter->cmdpriv.cmd_queue_comp);
if (padapter->cmdThread)
- _rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema);
+ wait_for_completion_interruptible(&padapter->cmdpriv.terminate_cmdthread_comp);
}
@@ -821,7 +415,6 @@ static u8 rtw_init_default_value(struct adapter *padapter)
padapter->bReadPortCancel = false;
padapter->bWritePortCancel = false;
padapter->bRxRSSIDisplay = 0;
- padapter->bNotifyChannelChange = 0;
return _SUCCESS;
}
@@ -912,8 +505,6 @@ u8 rtw_init_drv_sw(struct adapter *padapter)
rtw_hal_sreset_init(padapter);
- spin_lock_init(&padapter->br_ext_lock);
-
exit:
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-rtw_init_drv_sw\n"));
@@ -961,12 +552,6 @@ u8 rtw_free_drv_sw(struct adapter *padapter)
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("<== rtw_free_drv_sw\n"));
- /* free the old_pnetdev */
- if (padapter->rereg_nd_name_priv.old_pnetdev) {
- free_netdev(padapter->rereg_nd_name_priv.old_pnetdev);
- padapter->rereg_nd_name_priv.old_pnetdev = NULL;
- }
-
mutex_destroy(&padapter->hw_init_mutex);
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-rtw_free_drv_sw\n"));
@@ -1013,7 +598,6 @@ static int _netdev_open(struct net_device *pnetdev)
}
if (padapter->intf_start)
padapter->intf_start(padapter);
- rtw_proc_init_one(pnetdev);
rtw_led_control(padapter, LED_CTL_NO_LINK);
diff --git a/drivers/staging/rtl8188eu/os_dep/osdep_service.c b/drivers/staging/rtl8188eu/os_dep/osdep_service.c
index 764250b4ba86..7cd2655f27fe 100644
--- a/drivers/staging/rtl8188eu/os_dep/osdep_service.c
+++ b/drivers/staging/rtl8188eu/os_dep/osdep_service.c
@@ -55,21 +55,13 @@ void *rtw_malloc2d(int h, int w, int size)
return a;
}
-u32 _rtw_down_sema(struct semaphore *sema)
-{
- if (down_interruptible(sema))
- return _FAIL;
- return _SUCCESS;
-}
-
void _rtw_init_queue(struct __queue *pqueue)
{
INIT_LIST_HEAD(&(pqueue->queue));
spin_lock_init(&(pqueue->lock));
}
-struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv,
- void *old_priv)
+struct net_device *rtw_alloc_etherdev_with_old_priv(void *old_priv)
{
struct net_device *pnetdev;
struct rtw_netdev_priv_indicator *pnpi;
@@ -80,7 +72,6 @@ struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv,
pnpi = netdev_priv(pnetdev);
pnpi->priv = old_priv;
- pnpi->sizeof_priv = sizeof_priv;
RETURN:
return pnetdev;
diff --git a/drivers/staging/rtl8188eu/os_dep/recv_linux.c b/drivers/staging/rtl8188eu/os_dep/recv_linux.c
index 0c44914ea3e6..103cdb4ed073 100644
--- a/drivers/staging/rtl8188eu/os_dep/recv_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/recv_linux.c
@@ -24,7 +24,6 @@
/* alloc os related resource in struct recv_frame */
void rtw_os_recv_resource_alloc(struct recv_frame *precvframe)
{
- precvframe->pkt_newalloc = NULL;
precvframe->pkt = NULL;
}
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
index 11d51a30170f..68e1e6bbe87f 100644
--- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
@@ -25,9 +25,10 @@
#include <osdep_intf.h>
#include <usb_ops_linux.h>
-#include <usb_hal.h>
#include <rtw_ioctl.h>
+#include "rtl8188e_hal.h"
+
#define USB_VENDER_ID_REALTEK 0x0bda
/* DID_USB_v916_20130116 */
@@ -79,9 +80,8 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces;
pdvobjpriv->InterfaceNumber = piface_desc->bInterfaceNumber;
- pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints;
- for (i = 0; i < pdvobjpriv->nr_endpoint; i++) {
+ for (i = 0; i < piface_desc->bNumEndpoints; i++) {
int ep_num;
pendp_desc = &phost_iface->endpoint[i].desc;
@@ -98,7 +98,6 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
ep_num;
pdvobjpriv->RtNumOutPipes++;
}
- pdvobjpriv->ep_num[i] = ep_num;
}
if (pusbd->speed == USB_SPEED_HIGH)
@@ -107,13 +106,6 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
pdvobjpriv->ishighspeed = false;
mutex_init(&pdvobjpriv->usb_vendor_req_mutex);
- pdvobjpriv->usb_vendor_req_buf = kzalloc(MAX_USB_IO_CTL_SIZE, GFP_KERNEL);
-
- if (!pdvobjpriv->usb_vendor_req_buf) {
- usb_set_intfdata(usb_intf, NULL);
- kfree(pdvobjpriv);
- return NULL;
- }
usb_get_dev(pusbd);
return pdvobjpriv;
@@ -141,7 +133,6 @@ static void usb_dvobj_deinit(struct usb_interface *usb_intf)
}
}
- kfree(dvobj->usb_vendor_req_buf);
mutex_destroy(&dvobj->usb_vendor_req_mutex);
kfree(dvobj);
}
@@ -238,7 +229,7 @@ static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message)
rtw_cancel_all_timer(padapter);
LeaveAllPowerSaveMode(padapter);
- _enter_pwrlock(&pwrpriv->lock);
+ mutex_lock(&pwrpriv->mutex_lock);
/* s1. */
if (pnetdev) {
netif_carrier_off(pnetdev);
@@ -267,7 +258,7 @@ static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message)
rtw_free_network_queue(padapter, true);
rtw_dev_unload(padapter);
- _exit_pwrlock(&pwrpriv->lock);
+ mutex_unlock(&pwrpriv->mutex_lock);
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
rtw_indicate_scan_done(padapter, 1);
@@ -298,18 +289,20 @@ static int rtw_resume_process(struct adapter *padapter)
goto exit;
}
- _enter_pwrlock(&pwrpriv->lock);
+ mutex_lock(&pwrpriv->mutex_lock);
rtw_reset_drv_sw(padapter);
pwrpriv->bkeepfwalive = false;
pr_debug("bkeepfwalive(%x)\n", pwrpriv->bkeepfwalive);
- if (pm_netdev_open(pnetdev, true) != 0)
+ if (pm_netdev_open(pnetdev, true) != 0) {
+ mutex_unlock(&pwrpriv->mutex_lock);
goto exit;
+ }
netif_device_attach(pnetdev);
netif_carrier_on(pnetdev);
- _exit_pwrlock(&pwrpriv->lock);
+ mutex_unlock(&pwrpriv->mutex_lock);
rtw_roaming(padapter, NULL);
@@ -369,8 +362,9 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
padapter->pmondev = pmondev;
}
- /* step 2. hook HalFunc, allocate HalData */
- hal_set_hal_ops(padapter);
+ padapter->HalData = kzalloc(sizeof(struct hal_data_8188e), GFP_KERNEL);
+ if (!padapter->HalData)
+ DBG_88E("cant not alloc memory for HAL DATA\n");
padapter->intf_start = &usb_intf_start;
padapter->intf_stop = &usb_intf_stop;
@@ -456,11 +450,9 @@ static void rtw_usb_if1_deinit(struct adapter *if1)
free_mlme_ap_info(if1);
#endif
- if (pnetdev) {
- /* will call netdev_close() */
- unregister_netdev(pnetdev);
- rtw_proc_remove_one(pnetdev);
- }
+ if (pnetdev)
+ unregister_netdev(pnetdev); /* will call netdev_close() */
+
rtl88eu_mon_deinit(if1->pmondev);
rtw_cancel_all_timer(if1);
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
index ce1e1a135f1b..d0d591501b73 100644
--- a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
@@ -20,7 +20,7 @@
static void interrupt_handler_8188eu(struct adapter *adapt, u16 pkt_len, u8 *pbuf)
{
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *haldata = adapt->HalData;
if (pkt_len != INTERRUPT_MSG_FORMAT_LEN) {
DBG_88E("%s Invalid interrupt content length (%d)!\n", __func__, pkt_len);
@@ -48,7 +48,7 @@ static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb)
struct sk_buff *pkt_copy = NULL;
struct recv_frame *precvframe = NULL;
struct rx_pkt_attrib *pattrib = NULL;
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ struct hal_data_8188e *haldata = adapt->HalData;
struct recv_priv *precvpriv = &adapt->recvpriv;
struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue;
@@ -251,7 +251,7 @@ static int usbctrl_vendorreq(struct adapter *adapt, u8 request, u16 value, u16 i
}
/* Acquire IO memory for vendorreq */
- pIo_buf = dvobjpriv->usb_vendor_req_buf;
+ pIo_buf = kmalloc(MAX_USB_IO_CTL_SIZE, GFP_ATOMIC);
if (pIo_buf == NULL) {
DBG_88E("[%s] pIo_buf == NULL\n", __func__);
@@ -285,8 +285,7 @@ static int usbctrl_vendorreq(struct adapter *adapt, u8 request, u16 value, u16 i
if (status == (-ESHUTDOWN) || status == -ENODEV) {
adapt->bSurpriseRemoved = true;
} else {
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
- haldata->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL;
+ adapt->HalData->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL;
}
} else { /* status != len && status >= 0 */
if (status > 0) {
@@ -303,6 +302,8 @@ static int usbctrl_vendorreq(struct adapter *adapt, u8 request, u16 value, u16 i
if ((value >= FW_8188E_START_ADDRESS && value <= FW_8188E_END_ADDRESS) || status == len)
break;
}
+ kfree(pIo_buf);
+
release_mutex:
mutex_unlock(&dvobjpriv->usb_vendor_req_mutex);
exit:
@@ -434,10 +435,7 @@ static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
break;
case -EPROTO:
case -EOVERFLOW:
- {
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
- haldata->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL;
- }
+ adapt->HalData->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL;
precvbuf->reuse = true;
usb_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
break;
@@ -525,7 +523,7 @@ u32 usb_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *rmem)
return ret;
}
-void usb_read_port_cancel(struct adapter *padapter)
+void rtw_hal_inirp_deinit(struct adapter *padapter)
{
int i;
struct recv_buf *precvbuf;
@@ -691,7 +689,7 @@ check_completion:
tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
}
-u32 usb_write_port(struct adapter *padapter, u32 addr, u32 cnt, u8 *wmem)
+u32 usb_write_port(struct adapter *padapter, u32 addr, u32 cnt, struct xmit_buf *xmitbuf)
{
unsigned long irqL;
unsigned int pipe;
@@ -700,8 +698,7 @@ u32 usb_write_port(struct adapter *padapter, u32 addr, u32 cnt, u8 *wmem)
struct urb *purb = NULL;
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem;
- struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
+ struct xmit_frame *pxmitframe = (struct xmit_frame *)xmitbuf->priv_data;
struct usb_device *pusbd = pdvobj->pusbdev;
@@ -711,7 +708,7 @@ u32 usb_write_port(struct adapter *padapter, u32 addr, u32 cnt, u8 *wmem)
(padapter->pwrctrlpriv.pnp_bstop_trx)) {
RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
("usb_write_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
- rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY);
+ rtw_sctx_done_err(&xmitbuf->sctx, RTW_SCTX_DONE_TX_DENY);
goto exit;
}
@@ -720,44 +717,44 @@ u32 usb_write_port(struct adapter *padapter, u32 addr, u32 cnt, u8 *wmem)
switch (addr) {
case VO_QUEUE_INX:
pxmitpriv->voq_cnt++;
- pxmitbuf->flags = VO_QUEUE_INX;
+ xmitbuf->flags = VO_QUEUE_INX;
break;
case VI_QUEUE_INX:
pxmitpriv->viq_cnt++;
- pxmitbuf->flags = VI_QUEUE_INX;
+ xmitbuf->flags = VI_QUEUE_INX;
break;
case BE_QUEUE_INX:
pxmitpriv->beq_cnt++;
- pxmitbuf->flags = BE_QUEUE_INX;
+ xmitbuf->flags = BE_QUEUE_INX;
break;
case BK_QUEUE_INX:
pxmitpriv->bkq_cnt++;
- pxmitbuf->flags = BK_QUEUE_INX;
+ xmitbuf->flags = BK_QUEUE_INX;
break;
case HIGH_QUEUE_INX:
- pxmitbuf->flags = HIGH_QUEUE_INX;
+ xmitbuf->flags = HIGH_QUEUE_INX;
break;
default:
- pxmitbuf->flags = MGT_QUEUE_INX;
+ xmitbuf->flags = MGT_QUEUE_INX;
break;
}
spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
- purb = pxmitbuf->pxmit_urb[0];
+ purb = xmitbuf->pxmit_urb[0];
/* translate DMA FIFO addr to pipehandle */
pipe = ffaddr2pipehdl(pdvobj, addr);
usb_fill_bulk_urb(purb, pusbd, pipe,
- pxmitframe->buf_addr, /* pxmitbuf->pbuf */
+ pxmitframe->buf_addr, /* xmitbuf->pbuf */
cnt,
usb_write_port_complete,
- pxmitbuf);/* context is pxmitbuf */
+ xmitbuf);/* context is xmitbuf */
status = usb_submit_urb(purb, GFP_ATOMIC);
if (status) {
- rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR);
+ rtw_sctx_done_err(&xmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR);
DBG_88E("usb_write_port, status =%d\n", status);
RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_write_port(): usb_submit_urb, status =%x\n", status));
@@ -779,7 +776,7 @@ u32 usb_write_port(struct adapter *padapter, u32 addr, u32 cnt, u8 *wmem)
exit:
if (ret != _SUCCESS)
- rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
+ rtw_free_xmitbuf(pxmitpriv, xmitbuf);
return ret;
}
@@ -846,7 +843,7 @@ void rtl8188eu_xmit_tasklet(void *priv)
break;
}
- ret = rtl8188eu_xmitframe_complete(adapt, pxmitpriv, NULL);
+ ret = rtl8188eu_xmitframe_complete(adapt, pxmitpriv);
if (!ret)
break;
diff --git a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c
index 221e2750652e..4b1b04e00715 100644
--- a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c
@@ -72,7 +72,7 @@ int rtw_os_xmit_resource_alloc(struct adapter *padapter, struct xmit_buf *pxmitb
if (pxmitbuf->pallocated_buf == NULL)
return _FAIL;
- pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ);
+ pxmitbuf->pbuf = PTR_ALIGN(pxmitbuf->pallocated_buf, XMITBUF_ALIGN_SZ);
pxmitbuf->dma_transfer_addr = 0;
for (i = 0; i < 8; i++) {
diff --git a/drivers/staging/rtl8192e/dot11d.c b/drivers/staging/rtl8192e/dot11d.c
index 4d8fb4158f6b..25725b158eca 100644
--- a/drivers/staging/rtl8192e/dot11d.c
+++ b/drivers/staging/rtl8192e/dot11d.c
@@ -51,9 +51,8 @@ void dot11d_init(struct rtllib_device *ieee)
pDot11dInfo->State = DOT11D_STATE_NONE;
pDot11dInfo->CountryIeLen = 0;
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
+ memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER + 1);
RESET_CIE_WATCHDOG(ieee);
-
}
EXPORT_SYMBOL(dot11d_init);
@@ -99,14 +98,13 @@ void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee)
}
EXPORT_SYMBOL(Dot11d_Channelmap);
-
void Dot11d_Reset(struct rtllib_device *ieee)
{
struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee);
u32 i;
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
+ memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER + 1);
+ memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER + 1);
for (i = 1; i <= 11; i++)
(pDot11dInfo->channel_map)[i] = 1;
for (i = 12; i <= 14; i++)
@@ -123,8 +121,8 @@ void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr,
u8 i, j, NumTriples, MaxChnlNum;
struct chnl_txpow_triple *pTriple;
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
+ memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER + 1);
+ memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER + 1);
MaxChnlNum = 0;
NumTriples = (CoutryIeLen - 3) / 3;
pTriple = (struct chnl_txpow_triple *)(pCoutryIe + 3);
diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h
index 735a199ebdcf..aac395f26652 100644
--- a/drivers/staging/rtl8192e/dot11d.h
+++ b/drivers/staging/rtl8192e/dot11d.h
@@ -47,8 +47,8 @@ struct rt_dot11d_info {
u8 CountryIeSrcAddr[6];
u8 CountryIeWatchdog;
- u8 channel_map[MAX_CHANNEL_NUMBER+1];
- u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
+ u8 channel_map[MAX_CHANNEL_NUMBER + 1];
+ u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER + 1];
enum dot11d_state State;
};
@@ -78,6 +78,7 @@ static inline void RESET_CIE_WATCHDOG(struct rtllib_device *__pIeeeDev)
{
GET_CIE_WATCHDOG(__pIeeeDev) = 0;
}
+
#define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev))
void dot11d_init(struct rtllib_device *dev);
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
index ba64a4f1b3a8..8d6bca61e7aa 100644
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
+++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
@@ -1487,8 +1487,8 @@ static void _rtl92e_query_rxphystatus(
struct phy_ofdm_rx_status_rxsc_sgien_exintfflag *prxsc;
u8 *prxpkt;
u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
- char rx_pwr[4], rx_pwr_all = 0;
- char rx_snrX, rx_evmX;
+ s8 rx_pwr[4], rx_pwr_all = 0;
+ s8 rx_snrX, rx_evmX;
u8 evm, pwdb_all;
u32 RSSI, total_rssi = 0;
u8 is_cck_rate = 0;
@@ -1613,7 +1613,7 @@ static void _rtl92e_query_rxphystatus(
2) - 110;
tmp_rxsnr = pofdm_buf->rxsnr_X[i];
- rx_snrX = (char)(tmp_rxsnr);
+ rx_snrX = (s8)(tmp_rxsnr);
rx_snrX /= 2;
priv->stats.rxSNRdB[i] = (long)rx_snrX;
@@ -1643,7 +1643,7 @@ static void _rtl92e_query_rxphystatus(
for (i = 0; i < max_spatial_stream; i++) {
tmp_rxevm = pofdm_buf->rxevm_X[i];
- rx_evmX = (char)(tmp_rxevm);
+ rx_evmX = (s8)(tmp_rxevm);
rx_evmX /= 2;
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c
index 29cefb599bab..d437a8efe933 100644
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c
+++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c
@@ -11,7 +11,7 @@
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
-******************************************************************************/
+ *****************************************************************************/
/*Created on 2008/11/18, 3: 7*/
#include "r8192E_hwimg.h"
diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c
index 5e3bbe5c3ca4..dde492261451 100644
--- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c
+++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c
@@ -256,7 +256,7 @@ u32 rtl92e_get_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath,
return 0;
if (priv->rtllib->eRFPowerState != eRfOn && !priv->being_init_adapter)
return 0;
- down(&priv->rf_sem);
+ mutex_lock(&priv->rf_mutex);
if (priv->Rf_Mode == RF_OP_By_FW) {
Original_Value = _rtl92e_phy_rf_fw_read(dev, eRFPath, RegAddr);
udelay(200);
@@ -265,7 +265,7 @@ u32 rtl92e_get_rf_reg(struct net_device *dev, enum rf90_radio_path eRFPath,
}
BitShift = _rtl92e_calculate_bit_shift(BitMask);
Readback_Value = (Original_Value & BitMask) >> BitShift;
- up(&priv->rf_sem);
+ mutex_unlock(&priv->rf_mutex);
return Readback_Value;
}
@@ -630,7 +630,7 @@ void rtl92e_set_tx_power(struct net_device *dev, u8 channel)
{
struct r8192_priv *priv = rtllib_priv(dev);
u8 powerlevel = 0, powerlevelOFDM24G = 0;
- char ant_pwr_diff;
+ s8 ant_pwr_diff;
u32 u4RegValue;
if (priv->epromtype == EEPROM_93C46) {
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
index 803c8b02a0c8..30f65af4d614 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
@@ -107,9 +107,9 @@ void rtl92e_set_key(struct net_device *dev, u8 EntryNo, u8 KeyIndex,
__func__);
return;
}
- down(&priv->rtllib->ips_sem);
+ mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
- up(&priv->rtllib->ips_sem);
+ mutex_unlock(&priv->rtllib->ips_mutex);
}
}
priv->rtllib->is_set_key = true;
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
index 13a5ddc2bea5..4c30eea45f89 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
@@ -38,7 +38,7 @@ static int channels = 0x3fff;
static char *ifname = "wlan%d";
-static struct rtl819x_ops rtl819xp_ops = {
+static const struct rtl819x_ops rtl819xp_ops = {
.nic_type = NIC_8192E,
.get_eeprom_size = rtl92e_get_eeprom_size,
.init_adapter_variable = rtl92e_init_variables,
@@ -993,8 +993,8 @@ static void _rtl92e_init_priv_lock(struct r8192_priv *priv)
spin_lock_init(&priv->irq_th_lock);
spin_lock_init(&priv->rf_ps_lock);
spin_lock_init(&priv->ps_lock);
- sema_init(&priv->wx_sem, 1);
- sema_init(&priv->rf_sem, 1);
+ mutex_init(&priv->wx_mutex);
+ mutex_init(&priv->rf_mutex);
mutex_init(&priv->mutex);
}
@@ -1247,7 +1247,7 @@ static void _rtl92e_if_silent_reset(struct net_device *dev)
RESET_START:
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
if (priv->rtllib->state == RTLLIB_LINKED)
rtl92e_leisure_ps_leave(dev);
@@ -1255,7 +1255,7 @@ RESET_START:
if (priv->up) {
netdev_info(dev, "%s():the driver is not up.\n",
__func__);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return;
}
priv->up = 0;
@@ -1277,14 +1277,14 @@ RESET_START:
rtllib_stop_scan_syncro(ieee);
if (ieee->state == RTLLIB_LINKED) {
- SEM_DOWN_IEEE_WX(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
netdev_info(dev, "ieee->state is RTLLIB_LINKED\n");
rtllib_stop_send_beacons(priv->rtllib);
del_timer_sync(&ieee->associate_timer);
cancel_delayed_work(&ieee->associate_retry_wq);
rtllib_stop_scan(ieee);
netif_carrier_off(dev);
- SEM_UP_IEEE_WX(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
} else {
netdev_info(dev, "ieee->state is NOT LINKED\n");
rtllib_softmac_stop_protocol(priv->rtllib, 0, true);
@@ -1292,7 +1292,7 @@ RESET_START:
rtl92e_dm_backup_state(dev);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
RT_TRACE(COMP_RESET,
"%s():<==========down process is finished\n",
__func__);
@@ -1982,7 +1982,7 @@ void rtl92e_update_rx_statistics(struct r8192_priv *priv,
weighting) / 6;
}
-u8 rtl92e_rx_db_to_percent(char antpower)
+u8 rtl92e_rx_db_to_percent(s8 antpower)
{
if ((antpower <= -100) || (antpower >= 20))
return 0;
@@ -1993,9 +1993,9 @@ u8 rtl92e_rx_db_to_percent(char antpower)
} /* QueryRxPwrPercentage */
-u8 rtl92e_evm_db_to_percent(char value)
+u8 rtl92e_evm_db_to_percent(s8 value)
{
- char ret_val;
+ s8 ret_val;
ret_val = value;
@@ -2179,9 +2179,9 @@ static int _rtl92e_open(struct net_device *dev)
struct r8192_priv *priv = rtllib_priv(dev);
int ret;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = _rtl92e_try_up(dev);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -2206,11 +2206,11 @@ static int _rtl92e_close(struct net_device *dev)
rtllib_stop_scan(priv->rtllib);
}
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = _rtl92e_down(dev, true);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
@@ -2242,11 +2242,11 @@ static void _rtl92e_restart(void *data)
reset_wq);
struct net_device *dev = priv->rtllib->dev;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
rtl92e_commit(dev);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
}
static void _rtl92e_set_multicast(struct net_device *dev)
@@ -2265,12 +2265,12 @@ static int _rtl92e_set_mac_adr(struct net_device *dev, void *mac)
struct r8192_priv *priv = rtllib_priv(dev);
struct sockaddr *addr = mac;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ether_addr_copy(dev->dev_addr, addr->sa_data);
schedule_work(&priv->reset_wq);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return 0;
}
@@ -2287,7 +2287,7 @@ static int _rtl92e_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
struct iw_point *p = &wrq->u.data;
struct ieee_param *ipw = NULL;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
switch (cmd) {
case RTL_IOCTL_WPA_SUPPLICANT:
@@ -2393,7 +2393,7 @@ static int _rtl92e_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
}
out:
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h
index f627fdc15a58..babc0b3bce95 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h
@@ -375,8 +375,8 @@ struct r8192_priv {
struct tasklet_struct irq_tx_tasklet;
struct tasklet_struct irq_prepare_beacon_tasklet;
- struct semaphore wx_sem;
- struct semaphore rf_sem;
+ struct mutex wx_mutex;
+ struct mutex rf_mutex;
struct mutex mutex;
struct rt_stats stats;
@@ -503,8 +503,8 @@ struct r8192_priv {
u32 Pwr_Track;
u8 CCKPresentAttentuation_20Mdefault;
u8 CCKPresentAttentuation_40Mdefault;
- char CCKPresentAttentuation_difference;
- char CCKPresentAttentuation;
+ s8 CCKPresentAttentuation_difference;
+ s8 CCKPresentAttentuation;
long undecorated_smoothed_pwdb;
u32 MCSTxPowerLevelOriginalOffset[6];
@@ -604,8 +604,8 @@ void rtl92e_update_rx_pkt_timestamp(struct net_device *dev,
long rtl92e_translate_to_dbm(struct r8192_priv *priv, u8 signal_strength_index);
void rtl92e_update_rx_statistics(struct r8192_priv *priv,
struct rtllib_rx_stats *pprevious_stats);
-u8 rtl92e_evm_db_to_percent(char value);
-u8 rtl92e_rx_db_to_percent(char antpower);
+u8 rtl92e_evm_db_to_percent(s8 value);
+u8 rtl92e_rx_db_to_percent(s8 antpower);
void rtl92e_copy_mpdu_stats(struct rtllib_rx_stats *psrc_stats,
struct rtllib_rx_stats *ptarget_stats);
bool rtl92e_enable_nic(struct net_device *dev);
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c
index 98e4d88d0e73..aa4b015c3cc7 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_ps.c
@@ -179,9 +179,9 @@ void rtl92e_ips_leave_wq(void *data)
struct net_device *dev = ieee->dev;
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
- down(&priv->rtllib->ips_sem);
+ mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
- up(&priv->rtllib->ips_sem);
+ mutex_unlock(&priv->rtllib->ips_mutex);
}
void rtl92e_rtllib_ips_leave_wq(struct net_device *dev)
@@ -209,9 +209,9 @@ void rtl92e_rtllib_ips_leave(struct net_device *dev)
{
struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev);
- down(&priv->rtllib->ips_sem);
+ mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
- up(&priv->rtllib->ips_sem);
+ mutex_unlock(&priv->rtllib->ips_mutex);
}
static bool _rtl92e_ps_set_mode(struct net_device *dev, u8 rtPsMode)
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c
index 70df6a1485d6..7413a100ca19 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c
@@ -65,11 +65,11 @@ static int _rtl92e_wx_set_rate(struct net_device *dev,
if (priv->bHwRadioOff)
return 0;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_rate(priv->rtllib, info, wrqu, extra);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -84,11 +84,11 @@ static int _rtl92e_wx_set_rts(struct net_device *dev,
if (priv->bHwRadioOff)
return 0;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_rts(priv->rtllib, info, wrqu, extra);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -114,11 +114,11 @@ static int _rtl92e_wx_set_power(struct net_device *dev,
__func__);
return 0;
}
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_power(priv->rtllib, info, wrqu, extra);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -142,11 +142,11 @@ static int _rtl92e_wx_set_rawtx(struct net_device *dev,
if (priv->bHwRadioOff)
return 0;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_rawtx(priv->rtllib, info, wrqu, extra);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
@@ -158,12 +158,12 @@ static int _rtl92e_wx_force_reset(struct net_device *dev,
{
struct r8192_priv *priv = rtllib_priv(dev);
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
RT_TRACE(COMP_DBG, "%s(): force reset ! extra is %d\n",
__func__, *extra);
priv->force_reset = *extra;
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return 0;
}
@@ -177,7 +177,7 @@ static int _rtl92e_wx_adapter_power_status(struct net_device *dev,
(&(priv->rtllib->PowerSaveControl));
struct rtllib_device *ieee = priv->rtllib;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
RT_TRACE(COMP_POWER, "%s(): %s\n", __func__, (*extra == 6) ?
"DC power" : "AC power");
@@ -193,7 +193,7 @@ static int _rtl92e_wx_adapter_power_status(struct net_device *dev,
ieee->ps = *extra;
}
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return 0;
}
@@ -207,13 +207,13 @@ static int _rtl92e_wx_set_lps_awake_interval(struct net_device *dev,
struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *)
(&(priv->rtllib->PowerSaveControl));
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
netdev_info(dev, "%s(): set lps awake interval ! extra is %d\n",
__func__, *extra);
pPSC->RegMaxLPSAwakeIntvl = *extra;
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return 0;
}
@@ -223,13 +223,13 @@ static int _rtl92e_wx_set_force_lps(struct net_device *dev,
{
struct r8192_priv *priv = rtllib_priv(dev);
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
netdev_info(dev,
"%s(): force LPS ! extra is %d (1 is open 0 is close)\n",
__func__, *extra);
priv->force_lps = *extra;
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return 0;
}
@@ -266,7 +266,7 @@ static int _rtl92e_wx_set_mode(struct net_device *dev,
if (priv->bHwRadioOff)
return 0;
rtState = priv->rtllib->eRFPowerState;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
if (wrqu->mode == IW_MODE_ADHOC || wrqu->mode == IW_MODE_MONITOR ||
ieee->bNetPromiscuousMode) {
if (priv->rtllib->PowerSaveControl.bInactivePs) {
@@ -275,21 +275,21 @@ static int _rtl92e_wx_set_mode(struct net_device *dev,
RF_CHANGE_BY_IPS) {
netdev_warn(dev, "%s(): RF is OFF.\n",
__func__);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return -1;
}
netdev_info(dev,
"=========>%s(): rtl92e_ips_leave\n",
__func__);
- down(&priv->rtllib->ips_sem);
+ mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
- up(&priv->rtllib->ips_sem);
+ mutex_unlock(&priv->rtllib->ips_mutex);
}
}
}
ret = rtllib_wx_set_mode(priv->rtllib, a, wrqu, b);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -425,7 +425,7 @@ static int _rtl92e_wx_set_scan(struct net_device *dev,
}
}
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
priv->rtllib->FirstIe_InScan = true;
@@ -436,15 +436,15 @@ static int _rtl92e_wx_set_scan(struct net_device *dev,
RF_CHANGE_BY_IPS) {
netdev_warn(dev, "%s(): RF is OFF.\n",
__func__);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return -1;
}
RT_TRACE(COMP_PS,
"=========>%s(): rtl92e_ips_leave\n",
__func__);
- down(&priv->rtllib->ips_sem);
+ mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
- up(&priv->rtllib->ips_sem);
+ mutex_unlock(&priv->rtllib->ips_mutex);
}
}
rtllib_stop_scan(priv->rtllib);
@@ -471,7 +471,7 @@ static int _rtl92e_wx_set_scan(struct net_device *dev,
ret = rtllib_wx_set_scan(priv->rtllib, a, wrqu, b);
}
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -491,11 +491,11 @@ static int _rtl92e_wx_get_scan(struct net_device *dev,
return 0;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_get_scan(priv->rtllib, a, wrqu, b);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -513,10 +513,10 @@ static int _rtl92e_wx_set_essid(struct net_device *dev,
__func__);
return 0;
}
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_essid(priv->rtllib, a, wrqu, b);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -528,11 +528,11 @@ static int _rtl92e_wx_get_essid(struct net_device *dev,
int ret;
struct r8192_priv *priv = rtllib_priv(dev);
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_get_essid(priv->rtllib, a, wrqu, b);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -545,12 +545,12 @@ static int _rtl92e_wx_set_nick(struct net_device *dev,
if (wrqu->data.length > IW_ESSID_MAX_SIZE)
return -E2BIG;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
wrqu->data.length = min_t(size_t, wrqu->data.length,
sizeof(priv->nick));
memset(priv->nick, 0, sizeof(priv->nick));
memcpy(priv->nick, extra, wrqu->data.length);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return 0;
}
@@ -561,11 +561,11 @@ static int _rtl92e_wx_get_nick(struct net_device *dev,
{
struct r8192_priv *priv = rtllib_priv(dev);
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
wrqu->data.length = strlen(priv->nick);
memcpy(extra, priv->nick, wrqu->data.length);
wrqu->data.flags = 1; /* active */
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return 0;
}
@@ -579,11 +579,11 @@ static int _rtl92e_wx_set_freq(struct net_device *dev,
if (priv->bHwRadioOff)
return 0;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_freq(priv->rtllib, a, wrqu, b);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -644,11 +644,11 @@ static int _rtl92e_wx_set_wap(struct net_device *dev,
if (priv->bHwRadioOff)
return 0;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_wap(priv->rtllib, info, awrq, extra);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
@@ -698,14 +698,14 @@ static int _rtl92e_wx_set_enc(struct net_device *dev,
return -ENETDOWN;
priv->rtllib->wx_set_enc = 1;
- down(&priv->rtllib->ips_sem);
+ mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
- up(&priv->rtllib->ips_sem);
- down(&priv->wx_sem);
+ mutex_unlock(&priv->rtllib->ips_mutex);
+ mutex_lock(&priv->wx_mutex);
RT_TRACE(COMP_SEC, "Setting SW wep key");
ret = rtllib_wx_set_encode(priv->rtllib, info, wrqu, key);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
@@ -799,7 +799,7 @@ static int _rtl92e_wx_set_retry(struct net_device *dev,
if (priv->bHwRadioOff)
return 0;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
wrqu->retry.disabled) {
@@ -822,7 +822,7 @@ static int _rtl92e_wx_set_retry(struct net_device *dev,
rtl92e_commit(dev);
exit:
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return err;
}
@@ -875,7 +875,7 @@ static int _rtl92e_wx_set_sens(struct net_device *dev,
if (priv->bHwRadioOff)
return 0;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
if (priv->rf_set_sens == NULL) {
err = -1; /* we have not this support for this radio */
goto exit;
@@ -886,7 +886,7 @@ static int _rtl92e_wx_set_sens(struct net_device *dev,
err = -EINVAL;
exit:
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return err;
}
@@ -902,12 +902,12 @@ static int _rtl92e_wx_set_encode_ext(struct net_device *dev,
if (priv->bHwRadioOff)
return 0;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
priv->rtllib->wx_set_enc = 1;
- down(&priv->rtllib->ips_sem);
+ mutex_lock(&priv->rtllib->ips_mutex);
rtl92e_ips_leave(dev);
- up(&priv->rtllib->ips_sem);
+ mutex_unlock(&priv->rtllib->ips_mutex);
ret = rtllib_wx_set_encode_ext(ieee, info, wrqu, extra);
{
@@ -969,7 +969,7 @@ static int _rtl92e_wx_set_encode_ext(struct net_device *dev,
end_hw_sec:
priv->rtllib->wx_set_enc = 0;
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -985,9 +985,9 @@ static int _rtl92e_wx_set_auth(struct net_device *dev,
if (priv->bHwRadioOff)
return 0;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_auth(priv->rtllib, info, &(data->param), extra);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -1003,9 +1003,9 @@ static int _rtl92e_wx_set_mlme(struct net_device *dev,
if (priv->bHwRadioOff)
return 0;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_mlme(priv->rtllib, info, wrqu, extra);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -1020,9 +1020,9 @@ static int _rtl92e_wx_set_gen_ie(struct net_device *dev,
if (priv->bHwRadioOff)
return 0;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
ret = rtllib_wx_set_gen_ie(priv->rtllib, extra, data->data.length);
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return ret;
}
@@ -1097,14 +1097,14 @@ static int _rtl92e_wx_get_promisc_mode(struct net_device *dev,
struct r8192_priv *priv = rtllib_priv(dev);
struct rtllib_device *ieee = priv->rtllib;
- down(&priv->wx_sem);
+ mutex_lock(&priv->wx_mutex);
snprintf(extra, 45, "PromiscuousMode:%d, FilterSrcSTAFrame:%d",
ieee->IntelPromiscuousModeInfo.bPromiscuousOn,
ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame);
wrqu->data.length = strlen(extra) + 1;
- up(&priv->wx_sem);
+ mutex_unlock(&priv->wx_mutex);
return 0;
}
diff --git a/drivers/staging/rtl8192e/rtl819x_Qos.h b/drivers/staging/rtl8192e/rtl819x_Qos.h
index 463122db6d29..61da8f7475bb 100644
--- a/drivers/staging/rtl8192e/rtl819x_Qos.h
+++ b/drivers/staging/rtl8192e/rtl819x_Qos.h
@@ -169,9 +169,6 @@ union qos_tclas {
} TYPE2_8021Q;
};
-#define IsACValid(ac) ((ac >= 0 && ac <= 7) ? true : false)
-
-
union aci_aifsn {
u8 charData;
diff --git a/drivers/staging/rtl8192e/rtl819x_TSProc.c b/drivers/staging/rtl8192e/rtl819x_TSProc.c
index 2c8a526773ed..a966a8e490ab 100644
--- a/drivers/staging/rtl8192e/rtl819x_TSProc.c
+++ b/drivers/staging/rtl8192e/rtl819x_TSProc.c
@@ -306,6 +306,11 @@ static void MakeTSEntry(struct ts_common_info *pTsCommonInfo, u8 *Addr,
pTsCommonInfo->TClasNum = TCLAS_Num;
}
+static bool IsACValid(unsigned int tid)
+{
+ return tid < 7;
+}
+
bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS,
u8 *Addr, u8 TID, enum tr_select TxRxSelect, bool bAddNewTs)
{
diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h
index 776e179d5bfd..b895a537d3e4 100644
--- a/drivers/staging/rtl8192e/rtllib.h
+++ b/drivers/staging/rtl8192e/rtllib.h
@@ -30,7 +30,7 @@
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <linux/sched.h>
-#include <linux/semaphore.h>
+#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/wireless.h>
@@ -521,7 +521,7 @@ enum wireless_mode {
};
#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
+#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
#define ETH_P_IP 0x0800 /* Internet Protocol packet */
#define ETH_P_ARP 0x0806 /* Address Resolution packet */
#endif /* ETH_P_PAE */
@@ -1651,9 +1651,9 @@ struct rtllib_device {
short proto_started;
short proto_stoppping;
- struct semaphore wx_sem;
- struct semaphore scan_sem;
- struct semaphore ips_sem;
+ struct mutex wx_mutex;
+ struct mutex scan_mutex;
+ struct mutex ips_mutex;
spinlock_t mgmt_tx_lock;
spinlock_t beacon_lock;
@@ -2212,7 +2212,5 @@ void rtllib_indicate_packets(struct rtllib_device *ieee,
void HTUseDefaultSetting(struct rtllib_device *ieee);
#define RT_ASOC_RETRY_LIMIT 5
u8 MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee);
-#define SEM_DOWN_IEEE_WX(psem) down(psem)
-#define SEM_UP_IEEE_WX(psem) up(psem)
#endif /* RTLLIB_H */
diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c
index f4f318abb299..9d5788e04dd5 100644
--- a/drivers/staging/rtl8192e/rtllib_module.c
+++ b/drivers/staging/rtl8192e/rtllib_module.c
@@ -138,7 +138,7 @@ struct net_device *alloc_rtllib(int sizeof_priv)
rtllib_softmac_init(ieee);
ieee->pHTInfo = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL);
- if (ieee->pHTInfo == NULL)
+ if (!ieee->pHTInfo)
return NULL;
HTUpdateDefaultSetting(ieee);
diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c
index 62154e3f4463..da74dc49b95e 100644
--- a/drivers/staging/rtl8192e/rtllib_softmac.c
+++ b/drivers/staging/rtl8192e/rtllib_softmac.c
@@ -276,8 +276,9 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee)
}
}
-inline void softmac_ps_mgmt_xmit(struct sk_buff *skb,
- struct rtllib_device *ieee)
+static inline void
+softmac_ps_mgmt_xmit(struct sk_buff *skb,
+ struct rtllib_device *ieee)
{
short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
struct rtllib_hdr_3addr *header =
@@ -513,7 +514,7 @@ static void rtllib_softmac_scan_syncro(struct rtllib_device *ieee, u8 is_mesh)
ieee->be_scan_inprogress = true;
- down(&ieee->scan_sem);
+ mutex_lock(&ieee->scan_mutex);
while (1) {
do {
@@ -566,7 +567,7 @@ out:
if (IS_DOT11D_ENABLE(ieee))
DOT11D_ScanComplete(ieee);
}
- up(&ieee->scan_sem);
+ mutex_unlock(&ieee->scan_mutex);
ieee->be_scan_inprogress = false;
@@ -587,7 +588,7 @@ static void rtllib_softmac_scan_wq(void *data)
if (rtllib_act_scanning(ieee, true))
return;
- down(&ieee->scan_sem);
+ mutex_lock(&ieee->scan_mutex);
if (ieee->eRFPowerState == eRfOff) {
netdev_info(ieee->dev,
@@ -618,7 +619,7 @@ static void rtllib_softmac_scan_wq(void *data)
schedule_delayed_work(&ieee->softmac_scan_wq,
msecs_to_jiffies(RTLLIB_SOFTMAC_SCAN_TIME));
- up(&ieee->scan_sem);
+ mutex_unlock(&ieee->scan_mutex);
return;
out:
@@ -630,7 +631,7 @@ out1:
ieee->actscanning = false;
ieee->scan_watch_dog = 0;
ieee->scanning_continue = 0;
- up(&ieee->scan_sem);
+ mutex_unlock(&ieee->scan_mutex);
}
@@ -683,7 +684,7 @@ EXPORT_SYMBOL(rtllib_start_send_beacons);
static void rtllib_softmac_stop_scan(struct rtllib_device *ieee)
{
- down(&ieee->scan_sem);
+ mutex_lock(&ieee->scan_mutex);
ieee->scan_watch_dog = 0;
if (ieee->scanning_continue == 1) {
ieee->scanning_continue = 0;
@@ -692,7 +693,7 @@ static void rtllib_softmac_stop_scan(struct rtllib_device *ieee)
cancel_delayed_work_sync(&ieee->softmac_scan_wq);
}
- up(&ieee->scan_sem);
+ mutex_unlock(&ieee->scan_mutex);
}
void rtllib_stop_scan(struct rtllib_device *ieee)
@@ -753,7 +754,7 @@ static void rtllib_start_scan(struct rtllib_device *ieee)
}
}
-/* called with wx_sem held */
+/* called with wx_mutex held */
void rtllib_start_scan_syncro(struct rtllib_device *ieee, u8 is_mesh)
{
if (IS_DOT11D_ENABLE(ieee)) {
@@ -770,8 +771,10 @@ void rtllib_start_scan_syncro(struct rtllib_device *ieee, u8 is_mesh)
}
EXPORT_SYMBOL(rtllib_start_scan_syncro);
-inline struct sk_buff *rtllib_authentication_req(struct rtllib_network *beacon,
- struct rtllib_device *ieee, int challengelen, u8 *daddr)
+static inline struct sk_buff *
+rtllib_authentication_req(struct rtllib_network *beacon,
+ struct rtllib_device *ieee,
+ int challengelen, u8 *daddr)
{
struct sk_buff *skb;
struct rtllib_authentication *auth;
@@ -1130,7 +1133,7 @@ static void rtllib_resp_to_probe(struct rtllib_device *ieee, u8 *dest)
}
-inline int SecIsInPMKIDList(struct rtllib_device *ieee, u8 *bssid)
+static inline int SecIsInPMKIDList(struct rtllib_device *ieee, u8 *bssid)
{
int i = 0;
@@ -1146,8 +1149,9 @@ inline int SecIsInPMKIDList(struct rtllib_device *ieee, u8 *bssid)
return i;
}
-inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon,
- struct rtllib_device *ieee)
+static inline struct sk_buff *
+rtllib_association_req(struct rtllib_network *beacon,
+ struct rtllib_device *ieee)
{
struct sk_buff *skb;
struct rtllib_assoc_request_frame *hdr;
@@ -1590,7 +1594,7 @@ static void rtllib_associate_procedure_wq(void *data)
rtllib_stop_scan_syncro(ieee);
if (ieee->rtllib_ips_leave != NULL)
ieee->rtllib_ips_leave(ieee->dev);
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
if (ieee->data_hard_stop)
ieee->data_hard_stop(ieee->dev);
@@ -1605,14 +1609,14 @@ static void rtllib_associate_procedure_wq(void *data)
__func__);
if (ieee->rtllib_ips_leave_wq != NULL)
ieee->rtllib_ips_leave_wq(ieee->dev);
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
return;
}
ieee->associate_seq = 1;
rtllib_associate_step1(ieee, ieee->current_network.bssid);
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
}
inline void rtllib_softmac_new_net(struct rtllib_device *ieee,
@@ -2209,8 +2213,9 @@ static void rtllib_process_action(struct rtllib_device *ieee,
}
}
-inline int rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats)
+static inline int
+rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb,
+ struct rtllib_rx_stats *rx_stats)
{
u16 errcode;
int aid;
@@ -2344,8 +2349,9 @@ static void rtllib_rx_auth_resp(struct rtllib_device *ieee, struct sk_buff *skb)
}
}
-inline int rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb,
- struct rtllib_rx_stats *rx_stats)
+static inline int
+rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb,
+ struct rtllib_rx_stats *rx_stats)
{
if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
@@ -2361,7 +2367,8 @@ inline int rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb,
return 0;
}
-inline int rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb)
+static inline int
+rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb)
{
struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data;
u16 frame_ctl;
@@ -2582,16 +2589,16 @@ static void rtllib_start_ibss_wq(void *data)
struct rtllib_device, start_ibss_wq);
/* iwconfig mode ad-hoc will schedule this and return
* on the other hand this will block further iwconfig SET
- * operations because of the wx_sem hold.
+ * operations because of the wx_mutex hold.
* Anyway some most set operations set a flag to speed-up
* (abort) this wq (when syncro scanning) before sleeping
- * on the semaphore
+ * on the mutex
*/
if (!ieee->proto_started) {
netdev_info(ieee->dev, "==========oh driver down return\n");
return;
}
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
if (ieee->current_network.ssid_len == 0) {
strcpy(ieee->current_network.ssid, RTLLIB_DEFAULT_TX_ESSID);
@@ -2703,7 +2710,7 @@ static void rtllib_start_ibss_wq(void *data)
netif_carrier_on(ieee->dev);
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
}
inline void rtllib_start_ibss(struct rtllib_device *ieee)
@@ -2711,7 +2718,7 @@ inline void rtllib_start_ibss(struct rtllib_device *ieee)
schedule_delayed_work(&ieee->start_ibss_wq, msecs_to_jiffies(150));
}
-/* this is called only in user context, with wx_sem held */
+/* this is called only in user context, with wx_mutex held */
static void rtllib_start_bss(struct rtllib_device *ieee)
{
unsigned long flags;
@@ -2773,7 +2780,7 @@ static void rtllib_associate_retry_wq(void *data)
struct rtllib_device, associate_retry_wq);
unsigned long flags;
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
if (!ieee->proto_started)
goto exit;
@@ -2806,7 +2813,7 @@ static void rtllib_associate_retry_wq(void *data)
ieee->beinretry = false;
exit:
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
}
static struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee)
@@ -2853,9 +2860,9 @@ void rtllib_softmac_stop_protocol(struct rtllib_device *ieee, u8 mesh_flag,
u8 shutdown)
{
rtllib_stop_scan_syncro(ieee);
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
rtllib_stop_protocol(ieee, shutdown);
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
}
EXPORT_SYMBOL(rtllib_softmac_stop_protocol);
@@ -2902,9 +2909,9 @@ void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown)
void rtllib_softmac_start_protocol(struct rtllib_device *ieee, u8 mesh_flag)
{
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
rtllib_start_protocol(ieee);
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
}
EXPORT_SYMBOL(rtllib_softmac_start_protocol);
@@ -3034,9 +3041,9 @@ void rtllib_softmac_init(struct rtllib_device *ieee)
INIT_WORK_RSL(&ieee->wx_sync_scan_wq, (void *)rtllib_wx_sync_scan_wq,
ieee);
- sema_init(&ieee->wx_sem, 1);
- sema_init(&ieee->scan_sem, 1);
- sema_init(&ieee->ips_sem, 1);
+ mutex_init(&ieee->wx_mutex);
+ mutex_init(&ieee->scan_mutex);
+ mutex_init(&ieee->ips_mutex);
spin_lock_init(&ieee->mgmt_tx_lock);
spin_lock_init(&ieee->beacon_lock);
@@ -3049,7 +3056,7 @@ void rtllib_softmac_init(struct rtllib_device *ieee)
void rtllib_softmac_free(struct rtllib_device *ieee)
{
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
kfree(ieee->pDot11dInfo);
ieee->pDot11dInfo = NULL;
del_timer_sync(&ieee->associate_timer);
@@ -3064,7 +3071,7 @@ void rtllib_softmac_free(struct rtllib_device *ieee)
cancel_work_sync(&ieee->associate_complete_wq);
cancel_work_sync(&ieee->ips_leave_wq);
cancel_work_sync(&ieee->wx_sync_scan_wq);
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
tasklet_kill(&ieee->ps_task);
}
@@ -3397,8 +3404,9 @@ static int rtllib_wpa_set_encryption(struct rtllib_device *ieee,
return ret;
}
-inline struct sk_buff *rtllib_disauth_skb(struct rtllib_network *beacon,
- struct rtllib_device *ieee, u16 asRsn)
+static inline struct sk_buff *
+rtllib_disauth_skb(struct rtllib_network *beacon,
+ struct rtllib_device *ieee, u16 asRsn)
{
struct sk_buff *skb;
struct rtllib_disauth *disauth;
@@ -3423,8 +3431,9 @@ inline struct sk_buff *rtllib_disauth_skb(struct rtllib_network *beacon,
return skb;
}
-inline struct sk_buff *rtllib_disassociate_skb(struct rtllib_network *beacon,
- struct rtllib_device *ieee, u16 asRsn)
+static inline struct sk_buff *
+rtllib_disassociate_skb(struct rtllib_network *beacon,
+ struct rtllib_device *ieee, u16 asRsn)
{
struct sk_buff *skb;
struct rtllib_disassoc *disass;
@@ -3499,7 +3508,7 @@ int rtllib_wpa_supplicant_ioctl(struct rtllib_device *ieee, struct iw_point *p,
struct ieee_param *param;
int ret = 0;
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
if (p->length < sizeof(struct ieee_param) || !p->pointer) {
ret = -EINVAL;
@@ -3543,7 +3552,7 @@ int rtllib_wpa_supplicant_ioctl(struct rtllib_device *ieee, struct iw_point *p,
kfree(param);
out:
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
return ret;
}
diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c
index 61ed8b0413e4..5f1412fc410d 100644
--- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c
+++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c
@@ -35,7 +35,7 @@ int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a,
int ret;
struct iw_freq *fwrq = &wrqu->freq;
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
if (ieee->iw_mode == IW_MODE_INFRA) {
ret = 0;
@@ -81,7 +81,7 @@ int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a,
ret = 0;
out:
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
return ret;
}
EXPORT_SYMBOL(rtllib_wx_set_freq);
@@ -146,7 +146,7 @@ int rtllib_wx_set_wap(struct rtllib_device *ieee,
rtllib_stop_scan_syncro(ieee);
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
/* use ifconfig hw ether */
if (ieee->iw_mode == IW_MODE_MASTER) {
ret = -1;
@@ -185,7 +185,7 @@ int rtllib_wx_set_wap(struct rtllib_device *ieee,
if (ifup)
rtllib_start_protocol(ieee);
out:
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
return ret;
}
EXPORT_SYMBOL(rtllib_wx_set_wap);
@@ -287,7 +287,7 @@ int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a,
int set_mode_status = 0;
rtllib_stop_scan_syncro(ieee);
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
switch (wrqu->mode) {
case IW_MODE_MONITOR:
case IW_MODE_ADHOC:
@@ -322,7 +322,7 @@ int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a,
}
out:
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
return set_mode_status;
}
EXPORT_SYMBOL(rtllib_wx_set_mode);
@@ -412,7 +412,7 @@ void rtllib_wx_sync_scan_wq(void *data)
rtllib_wake_all_queues(ieee);
out:
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
}
@@ -421,7 +421,7 @@ int rtllib_wx_set_scan(struct rtllib_device *ieee, struct iw_request_info *a,
{
int ret = 0;
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) {
ret = -1;
@@ -435,7 +435,7 @@ int rtllib_wx_set_scan(struct rtllib_device *ieee, struct iw_request_info *a,
}
out:
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
return ret;
}
EXPORT_SYMBOL(rtllib_wx_set_scan);
@@ -450,7 +450,7 @@ int rtllib_wx_set_essid(struct rtllib_device *ieee,
unsigned long flags;
rtllib_stop_scan_syncro(ieee);
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
proto_started = ieee->proto_started;
@@ -492,7 +492,7 @@ int rtllib_wx_set_essid(struct rtllib_device *ieee,
if (proto_started)
rtllib_start_protocol(ieee);
out:
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
return ret;
}
EXPORT_SYMBOL(rtllib_wx_set_essid);
@@ -514,7 +514,7 @@ int rtllib_wx_set_rawtx(struct rtllib_device *ieee,
int enable = (parms[0] > 0);
short prev = ieee->raw_tx;
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
if (enable)
ieee->raw_tx = 1;
@@ -536,7 +536,7 @@ int rtllib_wx_set_rawtx(struct rtllib_device *ieee,
netif_carrier_off(ieee->dev);
}
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
return 0;
}
@@ -575,7 +575,7 @@ int rtllib_wx_set_power(struct rtllib_device *ieee,
return -1;
}
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
if (wrqu->power.disabled) {
RT_TRACE(COMP_DBG, "===>%s(): power disable\n", __func__);
@@ -611,7 +611,7 @@ int rtllib_wx_set_power(struct rtllib_device *ieee,
}
exit:
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
return ret;
}
@@ -622,7 +622,7 @@ int rtllib_wx_get_power(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
if (ieee->ps == RTLLIB_PS_DISABLED) {
wrqu->power.disabled = 1;
@@ -648,7 +648,7 @@ int rtllib_wx_get_power(struct rtllib_device *ieee,
wrqu->power.flags |= IW_POWER_UNICAST_R;
exit:
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
return 0;
}
diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c
index 58fc70ec5f2f..78a3ad5b231f 100644
--- a/drivers/staging/rtl8192e/rtllib_tx.c
+++ b/drivers/staging/rtl8192e/rtllib_tx.c
@@ -1,31 +1,31 @@
/******************************************************************************
-
- Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of version 2 of the GNU General Public License 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.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
- Contact Information:
- James P. Ketrenos <ipw2100-admin@linux.intel.com>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-******************************************************************************
-
- Few modifications for Realtek's Wi-Fi drivers by
- Andrea Merello <andrea.merello@gmail.com>
-
- A special thanks goes to Realtek for their support !
-
-******************************************************************************/
+ *
+ * Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License 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.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************
+ *
+ * Few modifications for Realtek's Wi-Fi drivers by
+ * Andrea Merello <andrea.merello@gmail.com>
+ *
+ * A special thanks goes to Realtek for their support !
+ *
+ *****************************************************************************/
#include <linux/compiler.h>
#include <linux/errno.h>
@@ -731,17 +731,19 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
if (qos_actived) {
hdr_len = RTLLIB_3ADDR_LEN + 2;
- /* in case we are a client verify acm is not set for this ac */
- while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) {
- netdev_info(ieee->dev, "skb->priority = %x\n",
- skb->priority);
- if (wme_downgrade_ac(skb))
- break;
- netdev_info(ieee->dev, "converted skb->priority = %x\n",
- skb->priority);
- }
+ /* in case we are a client verify acm is not set for this ac */
+ while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) {
+ netdev_info(ieee->dev, "skb->priority = %x\n",
+ skb->priority);
+ if (wme_downgrade_ac(skb))
+ break;
+ netdev_info(ieee->dev, "converted skb->priority = %x\n",
+ skb->priority);
+ }
+
qos_ctl |= skb->priority;
header.qos_ctl = cpu_to_le16(qos_ctl & RTLLIB_QOS_TID);
+
} else {
hdr_len = RTLLIB_3ADDR_LEN;
}
@@ -981,6 +983,7 @@ static int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev)
return 1;
}
+
int rtllib_xmit(struct sk_buff *skb, struct net_device *dev)
{
memset(skb->cb, 0, sizeof(skb->cb));
diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c
index 84e6272f28cd..b1500ee9a5cf 100644
--- a/drivers/staging/rtl8192e/rtllib_wx.c
+++ b/drivers/staging/rtl8192e/rtllib_wx.c
@@ -263,7 +263,7 @@ int rtllib_wx_get_scan(struct rtllib_device *ieee,
int err = 0;
netdev_dbg(ieee->dev, "Getting scan\n");
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
spin_lock_irqsave(&ieee->lock, flags);
list_for_each_entry(network, &ieee->network_list, list) {
@@ -287,7 +287,7 @@ int rtllib_wx_get_scan(struct rtllib_device *ieee,
}
spin_unlock_irqrestore(&ieee->lock, flags);
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
wrqu->data.length = ev - extra;
wrqu->data.flags = 0;
@@ -689,7 +689,7 @@ int rtllib_wx_set_mlme(struct rtllib_device *ieee,
if (ieee->state != RTLLIB_LINKED)
return -ENOLINK;
- down(&ieee->wx_sem);
+ mutex_lock(&ieee->wx_mutex);
switch (mlme->cmd) {
case IW_MLME_DEAUTH:
@@ -716,11 +716,11 @@ int rtllib_wx_set_mlme(struct rtllib_device *ieee,
ieee->current_network.ssid_len = 0;
break;
default:
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
return -EOPNOTSUPP;
}
- up(&ieee->wx_sem);
+ mutex_unlock(&ieee->wx_mutex);
return 0;
}
diff --git a/drivers/staging/rtl8192u/ieee80211/Makefile b/drivers/staging/rtl8192u/ieee80211/Makefile
index b5d0c2eb045b..9e3f432e5355 100644
--- a/drivers/staging/rtl8192u/ieee80211/Makefile
+++ b/drivers/staging/rtl8192u/ieee80211/Makefile
@@ -1,7 +1,6 @@
NIC_SELECT = RTL8192U
-ccflags-y := -I$(TOPDIR)/drivers/net/wireless
-ccflags-y += -O2
+ccflags-y := -O2
ccflags-y += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
ieee80211-rsl-objs := ieee80211_rx.o \
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
index 09e9499b7f9d..077ea13eb1e7 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
@@ -746,7 +746,7 @@ struct ieee80211_rx_stats {
bool bisrxaggrsubframe;
bool bPacketBeacon; //cosa add for rssi
bool bToSelfBA; //cosa add for rssi
- char cck_adc_pwdb[4]; //cosa add for rx path selection
+ s8 cck_adc_pwdb[4]; //cosa add for rx path selection
u16 Seq_Num;
};
@@ -1814,7 +1814,7 @@ struct ieee80211_device {
u32 wpax_type_notify; //{added by David, 2006.9.26}
/* QoS related flag */
- char init_wmmparam_flag;
+ s8 init_wmmparam_flag;
/* set on initialization */
u8 qos_support;
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
index 051c2be842d0..89cbc077a48d 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
@@ -1027,7 +1027,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
ieee,
(PTS_COMMON_INFO *) &pRxTS,
hdr->addr2,
- (u8)Frame_QoSTID((u8 *)(skb->data)),
+ Frame_QoSTID((u8 *)(skb->data)),
RX_DIR,
true))
{
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
index 49db1b75cd05..d7d85b3f19c4 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
@@ -284,7 +284,8 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee
}
}
-inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
+static inline void
+softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
{
short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
@@ -320,7 +321,7 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i
//dev_kfree_skb_any(skb);//edit by thomas
}
-inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
+static inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
{
unsigned int len, rate_len;
u8 *tag;
@@ -640,8 +641,9 @@ void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
}
EXPORT_SYMBOL(ieee80211_start_scan_syncro);
-inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
- struct ieee80211_device *ieee, int challengelen)
+static inline struct sk_buff *
+ieee80211_authentication_req(struct ieee80211_network *beacon,
+ struct ieee80211_device *ieee, int challengelen)
{
struct sk_buff *skb;
struct ieee80211_authentication *auth;
@@ -806,7 +808,7 @@ static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d
*(tag++) = 2;
put_unaligned_le16(ieee->current_network.atim_window,
- (u8 *)tag);
+ tag);
tag+=2;
}
@@ -978,7 +980,9 @@ static void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
}
-inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
+static inline struct sk_buff *
+ieee80211_association_req(struct ieee80211_network *beacon,
+ struct ieee80211_device *ieee)
{
struct sk_buff *skb;
//unsigned long flags;
@@ -3091,7 +3095,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
return ret;
}
-inline struct sk_buff *ieee80211_disassociate_skb(
+static inline struct sk_buff *ieee80211_disassociate_skb(
struct ieee80211_network *beacon,
struct ieee80211_device *ieee,
u8 asRsn)
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
index 28737ec65186..98fbb6ef484d 100644
--- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
@@ -354,7 +354,7 @@ int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb)
req = (struct rtl_80211_hdr_3addr *) skb->data;
tag = (u8 *)req;
- dst = (u8 *)(&req->addr2[0]);
+ dst = &req->addr2[0];
tag += sizeof(struct rtl_80211_hdr_3addr);
pDialogToken = tag + 2; //category+action
pBaParamSet = (PBA_PARAM_SET)(tag + 3); //+DialogToken
@@ -452,7 +452,7 @@ int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb)
}
rsp = (struct rtl_80211_hdr_3addr *)skb->data;
tag = (u8 *)rsp;
- dst = (u8 *)(&rsp->addr2[0]);
+ dst = &rsp->addr2[0];
tag += sizeof(struct rtl_80211_hdr_3addr);
pDialogToken = tag + 2;
pStatusCode = (u16 *)(tag + 3);
@@ -590,7 +590,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb)
IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
delba = (struct rtl_80211_hdr_3addr *)skb->data;
- dst = (u8 *)(&delba->addr2[0]);
+ dst = &delba->addr2[0];
pDelBaParamSet = (PDELBA_PARAM_SET)&delba->payload[2];
if(pDelBaParamSet->field.Initiator == 1)
diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h
index 821afc0ddac5..0b7b04ea0910 100644
--- a/drivers/staging/rtl8192u/r8192U.h
+++ b/drivers/staging/rtl8192u/r8192U.h
@@ -533,7 +533,7 @@ typedef struct _rt_9x_tx_rate_history {
u32 ht_mcs[4][16];
} rt_tx_rahis_t, *prt_tx_rahis_t;
typedef struct _RT_SMOOTH_DATA_4RF {
- char elements[4][100]; /* array to store values */
+ s8 elements[4][100]; /* array to store values */
u32 index; /* index to current array to store */
u32 TotalNum; /* num of valid elements */
u32 TotalVal[4]; /* sum of valid elements */
@@ -1031,7 +1031,7 @@ typedef struct r8192_priv {
s8 cck_present_attentuation;
u8 cck_present_attentuation_20Mdefault;
u8 cck_present_attentuation_40Mdefault;
- char cck_present_attentuation_difference;
+ s8 cck_present_attentuation_difference;
bool btxpower_tracking;
bool bcck_in_ch14;
bool btxpowerdata_readfromEEPORM;
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
index dd0970facdf5..457eeb5f5239 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -114,9 +114,9 @@ static int channels = 0x3fff;
-module_param(ifname, charp, S_IRUGO | S_IWUSR);
-module_param(hwwep, int, S_IRUGO | S_IWUSR);
-module_param(channels, int, S_IRUGO | S_IWUSR);
+module_param(ifname, charp, 0644);
+module_param(hwwep, int, 0644);
+module_param(channels, int, 0644);
MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default");
MODULE_PARM_DESC(hwwep, " Try to use hardware security support. ");
@@ -922,47 +922,6 @@ void rtl8192_rtx_disable(struct net_device *dev)
skb_queue_purge(&priv->skb_queue);
}
-inline u16 ieeerate2rtlrate(int rate)
-{
- switch (rate) {
- case 10:
- return 0;
- case 20:
- return 1;
- case 55:
- return 2;
- case 110:
- return 3;
- case 60:
- return 4;
- case 90:
- return 5;
- case 120:
- return 6;
- case 180:
- return 7;
- case 240:
- return 8;
- case 360:
- return 9;
- case 480:
- return 10;
- case 540:
- return 11;
- default:
- return 3;
- }
-}
-
-static u16 rtl_rate[] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540};
-inline u16 rtl8192_rate2rate(short rate)
-{
- if (rate > 11)
- return 0;
- return rtl_rate[rate];
-}
-
-
/* The prototype of rx_isr has changed since one version of Linux Kernel */
static void rtl8192_rx_isr(struct urb *urb)
{
@@ -1319,14 +1278,6 @@ void rtl819xusb_beacon_tx(struct net_device *dev, u16 tx_rate)
}
-inline u8 rtl8192_IsWirelessBMode(u16 rate)
-{
- if (((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220))
- return 1;
- else
- return 0;
-}
-
short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
{
struct r8192_priv *priv = ieee80211_priv(dev);
@@ -1702,11 +1653,8 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
}
if (bSend0Byte) {
tx_urb_zero = usb_alloc_urb(0, GFP_ATOMIC);
- if (!tx_urb_zero) {
- RT_TRACE(COMP_ERR,
- "can't alloc urb for zero byte\n");
+ if (!tx_urb_zero)
return -ENOMEM;
- }
usb_fill_bulk_urb(tx_urb_zero, udev,
usb_sndbulkpipe(udev, idx_pipe),
&zero, 0, tx_zero_isr, dev);
@@ -4209,7 +4157,7 @@ static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
*
* Return: 0-100 percentage
*---------------------------------------------------------------------------*/
-static u8 rtl819x_query_rxpwrpercentage(char antpower)
+static u8 rtl819x_query_rxpwrpercentage(s8 antpower)
{
if ((antpower <= -100) || (antpower >= 20))
return 0;
@@ -4220,9 +4168,9 @@ static u8 rtl819x_query_rxpwrpercentage(char antpower)
} /* QueryRxPwrPercentage */
-static u8 rtl819x_evm_dbtopercentage(char value)
+static u8 rtl819x_evm_dbtopercentage(s8 value)
{
- char ret_val;
+ s8 ret_val;
ret_val = value;
@@ -4297,8 +4245,8 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
phy_ofdm_rx_status_rxsc_sgien_exintfflag *prxsc;
u8 *prxpkt;
u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
- char rx_pwr[4], rx_pwr_all = 0;
- char rx_snrX, rx_evmX;
+ s8 rx_pwr[4], rx_pwr_all = 0;
+ s8 rx_snrX, rx_evmX;
u8 evm, pwdb_all;
u32 RSSI, total_rssi = 0;
u8 is_cck_rate = 0;
@@ -4423,7 +4371,7 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
/* Get Rx snr value in DB */
tmp_rxsnr = pofdm_buf->rxsnr_X[i];
- rx_snrX = (char)(tmp_rxsnr);
+ rx_snrX = (s8)(tmp_rxsnr);
rx_snrX /= 2;
priv->stats.rxSNRdB[i] = (long)rx_snrX;
@@ -4457,7 +4405,7 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
for (i = 0; i < max_spatial_stream; i++) {
tmp_rxevm = pofdm_buf->rxevm_X[i];
- rx_evmX = (char)(tmp_rxevm);
+ rx_evmX = (s8)(tmp_rxevm);
/* Do not use shift operation like "rx_evmX >>= 1"
* because the compiler of free build environment will
@@ -4475,10 +4423,10 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
*/
pstats->SignalQuality =
precord_stats->SignalQuality =
- (u8)(evm & 0xff);
+ evm & 0xff;
pstats->RxMIMOSignalQuality[i] =
precord_stats->RxMIMOSignalQuality[i] =
- (u8)(evm & 0xff);
+ evm & 0xff;
}
@@ -5013,8 +4961,7 @@ static int rtl8192_usb_probe(struct usb_interface *intf,
dev->netdev_ops = &rtl8192_netdev_ops;
- dev->wireless_handlers =
- (struct iw_handler_def *)&r8192_wx_handlers_def;
+ dev->wireless_handlers = &r8192_wx_handlers_def;
dev->type = ARPHRD_ETHER;
@@ -5222,7 +5169,8 @@ void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType,
} else {
/* Key Material */
if (KeyContent) {
- write_nic_dword(dev, WCAMI, (u32)(*(KeyContent + i - 2)));
+ write_nic_dword(dev, WCAMI,
+ *(KeyContent + i - 2));
write_nic_dword(dev, RWCAM, TargetCommand);
}
}
diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c
index 1e0e53c9c314..9209aad0515e 100644
--- a/drivers/staging/rtl8192u/r8192U_dm.c
+++ b/drivers/staging/rtl8192u/r8192U_dm.c
@@ -150,7 +150,7 @@ void deinit_hal_dm(struct net_device *dev)
#ifdef USB_RX_AGGREGATION_SUPPORT
void dm_CheckRxAggregation(struct net_device *dev)
{
- struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
+ struct r8192_priv *priv = ieee80211_priv(dev);
PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
static unsigned long lastTxOkCnt;
static unsigned long lastRxOkCnt;
@@ -2346,7 +2346,7 @@ dm_CheckEdcaTurbo_EXIT:
static void dm_init_ctstoself(struct net_device *dev)
{
- struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
+ struct r8192_priv *priv = ieee80211_priv(dev);
priv->ieee80211->bCTSToSelfEnable = true;
priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal;
@@ -2354,7 +2354,7 @@ static void dm_init_ctstoself(struct net_device *dev)
static void dm_ctstoself(struct net_device *dev)
{
- struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
+ struct r8192_priv *priv = ieee80211_priv(dev);
PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
static unsigned long lastTxOkCnt;
static unsigned long lastRxOkCnt;
diff --git a/drivers/staging/rtl8712/ieee80211.c b/drivers/staging/rtl8712/ieee80211.c
index 8918654b44ed..5dc3b5b9bfff 100644
--- a/drivers/staging/rtl8712/ieee80211.c
+++ b/drivers/staging/rtl8712/ieee80211.c
@@ -145,7 +145,7 @@ static void set_supported_rate(u8 *rates, uint mode)
case WIRELESS_11BG:
memcpy(rates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN);
memcpy(rates + IEEE80211_CCK_RATE_LEN, WIFI_OFDMRATES,
- IEEE80211_NUM_OFDM_RATESLEN);
+ IEEE80211_NUM_OFDM_RATESLEN);
break;
}
}
@@ -188,24 +188,24 @@ int r8712_generate_ie(struct registry_priv *pregistrypriv)
ie += 2;
/*SSID*/
ie = r8712_set_ie(ie, _SSID_IE_, pdev_network->Ssid.SsidLength,
- pdev_network->Ssid.Ssid, &sz);
+ pdev_network->Ssid.Ssid, &sz);
/*supported rates*/
set_supported_rate(pdev_network->rates, pregistrypriv->wireless_mode);
rateLen = r8712_get_rateset_len(pdev_network->rates);
if (rateLen > 8) {
ie = r8712_set_ie(ie, _SUPPORTEDRATES_IE_, 8,
- pdev_network->rates, &sz);
+ pdev_network->rates, &sz);
ie = r8712_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8),
- (pdev_network->rates + 8), &sz);
+ (pdev_network->rates + 8), &sz);
} else
ie = r8712_set_ie(ie, _SUPPORTEDRATES_IE_,
- rateLen, pdev_network->rates, &sz);
+ rateLen, pdev_network->rates, &sz);
/*DS parameter set*/
ie = r8712_set_ie(ie, _DSSET_IE_, 1,
- (u8 *)&(pdev_network->Configuration.DSConfig), &sz);
+ (u8 *)&(pdev_network->Configuration.DSConfig), &sz);
/*IBSS Parameter Set*/
ie = r8712_set_ie(ie, _IBSS_PARA_IE_, 2,
- (u8 *)&(pdev_network->Configuration.ATIMWindow), &sz);
+ (u8 *)&(pdev_network->Configuration.ATIMWindow), &sz);
return sz;
}
@@ -220,8 +220,7 @@ unsigned char *r8712_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit)
pbuf = r8712_get_ie(pbuf, _WPA_IE_ID_, &len, limit);
if (pbuf) {
/*check if oui matches...*/
- if (memcmp((pbuf + 2), wpa_oui_type,
- sizeof(wpa_oui_type)))
+ if (memcmp((pbuf + 2), wpa_oui_type, sizeof(wpa_oui_type)))
goto check_next_ie;
/*check version...*/
memcpy((u8 *)&val16, (pbuf + 6), sizeof(val16));
@@ -279,7 +278,7 @@ static int r8712_get_wpa2_cipher_suite(u8 *s)
}
int r8712_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher,
- int *pairwise_cipher)
+ int *pairwise_cipher)
{
int i;
int left, count;
@@ -322,7 +321,7 @@ int r8712_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher,
}
int r8712_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher,
- int *pairwise_cipher)
+ int *pairwise_cipher)
{
int i;
int left, count;
@@ -365,7 +364,7 @@ int r8712_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher,
}
int r8712_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len,
- u8 *wpa_ie, u16 *wpa_len)
+ u8 *wpa_ie, u16 *wpa_len)
{
u8 authmode;
u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01};
@@ -383,7 +382,7 @@ int r8712_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len,
} else {
if (authmode == _WPA2_IE_ID_) {
memcpy(rsn_ie, &in_ie[cnt],
- in_ie[cnt + 1] + 2);
+ in_ie[cnt + 1] + 2);
*rsn_len = in_ie[cnt + 1] + 2;
cnt += in_ie[cnt + 1] + 2; /*get next*/
} else {
diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c
index 57211f7e68a5..cbe4de05d26b 100644
--- a/drivers/staging/rtl8712/os_intfs.c
+++ b/drivers/staging/rtl8712/os_intfs.c
@@ -243,9 +243,9 @@ static u32 start_drv_threads(struct _adapter *padapter)
void r8712_stop_drv_threads(struct _adapter *padapter)
{
/*Below is to terminate r8712_cmd_thread & event_thread...*/
- up(&padapter->cmdpriv.cmd_queue_sema);
+ complete(&padapter->cmdpriv.cmd_queue_comp);
if (padapter->cmdThread)
- _down_sema(&padapter->cmdpriv.terminate_cmdthread_sema);
+ wait_for_completion_interruptible(&padapter->cmdpriv.terminate_cmdthread_comp);
padapter->cmdpriv.cmd_seq = 1;
}
@@ -425,7 +425,7 @@ static int netdev_open(struct net_device *pnetdev)
else
netif_wake_queue(pnetdev);
- if (video_mode)
+ if (video_mode)
enable_video_mode(padapter, cbw40_enable);
/* start driver mlme relation timer */
start_drv_timers(padapter);
diff --git a/drivers/staging/rtl8712/osdep_intf.h b/drivers/staging/rtl8712/osdep_intf.h
index aa0ec74af511..5d37e1f951cf 100644
--- a/drivers/staging/rtl8712/osdep_intf.h
+++ b/drivers/staging/rtl8712/osdep_intf.h
@@ -36,7 +36,7 @@ struct intf_priv {
/* when in USB, IO is through interrupt in/out endpoints */
struct usb_device *udev;
struct urb *piorw_urb;
- struct semaphore io_retevt;
+ struct completion io_retevt_comp;
};
int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h
index ad041c96fdb8..c9ea50daffff 100644
--- a/drivers/staging/rtl8712/osdep_service.h
+++ b/drivers/staging/rtl8712/osdep_service.h
@@ -57,13 +57,6 @@ struct __queue {
spin_lock_init(&((pqueue)->lock)); \
} while (0)
-static inline u32 _down_sema(struct semaphore *sema)
-{
- if (down_interruptible(sema))
- return _FAIL;
- return _SUCCESS;
-}
-
static inline u32 end_of_queue_search(struct list_head *head,
struct list_head *plist)
{
diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c
index 735a0eadd98c..576c15d25a0f 100644
--- a/drivers/staging/rtl8712/recv_linux.c
+++ b/drivers/staging/rtl8712/recv_linux.c
@@ -60,7 +60,6 @@ int r8712_os_recvbuf_resource_alloc(struct _adapter *padapter,
if (!precvbuf->purb)
res = _FAIL;
precvbuf->pskb = NULL;
- precvbuf->reuse = false;
precvbuf->pallocated_buf = NULL;
precvbuf->pbuf = NULL;
precvbuf->pdata = NULL;
diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c
index 13c018340ff2..9f61583af150 100644
--- a/drivers/staging/rtl8712/rtl8712_cmd.c
+++ b/drivers/staging/rtl8712/rtl8712_cmd.c
@@ -264,9 +264,9 @@ static struct cmd_obj *cmd_hdl_filter(struct _adapter *padapter,
*/
if (padapter->pwrctrlpriv.pwr_mode > PS_MODE_ACTIVE) {
padapter->pwrctrlpriv.pwr_mode = PS_MODE_ACTIVE;
- _enter_pwrlock(&(padapter->pwrctrlpriv.lock));
+ mutex_lock(&padapter->pwrctrlpriv.mutex_lock);
r8712_set_rpwm(padapter, PS_STATE_S4);
- up(&(padapter->pwrctrlpriv.lock));
+ mutex_unlock(&padapter->pwrctrlpriv.mutex_lock);
}
pcmd_r = pcmd;
break;
@@ -322,7 +322,7 @@ int r8712_cmd_thread(void *context)
allow_signal(SIGTERM);
while (1) {
- if ((_down_sema(&(pcmdpriv->cmd_queue_sema))) == _FAIL)
+ if (wait_for_completion_interruptible(&pcmdpriv->cmd_queue_comp))
break;
if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
break;
@@ -395,10 +395,10 @@ _next:
}
if (pcmd->cmdcode == GEN_CMD_CODE(_SetPwrMode)) {
if (padapter->pwrctrlpriv.bSleep) {
- _enter_pwrlock(&(padapter->
- pwrctrlpriv.lock));
+ mutex_lock(&padapter->
+ pwrctrlpriv.mutex_lock);
r8712_set_rpwm(padapter, PS_STATE_S2);
- up(&padapter->pwrctrlpriv.lock);
+ mutex_unlock(&padapter->pwrctrlpriv.mutex_lock);
}
}
r8712_free_cmd_obj(pcmd);
@@ -420,7 +420,7 @@ _next:
break;
r8712_free_cmd_obj(pcmd);
} while (1);
- up(&pcmdpriv->terminate_cmdthread_sema);
+ complete(&pcmdpriv->terminate_cmdthread_comp);
thread_exit();
}
diff --git a/drivers/staging/rtl8712/rtl8712_efuse.c b/drivers/staging/rtl8712/rtl8712_efuse.c
index 76f60ba5ee9b..205298e23656 100644
--- a/drivers/staging/rtl8712/rtl8712_efuse.c
+++ b/drivers/staging/rtl8712/rtl8712_efuse.c
@@ -248,7 +248,7 @@ u8 r8712_efuse_pg_packet_read(struct _adapter *padapter, u8 offset, u8 *data)
u8 tmpdata[PGPKT_DATA_SIZE];
u8 ret = true;
- if (data == NULL)
+ if (!data)
return false;
if (offset > 0x0f)
return false;
diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c
index 9055827cccf8..a8e237e480c9 100644
--- a/drivers/staging/rtl8712/rtl8712_led.c
+++ b/drivers/staging/rtl8712/rtl8712_led.c
@@ -43,7 +43,7 @@
#define LED_BLINK_LINK_INTERVAL_ALPHA 500
#define LED_BLINK_SCAN_INTERVAL_ALPHA 180
#define LED_BLINK_FASTER_INTERVAL_ALPHA 50
-#define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA 5000
+#define LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA 5000
/*===========================================================================
* LED object.
@@ -51,17 +51,19 @@
*/
enum _LED_STATE_871x {
LED_UNKNOWN = 0,
- LED_ON = 1,
- LED_OFF = 2,
+ LED_STATE_ON = 1,
+ LED_STATE_OFF = 2,
LED_BLINK_NORMAL = 3,
LED_BLINK_SLOWLY = 4,
LED_POWER_ON_BLINK = 5,
LED_SCAN_BLINK = 6, /* LED is blinking during scanning period,
* the # of times to blink is depend on time
- * for scanning. */
+ * for scanning.
+ */
LED_NO_LINK_BLINK = 7, /* LED is blinking during no link state. */
LED_BLINK_StartToBlink = 8,/* Customized for Sercomm Printer
- * Server case */
+ * Server case
+ */
LED_BLINK_WPS = 9, /* LED is blinkg during WPS communication */
LED_TXRX_BLINK = 10,
LED_BLINK_WPS_STOP = 11, /*for ALPHA */
@@ -92,7 +94,7 @@ static void InitLed871x(struct _adapter *padapter, struct LED_871x *pLed,
nic = padapter->pnetdev;
pLed->padapter = padapter;
pLed->LedPin = LedPin;
- pLed->CurrLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
pLed->bLedOn = false;
pLed->bLedBlinkInProgress = false;
pLed->BlinkTimes = 0;
@@ -110,7 +112,8 @@ static void DeInitLed871x(struct LED_871x *pLed)
{
del_timer_sync(&pLed->BlinkTimer);
/* We should reset bLedBlinkInProgress if we cancel
- * the LedControlTimer, */
+ * the LedControlTimer,
+ */
pLed->bLedBlinkInProgress = false;
}
@@ -208,7 +211,7 @@ static void SwLedBlink(struct LED_871x *pLed)
u8 bStopBlinking = false;
/* Change LED according to BlinkingLedState specified. */
- if (pLed->BlinkingLedState == LED_ON)
+ if (pLed->BlinkingLedState == LED_STATE_ON)
SwLedOn(padapter, pLed);
else
SwLedOff(padapter, pLed);
@@ -248,10 +251,10 @@ static void SwLedBlink(struct LED_871x *pLed)
pLed->bLedBlinkInProgress = false;
} else {
/* Assign LED state to toggle. */
- if (pLed->BlinkingLedState == LED_ON)
- pLed->BlinkingLedState = LED_OFF;
+ if (pLed->BlinkingLedState == LED_STATE_ON)
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
/* Schedule a timer to toggle LED state. */
switch (pLed->CurrLedState) {
@@ -288,7 +291,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
if (peeprompriv->CustomerID == RT_CID_819x_CAMEO)
pLed = &(ledpriv->SwLed1);
/* Change LED according to BlinkingLedState specified. */
- if (pLed->BlinkingLedState == LED_ON)
+ if (pLed->BlinkingLedState == LED_STATE_ON)
SwLedOn(padapter, pLed);
else
SwLedOff(padapter, pLed);
@@ -312,17 +315,17 @@ static void SwLedBlink1(struct LED_871x *pLed)
switch (pLed->CurrLedState) {
case LED_BLINK_SLOWLY:
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
break;
case LED_BLINK_NORMAL:
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
break;
@@ -335,27 +338,27 @@ static void SwLedBlink1(struct LED_871x *pLed)
pLed->bLedLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_NORMAL;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
} else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
pLed->bLedNoLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_SLOWLY;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
}
pLed->bLedScanBlinkInProgress = false;
} else {
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
}
@@ -369,18 +372,18 @@ static void SwLedBlink1(struct LED_871x *pLed)
pLed->bLedLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_NORMAL;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
} else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
pLed->bLedNoLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_SLOWLY;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
}
@@ -388,26 +391,26 @@ static void SwLedBlink1(struct LED_871x *pLed)
pLed->bLedBlinkInProgress = false;
} else {
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
}
break;
case LED_BLINK_WPS:
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
break;
case LED_BLINK_WPS_STOP: /* WPS success */
- if (pLed->BlinkingLedState == LED_ON) {
- pLed->BlinkingLedState = LED_OFF;
+ if (pLed->BlinkingLedState == LED_STATE_ON) {
+ pLed->BlinkingLedState = LED_STATE_OFF;
mod_timer(&pLed->BlinkTimer, jiffies +
- msecs_to_jiffies(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA));
+ msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
bStopBlinking = false;
} else {
bStopBlinking = true;
@@ -416,9 +419,9 @@ static void SwLedBlink1(struct LED_871x *pLed)
pLed->bLedLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_NORMAL;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
}
@@ -436,7 +439,7 @@ static void SwLedBlink2(struct LED_871x *pLed)
u8 bStopBlinking = false;
/* Change LED according to BlinkingLedState specified. */
- if (pLed->BlinkingLedState == LED_ON)
+ if (pLed->BlinkingLedState == LED_STATE_ON)
SwLedOn(padapter, pLed);
else
SwLedOff(padapter, pLed);
@@ -447,20 +450,20 @@ static void SwLedBlink2(struct LED_871x *pLed)
bStopBlinking = true;
if (bStopBlinking) {
if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
SwLedOn(padapter, pLed);
} else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
SwLedOff(padapter, pLed);
}
pLed->bLedScanBlinkInProgress = false;
} else {
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
}
@@ -471,20 +474,20 @@ static void SwLedBlink2(struct LED_871x *pLed)
bStopBlinking = true;
if (bStopBlinking) {
if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
SwLedOn(padapter, pLed);
} else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
SwLedOff(padapter, pLed);
}
pLed->bLedBlinkInProgress = false;
} else {
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
}
@@ -501,7 +504,7 @@ static void SwLedBlink3(struct LED_871x *pLed)
u8 bStopBlinking = false;
/* Change LED according to BlinkingLedState specified. */
- if (pLed->BlinkingLedState == LED_ON)
+ if (pLed->BlinkingLedState == LED_STATE_ON)
SwLedOn(padapter, pLed);
else
if (pLed->CurrLedState != LED_BLINK_WPS_STOP)
@@ -513,22 +516,22 @@ static void SwLedBlink3(struct LED_871x *pLed)
bStopBlinking = true;
if (bStopBlinking) {
if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
if (!pLed->bLedOn)
SwLedOn(padapter, pLed);
} else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
if (pLed->bLedOn)
SwLedOff(padapter, pLed);
}
pLed->bLedScanBlinkInProgress = false;
} else {
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
}
@@ -539,46 +542,46 @@ static void SwLedBlink3(struct LED_871x *pLed)
bStopBlinking = true;
if (bStopBlinking) {
if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
if (!pLed->bLedOn)
SwLedOn(padapter, pLed);
} else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
if (pLed->bLedOn)
SwLedOff(padapter, pLed);
}
pLed->bLedBlinkInProgress = false;
} else {
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
}
break;
case LED_BLINK_WPS:
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
break;
case LED_BLINK_WPS_STOP: /*WPS success*/
- if (pLed->BlinkingLedState == LED_ON) {
- pLed->BlinkingLedState = LED_OFF;
+ if (pLed->BlinkingLedState == LED_STATE_ON) {
+ pLed->BlinkingLedState = LED_STATE_OFF;
mod_timer(&pLed->BlinkTimer, jiffies +
- msecs_to_jiffies(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA));
+ msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
bStopBlinking = false;
} else {
bStopBlinking = true;
}
if (bStopBlinking) {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
SwLedOn(padapter, pLed);
pLed->bLedWPSBlinkInProgress = false;
}
@@ -596,32 +599,32 @@ static void SwLedBlink4(struct LED_871x *pLed)
u8 bStopBlinking = false;
/* Change LED according to BlinkingLedState specified. */
- if (pLed->BlinkingLedState == LED_ON)
+ if (pLed->BlinkingLedState == LED_STATE_ON)
SwLedOn(padapter, pLed);
else
SwLedOff(padapter, pLed);
if (!pLed1->bLedWPSBlinkInProgress &&
pLed1->BlinkingLedState == LED_UNKNOWN) {
- pLed1->BlinkingLedState = LED_OFF;
- pLed1->CurrLedState = LED_OFF;
+ pLed1->BlinkingLedState = LED_STATE_OFF;
+ pLed1->CurrLedState = LED_STATE_OFF;
SwLedOff(padapter, pLed1);
}
switch (pLed->CurrLedState) {
case LED_BLINK_SLOWLY:
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
break;
case LED_BLINK_StartToBlink:
if (pLed->bLedOn) {
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
} else {
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
}
@@ -634,17 +637,17 @@ static void SwLedBlink4(struct LED_871x *pLed)
pLed->bLedNoLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_SLOWLY;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
pLed->bLedScanBlinkInProgress = false;
} else {
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
}
@@ -657,37 +660,37 @@ static void SwLedBlink4(struct LED_871x *pLed)
pLed->bLedNoLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_SLOWLY;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
pLed->bLedBlinkInProgress = false;
} else {
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
}
break;
case LED_BLINK_WPS:
if (pLed->bLedOn) {
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
} else {
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
}
break;
case LED_BLINK_WPS_STOP: /*WPS authentication fail*/
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
break;
@@ -701,14 +704,14 @@ static void SwLedBlink4(struct LED_871x *pLed)
}
if (bStopBlinking) {
pLed->BlinkTimes = 10;
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
} else {
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
}
@@ -724,7 +727,7 @@ static void SwLedBlink5(struct LED_871x *pLed)
u8 bStopBlinking = false;
/* Change LED according to BlinkingLedState specified. */
- if (pLed->BlinkingLedState == LED_ON)
+ if (pLed->BlinkingLedState == LED_STATE_ON)
SwLedOn(padapter, pLed);
else
SwLedOff(padapter, pLed);
@@ -734,17 +737,17 @@ static void SwLedBlink5(struct LED_871x *pLed)
if (pLed->BlinkTimes == 0)
bStopBlinking = true;
if (bStopBlinking) {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
if (!pLed->bLedOn)
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
pLed->bLedScanBlinkInProgress = false;
} else {
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
}
@@ -754,17 +757,17 @@ static void SwLedBlink5(struct LED_871x *pLed)
if (pLed->BlinkTimes == 0)
bStopBlinking = true;
if (bStopBlinking) {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
if (!pLed->bLedOn)
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
pLed->bLedBlinkInProgress = false;
} else {
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
}
@@ -780,7 +783,7 @@ static void SwLedBlink6(struct LED_871x *pLed)
u8 bStopBlinking = false;
/* Change LED according to BlinkingLedState specified. */
- if (pLed->BlinkingLedState == LED_ON)
+ if (pLed->BlinkingLedState == LED_STATE_ON)
SwLedOn(padapter, pLed);
else
SwLedOff(padapter, pLed);
@@ -790,25 +793,25 @@ static void SwLedBlink6(struct LED_871x *pLed)
if (pLed->BlinkTimes == 0)
bStopBlinking = true;
if (bStopBlinking) {
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
if (!pLed->bLedOn)
SwLedOn(padapter, pLed);
pLed->bLedBlinkInProgress = false;
} else {
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
}
break;
case LED_BLINK_WPS:
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
break;
@@ -827,7 +830,8 @@ static void BlinkTimerCallback(unsigned long data)
struct LED_871x *pLed = (struct LED_871x *)data;
/* This fixed the crash problem on Fedora 12 when trying to do the
- * insmod;ifconfig up;rmmod commands. */
+ * insmod;ifconfig up;rmmod commands.
+ */
if (pLed->padapter->bSurpriseRemoved || pLed->padapter->bDriverStopped)
return;
schedule_work(&pLed->BlinkWorkItem);
@@ -908,9 +912,9 @@ static void SwLedControlMode1(struct _adapter *padapter,
pLed->bLedNoLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_SLOWLY;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
}
@@ -931,9 +935,9 @@ static void SwLedControlMode1(struct _adapter *padapter,
pLed->bLedLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_NORMAL;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
}
@@ -961,9 +965,9 @@ static void SwLedControlMode1(struct _adapter *padapter,
pLed->CurrLedState = LED_SCAN_BLINK;
pLed->BlinkTimes = 24;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
}
@@ -986,9 +990,9 @@ static void SwLedControlMode1(struct _adapter *padapter,
pLed->CurrLedState = LED_TXRX_BLINK;
pLed->BlinkTimes = 2;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
}
@@ -1016,9 +1020,9 @@ static void SwLedControlMode1(struct _adapter *padapter,
pLed->bLedWPSBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_WPS;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
}
@@ -1046,11 +1050,11 @@ static void SwLedControlMode1(struct _adapter *padapter,
pLed->bLedWPSBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_WPS_STOP;
if (pLed->bLedOn) {
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
mod_timer(&pLed->BlinkTimer, jiffies +
- msecs_to_jiffies(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA));
+ msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
} else {
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer,
jiffies + msecs_to_jiffies(0));
}
@@ -1063,15 +1067,15 @@ static void SwLedControlMode1(struct _adapter *padapter,
pLed->bLedNoLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_SLOWLY;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
break;
case LED_CTL_POWER_OFF:
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
if (pLed->bLedNoLinkBlinkInProgress) {
del_timer(&pLed->BlinkTimer);
pLed->bLedNoLinkBlinkInProgress = false;
@@ -1123,9 +1127,9 @@ static void SwLedControlMode2(struct _adapter *padapter,
pLed->CurrLedState = LED_SCAN_BLINK;
pLed->BlinkTimes = 24;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
}
@@ -1142,17 +1146,17 @@ static void SwLedControlMode2(struct _adapter *padapter,
pLed->CurrLedState = LED_TXRX_BLINK;
pLed->BlinkTimes = 2;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
}
break;
case LED_CTL_LINK:
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
if (pLed->bLedBlinkInProgress) {
del_timer(&pLed->BlinkTimer);
pLed->bLedBlinkInProgress = false;
@@ -1178,8 +1182,8 @@ static void SwLedControlMode2(struct _adapter *padapter,
pLed->bLedScanBlinkInProgress = false;
}
pLed->bLedWPSBlinkInProgress = true;
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer,
jiffies + msecs_to_jiffies(0));
}
@@ -1187,16 +1191,16 @@ static void SwLedControlMode2(struct _adapter *padapter,
case LED_CTL_STOP_WPS:
pLed->bLedWPSBlinkInProgress = false;
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer,
jiffies + msecs_to_jiffies(0));
break;
case LED_CTL_STOP_WPS_FAIL:
pLed->bLedWPSBlinkInProgress = false;
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
mod_timer(&pLed->BlinkTimer,
jiffies + msecs_to_jiffies(0));
break;
@@ -1204,15 +1208,15 @@ static void SwLedControlMode2(struct _adapter *padapter,
case LED_CTL_START_TO_LINK:
case LED_CTL_NO_LINK:
if (!IS_LED_BLINKING(pLed)) {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
mod_timer(&pLed->BlinkTimer,
jiffies + msecs_to_jiffies(0));
}
break;
case LED_CTL_POWER_OFF:
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
if (pLed->bLedBlinkInProgress) {
del_timer(&pLed->BlinkTimer);
pLed->bLedBlinkInProgress = false;
@@ -1255,9 +1259,9 @@ static void SwLedControlMode3(struct _adapter *padapter,
pLed->CurrLedState = LED_SCAN_BLINK;
pLed->BlinkTimes = 24;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
}
@@ -1273,9 +1277,9 @@ static void SwLedControlMode3(struct _adapter *padapter,
pLed->CurrLedState = LED_TXRX_BLINK;
pLed->BlinkTimes = 2;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
}
@@ -1283,8 +1287,8 @@ static void SwLedControlMode3(struct _adapter *padapter,
case LED_CTL_LINK:
if (IS_LED_WPS_BLINKING(pLed))
return;
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
if (pLed->bLedBlinkInProgress) {
del_timer(&pLed->BlinkTimer);
pLed->bLedBlinkInProgress = false;
@@ -1310,9 +1314,9 @@ static void SwLedControlMode3(struct _adapter *padapter,
pLed->bLedWPSBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_WPS;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
}
@@ -1326,11 +1330,11 @@ static void SwLedControlMode3(struct _adapter *padapter,
}
pLed->CurrLedState = LED_BLINK_WPS_STOP;
if (pLed->bLedOn) {
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
mod_timer(&pLed->BlinkTimer, jiffies +
- msecs_to_jiffies(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA));
+ msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
} else {
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer,
jiffies + msecs_to_jiffies(0));
}
@@ -1340,23 +1344,23 @@ static void SwLedControlMode3(struct _adapter *padapter,
del_timer(&pLed->BlinkTimer);
pLed->bLedWPSBlinkInProgress = false;
}
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
mod_timer(&pLed->BlinkTimer,
jiffies + msecs_to_jiffies(0));
break;
case LED_CTL_START_TO_LINK:
case LED_CTL_NO_LINK:
if (!IS_LED_BLINKING(pLed)) {
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
mod_timer(&pLed->BlinkTimer,
jiffies + msecs_to_jiffies(0));
}
break;
case LED_CTL_POWER_OFF:
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
if (pLed->bLedBlinkInProgress) {
del_timer(&pLed->BlinkTimer);
pLed->bLedBlinkInProgress = false;
@@ -1390,8 +1394,8 @@ static void SwLedControlMode4(struct _adapter *padapter,
if (pLed1->bLedWPSBlinkInProgress) {
pLed1->bLedWPSBlinkInProgress = false;
del_timer(&pLed1->BlinkTimer);
- pLed1->BlinkingLedState = LED_OFF;
- pLed1->CurrLedState = LED_OFF;
+ pLed1->BlinkingLedState = LED_STATE_OFF;
+ pLed1->CurrLedState = LED_STATE_OFF;
if (pLed1->bLedOn)
mod_timer(&pLed->BlinkTimer,
jiffies + msecs_to_jiffies(0));
@@ -1411,11 +1415,11 @@ static void SwLedControlMode4(struct _adapter *padapter,
pLed->bLedStartToLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_StartToBlink;
if (pLed->bLedOn) {
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
} else {
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
}
@@ -1428,8 +1432,8 @@ static void SwLedControlMode4(struct _adapter *padapter,
if (pLed1->bLedWPSBlinkInProgress) {
pLed1->bLedWPSBlinkInProgress = false;
del_timer(&pLed1->BlinkTimer);
- pLed1->BlinkingLedState = LED_OFF;
- pLed1->CurrLedState = LED_OFF;
+ pLed1->BlinkingLedState = LED_STATE_OFF;
+ pLed1->CurrLedState = LED_STATE_OFF;
if (pLed1->bLedOn)
mod_timer(&pLed->BlinkTimer,
jiffies + msecs_to_jiffies(0));
@@ -1446,9 +1450,9 @@ static void SwLedControlMode4(struct _adapter *padapter,
pLed->bLedNoLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_SLOWLY;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
}
@@ -1472,9 +1476,9 @@ static void SwLedControlMode4(struct _adapter *padapter,
pLed->CurrLedState = LED_SCAN_BLINK;
pLed->BlinkTimes = 24;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
}
@@ -1493,9 +1497,9 @@ static void SwLedControlMode4(struct _adapter *padapter,
pLed->CurrLedState = LED_TXRX_BLINK;
pLed->BlinkTimes = 2;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
}
@@ -1505,8 +1509,8 @@ static void SwLedControlMode4(struct _adapter *padapter,
if (pLed1->bLedWPSBlinkInProgress) {
pLed1->bLedWPSBlinkInProgress = false;
del_timer(&pLed1->BlinkTimer);
- pLed1->BlinkingLedState = LED_OFF;
- pLed1->CurrLedState = LED_OFF;
+ pLed1->BlinkingLedState = LED_STATE_OFF;
+ pLed1->CurrLedState = LED_STATE_OFF;
if (pLed1->bLedOn)
mod_timer(&pLed->BlinkTimer,
jiffies + msecs_to_jiffies(0));
@@ -1527,11 +1531,11 @@ static void SwLedControlMode4(struct _adapter *padapter,
pLed->bLedWPSBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_WPS;
if (pLed->bLedOn) {
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
} else {
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
}
@@ -1545,9 +1549,9 @@ static void SwLedControlMode4(struct _adapter *padapter,
pLed->bLedNoLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_SLOWLY;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
break;
@@ -1559,9 +1563,9 @@ static void SwLedControlMode4(struct _adapter *padapter,
pLed->bLedNoLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_SLOWLY;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
/*LED1 settings*/
@@ -1571,9 +1575,9 @@ static void SwLedControlMode4(struct _adapter *padapter,
pLed1->bLedWPSBlinkInProgress = true;
pLed1->CurrLedState = LED_BLINK_WPS_STOP;
if (pLed1->bLedOn)
- pLed1->BlinkingLedState = LED_OFF;
+ pLed1->BlinkingLedState = LED_STATE_OFF;
else
- pLed1->BlinkingLedState = LED_ON;
+ pLed1->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
break;
@@ -1585,9 +1589,9 @@ static void SwLedControlMode4(struct _adapter *padapter,
pLed->bLedNoLinkBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_SLOWLY;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
/*LED1 settings*/
@@ -1598,15 +1602,15 @@ static void SwLedControlMode4(struct _adapter *padapter,
pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP;
pLed1->BlinkTimes = 10;
if (pLed1->bLedOn)
- pLed1->BlinkingLedState = LED_OFF;
+ pLed1->BlinkingLedState = LED_STATE_OFF;
else
- pLed1->BlinkingLedState = LED_ON;
+ pLed1->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
break;
case LED_CTL_POWER_OFF:
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
if (pLed->bLedNoLinkBlinkInProgress) {
del_timer(&pLed->BlinkTimer);
pLed->bLedNoLinkBlinkInProgress = false;
@@ -1660,8 +1664,8 @@ static void SwLedControlMode5(struct _adapter *padapter,
case LED_CTL_LINK: /* solid blue */
if (pLed->CurrLedState == LED_SCAN_BLINK)
return;
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
pLed->bLedBlinkInProgress = false;
mod_timer(&pLed->BlinkTimer,
jiffies + msecs_to_jiffies(0));
@@ -1679,9 +1683,9 @@ static void SwLedControlMode5(struct _adapter *padapter,
pLed->CurrLedState = LED_SCAN_BLINK;
pLed->BlinkTimes = 24;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
}
@@ -1695,16 +1699,16 @@ static void SwLedControlMode5(struct _adapter *padapter,
pLed->CurrLedState = LED_TXRX_BLINK;
pLed->BlinkTimes = 2;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
}
break;
case LED_CTL_POWER_OFF:
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
if (pLed->bLedBlinkInProgress) {
del_timer(&pLed->BlinkTimer);
pLed->bLedBlinkInProgress = false;
@@ -1731,8 +1735,8 @@ static void SwLedControlMode6(struct _adapter *padapter,
case LED_CTL_SITE_SURVEY:
if (IS_LED_WPS_BLINKING(pLed))
return;
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
pLed->bLedBlinkInProgress = false;
mod_timer(&(pLed->BlinkTimer), jiffies + msecs_to_jiffies(0));
break;
@@ -1746,9 +1750,9 @@ static void SwLedControlMode6(struct _adapter *padapter,
pLed->CurrLedState = LED_TXRX_BLINK;
pLed->BlinkTimes = 2;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
}
@@ -1763,9 +1767,9 @@ static void SwLedControlMode6(struct _adapter *padapter,
pLed->bLedWPSBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_WPS;
if (pLed->bLedOn)
- pLed->BlinkingLedState = LED_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
else
- pLed->BlinkingLedState = LED_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer, jiffies +
msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
}
@@ -1776,14 +1780,14 @@ static void SwLedControlMode6(struct _adapter *padapter,
del_timer(&pLed->BlinkTimer);
pLed->bLedWPSBlinkInProgress = false;
}
- pLed->CurrLedState = LED_ON;
- pLed->BlinkingLedState = LED_ON;
+ pLed->CurrLedState = LED_STATE_ON;
+ pLed->BlinkingLedState = LED_STATE_ON;
mod_timer(&pLed->BlinkTimer,
jiffies + msecs_to_jiffies(0));
break;
case LED_CTL_POWER_OFF:
- pLed->CurrLedState = LED_OFF;
- pLed->BlinkingLedState = LED_OFF;
+ pLed->CurrLedState = LED_STATE_OFF;
+ pLed->BlinkingLedState = LED_STATE_OFF;
if (pLed->bLedBlinkInProgress) {
del_timer(&pLed->BlinkTimer);
pLed->bLedBlinkInProgress = false;
diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c
index f25b34c7d115..66f0e0a35167 100644
--- a/drivers/staging/rtl8712/rtl8712_recv.c
+++ b/drivers/staging/rtl8712/rtl8712_recv.c
@@ -60,7 +60,7 @@ int r8712_init_recv_priv(struct recv_priv *precvpriv, struct _adapter *padapter)
_init_queue(&precvpriv->free_recv_buf_queue);
precvpriv->pallocated_recv_buf =
kzalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4, GFP_ATOMIC);
- if (precvpriv->pallocated_recv_buf == NULL)
+ if (!precvpriv->pallocated_recv_buf)
return _FAIL;
precvpriv->precv_buf = precvpriv->pallocated_recv_buf + 4 -
((addr_t) (precvpriv->pallocated_recv_buf) & 3);
@@ -163,7 +163,8 @@ static void update_recvframe_attrib_from_recvstat(struct rx_pkt_attrib *pattrib,
drvinfo_sz = (le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16;
drvinfo_sz <<= 3;
/*TODO:
- * Offset 0 */
+ * Offset 0
+ */
pattrib->bdecrypted = ((le32_to_cpu(prxstat->rxdw0) & BIT(27)) >> 27)
? 0 : 1;
pattrib->crc_err = (le32_to_cpu(prxstat->rxdw0) & BIT(14)) >> 14;
@@ -210,7 +211,8 @@ static union recv_frame *recvframe_defrag(struct _adapter *adapter,
curfragnum = 0;
if (curfragnum != pfhdr->attrib.frag_num) {
/*the first fragment number must be 0
- *free the whole queue*/
+ *free the whole queue
+ */
r8712_free_recvframe(prframe, pfree_recv_queue);
r8712_free_recvframe_queue(defrag_q, pfree_recv_queue);
return NULL;
@@ -224,18 +226,21 @@ static union recv_frame *recvframe_defrag(struct _adapter *adapter,
/*check the fragment sequence (2nd ~n fragment frame) */
if (curfragnum != pnfhdr->attrib.frag_num) {
/* the fragment number must increase (after decache)
- * release the defrag_q & prframe */
+ * release the defrag_q & prframe
+ */
r8712_free_recvframe(prframe, pfree_recv_queue);
r8712_free_recvframe_queue(defrag_q, pfree_recv_queue);
return NULL;
}
curfragnum++;
/* copy the 2nd~n fragment frame's payload to the first fragment
- * get the 2nd~last fragment frame's payload */
+ * get the 2nd~last fragment frame's payload
+ */
wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
recvframe_pull(pnextrframe, wlanhdr_offset);
/* append to first fragment frame's tail (if privacy frame,
- * pull the ICV) */
+ * pull the ICV)
+ */
recvframe_pull_tail(prframe, pfhdr->attrib.icv_len);
memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len);
recvframe_put(prframe, pnfhdr->len);
@@ -269,7 +274,7 @@ union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter,
fragnum = pfhdr->attrib.frag_num;
psta_addr = pfhdr->attrib.ta;
psta = r8712_get_stainfo(pstapriv, psta_addr);
- if (psta == NULL)
+ if (!psta)
pdefrag_q = NULL;
else
pdefrag_q = &psta->sta_recvpriv.defrag_q;
@@ -278,7 +283,8 @@ union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter,
prtnframe = precv_frame;/*isn't a fragment frame*/
if (ismfrag == 1) {
/* 0~(n-1) fragment frame
- * enqueue to defraf_g */
+ * enqueue to defraf_g
+ */
if (pdefrag_q != NULL) {
if (fragnum == 0) {
/*the first fragment*/
@@ -294,7 +300,8 @@ union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter,
prtnframe = NULL;
} else {
/* can't find this ta's defrag_queue, so free this
- * recv_frame */
+ * recv_frame
+ */
r8712_free_recvframe(precv_frame, pfree_recv_queue);
prtnframe = NULL;
}
@@ -302,7 +309,8 @@ union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter,
}
if ((ismfrag == 0) && (fragnum != 0)) {
/* the last fragment frame
- * enqueue the last fragment */
+ * enqueue the last fragment
+ */
if (pdefrag_q != NULL) {
phead = &pdefrag_q->queue;
list_add_tail(&pfhdr->list, phead);
@@ -311,7 +319,8 @@ union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter,
prtnframe = precv_frame;
} else {
/* can't find this ta's defrag_queue, so free this
- * recv_frame */
+ * recv_frame
+ */
r8712_free_recvframe(precv_frame, pfree_recv_queue);
prtnframe = NULL;
}
@@ -391,7 +400,8 @@ static int amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe)
eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
!memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE))) {
/* remove RFC1042 or Bridge-Tunnel encapsulation and
- * replace EtherType */
+ * replace EtherType
+ */
skb_pull(sub_skb, SNAP_SIZE);
memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src,
ETH_ALEN);
@@ -530,7 +540,8 @@ int r8712_recv_indicatepkts_in_order(struct _adapter *padapter,
preorder_ctrl->indicate_seq = pattrib->seq_num;
}
/* Prepare indication list and indication.
- * Check if there is any packet need indicate. */
+ * Check if there is any packet need indicate.
+ */
while (!list_empty(phead)) {
prframe = container_of(plist, union recv_frame, u.list);
pattrib = &prframe->u.hdr.attrib;
@@ -757,7 +768,8 @@ static void query_rx_phy_status(struct _adapter *padapter,
/* Modify the RF RNA gain value to -40, -20,
* -2, 14 by Jenyu's suggestion
* Note: different RF with the different
- * RNA gain. */
+ * RNA gain.
+ */
case 0x3:
rx_pwr_all = -40 - (pcck_buf->cck_agc_rpt &
0x3e);
@@ -842,7 +854,8 @@ static void query_rx_phy_status(struct _adapter *padapter,
total_rssi += rssi;
}
/* (2)PWDB, Average PWDB cacluated by hardware (for
- * rate adaptive) */
+ * rate adaptive)
+ */
rx_pwr_all = (((pphy_head[PHY_STAT_PWDB_ALL_SHT]) >> 1) & 0x7f)
- 106;
pwdb_all = query_rx_pwr_percentage(rx_pwr_all);
@@ -870,7 +883,8 @@ static void query_rx_phy_status(struct _adapter *padapter,
}
/* UI BSS List signal strength(in percentage), make it good looking,
* from 0~100. It is assigned to the BSS List in
- * GetValueFromBeaconOrProbeRsp(). */
+ * GetValueFromBeaconOrProbeRsp().
+ */
if (bcck_rate)
prframe->u.hdr.attrib.signal_strength =
(u8)r8712_signal_scale_mapping(pwdb_all);
@@ -985,15 +999,15 @@ int recv_func(struct _adapter *padapter, void *pcontext)
}
process_phy_info(padapter, prframe);
prframe = r8712_decryptor(padapter, prframe);
- if (prframe == NULL) {
+ if (!prframe) {
retval = _FAIL;
goto _exit_recv_func;
}
prframe = r8712_recvframe_chk_defrag(padapter, prframe);
- if (prframe == NULL)
+ if (!prframe)
goto _exit_recv_func;
prframe = r8712_portctrl(padapter, prframe);
- if (prframe == NULL) {
+ if (!prframe) {
retval = _FAIL;
goto _exit_recv_func;
}
@@ -1027,10 +1041,12 @@ static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb)
transfer_len = pskb->len;
/* Test throughput with Netgear 3700 (No security) with Chariot 3T3R
* pairs. The packet count will be a big number so that the containing
- * packet will effect the Rx reordering. */
+ * packet will effect the Rx reordering.
+ */
if (transfer_len < pkt_len) {
/* In this case, it means the MAX_RECVBUF_SZ is too small to
- * get the data from 8712u. */
+ * get the data from 8712u.
+ */
return _FAIL;
}
do {
@@ -1049,7 +1065,7 @@ static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb)
if ((le32_to_cpu(prxstat->rxdw0) >> 23) & 0x01)
shift_sz = 2;
precvframe = r8712_alloc_recvframe(pfree_recv_queue);
- if (precvframe == NULL)
+ if (!precvframe)
goto _exit_recvbuf2recvframe;
INIT_LIST_HEAD(&precvframe->u.hdr.list);
precvframe->u.hdr.precvbuf = NULL; /*can't access the precvbuf*/
@@ -1057,14 +1073,16 @@ static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb)
tmp_len = pkt_len + drvinfo_sz + RXDESC_SIZE;
pkt_offset = (u16)round_up(tmp_len, 128);
/* for first fragment packet, driver need allocate 1536 +
- * drvinfo_sz + RXDESC_SIZE to defrag packet. */
+ * drvinfo_sz + RXDESC_SIZE to defrag packet.
+ */
if ((mf == 1) && (frag == 0))
/*1658+6=1664, 1664 is 128 alignment.*/
alloc_sz = max_t(u16, tmp_len, 1658);
else
alloc_sz = tmp_len;
/* 2 is for IP header 4 bytes alignment in QoS packet case.
- * 4 is for skb->data 4 bytes alignment. */
+ * 4 is for skb->data 4 bytes alignment.
+ */
alloc_sz += 6;
pkt_copy = netdev_alloc_skb(padapter->pnetdev, alloc_sz);
if (pkt_copy) {
diff --git a/drivers/staging/rtl8712/rtl8712_recv.h b/drivers/staging/rtl8712/rtl8712_recv.h
index fd9e3fc4c226..0b0c2730aac5 100644
--- a/drivers/staging/rtl8712/rtl8712_recv.h
+++ b/drivers/staging/rtl8712/rtl8712_recv.h
@@ -61,7 +61,8 @@ struct recv_stat {
struct phy_cck_rx_status {
/* For CCK rate descriptor. This is a unsigned 8:1 variable.
* LSB bit present 0.5. And MSB 7 bts present a signed value.
- * Range from -64~+63.5. */
+ * Range from -64~+63.5.
+ */
u8 adc_pwdb_X[4];
u8 sq_rpt;
u8 cck_agc_rpt;
@@ -103,7 +104,6 @@ struct recv_buf {
struct _adapter *adapter;
struct urb *purb;
_pkt *pskb;
- u8 reuse;
u8 irp_pending;
u32 transfer_len;
uint len;
@@ -116,13 +116,13 @@ struct recv_buf {
};
/*
- head ----->
- data ----->
- payload
- tail ----->
- end ----->
- len = (unsigned int )(tail - data);
-*/
+ * head ----->
+ * data ----->
+ * payload
+ * tail ----->
+ * end ----->
+ * len = (unsigned int )(tail - data);
+ */
struct recv_frame_hdr {
struct list_head list;
_pkt *pkt;
diff --git a/drivers/staging/rtl8712/rtl8712_spec.h b/drivers/staging/rtl8712/rtl8712_spec.h
index af11b44b1140..51e042815cc9 100644
--- a/drivers/staging/rtl8712/rtl8712_spec.h
+++ b/drivers/staging/rtl8712/rtl8712_spec.h
@@ -83,7 +83,8 @@
#define CMD_ADDR_MAPPING_SHIFT 2 /*SDIO CMD ADDR MAPPING,
*shift 2 bit for match
- * offset[14:2]*/
+ * offset[14:2]
+ */
/*Offset for SDIO LOCAL*/
#define OFFSET_SDIO_LOCAL 0x0FFF
diff --git a/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h b/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h
index eed09c872fc9..2e66d28d6918 100644
--- a/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h
+++ b/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h
@@ -68,11 +68,13 @@
#define SYS_CLKSEL BIT(SYS_CLKSEL_SHT) /* System Clock 80MHz*/
#define PS_CLKSEL_SHT 1
#define PS_CLKSEL BIT(PS_CLKSEL_SHT) /*System power save
- * clock select.*/
+ * clock select.
+ */
#define CPU_CLKSEL_SHT 2
#define CPU_CLKSEL BIT(CPU_CLKSEL_SHT) /* System Clock select,
* 1: AFE source,
- * 0: System clock(L-Bus)*/
+ * 0: System clock(L-Bus)
+ */
#define INT32K_EN_SHT 3
#define INT32K_EN BIT(INT32K_EN_SHT)
#define MACSLP_SHT 4
@@ -85,10 +87,12 @@
#define RING_CLK_EN BIT(RING_CLK_EN_SHT)
#define SWHW_SEL_SHT 14
#define SWHW_SEL BIT(SWHW_SEL_SHT) /* Load done,
- * control path switch.*/
+ * control path switch.
+ */
#define FWHW_SEL_SHT 15
#define FWHW_SEL BIT(FWHW_SEL_SHT) /* Sleep exit,
- * control path switch.*/
+ * control path switch.
+ */
/*9346CR*/
#define _VPDIDX_MSK 0xFF00
@@ -118,10 +122,12 @@
#define AFE_MISC_E32_EN BIT(AFE_MISC_E32_EN_SHT)
#define AFE_MISC_MBEN_SHT 1
#define AFE_MISC_MBEN BIT(AFE_MISC_MBEN_SHT)/* Enable AFE Macro
- * Block's Mbias.*/
+ * Block's Mbias.
+ */
#define AFE_MISC_BGEN_SHT 0
#define AFE_MISC_BGEN BIT(AFE_MISC_BGEN_SHT)/* Enable AFE Macro
- * Block's Bandgap.*/
+ * Block's Bandgap.
+ */
/*--------------------------------------------------------------------------*/
@@ -149,10 +155,12 @@
/* EFUSE_CTRL*/
#define EF_FLAG BIT(31) /* Access Flag, Write:1;
- * Read:0*/
+ * Read:0
+ */
#define EF_PGPD 0x70000000 /* E-fuse Program time*/
#define EF_RDT 0x0F000000 /* E-fuse read time: in the
- * unit of cycle time*/
+ * unit of cycle time
+ */
#define EF_PDN_EN BIT(19) /* EFuse Power down enable*/
#define ALD_EN BIT(18) /* Autoload Enable*/
#define EF_ADDR 0x0003FF00 /* Access Address*/
@@ -164,7 +172,8 @@
/* EFUSE_CLK_CTRL*/
#define EFUSE_CLK_EN BIT(1) /* E-Fuse Clock Enable*/
#define EFUSE_CLK_SEL BIT(0) /* E-Fuse Clock Select,
- * 0:500K, 1:40M*/
+ * 0:500K, 1:40M
+ */
#endif /*__RTL8712_SYSCFG_BITDEF_H__*/
diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c
index 7e0b94503dfc..c4f03a602a2e 100644
--- a/drivers/staging/rtl8712/rtl8712_xmit.c
+++ b/drivers/staging/rtl8712/rtl8712_xmit.c
@@ -535,7 +535,8 @@ static void update_txdesc(struct xmit_frame *pxmitframe, uint *pmem, int sz)
* seqnum per tid. about usb using 4-endpoint, qsel points out
* the correct mapping between AC&Endpoint,
* the purpose is that correct mapping lets the MAC release
- * the AC Queue list correctly. */
+ * the AC Queue list correctly.
+ */
ptxdesc->txdw3 = cpu_to_le32((pattrib->priority << SEQ_SHT) &
0x0fff0000);
if ((pattrib->ether_type != 0x888e) &&
@@ -586,7 +587,8 @@ static void update_txdesc(struct xmit_frame *pxmitframe, uint *pmem, int sz)
* per tid. about usb using 4-endpoint, qsel points out the
* correct mapping between AC&Endpoint,
* the purpose is that correct mapping let the MAC releases
- * the AC Queue list correctly. */
+ * the AC Queue list correctly.
+ */
ptxdesc->txdw3 = cpu_to_le32((pattrib->priority << SEQ_SHT) &
0x0fff0000);
/* offset 16 */
@@ -627,7 +629,7 @@ int r8712_xmitframe_complete(struct _adapter *padapter,
phwxmits = pxmitpriv->hwxmits;
hwentry = pxmitpriv->hwxmit_entry;
- if (pxmitbuf == NULL) {
+ if (!pxmitbuf) {
pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv);
if (!pxmitbuf)
return false;
@@ -686,7 +688,8 @@ int r8712_xmitframe_complete(struct _adapter *padapter,
res = r8712_xmitframe_coalesce(padapter,
pxmitframe->pkt, pxmitframe);
/* always return ndis_packet after
- * r8712_xmitframe_coalesce */
+ * r8712_xmitframe_coalesce
+ */
r8712_xmit_complete(padapter, pxmitframe);
}
if (res == _SUCCESS)
diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c
index aed03cfbb1ba..b7ee5e63af33 100644
--- a/drivers/staging/rtl8712/rtl871x_cmd.c
+++ b/drivers/staging/rtl8712/rtl871x_cmd.c
@@ -51,14 +51,14 @@
#include "mlme_osdep.h"
/*
-Caller and the r8712_cmd_thread can protect cmd_q by spin_lock.
-No irqsave is necessary.
-*/
+ * Caller and the r8712_cmd_thread can protect cmd_q by spin_lock.
+ * No irqsave is necessary.
+ */
static sint _init_cmd_priv(struct cmd_priv *pcmdpriv)
{
- sema_init(&(pcmdpriv->cmd_queue_sema), 0);
- sema_init(&(pcmdpriv->terminate_cmdthread_sema), 0);
+ init_completion(&pcmdpriv->cmd_queue_comp);
+ init_completion(&pcmdpriv->terminate_cmdthread_comp);
_init_queue(&(pcmdpriv->cmd_queue));
@@ -66,13 +66,13 @@ static sint _init_cmd_priv(struct cmd_priv *pcmdpriv)
pcmdpriv->cmd_seq = 1;
pcmdpriv->cmd_allocated_buf = kmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ,
GFP_ATOMIC);
- if (pcmdpriv->cmd_allocated_buf == NULL)
+ if (!pcmdpriv->cmd_allocated_buf)
return _FAIL;
pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ -
((addr_t)(pcmdpriv->cmd_allocated_buf) &
(CMDBUFF_ALIGN_SZ - 1));
pcmdpriv->rsp_allocated_buf = kmalloc(MAX_RSPSZ + 4, GFP_ATOMIC);
- if (pcmdpriv->rsp_allocated_buf == NULL)
+ if (!pcmdpriv->rsp_allocated_buf)
return _FAIL;
pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 -
((addr_t)(pcmdpriv->rsp_allocated_buf) & 3);
@@ -88,7 +88,7 @@ static sint _init_evt_priv(struct evt_priv *pevtpriv)
pevtpriv->event_seq = 0;
pevtpriv->evt_allocated_buf = kmalloc(MAX_EVTSZ + 4, GFP_ATOMIC);
- if (pevtpriv->evt_allocated_buf == NULL)
+ if (!pevtpriv->evt_allocated_buf)
return _FAIL;
pevtpriv->evt_buf = pevtpriv->evt_allocated_buf + 4 -
((addr_t)(pevtpriv->evt_allocated_buf) & 3);
@@ -110,20 +110,20 @@ static void _free_cmd_priv(struct cmd_priv *pcmdpriv)
}
/*
-Calling Context:
-
-_enqueue_cmd can only be called between kernel thread,
-since only spin_lock is used.
-
-ISR/Call-Back functions can't call this sub-function.
-
-*/
+ * Calling Context:
+ *
+ * _enqueue_cmd can only be called between kernel thread,
+ * since only spin_lock is used.
+ *
+ * ISR/Call-Back functions can't call this sub-function.
+ *
+ */
static sint _enqueue_cmd(struct __queue *queue, struct cmd_obj *obj)
{
unsigned long irqL;
- if (obj == NULL)
+ if (!obj)
return _SUCCESS;
spin_lock_irqsave(&queue->lock, irqL);
list_add_tail(&obj->list, &queue->queue);
@@ -172,7 +172,7 @@ u32 r8712_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj)
if (pcmdpriv->padapter->eeprompriv.bautoload_fail_flag)
return _FAIL;
res = _enqueue_cmd(&pcmdpriv->cmd_queue, obj);
- up(&pcmdpriv->cmd_queue_sema);
+ complete(&pcmdpriv->cmd_queue_comp);
return res;
}
@@ -181,7 +181,7 @@ u32 r8712_enqueue_cmd_ex(struct cmd_priv *pcmdpriv, struct cmd_obj *obj)
unsigned long irqL;
struct __queue *queue;
- if (obj == NULL)
+ if (!obj)
return _SUCCESS;
if (pcmdpriv->padapter->eeprompriv.bautoload_fail_flag)
return _FAIL;
@@ -189,7 +189,7 @@ u32 r8712_enqueue_cmd_ex(struct cmd_priv *pcmdpriv, struct cmd_obj *obj)
spin_lock_irqsave(&queue->lock, irqL);
list_add_tail(&obj->list, &queue->queue);
spin_unlock_irqrestore(&queue->lock, irqL);
- up(&pcmdpriv->cmd_queue_sema);
+ complete(&pcmdpriv->cmd_queue_comp);
return _SUCCESS;
}
@@ -211,11 +211,11 @@ void r8712_free_cmd_obj(struct cmd_obj *pcmd)
}
/*
-r8712_sitesurvey_cmd(~)
- ### NOTE:#### (!!!!)
- MUST TAKE CARE THAT BEFORE CALLING THIS FUNC,
- YOU SHOULD HAVE LOCKED pmlmepriv->lock
-*/
+ * r8712_sitesurvey_cmd(~)
+ * ### NOTE:#### (!!!!)
+ * MUST TAKE CARE THAT BEFORE CALLING THIS FUNC,
+ * YOU SHOULD HAVE LOCKED pmlmepriv->lock
+ */
u8 r8712_sitesurvey_cmd(struct _adapter *padapter,
struct ndis_802_11_ssid *pssid)
{
@@ -477,7 +477,7 @@ u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork)
}
}
psecnetwork = &psecuritypriv->sec_bss;
- if (psecnetwork == NULL) {
+ if (!psecnetwork) {
kfree(pcmd);
return _FAIL;
}
@@ -491,8 +491,9 @@ u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork)
memcpy(&psecuritypriv->authenticator_ie[1],
&psecnetwork->IEs[12], (256 - 1));
psecnetwork->IELength = 0;
- /* If the driver wants to use the bssid to create the connection.
- * If not, we copy the connecting AP's MAC address to it so that
+ /*
+ * If the driver wants to use the bssid to create the connection.
+ * If not, we copy the connecting AP's MAC address to it so that
* the driver just has the bssid information for PMKIDList searching.
*/
if (!pmlmepriv->assoc_by_bssid)
@@ -519,7 +520,8 @@ u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork)
}
}
if (pregistrypriv->ht_enable) {
- /* For WEP mode, we will use the bg mode to do the connection
+ /*
+ * For WEP mode, we will use the bg mode to do the connection
* to avoid some IOT issues, especially for Realtek 8192u
* SoftAP.
*/
@@ -882,16 +884,16 @@ void r8712_createbss_cmd_callback(struct _adapter *padapter,
if (!psta) {
psta = r8712_alloc_stainfo(&padapter->stapriv,
pnetwork->MacAddress);
- if (psta == NULL)
+ if (!psta)
goto createbss_cmd_fail;
}
r8712_indicate_connect(padapter);
} else {
pwlan = _r8712_alloc_network(pmlmepriv);
- if (pwlan == NULL) {
+ if (!pwlan) {
pwlan = r8712_get_oldest_wlan_network(
&pmlmepriv->scanned_queue);
- if (pwlan == NULL)
+ if (!pwlan)
goto createbss_cmd_fail;
pwlan->last_scanned = jiffies;
} else
@@ -904,8 +906,10 @@ void r8712_createbss_cmd_callback(struct _adapter *padapter,
(r8712_get_wlan_bssid_ex_sz(pnetwork)));
if (pmlmepriv->fw_state & _FW_UNDER_LINKING)
pmlmepriv->fw_state ^= _FW_UNDER_LINKING;
- /* we will set _FW_LINKED when there is one more sat to
- * join us (stassoc_event_callback) */
+ /*
+ * we will set _FW_LINKED when there is one more sat to
+ * join us (stassoc_event_callback)
+ */
}
createbss_cmd_fail:
spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
@@ -921,7 +925,7 @@ void r8712_setstaKey_cmdrsp_callback(struct _adapter *padapter,
struct sta_info *psta = r8712_get_stainfo(pstapriv,
psetstakey_rsp->addr);
- if (psta == NULL)
+ if (!psta)
goto exit;
psta->aid = psta->mac_id = psetstakey_rsp->keyid; /*CAM_ID(CAM_ENTRY)*/
exit:
@@ -941,7 +945,7 @@ void r8712_setassocsta_cmdrsp_callback(struct _adapter *padapter,
struct sta_info *psta = r8712_get_stainfo(pstapriv,
passocsta_parm->addr);
- if (psta == NULL)
+ if (!psta)
return;
psta->aid = psta->mac_id = passocsta_rsp->cam_id;
spin_lock_irqsave(&pmlmepriv->lock, irqL);
diff --git a/drivers/staging/rtl8712/rtl871x_cmd.h b/drivers/staging/rtl8712/rtl871x_cmd.h
index e4a2a50c85de..3284dcf2f1a9 100644
--- a/drivers/staging/rtl8712/rtl871x_cmd.h
+++ b/drivers/staging/rtl8712/rtl871x_cmd.h
@@ -50,8 +50,8 @@ struct cmd_obj {
};
struct cmd_priv {
- struct semaphore cmd_queue_sema;
- struct semaphore terminate_cmdthread_sema;
+ struct completion cmd_queue_comp;
+ struct completion terminate_cmdthread_comp;
struct __queue cmd_queue;
u8 cmd_seq;
u8 *cmd_buf; /*shall be non-paged, and 4 bytes aligned*/
@@ -185,10 +185,12 @@ struct setauth_parm {
*/
struct setkey_parm {
u8 algorithm; /* encryption algorithm, could be none, wep40,
- * TKIP, CCMP, wep104 */
+ * TKIP, CCMP, wep104
+ */
u8 keyid;
u8 grpkey; /* 1: this is the grpkey for 802.1x.
- * 0: this is the unicast key for 802.1x */
+ * 0: this is the unicast key for 802.1x
+ */
u8 key[16]; /* this could be 40 or 104 */
};
@@ -215,15 +217,15 @@ struct SetMacAddr_param {
};
/*
-Caller Ad-Hoc/AP
-
-Command -Rsp(AID == CAMID) mode
-
-This is to force fw to add an sta_data entry per driver's request.
-
-FW will write an cam entry associated with it.
-
-*/
+ * Caller Ad-Hoc/AP
+ *
+ * Command -Rsp(AID == CAMID) mode
+ *
+ * This is to force fw to add an sta_data entry per driver's request.
+ *
+ * FW will write an cam entry associated with it.
+ *
+ */
struct set_assocsta_parm {
u8 addr[ETH_ALEN];
};
@@ -234,27 +236,27 @@ struct set_assocsta_rsp {
};
/*
- Caller Ad-Hoc/AP
-
- Command mode
-
- This is to force fw to del an sta_data entry per driver's request
-
- FW will invalidate the cam entry associated with it.
-
-*/
+ * Caller Ad-Hoc/AP
+ *
+ * Command mode
+ *
+ * This is to force fw to del an sta_data entry per driver's request
+ *
+ * FW will invalidate the cam entry associated with it.
+ *
+ */
struct del_assocsta_parm {
u8 addr[ETH_ALEN];
};
/*
-Caller Mode: AP/Ad-HoC(M)
-
-Notes: To notify fw that given staid has changed its power state
-
-Command Mode
-
-*/
+ * Caller Mode: AP/Ad-HoC(M)
+ *
+ * Notes: To notify fw that given staid has changed its power state
+ *
+ * Command Mode
+ *
+ */
struct setstapwrstate_parm {
u8 staid;
u8 status;
@@ -262,25 +264,25 @@ struct setstapwrstate_parm {
};
/*
-Caller Mode: Any
-
-Notes: To setup the basic rate of RTL8711
-
-Command Mode
-
-*/
+ * Caller Mode: Any
+ *
+ * Notes: To setup the basic rate of RTL8711
+ *
+ * Command Mode
+ *
+ */
struct setbasicrate_parm {
u8 basicrates[NumRates];
};
/*
-Caller Mode: Any
-
-Notes: To read the current basic rate
-
-Command-Rsp Mode
-
-*/
+ * Caller Mode: Any
+ *
+ * Notes: To read the current basic rate
+ *
+ * Command-Rsp Mode
+ *
+ */
struct getbasicrate_parm {
u32 rsvd;
};
@@ -290,13 +292,13 @@ struct getbasicrate_rsp {
};
/*
-Caller Mode: Any
-
-Notes: To setup the data rate of RTL8711
-
-Command Mode
-
-*/
+ * Caller Mode: Any
+ *
+ * Notes: To setup the data rate of RTL8711
+ *
+ * Command Mode
+ *
+ */
struct setdatarate_parm {
u8 mac_id;
u8 datarates[NumRates];
@@ -332,13 +334,13 @@ struct SetChannelPlan_param {
};
/*
-Caller Mode: Any
-
-Notes: To read the current data rate
-
-Command-Rsp Mode
-
-*/
+ * Caller Mode: Any
+ *
+ * Notes: To read the current data rate
+ *
+ * Command-Rsp Mode
+ *
+ */
struct getdatarate_parm {
u32 rsvd;
@@ -349,36 +351,36 @@ struct getdatarate_rsp {
/*
-Caller Mode: Any
-AP: AP can use the info for the contents of beacon frame
-Infra: STA can use the info when sitesurveying
-Ad-HoC(M): Like AP
-Ad-HoC(C): Like STA
-
-
-Notes: To set the phy capability of the NIC
-
-Command Mode
-
-*/
+ * Caller Mode: Any
+ * AP: AP can use the info for the contents of beacon frame
+ * Infra: STA can use the info when sitesurveying
+ * Ad-HoC(M): Like AP
+ * Ad-HoC(C): Like STA
+ *
+ *
+ * Notes: To set the phy capability of the NIC
+ *
+ * Command Mode
+ *
+ */
/*
-Caller Mode: Any
-
-Notes: To set the channel/modem/band
-This command will be used when channel/modem/band is changed.
-
-Command Mode
-
-*/
+ * Caller Mode: Any
+ *
+ * Notes: To set the channel/modem/band
+ * This command will be used when channel/modem/band is changed.
+ *
+ * Command Mode
+ *
+ */
/*
-Caller Mode: Any
-
-Notes: To get the current setting of channel/modem/band
-
-Command-Rsp Mode
-
-*/
+ * Caller Mode: Any
+ *
+ * Notes: To get the current setting of channel/modem/band
+ *
+ * Command-Rsp Mode
+ *
+ */
struct getphy_rsp {
u8 rfchannel;
u8 modem;
@@ -428,58 +430,58 @@ struct getrfintfs_parm {
};
/*
- Notes: This command is used for H2C/C2H loopback testing
-
- mac[0] == 0
- ==> CMD mode, return H2C_SUCCESS.
- The following condition must be ture under CMD mode
- mac[1] == mac[4], mac[2] == mac[3], mac[0]=mac[5]= 0;
- s0 == 0x1234, s1 == 0xabcd, w0 == 0x78563412, w1 == 0x5aa5def7;
- s2 == (b1 << 8 | b0);
-
- mac[0] == 1
- ==> CMD_RSP mode, return H2C_SUCCESS_RSP
-
- The rsp layout shall be:
- rsp: parm:
- mac[0] = mac[5];
- mac[1] = mac[4];
- mac[2] = mac[3];
- mac[3] = mac[2];
- mac[4] = mac[1];
- mac[5] = mac[0];
- s0 = s1;
- s1 = swap16(s0);
- w0 = swap32(w1);
- b0 = b1
- s2 = s0 + s1
- b1 = b0
- w1 = w0
-
- mac[0] == 2
- ==> CMD_EVENT mode, return H2C_SUCCESS
- The event layout shall be:
- event: parm:
- mac[0] = mac[5];
- mac[1] = mac[4];
- mac[2] = event's sequence number, starting from 1 to parm's marc[3]
- mac[3] = mac[2];
- mac[4] = mac[1];
- mac[5] = mac[0];
- s0 = swap16(s0) - event.mac[2];
- s1 = s1 + event.mac[2];
- w0 = swap32(w0);
- b0 = b1
- s2 = s0 + event.mac[2]
- b1 = b0
- w1 = swap32(w1) - event.mac[2];
-
- parm->mac[3] is the total event counts that host requested.
-
-
- event will be the same with the cmd's param.
-
-*/
+ * Notes: This command is used for H2C/C2H loopback testing
+ *
+ * mac[0] == 0
+ * ==> CMD mode, return H2C_SUCCESS.
+ * The following condition must be ture under CMD mode
+ * mac[1] == mac[4], mac[2] == mac[3], mac[0]=mac[5]= 0;
+ * s0 == 0x1234, s1 == 0xabcd, w0 == 0x78563412, w1 == 0x5aa5def7;
+ * s2 == (b1 << 8 | b0);
+ *
+ * mac[0] == 1
+ * ==> CMD_RSP mode, return H2C_SUCCESS_RSP
+ *
+ * The rsp layout shall be:
+ * rsp: parm:
+ * mac[0] = mac[5];
+ * mac[1] = mac[4];
+ * mac[2] = mac[3];
+ * mac[3] = mac[2];
+ * mac[4] = mac[1];
+ * mac[5] = mac[0];
+ * s0 = s1;
+ * s1 = swap16(s0);
+ * w0 = swap32(w1);
+ * b0 = b1
+ * s2 = s0 + s1
+ * b1 = b0
+ * w1 = w0
+ *
+ * mac[0] == 2
+ * ==> CMD_EVENT mode, return H2C_SUCCESS
+ * The event layout shall be:
+ * event: parm:
+ * mac[0] = mac[5];
+ * mac[1] = mac[4];
+ * mac[2] = event's sequence number, starting from 1 to parm's marc[3]
+ * mac[3] = mac[2];
+ * mac[4] = mac[1];
+ * mac[5] = mac[0];
+ * s0 = swap16(s0) - event.mac[2];
+ * s1 = s1 + event.mac[2];
+ * w0 = swap32(w0);
+ * b0 = b1
+ * s2 = s0 + event.mac[2]
+ * b1 = b0
+ * w1 = swap32(w1) - event.mac[2];
+ *
+ * parm->mac[3] is the total event counts that host requested.
+ *
+ *
+ * event will be the same with the cmd's param.
+ *
+ */
/* CMD param Formart for DRV INTERNAL CMD HDL*/
struct drvint_cmd_parm {
@@ -570,7 +572,8 @@ struct setpwrmode_parm {
u8 bcn_rx_en;
u8 bcn_pass_cnt; /* fw report one beacon information to
* driver when it receives bcn_pass_cnt
- * beacons. */
+ * beacons.
+ */
u8 bcn_to; /* beacon TO (ms). ¡§=0¡¨ no limit.*/
u16 bcn_itv;
u8 app_itv; /* only for VOIP mode. */
diff --git a/drivers/staging/rtl8712/rtl871x_ht.h b/drivers/staging/rtl8712/rtl871x_ht.h
index 41872d937408..513f458ea07c 100644
--- a/drivers/staging/rtl8712/rtl871x_ht.h
+++ b/drivers/staging/rtl8712/rtl871x_ht.h
@@ -36,7 +36,8 @@ struct ht_priv {
unsigned int tx_amsdu_enable;/*for enable Tx A-MSDU */
unsigned int tx_amdsu_maxlen; /* 1: 8k, 0:4k ; default:8k, for tx */
unsigned int rx_ampdu_maxlen; /* for rx reordering ctrl win_sz,
- * updated when join_callback. */
+ * updated when join_callback.
+ */
struct ieee80211_ht_cap ht_cap;
};
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl.h b/drivers/staging/rtl8712/rtl871x_ioctl.h
index c9218be5bb4f..08bcb3b41bbd 100644
--- a/drivers/staging/rtl8712/rtl871x_ioctl.h
+++ b/drivers/staging/rtl8712/rtl871x_ioctl.h
@@ -68,7 +68,8 @@ struct oid_par_priv {
struct oid_obj_priv {
unsigned char dbg; /* 0: without OID debug message
- * 1: with OID debug message */
+ * 1: with OID debug message
+ */
uint (*oidfuns)(struct oid_par_priv *poid_par_priv);
};
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
index e205adf24da2..475e7904fe45 100644
--- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
@@ -1976,9 +1976,9 @@ static int r871x_get_ap_info(struct net_device *dev,
if (pdata->length >= 32) {
if (copy_from_user(data, pdata->pointer, 32))
return -EINVAL;
- data[32] = 0;
+ data[32] = 0;
} else {
- return -EINVAL;
+ return -EINVAL;
}
spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
phead = &queue->queue;
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c
index 56760cda8e89..0aaf2aab6dd0 100644
--- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.c
@@ -140,7 +140,8 @@ u8 r8712_set_802_11_bssid(struct _adapter *padapter, u8 *bssid)
ETH_ALEN)) {
if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE))
goto _Abort_Set_BSSID; /* driver is in
- * WIFI_ADHOC_MASTER_STATE */
+ * WIFI_ADHOC_MASTER_STATE
+ */
} else {
r8712_disassoc_cmd(padapter);
if (check_fwstate(pmlmepriv, _FW_LINKED))
@@ -203,7 +204,8 @@ void r8712_set_802_11_ssid(struct _adapter *padapter,
}
} else {
goto _Abort_Set_SSID; /* driver is in
- * WIFI_ADHOC_MASTER_STATE */
+ * WIFI_ADHOC_MASTER_STATE
+ */
}
}
} else {
@@ -254,12 +256,14 @@ void r8712_set_802_11_infrastructure_mode(struct _adapter *padapter,
(*pold_state == Ndis802_11IBSS)) {
/* will clr Linked_state before this function,
* we must have checked whether issue dis-assoc_cmd or
- * not */
+ * not
+ */
r8712_ind_disconnect(padapter);
}
*pold_state = networktype;
/* clear WIFI_STATION_STATE; WIFI_AP_STATE; WIFI_ADHOC_STATE;
- * WIFI_ADHOC_MASTER_STATE */
+ * WIFI_ADHOC_MASTER_STATE
+ */
_clr_fwstate_(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE |
WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE);
switch (networktype) {
diff --git a/drivers/staging/rtl8712/rtl871x_led.h b/drivers/staging/rtl8712/rtl871x_led.h
index eb612053a3dd..adfbc400a18d 100644
--- a/drivers/staging/rtl8712/rtl871x_led.h
+++ b/drivers/staging/rtl8712/rtl871x_led.h
@@ -72,14 +72,17 @@ enum LED_STRATEGY_871x {
SW_LED_MODE0, /* SW control 1 LED via GPIO0. It is default option. */
SW_LED_MODE1, /* 2 LEDs, through LED0 and LED1. For ALPHA. */
SW_LED_MODE2, /* SW control 1 LED via GPIO0,
- * custom for AzWave 8187 minicard. */
+ * custom for AzWave 8187 minicard.
+ */
SW_LED_MODE3, /* SW control 1 LED via GPIO0,
- * customized for Sercomm Printer Server case.*/
+ * customized for Sercomm Printer Server case.
+ */
SW_LED_MODE4, /*for Edimax / Belkin*/
SW_LED_MODE5, /*for Sercomm / Belkin*/
SW_LED_MODE6, /*for WNC / Corega*/
HW_LED, /* HW control 2 LEDs, LED0 and LED1 (there are 4 different
- * control modes, see MAC.CONFIG1 for details.)*/
+ * control modes, see MAC.CONFIG1 for details.)
+ */
};
struct LED_871x {
@@ -96,7 +99,8 @@ struct LED_871x {
u8 bLedWPSBlinkInProgress;
u32 BlinkTimes; /* No. times to toggle for blink.*/
u32 BlinkingLedState; /* Next state for blinking,
- * either LED_ON or OFF.*/
+ * either LED_ON or OFF.
+ */
struct timer_list BlinkTimer; /* Timer object for led blinking.*/
struct work_struct BlinkWorkItem; /* Workitem used by BlinkTimer */
@@ -115,7 +119,8 @@ struct led_priv {
/*===========================================================================
* Interface to manipulate LED objects.
- *===========================================================================*/
+ *===========================================================================
+ */
void r8712_InitSwLeds(struct _adapter *padapter);
void r8712_DeInitSwLeds(struct _adapter *padapter);
void LedControl871x(struct _adapter *padapter, enum LED_CTL_MODE LedAction);
diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c
index 772bf9fa9592..c1feef3da26c 100644
--- a/drivers/staging/rtl8712/rtl871x_mlme.c
+++ b/drivers/staging/rtl8712/rtl871x_mlme.c
@@ -403,7 +403,8 @@ static void update_scanned_network(struct _adapter *adapter,
/* If we didn't find a match, then get a new network slot to initialize
- * with this beacon's information */
+ * with this beacon's information
+ */
if (end_of_queue_search(phead, plist)) {
if (list_empty(&pmlmepriv->free_bss_pool.queue)) {
/* If there are no more slots, expire the oldest */
@@ -926,7 +927,8 @@ void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf)
if (psta != NULL) {
/*the sta have been in sta_info_queue => do nothing
*(between drv has received this event before and
- * fw have not yet to set key to CAM_ENTRY) */
+ * fw have not yet to set key to CAM_ENTRY)
+ */
return;
}
@@ -1171,7 +1173,8 @@ int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv)
pmlmepriv->assoc_ssid.SsidLength))) {
if (pmlmepriv->assoc_by_rssi) {
/* if the ssid is the same, select the bss
- * which has the max rssi*/
+ * which has the max rssi
+ */
if (pnetwork_max_rssi) {
if (pnetwork->network.Rssi >
pnetwork_max_rssi->network.Rssi)
@@ -1352,7 +1355,8 @@ static int SecIsInPMKIDList(struct _adapter *Adapter, u8 *bssid)
i = -1; /* Could not find. */
} else {
; /* There is one Pre-Authentication Key for the
- * specific BSSID. */
+ * specific BSSID.
+ */
}
return i;
}
@@ -1430,7 +1434,8 @@ sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie,
if (match) {
if (sec_ie[0] == _WPA_IE_ID_) {
/* parsing SSN IE to select required encryption
- * algorithm, and set the bc/mc encryption algorithm */
+ * algorithm, and set the bc/mc encryption algorithm
+ */
while (true) {
/*check wpa_oui tag*/
if (memcmp(&sec_ie[2], &wpa_oui[0], 4)) {
@@ -1444,7 +1449,8 @@ sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie,
}
if (!memcmp(&sec_ie[8], &wpa_oui[0], 3)) {
/* get bc/mc encryption type (group
- * key type)*/
+ * key type)
+ */
switch (sec_ie[11]) {
case 0x0: /*none*/
psecuritypriv->XGrpPrivacy =
@@ -1482,7 +1488,8 @@ sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie,
} /*else the uncst_oui is match*/
} else { /*mixed mode, unicast_enc_type > 1*/
/*select the uncst_oui and remove
- * the other uncst_oui*/
+ * the other uncst_oui
+ */
cnt = sec_ie[12];
remove_cnt = (cnt - 1) * 4;
sec_ie[12] = 0x01;
@@ -1499,7 +1506,8 @@ sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie,
}
if (authmode == _WPA2_IE_ID_) {
/* parsing RSN IE to select required encryption
- * algorithm, and set the bc/mc encryption algorithm */
+ * algorithm, and set the bc/mc encryption algorithm
+ */
while (true) {
if ((sec_ie[2] != 0x01) || (sec_ie[3] != 0x0)) {
/*IE Ver error*/
@@ -1543,7 +1551,8 @@ sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie,
} /*else the uncst_oui is match*/
} else { /*mixed mode, unicast_enc_type > 1*/
/*select the uncst_oui and remove the
- * other uncst_oui*/
+ * other uncst_oui
+ */
cnt = sec_ie[8];
remove_cnt = (cnt - 1) * 4;
sec_ie[8] = 0x01;
@@ -1667,7 +1676,8 @@ void r8712_joinbss_reset(struct _adapter *padapter)
struct ht_priv *phtpriv = &pmlmepriv->htpriv;
/* todo: if you want to do something io/reg/hw setting before join_bss,
- * please add code here */
+ * please add code here
+ */
phtpriv->ampdu_enable = false;/*reset to disabled*/
for (i = 0; i < 16; i++)
phtpriv->baddbareq_issued[i] = false;/*reset it*/
diff --git a/drivers/staging/rtl8712/rtl871x_mlme.h b/drivers/staging/rtl8712/rtl871x_mlme.h
index 61e0eb745d21..ddaaab058b2f 100644
--- a/drivers/staging/rtl8712/rtl871x_mlme.h
+++ b/drivers/staging/rtl8712/rtl871x_mlme.h
@@ -47,16 +47,20 @@
#define WIFI_ADHOC_MASTER_STATE 0x00000040
#define WIFI_UNDER_LINKING 0x00000080
#define WIFI_SITE_MONITOR 0x00000800 /* to indicate the station
- * is under site surveying*/
+ * is under site surveying
+ */
#define WIFI_MP_STATE 0x00010000
#define WIFI_MP_CTX_BACKGROUND 0x00020000 /* in cont. tx background*/
#define WIFI_MP_CTX_ST 0x00040000 /* in cont. tx with
- * single-tone*/
+ * single-tone
+ */
#define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 /* pending in cont, tx
- * background due to out of skb*/
+ * background due to out of skb
+ */
#define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continuous tx*/
#define WIFI_MP_CTX_CCK_CS 0x00200000 /* in cont, tx with carrier
- * suppression*/
+ * suppression
+ */
#define WIFI_MP_LPBK_STATE 0x00400000
#define _FW_UNDER_LINKING WIFI_UNDER_LINKING
diff --git a/drivers/staging/rtl8712/rtl871x_mp.c b/drivers/staging/rtl8712/rtl871x_mp.c
index 5e4fda1890f5..3c10a2c848c8 100644
--- a/drivers/staging/rtl8712/rtl871x_mp.c
+++ b/drivers/staging/rtl8712/rtl871x_mp.c
@@ -376,7 +376,8 @@ void r8712_SwitchBandwidth(struct _adapter *pAdapter)
/* Use PHY_REG.txt default value. Do not need to change.
* Correct the tx power for CCK rate in 40M.
* Set Control channel to upper or lower. These settings are
- * required only for 40MHz */
+ * required only for 40MHz
+ */
set_bb_reg(pAdapter, rCCK0_System, bCCKSideBand,
(HAL_PRIME_CHNL_OFFSET_DONT_CARE >> 1));
set_bb_reg(pAdapter, rOFDM1_LSTF, 0xC00,
diff --git a/drivers/staging/rtl8712/rtl871x_mp.h b/drivers/staging/rtl8712/rtl871x_mp.h
index 3f3b2e73b7d2..8df452e3e3ce 100644
--- a/drivers/staging/rtl8712/rtl871x_mp.h
+++ b/drivers/staging/rtl8712/rtl871x_mp.h
@@ -108,7 +108,8 @@ struct mp_priv {
unsigned char network_macaddr[6];
/*Testing Flag*/
u32 mode;/*0 for normal type packet,
- * 1 for loopback packet (16bytes TXCMD)*/
+ * 1 for loopback packet (16bytes TXCMD)
+ */
sint prev_fw_state;
u8 *pallocated_mp_xmitframe_buf;
u8 *pmp_xmtframe_buf;
diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.h b/drivers/staging/rtl8712/rtl871x_mp_ioctl.h
index 8dc898024e07..1102451a733d 100644
--- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.h
+++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.h
@@ -158,28 +158,37 @@ static const struct oid_obj_priv oid_rtl_seg_81_80_00[] = {
{1, oid_null_function}, /*0x05 OID_RT_PRO_SET_SCRAMBLER*/
{1, oid_null_function}, /*0x06 OID_RT_PRO_SET_FILTER_BB*/
{1, oid_null_function}, /*0x07
- * OID_RT_PRO_SET_MANUAL_DIVERS_BB*/
+ * OID_RT_PRO_SET_MANUAL_DIVERS_BB
+ */
{1, oid_rt_pro_set_channel_direct_call_hdl}, /*0x08*/
{1, oid_null_function}, /*0x09
- * OID_RT_PRO_SET_SLEEP_MODE_DIRECT_CALL*/
+ * OID_RT_PRO_SET_SLEEP_MODE_DIRECT_CALL
+ */
{1, oid_null_function}, /*0x0A
- * OID_RT_PRO_SET_WAKE_MODE_DIRECT_CALL*/
+ * OID_RT_PRO_SET_WAKE_MODE_DIRECT_CALL
+ */
{1, oid_rt_pro_set_continuous_tx_hdl}, /*0x0B
- * OID_RT_PRO_SET_TX_CONTINUOUS_DIRECT_CALL*/
+ * OID_RT_PRO_SET_TX_CONTINUOUS_DIRECT_CALL
+ */
{1, oid_rt_pro_set_single_carrier_tx_hdl}, /*0x0C
- * OID_RT_PRO_SET_SINGLE_CARRIER_TX_CONTINUOUS*/
+ * OID_RT_PRO_SET_SINGLE_CARRIER_TX_CONTINUOUS
+ */
{1, oid_null_function}, /*0x0D
- * OID_RT_PRO_SET_TX_ANTENNA_BB*/
+ * OID_RT_PRO_SET_TX_ANTENNA_BB
+ */
{1, oid_rt_pro_set_antenna_bb_hdl}, /*0x0E*/
{1, oid_null_function}, /*0x0F OID_RT_PRO_SET_CR_SCRAMBLER*/
{1, oid_null_function}, /*0x10 OID_RT_PRO_SET_CR_NEW_FILTER*/
{1, oid_rt_pro_set_tx_power_control_hdl}, /*0x11
- * OID_RT_PRO_SET_TX_POWER_CONTROL*/
+ * OID_RT_PRO_SET_TX_POWER_CONTROL
+ */
{1, oid_null_function}, /*0x12 OID_RT_PRO_SET_CR_TX_CONFIG*/
{1, oid_null_function}, /*0x13
- * OID_RT_PRO_GET_TX_POWER_CONTROL*/
+ * OID_RT_PRO_GET_TX_POWER_CONTROL
+ */
{1, oid_null_function}, /*0x14
- * OID_RT_PRO_GET_CR_SIGNAL_QUALITY*/
+ * OID_RT_PRO_GET_CR_SIGNAL_QUALITY
+ */
{1, oid_null_function}, /*0x15 OID_RT_PRO_SET_CR_SETPOINT*/
{1, oid_null_function}, /*0x16 OID_RT_PRO_SET_INTEGRATOR*/
{1, oid_null_function}, /*0x17 OID_RT_PRO_SET_SIGNAL_QUALITY*/
@@ -203,13 +212,17 @@ static const struct oid_obj_priv oid_rtl_seg_81_80_20[] = {
{1, oid_rt_pro_query_rx_packet_received_hdl}, /*0x26*/
{1, oid_rt_pro_query_rx_packet_crc32_error_hdl},/*0x27*/
{1, oid_null_function}, /*0x28
- *OID_RT_PRO_QUERY_CURRENT_ADDRESS*/
+ *OID_RT_PRO_QUERY_CURRENT_ADDRESS
+ */
{1, oid_null_function}, /*0x29
- *OID_RT_PRO_QUERY_PERMANENT_ADDRESS*/
+ *OID_RT_PRO_QUERY_PERMANENT_ADDRESS
+ */
{1, oid_null_function}, /*0x2A
- *OID_RT_PRO_SET_PHILIPS_RF_PARAMETERS*/
+ *OID_RT_PRO_SET_PHILIPS_RF_PARAMETERS
+ */
{1, oid_rt_pro_set_carrier_suppression_tx_hdl},/*0x2B
- *OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX*/
+ *OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX
+ */
{1, oid_null_function}, /*0x2C OID_RT_PRO_RECEIVE_PACKET*/
{1, oid_null_function}, /*0x2D OID_RT_PRO_WRITE_EEPROM_BYTE*/
{1, oid_null_function}, /*0x2E OID_RT_PRO_READ_EEPROM_BYTE*/
diff --git a/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h b/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h
index 2e9120a21a0b..11bcfb7bf77c 100644
--- a/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h
+++ b/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h
@@ -82,7 +82,8 @@
* 3. Page8(0x800)
*/
#define rFPGA0_RFMOD 0x800 /*RF mode & CCK TxSC RF
- * BW Setting?? */
+ * BW Setting??
+ */
#define rFPGA0_TxInfo 0x804 /* Status report?? */
#define rFPGA0_PSDFunction 0x808
#define rFPGA0_TxGainStage 0x80c /* Set TX PWR init gain? */
@@ -119,7 +120,8 @@
#define rFPGA0_AnalogParameter1 0x880 /* Crystal cap setting
* RF-R/W protection
- * for parameter4?? */
+ * for parameter4??
+ */
#define rFPGA0_AnalogParameter2 0x884
#define rFPGA0_AnalogParameter3 0x888 /* Useless now */
#define rFPGA0_AnalogParameter4 0x88c
@@ -146,7 +148,8 @@
* 5. PageA(0xA00)
*
* Set Control channel to upper or lower.
- * These settings are required only for 40MHz */
+ * These settings are required only for 40MHz
+ */
#define rCCK0_System 0xa00
#define rCCK0_AFESetting 0xa04 /* Disable init gain now */
@@ -155,20 +158,23 @@
#define rCCK0_RxAGC1 0xa0c
/* AGC default value, saturation level
* Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now.
- * Not the same as 90 series */
+ * Not the same as 90 series
+ */
#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */
#define rCCK0_RxHP 0xa14
#define rCCK0_DSPParameter1 0xa18 /* Timing recovery & Channel
- * estimation threshold */
+ * estimation threshold
+ */
#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */
#define rCCK0_TxFilter1 0xa20
#define rCCK0_TxFilter2 0xa24
#define rCCK0_DebugPort 0xa28 /* debug port and Tx filter3 */
#define rCCK0_FalseAlarmReport 0xa2c /* 0xa2d useless now 0xa30-a4f
- * channel report */
+ * channel report
+ */
#define rCCK0_TRSSIReport 0xa50
#define rCCK0_RxReport 0xa54 /* 0xa57 */
#define rCCK0_FACounterLower 0xa5c /* 0xa5b */
@@ -193,11 +199,13 @@
#define rOFDM0_XDRxIQImbalance 0xc2c
#define rOFDM0_RxDetector1 0xc30 /* PD,BW & SBD DM tune
- * init gain */
+ * init gain
+ */
#define rOFDM0_RxDetector2 0xc34 /* SBD & Fame Sync. */
#define rOFDM0_RxDetector3 0xc38 /* Frame Sync. */
#define rOFDM0_RxDetector4 0xc3c /* PD, SBD, Frame Sync &
- * Short-GI */
+ * Short-GI
+ */
#define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */
#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */
@@ -283,7 +291,8 @@
#define rTxAGC_Mcs15_Mcs12 0xe1c
/* Analog- control in RX_WAIT_CCA : REG: EE0
- * [Analog- Power & Control Register] */
+ * [Analog- Power & Control Register]
+ */
#define rRx_Wait_CCCA 0xe70
#define rAnapar_Ctrl_BB 0xee0
@@ -371,7 +380,8 @@
/*
* Bit Mask
*
- * 1. Page1(0x100) */
+ * 1. Page1(0x100)
+ */
#define bBBResetB 0x100 /* Useless now? */
#define bGlobalResetB 0x200
#define bOFDMTxStart 0x4
@@ -918,7 +928,8 @@
#define bPesudoNoiseState_D 0xffff0000
/* 7. RF Register
- * Zebra1 */
+ * Zebra1
+ */
#define bZebra1_HSSIEnable 0x8 /* Useless */
#define bZebra1_TRxControl 0xc00
#define bZebra1_TRxGainSetting 0x07f
diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c
index bf10d6db50e8..d464c136dd98 100644
--- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c
+++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c
@@ -52,7 +52,8 @@ void r8712_set_rpwm(struct _adapter *padapter, u8 val8)
pwrpriv->cpwm = val8;
break;
case PS_STATE_S2:/* only for USB normal powersave mode use,
- * temp mark some code. */
+ * temp mark some code.
+ */
case PS_STATE_S3:
case PS_STATE_S4:
pwrpriv->cpwm = val8;
@@ -103,14 +104,14 @@ void r8712_cpwm_int_hdl(struct _adapter *padapter,
if (pwrpriv->cpwm_tog == ((preportpwrstate->state) & 0x80))
return;
del_timer(&padapter->pwrctrlpriv.rpwm_check_timer);
- _enter_pwrlock(&pwrpriv->lock);
+ mutex_lock(&pwrpriv->mutex_lock);
pwrpriv->cpwm = (preportpwrstate->state) & 0xf;
if (pwrpriv->cpwm >= PS_STATE_S2) {
if (pwrpriv->alives & CMD_ALIVE)
- up(&(pcmdpriv->cmd_queue_sema));
+ complete(&(pcmdpriv->cmd_queue_comp));
}
pwrpriv->cpwm_tog = (preportpwrstate->state) & 0x80;
- up(&pwrpriv->lock);
+ mutex_unlock(&pwrpriv->mutex_lock);
}
static inline void register_task_alive(struct pwrctrl_priv *pwrctrl, uint tag)
@@ -141,10 +142,10 @@ static void SetPSModeWorkItemCallback(struct work_struct *work)
struct _adapter *padapter = container_of(pwrpriv,
struct _adapter, pwrctrlpriv);
if (!pwrpriv->bSleep) {
- _enter_pwrlock(&pwrpriv->lock);
+ mutex_lock(&pwrpriv->mutex_lock);
if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
r8712_set_rpwm(padapter, PS_STATE_S4);
- up(&pwrpriv->lock);
+ mutex_unlock(&pwrpriv->mutex_lock);
}
}
@@ -155,11 +156,11 @@ static void rpwm_workitem_callback(struct work_struct *work)
struct _adapter *padapter = container_of(pwrpriv,
struct _adapter, pwrctrlpriv);
if (pwrpriv->cpwm != pwrpriv->rpwm) {
- _enter_pwrlock(&pwrpriv->lock);
+ mutex_lock(&pwrpriv->mutex_lock);
r8712_read8(padapter, SDIO_HCPWM);
pwrpriv->rpwm_retry = 1;
r8712_set_rpwm(padapter, pwrpriv->rpwm);
- up(&pwrpriv->lock);
+ mutex_unlock(&pwrpriv->mutex_lock);
}
}
@@ -175,7 +176,7 @@ void r8712_init_pwrctrl_priv(struct _adapter *padapter)
struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
memset((unsigned char *)pwrctrlpriv, 0, sizeof(struct pwrctrl_priv));
- sema_init(&pwrctrlpriv->lock, 1);
+ mutex_init(&pwrctrlpriv->mutex_lock);
pwrctrlpriv->cpwm = PS_STATE_S4;
pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE;
pwrctrlpriv->smart_ps = 0;
@@ -207,13 +208,13 @@ sint r8712_register_cmd_alive(struct _adapter *padapter)
uint res = _SUCCESS;
struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv;
- _enter_pwrlock(&pwrctrl->lock);
+ mutex_lock(&pwrctrl->mutex_lock);
register_task_alive(pwrctrl, CMD_ALIVE);
if (pwrctrl->cpwm < PS_STATE_S2) {
r8712_set_rpwm(padapter, PS_STATE_S3);
res = _FAIL;
}
- up(&pwrctrl->lock);
+ mutex_unlock(&pwrctrl->mutex_lock);
return res;
}
@@ -229,7 +230,7 @@ void r8712_unregister_cmd_alive(struct _adapter *padapter)
{
struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv;
- _enter_pwrlock(&pwrctrl->lock);
+ mutex_lock(&pwrctrl->mutex_lock);
unregister_task_alive(pwrctrl, CMD_ALIVE);
if ((pwrctrl->cpwm > PS_STATE_S2) &&
(pwrctrl->pwr_mode > PS_MODE_ACTIVE)) {
@@ -239,5 +240,5 @@ void r8712_unregister_cmd_alive(struct _adapter *padapter)
r8712_set_rpwm(padapter, PS_STATE_S0);
}
}
- up(&pwrctrl->lock);
+ mutex_unlock(&pwrctrl->mutex_lock);
}
diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.h b/drivers/staging/rtl8712/rtl871x_pwrctrl.h
index dbfb55523545..c82fdf85d474 100644
--- a/drivers/staging/rtl8712/rtl871x_pwrctrl.h
+++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.h
@@ -87,16 +87,12 @@ struct reportpwrstate_parm {
unsigned short rsvd;
};
-static inline void _enter_pwrlock(struct semaphore *plock)
-{
- _down_sema(plock);
-}
-
struct pwrctrl_priv {
- struct semaphore lock;
+ struct mutex mutex_lock;
/*volatile*/ u8 rpwm; /* requested power state for fw */
/* fw current power state. updated when 1. read from HCPWM or
- * 2. driver lowers power level */
+ * 2. driver lowers power level
+ */
/*volatile*/ u8 cpwm;
/*volatile*/ u8 tog; /* toggling */
/*volatile*/ u8 cpwm_tog; /* toggling */
diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c
index 23c143890252..cbd2e51ba42b 100644
--- a/drivers/staging/rtl8712/rtl871x_recv.c
+++ b/drivers/staging/rtl8712/rtl871x_recv.c
@@ -265,7 +265,8 @@ union recv_frame *r8712_portctrl(struct _adapter *adapter,
if ((psta != NULL) && (psta->ieee8021x_blocked)) {
/* blocked
- * only accept EAPOL frame */
+ * only accept EAPOL frame
+ */
if (ether_type == 0x888e) {
prtnframe = precv_frame;
} else {
@@ -277,7 +278,8 @@ union recv_frame *r8712_portctrl(struct _adapter *adapter,
} else {
/* allowed
* check decryption status, and decrypt the
- * frame if needed */
+ * frame if needed
+ */
prtnframe = precv_frame;
/* check is the EAPOL frame or not (Rekey) */
if (ether_type == 0x888e) {
@@ -334,19 +336,22 @@ static sint sta2sta_data_frame(struct _adapter *adapter,
sta_addr = pattrib->src;
} else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
/* For Station mode, sa and bssid should always be BSSID,
- * and DA is my mac-address */
+ * and DA is my mac-address
+ */
if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN))
return _FAIL;
sta_addr = pattrib->bssid;
} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
if (bmcast) {
/* For AP mode, if DA == MCAST, then BSSID should
- * be also MCAST */
+ * be also MCAST
+ */
if (!IS_MCAST(pattrib->bssid))
return _FAIL;
} else { /* not mc-frame */
/* For AP mode, if DA is non-MCAST, then it must be
- * BSSID, and bssid == BSSID */
+ * BSSID, and bssid == BSSID
+ */
if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN))
return _FAIL;
sta_addr = pattrib->src;
@@ -391,7 +396,8 @@ static sint ap2sta_data_frame(struct _adapter *adapter,
if ((GetFrameSubType(ptr)) == WIFI_DATA_NULL)
return _FAIL;
/* drop QoS-SubType Data, including QoS NULL,
- * excluding QoS-Data */
+ * excluding QoS-Data
+ */
if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) ==
WIFI_QOS_DATA_TYPE) {
if (GetFrameSubType(ptr) & (BIT(4) | BIT(5) | BIT(6)))
@@ -445,7 +451,8 @@ static sint sta2ap_data_frame(struct _adapter *adapter,
if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
/* For AP mode, if DA is non-MCAST, then it must be BSSID,
* and bssid == BSSID
- * For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR */
+ * For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR
+ */
if (memcmp(pattrib->bssid, mybssid, ETH_ALEN))
return _FAIL;
*psta = r8712_get_stainfo(pstapriv, pattrib->src);
@@ -619,7 +626,8 @@ sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe)
(memcmp(psnap_type, (void *)SNAP_ETH_TYPE_APPLETALK_AARP, 2))) ||
!memcmp(psnap, (void *)bridge_tunnel_header, SNAP_SIZE)) {
/* remove RFC1042 or Bridge-Tunnel encapsulation and
- * replace EtherType */
+ * replace EtherType
+ */
bsnaphdr = true;
} else {
/* Leave Ethernet header part of hdr and full payload */
diff --git a/drivers/staging/rtl8712/rtl871x_recv.h b/drivers/staging/rtl8712/rtl871x_recv.h
index 77487bb9d3c0..f419943ad75d 100644
--- a/drivers/staging/rtl8712/rtl871x_recv.h
+++ b/drivers/staging/rtl8712/rtl871x_recv.h
@@ -153,7 +153,8 @@ static inline u8 *get_recvframe_data(union recv_frame *precvframe)
static inline u8 *recvframe_pull(union recv_frame *precvframe, sint sz)
{
/* used for extract sz bytes from rx_data, update rx_data and return
- * the updated rx_data to the caller */
+ * the updated rx_data to the caller
+ */
if (precvframe == NULL)
return NULL;
precvframe->u.hdr.rx_data += sz;
@@ -169,7 +170,8 @@ static inline u8 *recvframe_put(union recv_frame *precvframe, sint sz)
{
/* used for append sz bytes from ptr to rx_tail, update rx_tail and
* return the updated rx_tail to the caller
- * after putting, rx_tail must be still larger than rx_end. */
+ * after putting, rx_tail must be still larger than rx_end.
+ */
if (precvframe == NULL)
return NULL;
precvframe->u.hdr.rx_tail += sz;
@@ -186,7 +188,8 @@ static inline u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz)
/* rmv data from rx_tail (by yitsen)
* used for extract sz bytes from rx_end, update rx_end and return the
* updated rx_end to the caller
- * after pulling, rx_end must be still larger than rx_data. */
+ * after pulling, rx_end must be still larger than rx_data.
+ */
if (precvframe == NULL)
return NULL;
precvframe->u.hdr.rx_tail -= sz;
diff --git a/drivers/staging/rtl8712/rtl871x_security.h b/drivers/staging/rtl8712/rtl871x_security.h
index 2295f0e64dc2..fa952e17975b 100644
--- a/drivers/staging/rtl8712/rtl871x_security.h
+++ b/drivers/staging/rtl8712/rtl871x_security.h
@@ -90,18 +90,23 @@ struct RT_PMKID_LIST {
struct security_priv {
u32 AuthAlgrthm; /* 802.11 auth, could be open, shared,
- * 8021x and authswitch */
+ * 8021x and authswitch
+ */
u32 PrivacyAlgrthm; /* This specify the privacy for shared
- * auth. algorithm. */
+ * auth. algorithm.
+ */
u32 PrivacyKeyIndex; /* this is only valid for legendary
- * wep, 0~3 for key id. */
+ * wep, 0~3 for key id.
+ */
union Keytype DefKey[4]; /* this is only valid for def. key */
u32 DefKeylen[4];
u32 XGrpPrivacy; /* This specify the privacy algthm.
- * used for Grp key */
+ * used for Grp key
+ */
u32 XGrpKeyid; /* key id used for Grp Key */
union Keytype XGrpKey[2]; /* 802.1x Group Key, for
- * inx0 and inx1 */
+ * inx0 and inx1
+ */
union Keytype XGrptxmickey[2];
union Keytype XGrprxmickey[2];
union pn48 Grptxpn; /* PN48 used for Grp Key xmit. */
@@ -118,9 +123,11 @@ struct security_priv {
s32 sw_encrypt; /* from registry_priv */
s32 sw_decrypt; /* from registry_priv */
s32 hw_decrypted; /* if the rx packets is hw_decrypted==false,
- * it means the hw has not been ready. */
+ * it means the hw has not been ready.
+ */
u32 ndisauthtype; /* keeps the auth_type & enc_status from upper
- * layer ioctl(wpa_supplicant or wzc) */
+ * layer ioctl(wpa_supplicant or wzc)
+ */
u32 ndisencryptstatus;
struct wlan_bssid_ex sec_bss; /* for joinbss (h2c buffer) usage */
struct NDIS_802_11_WEP ndiswep;
@@ -136,7 +143,8 @@ struct security_priv {
u32 btkip_countermeasure_time;
/*-------------------------------------------------------------------
* For WPA2 Pre-Authentication.
- *------------------------------------------------------------------ */
+ *------------------------------------------------------------------
+ **/
struct RT_PMKID_LIST PMKIDList[NUM_PMKID_CACHE];
u8 PMKIDIndex;
};
diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
index e11ce2896893..e2d75e4c473f 100644
--- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c
+++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
@@ -188,7 +188,8 @@ void r8712_free_stainfo(struct _adapter *padapter, struct sta_info *psta)
_r8712_init_sta_xmit_priv(&psta->sta_xmitpriv);
_r8712_init_sta_recv_priv(&psta->sta_recvpriv);
/* for A-MPDU Rx reordering buffer control,
- * cancel reordering_ctrl_timer */
+ * cancel reordering_ctrl_timer
+ */
for (i = 0; i < 16; i++) {
preorder_ctrl = &psta->recvreorder_ctrl[i];
del_timer(&preorder_ctrl->reordering_ctrl_timer);
diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c
index 99256baafd38..be38364c8a7c 100644
--- a/drivers/staging/rtl8712/rtl871x_xmit.c
+++ b/drivers/staging/rtl8712/rtl871x_xmit.c
@@ -204,7 +204,8 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
{
/*If driver xmit ARP packet, driver can set ps mode to initial
- * setting. It stands for getting DHCP or fix IP.*/
+ * setting. It stands for getting DHCP or fix IP.
+ */
if (pattrib->ether_type == 0x0806) {
if (padapter->pwrctrlpriv.pwr_mode !=
padapter->registrypriv.power_mgnt) {
@@ -232,7 +233,8 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
if (pattrib->ether_type != 0x8712)
return _FAIL;
/* for mp storing the txcmd per packet,
- * according to the info of txcmd to update pattrib */
+ * according to the info of txcmd to update pattrib
+ */
/*get MP_TXDESC_SIZE bytes txcmd per packet*/
_r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE);
memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
@@ -244,7 +246,8 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
if (pattrib->ether_type == ETH_P_IP) {
/* The following is for DHCP and ARP packet, we use cck1M to
* tx these packets and let LPS awake some time
- * to prevent DHCP protocol fail */
+ * to prevent DHCP protocol fail
+ */
u8 tmp[24];
_r8712_pktfile_read(&pktfile, &tmp[0], 24);
@@ -255,7 +258,8 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
((tmp[21] == 67) && (tmp[23] == 68))) {
/* 68 : UDP BOOTP client
* 67 : UDP BOOTP server
- * Use low rate to send DHCP packet.*/
+ * Use low rate to send DHCP packet.
+ */
pattrib->dhcp_pkt = 1;
}
}
@@ -337,7 +341,8 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
else
pattrib->bswenc = false;
/* if in MP_STATE, update pkt_attrib from mp_txcmd, and overwrite
- * some settings above.*/
+ * some settings above.
+ */
if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
pattrib->priority = (txdesc.txdw1 >> QSEL_SHT) & 0x1f;
return _SUCCESS;
@@ -438,7 +443,8 @@ static sint xmitframe_addmic(struct _adapter *padapter,
}
r8712_secgetmic(&micdata, &(mic[0]));
/* add mic code and add the mic code length in
- * last_txcmdsz */
+ * last_txcmdsz
+ */
memcpy(payload, &(mic[0]), 8);
pattrib->last_txcmdsz += 8;
payload = payload - pattrib->last_txcmdsz + 8;
diff --git a/drivers/staging/rtl8712/rtl871x_xmit.h b/drivers/staging/rtl8712/rtl871x_xmit.h
index a9633c3f73d0..d899d0c6d3a6 100644
--- a/drivers/staging/rtl8712/rtl871x_xmit.h
+++ b/drivers/staging/rtl8712/rtl871x_xmit.h
@@ -58,7 +58,8 @@ do { \
} while (0)
/* Fixed the Big Endian bug when doing the Tx.
- * The Linksys WRH54G will check this.*/
+ * The Linksys WRH54G will check this.
+ */
#define TKIP_IV(pattrib_iv, txpn, keyidx)\
do { \
pattrib_iv[0] = txpn._byte_.TSC1;\
@@ -105,7 +106,8 @@ struct pkt_attrib {
u16 seqnum;
u16 ether_type;
u16 pktlen; /* the original 802.3 pkt raw_data len
- * (not include ether_hdr data) */
+ * (not include ether_hdr data)
+ */
u16 last_txcmdsz;
u8 pkt_hdrlen; /*the original 802.3 pkt header len*/
@@ -119,7 +121,8 @@ struct pkt_attrib {
u8 priority;
u8 encrypt; /* when 0 indicate no encrypt. when non-zero,
- * indicate the encrypt algorithm*/
+ * indicate the encrypt algorithm
+ */
u8 iv_len;
u8 icv_len;
unsigned char iv[8];
@@ -176,7 +179,8 @@ struct sta_xmit_priv {
spinlock_t lock;
sint option;
sint apsd_setting; /* When bit mask is on, the associated edca
- * queue supports APSD.*/
+ * queue supports APSD.
+ */
struct tx_servq be_q; /* priority == 0,3 */
struct tx_servq bk_q; /* priority == 1,2*/
struct tx_servq vi_q; /*priority == 4,5*/
diff --git a/drivers/staging/rtl8712/usb_halinit.c b/drivers/staging/rtl8712/usb_halinit.c
index ad21df16c2bd..0b159850f5a2 100644
--- a/drivers/staging/rtl8712/usb_halinit.c
+++ b/drivers/staging/rtl8712/usb_halinit.c
@@ -196,7 +196,8 @@ u8 r8712_usb_hal_bus_init(struct _adapter *padapter)
msleep(20);
/* Revised POS, */
/* Enable AFE Macro Block's Bandgap and Enable AFE Macro
- * Block's Mbias */
+ * Block's Mbias
+ */
r8712_write8(padapter, SPS0_CTRL + 1, 0x53);
r8712_write8(padapter, SPS0_CTRL, 0x57);
val8 = r8712_read8(padapter, AFE_MISC);
diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c
index c1a0ca490546..897d4621a5ce 100644
--- a/drivers/staging/rtl8712/usb_intf.c
+++ b/drivers/staging/rtl8712/usb_intf.c
@@ -301,7 +301,8 @@ void rtl871x_intf_stop(struct _adapter *padapter)
/*disable_hw_interrupt*/
if (!padapter->bSurpriseRemoved) {
/*device still exists, so driver can do i/o operation
- * TODO: */
+ * TODO:
+ */
}
/* cancel in irp */
@@ -368,7 +369,7 @@ static const struct device_type wlan_type = {
*
* notes: drv_init() is called when the bus driver has located a card for us
* to support. We accept the new device by returning 0.
-*/
+ */
static int r871xu_drv_init(struct usb_interface *pusb_intf,
const struct usb_device_id *pdid)
{
@@ -611,7 +612,8 @@ error:
}
/* rmmod module & unplug(SurpriseRemoved) will call r871xu_dev_remove()
- * => how to recognize both */
+ * => how to recognize both
+ */
static void r871xu_dev_remove(struct usb_interface *pusb_intf)
{
struct net_device *pnetdev = usb_get_intfdata(pusb_intf);
@@ -635,12 +637,14 @@ static void r871xu_dev_remove(struct usb_interface *pusb_intf)
r8712_free_drv_sw(padapter);
/* decrease the reference count of the usb device structure
- * when disconnect */
+ * when disconnect
+ */
usb_put_dev(udev);
}
/* If we didn't unplug usb dongle and remove/insert module, driver
* fails on sitesurvey for the first time when device is up.
- * Reset usb port for sitesurvey fail issue. */
+ * Reset usb port for sitesurvey fail issue.
+ */
if (udev->state != USB_STATE_NOTATTACHED)
usb_reset_device(udev);
}
diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c
index 6f12345709c2..fc6bb0be2a28 100644
--- a/drivers/staging/rtl8712/usb_ops_linux.c
+++ b/drivers/staging/rtl8712/usb_ops_linux.c
@@ -50,7 +50,7 @@ uint r8712_usb_init_intf_priv(struct intf_priv *pintfpriv)
pintfpriv->piorw_urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!pintfpriv->piorw_urb)
return _FAIL;
- sema_init(&(pintfpriv->io_retevt), 0);
+ init_completion(&pintfpriv->io_retevt_comp);
return _SUCCESS;
}
@@ -163,7 +163,7 @@ static void usb_write_mem_complete(struct urb *purb)
else
padapter->bSurpriseRemoved = true;
}
- up(&pintfpriv->io_retevt);
+ complete(&pintfpriv->io_retevt_comp);
}
void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
@@ -187,7 +187,7 @@ void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
wmem, cnt, usb_write_mem_complete,
pio_queue);
usb_submit_urb(piorw_urb, GFP_ATOMIC);
- _down_sema(&pintfpriv->io_retevt);
+ wait_for_completion_interruptible(&pintfpriv->io_retevt_comp);
}
static void r8712_usb_read_port_complete(struct urb *purb)
@@ -202,26 +202,23 @@ static void r8712_usb_read_port_complete(struct urb *purb)
if (purb->status == 0) { /* SUCCESS */
if ((purb->actual_length > (MAX_RECVBUF_SZ)) ||
(purb->actual_length < RXDESC_SIZE)) {
- precvbuf->reuse = true;
r8712_read_port(padapter, precvpriv->ff_hwaddr, 0,
(unsigned char *)precvbuf);
} else {
+ _pkt *pskb = precvbuf->pskb;
+
precvbuf->transfer_len = purb->actual_length;
pbuf = (uint *)precvbuf->pbuf;
isevt = le32_to_cpu(*(pbuf + 1)) & 0x1ff;
if ((isevt & 0x1ff) == 0x1ff) {
r8712_rxcmd_event_hdl(padapter, pbuf);
- precvbuf->reuse = true;
+ skb_queue_tail(&precvpriv->rx_skb_queue, pskb);
r8712_read_port(padapter, precvpriv->ff_hwaddr,
0, (unsigned char *)precvbuf);
} else {
- _pkt *pskb = precvbuf->pskb;
-
skb_put(pskb, purb->actual_length);
skb_queue_tail(&precvpriv->rx_skb_queue, pskb);
tasklet_hi_schedule(&precvpriv->recv_tasklet);
- precvbuf->pskb = NULL;
- precvbuf->reuse = false;
r8712_read_port(padapter, precvpriv->ff_hwaddr,
0, (unsigned char *)precvbuf);
}
@@ -241,7 +238,6 @@ static void r8712_usb_read_port_complete(struct urb *purb)
}
/* Fall through. */
case -EPROTO:
- precvbuf->reuse = true;
r8712_read_port(padapter, precvpriv->ff_hwaddr, 0,
(unsigned char *)precvbuf);
break;
@@ -270,51 +266,43 @@ u32 r8712_usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
struct usb_device *pusbd = pdvobj->pusbdev;
if (adapter->bDriverStopped || adapter->bSurpriseRemoved ||
- adapter->pwrctrlpriv.pnp_bstop_trx)
+ adapter->pwrctrlpriv.pnp_bstop_trx || !precvbuf)
return _FAIL;
- if (precvbuf->reuse || !precvbuf->pskb) {
- precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
- if (precvbuf->pskb != NULL)
- precvbuf->reuse = true;
+ r8712_init_recvbuf(adapter, precvbuf);
+ /* Try to use skb from the free queue */
+ precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
+
+ if (!precvbuf->pskb) {
+ precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev,
+ MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
+ if (!precvbuf->pskb)
+ return _FAIL;
+ tmpaddr = (addr_t)precvbuf->pskb->data;
+ alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
+ skb_reserve(precvbuf->pskb,
+ (RECVBUFF_ALIGN_SZ - alignment));
+ precvbuf->phead = precvbuf->pskb->head;
+ precvbuf->pdata = precvbuf->pskb->data;
+ precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
+ precvbuf->pend = skb_end_pointer(precvbuf->pskb);
+ precvbuf->pbuf = precvbuf->pskb->data;
+ } else { /* skb is reused */
+ precvbuf->phead = precvbuf->pskb->head;
+ precvbuf->pdata = precvbuf->pskb->data;
+ precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
+ precvbuf->pend = skb_end_pointer(precvbuf->pskb);
+ precvbuf->pbuf = precvbuf->pskb->data;
}
- if (precvbuf != NULL) {
- r8712_init_recvbuf(adapter, precvbuf);
- /* re-assign for linux based on skb */
- if (!precvbuf->reuse || !precvbuf->pskb) {
- precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev,
- MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
- if (!precvbuf->pskb)
- return _FAIL;
- tmpaddr = (addr_t)precvbuf->pskb->data;
- alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
- skb_reserve(precvbuf->pskb,
- (RECVBUFF_ALIGN_SZ - alignment));
- precvbuf->phead = precvbuf->pskb->head;
- precvbuf->pdata = precvbuf->pskb->data;
- precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
- precvbuf->pend = skb_end_pointer(precvbuf->pskb);
- precvbuf->pbuf = precvbuf->pskb->data;
- } else { /* reuse skb */
- precvbuf->phead = precvbuf->pskb->head;
- precvbuf->pdata = precvbuf->pskb->data;
- precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
- precvbuf->pend = skb_end_pointer(precvbuf->pskb);
- precvbuf->pbuf = precvbuf->pskb->data;
- precvbuf->reuse = false;
- }
- purb = precvbuf->purb;
- /* translate DMA FIFO addr to pipehandle */
- pipe = ffaddr2pipehdl(pdvobj, addr);
- usb_fill_bulk_urb(purb, pusbd, pipe,
- precvbuf->pbuf, MAX_RECVBUF_SZ,
- r8712_usb_read_port_complete,
- precvbuf);
- err = usb_submit_urb(purb, GFP_ATOMIC);
- if ((err) && (err != (-EPERM)))
- ret = _FAIL;
- } else {
+ purb = precvbuf->purb;
+ /* translate DMA FIFO addr to pipehandle */
+ pipe = ffaddr2pipehdl(pdvobj, addr);
+ usb_fill_bulk_urb(purb, pusbd, pipe,
+ precvbuf->pbuf, MAX_RECVBUF_SZ,
+ r8712_usb_read_port_complete,
+ precvbuf);
+ err = usb_submit_urb(purb, GFP_ATOMIC);
+ if ((err) && (err != (-EPERM)))
ret = _FAIL;
- }
return ret;
}
diff --git a/drivers/staging/rtl8712/wifi.h b/drivers/staging/rtl8712/wifi.h
index 7a352c45344f..b8af9656e6da 100644
--- a/drivers/staging/rtl8712/wifi.h
+++ b/drivers/staging/rtl8712/wifi.h
@@ -376,7 +376,8 @@ static inline unsigned char *get_hdr_bssid(unsigned char *pframe)
/*-----------------------------------------------------------------------------
Below is for the security related definition
-------------------------------------------------------------------------------*/
+ *-----------------------------------------------------------------------------
+ */
#define _RESERVED_FRAME_TYPE_ 0
#define _SKB_FRAME_TYPE_ 2
#define _PRE_ALLOCMEM_ 1
@@ -420,7 +421,8 @@ static inline unsigned char *get_hdr_bssid(unsigned char *pframe)
/* ---------------------------------------------------------------------------
Below is the fixed elements...
------------------------------------------------------------------------------*/
+ * ---------------------------------------------------------------------------
+ */
#define _AUTH_ALGM_NUM_ 2
#define _AUTH_SEQ_NUM_ 2
#define _BEACON_ITERVAL_ 2
@@ -448,20 +450,23 @@ static inline unsigned char *get_hdr_bssid(unsigned char *pframe)
/*-----------------------------------------------------------------------------
Below is the definition for 802.11i / 802.1x
-------------------------------------------------------------------------------*/
+ *------------------------------------------------------------------------------
+ */
#define _IEEE8021X_MGT_ 1 /*WPA */
#define _IEEE8021X_PSK_ 2 /* WPA with pre-shared key */
/*-----------------------------------------------------------------------------
Below is the definition for WMM
-------------------------------------------------------------------------------*/
+ *------------------------------------------------------------------------------
+ */
#define _WMM_IE_Length_ 7 /* for WMM STA */
#define _WMM_Para_Element_Length_ 24
/*-----------------------------------------------------------------------------
Below is the definition for 802.11n
-------------------------------------------------------------------------------*/
+ *------------------------------------------------------------------------------
+ */
/* block-ack parameters */
#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
diff --git a/drivers/staging/rtl8712/wlan_bssdef.h b/drivers/staging/rtl8712/wlan_bssdef.h
index fda5707c4acd..86a88b493a43 100644
--- a/drivers/staging/rtl8712/wlan_bssdef.h
+++ b/drivers/staging/rtl8712/wlan_bssdef.h
@@ -171,7 +171,8 @@ struct NDIS_802_11_REMOVE_KEY {
struct NDIS_802_11_WEP {
u32 Length; /* Length of this structure */
u32 KeyIndex; /* 0 is the per-client key,
- * 1-N are the global keys */
+ * 1-N are the global keys
+ */
u32 KeyLength; /* length of key in bytes */
u8 KeyMaterial[16]; /* variable length depending on above field */
};
@@ -194,7 +195,8 @@ struct wlan_network {
struct list_head list;
int network_type; /*refer to ieee80211.h for WIRELESS_11A/B/G */
int fixed; /* set to fixed when not to be removed asi
- * site-surveying */
+ * site-surveying
+ */
unsigned int last_scanned; /*timestamp for the network */
int aid; /*will only be valid when a BSS is joined. */
int join_res;
diff --git a/drivers/staging/rtl8712/xmit_linux.c b/drivers/staging/rtl8712/xmit_linux.c
index 695f9b9fc749..4ee4136b5c28 100644
--- a/drivers/staging/rtl8712/xmit_linux.c
+++ b/drivers/staging/rtl8712/xmit_linux.c
@@ -31,6 +31,7 @@
#include <linux/usb.h>
#include <linux/ip.h>
#include <linux/if_ether.h>
+#include <linux/kmemleak.h>
#include "osdep_service.h"
#include "drv_types.h"
@@ -91,7 +92,8 @@ void r8712_set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
} else {
/* "When priority processing of data frames is supported,
* a STA's SME should send EAPOL-Key frames at the highest
- * priority." */
+ * priority."
+ */
if (pattrib->ether_type == 0x888e)
UserPriority = 7;
@@ -132,6 +134,7 @@ int r8712_xmit_resource_alloc(struct _adapter *padapter,
netdev_err(padapter->pnetdev, "pxmitbuf->pxmit_urb[i] == NULL\n");
return _FAIL;
}
+ kmemleak_not_leak(pxmitbuf->pxmit_urb[i]);
}
return _SUCCESS;
}
@@ -162,16 +165,16 @@ int r8712_xmit_entry(_pkt *pkt, struct net_device *pnetdev)
struct _adapter *padapter = netdev_priv(pnetdev);
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- if (!r8712_if_up(padapter)) {
+ if (!r8712_if_up(padapter))
goto _xmit_entry_drop;
- }
+
pxmitframe = r8712_alloc_xmitframe(pxmitpriv);
- if (!pxmitframe) {
+ if (!pxmitframe)
goto _xmit_entry_drop;
- }
- if ((!r8712_update_attrib(padapter, pkt, &pxmitframe->attrib))) {
+
+ if ((!r8712_update_attrib(padapter, pkt, &pxmitframe->attrib)))
goto _xmit_entry_drop;
- }
+
padapter->ledpriv.LedControlHandler(padapter, LED_CTL_TX);
pxmitframe->pkt = pkt;
if (r8712_pre_xmit(padapter, pxmitframe)) {
diff --git a/drivers/staging/rtl8723au/Kconfig b/drivers/staging/rtl8723au/Kconfig
deleted file mode 100644
index 277c1ab69317..000000000000
--- a/drivers/staging/rtl8723au/Kconfig
+++ /dev/null
@@ -1,33 +0,0 @@
-config R8723AU
- tristate "Realtek RTL8723AU Wireless LAN NIC driver (deprecated)"
- depends on USB && WLAN && RFKILL
- select WIRELESS_EXT
- select WEXT_PRIV
- select CFG80211
- default n
- ---help---
- This option adds the Realtek RTL8723AU USB device such as found in
- the Lenovo Yoga 13 tablet. If built as a module, it will be called r8723au.
-
- Note: This driver is deprecated and scheduled to be removed in a
- future kernel release. Please use rtl8xxxu instead.
-
-if R8723AU
-
-config 8723AU_AP_MODE
- bool "Realtek RTL8723AU AP mode"
- default y
- ---help---
- This option enables Access Point mode. Unless you know that your system
- will never be used as an AP, or the target system has limited memory,
- "Y" should be selected.
-
-config 8723AU_BT_COEXIST
- bool "Realtek RTL8723AU BlueTooth Coexistence"
- default y
- ---help---
- This option enables icoexistence with BlueTooth communications for the r8723au driver.
- Unless you know that this driver will never by used with BT, or the target system has
- limited memory, "Y" should be selected.
-
-endif
diff --git a/drivers/staging/rtl8723au/Makefile b/drivers/staging/rtl8723au/Makefile
deleted file mode 100644
index 3e8989018a88..000000000000
--- a/drivers/staging/rtl8723au/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-r8723au-y := \
- core/rtw_cmd.o \
- core/rtw_efuse.o \
- core/rtw_ieee80211.o \
- core/rtw_mlme.o \
- core/rtw_mlme_ext.o \
- core/rtw_pwrctrl.o \
- core/rtw_recv.o \
- core/rtw_security.o \
- core/rtw_sreset.o \
- core/rtw_sta_mgt.o \
- core/rtw_xmit.o \
- core/rtw_wlan_util.o \
- hal/hal_com.o \
- hal/hal_intf.o \
- hal/Hal8723PwrSeq.o \
- hal/Hal8723UHWImg_CE.o \
- hal/HalDMOutSrc8723A_CE.o \
- hal/HalHWImg8723A_BB.o \
- hal/HalHWImg8723A_MAC.o \
- hal/HalHWImg8723A_RF.o \
- hal/HalPwrSeqCmd.o \
- hal/odm_RegConfig8723A.o \
- hal/odm_debug.o \
- hal/odm_interface.o \
- hal/odm_HWConfig.o \
- hal/odm.o \
- hal/rtl8723a_cmd.o \
- hal/rtl8723a_dm.o \
- hal/rtl8723a_hal_init.o \
- hal/rtl8723a_phycfg.o \
- hal/rtl8723a_rf6052.o \
- hal/rtl8723a_rxdesc.o \
- hal/rtl8723a_sreset.o \
- hal/rtl8723au_recv.o \
- hal/rtl8723au_xmit.o \
- hal/usb_halinit.o \
- hal/usb_ops_linux.o \
- os_dep/ioctl_cfg80211.o \
- os_dep/mlme_linux.o \
- os_dep/os_intfs.o \
- os_dep/recv_linux.o \
- os_dep/usb_intf.o \
- os_dep/usb_ops_linux.o \
- os_dep/xmit_linux.o
-
-r8723au-$(CONFIG_8723AU_BT_COEXIST) += hal/rtl8723a_bt-coexist.o
-r8723au-$(CONFIG_8723AU_AP_MODE) += core/rtw_ap.o
-
-obj-$(CONFIG_R8723AU) := r8723au.o
-
-ccflags-y += $(call cc-option,-Wtype-limits,)
-ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/include
diff --git a/drivers/staging/rtl8723au/TODO b/drivers/staging/rtl8723au/TODO
deleted file mode 100644
index 42b86e478df8..000000000000
--- a/drivers/staging/rtl8723au/TODO
+++ /dev/null
@@ -1,16 +0,0 @@
-TODO:
-- find and remove code valid only for 5 HGz. Many of the obvious
- ones have been removed, but things like channel > 14 still exist.
-- find and remove any code for other chips that is left over
-- convert any remaining unusual variable types
-- find codes that can use %pM and %Nph formatting
-- checkpatch.pl fixes - most of the remaining ones are lines too long. Many
- of them will require refactoring
-- merge Realtek's bugfixes and new features into the driver
-- switch to use MAC80211
-
-A mac80211 driver for this hardware already was integrated at
-drivers/net/wireless/realtek/rtl8xxxu/
-
-Please send any patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
-Jes Sorensen <Jes.Sorensen@redhat.com>, and Larry Finger <Larry.Finger@lwfinger.net>.
diff --git a/drivers/staging/rtl8723au/core/rtw_ap.c b/drivers/staging/rtl8723au/core/rtw_ap.c
deleted file mode 100644
index aad686da3cf0..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_ap.c
+++ /dev/null
@@ -1,1738 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTW_AP_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <linux/ieee80211.h>
-#include <wifi.h>
-#include <rtl8723a_cmd.h>
-#include <rtl8723a_hal.h>
-#include <asm/unaligned.h>
-#include <rtw_mlme_ext.h>
-
-void init_mlme_ap_info23a(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
-
- spin_lock_init(&pmlmepriv->bcn_update_lock);
-
- /* for ACL */
- _rtw_init_queue23a(&pacl_list->acl_node_q);
-
- start_ap_mode23a(padapter);
-}
-
-void free_mlme_ap_info23a(struct rtw_adapter *padapter)
-{
- struct sta_info *psta = NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- pmlmepriv->update_bcn = false;
- pmlmeext->bstart_bss = false;
-
- rtw_sta_flush23a(padapter);
-
- pmlmeinfo->state = MSR_NOLINK;
-
- /* free_assoc_sta_resources */
- rtw_free_all_stainfo23a(padapter);
-
- /* free bc/mc sta_info */
- psta = rtw_get_bcmc_stainfo23a(padapter);
- spin_lock_bh(&pstapriv->sta_hash_lock);
- rtw_free_stainfo23a(padapter, psta);
- spin_unlock_bh(&pstapriv->sta_hash_lock);
-}
-
-static void update_BCNTIM(struct rtw_adapter *padapter)
-{
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network;
- unsigned char *pie = pnetwork_mlmeext->IEs;
- u8 *p, *dst_ie, *premainder_ie = NULL, *pbackup_remainder_ie = NULL;
- uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
-
- p = rtw_get_ie23a(pie, WLAN_EID_TIM, &tim_ielen,
- pnetwork_mlmeext->IELength);
- if (p != NULL && tim_ielen > 0) {
- tim_ielen += 2;
-
- premainder_ie = p+tim_ielen;
-
- tim_ie_offset = (int)(p - pie);
-
- remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen;
-
- /* append TIM IE from dst_ie offset */
- dst_ie = p;
- } else {
- tim_ielen = 0;
-
- /* calculate head_len */
- offset = 0;
-
- /* get ssid_ie len */
- p = rtw_get_ie23a(pie, WLAN_EID_SSID,
- &tmp_len, pnetwork_mlmeext->IELength);
- if (p != NULL)
- offset += tmp_len+2;
-
- /* get supported rates len */
- p = rtw_get_ie23a(pie, WLAN_EID_SUPP_RATES,
- &tmp_len, pnetwork_mlmeext->IELength);
- if (p != NULL)
- offset += tmp_len+2;
-
- /* DS Parameter Set IE, len = 3 */
- offset += 3;
-
- premainder_ie = pie + offset;
-
- remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen;
-
- /* append TIM IE from offset */
- dst_ie = pie + offset;
- }
-
- if (remainder_ielen > 0) {
- pbackup_remainder_ie = kmalloc(remainder_ielen, GFP_ATOMIC);
- if (pbackup_remainder_ie && premainder_ie)
- memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
- }
-
- *dst_ie++ = WLAN_EID_TIM;
-
- if ((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fc))
- tim_ielen = 5;
- else
- tim_ielen = 4;
-
- *dst_ie++ = tim_ielen;
-
- *dst_ie++ = 0; /* DTIM count */
- *dst_ie++ = 1; /* DTIM period */
-
- if (pstapriv->tim_bitmap & BIT(0)) /* for bc/mc frames */
- *dst_ie++ = BIT(0); /* bitmap ctrl */
- else
- *dst_ie++ = 0;
-
- if (tim_ielen == 4) {
- *dst_ie++ = pstapriv->tim_bitmap & 0xff;
- } else if (tim_ielen == 5) {
- put_unaligned_le16(pstapriv->tim_bitmap, dst_ie);
- dst_ie += 2;
- }
-
- /* copy remainder IE */
- if (pbackup_remainder_ie) {
- memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
-
- kfree(pbackup_remainder_ie);
- }
-
- offset = (uint)(dst_ie - pie);
- pnetwork_mlmeext->IELength = offset + remainder_ielen;
-
- set_tx_beacon_cmd23a(padapter);
-}
-
-static u8 chk_sta_is_alive(struct sta_info *psta)
-{
- u8 ret = false;
-
- if ((psta->sta_stats.last_rx_data_pkts +
- psta->sta_stats.last_rx_ctrl_pkts) !=
- (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts))
- ret = true;
-
- sta_update_last_rx_pkts(psta);
-
- return ret;
-}
-
-void expire_timeout_chk23a(struct rtw_adapter *padapter)
-{
- struct list_head *phead;
- u8 updated = 0;
- struct sta_info *psta, *ptmp;
- struct sta_priv *pstapriv = &padapter->stapriv;
- u8 chk_alive_num = 0;
- struct sta_info *chk_alive_list[NUM_STA];
- int i;
-
- spin_lock_bh(&pstapriv->auth_list_lock);
- phead = &pstapriv->auth_list;
- /* check auth_queue */
- list_for_each_entry_safe(psta, ptmp, phead, auth_list) {
- if (psta->expire_to > 0) {
- psta->expire_to--;
- if (psta->expire_to == 0) {
- list_del_init(&psta->auth_list);
- pstapriv->auth_list_cnt--;
-
- DBG_8723A("auth expire %pM\n", psta->hwaddr);
-
- spin_unlock_bh(&pstapriv->auth_list_lock);
-
- spin_lock_bh(&pstapriv->sta_hash_lock);
- rtw_free_stainfo23a(padapter, psta);
- spin_unlock_bh(&pstapriv->sta_hash_lock);
-
- spin_lock_bh(&pstapriv->auth_list_lock);
- }
- }
- }
- spin_unlock_bh(&pstapriv->auth_list_lock);
-
- spin_lock_bh(&pstapriv->asoc_list_lock);
- phead = &pstapriv->asoc_list;
- /* check asoc_queue */
- list_for_each_entry_safe(psta, ptmp, phead, asoc_list) {
- if (chk_sta_is_alive(psta) || !psta->expire_to) {
- psta->expire_to = pstapriv->expire_to;
- psta->keep_alive_trycnt = 0;
- } else {
- psta->expire_to--;
- }
-
- if (psta->expire_to <= 0) {
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- if (padapter->registrypriv.wifi_spec == 1) {
- psta->expire_to = pstapriv->expire_to;
- continue;
- }
-
- if (psta->state & WIFI_SLEEP_STATE) {
- if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
- /*
- * check if alive by another method
- * if station is at ps mode.
- */
- psta->expire_to = pstapriv->expire_to;
- psta->state |= WIFI_STA_ALIVE_CHK_STATE;
- /*
- * update bcn with tim_bitmap
- * for this station
- */
- pstapriv->tim_bitmap |= CHKBIT(psta->aid);
- update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
-
- if (!pmlmeext->active_keep_alive_check)
- continue;
- }
- }
-
- if (pmlmeext->active_keep_alive_check) {
- chk_alive_list[chk_alive_num++] = psta;
- continue;
- }
-
- list_del_init(&psta->asoc_list);
- pstapriv->asoc_list_cnt--;
-
- DBG_8723A("asoc expire %pM, state = 0x%x\n",
- psta->hwaddr, psta->state);
- updated = ap_free_sta23a(padapter, psta, false, WLAN_REASON_DEAUTH_LEAVING);
- } else {
- /*
- * TODO: Aging mechanism to digest frames in
- * sleep_q to avoid running out of xmitframe
- */
- if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt)
- && padapter->xmitpriv.free_xmitframe_cnt < ((NR_XMITFRAME/pstapriv->asoc_list_cnt)/2)
- ) {
- DBG_8723A("%s sta:%pM, sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n",
- __func__,
- psta->hwaddr,
- psta->sleepq_len,
- padapter->xmitpriv.free_xmitframe_cnt,
- pstapriv->asoc_list_cnt);
- wakeup_sta_to_xmit23a(padapter, psta);
- }
- }
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
-
- if (chk_alive_num) {
-
- u8 backup_oper_channel = 0;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- /*
- * switch to correct channel of current
- * network before issue keep-alive frames
- */
- if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel) {
- backup_oper_channel = rtw_get_oper_ch23a(padapter);
- SelectChannel23a(padapter, pmlmeext->cur_channel);
- }
-
- /* issue null data to check sta alive */
- for (i = 0; i < chk_alive_num; i++) {
-
- int ret = _FAIL;
-
- psta = chk_alive_list[i];
- if (!(psta->state & _FW_LINKED))
- continue;
-
- if (psta->state & WIFI_SLEEP_STATE)
- ret = issue_nulldata23a(padapter, psta->hwaddr, 0, 1, 50);
- else
- ret = issue_nulldata23a(padapter, psta->hwaddr, 0, 3, 50);
-
- psta->keep_alive_trycnt++;
- if (ret == _SUCCESS) {
- DBG_8723A("asoc check, sta(%pM) is alive\n",
- psta->hwaddr);
- psta->expire_to = pstapriv->expire_to;
- psta->keep_alive_trycnt = 0;
- continue;
- } else if (psta->keep_alive_trycnt <= 3) {
- DBG_8723A("ack check for asoc expire, keep_alive_trycnt =%d\n", psta->keep_alive_trycnt);
- psta->expire_to = 1;
- continue;
- }
-
- psta->keep_alive_trycnt = 0;
-
- DBG_8723A("asoc expire %pM, state = 0x%x\n",
- psta->hwaddr, psta->state);
- spin_lock_bh(&pstapriv->asoc_list_lock);
- if (!list_empty(&psta->asoc_list)) {
- list_del_init(&psta->asoc_list);
- pstapriv->asoc_list_cnt--;
- updated = ap_free_sta23a(padapter, psta, false, WLAN_REASON_DEAUTH_LEAVING);
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
-
- }
-
- if (backup_oper_channel > 0) /* back to original operation channel */
- SelectChannel23a(padapter, backup_oper_channel);
-}
-
- associated_clients_update23a(padapter, updated);
-}
-
-void add_RATid23a(struct rtw_adapter *padapter, struct sta_info *psta, u8 rssi_level)
-{
- int i;
- u8 rf_type;
- u32 init_rate = 0;
- unsigned char sta_band = 0, raid, shortGIrate = false;
- unsigned char limit;
- unsigned int tx_ra_bitmap = 0;
- struct ht_priv *psta_ht = NULL;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_bssid_ex *pcur_network = &pmlmepriv->cur_network.network;
-
- if (psta)
- psta_ht = &psta->htpriv;
- else
- return;
-
- if (!(psta->state & _FW_LINKED))
- return;
-
- /* b/g mode ra_bitmap */
- for (i = 0; i < sizeof(psta->bssrateset); i++) {
- if (psta->bssrateset[i])
- tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value23a(psta->bssrateset[i]&0x7f);
- }
- /* n mode ra_bitmap */
- if (psta_ht->ht_option) {
- rf_type = rtl8723a_get_rf_type(padapter);
-
- if (rf_type == RF_2T2R)
- limit = 16; /* 2R */
- else
- limit = 8; /* 1R */
-
- for (i = 0; i < limit; i++) {
- if (psta_ht->ht_cap.mcs.rx_mask[i / 8] & BIT(i % 8))
- tx_ra_bitmap |= BIT(i + 12);
- }
-
- /* max short GI rate */
- shortGIrate = psta_ht->sgi;
- }
-
- if (pcur_network->DSConfig > 14) {
- /* 5G band */
- if (tx_ra_bitmap & 0xffff000)
- sta_band |= WIRELESS_11_5N | WIRELESS_11A;
- else
- sta_band |= WIRELESS_11A;
- } else {
- if (tx_ra_bitmap & 0xffff000)
- sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
- else if (tx_ra_bitmap & 0xff0)
- sta_band |= WIRELESS_11G | WIRELESS_11B;
- else
- sta_band |= WIRELESS_11B;
- }
-
- psta->wireless_mode = sta_band;
-
- raid = networktype_to_raid23a(sta_band);
- init_rate = get_highest_rate_idx23a(tx_ra_bitmap&0x0fffffff)&0x3f;
-
- if (psta->aid < NUM_STA) {
- u8 arg;
-
- arg = psta->mac_id&0x1f;
-
- arg |= BIT(7); /* support entry 2~31 */
-
- if (shortGIrate == true)
- arg |= BIT(5);
-
- tx_ra_bitmap |= ((raid<<28)&0xf0000000);
-
- DBG_8723A("%s => mac_id:%d , raid:%d , bitmap = 0x%x, arg = "
- "0x%x\n",
- __func__, psta->mac_id, raid, tx_ra_bitmap, arg);
-
- /* bitmap[0:27] = tx_rate_bitmap */
- /* bitmap[28:31]= Rate Adaptive id */
- /* arg[0:4] = macid */
- /* arg[5] = Short GI */
- rtl8723a_add_rateatid(padapter, tx_ra_bitmap, arg, rssi_level);
-
- if (shortGIrate == true)
- init_rate |= BIT(6);
-
- /* set ra_id, init_rate */
- psta->raid = raid;
- psta->init_rate = init_rate;
-
- } else
- DBG_8723A("station aid %d exceed the max number\n", psta->aid);
-}
-
-static void update_bmc_sta(struct rtw_adapter *padapter)
-{
- u32 init_rate = 0;
- unsigned char network_type, raid;
- int i, supportRateNum = 0;
- unsigned int tx_ra_bitmap = 0;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_bssid_ex *pcur_network = &pmlmepriv->cur_network.network;
- struct sta_info *psta = rtw_get_bcmc_stainfo23a(padapter);
-
- if (psta) {
- psta->aid = 0; /* default set to 0 */
- psta->mac_id = psta->aid + 1;
-
- psta->qos_option = 0;
- psta->htpriv.ht_option = false;
-
- psta->ieee8021x_blocked = 0;
-
- memset((void *)&psta->sta_stats, 0,
- sizeof(struct stainfo_stats));
-
- /* prepare for add_RATid23a */
- supportRateNum = rtw_get_rateset_len23a((u8 *)&pcur_network->SupportedRates);
- network_type = rtw_check_network_type23a((u8 *)&pcur_network->SupportedRates, supportRateNum, 1);
-
- memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum);
- psta->bssratelen = supportRateNum;
-
- /* b/g mode ra_bitmap */
- for (i = 0; i < supportRateNum; i++) {
- if (psta->bssrateset[i])
- tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value23a(psta->bssrateset[i]&0x7f);
- }
-
- if (pcur_network->DSConfig > 14) {
- /* force to A mode. 5G doesn't support CCK rates */
- network_type = WIRELESS_11A;
- tx_ra_bitmap = 0x150; /* 6, 12, 24 Mbps */
- } else {
- /* force to b mode */
- network_type = WIRELESS_11B;
- tx_ra_bitmap = 0xf;
- }
-
- raid = networktype_to_raid23a(network_type);
- init_rate = get_highest_rate_idx23a(tx_ra_bitmap&0x0fffffff)&0x3f;
-
- /* ap mode */
- rtl8723a_SetHalODMVar(padapter, HAL_ODM_STA_INFO, psta, true);
-
- {
- u8 arg;
-
- arg = psta->mac_id&0x1f;
-
- arg |= BIT(7);
-
- tx_ra_bitmap |= ((raid<<28)&0xf0000000);
-
- DBG_8723A("update_bmc_sta, mask = 0x%x, arg = 0x%x\n", tx_ra_bitmap, arg);
-
- /* bitmap[0:27] = tx_rate_bitmap */
- /* bitmap[28:31]= Rate Adaptive id */
- /* arg[0:4] = macid */
- /* arg[5] = Short GI */
- rtl8723a_add_rateatid(padapter, tx_ra_bitmap, arg, 0);
- }
-
- /* set ra_id, init_rate */
- psta->raid = raid;
- psta->init_rate = init_rate;
-
- spin_lock_bh(&psta->lock);
- psta->state = _FW_LINKED;
- spin_unlock_bh(&psta->lock);
-
- } else
- DBG_8723A("add_RATid23a_bmc_sta error!\n");
-}
-
-/*
- * AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode
- * MAC_ID = AID+1 for sta in ap/adhoc mode
- * MAC_ID = 1 for bc/mc for sta/ap/adhoc
- * MAC_ID = 0 for bssid for sta/ap/adhoc
- * CAM_ID = 0~3 for default key, cmd_id = macid + 3, macid = aid + 1;
- */
-void update_sta_info23a_apmode23a(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
- struct ht_priv *phtpriv_sta = &psta->htpriv;
- /* set intf_tag to if1 */
-
- psta->mac_id = psta->aid+1;
- DBG_8723A("%s\n", __func__);
-
- /* ap mode */
- rtl8723a_SetHalODMVar(padapter, HAL_ODM_STA_INFO, psta, true);
-
- if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
- psta->ieee8021x_blocked = true;
- else
- psta->ieee8021x_blocked = false;
-
- /* update sta's cap */
-
- /* ERP */
- VCS_update23a(padapter, psta);
- /* HT related cap */
- if (phtpriv_sta->ht_option) {
- /* check if sta supports rx ampdu */
- phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
-
- /* check if sta support s Short GI */
- if ((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40))
- phtpriv_sta->sgi = true;
-
- /* bwmode */
- if ((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
- /* phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_40; */
- phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
- phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
-
- }
-
- psta->qos_option = true;
-
- } else {
- phtpriv_sta->ampdu_enable = false;
-
- phtpriv_sta->sgi = false;
- phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
- phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- }
-
- /* Rx AMPDU */
- send_delba23a(padapter, 0, psta->hwaddr); /* recipient */
-
- /* TX AMPDU */
- send_delba23a(padapter, 1, psta->hwaddr); /* originator */
- phtpriv_sta->agg_enable_bitmap = 0x0;/* reset */
- phtpriv_sta->candidate_tid_bitmap = 0x0;/* reset */
-
- /* todo: init other variables */
-
- memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
-
- spin_lock_bh(&psta->lock);
- psta->state |= _FW_LINKED;
- spin_unlock_bh(&psta->lock);
-}
-
-static void update_hw_ht_param(struct rtw_adapter *padapter)
-{
- unsigned char max_AMPDU_len;
- unsigned char min_MPDU_spacing;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- DBG_8723A("%s\n", __func__);
- /*
- * handle A-MPDU parameter field
- * AMPDU_para [1:0]:Max AMPDU Len => 0:8k, 1:16k, 2:32k, 3:64k
- * AMPDU_para [4:2]:Min MPDU Start Spacing
- */
- max_AMPDU_len = pmlmeinfo->ht_cap.ampdu_params_info &
- IEEE80211_HT_AMPDU_PARM_FACTOR;
-
- min_MPDU_spacing = (pmlmeinfo->ht_cap.ampdu_params_info &
- IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2;
-
- rtl8723a_set_ampdu_min_space(padapter, min_MPDU_spacing);
- rtl8723a_set_ampdu_factor(padapter, max_AMPDU_len);
-
- /* Config SM Power Save setting */
- pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->ht_cap.cap_info) &
- IEEE80211_HT_CAP_SM_PS) >> 2;
- if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
- DBG_8723A("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
-}
-
-static void start_bss_network(struct rtw_adapter *padapter, u8 *pbuf)
-{
- const u8 *p;
- u8 val8, cur_channel, cur_bwmode, cur_ch_offset;
- u16 bcn_interval;
- u32 acparm;
- struct registry_priv *pregpriv = &padapter->registrypriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct wlan_bssid_ex *pnetwork = &pmlmepriv->cur_network.network;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network;
- struct ieee80211_ht_operation *pht_info = NULL;
-
- bcn_interval = (u16)pnetwork->beacon_interval;
- cur_channel = pnetwork->DSConfig;
- cur_bwmode = HT_CHANNEL_WIDTH_20;
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-
- /*
- * check if there is wps ie
- * if there is wpsie in beacon the hostapd will
- * update beacon twice when stating hostapd
- * and at first time the security
- * ie (RSN/WPA IE) will not include in beacon
- */
- if (!cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WPS,
- pnetwork->IEs,
- pnetwork->IELength))
- pmlmeext->bstart_bss = true;
-
- /* todo: update wmm, ht cap */
- /* pmlmeinfo->WMM_enable; */
- /* pmlmeinfo->HT_enable; */
- if (pmlmepriv->qos_option)
- pmlmeinfo->WMM_enable = true;
- if (pmlmepriv->htpriv.ht_option) {
- pmlmeinfo->WMM_enable = true;
- pmlmeinfo->HT_enable = true;
-
- update_hw_ht_param(padapter);
- }
-
- if (pmlmepriv->cur_network.join_res != true) {
- /*
- * setting only at first time
- * WEP Key will be set before this
- * function, do not clear CAM.
- */
- if (psecuritypriv->dot11PrivacyAlgrthm !=
- WLAN_CIPHER_SUITE_WEP40 &&
- psecuritypriv->dot11PrivacyAlgrthm !=
- WLAN_CIPHER_SUITE_WEP104)
- flush_all_cam_entry23a(padapter); /* clear CAM */
- }
-
- /* set MSR to AP_Mode */
- rtl8723a_set_media_status(padapter, MSR_AP);
-
- /* Set BSSID REG */
- hw_var_set_bssid(padapter, pnetwork->MacAddress);
-
- /* Set EDCA param reg */
- acparm = 0x002F3217; /* VO */
- rtl8723a_set_ac_param_vo(padapter, acparm);
- acparm = 0x005E4317; /* VI */
- rtl8723a_set_ac_param_vi(padapter, acparm);
- acparm = 0x005ea42b;
- rtl8723a_set_ac_param_be(padapter, acparm);
- acparm = 0x0000A444; /* BK */
- rtl8723a_set_ac_param_bk(padapter, acparm);
-
- /* Set Security */
- val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ?
- 0xcc : 0xcf;
- rtl8723a_set_sec_cfg(padapter, val8);
-
- /* Beacon Control related register */
- rtl8723a_set_beacon_interval(padapter, bcn_interval);
-
- UpdateBrateTbl23a(padapter, pnetwork->SupportedRates);
- HalSetBrateCfg23a(padapter, pnetwork->SupportedRates);
-
- if (!pmlmepriv->cur_network.join_res) {
- /* setting only at first time */
-
- /* disable dynamic functions, such as high power, DIG */
-
- /* turn on all dynamic functions */
- rtl8723a_odm_support_ability_set(padapter,
- DYNAMIC_ALL_FUNC_ENABLE);
- }
- /* set channel, bwmode */
-
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, pnetwork->IEs,
- pnetwork->IELength);
- if (p && p[1]) {
- pht_info = (struct ieee80211_ht_operation *)(p + 2);
-
- if (pregpriv->cbw40_enable && pht_info->ht_param &
- IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) {
- /* switch to the 40M Hz mode */
- cur_bwmode = HT_CHANNEL_WIDTH_40;
- switch (pht_info->ht_param &
- IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
- case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
- /*
- * pmlmeext->cur_ch_offset =
- * HAL_PRIME_CHNL_OFFSET_LOWER;
- */
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
- break;
- case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
- break;
- default:
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- break;
- }
- }
- }
- /*
- * TODO: need to judge the phy parameters
- * on concurrent mode for single phy
- */
- set_channel_bwmode23a(padapter, cur_channel, cur_ch_offset, cur_bwmode);
-
- DBG_8723A("CH =%d, BW =%d, offset =%d\n", cur_channel, cur_bwmode,
- cur_ch_offset);
-
- pmlmeext->cur_channel = cur_channel;
- pmlmeext->cur_bwmode = cur_bwmode;
- pmlmeext->cur_ch_offset = cur_ch_offset;
- pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type;
-
- /* update cur_wireless_mode */
- update_wireless_mode23a(padapter);
-
- /* update capability after cur_wireless_mode updated */
- update_capinfo23a(padapter, pnetwork->capability);
-
- /* let pnetwork_mlmeext == pnetwork_mlme. */
- memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
-
- if (pmlmeext->bstart_bss) {
- update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
-
- /* issue beacon frame */
- if (send_beacon23a(padapter) == _FAIL)
- DBG_8723A("issue_beacon23a, fail!\n");
- }
-
- /* update bc/mc sta_info */
- update_bmc_sta(padapter);
-}
-
-int rtw_check_beacon_data23a(struct rtw_adapter *padapter,
- struct ieee80211_mgmt *mgmt, unsigned int len)
-{
- int ret = _SUCCESS;
- u8 *p;
- u8 *pHT_caps_ie = NULL;
- u8 *pHT_info_ie = NULL;
- struct sta_info *psta = NULL;
- u16 ht_cap = false;
- uint ie_len = 0;
- int group_cipher, pairwise_cipher;
- u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];
- int supportRateNum = 0;
- u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
- struct registry_priv *pregistrypriv = &padapter->registrypriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_bssid_ex *pbss_network = &pmlmepriv->cur_network.network;
- u8 *ie = pbss_network->IEs;
- u8 *pbuf = mgmt->u.beacon.variable;
-
- len -= offsetof(struct ieee80211_mgmt, u.beacon.variable);
- /* SSID */
- /* Supported rates */
- /* DS Params */
- /* WLAN_EID_COUNTRY */
- /* ERP Information element */
- /* Extended supported rates */
- /* WPA/WPA2 */
- /* Wi-Fi Wireless Multimedia Extensions */
- /* ht_capab, ht_oper */
- /* WPS IE */
-
- DBG_8723A("%s, len =%d\n", __func__, len);
-
- if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
- return _FAIL;
-
- if (len > MAX_IE_SZ)
- return _FAIL;
-
- pbss_network->IELength = len;
-
- memset(ie, 0, MAX_IE_SZ);
-
- memcpy(ie, pbuf, pbss_network->IELength);
-
- if (pbss_network->ifmode != NL80211_IFTYPE_AP &&
- pbss_network->ifmode != NL80211_IFTYPE_P2P_GO)
- return _FAIL;
-
- pbss_network->Rssi = 0;
-
- memcpy(pbss_network->MacAddress, myid(&padapter->eeprompriv), ETH_ALEN);
-
- /* SSID */
- p = rtw_get_ie23a(ie, WLAN_EID_SSID, &ie_len, pbss_network->IELength);
- if (p && ie_len > 0) {
- memset(&pbss_network->Ssid, 0, sizeof(struct cfg80211_ssid));
- memcpy(pbss_network->Ssid.ssid, (p + 2), ie_len);
- pbss_network->Ssid.ssid_len = ie_len;
- }
-
- /* channel */
- channel = 0;
- p = rtw_get_ie23a(ie, WLAN_EID_DS_PARAMS, &ie_len,
- pbss_network->IELength);
- if (p && ie_len > 0)
- channel = *(p + 2);
-
- pbss_network->DSConfig = channel;
-
- memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
- /* get supported rates */
- p = rtw_get_ie23a(ie, WLAN_EID_SUPP_RATES, &ie_len,
- pbss_network->IELength);
- if (p) {
- memcpy(supportRate, p+2, ie_len);
- supportRateNum = ie_len;
- }
-
- /* get ext_supported rates */
- p = rtw_get_ie23a(ie, WLAN_EID_EXT_SUPP_RATES,
- &ie_len, pbss_network->IELength);
- if (p) {
- memcpy(supportRate+supportRateNum, p+2, ie_len);
- supportRateNum += ie_len;
- }
-
- network_type = rtw_check_network_type23a(supportRate,
- supportRateNum, channel);
-
- rtw_set_supported_rate23a(pbss_network->SupportedRates, network_type);
-
- /* parsing ERP_IE */
- p = rtw_get_ie23a(ie, WLAN_EID_ERP_INFO, &ie_len,
- pbss_network->IELength);
- if (p && ie_len > 0)
- ERP_IE_handler23a(padapter, p);
-
- /* update privacy/security */
- if (pbss_network->capability & BIT(4))
- pbss_network->Privacy = 1;
- else
- pbss_network->Privacy = 0;
-
- psecuritypriv->wpa_psk = 0;
-
- /* wpa2 */
- group_cipher = 0; pairwise_cipher = 0;
- psecuritypriv->wpa2_group_cipher = 0;
- psecuritypriv->wpa2_pairwise_cipher = 0;
- p = rtw_get_ie23a(ie, WLAN_EID_RSN, &ie_len,
- pbss_network->IELength);
- if (p && ie_len > 0) {
- if (rtw_parse_wpa2_ie23a(p, ie_len+2, &group_cipher,
- &pairwise_cipher, NULL) == _SUCCESS) {
- psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
-
- psecuritypriv->dot8021xalg = 1; /* psk, todo:802.1x */
- psecuritypriv->wpa_psk |= BIT(1);
-
- psecuritypriv->wpa2_group_cipher = group_cipher;
- psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
- }
- }
-
- /* wpa */
- ie_len = 0;
- group_cipher = 0;
- pairwise_cipher = 0;
- psecuritypriv->wpa_group_cipher = 0;
- psecuritypriv->wpa_pairwise_cipher = 0;
- for (p = ie; ; p += (ie_len + 2)) {
- p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
- pbss_network->IELength - (ie_len + 2));
- if ((p) && (!memcmp(p+2, RTW_WPA_OUI23A_TYPE, 4))) {
- if (rtw_parse_wpa_ie23a(p, ie_len+2, &group_cipher,
- &pairwise_cipher, NULL) == _SUCCESS) {
- psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
-
- /* psk, todo:802.1x */
- psecuritypriv->dot8021xalg = 1;
-
- psecuritypriv->wpa_psk |= BIT(0);
-
- psecuritypriv->wpa_group_cipher = group_cipher;
- psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;
- }
- break;
- }
-
- if (!p || !ie_len)
- break;
- }
-
- /* wmm */
- ie_len = 0;
- pmlmepriv->qos_option = 0;
- if (pregistrypriv->wmm_enable) {
- for (p = ie; ; p += (ie_len + 2)) {
- p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
- (pbss_network->IELength -
- (ie_len + 2)));
- if ((p) && !memcmp(p+2, WMM_PARA_IE, 6)) {
- pmlmepriv->qos_option = 1;
-
- *(p + 8) |= BIT(7);/* QoS Info:support U-APSD */
-
- /* disable all ACM bits since the WMM admission
- * control is not supported
- */
- *(p + 10) &= ~BIT(4); /* BE */
- *(p + 14) &= ~BIT(4); /* BK */
- *(p + 18) &= ~BIT(4); /* VI */
- *(p + 22) &= ~BIT(4); /* VO */
- break;
- }
- if ((p == NULL) || (ie_len == 0))
- break;
- }
- }
- /* parsing HT_CAP_IE */
- p = rtw_get_ie23a(ie, WLAN_EID_HT_CAPABILITY, &ie_len,
- pbss_network->IELength);
- if (p && ie_len > 0) {
- u8 rf_type;
-
- struct ieee80211_ht_cap *pht_cap = (struct ieee80211_ht_cap *)(p+2);
-
- pHT_caps_ie = p;
-
- ht_cap = true;
- network_type |= WIRELESS_11_24N;
-
- rf_type = rtl8723a_get_rf_type(padapter);
-
- if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
- (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))
- pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY & (0x07<<2));
- else
- pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_DENSITY&0x00);
-
- /* set Max Rx AMPDU size to 64K */
- pht_cap->ampdu_params_info |= (IEEE80211_HT_AMPDU_PARM_FACTOR & 0x03);
-
- if (rf_type == RF_1T1R) {
- pht_cap->mcs.rx_mask[0] = 0xff;
- pht_cap->mcs.rx_mask[1] = 0x0;
- }
-
- memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len);
- }
-
- /* parsing HT_INFO_IE */
- p = rtw_get_ie23a(ie, WLAN_EID_HT_OPERATION, &ie_len,
- pbss_network->IELength);
- if (p && ie_len > 0)
- pHT_info_ie = p;
-
- pmlmepriv->cur_network.network_type = network_type;
-
- pmlmepriv->htpriv.ht_option = false;
-
- /* ht_cap */
- if (pregistrypriv->ht_enable && ht_cap) {
- pmlmepriv->htpriv.ht_option = true;
- pmlmepriv->qos_option = 1;
-
- if (pregistrypriv->ampdu_enable == 1)
- pmlmepriv->htpriv.ampdu_enable = true;
-
- HT_caps_handler23a(padapter, pHT_caps_ie);
-
- HT_info_handler23a(padapter, pHT_info_ie);
- }
-
- pbss_network->Length = get_wlan_bssid_ex_sz(pbss_network);
-
- /* issue beacon to start bss network */
- start_bss_network(padapter, (u8 *)pbss_network);
-
- /* alloc sta_info for ap itself */
- psta = rtw_get_stainfo23a(&padapter->stapriv, pbss_network->MacAddress);
- if (!psta) {
- psta = rtw_alloc_stainfo23a(&padapter->stapriv,
- pbss_network->MacAddress,
- GFP_KERNEL);
- if (!psta)
- return _FAIL;
- }
- /* fix bug of flush_cam_entry at STOP AP mode */
- psta->state |= WIFI_AP_STATE;
- rtw_indicate_connect23a(padapter);
-
- /* for check if already set beacon */
- pmlmepriv->cur_network.join_res = true;
-
- return ret;
-}
-
-void rtw_set_macaddr_acl23a(struct rtw_adapter *padapter, int mode)
-{
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
-
- DBG_8723A("%s, mode =%d\n", __func__, mode);
-
- pacl_list->mode = mode;
-}
-
-static void update_bcn_erpinfo_ie(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
- unsigned char *p, *ie = pnetwork->IEs;
- u32 len = 0;
-
- DBG_8723A("%s, ERP_enable =%d\n", __func__, pmlmeinfo->ERP_enable);
-
- if (!pmlmeinfo->ERP_enable)
- return;
-
- /* parsing ERP_IE */
- p = rtw_get_ie23a(ie, WLAN_EID_ERP_INFO, &len, pnetwork->IELength);
- if (p && len > 0) {
- if (pmlmepriv->num_sta_non_erp == 1)
- p[2] |= WLAN_ERP_NON_ERP_PRESENT |
- WLAN_ERP_USE_PROTECTION;
- else
- p[2] &= ~(WLAN_ERP_NON_ERP_PRESENT |
- WLAN_ERP_USE_PROTECTION);
-
- if (pmlmepriv->num_sta_no_short_preamble > 0)
- p[2] |= WLAN_ERP_BARKER_PREAMBLE;
- else
- p[2] &= ~(WLAN_ERP_BARKER_PREAMBLE);
-
- ERP_IE_handler23a(padapter, p);
- }
-}
-
-static void update_bcn_wpa_ie(struct rtw_adapter *padapter)
-{
- DBG_8723A("%s\n", __func__);
-}
-
-static void update_bcn_wmm_ie(struct rtw_adapter *padapter)
-{
- DBG_8723A("%s\n", __func__);
-}
-
-static void update_bcn_wps_ie(struct rtw_adapter *padapter)
-{
- DBG_8723A("%s\n", __func__);
-}
-
-static void update_bcn_p2p_ie(struct rtw_adapter *padapter)
-{
-}
-
-static void update_bcn_vendor_spec_ie(struct rtw_adapter *padapter, u8 *oui)
-{
- DBG_8723A("%s\n", __func__);
-
- if (!memcmp(RTW_WPA_OUI23A_TYPE, oui, 4))
- update_bcn_wpa_ie(padapter);
- else if (!memcmp(WMM_OUI23A, oui, 4))
- update_bcn_wmm_ie(padapter);
- else if (!memcmp(WPS_OUI23A, oui, 4))
- update_bcn_wps_ie(padapter);
- else if (!memcmp(P2P_OUI23A, oui, 4))
- update_bcn_p2p_ie(padapter);
- else
- DBG_8723A("unknown OUI type!\n");
-}
-
-void update_beacon23a(struct rtw_adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
-{
- struct mlme_priv *pmlmepriv;
- struct mlme_ext_priv *pmlmeext;
- /* struct mlme_ext_info *pmlmeinfo; */
-
- /* DBG_8723A("%s\n", __func__); */
-
- if (!padapter)
- return;
-
- pmlmepriv = &padapter->mlmepriv;
- pmlmeext = &padapter->mlmeextpriv;
- /* pmlmeinfo = &pmlmeext->mlmext_info; */
-
- if (false == pmlmeext->bstart_bss)
- return;
-
- spin_lock_bh(&pmlmepriv->bcn_update_lock);
-
- switch (ie_id) {
- case WLAN_EID_TIM:
- update_BCNTIM(padapter);
- break;
-
- case WLAN_EID_ERP_INFO:
- update_bcn_erpinfo_ie(padapter);
- break;
-
- case WLAN_EID_VENDOR_SPECIFIC:
- update_bcn_vendor_spec_ie(padapter, oui);
- break;
-
- default:
- break;
- }
-
- pmlmepriv->update_bcn = true;
-
- spin_unlock_bh(&pmlmepriv->bcn_update_lock);
-
- if (tx)
- set_tx_beacon_cmd23a(padapter);
-}
-
-/*
- * op_mode
- * Set to 0 (HT pure) under the following conditions
- * - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
- * - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
- * Set to 1 (HT non-member protection) if there may be non-HT STAs
- * in both the primary and the secondary channel
- * Set to 2 if only HT STAs are associated in BSS,
- * however and at least one 20 MHz HT STA is associated
- * Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
- * (currently non-GF HT station is considered as non-HT STA also)
-*/
-static int rtw_ht_operation_update(struct rtw_adapter *padapter)
-{
- u16 cur_op_mode, new_op_mode;
- int op_mode_changes = 0;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
-
- if (pmlmepriv->htpriv.ht_option)
- return 0;
-
- /* if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed) */
- /* return 0; */
-
- DBG_8723A("%s current operation mode = 0x%X\n",
- __func__, pmlmepriv->ht_op_mode);
-
- if (!(pmlmepriv->ht_op_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
- && pmlmepriv->num_sta_ht_no_gf) {
- pmlmepriv->ht_op_mode |=
- IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT;
- op_mode_changes++;
- } else if ((pmlmepriv->ht_op_mode &
- IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) &&
- pmlmepriv->num_sta_ht_no_gf == 0) {
- pmlmepriv->ht_op_mode &=
- ~IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT;
- op_mode_changes++;
- }
-
- if (!(pmlmepriv->ht_op_mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT) &&
- (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {
- pmlmepriv->ht_op_mode |= IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
- op_mode_changes++;
- } else if ((pmlmepriv->ht_op_mode &
- IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT) &&
- (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {
- pmlmepriv->ht_op_mode &=
- ~IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
- op_mode_changes++;
- }
-
- /*
- * Note: currently we switch to the MIXED op mode if HT non-greenfield
- * station is associated. Probably it's a theoretical case, since
- * it looks like all known HT STAs support greenfield.
- */
- if (pmlmepriv->num_sta_no_ht ||
- (pmlmepriv->ht_op_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT))
- new_op_mode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
- else if ((le16_to_cpu(phtpriv_ap->ht_cap.cap_info) &
- IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
- pmlmepriv->num_sta_ht_20mhz)
- new_op_mode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
- else if (pmlmepriv->olbc_ht)
- new_op_mode = IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER;
- else
- new_op_mode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
-
- cur_op_mode = pmlmepriv->ht_op_mode & IEEE80211_HT_OP_MODE_PROTECTION;
- if (cur_op_mode != new_op_mode) {
- pmlmepriv->ht_op_mode &= ~IEEE80211_HT_OP_MODE_PROTECTION;
- pmlmepriv->ht_op_mode |= new_op_mode;
- op_mode_changes++;
- }
-
- DBG_8723A("%s new operation mode = 0x%X changes =%d\n",
- __func__, pmlmepriv->ht_op_mode, op_mode_changes);
-
- return op_mode_changes;
-}
-
-void associated_clients_update23a(struct rtw_adapter *padapter, u8 updated)
-{
- /* update associated stations cap. */
- if (updated == true) {
- struct list_head *phead;
- struct sta_info *psta, *ptmp;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- spin_lock_bh(&pstapriv->asoc_list_lock);
- phead = &pstapriv->asoc_list;
- list_for_each_entry_safe(psta, ptmp, phead, asoc_list)
- VCS_update23a(padapter, psta);
- spin_unlock_bh(&pstapriv->asoc_list_lock);
- }
-}
-
-/* called > TSR LEVEL for USB or SDIO Interface */
-void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- u8 beacon_updated = false;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) {
- if (!psta->no_short_preamble_set) {
- psta->no_short_preamble_set = 1;
-
- pmlmepriv->num_sta_no_short_preamble++;
-
- if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
- (pmlmepriv->num_sta_no_short_preamble == 1)) {
- beacon_updated = true;
- update_beacon23a(padapter, 0xFF, NULL, true);
- }
-
- }
- } else {
- if (psta->no_short_preamble_set) {
- psta->no_short_preamble_set = 0;
-
- pmlmepriv->num_sta_no_short_preamble--;
-
- if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
- (pmlmepriv->num_sta_no_short_preamble == 0)) {
- beacon_updated = true;
- update_beacon23a(padapter, 0xFF, NULL, true);
- }
-
- }
- }
-
- if (psta->flags & WLAN_STA_NONERP) {
- if (!psta->nonerp_set) {
- psta->nonerp_set = 1;
-
- pmlmepriv->num_sta_non_erp++;
-
- if (pmlmepriv->num_sta_non_erp == 1) {
- beacon_updated = true;
- update_beacon23a(padapter, WLAN_EID_ERP_INFO, NULL, true);
- }
- }
-
- } else {
- if (psta->nonerp_set) {
- psta->nonerp_set = 0;
-
- pmlmepriv->num_sta_non_erp--;
-
- if (pmlmepriv->num_sta_non_erp == 0) {
- beacon_updated = true;
- update_beacon23a(padapter, WLAN_EID_ERP_INFO, NULL, true);
- }
- }
-
- }
-
- if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)) {
- if (!psta->no_short_slot_time_set) {
- psta->no_short_slot_time_set = 1;
-
- pmlmepriv->num_sta_no_short_slot_time++;
-
- if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
- (pmlmepriv->num_sta_no_short_slot_time == 1)) {
- beacon_updated = true;
- update_beacon23a(padapter, 0xFF, NULL, true);
- }
-
- }
- } else {
- if (psta->no_short_slot_time_set) {
- psta->no_short_slot_time_set = 0;
-
- pmlmepriv->num_sta_no_short_slot_time--;
-
- if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
- (pmlmepriv->num_sta_no_short_slot_time == 0)) {
- beacon_updated = true;
- update_beacon23a(padapter, 0xFF, NULL, true);
- }
- }
- }
-
- if (psta->flags & WLAN_STA_HT) {
- u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);
-
- DBG_8723A("HT: STA %pM HT Capabilities Info: 0x%04x\n",
- psta->hwaddr, ht_capab);
-
- if (psta->no_ht_set) {
- psta->no_ht_set = 0;
- pmlmepriv->num_sta_no_ht--;
- }
-
- if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
- if (!psta->no_ht_gf_set) {
- psta->no_ht_gf_set = 1;
- pmlmepriv->num_sta_ht_no_gf++;
- }
- DBG_8723A("%s STA %pM - no greenfield, num of non-gf stations %d\n",
- __func__, psta->hwaddr,
- pmlmepriv->num_sta_ht_no_gf);
- }
-
- if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH_20_40) == 0) {
- if (!psta->ht_20mhz_set) {
- psta->ht_20mhz_set = 1;
- pmlmepriv->num_sta_ht_20mhz++;
- }
- DBG_8723A("%s STA %pM - 20 MHz HT, num of 20MHz HT STAs %d\n",
- __func__, psta->hwaddr,
- pmlmepriv->num_sta_ht_20mhz);
- }
-
- } else {
- if (!psta->no_ht_set) {
- psta->no_ht_set = 1;
- pmlmepriv->num_sta_no_ht++;
- }
- if (pmlmepriv->htpriv.ht_option) {
- DBG_8723A("%s STA %pM - no HT, num of non-HT stations %d\n",
- __func__, psta->hwaddr,
- pmlmepriv->num_sta_no_ht);
- }
- }
-
- if (rtw_ht_operation_update(padapter) > 0) {
- update_beacon23a(padapter, WLAN_EID_HT_CAPABILITY, NULL, false);
- update_beacon23a(padapter, WLAN_EID_HT_OPERATION, NULL, true);
- }
-
- /* update associated stations cap. */
- associated_clients_update23a(padapter, beacon_updated);
-
- DBG_8723A("%s, updated =%d\n", __func__, beacon_updated);
-}
-
-u8 bss_cap_update_on_sta_leave23a(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- u8 beacon_updated = false;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- if (!psta)
- return beacon_updated;
-
- if (psta->no_short_preamble_set) {
- psta->no_short_preamble_set = 0;
- pmlmepriv->num_sta_no_short_preamble--;
- if (pmlmeext->cur_wireless_mode > WIRELESS_11B
- && pmlmepriv->num_sta_no_short_preamble == 0) {
- beacon_updated = true;
- update_beacon23a(padapter, 0xFF, NULL, true);
- }
- }
-
- if (psta->nonerp_set) {
- psta->nonerp_set = 0;
- pmlmepriv->num_sta_non_erp--;
- if (pmlmepriv->num_sta_non_erp == 0) {
- beacon_updated = true;
- update_beacon23a(padapter, WLAN_EID_ERP_INFO,
- NULL, true);
- }
- }
-
- if (psta->no_short_slot_time_set) {
- psta->no_short_slot_time_set = 0;
- pmlmepriv->num_sta_no_short_slot_time--;
- if (pmlmeext->cur_wireless_mode > WIRELESS_11B
- && pmlmepriv->num_sta_no_short_slot_time == 0) {
- beacon_updated = true;
- update_beacon23a(padapter, 0xFF, NULL, true);
- }
- }
-
- if (psta->no_ht_gf_set) {
- psta->no_ht_gf_set = 0;
- pmlmepriv->num_sta_ht_no_gf--;
- }
-
- if (psta->no_ht_set) {
- psta->no_ht_set = 0;
- pmlmepriv->num_sta_no_ht--;
- }
-
- if (psta->ht_20mhz_set) {
- psta->ht_20mhz_set = 0;
- pmlmepriv->num_sta_ht_20mhz--;
- }
-
- if (rtw_ht_operation_update(padapter) > 0) {
- update_beacon23a(padapter, WLAN_EID_HT_CAPABILITY, NULL, false);
- update_beacon23a(padapter, WLAN_EID_HT_OPERATION, NULL, true);
- }
-
- /* update associated stations cap. */
-
- DBG_8723A("%s, updated =%d\n", __func__, beacon_updated);
-
- return beacon_updated;
-}
-
-u8 ap_free_sta23a(struct rtw_adapter *padapter, struct sta_info *psta, bool active, u16 reason)
-{
- struct sta_priv *pstapriv = &padapter->stapriv;
- u8 beacon_updated = false;
-
- if (!psta)
- return beacon_updated;
-
- if (active) {
- /* tear down Rx AMPDU */
- send_delba23a(padapter, 0, psta->hwaddr); /* recipient */
-
- /* tear down TX AMPDU */
- send_delba23a(padapter, 1, psta->hwaddr); /* originator */
-
- issue_deauth23a(padapter, psta->hwaddr, reason);
- }
-
- psta->htpriv.agg_enable_bitmap = 0x0; /* reset */
- psta->htpriv.candidate_tid_bitmap = 0x0; /* reset */
-
- /* report_del_sta_event23a(padapter, psta->hwaddr, reason); */
-
- /* clear cam entry / key */
- /* clear_cam_entry23a(padapter, (psta->mac_id + 3)); */
- rtw_clearstakey_cmd23a(padapter, (u8 *)psta, (u8)(psta->mac_id + 3),
- true);
-
- spin_lock_bh(&psta->lock);
- psta->state &= ~_FW_LINKED;
- spin_unlock_bh(&psta->lock);
-
- rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
-
- report_del_sta_event23a(padapter, psta->hwaddr, reason);
-
- beacon_updated = bss_cap_update_on_sta_leave23a(padapter, psta);
-
- spin_lock_bh(&pstapriv->sta_hash_lock);
- rtw_free_stainfo23a(padapter, psta);
- spin_unlock_bh(&pstapriv->sta_hash_lock);
-
- return beacon_updated;
-}
-
-int rtw_sta_flush23a(struct rtw_adapter *padapter)
-{
- struct list_head *phead;
- struct sta_info *psta, *ptmp;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- u8 chk_alive_num = 0;
- struct sta_info *chk_alive_list[NUM_STA];
- int i;
-
- DBG_8723A("%s(%s)\n", __func__, padapter->pnetdev->name);
-
- if ((pmlmeinfo->state&0x03) != MSR_AP)
- return 0;
-
- spin_lock_bh(&pstapriv->asoc_list_lock);
- phead = &pstapriv->asoc_list;
- list_for_each_entry_safe(psta, ptmp, phead, asoc_list) {
- /* Remove sta from asoc_list */
- list_del_init(&psta->asoc_list);
- pstapriv->asoc_list_cnt--;
-
- /* Keep sta for ap_free_sta23a() beyond this asoc_list loop */
- chk_alive_list[chk_alive_num++] = psta;
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
-
- /* For each sta in chk_alive_list, call ap_free_sta23a */
- for (i = 0; i < chk_alive_num; i++)
- ap_free_sta23a(padapter, chk_alive_list[i], true,
- WLAN_REASON_DEAUTH_LEAVING);
-
- issue_deauth23a(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
-
- associated_clients_update23a(padapter, true);
-
- return 0;
-}
-
-/* called > TSR LEVEL for USB or SDIO Interface */
-void sta_info_update23a(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- int flags = psta->flags;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- /* update wmm cap. */
- if (WLAN_STA_WME&flags)
- psta->qos_option = 1;
- else
- psta->qos_option = 0;
-
- if (pmlmepriv->qos_option == 0)
- psta->qos_option = 0;
-
- /* update 802.11n ht cap. */
- if (WLAN_STA_HT&flags) {
- psta->htpriv.ht_option = true;
- psta->qos_option = 1;
- } else {
- psta->htpriv.ht_option = false;
- }
-
- if (!pmlmepriv->htpriv.ht_option)
- psta->htpriv.ht_option = false;
-
- update_sta_info23a_apmode23a(padapter, psta);
-}
-
-/* called >= TSR LEVEL for USB or SDIO Interface */
-void ap_sta_info_defer_update23a(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- if (psta->state & _FW_LINKED) {
- /* add ratid */
- add_RATid23a(padapter, psta, 0);/* DM_RATR_STA_INIT */
- }
-}
-
-/* restore hw setting from sw data structures */
-void rtw_ap_restore_network(struct rtw_adapter *padapter)
-{
- struct mlme_priv *mlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sta_info *psta, *ptmp;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct list_head *phead;
- u8 chk_alive_num = 0;
- struct sta_info *chk_alive_list[NUM_STA];
- int i;
-
- rtw_setopmode_cmd23a(padapter, NL80211_IFTYPE_AP);
-
- set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
- start_bss_network(padapter, (u8 *)&mlmepriv->cur_network.network);
-
- if (padapter->securitypriv.dot11PrivacyAlgrthm ==
- WLAN_CIPHER_SUITE_TKIP ||
- padapter->securitypriv.dot11PrivacyAlgrthm ==
- WLAN_CIPHER_SUITE_CCMP) {
- /* restore group key, WEP keys is restored in ips_leave23a() */
- rtw_set_key23a(padapter, psecuritypriv,
- psecuritypriv->dot118021XGrpKeyid, 0);
- }
-
- /* per sta pairwise key and settings */
- if (padapter->securitypriv.dot11PrivacyAlgrthm !=
- WLAN_CIPHER_SUITE_TKIP &&
- padapter->securitypriv.dot11PrivacyAlgrthm !=
- WLAN_CIPHER_SUITE_CCMP) {
- return;
- }
-
- spin_lock_bh(&pstapriv->asoc_list_lock);
- phead = &pstapriv->asoc_list;
- list_for_each_entry_safe(psta, ptmp, phead, asoc_list)
- chk_alive_list[chk_alive_num++] = psta;
- spin_unlock_bh(&pstapriv->asoc_list_lock);
-
- for (i = 0; i < chk_alive_num; i++) {
- psta = chk_alive_list[i];
-
- if (psta->state & _FW_LINKED) {
- Update_RA_Entry23a(padapter, psta);
- /* pairwise key */
- rtw_setstakey_cmd23a(padapter, (unsigned char *)psta, true);
- }
- }
-}
-
-void start_ap_mode23a(struct rtw_adapter *padapter)
-{
- int i;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
-
- pmlmepriv->update_bcn = false;
-
- /* init_mlme_ap_info23a(padapter); */
- pmlmeext->bstart_bss = false;
-
- pmlmepriv->num_sta_non_erp = 0;
-
- pmlmepriv->num_sta_no_short_slot_time = 0;
-
- pmlmepriv->num_sta_no_short_preamble = 0;
-
- pmlmepriv->num_sta_ht_no_gf = 0;
- pmlmepriv->num_sta_no_ht = 0;
- pmlmepriv->num_sta_ht_20mhz = 0;
-
- pmlmepriv->olbc = false;
-
- pmlmepriv->olbc_ht = false;
-
- pmlmepriv->ht_op_mode = 0;
-
- for (i = 0; i < NUM_STA; i++)
- pstapriv->sta_aid[i] = NULL;
-
- /* for ACL */
- INIT_LIST_HEAD(&pacl_list->acl_node_q.queue);
- pacl_list->num = 0;
- pacl_list->mode = 0;
- for (i = 0; i < NUM_ACL; i++) {
- INIT_LIST_HEAD(&pacl_list->aclnode[i].list);
- pacl_list->aclnode[i].valid = false;
- }
-}
-
-void stop_ap_mode23a(struct rtw_adapter *padapter)
-{
- struct list_head *phead;
- struct rtw_wlan_acl_node *paclnode, *ptmp;
- struct sta_info *psta = NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
- struct rtw_queue *pacl_node_q = &pacl_list->acl_node_q;
-
- pmlmepriv->update_bcn = false;
- pmlmeext->bstart_bss = false;
-
- /*
- * reset and init security priv , this can
- * refine with rtw_reset_securitypriv23a
- */
- memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv));
- padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
- padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
-
- /* for ACL */
- spin_lock_bh(&pacl_node_q->lock);
- phead = get_list_head(pacl_node_q);
- list_for_each_entry_safe(paclnode, ptmp, phead, list) {
- if (paclnode->valid == true) {
- paclnode->valid = false;
- list_del_init(&paclnode->list);
- pacl_list->num--;
- }
- }
- spin_unlock_bh(&pacl_node_q->lock);
-
- DBG_8723A("%s, free acl_node_queue, num =%d\n",
- __func__, pacl_list->num);
-
- rtw_sta_flush23a(padapter);
-
- /* free_assoc_sta_resources */
- rtw_free_all_stainfo23a(padapter);
-
- psta = rtw_get_bcmc_stainfo23a(padapter);
- spin_lock_bh(&pstapriv->sta_hash_lock);
- rtw_free_stainfo23a(padapter, psta);
- spin_unlock_bh(&pstapriv->sta_hash_lock);
-
- rtw_init_bcmc_stainfo23a(padapter);
-
- rtw23a_free_mlme_priv_ie_data(pmlmepriv);
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_cmd.c b/drivers/staging/rtl8723au/core/rtw_cmd.c
deleted file mode 100644
index cd4e0f05d82f..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_cmd.c
+++ /dev/null
@@ -1,1470 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTW_CMD_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <recv_osdep.h>
-#include <mlme_osdep.h>
-#include <rtl8723a_cmd.h>
-#include <rtw_sreset.h>
-
-static struct cmd_hdl wlancmds[] = {
- GEN_DRV_CMD_HANDLER(0, NULL) /*0*/
- GEN_DRV_CMD_HANDLER(0, NULL)
- GEN_DRV_CMD_HANDLER(0, NULL)
- GEN_DRV_CMD_HANDLER(0, NULL)
- GEN_DRV_CMD_HANDLER(0, NULL)
- GEN_DRV_CMD_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL) /*10*/
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), join_cmd_hdl23a) /*14*/
- GEN_MLME_EXT_HANDLER(sizeof(struct disconnect_parm), disconnect_hdl23a)
- GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), createbss_hdl23a)
- GEN_MLME_EXT_HANDLER(sizeof(struct setopmode_parm), setopmode_hdl23a)
- GEN_MLME_EXT_HANDLER(sizeof(struct sitesurvey_parm), sitesurvey_cmd_hdl23a) /*18*/
- GEN_MLME_EXT_HANDLER(sizeof(struct setauth_parm), setauth_hdl23a)
- GEN_MLME_EXT_HANDLER(sizeof(struct setkey_parm), setkey_hdl23a) /*20*/
- GEN_MLME_EXT_HANDLER(sizeof(struct set_stakey_parm), set_stakey_hdl23a)
- GEN_MLME_EXT_HANDLER(sizeof(struct set_assocsta_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct del_assocsta_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct setstapwrstate_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct setbasicrate_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct getbasicrate_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct setdatarate_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct getdatarate_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct setphyinfo_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct getphyinfo_parm), NULL) /*30*/
- GEN_MLME_EXT_HANDLER(sizeof(struct setphy_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct getphy_parm), NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL) /*40*/
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl23a)
- GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl23a) /* 46 */
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL) /*50*/
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct Tx_Beacon_param), tx_beacon_hdl23a) /*55*/
-
- GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl23a) /*56*/
- GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl23a) /*57*/
-
- GEN_MLME_EXT_HANDLER(0, h2c_msg_hdl23a) /*58*/
- GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), set_chplan_hdl23a) /*59*/
- GEN_MLME_EXT_HANDLER(sizeof(struct LedBlink_param), led_blink_hdl23a) /*60*/
-
- GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelSwitch_param), set_csa_hdl23a) /*61*/
- GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param), tdls_hdl23a) /*62*/
-};
-
-struct _cmd_callback rtw_cmd_callback[] = {
- {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/
- {GEN_CMD_CODE(_Write_MACREG), NULL},
- {GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback23a},
- {GEN_CMD_CODE(_Write_BBREG), NULL},
- {GEN_CMD_CODE(_Read_RFREG), &rtw_getbbrfreg_cmdrsp_callback23a},
- {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/
- {GEN_CMD_CODE(_Read_EEPROM), NULL},
- {GEN_CMD_CODE(_Write_EEPROM), NULL},
- {GEN_CMD_CODE(_Read_EFUSE), NULL},
- {GEN_CMD_CODE(_Write_EFUSE), NULL},
-
- {GEN_CMD_CODE(_Read_CAM), NULL}, /*10*/
- {GEN_CMD_CODE(_Write_CAM), NULL},
- {GEN_CMD_CODE(_setBCNITV), NULL},
- {GEN_CMD_CODE(_setMBIDCFG), NULL},
- {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd23a_callback}, /*14*/
- {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd23a_callback}, /*15*/
- {GEN_CMD_CODE(_CreateBss), &rtw_createbss_cmd23a_callback},
- {GEN_CMD_CODE(_SetOpMode), NULL},
- {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback23a}, /*18*/
- {GEN_CMD_CODE(_SetAuth), NULL},
-
- {GEN_CMD_CODE(_SetKey), NULL}, /*20*/
- {GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback23a},
- {GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback23a},
- {GEN_CMD_CODE(_DelAssocSta), NULL},
- {GEN_CMD_CODE(_SetStaPwrState), NULL},
- {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/
- {GEN_CMD_CODE(_GetBasicRate), NULL},
- {GEN_CMD_CODE(_SetDataRate), NULL},
- {GEN_CMD_CODE(_GetDataRate), NULL},
- {GEN_CMD_CODE(_SetPhyInfo), NULL},
-
- {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/
- {GEN_CMD_CODE(_SetPhy), NULL},
- {GEN_CMD_CODE(_GetPhy), NULL},
- {GEN_CMD_CODE(_readRssi), NULL},
- {GEN_CMD_CODE(_readGain), NULL},
- {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/
- {GEN_CMD_CODE(_SetPwrMode), NULL},
- {GEN_CMD_CODE(_JoinbssRpt), NULL},
- {GEN_CMD_CODE(_SetRaTable), NULL},
- {GEN_CMD_CODE(_GetRaTable), NULL},
-
- {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/
- {GEN_CMD_CODE(_GetDTMReport), NULL},
- {GEN_CMD_CODE(_GetTXRateStatistics), NULL},
- {GEN_CMD_CODE(_SetUsbSuspend), NULL},
- {GEN_CMD_CODE(_SetH2cLbk), NULL},
- {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/
- {GEN_CMD_CODE(_SetChannel), NULL}, /*46*/
- {GEN_CMD_CODE(_SetTxPower), NULL},
- {GEN_CMD_CODE(_SwitchAntenna), NULL},
- {GEN_CMD_CODE(_SetCrystalCap), NULL},
- {GEN_CMD_CODE(_SetSingleCarrierTx), NULL}, /*50*/
-
- {GEN_CMD_CODE(_SetSingleToneTx), NULL}, /*51*/
- {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL},
- {GEN_CMD_CODE(_SetContinuousTx), NULL},
- {GEN_CMD_CODE(_SwitchBandwidth), NULL}, /*54*/
- {GEN_CMD_CODE(_TX_Beacon), NULL},/*55*/
-
- {GEN_CMD_CODE(_Set_MLME_EVT), NULL},/*56*/
- {GEN_CMD_CODE(_Set_Drv_Extra), NULL},/*57*/
- {GEN_CMD_CODE(_Set_H2C_MSG), NULL},/*58*/
- {GEN_CMD_CODE(_SetChannelPlan), NULL},/*59*/
- {GEN_CMD_CODE(_LedBlink), NULL},/*60*/
-
- {GEN_CMD_CODE(_SetChannelSwitch), NULL},/*61*/
- {GEN_CMD_CODE(_TDLS), NULL},/*62*/
-};
-
-/*
-Caller and the rtw_cmd_thread23a can protect cmd_q by spin_lock.
-No irqsave is necessary.
-*/
-
-int rtw_init_cmd_priv23a(struct cmd_priv *pcmdpriv)
-{
- int res = _SUCCESS;
-
- pcmdpriv->cmd_issued_cnt = 0;
- pcmdpriv->cmd_done_cnt = 0;
- pcmdpriv->rsp_cnt = 0;
-
- pcmdpriv->wq = alloc_workqueue("rtl8723au_cmd", 0, 1);
- if (!pcmdpriv->wq)
- res = _FAIL;
-
- return res;
-}
-
-/* forward definition */
-
-static void rtw_irq_work(struct work_struct *work);
-
-u32 rtw_init_evt_priv23a(struct evt_priv *pevtpriv)
-{
- pevtpriv->wq = alloc_workqueue("rtl8723au_evt", 0, 1);
-
- INIT_WORK(&pevtpriv->irq_wk, rtw_irq_work);
-
- return _SUCCESS;
-}
-
-void rtw_free_evt_priv23a(struct evt_priv *pevtpriv)
-{
- cancel_work_sync(&pevtpriv->irq_wk);
-}
-
-static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
-{
- /* set to true to allow enqueuing cmd when hw_init_completed is false */
- u8 bAllow = false;
-
- if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan))
- bAllow = true;
-
- if (pcmdpriv->padapter->hw_init_completed == false && bAllow == false)
- return _FAIL;
- return _SUCCESS;
-}
-
-static void rtw_cmd_work(struct work_struct *work);
-
-int rtw_enqueue_cmd23a(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
-{
- int res = _FAIL;
-
- if (!cmd_obj)
- goto exit;
-
- cmd_obj->padapter = pcmdpriv->padapter;
-
- res = rtw_cmd_filter(pcmdpriv, cmd_obj);
- if (res == _FAIL) {
- rtw_free_cmd_obj23a(cmd_obj);
- goto exit;
- }
-
- INIT_WORK(&cmd_obj->work, rtw_cmd_work);
-
- res = queue_work(pcmdpriv->wq, &cmd_obj->work);
-
- if (!res) {
- netdev_err(pcmdpriv->padapter->pnetdev,
- "%s: Call to queue_work() failed\n", __func__);
- res = _FAIL;
- } else
- res = _SUCCESS;
-exit:
-
- return res;
-}
-
-void rtw_free_cmd_obj23a(struct cmd_obj *pcmd)
-{
-
- if (pcmd->cmdcode != _JoinBss_CMD_ &&
- pcmd->cmdcode != _CreateBss_CMD_) {
- /* free parmbuf in cmd_obj */
- kfree(pcmd->parmbuf);
- }
-
- if (pcmd->rsp) {
- if (pcmd->rspsz != 0) {
- /* free rsp in cmd_obj */
- kfree(pcmd->rsp);
- }
- }
-
- kfree(pcmd);
-}
-
-static void rtw_cmd_work(struct work_struct *work)
-{
- int (*cmd_hdl)(struct rtw_adapter *padapter, const u8 *pbuf);
- void (*pcmd_callback)(struct rtw_adapter *dev, struct cmd_obj *pcmd);
- struct cmd_priv *pcmdpriv;
- struct cmd_obj *pcmd = container_of(work, struct cmd_obj, work);
-
- pcmdpriv = &pcmd->padapter->cmdpriv;
-
- if (rtw_cmd_filter(pcmdpriv, pcmd) == _FAIL) {
- pcmd->res = H2C_DROPPED;
- goto post_process;
- }
-
- pcmdpriv->cmd_issued_cnt++;
-
- pcmd->cmdsz = ALIGN(pcmd->cmdsz, 4);
-
- if (pcmd->cmdcode < (sizeof(wlancmds)/sizeof(struct cmd_hdl))) {
- cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;
-
- if (cmd_hdl)
- pcmd->res = cmd_hdl(pcmd->padapter, pcmd->parmbuf);
- else
- pcmd->res = H2C_DROPPED;
- } else
- pcmd->res = H2C_PARAMETERS_ERROR;
-
-post_process:
- /* call callback function for post-processed */
- if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) {
- pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback;
- if (!pcmd_callback) {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
- "mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n",
- pcmd_callback, pcmd->cmdcode);
- rtw_free_cmd_obj23a(pcmd);
- } else {
- /* need consider that free cmd_obj in
- rtw_cmd_callback */
- pcmd_callback(pcmd->padapter, pcmd);
- }
- } else {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
- "%s: cmdcode = 0x%x callback not defined!\n",
- __func__, pcmd->cmdcode);
- rtw_free_cmd_obj23a(pcmd);
- }
-}
-
-
-int rtw_sitesurvey_cmd23a(struct rtw_adapter *padapter,
- struct cfg80211_ssid *ssid, int ssid_num,
- struct rtw_ieee80211_channel *ch, int ch_num)
-{
- int res = _FAIL;
- struct cmd_obj *ph2c;
- struct sitesurvey_parm *psurveyPara;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- if (check_fwstate(pmlmepriv, _FW_LINKED))
- rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_SCAN, 1);
-
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!ph2c)
- return _FAIL;
-
- psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
- if (!psurveyPara) {
- kfree(ph2c);
- return _FAIL;
- }
-
- rtw_free_network_queue23a(padapter);
-
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
- "%s: flush network queue\n", __func__);
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara,
- GEN_CMD_CODE(_SiteSurvey));
-
- /* psurveyPara->bsslimit = 48; */
- psurveyPara->scan_mode = pmlmepriv->scan_mode;
-
- /* prepare ssid list */
- if (ssid) {
- int i;
-
- for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) {
- if (ssid[i].ssid_len) {
- memcpy(&psurveyPara->ssid[i], &ssid[i],
- sizeof(struct cfg80211_ssid));
- psurveyPara->ssid_num++;
- }
- }
- }
-
- /* prepare channel list */
- if (ch) {
- int i;
-
- for (i = 0; i < ch_num && i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
- if (ch[i].hw_value &&
- !(ch[i].flags & IEEE80211_CHAN_DISABLED)) {
- memcpy(&psurveyPara->ch[i], &ch[i],
- sizeof(struct rtw_ieee80211_channel));
- psurveyPara->ch_num++;
- }
- }
- }
-
- set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
-
- res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
-
- if (res == _SUCCESS) {
- mod_timer(&pmlmepriv->scan_to_timer, jiffies +
- msecs_to_jiffies(SCANNING_TIMEOUT));
-
- pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */
- } else
- _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
-
- return res;
-}
-
-void rtw_getbbrfreg_cmdrsp_callback23a(struct rtw_adapter *padapter,
- struct cmd_obj *pcmd)
-{
- kfree(pcmd->parmbuf);
- kfree(pcmd);
-}
-
-int rtw_createbss_cmd23a(struct rtw_adapter *padapter)
-{
- struct cmd_obj *pcmd;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_bssid_ex *pdev_network;
- u8 res = _SUCCESS;
-
- pdev_network = &padapter->registrypriv.dev_network;
-
- if (pmlmepriv->assoc_ssid.ssid_len == 0) {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
- "createbss for Any SSid:%s\n",
- pmlmepriv->assoc_ssid.ssid);
- } else {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
- "createbss for SSid:%s\n",
- pmlmepriv->assoc_ssid.ssid);
- }
-
- pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!pcmd) {
- res = _FAIL;
- goto exit;
- }
-
- pcmd->cmdcode = _CreateBss_CMD_;
- pcmd->parmbuf = (unsigned char *)pdev_network;
- pcmd->cmdsz = get_wlan_bssid_ex_sz(pdev_network);
- pcmd->rsp = NULL;
- pcmd->rspsz = 0;
-
- pdev_network->Length = pcmd->cmdsz;
-
- res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
-
-exit:
-
- return res;
-}
-
-int rtw_joinbss_cmd23a(struct rtw_adapter *padapter,
- struct wlan_network *pnetwork)
-{
- int res = _SUCCESS;
- struct wlan_bssid_ex *psecnetwork;
- struct cmd_obj *pcmd;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct registry_priv *pregistrypriv = &padapter->registrypriv;
- struct ht_priv *phtpriv = &pmlmepriv->htpriv;
- enum nl80211_iftype ifmode;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- ifmode = pnetwork->network.ifmode;
-
- if (pmlmepriv->assoc_ssid.ssid_len == 0) {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_,
- "+Join cmd: Any SSid\n");
- } else {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_,
- "+Join cmd: SSid =[%s]\n",
- pmlmepriv->assoc_ssid.ssid);
- }
-
- pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!pcmd) {
- res = _FAIL;
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
- "rtw_joinbss_cmd23a: memory allocate for cmd_obj fail!!!\n");
- goto exit;
- }
-
- /* for hidden ap to set fw_state here */
- if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE)) {
- switch (ifmode) {
- case NL80211_IFTYPE_ADHOC:
- set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
- break;
- case NL80211_IFTYPE_P2P_CLIENT:
- case NL80211_IFTYPE_STATION:
- set_fwstate(pmlmepriv, WIFI_STATION_STATE);
- break;
- default:
- break;
- }
- }
-
- psecnetwork = &psecuritypriv->sec_bss;
- if (!psecnetwork) {
- kfree(pcmd);
- res = _FAIL;
-
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
- "rtw_joinbss_cmd23a :psecnetwork == NULL!!!\n");
-
- goto exit;
- }
-
- memset(psecnetwork, 0, sizeof(struct wlan_bssid_ex));
-
- memcpy(psecnetwork, &pnetwork->network,
- get_wlan_bssid_ex_sz(&pnetwork->network));
-
- psecnetwork->IELength = 0;
- /* Added by Albert 2009/02/18 */
- /* If the the driver wants to use the bssid to create the
- * connection. If not, we have to copy the connecting AP's
- * MAC address to it so that the driver just has the bssid
- * information for PMKIDList searching. */
-
- if (pmlmepriv->assoc_by_bssid == false)
- ether_addr_copy(&pmlmepriv->assoc_bssid[0],
- &pnetwork->network.MacAddress[0]);
-
- psecnetwork->IELength =
- rtw_restruct_sec_ie23a(padapter, &pnetwork->network.IEs[0],
- &psecnetwork->IEs[0],
- pnetwork->network.IELength);
-
- pmlmepriv->qos_option = 0;
-
- if (pregistrypriv->wmm_enable) {
- u32 tmp_len;
-
- tmp_len = rtw_restruct_wmm_ie23a(padapter,
- &pnetwork->network.IEs[0],
- &psecnetwork->IEs[0],
- pnetwork->network.IELength,
- psecnetwork->IELength);
-
- if (psecnetwork->IELength != tmp_len) {
- psecnetwork->IELength = tmp_len;
- /* There is WMM IE in this corresp. beacon */
- pmlmepriv->qos_option = 1;
- } else {
- /* There is no WMM IE in this corresp. beacon */
- pmlmepriv->qos_option = 0;
- }
- }
-
- phtpriv->ht_option = false;
- if (pregistrypriv->ht_enable) {
- u32 algo = padapter->securitypriv.dot11PrivacyAlgrthm;
- /* Added by Albert 2010/06/23 */
- /* For the WEP mode, we will use the bg mode to do
- the connection to avoid some IOT issue. */
- /* Especially for Realtek 8192u SoftAP. */
- if (algo != WLAN_CIPHER_SUITE_WEP40 &&
- algo != WLAN_CIPHER_SUITE_WEP104 &&
- algo != WLAN_CIPHER_SUITE_TKIP) {
- /* rtw_restructure_ht_ie23a */
- rtw_restructure_ht_ie23a(padapter,
- &pnetwork->network.IEs[0],
- &psecnetwork->IEs[0],
- pnetwork->network.IELength,
- &psecnetwork->IELength);
- }
- }
-
- pmlmeinfo->assoc_AP_vendor =
- check_assoc_AP23a(pnetwork->network.IEs,
- pnetwork->network.IELength);
-
- if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_TENDA)
- padapter->pwrctrlpriv.smart_ps = 0;
- else
- padapter->pwrctrlpriv.smart_ps =
- padapter->registrypriv.smart_ps;
-
- DBG_8723A("%s: smart_ps =%d\n", __func__,
- padapter->pwrctrlpriv.smart_ps);
-
- /* get cmdsz before endian conversion */
- pcmd->cmdsz = get_wlan_bssid_ex_sz(psecnetwork);
-
- pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */
- pcmd->parmbuf = (unsigned char *)psecnetwork;
- pcmd->rsp = NULL;
- pcmd->rspsz = 0;
-
- res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
-exit:
-
- return res;
-}
-
-int rtw_disassoc_cmd23a(struct rtw_adapter *padapter, u32 deauth_timeout_ms,
- bool enqueue)
-{
- struct cmd_obj *cmdobj = NULL;
- struct disconnect_parm *param = NULL;
- struct cmd_priv *cmdpriv = &padapter->cmdpriv;
- int res = _SUCCESS;
-
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_,
- "+rtw_disassoc_cmd23a\n");
-
- /* prepare cmd parameter */
- param = kzalloc(sizeof(*param), GFP_ATOMIC);
- if (param == NULL) {
- res = _FAIL;
- goto exit;
- }
- param->deauth_timeout_ms = deauth_timeout_ms;
-
- if (enqueue) {
- /* need enqueue, prepare cmd_obj and enqueue */
- cmdobj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!cmdobj) {
- res = _FAIL;
- kfree(param);
- goto exit;
- }
- init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_);
- res = rtw_enqueue_cmd23a(cmdpriv, cmdobj);
- } else {
- /* no need to enqueue, do the cmd hdl directly and
- free cmd parameter */
- if (disconnect_hdl23a(padapter, (u8 *)param) != H2C_SUCCESS)
- res = _FAIL;
- kfree(param);
- }
-
-exit:
- return res;
-}
-
-int rtw_setopmode_cmd23a(struct rtw_adapter *padapter,
- enum nl80211_iftype ifmode)
-{
- struct cmd_obj *ph2c;
- struct setopmode_parm *psetop;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- int res = _SUCCESS;
-
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
- if (!ph2c) {
- res = false;
- goto exit;
- }
- psetop = kzalloc(sizeof(struct setopmode_parm), GFP_KERNEL);
-
- if (!psetop) {
- kfree(ph2c);
- res = false;
- goto exit;
- }
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_);
- psetop->mode = ifmode;
-
- res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
-exit:
- return res;
-}
-
-int rtw_setstakey_cmd23a(struct rtw_adapter *padapter, u8 *psta, u8 unicast_key)
-{
- struct cmd_obj *ph2c;
- struct set_stakey_parm *psetstakey_para;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- struct set_stakey_rsp *psetstakey_rsp = NULL;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct sta_info *sta = (struct sta_info *)psta;
- int res = _SUCCESS;
-
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
- if (!ph2c) {
- res = _FAIL;
- goto exit;
- }
-
- psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
- if (!psetstakey_para) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_KERNEL);
- if (!psetstakey_rsp) {
- kfree(ph2c);
- kfree(psetstakey_para);
- res = _FAIL;
- goto exit;
- }
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
- ph2c->rsp = (u8 *) psetstakey_rsp;
- ph2c->rspsz = sizeof(struct set_stakey_rsp);
-
- ether_addr_copy(psetstakey_para->addr, sta->hwaddr);
-
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
- psetstakey_para->algorithm =
- (unsigned char)psecuritypriv->dot11PrivacyAlgrthm;
- } else {
- GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm,
- false);
- }
-
- if (unicast_key == true) {
- memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16);
- } else {
- int idx = psecuritypriv->dot118021XGrpKeyid;
-
- memcpy(&psetstakey_para->key,
- &psecuritypriv->dot118021XGrpKey[idx].skey, 16);
- }
-
- /* jeff: set this because at least sw key is ready */
- padapter->securitypriv.busetkipkey = 1;
-
- res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
-
-exit:
-
- return res;
-}
-
-int rtw_clearstakey_cmd23a(struct rtw_adapter *padapter, u8 *psta, u8 entry,
- u8 enqueue)
-{
- struct cmd_obj *ph2c;
- struct set_stakey_parm *psetstakey_para;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- struct set_stakey_rsp *psetstakey_rsp = NULL;
- struct sta_info *sta = (struct sta_info *)psta;
- int res = _SUCCESS;
-
- if (!enqueue) {
- clear_cam_entry23a(padapter, entry);
- } else {
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
- if (!ph2c) {
- res = _FAIL;
- goto exit;
- }
-
- psetstakey_para = kzalloc(sizeof(struct set_stakey_parm),
- GFP_KERNEL);
- if (!psetstakey_para) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp),
- GFP_KERNEL);
- if (!psetstakey_rsp) {
- kfree(ph2c);
- kfree(psetstakey_para);
- res = _FAIL;
- goto exit;
- }
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para,
- _SetStaKey_CMD_);
- ph2c->rsp = (u8 *) psetstakey_rsp;
- ph2c->rspsz = sizeof(struct set_stakey_rsp);
-
- ether_addr_copy(psetstakey_para->addr, sta->hwaddr);
-
- psetstakey_para->algorithm = 0;
-
- psetstakey_para->id = entry;
-
- res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
- }
-exit:
- return res;
-}
-
-int rtw_addbareq_cmd23a(struct rtw_adapter *padapter, u8 tid, u8 *addr)
-{
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- struct cmd_obj *ph2c;
- struct addBaReq_parm *paddbareq_parm;
- int res = _SUCCESS;
-
- if (tid >= MAXTID) {
- res = _FAIL;
- goto exit;
- }
-
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!ph2c) {
- res = _FAIL;
- goto exit;
- }
-
- paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_ATOMIC);
- if (!paddbareq_parm) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- paddbareq_parm->tid = tid;
- ether_addr_copy(paddbareq_parm->addr, addr);
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm,
- GEN_CMD_CODE(_AddBAReq));
-
- res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
-exit:
- return res;
-}
-
-int rtw_dynamic_chk_wk_cmd23a(struct rtw_adapter *padapter)
-{
- struct cmd_obj *ph2c;
- struct drvextra_cmd_parm *pdrvextra_cmd_parm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- int res = _SUCCESS;
-
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!ph2c) {
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_ATOMIC);
- if (!pdrvextra_cmd_parm) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID;
- pdrvextra_cmd_parm->type_size = 0;
- pdrvextra_cmd_parm->pbuf = (u8 *)padapter;
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm,
- GEN_CMD_CODE(_Set_Drv_Extra));
-
- res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
-exit:
-
- return res;
-}
-
-static void traffic_status_watchdog(struct rtw_adapter *padapter)
-{
- u8 bEnterPS;
- u8 bBusyTraffic = false, bTxBusyTraffic = false, bRxBusyTraffic = false;
- u8 bHigherBusyTraffic = false, bHigherBusyRxTraffic = false;
- u8 bHigherBusyTxTraffic = false;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- int BusyThreshold = 100;
- struct rt_link_detect *ldi = &pmlmepriv->LinkDetectInfo;
-
- /* */
- /* Determine if our traffic is busy now */
- /* */
- if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- if (rtl8723a_BT_coexist(padapter))
- BusyThreshold = 50;
- else if (ldi->bBusyTraffic)
- BusyThreshold = 75;
- /* if we raise bBusyTraffic in last watchdog, using
- lower threshold. */
- if (ldi->NumRxOkInPeriod > BusyThreshold ||
- ldi->NumTxOkInPeriod > BusyThreshold) {
- bBusyTraffic = true;
-
- if (ldi->NumRxOkInPeriod > ldi->NumTxOkInPeriod)
- bRxBusyTraffic = true;
- else
- bTxBusyTraffic = true;
- }
-
- /* Higher Tx/Rx data. */
- if (ldi->NumRxOkInPeriod > 4000 ||
- ldi->NumTxOkInPeriod > 4000) {
- bHigherBusyTraffic = true;
-
- if (ldi->NumRxOkInPeriod > ldi->NumTxOkInPeriod)
- bHigherBusyRxTraffic = true;
- else
- bHigherBusyTxTraffic = true;
- }
-
- if (!rtl8723a_BT_coexist(padapter) ||
- !rtl8723a_BT_using_antenna_1(padapter)) {
- /* check traffic for powersaving. */
- if (((ldi->NumRxUnicastOkInPeriod +
- ldi->NumTxOkInPeriod) > 8) ||
- ldi->NumRxUnicastOkInPeriod > 2)
- bEnterPS = false;
- else
- bEnterPS = true;
-
- /* LeisurePS only work in infra mode. */
- if (bEnterPS)
- LPS_Enter23a(padapter);
- else
- LPS_Leave23a(padapter);
- }
- } else
- LPS_Leave23a(padapter);
-
- ldi->NumRxOkInPeriod = 0;
- ldi->NumTxOkInPeriod = 0;
- ldi->NumRxUnicastOkInPeriod = 0;
- ldi->bBusyTraffic = bBusyTraffic;
- ldi->bTxBusyTraffic = bTxBusyTraffic;
- ldi->bRxBusyTraffic = bRxBusyTraffic;
- ldi->bHigherBusyTraffic = bHigherBusyTraffic;
- ldi->bHigherBusyRxTraffic = bHigherBusyRxTraffic;
- ldi->bHigherBusyTxTraffic = bHigherBusyTxTraffic;
-}
-
-static void dynamic_chk_wk_hdl(struct rtw_adapter *padapter, u8 *pbuf, int sz)
-{
- struct mlme_priv *pmlmepriv;
-
- padapter = (struct rtw_adapter *)pbuf;
- pmlmepriv = &padapter->mlmepriv;
-
-#ifdef CONFIG_8723AU_AP_MODE
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
- expire_timeout_chk23a(padapter);
-#endif
-
- rtl8723a_sreset_xmit_status_check(padapter);
-
- linked_status_chk23a(padapter);
- traffic_status_watchdog(padapter);
-
- rtl8723a_HalDmWatchDog(padapter);
-
- /* */
- /* BT-Coexist */
- /* */
- rtl8723a_BT_do_coexist(padapter);
-}
-
-static void lps_ctrl_wk_hdl(struct rtw_adapter *padapter, u8 lps_ctrl_type)
-{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- u8 mstatus;
-
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))
- return;
-
- switch (lps_ctrl_type) {
- case LPS_CTRL_SCAN:
- rtl8723a_BT_wifiscan_notify(padapter, true);
- if (!rtl8723a_BT_using_antenna_1(padapter)) {
- if (check_fwstate(pmlmepriv, _FW_LINKED))
- LPS_Leave23a(padapter);
- }
- break;
- case LPS_CTRL_JOINBSS:
- LPS_Leave23a(padapter);
- break;
- case LPS_CTRL_CONNECT:
- mstatus = 1;/* connect */
- /* Reset LPS Setting */
- padapter->pwrctrlpriv.LpsIdleCount = 0;
- rtl8723a_set_FwJoinBssReport_cmd(padapter, 1);
- rtl8723a_BT_mediastatus_notify(padapter, mstatus);
- break;
- case LPS_CTRL_DISCONNECT:
- mstatus = 0;/* disconnect */
- rtl8723a_BT_mediastatus_notify(padapter, mstatus);
- if (!rtl8723a_BT_using_antenna_1(padapter))
- LPS_Leave23a(padapter);
- rtl8723a_set_FwJoinBssReport_cmd(padapter, 0);
- break;
- case LPS_CTRL_SPECIAL_PACKET:
- pwrpriv->DelayLPSLastTimeStamp = jiffies;
- rtl8723a_BT_specialpacket_notify(padapter);
- if (!rtl8723a_BT_using_antenna_1(padapter))
- LPS_Leave23a(padapter);
- break;
- case LPS_CTRL_LEAVE:
- rtl8723a_BT_lps_leave(padapter);
- if (!rtl8723a_BT_using_antenna_1(padapter))
- LPS_Leave23a(padapter);
- break;
-
- default:
- break;
- }
-}
-
-int rtw_lps_ctrl_wk_cmd23a(struct rtw_adapter *padapter,
- u8 lps_ctrl_type, u8 enqueue)
-{
- struct cmd_obj *ph2c;
- struct drvextra_cmd_parm *pdrvextra_cmd_parm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- int res = _SUCCESS;
-
- if (enqueue) {
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!ph2c) {
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm),
- GFP_ATOMIC);
- if (!pdrvextra_cmd_parm) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID;
- pdrvextra_cmd_parm->type_size = lps_ctrl_type;
- pdrvextra_cmd_parm->pbuf = NULL;
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm,
- GEN_CMD_CODE(_Set_Drv_Extra));
-
- res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
- } else
- lps_ctrl_wk_hdl(padapter, lps_ctrl_type);
-exit:
-
- return res;
-}
-
-int rtw_ps_cmd23a(struct rtw_adapter *padapter)
-{
- struct cmd_obj *ppscmd;
- struct drvextra_cmd_parm *pdrvextra_cmd_parm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- int res = _SUCCESS;
-
- ppscmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!ppscmd) {
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm),
- GFP_ATOMIC);
- if (!pdrvextra_cmd_parm) {
- kfree(ppscmd);
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID;
- pdrvextra_cmd_parm->pbuf = NULL;
- init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm,
- GEN_CMD_CODE(_Set_Drv_Extra));
-
- res = rtw_enqueue_cmd23a(pcmdpriv, ppscmd);
-exit:
-
- return res;
-}
-
-#ifdef CONFIG_8723AU_AP_MODE
-
-static void rtw_chk_hi_queue_hdl(struct rtw_adapter *padapter)
-{
- int cnt = 0;
- struct sta_info *psta_bmc;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
- if (!psta_bmc)
- return;
-
- if (psta_bmc->sleepq_len == 0) {
- bool val;
-
- val = rtl8723a_chk_hi_queue_empty(padapter);
-
- while (!val) {
- msleep(100);
-
- cnt++;
-
- if (cnt > 10)
- break;
-
- val = rtl8723a_chk_hi_queue_empty(padapter);
- }
-
- if (cnt <= 10) {
- pstapriv->tim_bitmap &= ~BIT(0);
- pstapriv->sta_dz_bitmap &= ~BIT(0);
-
- update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
- } else /* re check again */
- rtw_chk_hi_queue_cmd23a(padapter);
- }
-}
-
-int rtw_chk_hi_queue_cmd23a(struct rtw_adapter *padapter)
-{
- struct cmd_obj *ph2c;
- struct drvextra_cmd_parm *pdrvextra_cmd_parm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- int res = _SUCCESS;
-
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!ph2c) {
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm),
- GFP_ATOMIC);
- if (!pdrvextra_cmd_parm) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID;
- pdrvextra_cmd_parm->type_size = 0;
- pdrvextra_cmd_parm->pbuf = NULL;
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm,
- GEN_CMD_CODE(_Set_Drv_Extra));
-
- res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
-exit:
-
- return res;
-}
-#endif
-
-int rtw_c2h_wk_cmd23a(struct rtw_adapter *padapter, u8 *c2h_evt)
-{
- struct cmd_obj *ph2c;
- struct drvextra_cmd_parm *pdrvextra_cmd_parm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- int res = _SUCCESS;
-
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!ph2c) {
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm),
- GFP_ATOMIC);
- if (!pdrvextra_cmd_parm) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm->ec_id = C2H_WK_CID;
- pdrvextra_cmd_parm->type_size = c2h_evt?16:0;
- pdrvextra_cmd_parm->pbuf = c2h_evt;
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm,
- GEN_CMD_CODE(_Set_Drv_Extra));
-
- res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
-
-exit:
-
- return res;
-}
-
-static int c2h_evt_hdl(struct rtw_adapter *adapter, struct c2h_evt_hdr *c2h_evt)
-{
- int ret = _FAIL;
- u8 buf[16];
-
- if (!c2h_evt) {
- /* No c2h event in cmd_obj, read c2h event before handling*/
- if (c2h_evt_read23a(adapter, buf) == _SUCCESS) {
- c2h_evt = (struct c2h_evt_hdr *)buf;
-
- ret = c2h_handler_8723a(adapter, c2h_evt);
- }
- } else
- ret = c2h_handler_8723a(adapter, c2h_evt);
-
- return ret;
-}
-
-static void rtw_irq_work(struct work_struct *work)
-{
- struct evt_priv *evtpriv;
- struct rtw_adapter *adapter;
-
- evtpriv = container_of(work, struct evt_priv, irq_wk);
- adapter = container_of(evtpriv, struct rtw_adapter, evtpriv);
-
- c2h_evt_clear23a(adapter);
-}
-
-void rtw_evt_work(struct work_struct *work)
-{
- struct evt_work *ework;
- struct rtw_adapter *adapter;
-
- ework = container_of(work, struct evt_work, work);
- adapter = ework->adapter;
-
- c2h_evt_clear23a(adapter);
-
- if (!c2h_evt_exist(&ework->u.c2h_evt)) {
- kfree(ework);
- return;
- }
-
- if (c2h_id_filter_ccx_8723a(ework->u.c2h_evt.id) == true) {
- /* Handle CCX report here */
- c2h_handler_8723a(adapter, &ework->u.c2h_evt);
- kfree(ework);
- } else {
- /*
- * Enqueue into cmd_thread for others.
- * ework will be turned into a c2h_evt and freed once it
- * has been consumed.
- */
- rtw_c2h_wk_cmd23a(adapter, (u8 *)&ework->u.c2h_evt);
- }
-}
-
-int rtw_drvextra_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- const struct drvextra_cmd_parm *pdrvextra_cmd;
-
- if (!pbuf)
- return H2C_PARAMETERS_ERROR;
-
- pdrvextra_cmd = (struct drvextra_cmd_parm *)pbuf;
-
- switch (pdrvextra_cmd->ec_id) {
- case DYNAMIC_CHK_WK_CID:
- dynamic_chk_wk_hdl(padapter, pdrvextra_cmd->pbuf,
- pdrvextra_cmd->type_size);
- break;
- case POWER_SAVING_CTRL_WK_CID:
- rtw_ps_processor23a(padapter);
- break;
- case LPS_CTRL_WK_CID:
- lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type_size);
- break;
-#ifdef CONFIG_8723AU_AP_MODE
- case CHECK_HIQ_WK_CID:
- rtw_chk_hi_queue_hdl(padapter);
- break;
-#endif /* CONFIG_8723AU_AP_MODE */
- case C2H_WK_CID:
- c2h_evt_hdl(padapter,
- (struct c2h_evt_hdr *)pdrvextra_cmd->pbuf);
- break;
-
- default:
- break;
- }
-
- if (pdrvextra_cmd->pbuf && (pdrvextra_cmd->type_size > 0)) {
- kfree(pdrvextra_cmd->pbuf);
- /*
- * No need to set pdrvextra_cmd->pbuf = NULL as we were
- * operating on a copy of the original pcmd->parmbuf
- * created in rtw_cmd_work().
- */
- }
-
- return H2C_SUCCESS;
-}
-
-void rtw_survey_cmd_callback23a(struct rtw_adapter *padapter,
- struct cmd_obj *pcmd)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- if (pcmd->res == H2C_DROPPED) {
- /* TODO: cancel timer and do timeout handler directly... */
- /* need to make timeout handlerOS independent */
- mod_timer(&pmlmepriv->scan_to_timer,
- jiffies + msecs_to_jiffies(1));
- } else if (pcmd->res != H2C_SUCCESS) {
- mod_timer(&pmlmepriv->scan_to_timer,
- jiffies + msecs_to_jiffies(1));
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
- "********Error: MgntActrtw_set_802_11_bssid23a_LIST_SCAN Fail ************\n");
- }
-
- /* free cmd */
- rtw_free_cmd_obj23a(pcmd);
-}
-
-void rtw_disassoc_cmd23a_callback(struct rtw_adapter *padapter,
- struct cmd_obj *pcmd)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- if (pcmd->res != H2C_SUCCESS) {
- spin_lock_bh(&pmlmepriv->lock);
- set_fwstate(pmlmepriv, _FW_LINKED);
- spin_unlock_bh(&pmlmepriv->lock);
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
- "***Error: disconnect_cmd_callback Fail ***\n");
- return;
- }
-
- /* free cmd */
- rtw_free_cmd_obj23a(pcmd);
-}
-
-void rtw_joinbss_cmd23a_callback(struct rtw_adapter *padapter,
- struct cmd_obj *pcmd)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- if (pcmd->res == H2C_DROPPED) {
- /* TODO: cancel timer and do timeout handler directly... */
- /* need to make timeout handlerOS independent */
- mod_timer(&pmlmepriv->assoc_timer,
- jiffies + msecs_to_jiffies(1));
- } else if (pcmd->res != H2C_SUCCESS) {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
- "********Error:rtw_select_and_join_from_scanned_queue Wait Sema Fail ************\n");
- mod_timer(&pmlmepriv->assoc_timer,
- jiffies + msecs_to_jiffies(1));
- }
-
- rtw_free_cmd_obj23a(pcmd);
-}
-
-void rtw_createbss_cmd23a_callback(struct rtw_adapter *padapter,
- struct cmd_obj *pcmd)
-{
- struct sta_info *psta;
- struct wlan_network *pwlan;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf;
- struct wlan_network *tgt_network = &pmlmepriv->cur_network;
- struct rtw_queue *scanned_queue = &pmlmepriv->scanned_queue;
-
- if (pcmd->res != H2C_SUCCESS) {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
- "********Error: rtw_createbss_cmd23a_callback Fail ************\n");
- mod_timer(&pmlmepriv->assoc_timer,
- jiffies + msecs_to_jiffies(1));
- }
-
- del_timer_sync(&pmlmepriv->assoc_timer);
-
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
- psta = rtw_get_stainfo23a(&padapter->stapriv,
- pnetwork->MacAddress);
- if (!psta) {
- psta = rtw_alloc_stainfo23a(&padapter->stapriv,
- pnetwork->MacAddress,
- GFP_KERNEL);
- if (!psta) {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
- "Can't alloc sta_info when createbss_cmd_callback\n");
- goto createbss_cmd_fail;
- }
- }
-
- spin_lock_bh(&pmlmepriv->lock);
- rtw_indicate_connect23a(padapter);
- spin_unlock_bh(&pmlmepriv->lock);
- } else {
- pwlan = rtw_alloc_network(pmlmepriv, GFP_KERNEL);
- spin_lock_bh(&scanned_queue->lock);
- if (!pwlan) {
- pwlan = rtw_get_oldest_wlan_network23a(scanned_queue);
- if (!pwlan) {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
- "Error: can't get pwlan in rtw23a_joinbss_event_cb\n");
- spin_unlock_bh(&scanned_queue->lock);
- goto createbss_cmd_fail;
- }
- pwlan->last_scanned = jiffies;
- } else {
- list_add_tail(&pwlan->list,
- &scanned_queue->queue);
- }
-
- pnetwork->Length = get_wlan_bssid_ex_sz(pnetwork);
- memcpy(&pwlan->network, pnetwork, pnetwork->Length);
- /* pwlan->fixed = true; */
-
- /* list_add_tail(&pwlan->list,
- &pmlmepriv->scanned_queue.queue); */
-
- /* copy pdev_network information to
- pmlmepriv->cur_network */
- memcpy(&tgt_network->network, pnetwork,
- get_wlan_bssid_ex_sz(pnetwork));
-
- /* reset DSConfig */
-
- clr_fwstate(pmlmepriv, _FW_UNDER_LINKING);
-
- /* we will set _FW_LINKED when there is one more sat to
- join us (rtw_stassoc_event_callback23a) */
- spin_unlock_bh(&scanned_queue->lock);
- }
-
-createbss_cmd_fail:
-
- rtw_free_cmd_obj23a(pcmd);
-}
-
-void rtw_setstaKey_cmdrsp_callback23a(struct rtw_adapter *padapter,
- struct cmd_obj *pcmd)
-{
- struct sta_priv *pstapriv;
- struct set_stakey_rsp *psetstakey_rsp;
- struct sta_info *psta;
-
- pstapriv = &padapter->stapriv;
- psetstakey_rsp = (struct set_stakey_rsp *) (pcmd->rsp);
- psta = rtw_get_stainfo23a(pstapriv, psetstakey_rsp->addr);
-
- if (!psta) {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
- "ERROR: rtw_setstaKey_cmdrsp_callback23a => can't get sta_info\n");
- goto exit;
- }
-
-exit:
-
- rtw_free_cmd_obj23a(pcmd);
-}
-
-void rtw_setassocsta_cmdrsp_callback23a(struct rtw_adapter *padapter,
- struct cmd_obj *pcmd)
-{
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct set_assocsta_parm *passocsta_parm;
- struct set_assocsta_rsp *passocsta_rsp;
- struct sta_info *psta;
-
- passocsta_parm = (struct set_assocsta_parm *)(pcmd->parmbuf);
- passocsta_rsp = (struct set_assocsta_rsp *) (pcmd->rsp);
- psta = rtw_get_stainfo23a(pstapriv, passocsta_parm->addr);
-
- if (psta == NULL) {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
- "ERROR: setassocsta_cmdrsp_callbac => can't get sta_info\n");
- goto exit;
- }
-
- psta->aid = psta->mac_id = passocsta_rsp->cam_id;
-
- spin_lock_bh(&pmlmepriv->lock);
-
- if (check_fwstate(pmlmepriv, WIFI_MP_STATE) &&
- check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
- _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
-
- set_fwstate(pmlmepriv, _FW_LINKED);
- spin_unlock_bh(&pmlmepriv->lock);
-
-exit:
- rtw_free_cmd_obj23a(pcmd);
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_efuse.c b/drivers/staging/rtl8723au/core/rtw_efuse.c
deleted file mode 100644
index 359ef4197e94..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_efuse.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTW_EFUSE_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-#include <rtw_efuse.h>
-#include <rtl8723a_hal.h>
-#include <usb_ops_linux.h>
-
-#define REG_EFUSE_CTRL 0x0030
-#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control */
-
-#define VOLTAGE_V25 0x03
-#define LDOE25_SHIFT 28
-
-/*
- * When we want to enable write operation, we should change to
- * pwr on state. When we stop write, we should switch to 500k mode
- * and disable LDO 2.5V.
- */
-static void Efuse_PowerSwitch(struct rtw_adapter *padapter,
- u8 bWrite, u8 PwrState)
-{
- u8 tempval;
- u16 tmpV16;
-
- if (PwrState == true) {
- rtl8723au_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
-
- /*
- * 1.2V Power: From VDDON with Power
- * Cut(0x0000h[15]), default valid
- */
- tmpV16 = rtl8723au_read16(padapter, REG_SYS_ISO_CTRL);
- if (!(tmpV16 & PWC_EV12V)) {
- tmpV16 |= PWC_EV12V;
- rtl8723au_write16(padapter, REG_SYS_ISO_CTRL, tmpV16);
- }
- /* Reset: 0x0000h[28], default valid */
- tmpV16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN);
- if (!(tmpV16 & FEN_ELDR)) {
- tmpV16 |= FEN_ELDR;
- rtl8723au_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
- }
-
- /*
- * Clock: Gated(0x0008h[5]) 8M(0x0008h[1])
- * clock from ANA, default valid
- */
- tmpV16 = rtl8723au_read16(padapter, REG_SYS_CLKR);
- if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
- tmpV16 |= (LOADER_CLK_EN | ANA8M);
- rtl8723au_write16(padapter, REG_SYS_CLKR, tmpV16);
- }
-
- if (bWrite == true) {
- /* Enable LDO 2.5V before read/write action */
- tempval = rtl8723au_read8(padapter, EFUSE_TEST + 3);
- tempval &= 0x0F;
- tempval |= (VOLTAGE_V25 << 4);
- rtl8723au_write8(padapter, EFUSE_TEST + 3,
- tempval | 0x80);
- }
- } else {
- rtl8723au_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
-
- if (bWrite == true) {
- /* Disable LDO 2.5V after read/write action */
- tempval = rtl8723au_read8(padapter, EFUSE_TEST + 3);
- rtl8723au_write8(padapter, EFUSE_TEST + 3,
- tempval & 0x7F);
- }
- }
-}
-
-u16 Efuse_GetCurrentSize23a(struct rtw_adapter *pAdapter, u8 efuseType)
-{
- u16 ret = 0;
-
- if (efuseType == EFUSE_WIFI)
- ret = rtl8723a_EfuseGetCurrentSize_WiFi(pAdapter);
- else
- ret = rtl8723a_EfuseGetCurrentSize_BT(pAdapter);
-
- return ret;
-}
-
-/* Get current efuse area enabled word */
-u8 Efuse_CalculateWordCnts23a(u8 word_en)
-{
- return hweight8((~word_en) & 0xf);
-}
-
-/*
- * Description: Execute E-Fuse read byte operation.
- *
- * Assumptions: 1. Boot from E-Fuse and successfully auto-load.
- * 2. PASSIVE_LEVEL (USB interface)
- */
-void ReadEFuseByte23a(struct rtw_adapter *Adapter, u16 _offset, u8 *pbuf)
-{
- u32 value32;
- u8 readbyte;
- u16 retry;
-
- /* Write Address */
- rtl8723au_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff));
- readbyte = rtl8723au_read8(Adapter, EFUSE_CTRL+2);
- rtl8723au_write8(Adapter, EFUSE_CTRL+2,
- ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
-
- /* Write bit 32 0 */
- readbyte = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
- rtl8723au_write8(Adapter, EFUSE_CTRL+3, readbyte & 0x7f);
-
- /* Check bit 32 read-ready */
- retry = 0;
- value32 = rtl8723au_read32(Adapter, EFUSE_CTRL);
- while (!((value32 >> 24) & 0x80) && retry < 10000) {
- value32 = rtl8723au_read32(Adapter, EFUSE_CTRL);
- retry++;
- }
-
- /*
- * Added suggested delay. This fixes the problem that
- * Efuse read error in high temperature condition.
- * Designer says that there shall be some delay after
- * ready bit is set, or the result will always stay
- * on last data we read.
- */
- udelay(50);
- value32 = rtl8723au_read32(Adapter, EFUSE_CTRL);
-
- *pbuf = (u8)(value32 & 0xff);
-}
-
-void EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType,
- u8 type, void *pOut)
-{
- u8 *pu1Tmp;
- u16 *pu2Tmp;
- u8 *pMax_section;
-
- switch (type) {
- case TYPE_EFUSE_MAX_SECTION:
- pMax_section = pOut;
-
- if (efuseType == EFUSE_WIFI)
- *pMax_section = EFUSE_MAX_SECTION_8723A;
- else
- *pMax_section = EFUSE_BT_MAX_SECTION;
- break;
-
- case TYPE_EFUSE_REAL_CONTENT_LEN:
- pu2Tmp = pOut;
-
- if (efuseType == EFUSE_WIFI)
- *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A;
- else
- *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
- break;
-
- case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
- pu2Tmp = pOut;
-
- if (efuseType == EFUSE_WIFI)
- *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A -
- EFUSE_OOB_PROTECT_BYTES);
- else
- *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN -
- EFUSE_PROTECT_BYTES_BANK);
- break;
-
- case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
- pu2Tmp = pOut;
-
- if (efuseType == EFUSE_WIFI)
- *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A -
- EFUSE_OOB_PROTECT_BYTES);
- else
- *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN -
- (EFUSE_PROTECT_BYTES_BANK * 3));
- break;
-
- case TYPE_EFUSE_MAP_LEN:
- pu2Tmp = pOut;
-
- if (efuseType == EFUSE_WIFI)
- *pu2Tmp = EFUSE_MAP_LEN_8723A;
- else
- *pu2Tmp = EFUSE_BT_MAP_LEN;
- break;
-
- case TYPE_EFUSE_PROTECT_BYTES_BANK:
- pu1Tmp = pOut;
-
- if (efuseType == EFUSE_WIFI)
- *pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
- else
- *pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
- break;
-
- case TYPE_EFUSE_CONTENT_LEN_BANK:
- pu2Tmp = pOut;
-
- if (efuseType == EFUSE_WIFI)
- *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A;
- else
- *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
- break;
-
- default:
- pu1Tmp = pOut;
- *pu1Tmp = 0;
- break;
- }
-}
-
-/* Copy from WMAC for EFUSE read 1 byte. */
-u8 EFUSE_Read1Byte23a(struct rtw_adapter *Adapter, u16 Address)
-{
- u8 data;
- u8 Bytetemp = {0x00};
- u8 temp = {0x00};
- u32 k = 0;
- u16 contentLen = 0;
-
- EFUSE_GetEfuseDefinition23a(Adapter, EFUSE_WIFI,
- TYPE_EFUSE_REAL_CONTENT_LEN,
- (void *)&contentLen);
-
- if (Address < contentLen) { /* E-fuse 512Byte */
- /* Write E-fuse Register address bit0~7 */
- temp = Address & 0xFF;
- rtl8723au_write8(Adapter, EFUSE_CTRL+1, temp);
- Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+2);
- /* Write E-fuse Register address bit8~9 */
- temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
- rtl8723au_write8(Adapter, EFUSE_CTRL+2, temp);
-
- /* Write 0x30[31]= 0 */
- Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
- temp = Bytetemp & 0x7F;
- rtl8723au_write8(Adapter, EFUSE_CTRL+3, temp);
-
- /* Wait Write-ready (0x30[31]= 1) */
- Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
- while (!(Bytetemp & 0x80)) {
- Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
- k++;
- if (k == 1000) {
- k = 0;
- break;
- }
- }
- data = rtl8723au_read8(Adapter, EFUSE_CTRL);
- return data;
- }
- return 0xFF;
-}
-
-/* Read one byte from real Efuse. */
-int efuse_OneByteRead23a(struct rtw_adapter *pAdapter, u16 addr, u8 *data)
-{
- u8 tmpidx = 0;
- int bResult;
-
- /* -----------------e-fuse reg ctrl ---------------------------- */
- /* address */
- rtl8723au_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
- rtl8723au_write8(pAdapter, EFUSE_CTRL + 2,
- ((u8)((addr >> 8) & 0x03)) |
- (rtl8723au_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC));
-
- rtl8723au_write8(pAdapter, EFUSE_CTRL + 3, 0x72); /* read cmd */
-
- while (!(0x80 & rtl8723au_read8(pAdapter, EFUSE_CTRL + 3)) &&
- (tmpidx < 100))
- tmpidx++;
- if (tmpidx < 100) {
- *data = rtl8723au_read8(pAdapter, EFUSE_CTRL);
- bResult = _SUCCESS;
- } else {
- *data = 0xff;
- bResult = _FAIL;
- }
- return bResult;
-}
-
-/* Write one byte to reald Efuse. */
-int efuse_OneByteWrite23a(struct rtw_adapter *pAdapter, u16 addr, u8 data)
-{
- u8 tmpidx = 0;
- int bResult;
-
- /* return 0; */
-
- /* -----------------e-fuse reg ctrl ------------------------- */
- /* address */
- rtl8723au_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
- rtl8723au_write8(pAdapter, EFUSE_CTRL + 2,
- (rtl8723au_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC) |
- (u8)((addr >> 8) & 0x03));
- rtl8723au_write8(pAdapter, EFUSE_CTRL, data); /* data */
-
- rtl8723au_write8(pAdapter, EFUSE_CTRL + 3, 0xF2); /* write cmd */
-
- while ((0x80 & rtl8723au_read8(pAdapter, EFUSE_CTRL + 3)) &&
- (tmpidx < 100)) {
- tmpidx++;
- }
-
- if (tmpidx < 100)
- bResult = _SUCCESS;
- else
- bResult = _FAIL;
-
- return bResult;
-}
-
-/* Read allowed word in current efuse section data. */
-void efuse_WordEnableDataRead23a(u8 word_en, u8 *sourdata, u8 *targetdata)
-{
- if (!(word_en&BIT(0))) {
- targetdata[0] = sourdata[0];
- targetdata[1] = sourdata[1];
- }
- if (!(word_en&BIT(1))) {
- targetdata[2] = sourdata[2];
- targetdata[3] = sourdata[3];
- }
- if (!(word_en&BIT(2))) {
- targetdata[4] = sourdata[4];
- targetdata[5] = sourdata[5];
- }
- if (!(word_en&BIT(3))) {
- targetdata[6] = sourdata[6];
- targetdata[7] = sourdata[7];
- }
-}
-
-static int efuse_read8(struct rtw_adapter *padapter, u16 address, u8 *value)
-{
- return efuse_OneByteRead23a(padapter, address, value);
-}
-
-static int efuse_write8(struct rtw_adapter *padapter, u16 address, u8 *value)
-{
- return efuse_OneByteWrite23a(padapter, address, *value);
-}
-
-/* read/write raw efuse data */
-int rtw_efuse_access23a(struct rtw_adapter *padapter, u8 bWrite, u16 start_addr,
- u16 cnts, u8 *data)
-{
- int i = 0;
- u16 real_content_len = 0, max_available_size = 0;
- int res = _FAIL;
- int (*rw8)(struct rtw_adapter *, u16, u8*);
-
- EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
- TYPE_EFUSE_REAL_CONTENT_LEN,
- (void *)&real_content_len);
- EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
- TYPE_AVAILABLE_EFUSE_BYTES_TOTAL,
- (void *)&max_available_size);
-
- if (start_addr > real_content_len)
- return _FAIL;
-
- if (true == bWrite) {
- if ((start_addr + cnts) > max_available_size)
- return _FAIL;
- rw8 = &efuse_write8;
- } else
- rw8 = &efuse_read8;
-
- Efuse_PowerSwitch(padapter, bWrite, true);
-
- /* e-fuse one byte read/write */
- for (i = 0; i < cnts; i++) {
- if (start_addr >= real_content_len) {
- res = _FAIL;
- break;
- }
-
- res = rw8(padapter, start_addr++, data++);
- if (res == _FAIL)
- break;
- }
-
- Efuse_PowerSwitch(padapter, bWrite, false);
-
- return res;
-}
-
-u16 efuse_GetMaxSize23a(struct rtw_adapter *padapter)
-{
- u16 max_size;
-
- EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
- TYPE_AVAILABLE_EFUSE_BYTES_TOTAL,
- (void *)&max_size);
- return max_size;
-}
-
-int rtw_efuse_map_read23a(struct rtw_adapter *padapter,
- u16 addr, u16 cnts, u8 *data)
-{
- u16 mapLen = 0;
-
- EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
- TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
-
- if ((addr + cnts) > mapLen)
- return _FAIL;
-
- Efuse_PowerSwitch(padapter, false, true);
-
- rtl8723a_readefuse(padapter, EFUSE_WIFI, addr, cnts, data);
-
- Efuse_PowerSwitch(padapter, false, false);
-
- return _SUCCESS;
-}
-
-int rtw_BT_efuse_map_read23a(struct rtw_adapter *padapter,
- u16 addr, u16 cnts, u8 *data)
-{
- u16 mapLen = 0;
-
- EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
- TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
-
- if ((addr + cnts) > mapLen)
- return _FAIL;
-
- Efuse_PowerSwitch(padapter, false, true);
-
- rtl8723a_readefuse(padapter, EFUSE_BT, addr, cnts, data);
-
- Efuse_PowerSwitch(padapter, false, false);
-
- return _SUCCESS;
-}
-
-/* Read All Efuse content */
-static void Efuse_ReadAllMap(struct rtw_adapter *pAdapter, u8 efuseType,
- u8 *Efuse)
-{
- u16 mapLen = 0;
-
- Efuse_PowerSwitch(pAdapter, false, true);
-
- EFUSE_GetEfuseDefinition23a(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN,
- (void *)&mapLen);
-
- rtl8723a_readefuse(pAdapter, efuseType, 0, mapLen, Efuse);
-
- Efuse_PowerSwitch(pAdapter, false, false);
-}
-
-/*
- * Functions: efuse_ShadowRead1Byte
- * efuse_ShadowRead2Byte
- * efuse_ShadowRead4Byte
- *
- * Read from efuse init map by one/two/four bytes
- */
-static void efuse_ShadowRead1Byte(struct rtw_adapter *pAdapter, u16 Offset,
- u8 *Value)
-{
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
-
- *Value = pEEPROM->efuse_eeprom_data[Offset];
-}
-
-static void efuse_ShadowRead2Byte(struct rtw_adapter *pAdapter, u16 Offset,
- u16 *Value)
-{
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
-
- *Value = pEEPROM->efuse_eeprom_data[Offset];
- *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
-}
-
-static void efuse_ShadowRead4Byte(struct rtw_adapter *pAdapter, u16 Offset,
- u32 *Value)
-{
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
-
- *Value = pEEPROM->efuse_eeprom_data[Offset];
- *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
- *Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16;
- *Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24;
-}
-
-/* Transfer current EFUSE content to shadow init and modify map. */
-void EFUSE_ShadowMapUpdate23a(struct rtw_adapter *pAdapter, u8 efuseType)
-{
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
- u16 mapLen = 0;
-
- EFUSE_GetEfuseDefinition23a(pAdapter, efuseType,
- TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
-
- if (pEEPROM->bautoload_fail_flag == true)
- memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
- else
- Efuse_ReadAllMap(pAdapter, efuseType,
- pEEPROM->efuse_eeprom_data);
-}
-
-/* Read from efuse init map */
-void EFUSE_ShadowRead23a(struct rtw_adapter *pAdapter, u8 Type,
- u16 Offset, u32 *Value)
-{
- if (Type == 1)
- efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);
- else if (Type == 2)
- efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value);
- else if (Type == 4)
- efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value);
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_ieee80211.c b/drivers/staging/rtl8723au/core/rtw_ieee80211.c
deleted file mode 100644
index 07a6490a83d6..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_ieee80211.c
+++ /dev/null
@@ -1,855 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _IEEE80211_C
-
-#include <drv_types.h>
-#include <linux/ieee80211.h>
-#include <ieee80211.h>
-#include <wifi.h>
-#include <osdep_service.h>
-#include <wlan_bssdef.h>
-
-u8 RTW_WPA_OUI23A_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
-u16 RTW_WPA_VERSION23A = 1;
-u8 WPA_AUTH_KEY_MGMT_NONE23A[] = { 0x00, 0x50, 0xf2, 0 };
-u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X23A[] = { 0x00, 0x50, 0xf2, 1 };
-u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X23A[] = { 0x00, 0x50, 0xf2, 2 };
-u8 WPA_CIPHER_SUITE_NONE23A[] = { 0x00, 0x50, 0xf2, 0 };
-u8 WPA_CIPHER_SUITE_WEP4023A[] = { 0x00, 0x50, 0xf2, 1 };
-u8 WPA_CIPHER_SUITE_TKIP23A[] = { 0x00, 0x50, 0xf2, 2 };
-u8 WPA_CIPHER_SUITE_WRAP23A[] = { 0x00, 0x50, 0xf2, 3 };
-u8 WPA_CIPHER_SUITE_CCMP23A[] = { 0x00, 0x50, 0xf2, 4 };
-u8 WPA_CIPHER_SUITE_WEP10423A[] = { 0x00, 0x50, 0xf2, 5 };
-
-u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X23A[] = { 0x00, 0x0f, 0xac, 1 };
-u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X23A[] = { 0x00, 0x0f, 0xac, 2 };
-u8 RSN_CIPHER_SUITE_NONE23A[] = { 0x00, 0x0f, 0xac, 0 };
-u8 RSN_CIPHER_SUITE_WEP4023A[] = { 0x00, 0x0f, 0xac, 1 };
-u8 RSN_CIPHER_SUITE_TKIP23A[] = { 0x00, 0x0f, 0xac, 2 };
-u8 RSN_CIPHER_SUITE_WRAP23A[] = { 0x00, 0x0f, 0xac, 3 };
-u8 RSN_CIPHER_SUITE_CCMP23A[] = { 0x00, 0x0f, 0xac, 4 };
-u8 RSN_CIPHER_SUITE_WEP10423A[] = { 0x00, 0x0f, 0xac, 5 };
-/* */
-/* for adhoc-master to generate ie and provide supported-rate to fw */
-/* */
-
-static u8 WIFI_CCKRATES[] = {
- IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK
-};
-
-static u8 WIFI_OFDMRATES[] = {
- IEEE80211_OFDM_RATE_6MB,
- IEEE80211_OFDM_RATE_9MB,
- IEEE80211_OFDM_RATE_12MB,
- IEEE80211_OFDM_RATE_18MB,
- IEEE80211_OFDM_RATE_24MB,
- IEEE80211_OFDM_RATE_36MB,
- IEEE80211_OFDM_RATE_48MB,
- IEEE80211_OFDM_RATE_54MB
-};
-
-int rtw_get_bit_value_from_ieee_value23a(u8 val)
-{
- unsigned char dot11_rate_table[]=
- {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 0};
-
- int i = 0;
-
- while (dot11_rate_table[i] != 0) {
- if (dot11_rate_table[i] == val)
- return BIT(i);
- i++;
- }
- return 0;
-}
-
-static bool rtw_is_cckrates_included(u8 *rate)
-{
- u32 i = 0;
-
- while (rate[i]) {
- if ((rate[i] & 0x7f) == 2 || (rate[i] & 0x7f) == 4 ||
- (rate[i] & 0x7f) == 11 || (rate[i] & 0x7f) == 22)
- return true;
- i++;
- }
-
- return false;
-}
-
-static bool rtw_is_cckratesonly_included(u8 *rate)
-{
- u32 i = 0;
-
- while (rate[i]) {
- if ((rate[i] & 0x7f) != 2 && (rate[i] & 0x7f) != 4 &&
- (rate[i] & 0x7f) != 11 && (rate[i] & 0x7f) != 22)
- return false;
-
- i++;
- }
-
- return true;
-}
-
-int rtw_check_network_type23a(unsigned char *rate, int ratelen, int channel)
-{
- if (channel > 14) {
- if (rtw_is_cckrates_included(rate))
- return WIRELESS_INVALID;
- else
- return WIRELESS_11A;
- } else { /* could be pure B, pure G, or B/G */
- if (rtw_is_cckratesonly_included(rate))
- return WIRELESS_11B;
- else if (rtw_is_cckrates_included(rate))
- return WIRELESS_11BG;
- else
- return WIRELESS_11G;
- }
-}
-
-/* rtw_set_ie23a will update frame length */
-u8 *rtw_set_ie23a(u8 *pbuf, int index, uint len, const u8 *source, uint *frlen)
-{
-
- *pbuf = (u8)index;
-
- *(pbuf + 1) = (u8)len;
-
- if (len > 0)
- memcpy((void *)(pbuf + 2), (void *)source, len);
-
- *frlen = *frlen + (len + 2);
-
- return pbuf + len + 2;
-}
-
-inline u8 *rtw_set_ie23a_ch_switch (u8 *buf, u32 *buf_len, u8 ch_switch_mode,
- u8 new_ch, u8 ch_switch_cnt)
-{
- u8 ie_data[3];
-
- ie_data[0] = ch_switch_mode;
- ie_data[1] = new_ch;
- ie_data[2] = ch_switch_cnt;
- return rtw_set_ie23a(buf, WLAN_EID_CHANNEL_SWITCH, 3, ie_data, buf_len);
-}
-
-inline u8 hal_ch_offset_to_secondary_ch_offset23a(u8 ch_offset)
-{
- if (ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
- return IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- else if (ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
- return IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-
- return IEEE80211_HT_PARAM_CHA_SEC_NONE;
-}
-
-inline u8 *rtw_set_ie23a_secondary_ch_offset(u8 *buf, u32 *buf_len,
- u8 secondary_ch_offset)
-{
- return rtw_set_ie23a(buf, WLAN_EID_SECONDARY_CHANNEL_OFFSET,
- 1, &secondary_ch_offset, buf_len);
-}
-
-/*----------------------------------------------------------------------------
-index: the information element id index, limit is the limit for search
------------------------------------------------------------------------------*/
-u8 *rtw_get_ie23a(u8 *pbuf, int index, int *len, int limit)
-{
- int tmp, i;
- u8 *p;
-
- if (limit < 1) {
-
- return NULL;
- }
-
- p = pbuf;
- i = 0;
- *len = 0;
- while (1) {
- if (*p == index) {
- *len = *(p + 1);
- return p;
- } else {
- tmp = *(p + 1);
- p += (tmp + 2);
- i += (tmp + 2);
- }
- if (i >= limit)
- break;
- }
-
- return NULL;
-}
-
-/**
- * rtw_get_ie23a_ex - Search specific IE from a series of IEs
- * @in_ie: Address of IEs to search
- * @in_len: Length limit from in_ie
- * @eid: Element ID to match
- * @oui: OUI to match
- * @oui_len: OUI length
- * @ie: If not NULL and the specific IE is found, the IE will be copied
- * to the buf starting from the specific IE
- * @ielen: If not NULL and the specific IE is found, will set to the length
- * of the entire IE
- *
- * Returns: The address of the specific IE found, or NULL
- */
-u8 *rtw_get_ie23a_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len,
- u8 *ie, uint *ielen)
-{
- uint cnt;
- u8 *target_ie = NULL;
-
- if (ielen)
- *ielen = 0;
-
- if (!in_ie || in_len <= 0)
- return target_ie;
-
- cnt = 0;
-
- while (cnt < in_len) {
- if (eid == in_ie[cnt] &&
- (!oui || !memcmp(&in_ie[cnt+2], oui, oui_len))) {
- target_ie = &in_ie[cnt];
-
- if (ie)
- memcpy(ie, &in_ie[cnt], in_ie[cnt+1]+2);
-
- if (ielen)
- *ielen = in_ie[cnt+1]+2;
- break;
- } else {
- cnt += in_ie[cnt + 1] + 2; /* goto next */
- }
- }
-
- return target_ie;
-}
-
-/**
- * rtw_ies_remove_ie23a - Find matching IEs and remove
- * @ies: Address of IEs to search
- * @ies_len: Pointer of length of ies, will update to new length
- * @offset: The offset to start search
- * @eid: Element ID to match
- * @oui: OUI to match
- * @oui_len: OUI length
- *
- * Returns: _SUCCESS: ies is updated, _FAIL: not updated
- */
-int rtw_ies_remove_ie23a(u8 *ies, uint *ies_len, uint offset, u8 eid,
- u8 *oui, u8 oui_len)
-{
- int ret = _FAIL;
- u8 *target_ie;
- u32 target_ielen;
- u8 *start;
- uint search_len;
-
- if (!ies || !ies_len || *ies_len <= offset)
- goto exit;
-
- start = ies + offset;
- search_len = *ies_len - offset;
-
- while (1) {
- target_ie = rtw_get_ie23a_ex(start, search_len, eid, oui, oui_len,
- NULL, &target_ielen);
- if (target_ie && target_ielen) {
- u8 buf[MAX_IE_SZ] = {0};
- u8 *remain_ies = target_ie + target_ielen;
- uint remain_len = search_len - (remain_ies - start);
-
- memcpy(buf, remain_ies, remain_len);
- memcpy(target_ie, buf, remain_len);
- *ies_len = *ies_len - target_ielen;
- ret = _SUCCESS;
-
- start = target_ie;
- search_len = remain_len;
- } else {
- break;
- }
- }
-exit:
- return ret;
-}
-
-void rtw_set_supported_rate23a(u8 *SupportedRates, uint mode)
-{
-
-
- memset(SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
-
- switch (mode) {
- case WIRELESS_11B:
- memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN);
- break;
-
- case WIRELESS_11G:
- case WIRELESS_11A:
- case WIRELESS_11_5N:
- case WIRELESS_11A_5N:/* Todo: no basic rate for ofdm ? */
- memcpy(SupportedRates, WIFI_OFDMRATES,
- IEEE80211_NUM_OFDM_RATESLEN);
- break;
-
- case WIRELESS_11BG:
- case WIRELESS_11G_24N:
- case WIRELESS_11_24N:
- case WIRELESS_11BG_24N:
- memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN);
- memcpy(SupportedRates + IEEE80211_CCK_RATE_LEN, WIFI_OFDMRATES,
- IEEE80211_NUM_OFDM_RATESLEN);
- break;
- }
-
-}
-
-uint rtw_get_rateset_len23a(u8 *rateset)
-{
- uint i = 0;
-
- while(1) {
- if (rateset[i] == 0)
- break;
-
- if (i > 12)
- break;
-
- i++;
- }
-
- return i;
-}
-
-int rtw_generate_ie23a(struct registry_priv *pregistrypriv)
-{
- u8 wireless_mode;
- int sz = 0, rateLen;
- struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
- u8 *ie = pdev_network->IEs;
- u16 cap;
-
- pdev_network->tsf = 0;
-
- cap = WLAN_CAPABILITY_IBSS;
-
- if (pregistrypriv->preamble == PREAMBLE_SHORT)
- cap |= WLAN_CAPABILITY_SHORT_PREAMBLE;
-
- if (pdev_network->Privacy)
- cap |= WLAN_CAPABILITY_PRIVACY;
-
- pdev_network->capability = cap;
-
- /* SSID */
- ie = rtw_set_ie23a(ie, WLAN_EID_SSID, pdev_network->Ssid.ssid_len,
- pdev_network->Ssid.ssid, &sz);
-
- /* supported rates */
- if (pregistrypriv->wireless_mode == WIRELESS_11ABGN) {
- if (pdev_network->DSConfig > 14)
- wireless_mode = WIRELESS_11A_5N;
- else
- wireless_mode = WIRELESS_11BG_24N;
- } else {
- wireless_mode = pregistrypriv->wireless_mode;
- }
-
- rtw_set_supported_rate23a(pdev_network->SupportedRates, wireless_mode) ;
-
- rateLen = rtw_get_rateset_len23a(pdev_network->SupportedRates);
-
- if (rateLen > 8) {
- ie = rtw_set_ie23a(ie, WLAN_EID_SUPP_RATES, 8,
- pdev_network->SupportedRates, &sz);
- /* ie = rtw_set_ie23a(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz); */
- } else {
- ie = rtw_set_ie23a(ie, WLAN_EID_SUPP_RATES, rateLen,
- pdev_network->SupportedRates, &sz);
- }
-
- /* DS parameter set */
- ie = rtw_set_ie23a(ie, WLAN_EID_DS_PARAMS, 1,
- (u8 *)&pdev_network->DSConfig, &sz);
-
- /* IBSS Parameter Set */
-
- ie = rtw_set_ie23a(ie, WLAN_EID_IBSS_PARAMS, 2,
- (u8 *)&pdev_network->ATIMWindow, &sz);
-
- if (rateLen > 8) {
- ie = rtw_set_ie23a(ie, WLAN_EID_EXT_SUPP_RATES, (rateLen - 8),
- (pdev_network->SupportedRates + 8), &sz);
- }
-
-
-
- /* return _SUCCESS; */
-
- return sz;
-}
-
-static int rtw_get_wpa_cipher_suite(const u8 *s)
-{
- if (!memcmp(s, WPA_CIPHER_SUITE_NONE23A, WPA_SELECTOR_LEN))
- return WPA_CIPHER_NONE;
- if (!memcmp(s, WPA_CIPHER_SUITE_WEP4023A, WPA_SELECTOR_LEN))
- return WPA_CIPHER_WEP40;
- if (!memcmp(s, WPA_CIPHER_SUITE_TKIP23A, WPA_SELECTOR_LEN))
- return WPA_CIPHER_TKIP;
- if (!memcmp(s, WPA_CIPHER_SUITE_CCMP23A, WPA_SELECTOR_LEN))
- return WPA_CIPHER_CCMP;
- if (!memcmp(s, WPA_CIPHER_SUITE_WEP10423A, WPA_SELECTOR_LEN))
- return WPA_CIPHER_WEP104;
-
- return 0;
-}
-
-static int rtw_get_wpa2_cipher_suite(const u8 *s)
-{
- if (!memcmp(s, RSN_CIPHER_SUITE_NONE23A, RSN_SELECTOR_LEN))
- return WPA_CIPHER_NONE;
- if (!memcmp(s, RSN_CIPHER_SUITE_WEP4023A, RSN_SELECTOR_LEN))
- return WPA_CIPHER_WEP40;
- if (!memcmp(s, RSN_CIPHER_SUITE_TKIP23A, RSN_SELECTOR_LEN))
- return WPA_CIPHER_TKIP;
- if (!memcmp(s, RSN_CIPHER_SUITE_CCMP23A, RSN_SELECTOR_LEN))
- return WPA_CIPHER_CCMP;
- if (!memcmp(s, RSN_CIPHER_SUITE_WEP10423A, RSN_SELECTOR_LEN))
- return WPA_CIPHER_WEP104;
-
- return 0;
-}
-
-int rtw_parse_wpa_ie23a(const u8 *wpa_ie, int wpa_ie_len, int *group_cipher,
- int *pairwise_cipher, int *is_8021x)
-{
- int i, ret = _SUCCESS;
- int left, count;
- const u8 *pos;
-
- if (wpa_ie_len <= 0) {
- /* No WPA IE - fail silently */
- return _FAIL;
- }
-
- if (wpa_ie[1] != (u8)(wpa_ie_len - 2))
- return _FAIL;
-
- pos = wpa_ie;
-
- pos += 8;
- left = wpa_ie_len - 8;
-
- /* group_cipher */
- if (left >= WPA_SELECTOR_LEN) {
-
- *group_cipher = rtw_get_wpa_cipher_suite(pos);
-
- pos += WPA_SELECTOR_LEN;
- left -= WPA_SELECTOR_LEN;
- } else if (left > 0) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "%s: ie length mismatch, %u too much\n",
- __func__, left);
-
- return _FAIL;
- }
-
- /* pairwise_cipher */
- if (left >= 2) {
- /* count = le16_to_cpu(*(u16*)pos); */
- count = get_unaligned_le16(pos);
- pos += 2;
- left -= 2;
-
- if (count == 0 || left < count * WPA_SELECTOR_LEN) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "%s: ie count botch (pairwise), count %u left %u\n",
- __func__, count, left);
- return _FAIL;
- }
-
- for (i = 0; i < count; i++) {
- *pairwise_cipher |= rtw_get_wpa_cipher_suite(pos);
-
- pos += WPA_SELECTOR_LEN;
- left -= WPA_SELECTOR_LEN;
- }
- } else if (left == 1) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "%s: ie too short (for key mgmt)\n", __func__);
- return _FAIL;
- }
-
- if (is_8021x) {
- if (left >= 6) {
- pos += 2;
- if (!memcmp(pos, RTW_WPA_OUI23A_TYPE, 4)) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "%s : there has 802.1x auth\n",
- __func__);
- *is_8021x = 1;
- }
- }
- }
-
- return ret;
-}
-
-int rtw_parse_wpa2_ie23a(const u8 *rsn_ie, int rsn_ie_len, int *group_cipher,
- int *pairwise_cipher, int *is_8021x)
-{
- int i, ret = _SUCCESS;
- int left, count;
- const u8 *pos;
- u8 SUITE_1X[4] = {0x00, 0x0f, 0xac, 0x01};
-
- if (rsn_ie_len <= 0) {
- /* No RSN IE - fail silently */
- return _FAIL;
- }
-
- if (*rsn_ie != WLAN_EID_RSN || *(rsn_ie+1) != (u8)(rsn_ie_len - 2)) {
- return _FAIL;
- }
-
- pos = rsn_ie;
- pos += 4;
- left = rsn_ie_len - 4;
-
- /* group_cipher */
- if (left >= RSN_SELECTOR_LEN) {
- *group_cipher = rtw_get_wpa2_cipher_suite(pos);
-
- pos += RSN_SELECTOR_LEN;
- left -= RSN_SELECTOR_LEN;
- } else if (left > 0) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "%s: ie length mismatch, %u too much\n",
- __func__, left);
- return _FAIL;
- }
-
- /* pairwise_cipher */
- if (left >= 2) {
- /* count = le16_to_cpu(*(u16*)pos); */
- count = get_unaligned_le16(pos);
- pos += 2;
- left -= 2;
-
- if (count == 0 || left < count * RSN_SELECTOR_LEN) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "%s: ie count botch (pairwise), count %u left %u\n",
- __func__, count, left);
- return _FAIL;
- }
-
- for (i = 0; i < count; i++) {
- *pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos);
-
- pos += RSN_SELECTOR_LEN;
- left -= RSN_SELECTOR_LEN;
- }
- } else if (left == 1) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "%s: ie too short (for key mgmt)\n", __func__);
-
- return _FAIL;
- }
-
- if (is_8021x) {
- if (left >= 6) {
- pos += 2;
- if (!memcmp(pos, SUITE_1X, 4)) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "%s (): there has 802.1x auth\n",
- __func__);
- *is_8021x = 1;
- }
- }
- }
-
- return ret;
-}
-
-/**
- * rtw_get_wps_attr23a - Search a specific WPS attribute from a given WPS IE
- * @wps_ie: Address of WPS IE to search
- * @wps_ielen: Length limit from wps_ie
- * @target_attr_id: The attribute ID of WPS attribute to search
- * @buf_attr: If not NULL and the WPS attribute is found, WPS attribute
- * will be copied to the buf starting from buf_attr
- * @len_attr: If not NULL and the WPS attribute is found, will set to the
- * length of the entire WPS attribute
- *
- * Returns: the address of the specific WPS attribute found, or NULL
- */
-const u8 *rtw_get_wps_attr23a(const u8 *wps_ie, uint wps_ielen,
- u16 target_attr_id, u8 *buf_attr, u32 *len_attr)
-{
- const u8 *attr_ptr = NULL;
- const u8 *target_attr_ptr = NULL;
- u8 wps_oui[4] = {0x00, 0x50, 0xF2, 0x04};
-
- if (len_attr)
- *len_attr = 0;
-
- if (wps_ie[0] != WLAN_EID_VENDOR_SPECIFIC ||
- memcmp(wps_ie + 2, wps_oui, 4)) {
- return attr_ptr;
- }
-
- /* 6 = 1(Element ID) + 1(Length) + 4(WPS OUI) */
- attr_ptr = wps_ie + 6; /* goto first attr */
-
- while (attr_ptr - wps_ie < wps_ielen) {
- /* 4 = 2(Attribute ID) + 2(Length) */
- u16 attr_id = get_unaligned_be16(attr_ptr);
- u16 attr_data_len = get_unaligned_be16(attr_ptr + 2);
- u16 attr_len = attr_data_len + 4;
-
- /* DBG_8723A("%s attr_ptr:%p, id:%u, length:%u\n", __func__, attr_ptr, attr_id, attr_data_len); */
- if (attr_id == target_attr_id) {
- target_attr_ptr = attr_ptr;
-
- if (buf_attr)
- memcpy(buf_attr, attr_ptr, attr_len);
-
- if (len_attr)
- *len_attr = attr_len;
-
- break;
- } else {
- attr_ptr += attr_len; /* goto next */
- }
- }
-
- return target_attr_ptr;
-}
-
-/**
- * rtw_get_wps_attr_content23a - Search a specific WPS attribute content
- * from a given WPS IE
- * @wps_ie: Address of WPS IE to search
- * @wps_ielen: Length limit from wps_ie
- * @target_attr_id: The attribute ID of WPS attribute to search
- * @buf_content: If not NULL and the WPS attribute is found, WPS attribute
- * content will be copied to the buf starting from buf_content
- * @len_content: If not NULL and the WPS attribute is found, will set to the
- * length of the WPS attribute content
- *
- * Returns: the address of the specific WPS attribute content found, or NULL
- */
-const u8 *rtw_get_wps_attr_content23a(const u8 *wps_ie, uint wps_ielen,
- u16 target_attr_id, u8 *buf_content)
-{
- const u8 *attr_ptr;
- u32 attr_len;
-
- attr_ptr = rtw_get_wps_attr23a(wps_ie, wps_ielen, target_attr_id,
- NULL, &attr_len);
-
- if (attr_ptr && attr_len) {
- if (buf_content)
- memcpy(buf_content, attr_ptr + 4, attr_len - 4);
-
- return attr_ptr + 4;
- }
-
- return NULL;
-}
-
-static int rtw_get_cipher_info(struct wlan_network *pnetwork)
-{
- const u8 *pbuf;
- int group_cipher = 0, pairwise_cipher = 0, is8021x = 0;
- int ret = _FAIL;
- int r, plen;
- char *pie;
-
- pie = pnetwork->network.IEs;
- plen = pnetwork->network.IELength;
-
- pbuf = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WPA, pie, plen);
-
- if (pbuf && pbuf[1] > 0) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "rtw_get_cipher_info: wpa_ielen: %d\n", pbuf[1]);
- r = rtw_parse_wpa_ie23a(pbuf, pbuf[1] + 2, &group_cipher,
- &pairwise_cipher, &is8021x);
- if (r == _SUCCESS) {
- pnetwork->BcnInfo.pairwise_cipher = pairwise_cipher;
- pnetwork->BcnInfo.group_cipher = group_cipher;
- pnetwork->BcnInfo.is_8021x = is8021x;
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "%s: pnetwork->pairwise_cipher: %d, is_8021x is %d\n",
- __func__, pnetwork->BcnInfo.pairwise_cipher,
- pnetwork->BcnInfo.is_8021x);
- ret = _SUCCESS;
- }
- } else {
- pbuf = cfg80211_find_ie(WLAN_EID_RSN, pie, plen);
-
- if (pbuf && pbuf[1] > 0) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "get RSN IE\n");
- r = rtw_parse_wpa2_ie23a(pbuf, pbuf[1] + 2,
- &group_cipher, &pairwise_cipher,
- &is8021x);
- if (r == _SUCCESS) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "get RSN IE OK!!!\n");
- pnetwork->BcnInfo.pairwise_cipher =
- pairwise_cipher;
- pnetwork->BcnInfo.group_cipher = group_cipher;
- pnetwork->BcnInfo.is_8021x = is8021x;
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "%s: pnetwork->pairwise_cipher: %d,pnetwork->group_cipher is %d, is_8021x is %d\n",
- __func__,
- pnetwork->BcnInfo.pairwise_cipher,
- pnetwork->BcnInfo.group_cipher,
- pnetwork->BcnInfo.is_8021x);
- ret = _SUCCESS;
- }
- }
- }
-
- return ret;
-}
-
-void rtw_get_bcn_info23a(struct wlan_network *pnetwork)
-{
- u8 bencrypt = 0;
- int pie_len;
- u8 *pie;
- const u8 *p;
-
- if (pnetwork->network.capability & WLAN_CAPABILITY_PRIVACY) {
- bencrypt = 1;
- pnetwork->network.Privacy = 1;
- } else
- pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_OPENSYS;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "%s: ssid =%s\n", __func__, pnetwork->network.Ssid.ssid);
-
- pie = pnetwork->network.IEs;
- pie_len = pnetwork->network.IELength;
-
- p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
- if (p && p[1]) {
- pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA2;
- } else if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WPA,
- pie, pie_len)) {
- pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA;
- } else {
- if (bencrypt)
- pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WEP;
- }
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "%s: pnetwork->encryp_protocol is %x\n", __func__,
- pnetwork->BcnInfo.encryp_protocol);
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "%s: pnetwork->encryp_protocol is %x\n", __func__,
- pnetwork->BcnInfo.encryp_protocol);
- rtw_get_cipher_info(pnetwork);
-
- /* get bwmode and ch_offset */
-}
-
-/* show MCS rate, unit: 100Kbps */
-u16 rtw_mcs_rate23a(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40,
- struct ieee80211_mcs_info *mcs)
-{
- u16 max_rate = 0;
-
- if (rf_type == RF_1T1R) {
- if (mcs->rx_mask[0] & BIT(7))
- max_rate = (bw_40MHz) ? ((short_GI_40)?1500:1350):
- ((short_GI_20)?722:650);
- else if (mcs->rx_mask[0] & BIT(6))
- max_rate = (bw_40MHz) ? ((short_GI_40)?1350:1215):
- ((short_GI_20)?650:585);
- else if (mcs->rx_mask[0] & BIT(5))
- max_rate = (bw_40MHz) ? ((short_GI_40)?1200:1080):
- ((short_GI_20)?578:520);
- else if (mcs->rx_mask[0] & BIT(4))
- max_rate = (bw_40MHz) ? ((short_GI_40)?900:810):
- ((short_GI_20)?433:390);
- else if (mcs->rx_mask[0] & BIT(3))
- max_rate = (bw_40MHz) ? ((short_GI_40)?600:540):
- ((short_GI_20)?289:260);
- else if (mcs->rx_mask[0] & BIT(2))
- max_rate = (bw_40MHz) ? ((short_GI_40)?450:405):
- ((short_GI_20)?217:195);
- else if (mcs->rx_mask[0] & BIT(1))
- max_rate = (bw_40MHz) ? ((short_GI_40)?300:270):
- ((short_GI_20)?144:130);
- else if (mcs->rx_mask[0] & BIT(0))
- max_rate = (bw_40MHz) ? ((short_GI_40)?150:135):
- ((short_GI_20)?72:65);
- } else {
- if (mcs->rx_mask[1]) {
- if (mcs->rx_mask[1] & BIT(7))
- max_rate = (bw_40MHz) ? ((short_GI_40)?3000:2700):((short_GI_20)?1444:1300);
- else if (mcs->rx_mask[1] & BIT(6))
- max_rate = (bw_40MHz) ? ((short_GI_40)?2700:2430):((short_GI_20)?1300:1170);
- else if (mcs->rx_mask[1] & BIT(5))
- max_rate = (bw_40MHz) ? ((short_GI_40)?2400:2160):((short_GI_20)?1156:1040);
- else if (mcs->rx_mask[1] & BIT(4))
- max_rate = (bw_40MHz) ? ((short_GI_40)?1800:1620):((short_GI_20)?867:780);
- else if (mcs->rx_mask[1] & BIT(3))
- max_rate = (bw_40MHz) ? ((short_GI_40)?1200:1080):((short_GI_20)?578:520);
- else if (mcs->rx_mask[1] & BIT(2))
- max_rate = (bw_40MHz) ? ((short_GI_40)?900:810):((short_GI_20)?433:390);
- else if (mcs->rx_mask[1] & BIT(1))
- max_rate = (bw_40MHz) ? ((short_GI_40)?600:540):((short_GI_20)?289:260);
- else if (mcs->rx_mask[1] & BIT(0))
- max_rate = (bw_40MHz) ? ((short_GI_40)?300:270):((short_GI_20)?144:130);
- } else {
- if (mcs->rx_mask[0] & BIT(7))
- max_rate = (bw_40MHz) ? ((short_GI_40)?1500:1350):((short_GI_20)?722:650);
- else if (mcs->rx_mask[0] & BIT(6))
- max_rate = (bw_40MHz) ? ((short_GI_40)?1350:1215):((short_GI_20)?650:585);
- else if (mcs->rx_mask[0] & BIT(5))
- max_rate = (bw_40MHz) ? ((short_GI_40)?1200:1080):((short_GI_20)?578:520);
- else if (mcs->rx_mask[0] & BIT(4))
- max_rate = (bw_40MHz) ? ((short_GI_40)?900:810):((short_GI_20)?433:390);
- else if (mcs->rx_mask[0] & BIT(3))
- max_rate = (bw_40MHz) ? ((short_GI_40)?600:540):((short_GI_20)?289:260);
- else if (mcs->rx_mask[0] & BIT(2))
- max_rate = (bw_40MHz) ? ((short_GI_40)?450:405):((short_GI_20)?217:195);
- else if (mcs->rx_mask[0] & BIT(1))
- max_rate = (bw_40MHz) ? ((short_GI_40)?300:270):((short_GI_20)?144:130);
- else if (mcs->rx_mask[0] & BIT(0))
- max_rate = (bw_40MHz) ? ((short_GI_40)?150:135):((short_GI_20)?72:65);
- }
- }
- return max_rate;
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_mlme.c b/drivers/staging/rtl8723au/core/rtw_mlme.c
deleted file mode 100644
index a786fc4bdb53..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_mlme.c
+++ /dev/null
@@ -1,2314 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTW_MLME_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <recv_osdep.h>
-#include <xmit_osdep.h>
-#include <hal_intf.h>
-#include <mlme_osdep.h>
-#include <sta_info.h>
-#include <linux/ieee80211.h>
-#include <wifi.h>
-#include <wlan_bssdef.h>
-#include <rtw_sreset.h>
-
-static struct wlan_network *
-rtw_select_candidate_from_queue(struct mlme_priv *pmlmepriv);
-static int rtw_do_join(struct rtw_adapter *padapter);
-
-static void rtw_init_mlme_timer(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- setup_timer(&pmlmepriv->assoc_timer, rtw23a_join_to_handler,
- (unsigned long)padapter);
-
- setup_timer(&pmlmepriv->scan_to_timer, rtw_scan_timeout_handler23a,
- (unsigned long)padapter);
-
- setup_timer(&pmlmepriv->dynamic_chk_timer,
- rtw_dynamic_check_timer_handler, (unsigned long)padapter);
-
- setup_timer(&pmlmepriv->set_scan_deny_timer,
- rtw_set_scan_deny_timer_hdl, (unsigned long)padapter);
-}
-
-int rtw_init_mlme_priv23a(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- pmlmepriv->nic_hdl = padapter;
-
- pmlmepriv->fw_state = 0;
- pmlmepriv->cur_network.network.ifmode = NL80211_IFTYPE_UNSPECIFIED;
- /* 1: active, 0: pasive. Maybe someday we should rename this
- varable to "active_mode" (Jeff) */
- pmlmepriv->scan_mode = SCAN_ACTIVE;
-
- spin_lock_init(&pmlmepriv->lock);
- _rtw_init_queue23a(&pmlmepriv->scanned_queue);
-
- memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct cfg80211_ssid));
-
- rtw_clear_scan_deny(padapter);
-
- rtw_init_mlme_timer(padapter);
- return _SUCCESS;
-}
-
-#ifdef CONFIG_8723AU_AP_MODE
-static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
-{
- if (*ppie) {
- kfree(*ppie);
- *plen = 0;
- *ppie = NULL;
- }
-}
-#endif
-
-void rtw23a_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
-{
-#ifdef CONFIG_8723AU_AP_MODE
- kfree(pmlmepriv->assoc_req);
- kfree(pmlmepriv->assoc_rsp);
- rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie,
- &pmlmepriv->wps_probe_req_ie_len);
-#endif
-}
-
-void rtw_free_mlme_priv23a(struct mlme_priv *pmlmepriv)
-{
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "rtw_free_mlme_priv23a\n");
-
- rtw23a_free_mlme_priv_ie_data(pmlmepriv);
-}
-
-struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv, gfp_t gfp)
-{
- struct wlan_network *pnetwork;
-
- pnetwork = kzalloc(sizeof(struct wlan_network), gfp);
- if (pnetwork) {
- INIT_LIST_HEAD(&pnetwork->list);
- pnetwork->network_type = 0;
- pnetwork->fixed = false;
- pnetwork->last_scanned = jiffies;
- pnetwork->join_res = 0;
- }
-
- return pnetwork;
-}
-
-static void _rtw_free_network23a(struct mlme_priv *pmlmepriv,
- struct wlan_network *pnetwork)
-{
- if (!pnetwork)
- return;
-
- if (pnetwork->fixed == true)
- return;
-
- list_del_init(&pnetwork->list);
-
- kfree(pnetwork);
-}
-
-/*
- return the wlan_network with the matching addr
-
- Shall be called under atomic context... to avoid possible racing condition...
-*/
-struct wlan_network *
-rtw_find_network23a(struct rtw_queue *scanned_queue, u8 *addr)
-{
- struct list_head *phead, *plist;
- struct wlan_network *pnetwork = NULL;
-
- if (is_zero_ether_addr(addr)) {
- pnetwork = NULL;
- goto exit;
- }
-
- /* spin_lock_bh(&scanned_queue->lock); */
-
- phead = get_list_head(scanned_queue);
- plist = phead->next;
-
- while (plist != phead) {
- pnetwork = container_of(plist, struct wlan_network, list);
-
- if (ether_addr_equal(addr, pnetwork->network.MacAddress))
- break;
-
- plist = plist->next;
- }
-
- if (plist == phead)
- pnetwork = NULL;
-
- /* spin_unlock_bh(&scanned_queue->lock); */
-
-exit:
-
- return pnetwork;
-}
-
-void rtw_free_network_queue23a(struct rtw_adapter *padapter)
-{
- struct list_head *phead;
- struct wlan_network *pnetwork, *ptmp;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct rtw_queue *scanned_queue = &pmlmepriv->scanned_queue;
-
- spin_lock_bh(&scanned_queue->lock);
- phead = get_list_head(scanned_queue);
- list_for_each_entry_safe(pnetwork, ptmp, phead, list)
- _rtw_free_network23a(pmlmepriv, pnetwork);
- spin_unlock_bh(&scanned_queue->lock);
-}
-
-int rtw_if_up23a(struct rtw_adapter *padapter)
-{
- int res;
-
- if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
- !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "rtw_if_up23a:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
- padapter->bDriverStopped, padapter->bSurpriseRemoved);
- res = false;
- } else
- res = true;
-
- return res;
-}
-
-void rtw_generate_random_ibss23a(u8 *pibss)
-{
- unsigned long curtime = jiffies;
-
- pibss[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */
- pibss[1] = 0x11;
- pibss[2] = 0x87;
- pibss[3] = curtime & 0xff;/* p[0]; */
- pibss[4] = (curtime >> 8) & 0xff;/* p[1]; */
- pibss[5] = (curtime >> 16) & 0xff;/* p[2]; */
-}
-
-void rtw_set_roaming(struct rtw_adapter *adapter, u8 to_roaming)
-{
- if (to_roaming == 0)
- adapter->mlmepriv.to_join = false;
- adapter->mlmepriv.to_roaming = to_roaming;
-}
-
-static void _rtw_roaming(struct rtw_adapter *padapter,
- struct wlan_network *tgt_network)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_network *pnetwork;
- int do_join_r;
-
- if (tgt_network)
- pnetwork = tgt_network;
- else
- pnetwork = &pmlmepriv->cur_network;
-
- if (padapter->mlmepriv.to_roaming > 0) {
- DBG_8723A("roaming from %s(%pM), length:%d\n",
- pnetwork->network.Ssid.ssid,
- pnetwork->network.MacAddress,
- pnetwork->network.Ssid.ssid_len);
- memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid,
- sizeof(struct cfg80211_ssid));
-
- pmlmepriv->assoc_by_bssid = false;
-
- while (1) {
- do_join_r = rtw_do_join(padapter);
- if (do_join_r == _SUCCESS)
- break;
- else {
- DBG_8723A("roaming do_join return %d\n",
- do_join_r);
- pmlmepriv->to_roaming--;
-
- if (padapter->mlmepriv.to_roaming > 0)
- continue;
- else {
- DBG_8723A("%s(%d) -to roaming fail, "
- "indicate_disconnect\n",
- __func__, __LINE__);
- rtw_indicate_disconnect23a(padapter);
- break;
- }
- }
- }
- }
-}
-
-void rtw23a_roaming(struct rtw_adapter *padapter,
- struct wlan_network *tgt_network)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- spin_lock_bh(&pmlmepriv->lock);
- _rtw_roaming(padapter, tgt_network);
- spin_unlock_bh(&pmlmepriv->lock);
-}
-
-static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv,
- struct wlan_network *pnetwork)
-{
- _rtw_free_network23a(pmlmepriv, pnetwork);
-}
-
-bool rtw_is_same_ibss23a(struct rtw_adapter *adapter,
- struct wlan_network *pnetwork)
-{
- int ret;
- struct security_priv *psecuritypriv = &adapter->securitypriv;
-
- if (psecuritypriv->dot11PrivacyAlgrthm != 0 &&
- pnetwork->network.Privacy == 0)
- ret = false;
- else if (psecuritypriv->dot11PrivacyAlgrthm == 0 &&
- pnetwork->network.Privacy == 1)
- ret = false;
- else
- ret = true;
-
- return ret;
-}
-
-inline int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b);
-inline int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b)
-{
- return (a->Ssid.ssid_len == b->Ssid.ssid_len) &&
- !memcmp(a->Ssid.ssid, b->Ssid.ssid, a->Ssid.ssid_len);
-}
-
-int is_same_network23a(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst)
-{
- u16 s_cap, d_cap;
-
- s_cap = src->capability;
- d_cap = dst->capability;
-
- return ((src->Ssid.ssid_len == dst->Ssid.ssid_len) &&
- /* (src->DSConfig == dst->DSConfig) && */
- ether_addr_equal(src->MacAddress, dst->MacAddress) &&
- !memcmp(src->Ssid.ssid, dst->Ssid.ssid, src->Ssid.ssid_len) &&
- (s_cap & WLAN_CAPABILITY_IBSS) ==
- (d_cap & WLAN_CAPABILITY_IBSS) &&
- (s_cap & WLAN_CAPABILITY_ESS) == (d_cap & WLAN_CAPABILITY_ESS));
-}
-
-struct wlan_network *
-rtw_get_oldest_wlan_network23a(struct rtw_queue *scanned_queue)
-{
- struct list_head *phead;
- struct wlan_network *pwlan;
- struct wlan_network *oldest = NULL;
-
- phead = get_list_head(scanned_queue);
- list_for_each_entry(pwlan, phead, list) {
- if (pwlan->fixed != true) {
- if (!oldest || time_after(oldest->last_scanned,
- pwlan->last_scanned))
- oldest = pwlan;
- }
- }
-
- return oldest;
-}
-
-void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
- struct rtw_adapter *padapter, bool update_ie)
-{
- u8 ss_ori = dst->SignalStrength;
- u8 sq_ori = dst->SignalQuality;
- long rssi_ori = dst->Rssi;
-
- u8 ss_smp = src->SignalStrength;
- u8 sq_smp = src->SignalQuality;
- long rssi_smp = src->Rssi;
-
- u8 ss_final;
- u8 sq_final;
- long rssi_final;
-
- DBG_8723A("%s %s(%pM, ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, "
- "ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n",
- __func__, src->Ssid.ssid, src->MacAddress,
- src->DSConfig, ss_ori, sq_ori, rssi_ori,
- ss_smp, sq_smp, rssi_smp
- );
-
- /* The rule below is 1/5 for sample value, 4/5 for history value */
- if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) &&
- is_same_network23a(&padapter->mlmepriv.cur_network.network, src)) {
- /* Take the recvpriv's value for the connected AP*/
- ss_final = padapter->recvpriv.signal_strength;
- sq_final = padapter->recvpriv.signal_qual;
- /* the rssi value here is undecorated, and will be
- used for antenna diversity */
- if (sq_smp != 101) /* from the right channel */
- rssi_final = (src->Rssi+dst->Rssi*4)/5;
- else
- rssi_final = rssi_ori;
- } else {
- if (sq_smp != 101) { /* from the right channel */
- ss_final = ((u32)src->SignalStrength +
- (u32)dst->SignalStrength * 4) / 5;
- sq_final = ((u32)src->SignalQuality +
- (u32)dst->SignalQuality * 4) / 5;
- rssi_final = src->Rssi+dst->Rssi * 4 / 5;
- } else {
- /* bss info not receiving from the right channel, use
- the original RX signal infos */
- ss_final = dst->SignalStrength;
- sq_final = dst->SignalQuality;
- rssi_final = dst->Rssi;
- }
-
- }
-
- if (update_ie)
- memcpy(dst, src, get_wlan_bssid_ex_sz(src));
-
- dst->SignalStrength = ss_final;
- dst->SignalQuality = sq_final;
- dst->Rssi = rssi_final;
-
- DBG_8723A("%s %s(%pM), SignalStrength:%u, SignalQuality:%u, "
- "RawRSSI:%ld\n", __func__, dst->Ssid.ssid, dst->MacAddress,
- dst->SignalStrength, dst->SignalQuality, dst->Rssi);
-}
-
-static void update_current_network(struct rtw_adapter *adapter,
- struct wlan_bssid_ex *pnetwork)
-{
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
-
- if (check_fwstate(pmlmepriv, _FW_LINKED) &&
- is_same_network23a(&pmlmepriv->cur_network.network, pnetwork)) {
- update_network23a(&pmlmepriv->cur_network.network,
- pnetwork, adapter, true);
-
- rtw_update_protection23a(adapter,
- pmlmepriv->cur_network.network.IEs,
- pmlmepriv->cur_network.network.IELength);
- }
-}
-
-/*
-
-Caller must hold pmlmepriv->lock first.
-
-*/
-static void rtw_update_scanned_network(struct rtw_adapter *adapter,
- struct wlan_bssid_ex *target)
-{
- struct list_head *plist, *phead;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct wlan_network *pnetwork = NULL;
- struct wlan_network *oldest = NULL;
- struct rtw_queue *queue = &pmlmepriv->scanned_queue;
- u32 bssid_ex_sz;
- int found = 0;
-
- spin_lock_bh(&queue->lock);
- phead = get_list_head(queue);
- list_for_each(plist, phead) {
- pnetwork = container_of(plist, struct wlan_network, list);
-
- if (is_same_network23a(&pnetwork->network, target)) {
- found = 1;
- break;
- }
- if (!oldest || time_after(oldest->last_scanned,
- pnetwork->last_scanned))
- oldest = pnetwork;
- }
-
- /* If we didn't find a match, then get a new network slot to initialize
- * with this beacon's information */
- if (!found) {
- pnetwork = rtw_alloc_network(pmlmepriv, GFP_ATOMIC);
- if (!pnetwork) {
- if (!oldest) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "something wrong here\n");
- goto exit;
- }
- pnetwork = oldest;
- } else
- list_add_tail(&pnetwork->list, &queue->queue);
-
- bssid_ex_sz = get_wlan_bssid_ex_sz(target);
- target->Length = bssid_ex_sz;
- memcpy(&pnetwork->network, target, bssid_ex_sz);
-
- /* variable initialize */
- pnetwork->fixed = false;
- pnetwork->last_scanned = jiffies;
-
- pnetwork->network_type = 0;
- pnetwork->join_res = 0;
-
- /* bss info not receiving from the right channel */
- if (pnetwork->network.SignalQuality == 101)
- pnetwork->network.SignalQuality = 0;
- } else {
- /*
- * we have an entry and we are going to update it. But
- * this entry may be already expired. In this case we
- * do the same as we found a new net and call the
- * new_net handler
- */
- bool update_ie = true;
-
- pnetwork->last_scanned = jiffies;
-
- /* target.reserved == 1, means that scanned network is
- * a bcn frame. */
- if (pnetwork->network.IELength > target->IELength &&
- target->reserved == 1)
- update_ie = false;
-
- update_network23a(&pnetwork->network, target, adapter,
- update_ie);
- }
-
-exit:
- spin_unlock_bh(&queue->lock);
-}
-
-static void rtw_add_network(struct rtw_adapter *adapter,
- struct wlan_bssid_ex *pnetwork)
-{
- update_current_network(adapter, pnetwork);
- rtw_update_scanned_network(adapter, pnetwork);
-}
-
-/* select the desired network based on the capability of the (i)bss. */
-/* check items: (1) security */
-/* (2) network_type */
-/* (3) WMM */
-/* (4) HT */
-/* (5) others */
-static int rtw_is_desired_network(struct rtw_adapter *adapter,
- struct wlan_network *pnetwork)
-{
- struct security_priv *psecuritypriv = &adapter->securitypriv;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- u32 desired_encmode;
- u32 privacy;
- int bselected = true;
-
- desired_encmode = psecuritypriv->ndisencryptstatus;
- privacy = pnetwork->network.Privacy;
-
- if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
- if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WPA,
- pnetwork->network.IEs,
- pnetwork->network.IELength))
- return true;
- else
- return false;
- }
- if (adapter->registrypriv.wifi_spec == 1) {
- /* for correct flow of 8021X to do.... */
- if (desired_encmode == Ndis802_11EncryptionDisabled &&
- privacy != 0)
- bselected = false;
- }
-
- if (desired_encmode != Ndis802_11EncryptionDisabled && privacy == 0) {
- DBG_8723A("desired_encmode: %d, privacy: %d\n",
- desired_encmode, privacy);
- bselected = false;
- }
-
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
- if (pnetwork->network.ifmode !=
- pmlmepriv->cur_network.network.ifmode)
- bselected = false;
- }
-
- return bselected;
-}
-
-void rtw_survey_event_cb23a(struct rtw_adapter *adapter, const u8 *pbuf)
-{
- u32 len;
- struct wlan_bssid_ex *pnetwork;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct survey_event *survey = (struct survey_event *)pbuf;
-
- pnetwork = survey->bss;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "rtw_survey_event_cb23a, ssid=%s\n", pnetwork->Ssid.ssid);
-
- len = get_wlan_bssid_ex_sz(pnetwork);
- if (len > (sizeof(struct wlan_bssid_ex))) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "****rtw_survey_event_cb23a: return a wrong bss ***\n");
- return;
- }
-
- spin_lock_bh(&pmlmepriv->lock);
-
- /* update IBSS_network 's timestamp */
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
- if (ether_addr_equal(pmlmepriv->cur_network.network.MacAddress,
- pnetwork->MacAddress)) {
- struct wlan_network *ibss_wlan;
-
- pmlmepriv->cur_network.network.beacon_interval =
- pnetwork->beacon_interval;
- pmlmepriv->cur_network.network.capability =
- pnetwork->capability;
- pmlmepriv->cur_network.network.tsf = pnetwork->tsf;
- spin_lock_bh(&pmlmepriv->scanned_queue.lock);
- ibss_wlan = rtw_find_network23a(
- &pmlmepriv->scanned_queue,
- pnetwork->MacAddress);
- if (ibss_wlan) {
- pmlmepriv->cur_network.network.beacon_interval =
- ibss_wlan->network.beacon_interval;
- pmlmepriv->cur_network.network.capability =
- ibss_wlan->network.capability;
- pmlmepriv->cur_network.network.tsf =
- ibss_wlan->network.tsf;
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
- goto exit;
- }
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
- }
- }
-
- /* lock pmlmepriv->lock when you accessing network_q */
- if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
- if (pnetwork->Ssid.ssid[0] == 0)
- pnetwork->Ssid.ssid_len = 0;
-
- rtw_add_network(adapter, pnetwork);
- }
-
-exit:
-
- spin_unlock_bh(&pmlmepriv->lock);
-
- kfree(survey->bss);
- survey->bss = NULL;
-}
-
-void
-rtw_surveydone_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
-{
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
- int ret;
-
- spin_lock_bh(&pmlmepriv->lock);
-
- if (pmlmepriv->wps_probe_req_ie) {
- pmlmepriv->wps_probe_req_ie_len = 0;
- kfree(pmlmepriv->wps_probe_req_ie);
- pmlmepriv->wps_probe_req_ie = NULL;
- }
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "rtw_surveydone_event_callback23a: fw_state:%x\n",
- get_fwstate(pmlmepriv));
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
- del_timer_sync(&pmlmepriv->scan_to_timer);
-
- _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
- } else {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "nic status =%x, survey done event comes too late!\n",
- get_fwstate(pmlmepriv));
- }
-
- rtw_set_signal_stat_timer(&adapter->recvpriv);
-
- if (pmlmepriv->to_join == true) {
- set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
- ret = rtw_select_and_join_from_scanned_queue23a(
- pmlmepriv);
- if (ret != _SUCCESS)
- rtw_do_join_adhoc(adapter);
- } else {
- pmlmepriv->to_join = false;
- ret = rtw_select_and_join_from_scanned_queue23a(
- pmlmepriv);
- if (ret != _SUCCESS) {
- DBG_8723A("try_to_join, but select scanning "
- "queue fail, to_roaming:%d\n",
- adapter->mlmepriv.to_roaming);
- if (adapter->mlmepriv.to_roaming) {
- if (--pmlmepriv->to_roaming == 0 ||
- rtw_sitesurvey_cmd23a(
- adapter,
- &pmlmepriv->assoc_ssid, 1,
- NULL, 0) != _SUCCESS) {
- rtw_set_roaming(adapter, 0);
- rtw_free_assoc_resources23a(
- adapter, 1);
- rtw_indicate_disconnect23a(
- adapter);
- } else
- pmlmepriv->to_join = true;
- }
- _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
- }
- }
- }
-
- spin_unlock_bh(&pmlmepriv->lock);
-
- rtw_os_xmit_schedule23a(adapter);
-
- if (pmlmeext->sitesurvey_res.bss_cnt == 0)
- rtw_sreset_reset(adapter);
-
- rtw_cfg80211_surveydone_event_callback(adapter);
-}
-
-static void free_scanqueue(struct mlme_priv *pmlmepriv)
-{
- struct wlan_network *pnetwork, *ptemp;
- struct rtw_queue *scan_queue = &pmlmepriv->scanned_queue;
- struct list_head *phead;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, "+free_scanqueue\n");
- spin_lock_bh(&scan_queue->lock);
- phead = get_list_head(scan_queue);
- list_for_each_entry_safe(pnetwork, ptemp, phead, list) {
- pnetwork->fixed = false;
- _rtw_free_network23a(pmlmepriv, pnetwork);
- }
- spin_unlock_bh(&scan_queue->lock);
-}
-
-/*
- *rtw_free_assoc_resources23a: the caller has to lock pmlmepriv->lock
- */
-void rtw_free_assoc_resources23a(struct rtw_adapter *adapter,
- int lock_scanned_queue)
-{
- struct wlan_network *pwlan;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct sta_priv *pstapriv = &adapter->stapriv;
- struct wlan_network *tgt_network = &pmlmepriv->cur_network;
- struct sta_info *psta;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
- "+rtw_free_assoc_resources23a\n");
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "tgt_network->network.MacAddress=%pM ssid=%s\n",
- tgt_network->network.MacAddress,
- tgt_network->network.Ssid.ssid);
-
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE)) {
- psta = rtw_get_stainfo23a(&adapter->stapriv,
- tgt_network->network.MacAddress);
-
- spin_lock_bh(&pstapriv->sta_hash_lock);
- rtw_free_stainfo23a(adapter, psta);
- spin_unlock_bh(&pstapriv->sta_hash_lock);
- }
-
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE |
- WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) {
- rtw_free_all_stainfo23a(adapter);
-
- psta = rtw_get_bcmc_stainfo23a(adapter);
- spin_lock_bh(&pstapriv->sta_hash_lock);
- rtw_free_stainfo23a(adapter, psta);
- spin_unlock_bh(&pstapriv->sta_hash_lock);
-
- rtw_init_bcmc_stainfo23a(adapter);
- }
-
- if (lock_scanned_queue)
- spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
- pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
- tgt_network->network.MacAddress);
- if (pwlan)
- pwlan->fixed = false;
- else
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "rtw_free_assoc_resources23a : pwlan== NULL\n");
-
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) &&
- adapter->stapriv.asoc_sta_count == 1)
- rtw_free_network_nolock(pmlmepriv, pwlan);
-
- if (lock_scanned_queue)
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
- pmlmepriv->key_mask = 0;
-}
-
-/*
-*rtw_indicate_connect23a: the caller has to lock pmlmepriv->lock
-*/
-void rtw_indicate_connect23a(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "+rtw_indicate_connect23a\n");
-
- pmlmepriv->to_join = false;
-
- if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
- set_fwstate(pmlmepriv, _FW_LINKED);
-
- rtw_cfg80211_indicate_connect(padapter);
-
- netif_carrier_on(padapter->pnetdev);
-
- if (padapter->pid[2] != 0)
- kill_pid(find_vpid(padapter->pid[2]), SIGALRM, 1);
- }
-
- rtw_set_roaming(padapter, 0);
-
- rtw_set_scan_deny(padapter, 3000);
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "-rtw_indicate_connect23a: fw_state=0x%08x\n",
- get_fwstate(pmlmepriv));
-}
-
-/*
- *rtw_indicate_disconnect23a: the caller has to lock pmlmepriv->lock
- */
-void rtw_indicate_disconnect23a(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "+rtw_indicate_disconnect23a\n");
-
- _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS);
-
- /* DBG_8723A("clear wps when %s\n", __func__); */
-
- if (padapter->mlmepriv.to_roaming > 0)
- _clr_fwstate_(pmlmepriv, _FW_LINKED);
-
- if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) ||
- padapter->mlmepriv.to_roaming <= 0) {
- rtw_os_indicate_disconnect23a(padapter);
-
- /* set ips_deny_time to avoid enter IPS before LPS leave */
- padapter->pwrctrlpriv.ips_deny_time =
- jiffies + msecs_to_jiffies(3000);
-
- _clr_fwstate_(pmlmepriv, _FW_LINKED);
-
- rtw_clear_scan_deny(padapter);
- }
-
- rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_DISCONNECT, 1);
-}
-
-void rtw_scan_abort23a(struct rtw_adapter *adapter)
-{
- unsigned long start;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
-
- start = jiffies;
- pmlmeext->scan_abort = true;
- while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) &&
- jiffies_to_msecs(jiffies - start) <= 200) {
- if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
- break;
-
- DBG_8723A("%s(%s): fw_state = _FW_UNDER_SURVEY!\n",
- __func__, adapter->pnetdev->name);
- msleep(20);
- }
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
- if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved)
- DBG_8723A("%s(%s): waiting for scan_abort time out!\n",
- __func__, adapter->pnetdev->name);
- rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter->rtw_wdev),
- true);
- }
- pmlmeext->scan_abort = false;
-}
-
-static struct sta_info *
-rtw_joinbss_update_stainfo(struct rtw_adapter *padapter,
- struct wlan_network *pnetwork)
-{
- int i;
- struct sta_info *bmc_sta, *psta;
- struct recv_reorder_ctrl *preorder_ctrl;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- psta = rtw_get_stainfo23a(pstapriv, pnetwork->network.MacAddress);
- if (!psta)
- psta = rtw_alloc_stainfo23a(pstapriv,
- pnetwork->network.MacAddress,
- GFP_ATOMIC);
-
- if (psta) { /* update ptarget_sta */
- DBG_8723A("%s\n", __func__);
-
- psta->aid = pnetwork->join_res;
- psta->mac_id = 0;
-
- /* sta mode */
- rtl8723a_SetHalODMVar(padapter, HAL_ODM_STA_INFO, psta, true);
-
- /* security related */
- if (padapter->securitypriv.dot11AuthAlgrthm ==
- dot11AuthAlgrthm_8021X) {
- padapter->securitypriv.binstallGrpkey = 0;
- padapter->securitypriv.busetkipkey = 0;
-
- psta->ieee8021x_blocked = true;
- psta->dot118021XPrivacy =
- padapter->securitypriv.dot11PrivacyAlgrthm;
-
- memset(&psta->dot118021x_UncstKey, 0,
- sizeof (union Keytype));
-
- memset(&psta->dot11tkiprxmickey, 0,
- sizeof (union Keytype));
- memset(&psta->dot11tkiptxmickey, 0,
- sizeof (union Keytype));
-
- memset(&psta->dot11txpn, 0, sizeof (union pn48));
- memset(&psta->dot11rxpn, 0, sizeof (union pn48));
- }
-
- /* Commented by Albert 2012/07/21 */
- /* When doing the WPS, the wps_ie_len won't equal to 0 */
- /* And the Wi-Fi driver shouldn't allow the data packet
- to be transmitted. */
- if (padapter->securitypriv.wps_ie_len != 0) {
- psta->ieee8021x_blocked = true;
- padapter->securitypriv.wps_ie_len = 0;
- }
-
- /* for A-MPDU Rx reordering buffer control for bmc_sta &
- * sta_info */
- /* if A-MPDU Rx is enabled, resetting
- rx_ordering_ctrl wstart_b(indicate_seq) to default
- value = 0xffff */
- /* todo: check if AP can send A-MPDU packets */
- for (i = 0; i < 16 ; i++) {
- /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
- preorder_ctrl = &psta->recvreorder_ctrl[i];
- preorder_ctrl->enable = false;
- preorder_ctrl->indicate_seq = 0xffff;
- preorder_ctrl->wend_b = 0xffff;
- /* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
- preorder_ctrl->wsize_b = 64;
- }
-
- bmc_sta = rtw_get_bcmc_stainfo23a(padapter);
- if (bmc_sta) {
- for (i = 0; i < 16 ; i++) {
- preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
- preorder_ctrl->enable = false;
- preorder_ctrl->indicate_seq = 0xffff;
- preorder_ctrl->wend_b = 0xffff;
- /* max_ampdu_sz; ex. 32(kbytes) ->
- wsize_b = 32 */
- preorder_ctrl->wsize_b = 64;
- }
- }
-
- /* misc. */
- update_sta_info23a(padapter, psta);
-
- }
-
- return psta;
-}
-
-/* pnetwork : returns from rtw23a_joinbss_event_cb */
-/* ptarget_wlan: found from scanned_queue */
-static void
-rtw_joinbss_update_network23a(struct rtw_adapter *padapter,
- struct wlan_network *ptarget_wlan,
- struct wlan_network *pnetwork)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_network *cur_network = &pmlmepriv->cur_network;
-
- DBG_8723A("%s\n", __func__);
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "fw_state:%x, BSSID:%pM\n",
- get_fwstate(pmlmepriv),
- pnetwork->network.MacAddress);
-
- /* why not use ptarget_wlan?? */
- memcpy(&cur_network->network, &pnetwork->network,
- pnetwork->network.Length);
- /* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
- cur_network->network.IELength = ptarget_wlan->network.IELength;
- memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0],
- MAX_IE_SZ);
-
- cur_network->network.capability = ptarget_wlan->network.capability;
- cur_network->network.beacon_interval =
- ptarget_wlan->network.beacon_interval;
- cur_network->network.tsf = ptarget_wlan->network.tsf;
-
- rtw_set_signal_stat_timer(&padapter->recvpriv);
- padapter->recvpriv.signal_strength =
- ptarget_wlan->network.SignalStrength;
- padapter->recvpriv.signal_qual = ptarget_wlan->network.SignalQuality;
- /*
- * the ptarget_wlan->network.Rssi is raw data, we use
- * ptarget_wlan->network.SignalStrength instead (has scaled)
- */
- DBG_8723A("%s signal_strength:%3u, signal_qual:%3u\n",
- __func__, padapter->recvpriv.signal_strength,
- padapter->recvpriv.signal_qual);
- rtw_set_signal_stat_timer(&padapter->recvpriv);
-
- /* update fw_state will clr _FW_UNDER_LINKING here indirectly */
- switch (pnetwork->network.ifmode) {
- case NL80211_IFTYPE_P2P_CLIENT:
- case NL80211_IFTYPE_STATION:
- if (pmlmepriv->fw_state & WIFI_UNDER_WPS)
- pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS;
- else
- pmlmepriv->fw_state = WIFI_STATION_STATE;
- break;
- case NL80211_IFTYPE_ADHOC:
- pmlmepriv->fw_state = WIFI_ADHOC_STATE;
- break;
- default:
- pmlmepriv->fw_state = WIFI_NULL_STATE;
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "Invalid network_mode\n");
- break;
- }
-
- rtw_update_protection23a(padapter, cur_network->network.IEs,
- cur_network->network.IELength);
-
- rtw_update_ht_cap23a(padapter, cur_network->network.IEs,
- cur_network->network.IELength);
-}
-
-/*
- * Notes:
- * the function could be > passive_level (the same context as Rx tasklet)
- * pnetwork : returns from rtw23a_joinbss_event_cb
- * ptarget_wlan: found from scanned_queue
- * if join_res > 0, for (fw_state==WIFI_STATION_STATE),
- * we check if "ptarget_sta" & "ptarget_wlan" exist.
- * if join_res > 0, for (fw_state==WIFI_ADHOC_STATE),
- * we only check if "ptarget_wlan" exist.
- * if join_res > 0, update "cur_network->network" from "pnetwork->network"
- * if (ptarget_wlan !=NULL).
- */
-
-void rtw_joinbss_event_prehandle23a(struct rtw_adapter *adapter, u8 *pbuf)
-{
- struct sta_info *ptarget_sta, *pcur_sta;
- struct sta_priv *pstapriv = &adapter->stapriv;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
- struct wlan_network *cur_network = &pmlmepriv->cur_network;
- struct wlan_network *pcur_wlan, *ptarget_wlan = NULL;
- bool the_same_macaddr;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "joinbss event call back received with res=%d\n",
- pnetwork->join_res);
-
- if (pmlmepriv->assoc_ssid.ssid_len == 0) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "@@@@@ joinbss event call back for Any SSid\n");
- } else {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "@@@@@ rtw23a_joinbss_event_cb for SSid:%s\n",
- pmlmepriv->assoc_ssid.ssid);
- }
-
- if (ether_addr_equal(pnetwork->network.MacAddress,
- cur_network->network.MacAddress))
- the_same_macaddr = true;
- else
- the_same_macaddr = false;
-
- pnetwork->network.Length = get_wlan_bssid_ex_sz(&pnetwork->network);
- if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex)) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "***joinbss_evt_callback return a wrong bss ***\n");
- return;
- }
-
- spin_lock_bh(&pmlmepriv->lock);
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "rtw23a_joinbss_event_cb !! _enter_critical\n");
-
- if (pnetwork->join_res > 0) {
- spin_lock_bh(&pmlmepriv->scanned_queue.lock);
- if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
- /* s1. find ptarget_wlan */
- if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- if (the_same_macaddr) {
- ptarget_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
- } else {
- pcur_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
- if (pcur_wlan)
- pcur_wlan->fixed = false;
-
- pcur_sta = rtw_get_stainfo23a(pstapriv, cur_network->network.MacAddress);
- if (pcur_sta) {
- spin_lock_bh(&pstapriv->sta_hash_lock);
- rtw_free_stainfo23a(adapter,
- pcur_sta);
- spin_unlock_bh(&pstapriv->sta_hash_lock);
- }
-
- ptarget_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
- if (check_fwstate(pmlmepriv,
- WIFI_STATION_STATE)) {
- if (ptarget_wlan)
- ptarget_wlan->fixed =
- true;
- }
- }
-
- } else {
- ptarget_wlan = rtw_find_network23a(
- &pmlmepriv->scanned_queue,
- pnetwork->network.MacAddress);
- if (check_fwstate(pmlmepriv,
- WIFI_STATION_STATE)) {
- if (ptarget_wlan)
- ptarget_wlan->fixed = true;
- }
- }
-
- /* s2. update cur_network */
- if (ptarget_wlan)
- rtw_joinbss_update_network23a(adapter,
- ptarget_wlan,
- pnetwork);
- else {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "Can't find ptarget_wlan when joinbss_event callback\n");
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
- goto ignore_joinbss_callback;
- }
-
- /* s3. find ptarget_sta & update ptarget_sta after
- update cur_network only for station mode */
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
- ptarget_sta = rtw_joinbss_update_stainfo(
- adapter, pnetwork);
- if (!ptarget_sta) {
- RT_TRACE(_module_rtl871x_mlme_c_,
- _drv_err_,
- "Can't update stainfo when joinbss_event callback\n");
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
- goto ignore_joinbss_callback;
- }
- }
-
- /* s4. indicate connect */
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
- rtw_indicate_connect23a(adapter);
- else {
- /* adhoc mode will rtw_indicate_connect23a
- when rtw_stassoc_event_callback23a */
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "adhoc mode, fw_state:%x\n",
- get_fwstate(pmlmepriv));
- }
-
- /* s5. Cancle assoc_timer */
- del_timer_sync(&pmlmepriv->assoc_timer);
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "Cancle assoc_timer\n");
- } else {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "rtw23a_joinbss_event_cb err: fw_state:%x\n",
- get_fwstate(pmlmepriv));
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
- goto ignore_joinbss_callback;
- }
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
- } else if (pnetwork->join_res == -4) {
- rtw_reset_securitypriv23a(adapter);
- mod_timer(&pmlmepriv->assoc_timer,
- jiffies + msecs_to_jiffies(1));
-
- /* rtw_free_assoc_resources23a(adapter, 1); */
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n",
- get_fwstate(pmlmepriv));
- _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
- }
- } else {
- /* if join_res < 0 (join fails), then try again */
- mod_timer(&pmlmepriv->assoc_timer,
- jiffies + msecs_to_jiffies(1));
- _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
- }
-
-ignore_joinbss_callback:
-
- spin_unlock_bh(&pmlmepriv->lock);
-}
-
-void rtw23a_joinbss_event_cb(struct rtw_adapter *adapter, const u8 *pbuf)
-{
- struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
-
- mlmeext_joinbss_event_callback23a(adapter, pnetwork->join_res);
-
- rtw_os_xmit_schedule23a(adapter);
-}
-
-void rtw_stassoc_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
-{
- struct sta_info *psta;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf;
- struct wlan_network *cur_network = &pmlmepriv->cur_network;
- struct wlan_network *ptarget_wlan;
-
- if (rtw_access_ctrl23a(adapter, pstassoc->macaddr) == false)
- return;
-
-#ifdef CONFIG_8723AU_AP_MODE
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
- psta = rtw_get_stainfo23a(&adapter->stapriv, pstassoc->macaddr);
- if (psta) {
- /* bss_cap_update_on_sta_join23a(adapter, psta); */
- /* sta_info_update23a(adapter, psta); */
- ap_sta_info_defer_update23a(adapter, psta);
- }
- return;
- }
-#endif
- /* for AD-HOC mode */
- psta = rtw_get_stainfo23a(&adapter->stapriv, pstassoc->macaddr);
- if (psta != NULL) {
- /* the sta have been in sta_info_queue => do nothing */
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "Error: rtw_stassoc_event_callback23a: sta has been in sta_hash_queue\n");
- /* between drv has received this event before and
- fw have not yet to set key to CAM_ENTRY) */
- return;
- }
-
- psta = rtw_alloc_stainfo23a(&adapter->stapriv, pstassoc->macaddr,
- GFP_KERNEL);
- if (!psta) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "Can't alloc sta_info when rtw_stassoc_event_callback23a\n");
- return;
- }
-
- /* to do : init sta_info variable */
- psta->qos_option = 0;
- psta->mac_id = (uint)pstassoc->cam_id;
- /* psta->aid = (uint)pstassoc->cam_id; */
- DBG_8723A("%s\n", __func__);
- /* for ad-hoc mode */
- rtl8723a_SetHalODMVar(adapter, HAL_ODM_STA_INFO, psta, true);
-
- if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
- psta->dot118021XPrivacy =
- adapter->securitypriv.dot11PrivacyAlgrthm;
-
- psta->ieee8021x_blocked = false;
-
- spin_lock_bh(&pmlmepriv->lock);
-
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
- if (adapter->stapriv.asoc_sta_count == 2) {
- spin_lock_bh(&pmlmepriv->scanned_queue.lock);
- ptarget_wlan =
- rtw_find_network23a(&pmlmepriv->scanned_queue,
- cur_network->network.MacAddress);
- if (ptarget_wlan)
- ptarget_wlan->fixed = true;
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
- /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
- rtw_indicate_connect23a(adapter);
- }
- }
-
- spin_unlock_bh(&pmlmepriv->lock);
-
- mlmeext_sta_add_event_callback23a(adapter, psta);
-}
-
-void rtw_stadel_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
-{
- int mac_id;
- struct sta_info *psta;
- struct wlan_network *pwlan;
- struct wlan_bssid_ex *pdev_network;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct stadel_event *pstadel = (struct stadel_event *)pbuf;
- struct sta_priv *pstapriv = &adapter->stapriv;
- struct wlan_network *tgt_network = &pmlmepriv->cur_network;
-
- psta = rtw_get_stainfo23a(&adapter->stapriv, pstadel->macaddr);
- if (psta)
- mac_id = psta->mac_id;
- else
- mac_id = pstadel->mac_id;
-
- DBG_8723A("%s(mac_id=%d)=%pM\n", __func__, mac_id, pstadel->macaddr);
-
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
- return;
-
- mlmeext_sta_del_event_callback23a(adapter);
-
- spin_lock_bh(&pmlmepriv->lock);
-
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
- if (adapter->mlmepriv.to_roaming > 0) {
- /* this stadel_event is caused by roaming,
- decrease to_roaming */
- pmlmepriv->to_roaming--;
- } else if (adapter->mlmepriv.to_roaming == 0)
- rtw_set_roaming(adapter, adapter->registrypriv.max_roaming_times);
- if (*((u16 *)pstadel->rsvd) != WLAN_REASON_EXPIRATION_CHK)
- rtw_set_roaming(adapter, 0); /* don't roam */
-
- rtw_free_uc_swdec_pending_queue23a(adapter);
-
- rtw_free_assoc_resources23a(adapter, 1);
- rtw_indicate_disconnect23a(adapter);
- spin_lock_bh(&pmlmepriv->scanned_queue.lock);
- /* remove the network entry in scanned_queue */
- pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
- tgt_network->network.MacAddress);
- if (pwlan) {
- pwlan->fixed = false;
- rtw_free_network_nolock(pmlmepriv, pwlan);
- }
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
- _rtw_roaming(adapter, tgt_network);
- }
-
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
-
- spin_lock_bh(&pstapriv->sta_hash_lock);
- rtw_free_stainfo23a(adapter, psta);
- spin_unlock_bh(&pstapriv->sta_hash_lock);
-
- /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
- if (adapter->stapriv.asoc_sta_count == 1) {
- spin_lock_bh(&pmlmepriv->scanned_queue.lock);
- /* free old ibss network */
- /* pwlan = rtw_find_network23a(
- &pmlmepriv->scanned_queue, pstadel->macaddr); */
- pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
- tgt_network->network.MacAddress);
- if (pwlan) {
- pwlan->fixed = false;
- rtw_free_network_nolock(pmlmepriv, pwlan);
- }
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
- /* re-create ibss */
- pdev_network = &adapter->registrypriv.dev_network;
-
- memcpy(pdev_network, &tgt_network->network,
- get_wlan_bssid_ex_sz(&tgt_network->network));
-
- rtw_do_join_adhoc(adapter);
- }
- }
-
- spin_unlock_bh(&pmlmepriv->lock);
-}
-
-/*
-* rtw23a_join_to_handler - Timeout/failure handler for CMD JoinBss
-* @adapter: pointer to _adapter structure
-*/
-void rtw23a_join_to_handler (unsigned long data)
-{
- struct rtw_adapter *adapter = (struct rtw_adapter *)data;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- int do_join_r;
-
- DBG_8723A("%s, fw_state=%x\n", __func__, get_fwstate(pmlmepriv));
-
- if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
- return;
-
- spin_lock_bh(&pmlmepriv->lock);
-
- if (adapter->mlmepriv.to_roaming > 0) {
- /* join timeout caused by roaming */
- while (1) {
- pmlmepriv->to_roaming--;
- if (adapter->mlmepriv.to_roaming != 0) {
- /* try another */
- DBG_8723A("%s try another roaming\n", __func__);
- do_join_r = rtw_do_join(adapter);
- if (do_join_r != _SUCCESS) {
- DBG_8723A("%s roaming do_join return "
- "%d\n", __func__ , do_join_r);
- continue;
- }
- break;
- } else {
- DBG_8723A("%s We've try roaming but fail\n",
- __func__);
- rtw_indicate_disconnect23a(adapter);
- break;
- }
- }
- } else {
- rtw_indicate_disconnect23a(adapter);
- free_scanqueue(pmlmepriv);/* */
-
- /* indicate disconnect for the case that join_timeout and
- check_fwstate != FW_LINKED */
- rtw_cfg80211_indicate_disconnect(adapter);
- }
-
- spin_unlock_bh(&pmlmepriv->lock);
-
-}
-
-/*
-* rtw_scan_timeout_handler23a - Timeout/Failure handler for CMD SiteSurvey
-* @data: pointer to _adapter structure
-*/
-void rtw_scan_timeout_handler23a(unsigned long data)
-{
- struct rtw_adapter *adapter = (struct rtw_adapter *)data;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
-
- DBG_8723A("%s(%s): fw_state =%x\n", __func__, adapter->pnetdev->name,
- get_fwstate(pmlmepriv));
-
- spin_lock_bh(&pmlmepriv->lock);
-
- _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
-
- spin_unlock_bh(&pmlmepriv->lock);
-
- rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter->rtw_wdev), true);
-}
-
-void rtw_dynamic_check_timer_handler(unsigned long data)
-{
- struct rtw_adapter *adapter = (struct rtw_adapter *)data;
-
- if (adapter->hw_init_completed == false)
- goto out;
-
- if (adapter->bDriverStopped == true ||
- adapter->bSurpriseRemoved == true)
- goto out;
-
- if (adapter->net_closed == true)
- goto out;
-
- rtw_dynamic_chk_wk_cmd23a(adapter);
-
-out:
- mod_timer(&adapter->mlmepriv.dynamic_chk_timer,
- jiffies + msecs_to_jiffies(2000));
-}
-
-inline bool rtw_is_scan_deny(struct rtw_adapter *adapter)
-{
- struct mlme_priv *mlmepriv = &adapter->mlmepriv;
-
- return (atomic_read(&mlmepriv->set_scan_deny) != 0) ? true : false;
-}
-
-void rtw_clear_scan_deny(struct rtw_adapter *adapter)
-{
- struct mlme_priv *mlmepriv = &adapter->mlmepriv;
-
- atomic_set(&mlmepriv->set_scan_deny, 0);
-}
-
-void rtw_set_scan_deny_timer_hdl(unsigned long data)
-{
- struct rtw_adapter *adapter = (struct rtw_adapter *)data;
-
- rtw_clear_scan_deny(adapter);
-}
-
-void rtw_set_scan_deny(struct rtw_adapter *adapter, u32 ms)
-{
- struct mlme_priv *mlmepriv = &adapter->mlmepriv;
-
- atomic_set(&mlmepriv->set_scan_deny, 1);
- mod_timer(&mlmepriv->set_scan_deny_timer,
- jiffies + msecs_to_jiffies(ms));
-}
-
-#if defined(IEEE80211_SCAN_RESULT_EXPIRE)
-#define RTW_SCAN_RESULT_EXPIRE \
- ((IEEE80211_SCAN_RESULT_EXPIRE / (HZ*1000)) - 1000) /* 3000 -1000 */
-#else
-#define RTW_SCAN_RESULT_EXPIRE 2000
-#endif
-
-/*
-* Select a new join candidate from the original @param candidate and
-* @param competitor
-* @return true: candidate is updated
-* @return false: candidate is not updated
-*/
-static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv,
- struct wlan_network **candidate,
- struct wlan_network *competitor)
-{
- int updated = false;
- struct rtw_adapter *adapter;
-
- adapter = container_of(pmlmepriv, struct rtw_adapter, mlmepriv);
-
- /* check bssid, if needed */
- if (pmlmepriv->assoc_by_bssid == true) {
- if (!ether_addr_equal(competitor->network.MacAddress,
- pmlmepriv->assoc_bssid))
- goto exit;
- }
-
- /* check ssid, if needed */
- if (pmlmepriv->assoc_ssid.ssid_len) {
- if (competitor->network.Ssid.ssid_len !=
- pmlmepriv->assoc_ssid.ssid_len ||
- memcmp(competitor->network.Ssid.ssid,
- pmlmepriv->assoc_ssid.ssid,
- pmlmepriv->assoc_ssid.ssid_len))
- goto exit;
- }
-
- if (rtw_is_desired_network(adapter, competitor) == false)
- goto exit;
-
- if (adapter->mlmepriv.to_roaming > 0) {
- unsigned int passed;
-
- passed = jiffies_to_msecs(jiffies - competitor->last_scanned);
- if (passed >= RTW_SCAN_RESULT_EXPIRE ||
- is_same_ess(&competitor->network,
- &pmlmepriv->cur_network.network) == false)
- goto exit;
- }
-
- if (!*candidate ||
- (*candidate)->network.Rssi<competitor->network.Rssi) {
- *candidate = competitor;
- updated = true;
- }
-
- if (updated) {
- DBG_8723A("[by_bssid:%u][assoc_ssid:%s][to_roaming:%u] new candidate: %s(%pM) rssi:%d\n",
- pmlmepriv->assoc_by_bssid,
- pmlmepriv->assoc_ssid.ssid,
- adapter->mlmepriv.to_roaming,
- (*candidate)->network.Ssid.ssid,
- (*candidate)->network.MacAddress,
- (int)(*candidate)->network.Rssi);
- }
-
-exit:
- return updated;
-}
-
-/*
-Calling context:
-The caller of the sub-routine will be in critical section...
-
-The caller must hold the following spinlock
-
-pmlmepriv->lock
-
-*/
-
-static int rtw_do_join(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- int ret;
-
- pmlmepriv->cur_network.join_res = -2;
-
- set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
-
- pmlmepriv->to_join = true;
-
- ret = rtw_select_and_join_from_scanned_queue23a(pmlmepriv);
- if (ret == _SUCCESS) {
- pmlmepriv->to_join = false;
- } else {
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
- /* switch to ADHOC_MASTER */
- ret = rtw_do_join_adhoc(padapter);
- if (ret != _SUCCESS)
- goto exit;
- } else {
- /* can't associate ; reset under-linking */
- _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
-
- ret = _FAIL;
- pmlmepriv->to_join = false;
- }
- }
-
-exit:
- return ret;
-}
-
-static struct wlan_network *
-rtw_select_candidate_from_queue(struct mlme_priv *pmlmepriv)
-{
- struct wlan_network *pnetwork, *ptmp, *candidate = NULL;
- struct rtw_queue *queue = &pmlmepriv->scanned_queue;
- struct list_head *phead;
-
- spin_lock_bh(&pmlmepriv->scanned_queue.lock);
- phead = get_list_head(queue);
- list_for_each_entry_safe(pnetwork, ptmp, phead, list)
- rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
- return candidate;
-}
-
-
-int rtw_do_join_adhoc(struct rtw_adapter *adapter)
-{
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct wlan_bssid_ex *pdev_network;
- u8 *ibss;
- int ret;
-
- pdev_network = &adapter->registrypriv.dev_network;
- ibss = adapter->registrypriv.dev_network.MacAddress;
-
- _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "switching to adhoc master\n");
-
- memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid,
- sizeof(struct cfg80211_ssid));
-
- rtw_update_registrypriv_dev_network23a(adapter);
- rtw_generate_random_ibss23a(ibss);
-
- pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
-
- ret = rtw_createbss_cmd23a(adapter);
- if (ret != _SUCCESS) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "Error =>rtw_createbss_cmd23a status FAIL\n");
- } else {
- pmlmepriv->to_join = false;
- }
-
- return ret;
-}
-
-int rtw_do_join_network(struct rtw_adapter *adapter,
- struct wlan_network *candidate)
-{
- int ret;
-
- /* check for situation of _FW_LINKED */
- if (check_fwstate(&adapter->mlmepriv, _FW_LINKED)) {
- DBG_8723A("%s: _FW_LINKED while ask_for_joinbss!\n", __func__);
-
- rtw_disassoc_cmd23a(adapter, 0, true);
- rtw_indicate_disconnect23a(adapter);
- rtw_free_assoc_resources23a(adapter, 0);
- }
- set_fwstate(&adapter->mlmepriv, _FW_UNDER_LINKING);
-
- ret = rtw_joinbss_cmd23a(adapter, candidate);
-
- if (ret == _SUCCESS)
- mod_timer(&adapter->mlmepriv.assoc_timer,
- jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
-
- return ret;
-}
-
-int rtw_select_and_join_from_scanned_queue23a(struct mlme_priv *pmlmepriv)
-{
- struct rtw_adapter *adapter;
- struct wlan_network *candidate = NULL;
- int ret;
-
- adapter = pmlmepriv->nic_hdl;
-
- candidate = rtw_select_candidate_from_queue(pmlmepriv);
- if (!candidate) {
- DBG_8723A("%s: return _FAIL(candidate == NULL)\n", __func__);
- ret = _FAIL;
- goto exit;
- } else {
- DBG_8723A("%s: candidate: %s(%pM, ch:%u)\n",
- __func__,
- candidate->network.Ssid.ssid,
- candidate->network.MacAddress,
- candidate->network.DSConfig);
- }
-
- ret = rtw_do_join_network(adapter, candidate);
-
-exit:
- return ret;
-}
-
-int rtw_set_auth23a(struct rtw_adapter *adapter,
- struct security_priv *psecuritypriv)
-{
- struct cmd_obj *pcmd;
- struct setauth_parm *psetauthparm;
- struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
- int res = _SUCCESS;
-
- pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
- if (!pcmd) {
- res = _FAIL; /* try again */
- goto exit;
- }
-
- psetauthparm = kzalloc(sizeof(struct setauth_parm), GFP_KERNEL);
- if (!psetauthparm) {
- kfree(pcmd);
- res = _FAIL;
- goto exit;
- }
-
- psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
-
- pcmd->cmdcode = _SetAuth_CMD_;
- pcmd->parmbuf = (unsigned char *)psetauthparm;
- pcmd->cmdsz = (sizeof(struct setauth_parm));
- pcmd->rsp = NULL;
- pcmd->rspsz = 0;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "after enqueue set_auth_cmd, auth_mode=%x\n",
- psecuritypriv->dot11AuthAlgrthm);
-
- res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
-
-exit:
-
- return res;
-}
-
-int rtw_set_key23a(struct rtw_adapter *adapter,
- struct security_priv *psecuritypriv, int keyid, u8 set_tx)
-{
- u8 keylen;
- struct cmd_obj *pcmd;
- struct setkey_parm *psetkeyparm;
- struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- int res = _SUCCESS;
-
- if (keyid >= 4) {
- res = _FAIL;
- goto exit;
- }
-
- pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
- if (!pcmd) {
- res = _FAIL; /* try again */
- goto exit;
- }
- psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
- if (!psetkeyparm) {
- kfree(pcmd);
- res = _FAIL;
- goto exit;
- }
-
- if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
- psetkeyparm->algorithm = (unsigned char)
- psecuritypriv->dot118021XGrpPrivacy;
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "rtw_set_key23a: psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy =%d\n",
- psetkeyparm->algorithm);
- } else {
- psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm;
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "rtw_set_key23a: psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm =%d\n",
- psetkeyparm->algorithm);
- }
- psetkeyparm->keyid = keyid;/* 0~3 */
- psetkeyparm->set_tx = set_tx;
- if (is_wep_enc(psetkeyparm->algorithm))
- pmlmepriv->key_mask |= BIT(psetkeyparm->keyid);
-
- DBG_8723A("==> rtw_set_key23a algorithm(%x), keyid(%x), key_mask(%x)\n",
- psetkeyparm->algorithm, psetkeyparm->keyid,
- pmlmepriv->key_mask);
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "rtw_set_key23a: psetkeyparm->algorithm =%d psetkeyparm->keyid = (u8)keyid =%d\n",
- psetkeyparm->algorithm, keyid);
-
- switch (psetkeyparm->algorithm) {
- case WLAN_CIPHER_SUITE_WEP40:
- keylen = 5;
- memcpy(&psetkeyparm->key[0],
- &psecuritypriv->wep_key[keyid].key, keylen);
- break;
- case WLAN_CIPHER_SUITE_WEP104:
- keylen = 13;
- memcpy(&psetkeyparm->key[0],
- &psecuritypriv->wep_key[keyid].key, keylen);
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- keylen = 16;
- memcpy(&psetkeyparm->key,
- &psecuritypriv->dot118021XGrpKey[keyid], keylen);
- psetkeyparm->grpkey = 1;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- keylen = 16;
- memcpy(&psetkeyparm->key,
- &psecuritypriv->dot118021XGrpKey[keyid], keylen);
- psetkeyparm->grpkey = 1;
- break;
- default:
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "rtw_set_key23a:psecuritypriv->dot11PrivacyAlgrthm = %x (must be 1 or 2 or 4 or 5)\n",
- psecuritypriv->dot11PrivacyAlgrthm);
- res = _FAIL;
- kfree(pcmd);
- kfree(psetkeyparm);
- goto exit;
- }
-
- pcmd->cmdcode = _SetKey_CMD_;
- pcmd->parmbuf = (u8 *)psetkeyparm;
- pcmd->cmdsz = (sizeof(struct setkey_parm));
- pcmd->rsp = NULL;
- pcmd->rspsz = 0;
-
- /* sema_init(&pcmd->cmd_sem, 0); */
-
- res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
-
-exit:
-
- return res;
-}
-
-/* adjust IEs for rtw_joinbss_cmd23a in WMM */
-int rtw_restruct_wmm_ie23a(struct rtw_adapter *adapter, u8 *in_ie,
- u8 *out_ie, uint in_len, uint initial_out_len)
-{
- int ielength;
- const u8 *p;
-
- ielength = initial_out_len;
-
- p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WMM,
- in_ie, in_len);
-
- if (p && p[1]) {
- memcpy(out_ie + initial_out_len, p, 9);
-
- out_ie[initial_out_len + 1] = 7;
- out_ie[initial_out_len + 6] = 0;
- out_ie[initial_out_len + 8] = 0;
-
- ielength += 9;
- }
-
- return ielength;
-}
-
-/* */
-/* Ported from 8185: IsInPreAuthKeyList().
- (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) */
-/* Added by Annie, 2006-05-07. */
-/* */
-/* Search by BSSID, */
-/* Return Value: */
-/* -1 :if there is no pre-auth key in the table */
-/* >= 0 :if there is pre-auth key, and return the entry id */
-/* */
-/* */
-
-static int SecIsInPMKIDList(struct rtw_adapter *Adapter, u8 *bssid)
-{
- struct security_priv *psecuritypriv = &Adapter->securitypriv;
- int i = 0;
-
- do {
- if (psecuritypriv->PMKIDList[i].bUsed &&
- ether_addr_equal(psecuritypriv->PMKIDList[i].Bssid, bssid)) {
- break;
- } else {
- i++;
- /* continue; */
- }
- } while (i < NUM_PMKID_CACHE);
-
- if (i == NUM_PMKID_CACHE)
- i = -1;/* Could not find. */
- else {
- /* There is one Pre-Authentication Key for
- the specific BSSID. */
- }
-
- return i;
-}
-
-/* */
-/* Check the RSN IE length */
-/* If the RSN IE length <= 20, the RSN IE didn't include
- the PMKID information */
-/* 0-11th element in the array are the fixed IE */
-/* 12th element in the array is the IE */
-/* 13th element in the array is the IE length */
-/* */
-
-static int rtw_append_pmkid(struct rtw_adapter *Adapter, int iEntry,
- u8 *ie, uint ie_len)
-{
- struct security_priv *psecuritypriv = &Adapter->securitypriv;
-
- if (ie[1] <= 20) {
- /* The RSN IE didn't include the PMK ID,
- append the PMK information */
- ie[ie_len] = 1;
- ie_len++;
- ie[ie_len] = 0; /* PMKID count = 0x0100 */
- ie_len++;
- memcpy(&ie[ie_len],
- &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
-
- ie_len += 16;
- ie[1] += 18;/* PMKID length = 2+16 */
- }
- return ie_len;
-}
-
-int rtw_restruct_sec_ie23a(struct rtw_adapter *adapter, u8 *in_ie, u8 *out_ie,
- uint in_len)
-{
- u8 authmode;
- uint ielength;
- int iEntry;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct security_priv *psecuritypriv = &adapter->securitypriv;
- uint ndisauthmode = psecuritypriv->ndisauthtype;
- uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
- "+rtw_restruct_sec_ie23a: ndisauthmode=%d ndissecuritytype=%d\n",
- ndisauthmode, ndissecuritytype);
-
- ielength = 0;
- if (ndisauthmode == Ndis802_11AuthModeWPA ||
- ndisauthmode == Ndis802_11AuthModeWPAPSK)
- authmode = WLAN_EID_VENDOR_SPECIFIC;
- if (ndisauthmode == Ndis802_11AuthModeWPA2 ||
- ndisauthmode == Ndis802_11AuthModeWPA2PSK)
- authmode = WLAN_EID_RSN;
-
- if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
- memcpy(out_ie + ielength, psecuritypriv->wps_ie,
- psecuritypriv->wps_ie_len);
-
- ielength += psecuritypriv->wps_ie_len;
- } else if (authmode == WLAN_EID_VENDOR_SPECIFIC ||
- authmode == WLAN_EID_RSN) {
- /* copy RSN or SSN */
- memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0],
- psecuritypriv->supplicant_ie[1] + 2);
- ielength += psecuritypriv->supplicant_ie[1] + 2;
- }
-
- iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
- if (iEntry < 0)
- return ielength;
- else {
- if (authmode == WLAN_EID_RSN)
- ielength = rtw_append_pmkid(adapter, iEntry,
- out_ie, ielength);
- }
-
- return ielength;
-}
-
-void rtw_init_registrypriv_dev_network23a(struct rtw_adapter *adapter)
-{
- struct registry_priv *pregistrypriv = &adapter->registrypriv;
- struct eeprom_priv *peepriv = &adapter->eeprompriv;
- struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
- u8 *myhwaddr = myid(peepriv);
-
- ether_addr_copy(pdev_network->MacAddress, myhwaddr);
-
- memcpy(&pdev_network->Ssid, &pregistrypriv->ssid,
- sizeof(struct cfg80211_ssid));
-
- pdev_network->beacon_interval = 100;
-}
-
-void rtw_update_registrypriv_dev_network23a(struct rtw_adapter *adapter)
-{
- int sz = 0;
- struct registry_priv *pregistrypriv = &adapter->registrypriv;
- struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
- struct security_priv *psecuritypriv = &adapter->securitypriv;
- struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
- /* struct xmit_priv *pxmitpriv = &adapter->xmitpriv; */
-
- pdev_network->Privacy =
- (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0);
-
- pdev_network->Rssi = 0;
-
- pdev_network->DSConfig = pregistrypriv->channel;
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "pregistrypriv->channel =%d, pdev_network->DSConfig = 0x%x\n",
- pregistrypriv->channel, pdev_network->DSConfig);
-
- if (cur_network->network.ifmode == NL80211_IFTYPE_ADHOC)
- pdev_network->ATIMWindow = 0;
-
- pdev_network->ifmode = cur_network->network.ifmode;
-
- /* 1. Supported rates */
- /* 2. IE */
-
- sz = rtw_generate_ie23a(pregistrypriv);
-
- pdev_network->IELength = sz;
-
- pdev_network->Length =
- get_wlan_bssid_ex_sz(pdev_network);
-
- /* notes: translate IELength & Length after assign the
- Length to cmdsz in createbss_cmd(); */
- /* pdev_network->IELength = cpu_to_le32(sz); */
-}
-
-/* the function is at passive_level */
-void rtw_joinbss_reset23a(struct rtw_adapter *padapter)
-{
- u8 threshold;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct ht_priv *phtpriv = &pmlmepriv->htpriv;
-
- /* todo: if you want to do something io/reg/hw setting
- before join_bss, please add code here */
-
- pmlmepriv->num_FortyMHzIntolerant = 0;
-
- pmlmepriv->num_sta_no_ht = 0;
-
- phtpriv->ampdu_enable = false;/* reset to disabled */
-
- /* TH = 1 => means that invalidate usb rx aggregation */
- /* TH = 0 => means that validate usb rx aggregation, use init value. */
- if (phtpriv->ht_option) {
- if (padapter->registrypriv.wifi_spec == 1)
- threshold = 1;
- else
- threshold = 0;
- } else
- threshold = 1;
-
- rtl8723a_set_rxdma_agg_pg_th(padapter, threshold);
-}
-
-/* the function is >= passive_level */
-bool rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie,
- u8 *out_ie, uint in_len, uint *pout_len)
-{
- u32 out_len;
- int max_rx_ampdu_factor;
- unsigned char *pframe;
- const u8 *p;
- struct ieee80211_ht_cap ht_capie;
- u8 WMM_IE[7] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct ht_priv *phtpriv = &pmlmepriv->htpriv;
-
- phtpriv->ht_option = false;
-
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, in_ie, in_len);
-
- if (p && p[1] > 0) {
- u32 rx_packet_offset, max_recvbuf_sz;
-
- if (pmlmepriv->qos_option == 0) {
- out_len = *pout_len;
- pframe = rtw_set_ie23a(out_ie + out_len,
- WLAN_EID_VENDOR_SPECIFIC,
- sizeof(WMM_IE), WMM_IE,
- pout_len);
-
- pmlmepriv->qos_option = 1;
- }
-
- out_len = *pout_len;
-
- memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap));
-
- ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
- IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
- IEEE80211_HT_CAP_TX_STBC | IEEE80211_HT_CAP_DSSSCCK40);
-
- GetHalDefVar8192CUsb(padapter, HAL_DEF_RX_PACKET_OFFSET,
- &rx_packet_offset);
- GetHalDefVar8192CUsb(padapter, HAL_DEF_MAX_RECVBUF_SZ,
- &max_recvbuf_sz);
-
- GetHalDefVar8192CUsb(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
- &max_rx_ampdu_factor);
- ht_capie.ampdu_params_info = max_rx_ampdu_factor & 0x03;
-
- if (padapter->securitypriv.dot11PrivacyAlgrthm ==
- WLAN_CIPHER_SUITE_CCMP)
- ht_capie.ampdu_params_info |=
- (IEEE80211_HT_AMPDU_PARM_DENSITY& (0x07 << 2));
- else
- ht_capie.ampdu_params_info |=
- (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00);
-
- pframe = rtw_set_ie23a(out_ie + out_len, WLAN_EID_HT_CAPABILITY,
- sizeof(struct ieee80211_ht_cap),
- (unsigned char *)&ht_capie, pout_len);
-
- phtpriv->ht_option = true;
-
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, in_ie, in_len);
- if (p && (p[1] == sizeof(struct ieee80211_ht_operation))) {
- out_len = *pout_len;
- pframe = rtw_set_ie23a(out_ie + out_len,
- WLAN_EID_HT_OPERATION,
- p[1], p + 2 , pout_len);
- }
- }
-
- return phtpriv->ht_option;
-}
-
-/* the function is > passive_level (in critical_section) */
-void rtw_update_ht_cap23a(struct rtw_adapter *padapter, u8 *pie, uint ie_len)
-{
- u8 max_ampdu_sz;
- const u8 *p;
- struct ieee80211_ht_cap *pht_capie;
- struct ieee80211_ht_operation *pht_addtinfo;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct ht_priv *phtpriv = &pmlmepriv->htpriv;
- struct registry_priv *pregistrypriv = &padapter->registrypriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- if (!phtpriv->ht_option)
- return;
-
- if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
- return;
-
- DBG_8723A("+rtw_update_ht_cap23a()\n");
-
- /* maybe needs check if ap supports rx ampdu. */
- if (!phtpriv->ampdu_enable && pregistrypriv->ampdu_enable == 1) {
- if (pregistrypriv->wifi_spec == 1)
- phtpriv->ampdu_enable = false;
- else
- phtpriv->ampdu_enable = true;
- } else if (pregistrypriv->ampdu_enable == 2)
- phtpriv->ampdu_enable = true;
-
- /* check Max Rx A-MPDU Size */
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, ie_len);
-
- if (p && p[1] > 0) {
- pht_capie = (struct ieee80211_ht_cap *)(p + 2);
- max_ampdu_sz = pht_capie->ampdu_params_info &
- IEEE80211_HT_AMPDU_PARM_FACTOR;
- /* max_ampdu_sz (kbytes); */
- max_ampdu_sz = 1 << (max_ampdu_sz + 3);
-
- phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
- }
-
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, pie, ie_len);
- if (p && p[1] > 0) {
- pht_addtinfo = (struct ieee80211_ht_operation *)(p + 2);
- /* todo: */
- }
-
- /* update cur_bwmode & cur_ch_offset */
- if (pregistrypriv->cbw40_enable &&
- pmlmeinfo->ht_cap.cap_info &
- cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
- pmlmeinfo->HT_info.ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) {
- int i;
- u8 rf_type;
-
- rf_type = rtl8723a_get_rf_type(padapter);
-
- /* update the MCS rates */
- for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
- if (rf_type == RF_1T1R || rf_type == RF_1T2R)
- pmlmeinfo->ht_cap.mcs.rx_mask[i] &=
- MCS_rate_1R23A[i];
- else
- pmlmeinfo->ht_cap.mcs.rx_mask[i] &=
- MCS_rate_2R23A[i];
- }
- /* switch to the 40M Hz mode according to the AP */
- pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
- switch (pmlmeinfo->HT_info.ht_param &
- IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
- case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
- pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
- break;
-
- case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
- pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
- break;
-
- default:
- pmlmeext->cur_ch_offset =
- HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- break;
- }
- }
-
- /* */
- /* Config SM Power Save setting */
- /* */
- pmlmeinfo->SM_PS =
- (le16_to_cpu(pmlmeinfo->ht_cap.cap_info) &
- IEEE80211_HT_CAP_SM_PS) >> IEEE80211_HT_CAP_SM_PS_SHIFT;
- if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
- DBG_8723A("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
-
- /* */
- /* Config current HT Protection mode. */
- /* */
- pmlmeinfo->HT_protection =
- le16_to_cpu(pmlmeinfo->HT_info.operation_mode) &
- IEEE80211_HT_OP_MODE_PROTECTION;
-}
-
-void rtw_issue_addbareq_cmd23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe)
-{
- u8 issued;
- int priority;
- struct sta_info *psta;
- struct ht_priv *phtpriv;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- s32 bmcst = is_multicast_ether_addr(pattrib->ra);
-
- if (bmcst || padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100)
- return;
-
- priority = pattrib->priority;
-
- if (pattrib->psta)
- psta = pattrib->psta;
- else {
- DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
- psta = rtw_get_stainfo23a(&padapter->stapriv, pattrib->ra);
- }
-
- if (!psta) {
- DBG_8723A("%s, psta == NUL\n", __func__);
- return;
- }
-
- if (!(psta->state &_FW_LINKED)) {
- DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
- __func__, psta->state);
- return;
- }
-
- phtpriv = &psta->htpriv;
-
- if (phtpriv->ht_option && phtpriv->ampdu_enable) {
- issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
- issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
-
- if (issued == 0) {
- DBG_8723A("rtw_issue_addbareq_cmd23a, p =%d\n",
- priority);
- psta->htpriv.candidate_tid_bitmap |= BIT(priority);
- rtw_addbareq_cmd23a(padapter, (u8) priority,
- pattrib->ra);
- }
- }
-}
-
-int rtw_linked_check(struct rtw_adapter *padapter)
-{
- if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) ||
- check_fwstate(&padapter->mlmepriv,
- WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) {
- if (padapter->stapriv.asoc_sta_count > 2)
- return true;
- } else { /* Station mode */
- if (check_fwstate(&padapter->mlmepriv, _FW_LINKED))
- return true;
- }
- return false;
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
deleted file mode 100644
index 7dd1540ebedd..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
+++ /dev/null
@@ -1,6187 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTW_MLME_EXT_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <wifi.h>
-#include <rtw_mlme_ext.h>
-#include <wlan_bssdef.h>
-#include <mlme_osdep.h>
-#include <recv_osdep.h>
-#include <linux/ieee80211.h>
-#include <rtl8723a_hal.h>
-
-static int OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnProbeReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnProbeRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int DoReserved23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnAuth23aClient23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-
-static int on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnAction23a_back23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int on_action_public23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnAction23a_wmm(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static int OnAction23a_p2p(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-
-static void issue_assocreq(struct rtw_adapter *padapter);
-static void issue_probereq(struct rtw_adapter *padapter,
- struct cfg80211_ssid *pssid, u8 *da);
-static int issue_probereq_ex(struct rtw_adapter *padapter,
- struct cfg80211_ssid *pssid,
- u8 *da, int try_cnt, int wait_ms);
-static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da);
-static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
- unsigned short status);
-static int issue_deauth_ex(struct rtw_adapter *padapter, u8 *da,
- unsigned short reason, int try_cnt, int wait_ms);
-static void start_clnt_assoc(struct rtw_adapter *padapter);
-static void start_clnt_auth(struct rtw_adapter *padapter);
-static void start_clnt_join(struct rtw_adapter *padapter);
-static void start_create_ibss(struct rtw_adapter *padapter);
-static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame);
-
-#ifdef CONFIG_8723AU_AP_MODE
-static int OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
- struct sta_info *pstat, u16 pkt_type);
-#endif
-
-static struct mlme_handler mlme_sta_tbl[]={
- {"OnAssocReq23a", &OnAssocReq23a},
- {"OnAssocRsp23a", &OnAssocRsp23a},
- {"OnReAssocReq", &OnAssocReq23a},
- {"OnReAssocRsp", &OnAssocRsp23a},
- {"OnProbeReq23a", &OnProbeReq23a},
- {"OnProbeRsp23a", &OnProbeRsp23a},
-
- /*----------------------------------------------------------
- below 2 are reserved
- -----------------------------------------------------------*/
- {"DoReserved23a", &DoReserved23a},
- {"DoReserved23a", &DoReserved23a},
- {"OnBeacon23a", &OnBeacon23a},
- {"OnATIM", &OnAtim23a},
- {"OnDisassoc23a", &OnDisassoc23a},
- {"OnAuth23a", &OnAuth23aClient23a},
- {"OnDeAuth23a", &OnDeAuth23a},
- {"OnAction23a", &OnAction23a},
-};
-
-static struct action_handler OnAction23a_tbl[]={
- {WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct23a},
- {WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction23a_qos},
- {WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction23a_dls},
- {WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction23a_back23a},
- {WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public23a},
- {WLAN_CATEGORY_HT, "ACTION_HT", &OnAction23a_ht},
- {WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved23a},
- {WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction23a_wmm},
- {WLAN_CATEGORY_VENDOR_SPECIFIC, "ACTION_P2P", &OnAction23a_p2p},
-};
-
-static u8 null_addr[ETH_ALEN]= {0, 0, 0, 0, 0, 0};
-
-/**************************************************
-OUI definitions for the vendor specific IE
-***************************************************/
-unsigned char WMM_OUI23A[] = {0x00, 0x50, 0xf2, 0x02};
-unsigned char WPS_OUI23A[] = {0x00, 0x50, 0xf2, 0x04};
-unsigned char P2P_OUI23A[] = {0x50, 0x6F, 0x9A, 0x09};
-unsigned char WFD_OUI23A[] = {0x50, 0x6F, 0x9A, 0x0A};
-
-unsigned char WMM_INFO_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
-unsigned char WMM_PARA_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
-
-static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
-
-/********************************************************
-MCS rate definitions
-*********************************************************/
-unsigned char MCS_rate_2R23A[16] = {
- 0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
-unsigned char MCS_rate_1R23A[16] = {
- 0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
-
-/********************************************************
-ChannelPlan definitions
-*********************************************************/
-
-static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
- /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
- /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
- /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
- /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
- /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
- {{10, 11, 12, 13}, 4},
- /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
- {{}, 0},
-};
-
-static struct rt_channel_plan_5g RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
- /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
- {{}, 0},
- /* 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
- 116, 120, 124, 128, 132, 136, 140}, 19},
- /* 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
- 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
- /* 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
- 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22},
- /* 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
- 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
- /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
- {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},
- /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},
- /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12},
- /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
- {{149, 153, 157, 161, 165}, 5},
- /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
- {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
- /* 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
- 116, 136, 140, 149, 153, 157, 161, 165}, 20},
- /* 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
- 116, 120, 124, 149, 153, 157, 161, 165}, 20},
- /* 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
- 116, 120, 124, 128, 132, 136, 140}, 19},
- /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
- {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
- /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
- {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},
- /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
- {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149,
- 153, 157, 161, 165}, 15},
- /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
- {{56, 60, 64, 149, 153, 157, 161, 165}, 8},
-
- /* Driver self defined for old channel plan Compatible,
- Remember to modify if have new channel plan definition ===== */
- /* 0x11, RT_CHANNEL_DOMAIN_5G_FCC */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
- 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},
- /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
- {{36, 40, 44, 48}, 4},
- /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
- {{36, 40, 44, 48, 149, 153, 157, 161}, 8},
-};
-
-static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
- /* 0x00 ~ 0x1F , Old Define ===== */
- {0x02, 0x11}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
- {0x02, 0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
- {0x01, 0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
- {0x01, 0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
- {0x01, 0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
- {0x03, 0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
- {0x03, 0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
- {0x01, 0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
- {0x03, 0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
- {0x03, 0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
- {0x00, 0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
- {0x02, 0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
- {0x01, 0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
- {0x02, 0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
- {0x02, 0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
- {0x02, 0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
- {0x01, 0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
- {0x02, 0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
- {0x01, 0x12}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
- {0x00, 0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
- {0x02, 0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
- {0x00, 0x12}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
- {0x00, 0x13}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
- {0x03, 0x12}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
- {0x05, 0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
- {0x02, 0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
- {0x00, 0x00}, /* 0x1A, */
- {0x00, 0x00}, /* 0x1B, */
- {0x00, 0x00}, /* 0x1C, */
- {0x00, 0x00}, /* 0x1D, */
- {0x00, 0x00}, /* 0x1E, */
- {0x05, 0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
- /* 0x20 ~ 0x7F , New Define ===== */
- {0x00, 0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
- {0x01, 0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
- {0x02, 0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
- {0x03, 0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
- {0x04, 0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
- {0x02, 0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
- {0x00, 0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
- {0x03, 0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
- {0x00, 0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
- {0x00, 0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
- {0x00, 0x00}, /* 0x2A, */
- {0x00, 0x00}, /* 0x2B, */
- {0x00, 0x00}, /* 0x2C, */
- {0x00, 0x00}, /* 0x2D, */
- {0x00, 0x00}, /* 0x2E, */
- {0x00, 0x00}, /* 0x2F, */
- {0x00, 0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
- {0x00, 0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
- {0x00, 0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
- {0x00, 0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
- {0x02, 0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
- {0x00, 0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
- {0x00, 0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
- {0x03, 0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
- {0x03, 0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
- {0x02, 0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
- {0x00, 0x00}, /* 0x3A, */
- {0x00, 0x00}, /* 0x3B, */
- {0x00, 0x00}, /* 0x3C, */
- {0x00, 0x00}, /* 0x3D, */
- {0x00, 0x00}, /* 0x3E, */
- {0x00, 0x00}, /* 0x3F, */
- {0x02, 0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
- {0x03, 0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
-};
-
-static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE =
-{0x03, 0x02}; /* use the conbination for max channel numbers */
-
-static void dummy_event_callback(struct rtw_adapter *adapter, const u8 *pbuf)
-{
-}
-
-static struct fwevent wlanevents[] =
-{
- {0, &dummy_event_callback}, /*0*/
- {0, NULL},
- {0, NULL},
- {0, NULL},
- {0, NULL},
- {0, NULL},
- {0, NULL},
- {0, NULL},
- {0, &rtw_survey_event_cb23a}, /*8*/
- {sizeof (struct surveydone_event), &rtw_surveydone_event_callback23a},
- {0, &rtw23a_joinbss_event_cb}, /*10*/
- {sizeof(struct stassoc_event), &rtw_stassoc_event_callback23a},
- {sizeof(struct stadel_event), &rtw_stadel_event_callback23a},
- {0, &dummy_event_callback},
- {0, &dummy_event_callback},
- {0, NULL}, /*15*/
- {0, NULL},
- {0, NULL},
- {0, NULL},
- {0, &dummy_event_callback},
- {0, NULL}, /*20*/
- {0, NULL},
- {0, NULL},
- {0, &dummy_event_callback},
- {0, NULL},
-};
-
-
-static void rtw_correct_TSF(struct rtw_adapter *padapter)
-{
- hw_var_set_correct_tsf(padapter);
-}
-
-static void
-rtw_update_TSF(struct mlme_ext_priv *pmlmeext, struct ieee80211_mgmt *mgmt)
-{
- pmlmeext->TSFValue = get_unaligned_le64(&mgmt->u.beacon.timestamp);
-}
-
-/*
- * Search the @param channel_num in given @param channel_set
- * @ch_set: the given channel set
- * @ch: the given channel number
- *
- * return the index of channel_num in channel_set, -1 if not found
- */
-int rtw_ch_set_search_ch23a(struct rt_channel_info *ch_set, const u32 ch)
-{
- int i;
-
- for (i = 0; ch_set[i]. ChannelNum != 0; i++) {
- if (ch == ch_set[i].ChannelNum)
- break;
- }
-
- if (i >= ch_set[i].ChannelNum)
- return -1;
- return i;
-}
-
-/****************************************************************************
-
-Following are the initialization functions for WiFi MLME
-
-*****************************************************************************/
-
-int init_hw_mlme_ext23a(struct rtw_adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
- pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
- return _SUCCESS;
-}
-
-static void init_mlme_ext_priv23a_value(struct rtw_adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- unsigned char mixed_datarate[NumRates] = {
- _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
- _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_,
- _48M_RATE_, _54M_RATE_, 0xff};
- unsigned char mixed_basicrate[NumRates] = {
- _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
- _12M_RATE_, _24M_RATE_, 0xff,};
-
- atomic_set(&pmlmeext->event_seq, 0);
- /* reset to zero when disconnect at client mode */
- pmlmeext->mgnt_seq = 0;
-
- pmlmeext->cur_channel = padapter->registrypriv.channel;
- pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
- pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-
- pmlmeext->retry = 0;
-
- pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
-
- memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
- memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
-
- if (pmlmeext->cur_channel > 14)
- pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
- else
- pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
-
- pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
- pmlmeext->sitesurvey_res.channel_idx = 0;
- pmlmeext->sitesurvey_res.bss_cnt = 0;
- pmlmeext->scan_abort = false;
-
- pmlmeinfo->state = MSR_NOLINK;
- pmlmeinfo->reauth_count = 0;
- pmlmeinfo->reassoc_count = 0;
- pmlmeinfo->link_count = 0;
- pmlmeinfo->auth_seq = 0;
- pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
- pmlmeinfo->key_index = 0;
- pmlmeinfo->iv = 0;
-
- pmlmeinfo->enc_algo = 0;
- pmlmeinfo->authModeToggle = 0;
-
- memset(pmlmeinfo->chg_txt, 0, 128);
-
- pmlmeinfo->slotTime = SHORT_SLOT_TIME;
- pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
-
- pmlmeinfo->dialogToken = 0;
-
- pmlmeext->action_public_rxseq = 0xffff;
- pmlmeext->action_public_dialog_token = 0xff;
-}
-
-static int has_channel(struct rt_channel_info *channel_set,
- u8 chanset_size, u8 chan) {
- int i;
-
- for (i = 0; i < chanset_size; i++) {
- if (channel_set[i].ChannelNum == chan)
- return 1;
- }
-
- return 0;
-}
-
-static void init_channel_list(struct rtw_adapter *padapter,
- struct rt_channel_info *channel_set,
- u8 chanset_size,
- struct p2p_channels *channel_list)
-{
- struct p2p_oper_class_map op_class[] = {
- { IEEE80211G, 81, 1, 13, 1, BW20 },
- { IEEE80211G, 82, 14, 14, 1, BW20 },
- { IEEE80211A, 115, 36, 48, 4, BW20 },
- { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
- { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
- { IEEE80211A, 124, 149, 161, 4, BW20 },
- { IEEE80211A, 125, 149, 169, 4, BW20 },
- { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
- { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
- { -1, 0, 0, 0, 0, BW20 }
- };
-
- int cla, op;
-
- cla = 0;
-
- for (op = 0; op_class[op].op_class; op++) {
- u8 ch;
- struct p2p_oper_class_map *o = &op_class[op];
- struct p2p_reg_class *reg = NULL;
-
- for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
- if (!has_channel(channel_set, chanset_size, ch))
- continue;
-
- if ((0 == padapter->registrypriv.ht_enable) &&
- (o->inc == 8))
- continue;
-
- if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) &&
- ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
- continue;
-
- if (reg == NULL) {
- reg = &channel_list->reg_class[cla];
- cla++;
- reg->reg_class = o->op_class;
- reg->channels = 0;
- }
- reg->channel[reg->channels] = ch;
- reg->channels++;
- }
- }
- channel_list->reg_classes = cla;
-}
-
-static u8 init_channel_set(struct rtw_adapter *padapter, u8 cplan,
- struct rt_channel_info *c_set)
-{
- u8 i, ch_size = 0;
- u8 b5GBand = false, b2_4GBand = false;
- u8 Index2G = 0, Index5G = 0;
-
- memset(c_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM);
-
- if (cplan >= RT_CHANNEL_DOMAIN_MAX &&
- cplan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) {
- DBG_8723A("ChannelPlan ID %x error !!!!!\n", cplan);
- return ch_size;
- }
-
- if (padapter->registrypriv.wireless_mode & WIRELESS_11G) {
- b2_4GBand = true;
- if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
- Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
- else
- Index2G = RTW_ChannelPlanMap[cplan].Index2G;
- }
-
- if (padapter->registrypriv.wireless_mode & WIRELESS_11A) {
- b5GBand = true;
- if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
- Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
- else
- Index5G = RTW_ChannelPlanMap[cplan].Index5G;
- }
-
- if (b2_4GBand) {
- for (i = 0; i < RTW_ChannelPlan2G[Index2G].Len; i++) {
- c_set[ch_size].ChannelNum =
- RTW_ChannelPlan2G[Index2G].Channel[i];
-
- if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == cplan) ||
- /* Channel 1~11 is active, and 12~14 is passive */
- RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == cplan) {
- if (c_set[ch_size].ChannelNum >= 1 &&
- c_set[ch_size].ChannelNum <= 11)
- c_set[ch_size].ScanType = SCAN_ACTIVE;
- else if (c_set[ch_size].ChannelNum >= 12 &&
- c_set[ch_size].ChannelNum <= 14)
- c_set[ch_size].ScanType = SCAN_PASSIVE;
- } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == cplan ||
- RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == cplan ||
- RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) {
- /* channel 12~13, passive scan */
- if (c_set[ch_size].ChannelNum <= 11)
- c_set[ch_size].ScanType = SCAN_ACTIVE;
- else
- c_set[ch_size].ScanType = SCAN_PASSIVE;
- } else
- c_set[ch_size].ScanType = SCAN_ACTIVE;
-
- ch_size++;
- }
- }
-
- if (b5GBand) {
- for (i = 0; i < RTW_ChannelPlan5G[Index5G].Len; i++) {
- if (RTW_ChannelPlan5G[Index5G].Channel[i] <= 48 ||
- RTW_ChannelPlan5G[Index5G].Channel[i] >= 149) {
- c_set[ch_size].ChannelNum =
- RTW_ChannelPlan5G[Index5G].Channel[i];
- if (RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == cplan) {
- /* passive scan for all 5G channels */
- c_set[ch_size].ScanType =
- SCAN_PASSIVE;
- } else
- c_set[ch_size].ScanType =
- SCAN_ACTIVE;
- DBG_8723A("%s(): channel_set[%d].ChannelNum = "
- "%d\n", __func__, ch_size,
- c_set[ch_size].ChannelNum);
- ch_size++;
- }
- }
- }
-
- return ch_size;
-}
-
-int init_mlme_ext_priv23a(struct rtw_adapter *padapter)
-{
- struct registry_priv *pregistrypriv = &padapter->registrypriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- pmlmeext->padapter = padapter;
-
- init_mlme_ext_priv23a_value(padapter);
- pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
-
- init_mlme_ext_timer23a(padapter);
-
-#ifdef CONFIG_8723AU_AP_MODE
- init_mlme_ap_info23a(padapter);
-#endif
-
- pmlmeext->max_chan_nums = init_channel_set(padapter,
- pmlmepriv->ChannelPlan,
- pmlmeext->channel_set);
- init_channel_list(padapter, pmlmeext->channel_set,
- pmlmeext->max_chan_nums, &pmlmeext->channel_list);
-
- pmlmeext->chan_scan_time = SURVEY_TO;
- pmlmeext->mlmeext_init = true;
-
- pmlmeext->active_keep_alive_check = true;
- return _SUCCESS;
-}
-
-void free_mlme_ext_priv23a (struct mlme_ext_priv *pmlmeext)
-{
- struct rtw_adapter *padapter = pmlmeext->padapter;
-
- if (!padapter)
- return;
-
- if (padapter->bDriverStopped == true) {
- del_timer_sync(&pmlmeext->survey_timer);
- del_timer_sync(&pmlmeext->link_timer);
- /* del_timer_sync(&pmlmeext->ADDBA_timer); */
- }
-}
-
-static void
-_mgt_dispatcher23a(struct rtw_adapter *padapter, struct mlme_handler *ptable,
- struct recv_frame *precv_frame)
-{
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-
- if (ptable->func) {
- /* receive the frames that ra(a1) is my address
- or ra(a1) is bc address. */
- if (!ether_addr_equal(hdr->addr1, myid(&padapter->eeprompriv))&&
- !is_broadcast_ether_addr(hdr->addr1))
- return;
-
- ptable->func(padapter, precv_frame);
- }
-}
-
-void mgt_dispatcher23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
- struct mlme_handler *ptable;
-#ifdef CONFIG_8723AU_AP_MODE
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-#endif /* CONFIG_8723AU_AP_MODE */
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
- struct sta_info *psta;
- u16 stype;
- int index;
-
- if (!ieee80211_is_mgmt(mgmt->frame_control))
- return;
-
- /* receive the frames that ra(a1) is my address or ra(a1) is
- bc address. */
- if (!ether_addr_equal(mgmt->da, myid(&padapter->eeprompriv)) &&
- !is_broadcast_ether_addr(mgmt->da))
- return;
-
- ptable = mlme_sta_tbl;
-
- stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
- index = stype >> 4;
-
- if (index > 13) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "Currently we do not support reserved sub-fr-type =%d\n",
- index);
- return;
- }
- ptable += index;
-
- psta = rtw_get_stainfo23a(&padapter->stapriv, mgmt->sa);
-
- if (psta) {
- if (ieee80211_has_retry(mgmt->frame_control)) {
- if (precv_frame->attrib.seq_num ==
- psta->RxMgmtFrameSeqNum) {
- /* drop the duplicate management frame */
- DBG_8723A("Drop duplicate management frame "
- "with seq_num = %d.\n",
- precv_frame->attrib.seq_num);
- return;
- }
- }
- psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num;
- }
-
-#ifdef CONFIG_8723AU_AP_MODE
- switch (stype) {
- case IEEE80211_STYPE_AUTH:
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
- ptable->func = &OnAuth23a;
- else
- ptable->func = &OnAuth23aClient23a;
- /* pass through */
- case IEEE80211_STYPE_ASSOC_REQ:
- case IEEE80211_STYPE_REASSOC_REQ:
- _mgt_dispatcher23a(padapter, ptable, precv_frame);
- break;
- case IEEE80211_STYPE_PROBE_REQ:
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
- _mgt_dispatcher23a(padapter, ptable, precv_frame);
- else
- _mgt_dispatcher23a(padapter, ptable, precv_frame);
- break;
- case IEEE80211_STYPE_BEACON:
- _mgt_dispatcher23a(padapter, ptable, precv_frame);
- break;
- case IEEE80211_STYPE_ACTION:
- /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) */
- _mgt_dispatcher23a(padapter, ptable, precv_frame);
- break;
- default:
- _mgt_dispatcher23a(padapter, ptable, precv_frame);
- break;
- }
-#else
- _mgt_dispatcher23a(padapter, ptable, precv_frame);
-#endif
-}
-
-/****************************************************************************
-
-Following are the callback functions for each subtype of the management frames
-
-*****************************************************************************/
-
-static int
-OnProbeReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- const u8 *ie;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *cur = &pmlmeinfo->network;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
- int len = skb->len;
-
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
- return _SUCCESS;
-
- if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
- !check_fwstate(pmlmepriv,
- WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
- return _SUCCESS;
-
- if (unlikely(!ieee80211_is_probe_req(mgmt->frame_control))) {
- printk(KERN_WARNING "%s: Received non probe request frame\n",
- __func__);
- return _FAIL;
- }
-
- len -= offsetof(struct ieee80211_mgmt, u.probe_req.variable);
-
- ie = cfg80211_find_ie(WLAN_EID_SSID, mgmt->u.probe_req.variable, len);
-
- /* check (wildcard) SSID */
- if (!ie)
- goto out;
-
- if ((ie[1] && memcmp(ie + 2, cur->Ssid.ssid, cur->Ssid.ssid_len)) ||
- (ie[1] == 0 && pmlmeinfo->hidden_ssid_mode)) {
- return _SUCCESS;
- }
-
- if (check_fwstate(pmlmepriv, _FW_LINKED) &&
- pmlmepriv->cur_network.join_res)
- issue_probersp(padapter, mgmt->sa);
-
-out:
- return _SUCCESS;
-}
-
-static int
-OnProbeRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
- report_survey_event23a(padapter, precv_frame);
- return _SUCCESS;
- }
-
- return _SUCCESS;
-}
-
-static int
-OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- int cam_idx;
- struct sta_info *psta;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
- int pkt_len = skb->len;
- struct wlan_bssid_ex *pbss;
- int ret = _SUCCESS;
- u8 *p, *pie;
- int pie_len;
- u32 ielen = 0;
-
- pie = mgmt->u.beacon.variable;
- pie_len = pkt_len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
- p = rtw_get_ie23a(pie, WLAN_EID_EXT_SUPP_RATES, &ielen, pie_len);
- if (p && ielen > 0) {
- if (p[1 + ielen] == 0x2D && p[2 + ielen] != 0x2D) {
- /* Invalid value 0x2D is detected in Extended Supported
- * Rates (ESR) IE. Try to fix the IE length to avoid
- * failed Beacon parsing.
- */
- DBG_8723A("[WIFIDBG] Error in ESR IE is detected in "
- "Beacon of BSSID: %pM. Fix the length of "
- "ESR IE to avoid failed Beacon parsing.\n",
- mgmt->bssid);
- p[1] = ielen - 1;
- }
- }
-
- if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
- report_survey_event23a(padapter, precv_frame);
- return _SUCCESS;
- }
-
- if (!ether_addr_equal(mgmt->bssid,
- get_my_bssid23a(&pmlmeinfo->network)))
- goto out;
-
- if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
- /* we should update current network before auth,
- or some IE is wrong */
- pbss = collect_bss_info(padapter, precv_frame);
- if (pbss) {
- update_network23a(&pmlmepriv->cur_network.network, pbss,
- padapter, true);
- rtw_get_bcn_info23a(&pmlmepriv->cur_network);
- kfree(pbss);
- }
-
- /* check the vendor of the assoc AP */
- pmlmeinfo->assoc_AP_vendor =
- check_assoc_AP23a((u8 *)&mgmt->u.beacon, pkt_len -
- offsetof(struct ieee80211_mgmt, u));
-
- /* update TSF Value */
- rtw_update_TSF(pmlmeext, mgmt);
-
- /* start auth */
- start_clnt_auth(padapter);
-
- return _SUCCESS;
- }
-
- if (((pmlmeinfo->state & 0x03) == MSR_AP) &&
- (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
- psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
- if (psta) {
- ret = rtw_check_bcn_info23a(padapter, mgmt, pkt_len);
- if (ret != _SUCCESS) {
- DBG_8723A_LEVEL(_drv_always_, "ap has changed, "
- "disconnect now\n");
- receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress, 65535);
- return _SUCCESS;
- }
- /* update WMM, ERP in the beacon */
- /* todo: the timer is used instead of
- the number of the beacon received */
- if ((sta_rx_pkts(psta) & 0xf) == 0) {
- /* DBG_8723A("update_bcn_info\n"); */
- update_beacon23a_info(padapter, mgmt,
- pkt_len, psta);
- }
- }
- } else if ((pmlmeinfo->state&0x03) == MSR_ADHOC) {
- psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
- if (psta) {
- /* update WMM, ERP in the beacon */
- /* todo: the timer is used instead of the
- number of the beacon received */
- if ((sta_rx_pkts(psta) & 0xf) == 0) {
- /* DBG_8723A("update_bcn_info\n"); */
- update_beacon23a_info(padapter, mgmt,
- pkt_len, psta);
- }
- } else {
- /* allocate a new CAM entry for IBSS station */
- cam_idx = allocate_fw_sta_entry23a(padapter);
- if (cam_idx == NUM_STA)
- goto out;
-
- /* get supported rate */
- if (update_sta_support_rate23a(padapter, pie, pie_len,
- cam_idx) == _FAIL) {
- pmlmeinfo->FW_sta_info[cam_idx].status = 0;
- goto out;
- }
-
- /* update TSF Value */
- rtw_update_TSF(pmlmeext, mgmt);
-
- /* report sta add event */
- report_add_sta_event23a(padapter, mgmt->sa,
- cam_idx);
- }
- }
-
-out:
-
- return _SUCCESS;
-}
-
-#ifdef CONFIG_8723AU_AP_MODE
-static int
-OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- static struct sta_info stat;
- struct sta_info *pstat = NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
- u8 *pframe;
- const u8 *p;
- unsigned char *sa;
- u16 auth_mode, seq, algorithm;
- int status, len = skb->len;
-
- if ((pmlmeinfo->state & 0x03) != MSR_AP)
- return _FAIL;
-
- DBG_8723A("+OnAuth23a\n");
-
- sa = mgmt->sa;
-
- auth_mode = psecuritypriv->dot11AuthAlgrthm;
-
- pframe = mgmt->u.auth.variable;
- len = skb->len - offsetof(struct ieee80211_mgmt, u.auth.variable);
-
- seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
- algorithm = le16_to_cpu(mgmt->u.auth.auth_alg);
-
- DBG_8723A("auth alg =%x, seq =%X\n", algorithm, seq);
-
- if (auth_mode == 2 &&
- psecuritypriv->dot11PrivacyAlgrthm != WLAN_CIPHER_SUITE_WEP40 &&
- psecuritypriv->dot11PrivacyAlgrthm != WLAN_CIPHER_SUITE_WEP104)
- auth_mode = 0;
-
- /* rx a shared-key auth but shared not enabled, or */
- /* rx a open-system auth but shared-key is enabled */
- if ((algorithm != WLAN_AUTH_OPEN && auth_mode == 0) ||
- (algorithm == WLAN_AUTH_OPEN && auth_mode == 1)) {
- DBG_8723A("auth rejected due to bad alg [alg =%d, auth_mib "
- "=%d] %02X%02X%02X%02X%02X%02X\n",
- algorithm, auth_mode,
- sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
-
- status = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
-
- goto auth_fail;
- }
-
- if (rtw_access_ctrl23a(padapter, sa) == false) {
- status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
- goto auth_fail;
- }
-
- pstat = rtw_get_stainfo23a(pstapriv, sa);
- if (!pstat) {
- /* allocate a new one */
- DBG_8723A("going to alloc stainfo for sa =%pM\n", sa);
- pstat = rtw_alloc_stainfo23a(pstapriv, sa, GFP_ATOMIC);
- if (!pstat) {
- DBG_8723A(" Exceed the upper limit of supported "
- "clients...\n");
- status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
- goto auth_fail;
- }
-
- pstat->state = WIFI_FW_AUTH_NULL;
- pstat->auth_seq = 0;
-
- /* pstat->flags = 0; */
- /* pstat->capability = 0; */
- } else {
- spin_lock_bh(&pstapriv->asoc_list_lock);
- if (!list_empty(&pstat->asoc_list)) {
- list_del_init(&pstat->asoc_list);
- pstapriv->asoc_list_cnt--;
- if (pstat->expire_to > 0) {
- /* TODO: STA re_auth within expire_to */
- }
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
-
- if (seq == 1) {
- /* TODO: STA re_auth and auth timeout */
- }
- }
-
- spin_lock_bh(&pstapriv->auth_list_lock);
- if (list_empty(&pstat->auth_list)) {
- list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
- pstapriv->auth_list_cnt++;
- }
- spin_unlock_bh(&pstapriv->auth_list_lock);
-
- if (pstat->auth_seq == 0)
- pstat->expire_to = pstapriv->auth_to;
-
- if ((pstat->auth_seq + 1) != seq) {
- DBG_8723A("(1)auth rejected because out of seq [rx_seq =%d, "
- "exp_seq =%d]!\n", seq, pstat->auth_seq+1);
- status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
- goto auth_fail;
- }
-
- if (algorithm == WLAN_AUTH_OPEN && (auth_mode == 0 || auth_mode == 2)) {
- if (seq == 1) {
- pstat->state &= ~WIFI_FW_AUTH_NULL;
- pstat->state |= WIFI_FW_AUTH_SUCCESS;
- pstat->expire_to = pstapriv->assoc_to;
- pstat->authalg = algorithm;
- } else {
- DBG_8723A("(2)auth rejected because out of seq "
- "[rx_seq =%d, exp_seq =%d]!\n",
- seq, pstat->auth_seq+1);
- status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
- goto auth_fail;
- }
- } else { /* shared system or auto authentication */
- if (seq == 1) {
- /* prepare for the challenging txt... */
- pstat->state &= ~WIFI_FW_AUTH_NULL;
- pstat->state |= WIFI_FW_AUTH_STATE;
- pstat->authalg = algorithm;
- pstat->auth_seq = 2;
- } else if (seq == 3) {
- /* checking for challenging txt... */
- DBG_8723A("checking for challenging txt...\n");
-
- p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pframe, len);
- if (!p || p[1] <= 0) {
- DBG_8723A("auth rejected because challenge "
- "failure!(1)\n");
- status = WLAN_STATUS_CHALLENGE_FAIL;
- goto auth_fail;
- }
-
- if (!memcmp(p + 2, pstat->chg_txt, 128)) {
- pstat->state &= ~WIFI_FW_AUTH_STATE;
- pstat->state |= WIFI_FW_AUTH_SUCCESS;
- /* challenging txt is correct... */
- pstat->expire_to = pstapriv->assoc_to;
- } else {
- DBG_8723A("auth rejected because challenge "
- "failure!\n");
- status = WLAN_STATUS_CHALLENGE_FAIL;
- goto auth_fail;
- }
- } else {
- DBG_8723A("(3)auth rejected because out of seq "
- "[rx_seq =%d, exp_seq =%d]!\n",
- seq, pstat->auth_seq+1);
- status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
- goto auth_fail;
- }
- }
-
- /* Now, we are going to issue_auth... */
- pstat->auth_seq = seq + 1;
-
- issue_auth(padapter, pstat, WLAN_STATUS_SUCCESS);
-
- if (pstat->state & WIFI_FW_AUTH_SUCCESS)
- pstat->auth_seq = 0;
-
- return _SUCCESS;
-
-auth_fail:
-
- if (pstat)
- rtw_free_stainfo23a(padapter, pstat);
-
- pstat = &stat;
- memset((char *)pstat, '\0', sizeof(stat));
- pstat->auth_seq = 2;
- ether_addr_copy(pstat->hwaddr, sa);
-
- issue_auth(padapter, pstat, (unsigned short)status);
-
- return _FAIL;
-}
-#endif
-
-static int
-OnAuth23aClient23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- unsigned int seq, status, algthm;
- unsigned int go2asoc = 0;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
- const u8 *p;
- u8 *pie;
- int plen = skb->len;
-
- DBG_8723A("%s\n", __func__);
-
- /* check A1 matches or not */
- if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
- return _SUCCESS;
-
- if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
- return _SUCCESS;
-
- pie = mgmt->u.auth.variable;
- plen -= offsetof(struct ieee80211_mgmt, u.auth.variable);
-
- algthm = le16_to_cpu(mgmt->u.auth.auth_alg);
- seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
- status = le16_to_cpu(mgmt->u.auth.status_code);
-
- if (status) {
- DBG_8723A("clnt auth fail, status: %d\n", status);
- /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
- if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
- if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
- pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
- else
- pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
- /* pmlmeinfo->reauth_count = 0; */
- }
-
- set_link_timer(pmlmeext, 1);
- goto authclnt_fail;
- }
-
- if (seq == 2) {
- if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
- /* legendary shared system */
- p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pie, plen);
-
- if (!p) {
- /* DBG_8723A("marc: no challenge text?\n"); */
- goto authclnt_fail;
- }
-
- memcpy((void *)(pmlmeinfo->chg_txt), p + 2, p[1]);
- pmlmeinfo->auth_seq = 3;
- issue_auth(padapter, NULL, 0);
- set_link_timer(pmlmeext, REAUTH_TO);
-
- return _SUCCESS;
- } else {
- /* open system */
- go2asoc = 1;
- }
- } else if (seq == 4) {
- if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
- go2asoc = 1;
- else
- goto authclnt_fail;
- } else {
- /* this is also illegal */
- /* DBG_8723A("marc: clnt auth failed due to illegal seq =%x\n",
- seq); */
- goto authclnt_fail;
- }
-
- if (go2asoc) {
- DBG_8723A_LEVEL(_drv_always_, "auth success, start assoc\n");
- start_clnt_assoc(padapter);
- return _SUCCESS;
- }
-
-authclnt_fail:
-
- /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
-
- return _FAIL;
-}
-
-#ifdef CONFIG_8723AU_AP_MODE
-static int rtw_validate_vendor_specific_ies(const u8 *pos, int elen)
-{
- unsigned int oui;
-
- /* first 3 bytes in vendor specific information element are the IEEE
- * OUI of the vendor. The following byte is used a vendor specific
- * sub-type. */
- if (elen < 4) {
- DBG_8723A("short vendor specific information element "
- "ignored (len =%i)\n", elen);
- return -EINVAL;
- }
-
- oui = RTW_GET_BE24(pos);
- switch (oui) {
- case WLAN_OUI_MICROSOFT:
- /* Microsoft/Wi-Fi information elements are further typed and
- * subtyped */
- switch (pos[3]) {
- case WLAN_OUI_TYPE_MICROSOFT_WPA:
- /* Microsoft OUI (00:50:F2) with OUI Type 1:
- * real WPA information element */
- break;
- case WLAN_OUI_TYPE_MICROSOFT_WMM:
- if (elen < 5) {
- DBG_8723A("short WME information element "
- "ignored (len =%i)\n", elen);
- return -EINVAL;
- }
- switch (pos[4]) {
- case WME_OUI_SUBTYPE_INFORMATION_ELEMENT:
- case WME_OUI_SUBTYPE_PARAMETER_ELEMENT:
- break;
- case WME_OUI_SUBTYPE_TSPEC_ELEMENT:
- break;
- default:
- DBG_8723A("unknown WME information element "
- "ignored (subtype =%d len =%i)\n",
- pos[4], elen);
- return -EINVAL;
- }
- break;
- case WLAN_OUI_TYPE_MICROSOFT_WPS:
- /* Wi-Fi Protected Setup (WPS) IE */
- break;
- default:
- DBG_8723A("Unknown Microsoft information element "
- "ignored (type =%d len =%i)\n",
- pos[3], elen);
- return -EINVAL;
- }
- break;
-
- case OUI_BROADCOM:
- switch (pos[3]) {
- case VENDOR_HT_CAPAB_OUI_TYPE:
- break;
- default:
- DBG_8723A("Unknown Broadcom information element "
- "ignored (type =%d len =%i)\n", pos[3], elen);
- return -EINVAL;
- }
- break;
-
- default:
- DBG_8723A("unknown vendor specific information element "
- "ignored (vendor OUI %02x:%02x:%02x len =%i)\n",
- pos[0], pos[1], pos[2], elen);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int rtw_validate_frame_ies(const u8 *start, uint len)
-{
- const u8 *pos = start;
- int left = len;
- int unknown = 0;
-
- while (left >= 2) {
- u8 id, elen;
-
- id = *pos++;
- elen = *pos++;
- left -= 2;
-
- if (elen > left) {
- DBG_8723A("%s: IEEE 802.11 failed (id =%d elen =%d "
- "left =%i)\n", __func__, id, elen, left);
- return -EINVAL;
- }
-
- switch (id) {
- case WLAN_EID_SSID:
- case WLAN_EID_SUPP_RATES:
- case WLAN_EID_FH_PARAMS:
- case WLAN_EID_DS_PARAMS:
- case WLAN_EID_CF_PARAMS:
- case WLAN_EID_TIM:
- case WLAN_EID_IBSS_PARAMS:
- case WLAN_EID_CHALLENGE:
- case WLAN_EID_ERP_INFO:
- case WLAN_EID_EXT_SUPP_RATES:
- break;
- case WLAN_EID_VENDOR_SPECIFIC:
- if (rtw_validate_vendor_specific_ies(pos, elen))
- unknown++;
- break;
- case WLAN_EID_RSN:
- case WLAN_EID_PWR_CAPABILITY:
- case WLAN_EID_SUPPORTED_CHANNELS:
- case WLAN_EID_MOBILITY_DOMAIN:
- case WLAN_EID_FAST_BSS_TRANSITION:
- case WLAN_EID_TIMEOUT_INTERVAL:
- case WLAN_EID_HT_CAPABILITY:
- case WLAN_EID_HT_OPERATION:
- default:
- unknown++;
- DBG_8723A("%s IEEE 802.11 ignored unknown element "
- "(id =%d elen =%d)\n", __func__, id, elen);
- break;
- }
-
- left -= elen;
- pos += elen;
- }
-
- if (left)
- return -EINVAL;
-
- return 0;
-}
-#endif
-
-static int
-OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
-#ifdef CONFIG_8723AU_AP_MODE
- u16 capab_info, listen_interval;
- struct sta_info *pstat;
- unsigned char reassoc;
- int i, wpa_ie_len, left;
- unsigned char supportRate[16];
- int supportRateNum;
- unsigned short status = WLAN_STATUS_SUCCESS;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *cur = &pmlmeinfo->network;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
- const u8 *pos, *p, *wpa_ie, *wps_ie;
- u8 *pframe = skb->data;
- uint pkt_len = skb->len;
- int r;
-
- if ((pmlmeinfo->state & 0x03) != MSR_AP)
- return _FAIL;
-
- left = pkt_len - sizeof(struct ieee80211_hdr_3addr);
- if (ieee80211_is_assoc_req(mgmt->frame_control)) {
- reassoc = 0;
- pos = mgmt->u.assoc_req.variable;
- left -= offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
- } else { /* WIFI_REASSOCREQ */
- reassoc = 1;
- pos = mgmt->u.reassoc_req.variable;
- left -= offsetof(struct ieee80211_mgmt, u.reassoc_req.variable);
- }
-
- if (left < 0) {
- DBG_8723A("handle_assoc(reassoc =%d) - too short payload "
- "(len =%lu)\n", reassoc, (unsigned long)pkt_len);
- return _FAIL;
- }
-
- pstat = rtw_get_stainfo23a(pstapriv, mgmt->sa);
- if (!pstat) {
- status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
- goto asoc_class2_error;
- }
-
- /* These two are located at the same offsets whether it's an
- * assoc_req or a reassoc_req */
- capab_info = get_unaligned_le16(&mgmt->u.assoc_req.capab_info);
- listen_interval =
- get_unaligned_le16(&mgmt->u.assoc_req.listen_interval);
-
- DBG_8723A("%s\n", __func__);
-
- /* check if this stat has been successfully authenticated/assocated */
- if (!(pstat->state & WIFI_FW_AUTH_SUCCESS)) {
- if (!(pstat->state & WIFI_FW_ASSOC_SUCCESS)) {
- status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
- goto asoc_class2_error;
- } else {
- pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
- pstat->state |= WIFI_FW_ASSOC_STATE;
- }
- } else {
- pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
- pstat->state |= WIFI_FW_ASSOC_STATE;
- }
-
- pstat->capability = capab_info;
-
- /* now parse all ieee802_11 ie to point to elems */
-
- if (rtw_validate_frame_ies(pos, left)) {
- DBG_8723A("STA %pM sent invalid association request\n",
- pstat->hwaddr);
- status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- goto OnAssocReq23aFail;
- }
-
- /* now we should check all the fields... */
- /* checking SSID */
- p = cfg80211_find_ie(WLAN_EID_SSID, pos, left);
- if (!p || p[1] == 0) {
- /* broadcast ssid, however it is not allowed in assocreq */
- DBG_8723A("STA %pM sent invalid association request lacking an SSID\n",
- pstat->hwaddr);
- status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- goto OnAssocReq23aFail;
- } else {
- /* check if ssid match */
- if (memcmp(p + 2, cur->Ssid.ssid, cur->Ssid.ssid_len))
- status = WLAN_STATUS_UNSPECIFIED_FAILURE;
-
- if (p[1] != cur->Ssid.ssid_len)
- status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- }
-
- if (status != WLAN_STATUS_SUCCESS)
- goto OnAssocReq23aFail;
-
- /* check if the supported rate is ok */
- p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, pos, left);
- if (!p) {
- DBG_8723A("Rx a sta assoc-req which supported rate is "
- "empty!\n");
- /* use our own rate set as statoin used */
- /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
- /* supportRateNum = AP_BSSRATE_LEN; */
-
- status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- goto OnAssocReq23aFail;
- } else {
- memcpy(supportRate, p + 2, p[1]);
- supportRateNum = p[1];
-
- p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, pos, left);
- if (p) {
- if (supportRateNum <= sizeof(supportRate)) {
- memcpy(supportRate+supportRateNum, p + 2, p[1]);
- supportRateNum += p[1];
- }
- }
- }
-
- /* todo: mask supportRate between AP & STA -> move to update raid */
- /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
-
- /* update station supportRate */
- pstat->bssratelen = supportRateNum;
- memcpy(pstat->bssrateset, supportRate, supportRateNum);
- Update23aTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
-
- /* check RSN/WPA/WPS */
- pstat->dot8021xalg = 0;
- pstat->wpa_psk = 0;
- pstat->wpa_group_cipher = 0;
- pstat->wpa2_group_cipher = 0;
- pstat->wpa_pairwise_cipher = 0;
- pstat->wpa2_pairwise_cipher = 0;
- memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
-
- wpa_ie = cfg80211_find_ie(WLAN_EID_RSN, pos, left);
- if (!wpa_ie)
- wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WPA,
- pos, left);
- if (wpa_ie) {
- int group_cipher = 0, pairwise_cipher = 0;
-
- wpa_ie_len = wpa_ie[1];
- if (psecuritypriv->wpa_psk & BIT(1)) {
- r = rtw_parse_wpa2_ie23a(wpa_ie, wpa_ie_len + 2,
- &group_cipher,
- &pairwise_cipher, NULL);
- if (r == _SUCCESS) {
- pstat->dot8021xalg = 1;/* psk, todo:802.1x */
- pstat->wpa_psk |= BIT(1);
-
- pstat->wpa2_group_cipher = group_cipher &
- psecuritypriv->wpa2_group_cipher;
- pstat->wpa2_pairwise_cipher = pairwise_cipher &
- psecuritypriv->wpa2_pairwise_cipher;
- } else
- status = WLAN_STATUS_INVALID_IE;
- } else if (psecuritypriv->wpa_psk & BIT(0)) {
- r = rtw_parse_wpa_ie23a(wpa_ie, wpa_ie_len + 2,
- &group_cipher, &pairwise_cipher,
- NULL);
- if (r == _SUCCESS) {
- pstat->dot8021xalg = 1;/* psk, todo:802.1x */
- pstat->wpa_psk |= BIT(0);
-
- pstat->wpa_group_cipher = group_cipher &
- psecuritypriv->wpa_group_cipher;
- pstat->wpa_pairwise_cipher = pairwise_cipher &
- psecuritypriv->wpa_pairwise_cipher;
- } else
- status = WLAN_STATUS_INVALID_IE;
- } else {
- wpa_ie = NULL;
- wpa_ie_len = 0;
- }
- if (wpa_ie && status == WLAN_STATUS_SUCCESS) {
- if (!pstat->wpa_group_cipher)
- status = WLAN_STATUS_INVALID_GROUP_CIPHER;
-
- if (!pstat->wpa_pairwise_cipher)
- status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
- }
- }
-
- if (status != WLAN_STATUS_SUCCESS)
- goto OnAssocReq23aFail;
-
- pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
-
- wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WPS,
- pos, left);
-
- if (!wpa_ie) {
- if (wps_ie) {
- DBG_8723A("STA included WPS IE in (Re)Association "
- "Request - assume WPS is used\n");
- pstat->flags |= WLAN_STA_WPS;
- } else {
- DBG_8723A("STA did not include WPA/RSN IE in (Re)"
- "Association Request - possible WPS use\n");
- pstat->flags |= WLAN_STA_MAYBE_WPS;
- }
- } else {
- int copy_len;
-
- if (psecuritypriv->wpa_psk == 0) {
- DBG_8723A("STA %pM: WPA/RSN IE in association request, but AP don't support WPA/RSN\n",
- pstat->hwaddr);
-
- status = WLAN_STATUS_INVALID_IE;
-
- goto OnAssocReq23aFail;
- }
-
- if (wps_ie) {
- DBG_8723A("STA included WPS IE in (Re)Association "
- "Request - WPS is used\n");
- pstat->flags |= WLAN_STA_WPS;
- copy_len = 0;
- } else {
- copy_len = ((wpa_ie_len + 2) > sizeof(pstat->wpa_ie)) ?
- sizeof(pstat->wpa_ie) : (wpa_ie_len + 2);
- }
-
- if (copy_len > 0)
- memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len);
- }
-
- /* check if there is WMM IE & support WWM-PS */
- pstat->flags &= ~WLAN_STA_WME;
- pstat->qos_option = 0;
- pstat->qos_info = 0;
- pstat->has_legacy_ac = true;
- pstat->uapsd_vo = 0;
- pstat->uapsd_vi = 0;
- pstat->uapsd_be = 0;
- pstat->uapsd_bk = 0;
- if (pmlmepriv->qos_option) {
- const u8 *end = pos + left;
-
- p = pos;
-
- for (;;) {
- left = end - p;
- p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WMM,
- p, left);
- if (p) {
- pstat->flags |= WLAN_STA_WME;
-
- pstat->qos_option = 1;
- pstat->qos_info = *(p + 8);
-
- pstat->max_sp_len =
- (pstat->qos_info >> 5) & 0x3;
-
- if ((pstat->qos_info & 0xf) != 0xf)
- pstat->has_legacy_ac = true;
- else
- pstat->has_legacy_ac = false;
-
- if (pstat->qos_info & 0xf) {
- if (pstat->qos_info & BIT(0))
- pstat->uapsd_vo = BIT(0)|BIT(1);
- else
- pstat->uapsd_vo = 0;
-
- if (pstat->qos_info & BIT(1))
- pstat->uapsd_vi = BIT(0)|BIT(1);
- else
- pstat->uapsd_vi = 0;
-
- if (pstat->qos_info & BIT(2))
- pstat->uapsd_bk = BIT(0)|BIT(1);
- else
- pstat->uapsd_bk = 0;
-
- if (pstat->qos_info & BIT(3))
- pstat->uapsd_be = BIT(0)|BIT(1);
- else
- pstat->uapsd_be = 0;
-
- break;
- }
- } else {
- break;
- }
- p = p + p[1] + 2;
- }
- }
-
- /* save HT capabilities in the sta object */
- memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pos, left);
-
- if (p && p[1] >= sizeof(struct ieee80211_ht_cap)) {
- pstat->flags |= WLAN_STA_HT;
-
- pstat->flags |= WLAN_STA_WME;
-
- memcpy(&pstat->htpriv.ht_cap, p + 2,
- sizeof(struct ieee80211_ht_cap));
- } else
- pstat->flags &= ~WLAN_STA_HT;
-
- if (!pmlmepriv->htpriv.ht_option && pstat->flags & WLAN_STA_HT){
- status = WLAN_STATUS_UNSPECIFIED_FAILURE;
- goto OnAssocReq23aFail;
- }
-
- if (pstat->flags & WLAN_STA_HT &&
- (pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP ||
- pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) {
- DBG_8723A("HT: %pM tried to use TKIP with HT association\n",
- pstat->hwaddr);
-
- /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
- /* goto OnAssocReq23aFail; */
- }
-
- pstat->flags |= WLAN_STA_NONERP;
- for (i = 0; i < pstat->bssratelen; i++) {
- if ((pstat->bssrateset[i] & 0x7f) > 22) {
- pstat->flags &= ~WLAN_STA_NONERP;
- break;
- }
- }
-
- if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
- pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
- else
- pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
-
- if (status != WLAN_STATUS_SUCCESS)
- goto OnAssocReq23aFail;
-
- /* TODO: identify_proprietary_vendor_ie(); */
- /* Realtek proprietary IE */
- /* identify if this is Broadcom sta */
- /* identify if this is ralink sta */
- /* Customer proprietary IE */
-
- /* get a unique AID */
- if (pstat->aid > 0) {
- DBG_8723A(" old AID %d\n", pstat->aid);
- } else {
- for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
- if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
- break;
-
- if (pstat->aid > NUM_STA)
- pstat->aid = NUM_STA;
- if (pstat->aid > pstapriv->max_num_sta) {
-
- pstat->aid = 0;
-
- DBG_8723A(" no room for more AIDs\n");
-
- status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
-
- goto OnAssocReq23aFail;
- } else {
- pstapriv->sta_aid[pstat->aid - 1] = pstat;
- DBG_8723A("allocate new AID = (%d)\n", pstat->aid);
- }
- }
-
- pstat->state &= ~WIFI_FW_ASSOC_STATE;
- pstat->state |= WIFI_FW_ASSOC_SUCCESS;
-
- spin_lock_bh(&pstapriv->auth_list_lock);
- if (!list_empty(&pstat->auth_list)) {
- list_del_init(&pstat->auth_list);
- pstapriv->auth_list_cnt--;
- }
- spin_unlock_bh(&pstapriv->auth_list_lock);
-
- spin_lock_bh(&pstapriv->asoc_list_lock);
- if (list_empty(&pstat->asoc_list)) {
- pstat->expire_to = pstapriv->expire_to;
- list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
- pstapriv->asoc_list_cnt++;
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
-
- /* now the station is qualified to join our BSS... */
- if (pstat->state & WIFI_FW_ASSOC_SUCCESS &&
- status == WLAN_STATUS_SUCCESS) {
- /* 1 bss_cap_update & sta_info_update23a */
- bss_cap_update_on_sta_join23a(padapter, pstat);
- sta_info_update23a(padapter, pstat);
-
- /* issue assoc rsp before notify station join event. */
- if (ieee80211_is_assoc_req(mgmt->frame_control))
- issue_assocrsp(padapter, status, pstat,
- IEEE80211_STYPE_ASSOC_RESP);
- else
- issue_assocrsp(padapter, status, pstat,
- IEEE80211_STYPE_REASSOC_RESP);
-
- /* 2 - report to upper layer */
- DBG_8723A("indicate_sta_join_event to upper layer - hostapd\n");
- rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
-
- /* 3-(1) report sta add event */
- report_add_sta_event23a(padapter, pstat->hwaddr, pstat->aid);
- }
-
- return _SUCCESS;
-
-asoc_class2_error:
-
- issue_deauth23a(padapter, mgmt->sa, status);
- return _FAIL;
-
-OnAssocReq23aFail:
-
- pstat->aid = 0;
- if (ieee80211_is_assoc_req(mgmt->frame_control))
- issue_assocrsp(padapter, status, pstat,
- IEEE80211_STYPE_ASSOC_RESP);
- else
- issue_assocrsp(padapter, status, pstat,
- IEEE80211_STYPE_REASSOC_RESP);
-
-#endif /* CONFIG_8723AU_AP_MODE */
-
- return _FAIL;
-}
-
-static int
-OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_mgmt *pmgmt = (struct ieee80211_mgmt *) skb->data;
- int res;
- unsigned short status;
- const u8 *p, *pie;
- u8 *pframe = skb->data;
- int pkt_len = skb->len;
- int pielen;
-
- DBG_8723A("%s\n", __func__);
-
- /* check A1 matches or not */
- if (!ether_addr_equal(myid(&padapter->eeprompriv), pmgmt->da))
- return _SUCCESS;
-
- if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
- return _SUCCESS;
-
- if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
- return _SUCCESS;
-
- del_timer_sync(&pmlmeext->link_timer);
-
- /* status */
- status = le16_to_cpu(pmgmt->u.assoc_resp.status_code);
- if (status > 0) {
- DBG_8723A("assoc reject, status code: %d\n", status);
- pmlmeinfo->state = MSR_NOLINK;
- res = -4;
- goto report_assoc_result;
- }
-
- /* get capabilities */
- pmlmeinfo->capability = le16_to_cpu(pmgmt->u.assoc_resp.capab_info);
-
- /* set slot time */
- pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
-
- /* AID */
- res = pmlmeinfo->aid = le16_to_cpu(pmgmt->u.assoc_resp.aid) & 0x3fff;
-
- pie = pframe + offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
- pielen = pkt_len -
- offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
-
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
- pmgmt->u.assoc_resp.variable, pielen);
- if (p && p[1])
- HT_caps_handler23a(padapter, p);
-
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
- pmgmt->u.assoc_resp.variable, pielen);
- if (p && p[1])
- HT_info_handler23a(padapter, p);
-
- p = cfg80211_find_ie(WLAN_EID_ERP_INFO,
- pmgmt->u.assoc_resp.variable, pielen);
- if (p && p[1])
- ERP_IE_handler23a(padapter, p);
-
- pie = pframe + offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
- while (true) {
- p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WMM,
- pie, pframe + pkt_len - pie);
- if (!p)
- break;
-
- pie = p + p[1] + 2;
- /* if this IE is too short, try the next */
- if (p[1] <= 4)
- continue;
- /* if this IE is WMM params, we found what we wanted */
- if (p[6] == 1)
- break;
- }
-
- if (p && p[1])
- WMM_param_handler23a(padapter, p);
-
- pmlmeinfo->state &= ~WIFI_FW_ASSOC_STATE;
- pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
-
- /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
- UpdateBrateTbl23a(padapter, pmlmeinfo->network.SupportedRates);
-
-report_assoc_result:
- pmlmepriv->assoc_rsp_len = 0;
- if (res > 0) {
- kfree(pmlmepriv->assoc_rsp);
- pmlmepriv->assoc_rsp = kmalloc(pkt_len, GFP_ATOMIC);
- if (pmlmepriv->assoc_rsp) {
- memcpy(pmlmepriv->assoc_rsp, pframe, pkt_len);
- pmlmepriv->assoc_rsp_len = pkt_len;
- }
- } else
- kfree(pmlmepriv->assoc_rsp);
-
- report_join_res23a(padapter, res);
-
- return _SUCCESS;
-}
-
-static int
-OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- unsigned short reason;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
-
- if (!ether_addr_equal(mgmt->bssid,
- get_my_bssid23a(&pmlmeinfo->network)))
- return _SUCCESS;
-
- reason = le16_to_cpu(mgmt->u.deauth.reason_code);
-
- DBG_8723A("%s Reason code(%d)\n", __func__, reason);
-
-#ifdef CONFIG_8723AU_AP_MODE
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
- struct sta_info *psta;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- DBG_8723A_LEVEL(_drv_always_, "ap recv deauth reason code(%d) "
- "sta:%pM\n", reason, mgmt->sa);
-
- psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
- if (psta) {
- u8 updated = 0;
-
- spin_lock_bh(&pstapriv->asoc_list_lock);
- if (!list_empty(&psta->asoc_list)) {
- list_del_init(&psta->asoc_list);
- pstapriv->asoc_list_cnt--;
- updated = ap_free_sta23a(padapter, psta,
- false, reason);
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
-
- associated_clients_update23a(padapter, updated);
- }
-
- return _SUCCESS;
- } else
-#endif
- {
- DBG_8723A_LEVEL(_drv_always_, "sta recv deauth reason code(%d) "
- "sta:%pM\n", reason, mgmt->bssid);
-
- receive_disconnect23a(padapter, mgmt->bssid, reason);
- }
- pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
-
- return _SUCCESS;
-}
-
-static int
-OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- unsigned short reason;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
-
- if (!ether_addr_equal(mgmt->bssid,
- get_my_bssid23a(&pmlmeinfo->network)))
- return _SUCCESS;
-
- reason = le16_to_cpu(mgmt->u.disassoc.reason_code);
-
- DBG_8723A("%s Reason code(%d)\n", __func__, reason);
-
-#ifdef CONFIG_8723AU_AP_MODE
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
- struct sta_info *psta;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason code(%d)"
- " sta:%pM\n", reason, mgmt->sa);
-
- psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
- if (psta) {
- u8 updated = 0;
-
- spin_lock_bh(&pstapriv->asoc_list_lock);
- if (!list_empty(&psta->asoc_list)) {
- list_del_init(&psta->asoc_list);
- pstapriv->asoc_list_cnt--;
- updated = ap_free_sta23a(padapter, psta,
- false, reason);
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
-
- associated_clients_update23a(padapter, updated);
- }
-
- return _SUCCESS;
- } else
-#endif
- {
- DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason "
- "code(%d) sta:%pM\n", reason, mgmt->bssid);
-
- receive_disconnect23a(padapter, mgmt->bssid, reason);
- }
- pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
- return _SUCCESS;
-}
-
-static int
-OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- DBG_8723A("%s\n", __func__);
- return _SUCCESS;
-}
-
-static int
-on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- return _FAIL;
-}
-
-static int
-OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- return _SUCCESS;
-}
-
-static int
-OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- return _SUCCESS;
-}
-
-static int OnAction23a_back23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
- u8 *addr;
- struct sta_info *psta = NULL;
- struct recv_reorder_ctrl *preorder_ctrl;
- unsigned char category, action;
- unsigned short tid, status, capab, params, reason_code = 0;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- /* check RA matches or not */
- if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
- return _SUCCESS;
-
- DBG_8723A("%s\n", __func__);
-
- if ((pmlmeinfo->state&0x03) != MSR_AP)
- if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
- return _SUCCESS;
-
- addr = mgmt->sa;
- psta = rtw_get_stainfo23a(pstapriv, addr);
-
- if (!psta)
- return _SUCCESS;
-
- category = mgmt->u.action.category;
- if (category == WLAN_CATEGORY_BACK) { /* representing Block Ack */
- if (!pmlmeinfo->HT_enable)
- return _SUCCESS;
- /* action_code is located in the same place for all
- action events, so pick any */
- action = mgmt->u.action.u.wme_action.action_code;
- DBG_8723A("%s, action =%d\n", __func__, action);
- switch (action) {
- case WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
- memcpy(&pmlmeinfo->ADDBA_req,
- &mgmt->u.action.u.addba_req.dialog_token,
- sizeof(struct ADDBA_request));
- process_addba_req23a(padapter,
- (u8 *)&pmlmeinfo->ADDBA_req, addr);
- if (pmlmeinfo->bAcceptAddbaReq == true)
- issue_action_BA23a(padapter, addr,
- WLAN_ACTION_ADDBA_RESP, 0);
- else {
- /* reject ADDBA Req */
- issue_action_BA23a(padapter, addr,
- WLAN_ACTION_ADDBA_RESP, 37);
- }
- break;
- case WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
- status = get_unaligned_le16(
- &mgmt->u.action.u.addba_resp.status);
- capab = get_unaligned_le16(
- &mgmt->u.action.u.addba_resp.capab);
- tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
- if (status == 0) { /* successful */
- DBG_8723A("agg_enable for TID =%d\n", tid);
- psta->htpriv.agg_enable_bitmap |= BIT(tid);
- psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
- } else
- psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
- break;
-
- case WLAN_ACTION_DELBA: /* DELBA */
- params = get_unaligned_le16(
- &mgmt->u.action.u.delba.params);
- tid = params >> 12;
-
- if (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) {
- preorder_ctrl = &psta->recvreorder_ctrl[tid];
- preorder_ctrl->enable = false;
- preorder_ctrl->indicate_seq = 0xffff;
- } else {
- psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
- psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
- }
- reason_code = get_unaligned_le16(
- &mgmt->u.action.u.delba.reason_code);
- /* todo: how to notify the host while receiving
- DELETE BA */
- break;
- default:
- break;
- }
- }
- return _SUCCESS;
-}
-
-static int on_action_public23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u8 *pframe = skb->data;
- int freq, channel;
-
- /* check RA matches or not */
- if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
- return _FAIL;
-
- channel = rtw_get_oper_ch23a(padapter);
-
- if (channel <= RTW_CH_MAX_2G_CHANNEL)
- freq = ieee80211_channel_to_frequency(channel,
- NL80211_BAND_2GHZ);
- else
- freq = ieee80211_channel_to_frequency(channel,
- NL80211_BAND_5GHZ);
-
- if (cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, pframe,
- skb->len, 0))
- return _SUCCESS;
-
- return _FAIL;
-}
-
-static int
-OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- return _SUCCESS;
-}
-
-static int
-OnAction23a_wmm(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- return _SUCCESS;
-}
-
-static int
-OnAction23a_p2p(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- return _SUCCESS;
-}
-
-static int
-OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
-{
- int i;
- u8 category;
- struct action_handler *ptable;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
-
- category = mgmt->u.action.category;
-
- for (i = 0; i < ARRAY_SIZE(OnAction23a_tbl); i++) {
- ptable = &OnAction23a_tbl[i];
-
- if (category == ptable->num)
- ptable->func(padapter, precv_frame);
- }
-
- return _SUCCESS;
-}
-
-static int DoReserved23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
- return _SUCCESS;
-}
-
-struct xmit_frame *alloc_mgtxmitframe23a(struct xmit_priv *pxmitpriv)
-{
- struct xmit_frame *pmgntframe;
- struct xmit_buf *pxmitbuf;
-
- pmgntframe = rtw_alloc_xmitframe23a_ext(pxmitpriv);
-
- if (!pmgntframe) {
- DBG_8723A("%s(%s): alloc xmitframe fail\n", __func__,
- pxmitpriv->adapter->pnetdev->name);
- goto exit;
- }
-
- pxmitbuf = rtw_alloc_xmitbuf23a_ext(pxmitpriv);
- if (!pxmitbuf) {
- DBG_8723A("%s(%s): alloc xmitbuf fail\n", __func__,
- pxmitpriv->adapter->pnetdev->name);
- rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
- pmgntframe = NULL;
- goto exit;
- }
-
- pmgntframe->frame_tag = MGNT_FRAMETAG;
- pmgntframe->pxmitbuf = pxmitbuf;
- pmgntframe->buf_addr = pxmitbuf->pbuf;
- pxmitbuf->priv_data = pmgntframe;
-
-exit:
- return pmgntframe;
-}
-
-/****************************************************************************
-
-Following are some TX functions for WiFi MLME
-
-*****************************************************************************/
-
-void update_mgnt_tx_rate23a(struct rtw_adapter *padapter, u8 rate)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- pmlmeext->tx_rate = rate;
- DBG_8723A("%s(): rate = %x\n", __func__, rate);
-}
-
-void update_mgntframe_attrib23a(struct rtw_adapter *padapter,
- struct pkt_attrib *pattrib)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- memset((u8 *)pattrib, 0, sizeof(struct pkt_attrib));
-
- pattrib->hdrlen = 24;
- pattrib->nr_frags = 1;
- pattrib->priority = 7;
- pattrib->mac_id = 0;
- pattrib->qsel = 0x12;
-
- pattrib->pktlen = 0;
-
- if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
- pattrib->raid = 6;/* b mode */
- else
- pattrib->raid = 5;/* a/g mode */
-
- pattrib->encrypt = 0;
- pattrib->bswenc = false;
-
- pattrib->qos_en = false;
- pattrib->ht_en = false;
- pattrib->bwmode = HT_CHANNEL_WIDTH_20;
- pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- pattrib->sgi = false;
-
- pattrib->seqnum = pmlmeext->mgnt_seq;
-
- pattrib->retry_ctrl = true;
-}
-
-void dump_mgntframe23a(struct rtw_adapter *padapter,
- struct xmit_frame *pmgntframe)
-{
- if (padapter->bSurpriseRemoved == true ||
- padapter->bDriverStopped == true)
- return;
-
- rtl8723au_mgnt_xmit(padapter, pmgntframe);
-}
-
-int dump_mgntframe23a_and_wait(struct rtw_adapter *padapter,
- struct xmit_frame *pmgntframe, int timeout_ms)
-{
- int ret = _FAIL;
- unsigned long irqL;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
- struct submit_ctx sctx;
-
- if (padapter->bSurpriseRemoved == true ||
- padapter->bDriverStopped == true)
- return ret;
-
- rtw_sctx_init23a(&sctx, timeout_ms);
- pxmitbuf->sctx = &sctx;
-
- ret = rtl8723au_mgnt_xmit(padapter, pmgntframe);
-
- if (ret == _SUCCESS)
- ret = rtw_sctx_wait23a(&sctx);
-
- spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
- pxmitbuf->sctx = NULL;
- spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
-
- return ret;
-}
-
-int dump_mgntframe23a_and_wait_ack23a(struct rtw_adapter *padapter,
- struct xmit_frame *pmgntframe)
-{
- int ret = _FAIL;
- u32 timeout_ms = 500;/* 500ms */
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- if (padapter->bSurpriseRemoved == true ||
- padapter->bDriverStopped == true)
- return _FAIL;
-
- mutex_lock(&pxmitpriv->ack_tx_mutex);
- pxmitpriv->ack_tx = true;
-
- pmgntframe->ack_report = 1;
- if (rtl8723au_mgnt_xmit(padapter, pmgntframe) == _SUCCESS)
- ret = rtw_ack_tx_wait23a(pxmitpriv, timeout_ms);
-
- pxmitpriv->ack_tx = false;
- mutex_unlock(&pxmitpriv->ack_tx_mutex);
-
- return ret;
-}
-
-static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
-{
- u8 *ssid_ie;
- int ssid_len_ori;
- int len_diff = 0;
- u8 *next_ie;
- u32 remain_len;
-
- ssid_ie = rtw_get_ie23a(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
-
- /* DBG_8723A("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n",
- __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
-
- if (ssid_ie && ssid_len_ori > 0) {
- switch (hidden_ssid_mode) {
- case 1:
- next_ie = ssid_ie + 2 + ssid_len_ori;
- remain_len = ies_len -(next_ie-ies);
-
- ssid_ie[1] = 0;
- memcpy(ssid_ie+2, next_ie, remain_len);
- len_diff -= ssid_len_ori;
-
- break;
- case 2:
- memset(&ssid_ie[2], 0, ssid_len_ori);
- break;
- default:
- break;
- }
- }
-
- return len_diff;
-}
-
-void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_mgmt *mgmt;
- unsigned int rate_len;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
- u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- const u8 *wps_ie;
- u8 sr = 0;
- int len_diff;
-
- /* DBG_8723A("%s\n", __func__); */
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (!pmgntframe) {
- DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
- return;
- }
-#ifdef CONFIG_8723AU_AP_MODE
- spin_lock_bh(&pmlmepriv->bcn_update_lock);
-#endif
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
- pattrib->qsel = 0x10;
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- mgmt = (struct ieee80211_mgmt *)pframe;
-
- mgmt->frame_control =
- cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
- mgmt->seq_ctrl = 0;
-
- ether_addr_copy(mgmt->da, bc_addr);
- ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
- ether_addr_copy(mgmt->bssid, get_my_bssid23a(cur_network));
-
- /* timestamp will be inserted by hardware */
-
- put_unaligned_le16(cur_network->beacon_interval,
- &mgmt->u.beacon.beacon_int);
-
- put_unaligned_le16(cur_network->capability,
- &mgmt->u.beacon.capab_info);
-
- pframe = mgmt->u.beacon.variable;
- pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
-
- if ((pmlmeinfo->state & 0x03) == MSR_AP) {
- u8 *iebuf;
- int buflen;
- /* DBG_8723A("ie len =%d\n", cur_network->IELength); */
- memcpy(pframe, cur_network->IEs, cur_network->IELength);
- len_diff = update_hidden_ssid(pframe, cur_network->IELength,
- pmlmeinfo->hidden_ssid_mode);
- pframe += (cur_network->IELength+len_diff);
- pattrib->pktlen += (cur_network->IELength+len_diff);
-
- iebuf = mgmt->u.beacon.variable;
- buflen = pattrib->pktlen -
- offsetof(struct ieee80211_mgmt, u.beacon.variable);
- wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WPS,
- iebuf, buflen);
-
- if (wps_ie && wps_ie[1] > 0) {
- rtw_get_wps_attr_content23a(wps_ie, wps_ie[1],
- WPS_ATTR_SELECTED_REGISTRAR,
- (u8 *)&sr);
- }
- if (sr != 0)
- set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
- else
- _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
-
- goto _issue_bcn;
- }
-
- /* SSID */
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
- cur_network->Ssid.ssid_len,
- cur_network->Ssid.ssid, &pattrib->pktlen);
-
- /* supported rates... */
- rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
- ((rate_len > 8)? 8: rate_len),
- cur_network->SupportedRates, &pattrib->pktlen);
-
- /* DS parameter set */
- pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)
- &cur_network->DSConfig, &pattrib->pktlen);
-
- /* if ((pmlmeinfo->state&0x03) == MSR_ADHOC) */
- {
- u8 erpinfo = 0;
- u32 ATIMWindow;
- /* IBSS Parameter Set... */
- /* ATIMWindow = cur->ATIMWindow; */
- ATIMWindow = 0;
- pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
- (unsigned char *)&ATIMWindow,
- &pattrib->pktlen);
-
- /* ERP IE */
- pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
- &erpinfo, &pattrib->pktlen);
- }
-
- /* EXTERNDED SUPPORTED RATE */
- if (rate_len > 8)
- pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
- rate_len - 8,
- cur_network->SupportedRates + 8,
- &pattrib->pktlen);
-
- /* todo:HT for adhoc */
-
-_issue_bcn:
-
-#ifdef CONFIG_8723AU_AP_MODE
- pmlmepriv->update_bcn = false;
-
- spin_unlock_bh(&pmlmepriv->bcn_update_lock);
-#endif
-
- if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
- DBG_8723A("beacon frame too large\n");
- return;
- }
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- /* DBG_8723A("issue bcn_sz =%d\n", pattrib->last_txcmdsz); */
- if (timeout_ms > 0)
- dump_mgntframe23a_and_wait(padapter, pmgntframe, timeout_ms);
- else
- dump_mgntframe23a(padapter, pmgntframe);
-}
-
-static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_mgmt *mgmt;
- unsigned char *mac, *bssid;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-#ifdef CONFIG_8723AU_AP_MODE
- const u8 *pwps_ie;
- u8 *ssid_ie;
- int ssid_ielen;
- int ssid_ielen_diff;
- u8 buf[MAX_IE_SZ];
-#endif
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
- unsigned int rate_len;
-
- /* DBG_8723A("%s\n", __func__); */
-
- if (cur_network->IELength > MAX_IE_SZ)
- return;
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (!pmgntframe) {
- DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
- return;
- }
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
- mgmt = (struct ieee80211_mgmt *)pframe;
-
- mac = myid(&padapter->eeprompriv);
- bssid = cur_network->MacAddress;
-
- mgmt->frame_control =
- cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
-
- ether_addr_copy(mgmt->da, da);
- ether_addr_copy(mgmt->sa, mac);
- ether_addr_copy(mgmt->bssid, bssid);
-
- mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
- pmlmeext->mgnt_seq++;
-
- pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
-
- /* timestamp will be inserted by hardware */
- put_unaligned_le16(cur_network->beacon_interval,
- &mgmt->u.probe_resp.beacon_int);
-
- put_unaligned_le16(cur_network->capability,
- &mgmt->u.probe_resp.capab_info);
-
- pframe = mgmt->u.probe_resp.variable;
- pattrib->pktlen =
- offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
-
- /* below for ad-hoc mode */
-
-#ifdef CONFIG_8723AU_AP_MODE
- if ((pmlmeinfo->state & 0x03) == MSR_AP) {
- pwps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WPS,
- cur_network->IEs,
- cur_network->IELength);
-
- memcpy(pframe, cur_network->IEs, cur_network->IELength);
- pframe += cur_network->IELength;
- pattrib->pktlen += cur_network->IELength;
-
- /* retrieve SSID IE from cur_network->Ssid */
-
- ssid_ie = rtw_get_ie23a(mgmt->u.probe_resp.variable,
- WLAN_EID_SSID, &ssid_ielen,
- pframe - mgmt->u.probe_resp.variable);
-
- ssid_ielen_diff = cur_network->Ssid.ssid_len - ssid_ielen;
-
- if (ssid_ie && cur_network->Ssid.ssid_len) {
- uint remainder_ielen;
- u8 *remainder_ie;
-
- remainder_ie = ssid_ie + 2;
-
- remainder_ielen = pframe - remainder_ie;
-
- DBG_8723A_LEVEL(_drv_warning_, "%s(%s): "
- "remainder_ielen > MAX_IE_SZ\n",
- __func__, padapter->pnetdev->name);
- if (remainder_ielen > MAX_IE_SZ)
- remainder_ielen = MAX_IE_SZ;
-
- memcpy(buf, remainder_ie, remainder_ielen);
- memcpy(remainder_ie + ssid_ielen_diff, buf,
- remainder_ielen);
- *(ssid_ie + 1) = cur_network->Ssid.ssid_len;
- memcpy(ssid_ie + 2, cur_network->Ssid.ssid,
- cur_network->Ssid.ssid_len);
-
- pframe += ssid_ielen_diff;
- pattrib->pktlen += ssid_ielen_diff;
- }
- } else
-#endif
- {
- /* SSID */
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
- cur_network->Ssid.ssid_len,
- cur_network->Ssid.ssid,
- &pattrib->pktlen);
-
- /* supported rates... */
- rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
- ((rate_len > 8)? 8: rate_len),
- cur_network->SupportedRates,
- &pattrib->pktlen);
-
- /* DS parameter set */
- pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1,
- (unsigned char *)&cur_network->DSConfig,
- &pattrib->pktlen);
-
- if ((pmlmeinfo->state & 0x03) == MSR_ADHOC) {
- u8 erpinfo = 0;
- u32 ATIMWindow;
- /* IBSS Parameter Set... */
- /* ATIMWindow = cur->ATIMWindow; */
- ATIMWindow = 0;
- pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
- (unsigned char *)&ATIMWindow,
- &pattrib->pktlen);
-
- /* ERP IE */
- pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
- &erpinfo, &pattrib->pktlen);
- }
-
- /* EXTERNDED SUPPORTED RATE */
- if (rate_len > 8)
- pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
- rate_len - 8,
- cur_network->SupportedRates + 8,
- &pattrib->pktlen);
-
- /* todo:HT for adhoc */
- }
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-}
-
-static int _issue_probereq(struct rtw_adapter *padapter,
- struct cfg80211_ssid *pssid, u8 *da, int wait_ack)
-{
- int ret = _FAIL;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned char *mac;
- unsigned char bssrate[NumRates];
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- int bssrate_len = 0;
- u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
- "+%s\n", __func__);
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (!pmgntframe)
- goto exit;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
-
- mac = myid(&padapter->eeprompriv);
-
- pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_PROBE_REQ);
-
- if (da) {
- /* unicast probe request frame */
- ether_addr_copy(pwlanhdr->addr1, da);
- ether_addr_copy(pwlanhdr->addr3, da);
- } else {
- /* broadcast probe request frame */
- ether_addr_copy(pwlanhdr->addr1, bc_addr);
- ether_addr_copy(pwlanhdr->addr3, bc_addr);
- }
-
- ether_addr_copy(pwlanhdr->addr2, mac);
-
- pwlanhdr->seq_ctrl =
- cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
-
- pmlmeext->mgnt_seq++;
-
- pframe += sizeof (struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof (struct ieee80211_hdr_3addr);
-
- if (pssid)
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, pssid->ssid_len,
- pssid->ssid, &pattrib->pktlen);
- else
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, 0, NULL,
- &pattrib->pktlen);
-
- get_rate_set23a(padapter, bssrate, &bssrate_len);
-
- if (bssrate_len > 8) {
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
- bssrate, &pattrib->pktlen);
- pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
- (bssrate_len - 8), (bssrate + 8),
- &pattrib->pktlen);
- } else {
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
- bssrate_len, bssrate, &pattrib->pktlen);
- }
-
- /* add wps_ie for wps2.0 */
- if (pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie) {
- memcpy(pframe, pmlmepriv->wps_probe_req_ie,
- pmlmepriv->wps_probe_req_ie_len);
- pframe += pmlmepriv->wps_probe_req_ie_len;
- pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
- }
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
- "issuing probe_req, tx_len =%d\n", pattrib->last_txcmdsz);
-
- if (wait_ack) {
- ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
- } else {
- dump_mgntframe23a(padapter, pmgntframe);
- ret = _SUCCESS;
- }
-
-exit:
- return ret;
-}
-
-static inline void issue_probereq(struct rtw_adapter *padapter,
- struct cfg80211_ssid *pssid, u8 *da)
-{
- _issue_probereq(padapter, pssid, da, false);
-}
-
-static int issue_probereq_ex(struct rtw_adapter *padapter,
- struct cfg80211_ssid *pssid, u8 *da,
- int try_cnt, int wait_ms)
-{
- int ret;
- int i = 0;
- unsigned long start = jiffies;
-
- do {
- ret = _issue_probereq(padapter, pssid, da,
- wait_ms > 0 ? true : false);
-
- i++;
-
- if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
- break;
-
- if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
- msleep(wait_ms);
-
- } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
-
- if (ret != _FAIL) {
- ret = _SUCCESS;
- goto exit;
- }
-
- if (try_cnt && wait_ms) {
- if (da)
- DBG_8723A("%s(%s): to %pM, ch:%u%s, %d/%d in %u ms\n",
- __func__, padapter->pnetdev->name,
- da, rtw_get_oper_ch23a(padapter),
- ret == _SUCCESS ? ", acked" : "", i, try_cnt,
- jiffies_to_msecs(jiffies - start));
- else
- DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
- __func__, padapter->pnetdev->name,
- rtw_get_oper_ch23a(padapter),
- ret == _SUCCESS ? ", acked" : "", i, try_cnt,
- jiffies_to_msecs(jiffies - start));
- }
-exit:
- return ret;
-}
-
-/* if psta == NULL, indiate we are station(client) now... */
-static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
- unsigned short status)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_mgmt *mgmt;
- unsigned int val32;
- u16 auth_algo;
- int use_shared_key = 0;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (!pmgntframe)
- return;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- mgmt = (struct ieee80211_mgmt *)pframe;
-
- mgmt->frame_control =
- cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
- mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
- pmlmeext->mgnt_seq++;
-
- pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.auth.variable);
-
- if (psta) { /* for AP mode */
-#ifdef CONFIG_8723AU_AP_MODE
- unsigned short val16;
-
- ether_addr_copy(mgmt->da, psta->hwaddr);
- ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
- ether_addr_copy(mgmt->bssid, myid(&padapter->eeprompriv));
-
- /* setting auth algo number */
- val16 = (u16)psta->authalg;
-
- if (status != WLAN_STATUS_SUCCESS)
- val16 = 0;
-
- if (val16)
- use_shared_key = 1;
-
- mgmt->u.auth.auth_alg = cpu_to_le16(val16);
-
- /* setting auth seq number */
- mgmt->u.auth.auth_transaction =
- cpu_to_le16((u16)psta->auth_seq);
-
- /* setting status code... */
- mgmt->u.auth.status_code = cpu_to_le16(status);
-
- pframe = mgmt->u.auth.variable;
- /* added challenging text... */
- if ((psta->auth_seq == 2) &&
- (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
- pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
- psta->chg_txt, &pattrib->pktlen);
-#endif
- } else {
- struct ieee80211_mgmt *iv_mgmt;
-
- ether_addr_copy(mgmt->da, get_my_bssid23a(&pmlmeinfo->network));
- ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
- ether_addr_copy(mgmt->bssid,
- get_my_bssid23a(&pmlmeinfo->network));
-
- /* setting auth algo number */
- /* 0:OPEN System, 1:Shared key */
- if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
- use_shared_key = 1;
- auth_algo = WLAN_AUTH_SHARED_KEY;
- } else
- auth_algo = WLAN_AUTH_OPEN;
-
- /* DBG_8723A("%s auth_algo = %s auth_seq =%d\n", __func__,
- (pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED",
- pmlmeinfo->auth_seq); */
-
- /* setting IV for auth seq #3 */
- if ((pmlmeinfo->auth_seq == 3) &&
- (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
- (use_shared_key == 1)) {
- u32 *piv = (u32 *)&mgmt->u.auth;
-
- iv_mgmt = (struct ieee80211_mgmt *)(pframe + 4);
- /* DBG_8723A("==> iv(%d), key_index(%d)\n",
- pmlmeinfo->iv, pmlmeinfo->key_index); */
- val32 = (pmlmeinfo->iv & 0x3fffffff) |
- (pmlmeinfo->key_index << 30);
- pmlmeinfo->iv++;
- put_unaligned_le32(val32, piv);
-
- pattrib->pktlen += 4;
-
- pattrib->iv_len = IEEE80211_WEP_IV_LEN;
- } else
- iv_mgmt = mgmt;
-
- iv_mgmt->u.auth.auth_alg = cpu_to_le16(auth_algo);
-
- /* setting auth seq number */
- iv_mgmt->u.auth.auth_transaction =
- cpu_to_le16(pmlmeinfo->auth_seq);
-
- /* setting status code... */
- iv_mgmt->u.auth.status_code = cpu_to_le16(status);
-
- pframe = iv_mgmt->u.auth.variable;
-
- /* then checking to see if sending challenging text... */
- if ((pmlmeinfo->auth_seq == 3) &&
- (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
- (use_shared_key == 1)) {
- pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
- pmlmeinfo->chg_txt,
- &pattrib->pktlen);
-
- mgmt->frame_control |=
- cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-
- pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
-
- pattrib->encrypt = WLAN_CIPHER_SUITE_WEP40;
-
- pattrib->icv_len = IEEE80211_WEP_ICV_LEN;
-
- pattrib->pktlen += pattrib->icv_len;
- }
- }
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- rtw_wep_encrypt23a(padapter, pmgntframe);
- DBG_8723A("%s\n", __func__);
- dump_mgntframe23a(padapter, pmgntframe);
-}
-
-#ifdef CONFIG_8723AU_AP_MODE
-static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
- struct sta_info *pstat, u16 pkt_type)
-{
- struct xmit_frame *pmgntframe;
- struct ieee80211_mgmt *mgmt;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
- const u8 *p;
- u8 *ie = pnetwork->IEs;
-
- DBG_8723A("%s\n", __func__);
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (!pmgntframe)
- return;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- mgmt = (struct ieee80211_mgmt *)pframe;
-
- mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | pkt_type);
-
- ether_addr_copy(mgmt->da, pstat->hwaddr);
- ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
- ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
-
- mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
-
- pmlmeext->mgnt_seq++;
-
- pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen =
- offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
-
- mgmt->u.assoc_resp.capab_info = cpu_to_le16(pnetwork->capability);
- mgmt->u.assoc_resp.status_code = cpu_to_le16(status);
- mgmt->u.assoc_resp.aid = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
-
- pframe = mgmt->u.assoc_resp.variable;
-
- if (pstat->bssratelen <= 8) {
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
- pstat->bssratelen, pstat->bssrateset,
- &pattrib->pktlen);
- } else {
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
- pstat->bssrateset, &pattrib->pktlen);
- pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
- pstat->bssratelen - 8,
- pstat->bssrateset + 8, &pattrib->pktlen);
- }
-
- if (pstat->flags & WLAN_STA_HT && pmlmepriv->htpriv.ht_option) {
- /* FILL HT CAP INFO IE */
- /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ie,
- pnetwork->IELength);
- if (p && p[1]) {
- memcpy(pframe, p, p[1] + 2);
- pframe += (p[1] + 2);
- pattrib->pktlen += (p[1] + 2);
- }
-
- /* FILL HT ADD INFO IE */
- /* p = hostapd_eid_ht_operation(hapd, p); */
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, ie,
- pnetwork->IELength);
- if (p && p[1] > 0) {
- memcpy(pframe, p, p[1] + 2);
- pframe += (p[1] + 2);
- pattrib->pktlen += (p[1] + 2);
- }
- }
-
- /* FILL WMM IE */
- if (pstat->flags & WLAN_STA_WME && pmlmepriv->qos_option) {
- unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02,
- 0x01, 0x01};
- int ie_len = 0;
-
- for (p = ie; ; p += (ie_len + 2)) {
- p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p,
- pnetwork->IELength - (ie_len + 2));
- if (p)
- ie_len = p[1];
- else
- ie_len = 0;
- if (p && !memcmp(p + 2, WMM_PARA_IE, 6)) {
- memcpy(pframe, p, ie_len + 2);
- pframe += (ie_len + 2);
- pattrib->pktlen += (ie_len + 2);
-
- break;
- }
-
- if (!p || ie_len == 0)
- break;
- }
- }
-
- if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) {
- pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
- REALTEK_96B_IE, &pattrib->pktlen);
- }
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-}
-#endif
-
-static void issue_assocreq(struct rtw_adapter *padapter)
-{
- int ret = _FAIL;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- const u8 *p;
- struct ieee80211_mgmt *mgmt;
- unsigned int i, j, index = 0;
- unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
- struct registry_priv *pregpriv = &padapter->registrypriv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- int bssrate_len = 0, sta_bssrate_len = 0, pie_len;
- u8 *pie;
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (!pmgntframe)
- goto exit;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
- mgmt = (struct ieee80211_mgmt *)pframe;
-
- mgmt->frame_control =
- cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ);
-
- ether_addr_copy(mgmt->da, get_my_bssid23a(&pmlmeinfo->network));
- ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
- ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
-
- mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
- pmlmeext->mgnt_seq++;
-
- /* caps */
- put_unaligned_le16(pmlmeinfo->network.capability,
- &mgmt->u.assoc_req.capab_info);
- /* todo: listen interval for power saving */
- put_unaligned_le16(3, &mgmt->u.assoc_req.listen_interval);
-
- pframe = mgmt->u.assoc_req.variable;
- pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
-
- /* SSID */
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
- pmlmeinfo->network.Ssid.ssid_len,
- pmlmeinfo->network.Ssid.ssid, &pattrib->pktlen);
-
- /* supported rate & extended supported rate */
-
- get_rate_set23a(padapter, sta_bssrate, &sta_bssrate_len);
- /* DBG_8723A("sta_bssrate_len =%d\n", sta_bssrate_len); */
-
- /* for JAPAN, channel 14 can only uses B Mode(CCK) */
- if (pmlmeext->cur_channel == 14)
- sta_bssrate_len = 4;
-
- /* for (i = 0; i < sta_bssrate_len; i++) { */
- /* DBG_8723A("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
- /* */
-
- for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
- if (pmlmeinfo->network.SupportedRates[i] == 0)
- break;
- DBG_8723A("network.SupportedRates[%d]=%02X\n", i,
- pmlmeinfo->network.SupportedRates[i]);
- }
-
- for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
- if (pmlmeinfo->network.SupportedRates[i] == 0)
- break;
-
- /* Check if the AP's supported rates are also
- supported by STA. */
- for (j = 0; j < sta_bssrate_len; j++) {
- /* Avoid the proprietary data rate (22Mbps) of
- Handlink WSG-4000 AP */
- if ((pmlmeinfo->network.SupportedRates[i] |
- IEEE80211_BASIC_RATE_MASK) ==
- (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
- /* DBG_8723A("match i = %d, j =%d\n", i, j); */
- break;
- }
- }
-
- if (j == sta_bssrate_len) {
- /* the rate is not supported by STA */
- DBG_8723A("%s(): the rate[%d]=%02X is not supported by "
- "STA!\n", __func__, i,
- pmlmeinfo->network.SupportedRates[i]);
- } else {
- /* the rate is supported by STA */
- bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
- }
- }
-
- bssrate_len = index;
- DBG_8723A("bssrate_len = %d\n", bssrate_len);
-
- if (bssrate_len == 0) {
- rtw_free_xmitbuf23a(pxmitpriv, pmgntframe->pxmitbuf);
- rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
- goto exit; /* don't connect to AP if no joint supported rate */
- }
-
- if (bssrate_len > 8) {
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
- bssrate, &pattrib->pktlen);
- pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
- (bssrate_len - 8), (bssrate + 8),
- &pattrib->pktlen);
- } else
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
- bssrate_len, bssrate, &pattrib->pktlen);
-
- /* RSN */
-
- pie = pmlmeinfo->network.IEs;
- pie_len = pmlmeinfo->network.IELength;
-
- p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
- if (p)
- pframe = rtw_set_ie23a(pframe, WLAN_EID_RSN, p[1], p + 2,
- &pattrib->pktlen);
-
- /* HT caps */
- if (padapter->mlmepriv.htpriv.ht_option) {
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, pie_len);
-
- if (p && !is_ap_in_tkip23a(padapter)) {
- struct ieee80211_ht_cap *cap = &pmlmeinfo->ht_cap;
-
- memcpy(cap, p + 2, sizeof(struct ieee80211_ht_cap));
-
- /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
- if (pregpriv->cbw40_enable == 0) {
- cap->cap_info &= ~cpu_to_le16(
- IEEE80211_HT_CAP_SGI_40 |
- IEEE80211_HT_CAP_SUP_WIDTH_20_40);
- } else {
- cap->cap_info |= cpu_to_le16(
- IEEE80211_HT_CAP_SUP_WIDTH_20_40);
- }
-
- /* todo: disable SM power save mode */
- cap->cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SM_PS);
-
- rf_type = rtl8723a_get_rf_type(padapter);
- /* switch (pregpriv->rf_config) */
- switch (rf_type) {
- case RF_1T1R:
- /* RX STBC One spatial stream */
- if (pregpriv->rx_stbc)
- cap->cap_info |= cpu_to_le16(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
-
- memcpy(&cap->mcs, MCS_rate_1R23A, 16);
- break;
-
- case RF_2T2R:
- case RF_1T2R:
- default:
- /* enable for 2.4/5 GHz */
- if (pregpriv->rx_stbc == 0x3 ||
- (pmlmeext->cur_wireless_mode &
- WIRELESS_11_24N &&
- /* enable for 2.4GHz */
- pregpriv->rx_stbc == 0x1) ||
- (pmlmeext->cur_wireless_mode &
- WIRELESS_11_5N &&
- pregpriv->rx_stbc == 0x2) ||
- /* enable for 5GHz */
- pregpriv->wifi_spec == 1) {
- DBG_8723A("declare supporting RX "
- "STBC\n");
- /* RX STBC two spatial stream */
- cap->cap_info |= cpu_to_le16(2 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
- }
- memcpy(&cap->mcs, MCS_rate_2R23A, 16);
- break;
- }
-
- if (rtl8723a_BT_coexist(padapter) &&
- rtl8723a_BT_using_antenna_1(padapter)) {
- /* set to 8K */
- cap->ampdu_params_info &=
- ~IEEE80211_HT_AMPDU_PARM_FACTOR;
-/* cap->ampdu_params_info |= MAX_AMPDU_FACTOR_8K */
- }
-
- pframe = rtw_set_ie23a(pframe, WLAN_EID_HT_CAPABILITY,
- p[1], (u8 *)&pmlmeinfo->ht_cap,
- &pattrib->pktlen);
- }
- }
-
- /* vendor specific IE, such as WPA, WMM, WPS */
- for (i = 0; i < pmlmeinfo->network.IELength;) {
- p = pmlmeinfo->network.IEs + i;
-
- switch (p[0]) {
- case WLAN_EID_VENDOR_SPECIFIC:
- if (!memcmp(p + 2, RTW_WPA_OUI23A_TYPE, 4) ||
- !memcmp(p + 2, WMM_OUI23A, 4) ||
- !memcmp(p + 2, WPS_OUI23A, 4)) {
- u8 plen = p[1];
-
- if (!padapter->registrypriv.wifi_spec) {
- /* Commented by Kurt 20110629 */
- /* In some older APs, WPS handshake */
- /* would be fail if we append vender
- extensions informations to AP */
- if (!memcmp(p + 2, WPS_OUI23A, 4))
- plen = 14;
- }
- pframe = rtw_set_ie23a(pframe,
- WLAN_EID_VENDOR_SPECIFIC,
- plen, p + 2,
- &pattrib->pktlen);
- }
- break;
-
- default:
- break;
- }
-
- i += p[1] + 2;
- }
-
- if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
- pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
- REALTEK_96B_IE, &pattrib->pktlen);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
- dump_mgntframe23a(padapter, pmgntframe);
-
- ret = _SUCCESS;
-
-exit:
- pmlmepriv->assoc_req_len = 0;
- if (ret == _SUCCESS) {
- kfree(pmlmepriv->assoc_req);
- pmlmepriv->assoc_req = kmalloc(pattrib->pktlen, GFP_ATOMIC);
- if (pmlmepriv->assoc_req) {
- memcpy(pmlmepriv->assoc_req, mgmt, pattrib->pktlen);
- pmlmepriv->assoc_req_len = pattrib->pktlen;
- }
- } else
- kfree(pmlmepriv->assoc_req);
-}
-
-/* when wait_ack is true, this function should be called at process context */
-static int _issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
- unsigned int power_mode, int wait_ack)
-{
- int ret = _FAIL;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- struct xmit_priv *pxmitpriv;
- struct mlme_ext_priv *pmlmeext;
- struct mlme_ext_info *pmlmeinfo;
-
- /* DBG_8723A("%s:%d\n", __func__, power_mode); */
-
- if (!padapter)
- goto exit;
-
- pxmitpriv = &padapter->xmitpriv;
- pmlmeext = &padapter->mlmeextpriv;
- pmlmeinfo = &pmlmeext->mlmext_info;
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (!pmgntframe)
- goto exit;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
- pattrib->retry_ctrl = false;
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
-
- pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_NULLFUNC);
-
- if ((pmlmeinfo->state&0x03) == MSR_AP)
- pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
- else if ((pmlmeinfo->state&0x03) == MSR_INFRA)
- pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_TODS);
-
- if (power_mode)
- pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
-
- ether_addr_copy(pwlanhdr->addr1, da);
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
-
- pwlanhdr->seq_ctrl =
- cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
- pmlmeext->mgnt_seq++;
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- if (wait_ack)
- ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
- else {
- dump_mgntframe23a(padapter, pmgntframe);
- ret = _SUCCESS;
- }
-
-exit:
- return ret;
-}
-
-/* when wait_ms >0 , this function should be called at process context */
-/* da == NULL for station mode */
-int issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
- unsigned int power_mode, int try_cnt, int wait_ms)
-{
- int ret;
- int i = 0;
- unsigned long start = jiffies;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- /* da == NULL, assume it's null data for sta to ap*/
- if (da == NULL)
- da = get_my_bssid23a(&pmlmeinfo->network);
-
- do {
- ret = _issue_nulldata23a(padapter, da, power_mode,
- wait_ms > 0 ? true : false);
-
- i++;
-
- if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
- break;
-
- if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
- msleep(wait_ms);
-
- } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
-
- if (ret != _FAIL) {
- ret = _SUCCESS;
- goto exit;
- }
-
- if (try_cnt && wait_ms) {
- if (da)
- DBG_8723A("%s(%s): to %pM, ch:%u%s, %d/%d in %u ms\n",
- __func__, padapter->pnetdev->name,
- da, rtw_get_oper_ch23a(padapter),
- ret == _SUCCESS ? ", acked" : "", i, try_cnt,
- jiffies_to_msecs(jiffies - start));
- else
- DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
- __func__, padapter->pnetdev->name,
- rtw_get_oper_ch23a(padapter),
- ret == _SUCCESS ? ", acked" : "", i, try_cnt,
- jiffies_to_msecs(jiffies - start));
- }
-exit:
- return ret;
-}
-
-/* when wait_ack is true, this function should be called at process context */
-static int _issue_qos_nulldata23a(struct rtw_adapter *padapter,
- unsigned char *da, u16 tid, int wait_ack)
-{
- int ret = _FAIL;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_qos_hdr *pwlanhdr;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- DBG_8723A("%s\n", __func__);
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (!pmgntframe)
- goto exit;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
-
- pattrib->hdrlen += 2;
- pattrib->qos_en = true;
- pattrib->eosp = 1;
- pattrib->ack_policy = 0;
- pattrib->mdata = 0;
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct ieee80211_qos_hdr *)pframe;
-
- pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_QOS_NULLFUNC);
-
- if ((pmlmeinfo->state&0x03) == MSR_AP)
- pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
- else if ((pmlmeinfo->state&0x03) == MSR_INFRA)
- pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_TODS);
-
- if (pattrib->mdata)
- pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
-
- pwlanhdr->qos_ctrl = cpu_to_le16(tid & IEEE80211_QOS_CTL_TID_MASK);
- pwlanhdr->qos_ctrl |= cpu_to_le16((pattrib->ack_policy << 5) &
- IEEE80211_QOS_CTL_ACK_POLICY_MASK);
- if (pattrib->eosp)
- pwlanhdr->qos_ctrl |= cpu_to_le16(IEEE80211_QOS_CTL_EOSP);
-
- ether_addr_copy(pwlanhdr->addr1, da);
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
-
- pwlanhdr->seq_ctrl =
- cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
- pmlmeext->mgnt_seq++;
-
- pframe += sizeof(struct ieee80211_qos_hdr);
- pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- if (wait_ack)
- ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
- else {
- dump_mgntframe23a(padapter, pmgntframe);
- ret = _SUCCESS;
- }
-
-exit:
- return ret;
-}
-
-/* when wait_ms >0 , this function should be called at process context */
-/* da == NULL for station mode */
-int issue_qos_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
- u16 tid, int try_cnt, int wait_ms)
-{
- int ret;
- int i = 0;
- unsigned long start = jiffies;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- /* da == NULL, assume it's null data for sta to ap*/
- if (da == NULL)
- da = get_my_bssid23a(&pmlmeinfo->network);
-
- do {
- ret = _issue_qos_nulldata23a(padapter, da, tid,
- wait_ms > 0 ? true : false);
-
- i++;
-
- if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
- break;
-
- if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
- msleep(wait_ms);
- } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
-
- if (ret != _FAIL) {
- ret = _SUCCESS;
- goto exit;
- }
-
- if (try_cnt && wait_ms) {
- if (da)
- DBG_8723A("%s(%s): to %pM, ch:%u%s, %d/%d in %u ms\n",
- __func__, padapter->pnetdev->name,
- da, rtw_get_oper_ch23a(padapter),
- ret == _SUCCESS ? ", acked" : "", i, try_cnt,
- jiffies_to_msecs(jiffies - start));
- else
- DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
- __func__, padapter->pnetdev->name,
- rtw_get_oper_ch23a(padapter),
- ret == _SUCCESS ? ", acked" : "", i, try_cnt,
- jiffies_to_msecs(jiffies - start));
- }
-exit:
- return ret;
-}
-
-static int _issue_deauth(struct rtw_adapter *padapter, unsigned char *da,
- unsigned short reason, u8 wait_ack)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct ieee80211_mgmt *mgmt;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- int ret = _FAIL;
-
- /* DBG_8723A("%s to %pM\n", __func__, da); */
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (!pmgntframe)
- goto exit;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
- pattrib->retry_ctrl = false;
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
-
- mgmt->frame_control =
- cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH);
-
- ether_addr_copy(mgmt->da, da);
- ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
- ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
-
- mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
- pmlmeext->mgnt_seq++;
-
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr) + 2;
-
- mgmt->u.deauth.reason_code = cpu_to_le16(reason);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- if (wait_ack)
- ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
- else {
- dump_mgntframe23a(padapter, pmgntframe);
- ret = _SUCCESS;
- }
-
-exit:
- return ret;
-}
-
-int issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
- unsigned short reason)
-{
- DBG_8723A("%s to %pM\n", __func__, da);
- return _issue_deauth(padapter, da, reason, false);
-}
-
-static int issue_deauth_ex(struct rtw_adapter *padapter, u8 *da,
- unsigned short reason, int try_cnt, int wait_ms)
-{
- int ret;
- int i = 0;
- unsigned long start = jiffies;
-
- do {
- ret = _issue_deauth(padapter, da, reason,
- wait_ms >0 ? true : false);
-
- i++;
-
- if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
- break;
-
- if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
- msleep(wait_ms);
-
- } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
-
- if (ret != _FAIL) {
- ret = _SUCCESS;
- goto exit;
- }
-
- if (try_cnt && wait_ms) {
- if (da)
- DBG_8723A("%s(%s): to %pM, ch:%u%s, %d/%d in %u ms\n",
- __func__, padapter->pnetdev->name,
- da, rtw_get_oper_ch23a(padapter),
- ret == _SUCCESS ? ", acked" : "", i, try_cnt,
- jiffies_to_msecs(jiffies - start));
- else
- DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
- __func__, padapter->pnetdev->name,
- rtw_get_oper_ch23a(padapter),
- ret == _SUCCESS ? ", acked" : "", i, try_cnt,
- jiffies_to_msecs(jiffies - start));
- }
-exit:
- return ret;
-}
-
-void issue_action_spct_ch_switch23a(struct rtw_adapter *padapter,
- u8 *ra, u8 new_ch, u8 ch_offset)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_mgmt *mgmt;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- DBG_8723A("%s(%s): ra=%pM, ch:%u, offset:%u\n",
- __func__, padapter->pnetdev->name, ra, new_ch, ch_offset);
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (!pmgntframe)
- return;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
-
- mgmt->frame_control =
- cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
-
- ether_addr_copy(mgmt->da, ra); /* RA */
- ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv)); /* TA */
- ether_addr_copy(mgmt->bssid, ra); /* DA = RA */
-
- mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
- pmlmeext->mgnt_seq++;
-
- mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
- mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH;
-
- pframe = mgmt->u.action.u.chan_switch.variable;
- pattrib->pktlen = offsetof(struct ieee80211_mgmt,
- u.action.u.chan_switch.variable);
-
- pframe = rtw_set_ie23a_ch_switch (pframe, &pattrib->pktlen, 0,
- new_ch, 0);
- pframe = rtw_set_ie23a_secondary_ch_offset(pframe, &pattrib->pktlen,
- hal_ch_offset_to_secondary_ch_offset23a(ch_offset));
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-}
-
-void issue_action_BA23a(struct rtw_adapter *padapter,
- const unsigned char *raddr,
- unsigned char action, unsigned short status)
-{
- u16 start_seq;
- u16 BA_para_set;
- u16 BA_starting_seqctrl;
- u16 BA_para;
- int max_rx_ampdu_factor;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct ieee80211_mgmt *mgmt;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct sta_info *psta;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct registry_priv *pregpriv = &padapter->registrypriv;
- u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
-
- DBG_8723A("%s, action =%d, status =%d\n", __func__, action, status);
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (!pmgntframe)
- return;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
-
- mgmt->frame_control =
- cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
-
- ether_addr_copy(mgmt->da, raddr);
- ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
- ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
-
- mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
- pmlmeext->mgnt_seq++;
-
- mgmt->u.action.category = WLAN_CATEGORY_BACK;
-
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr) + 1;
-
- switch (action) {
- case WLAN_ACTION_ADDBA_REQ:
- pattrib->pktlen += sizeof(mgmt->u.action.u.addba_req);
-
- mgmt->u.action.u.addba_req.action_code = action;
-
- do {
- pmlmeinfo->dialogToken++;
- } while (pmlmeinfo->dialogToken == 0);
-
- mgmt->u.action.u.addba_req.dialog_token =
- pmlmeinfo->dialogToken;
-
- if (rtl8723a_BT_coexist(padapter) &&
- rtl8723a_BT_using_antenna_1(padapter) &&
- (pmlmeinfo->assoc_AP_vendor != broadcomAP ||
- memcmp(raddr, tendaAPMac, 3))) {
- /* A-MSDU NOT Supported */
- BA_para_set = 0;
- /* immediate Block Ack */
- BA_para_set |= (1 << 1) &
- IEEE80211_ADDBA_PARAM_POLICY_MASK;
- /* TID */
- BA_para_set |= (status << 2) &
- IEEE80211_ADDBA_PARAM_TID_MASK;
- /* max buffer size is 8 MSDU */
- BA_para_set |= (8 << 6) &
- IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
- } else {
- /* immediate ack & 64 buffer size */
- BA_para_set = 0x1002 | ((status & 0xf) << 2);
- }
-
- put_unaligned_le16(BA_para_set,
- &mgmt->u.action.u.addba_req.capab);
-
- /* 5ms */
- put_unaligned_le16(5000, &mgmt->u.action.u.addba_req.timeout);
-
- psta = rtw_get_stainfo23a(pstapriv, raddr);
- if (psta) {
- int idx;
-
- idx = status & 0x07;
- start_seq =
- (psta->sta_xmitpriv.txseq_tid[idx] & 0xfff) + 1;
-
- DBG_8723A("BA_starting_seqctrl = %d for TID =%d\n",
- start_seq, idx);
-
- psta->BA_starting_seqctrl[idx] = start_seq;
-
- BA_starting_seqctrl = start_seq << 4;
- } else
- BA_starting_seqctrl = 0;
-
- put_unaligned_le16(BA_starting_seqctrl,
- &mgmt->u.action.u.addba_req.start_seq_num);
-
- break;
-
- case WLAN_ACTION_ADDBA_RESP:
- pattrib->pktlen += sizeof(mgmt->u.action.u.addba_resp);
-
- mgmt->u.action.u.addba_resp.action_code = action;
- mgmt->u.action.u.addba_resp.dialog_token =
- pmlmeinfo->ADDBA_req.dialog_token;
- put_unaligned_le16(status,
- &mgmt->u.action.u.addba_resp.status);
-
- GetHalDefVar8192CUsb(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
- &max_rx_ampdu_factor);
-
- BA_para = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f;
- if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_64K)
- BA_para_set = BA_para | 0x1000; /* 64 buffer size */
- else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_32K)
- BA_para_set = BA_para | 0x0800; /* 32 buffer size */
- else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_16K)
- BA_para_set = BA_para | 0x0400; /* 16 buffer size */
- else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_8K)
- BA_para_set = BA_para | 0x0200; /* 8 buffer size */
- else
- BA_para_set = BA_para | 0x1000; /* 64 buffer size */
-
- if (rtl8723a_BT_coexist(padapter) &&
- rtl8723a_BT_using_antenna_1(padapter) &&
- (pmlmeinfo->assoc_AP_vendor != broadcomAP ||
- memcmp(raddr, tendaAPMac, 3))) {
- /* max buffer size is 8 MSDU */
- BA_para_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
- BA_para_set |= (8 << 6) &
- IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
- }
-
- if (pregpriv->ampdu_amsdu == 0)/* disabled */
- BA_para_set &= ~BIT(0);
- else if (pregpriv->ampdu_amsdu == 1)/* enabled */
- BA_para_set |= BIT(0);
-
- put_unaligned_le16(BA_para_set,
- &mgmt->u.action.u.addba_resp.capab);
-
- mgmt->u.action.u.addba_resp.timeout
- = pmlmeinfo->ADDBA_req.BA_timeout_value;
-
- pattrib->pktlen += 8;
- break;
- case WLAN_ACTION_DELBA:
- pattrib->pktlen += sizeof(mgmt->u.action.u.delba);
-
- mgmt->u.action.u.delba.action_code = action;
- BA_para_set = (status & 0x1F) << 3;
- mgmt->u.action.u.delba.params = cpu_to_le16(BA_para_set);
- mgmt->u.action.u.delba.reason_code =
- cpu_to_le16(WLAN_REASON_QSTA_NOT_USE);
-
- pattrib->pktlen += 5;
- break;
- default:
- break;
- }
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-}
-
-int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr)
-{
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sta_info *psta = NULL;
- /* struct recv_reorder_ctrl *preorder_ctrl; */
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- u16 tid;
-
- if ((pmlmeinfo->state&0x03) != MSR_AP)
- if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
- return _SUCCESS;
-
- psta = rtw_get_stainfo23a(pstapriv, addr);
- if (psta == NULL)
- return _SUCCESS;
-
- if (initiator == 0) { /* recipient */
- for (tid = 0; tid < MAXTID; tid++) {
- if (psta->recvreorder_ctrl[tid].enable == true) {
- DBG_8723A("rx agg disable tid(%d)\n", tid);
- issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
- psta->recvreorder_ctrl[tid].enable = false;
- psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
- }
- }
- } else if (initiator == 1) { /* originator */
- for (tid = 0; tid < MAXTID; tid++) {
- if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
- DBG_8723A("tx agg disable tid(%d)\n", tid);
- issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
- psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
- psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
-
- }
- }
- }
- return _SUCCESS;
-}
-
-int send_beacon23a(struct rtw_adapter *padapter)
-{
- bool bxmitok;
- int issue = 0;
- int poll = 0;
- unsigned long start = jiffies;
- unsigned int passing_time;
-
- rtl8723a_bcn_valid(padapter);
- do {
- issue_beacon23a(padapter, 100);
- issue++;
- do {
- yield();
- bxmitok = rtl8723a_get_bcn_valid(padapter);
- poll++;
- } while ((poll % 10) != 0 && !bxmitok &&
- !padapter->bSurpriseRemoved &&
- !padapter->bDriverStopped);
-
- } while (!bxmitok && issue<100 && !padapter->bSurpriseRemoved &&
- !padapter->bDriverStopped);
-
- if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
- return _FAIL;
-
- passing_time = jiffies_to_msecs(jiffies - start);
-
- if (!bxmitok) {
- DBG_8723A("%s fail! %u ms\n", __func__, passing_time);
- return _FAIL;
- } else {
-
- if (passing_time > 100 || issue > 3)
- DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n",
- __func__, issue, poll, passing_time);
- return _SUCCESS;
- }
-}
-
-/****************************************************************************
-
-Following are some utitity functions for WiFi MLME
-
-*****************************************************************************/
-
-bool IsLegal5GChannel(struct rtw_adapter *Adapter, u8 channel)
-{
-
- int i = 0;
- u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
- 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
- 114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
- 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
- 161, 163, 165};
- for (i = 0; i < sizeof(Channel_5G); i++)
- if (channel == Channel_5G[i])
- return true;
- return false;
-}
-
-static void rtw_site_survey(struct rtw_adapter *padapter)
-{
- unsigned char survey_channel = 0;
- enum rt_scan_type ScanType = SCAN_PASSIVE;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct rtw_ieee80211_channel *ch;
-
- if (pmlmeext->sitesurvey_res.channel_idx <
- pmlmeext->sitesurvey_res.ch_num) {
- ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
- survey_channel = ch->hw_value;
- ScanType = (ch->flags & IEEE80211_CHAN_NO_IR) ?
- SCAN_PASSIVE : SCAN_ACTIVE;
- }
-
- if (survey_channel != 0) {
- /* PAUSE 4-AC Queue when site_survey */
- if (pmlmeext->sitesurvey_res.channel_idx == 0)
- set_channel_bwmode23a(padapter, survey_channel,
- HAL_PRIME_CHNL_OFFSET_DONT_CARE,
- HT_CHANNEL_WIDTH_20);
- else
- SelectChannel23a(padapter, survey_channel);
-
- if (ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */
- {
- int i;
-
- for (i = 0;i<RTW_SSID_SCAN_AMOUNT;i++) {
- if (pmlmeext->sitesurvey_res.ssid[i].ssid_len) {
- /* todo: to issue two probe req??? */
- issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
- /* msleep(SURVEY_TO>>1); */
- issue_probereq(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
- }
- }
-
- if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
- /* todo: to issue two probe req??? */
- issue_probereq(padapter, NULL, NULL);
- /* msleep(SURVEY_TO>>1); */
- issue_probereq(padapter, NULL, NULL);
- }
- }
-
- set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
- } else {
- /* channel number is 0 or this channel is not valid. */
- pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
-
- /* switch back to the original channel */
-
- set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
- pmlmeext->cur_ch_offset,
- pmlmeext->cur_bwmode);
-
- /* flush 4-AC Queue after rtw_site_survey */
- /* val8 = 0; */
-
- /* config MSR */
- rtl8723a_set_media_status(padapter, pmlmeinfo->state & 0x3);
-
- /* restore RX GAIN */
- rtl8723a_set_initial_gain(padapter, 0xff);
- /* turn on dynamic functions */
- rtl8723a_odm_support_ability_restore(padapter);
-
- if (is_client_associated_to_ap23a(padapter) == true)
- issue_nulldata23a(padapter, NULL, 0, 3, 500);
-
- rtl8723a_mlme_sitesurvey(padapter, 0);
-
- report_surveydone_event23a(padapter);
-
- pmlmeext->chan_scan_time = SURVEY_TO;
- pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
- }
-}
-
-/* collect bss info from Beacon and Probe request/response frames. */
-static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
- struct registry_priv *pregistrypriv = &padapter->registrypriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *bssid;
- const u8 *p;
- u8 *pie;
- unsigned int length;
- int i;
-
- length = skb->len;
-
- bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
- if (!bssid)
- return NULL;
-
- if (ieee80211_is_beacon(mgmt->frame_control)) {
- length -= offsetof(struct ieee80211_mgmt, u.beacon.variable);
- pie = mgmt->u.beacon.variable;
- bssid->reserved = 1;
- bssid->capability =
- get_unaligned_le16(&mgmt->u.beacon.capab_info);
- bssid->beacon_interval =
- get_unaligned_le16(&mgmt->u.beacon.beacon_int);
- bssid->tsf = get_unaligned_le64(&mgmt->u.beacon.timestamp);
- } else if (ieee80211_is_probe_req(mgmt->frame_control)) {
- length -= offsetof(struct ieee80211_mgmt, u.probe_req.variable);
- pie = mgmt->u.probe_req.variable;
- bssid->reserved = 2;
- bssid->capability = 0;
- bssid->beacon_interval =
- padapter->registrypriv.dev_network.beacon_interval;
- bssid->tsf = 0;
- } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
- length -=
- offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
- pie = mgmt->u.probe_resp.variable;
- bssid->reserved = 3;
- bssid->capability =
- get_unaligned_le16(&mgmt->u.probe_resp.capab_info);
- bssid->beacon_interval =
- get_unaligned_le16(&mgmt->u.probe_resp.beacon_int);
- bssid->tsf = get_unaligned_le64(&mgmt->u.probe_resp.timestamp);
- } else {
- length -= offsetof(struct ieee80211_mgmt, u.beacon.variable);
- pie = mgmt->u.beacon.variable;
- bssid->reserved = 0;
- bssid->capability =
- get_unaligned_le16(&mgmt->u.beacon.capab_info);
- bssid->beacon_interval =
- padapter->registrypriv.dev_network.beacon_interval;
- bssid->tsf = 0;
- }
-
- if (length > MAX_IE_SZ) {
- /* DBG_8723A("IE too long for survey event\n"); */
- kfree(bssid);
- return NULL;
- }
-
- bssid->Length = offsetof(struct wlan_bssid_ex, IEs) + length;
-
- /* below is to copy the information element */
- bssid->IELength = length;
- memcpy(bssid->IEs, pie, bssid->IELength);
-
- /* get the signal strength */
- /* in dBM.raw data */
- bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower;
- bssid->SignalQuality =
- precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
- bssid->SignalStrength =
- precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
-
- /* checking SSID */
- p = cfg80211_find_ie(WLAN_EID_SSID, bssid->IEs, bssid->IELength);
-
- if (!p) {
- DBG_8723A("marc: cannot find SSID for survey event\n");
- goto fail;
- }
-
- if (p[1] > IEEE80211_MAX_SSID_LEN) {
- DBG_8723A("%s()-%d: IE too long (%d) for survey "
- "event\n", __func__, __LINE__, p[1]);
- goto fail;
- }
- memcpy(bssid->Ssid.ssid, p + 2, p[1]);
- bssid->Ssid.ssid_len = p[1];
-
- /* checking rate info... */
- i = 0;
- p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, bssid->IEs, bssid->IELength);
- if (p) {
- if (p[1] > NDIS_802_11_LENGTH_RATES_EX) {
- DBG_8723A("%s()-%d: IE too long (%d) for survey "
- "event\n", __func__, __LINE__, p[1]);
- goto fail;
- }
- memcpy(bssid->SupportedRates, p + 2, p[1]);
- i = p[1];
- }
-
- p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, bssid->IEs,
- bssid->IELength);
- if (p) {
- if (p[1] > (NDIS_802_11_LENGTH_RATES_EX-i)) {
- DBG_8723A("%s()-%d: IE too long (%d) for survey "
- "event\n", __func__, __LINE__, p[1]);
- goto fail;
- }
- memcpy(bssid->SupportedRates + i, p + 2, p[1]);
- }
-
- /* Checking for DSConfig */
- p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bssid->IEs, bssid->IELength);
-
- bssid->DSConfig = 0;
-
- if (p) {
- bssid->DSConfig = p[2];
- } else {/* In 5G, some ap do not have DSSET IE */
- /* checking HT info for channel */
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, bssid->IEs,
- bssid->IELength);
- if (p) {
- struct ieee80211_ht_operation *HT_info =
- (struct ieee80211_ht_operation *)(p + 2);
- bssid->DSConfig = HT_info->primary_chan;
- } else /* use current channel */
- bssid->DSConfig = rtw_get_oper_ch23a(padapter);
- }
-
- if (ieee80211_is_probe_req(mgmt->frame_control)) {
- /* FIXME */
- bssid->ifmode = NL80211_IFTYPE_STATION;
- ether_addr_copy(bssid->MacAddress, mgmt->sa);
- bssid->Privacy = 1;
- return bssid;
- }
-
- if (bssid->capability & WLAN_CAPABILITY_ESS) {
- bssid->ifmode = NL80211_IFTYPE_STATION;
- ether_addr_copy(bssid->MacAddress, mgmt->sa);
- } else {
- bssid->ifmode = NL80211_IFTYPE_ADHOC;
- ether_addr_copy(bssid->MacAddress, mgmt->bssid);
- }
-
- if (bssid->capability & WLAN_CAPABILITY_PRIVACY)
- bssid->Privacy = 1;
- else
- bssid->Privacy = 0;
-
- bssid->ATIMWindow = 0;
-
- /* 20/40 BSS Coexistence check */
- if (pregistrypriv->wifi_spec == 1 &&
- pmlmeinfo->bwmode_updated == false) {
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, bssid->IEs,
- bssid->IELength);
- if (p && p[1] > 0) {
- struct ieee80211_ht_cap *pHT_caps;
-
- pHT_caps = (struct ieee80211_ht_cap *)(p + 2);
-
- if (pHT_caps->cap_info &
- cpu_to_le16(IEEE80211_HT_CAP_40MHZ_INTOLERANT))
- pmlmepriv->num_FortyMHzIntolerant++;
- } else
- pmlmepriv->num_sta_no_ht++;
- }
-
-
- /* mark bss info receiving from nearby channel as SignalQuality 101 */
- if (bssid->DSConfig != rtw_get_oper_ch23a(padapter))
- bssid->SignalQuality = 101;
-
- return bssid;
-fail:
- kfree (bssid);
- return NULL;
-}
-
-static void start_create_ibss(struct rtw_adapter *padapter)
-{
- unsigned short caps;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
-
- pmlmeext->cur_channel = (u8)pnetwork->DSConfig;
- pmlmeinfo->bcn_interval = pnetwork->beacon_interval;
-
- /* update wireless mode */
- update_wireless_mode23a(padapter);
-
- /* update capability */
- caps = pnetwork->capability;
- update_capinfo23a(padapter, caps);
- if (caps & WLAN_CAPABILITY_IBSS) { /* adhoc master */
- rtl8723a_set_sec_cfg(padapter, 0xcf);
-
- /* switch channel */
- /* SelectChannel23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
- set_channel_bwmode23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-
- rtl8723a_SetBeaconRelatedRegisters(padapter);
-
- /* set msr to MSR_ADHOC */
- pmlmeinfo->state = MSR_ADHOC;
- rtl8723a_set_media_status(padapter, pmlmeinfo->state & 0x3);
-
- /* issue beacon */
- if (send_beacon23a(padapter) == _FAIL) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "issuing beacon frame fail....\n");
-
- report_join_res23a(padapter, -1);
- pmlmeinfo->state = MSR_NOLINK;
- } else {
- hw_var_set_bssid(padapter, padapter->registrypriv.dev_network.MacAddress);
- hw_var_set_mlme_join(padapter, 0);
-
- report_join_res23a(padapter, 1);
- pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
- }
- } else {
- DBG_8723A("%s: invalid cap:%x\n", __func__, caps);
- return;
- }
-}
-
-static void start_clnt_join(struct rtw_adapter *padapter)
-{
- unsigned short caps;
- u8 val8;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
- int beacon_timeout;
-
- pmlmeext->cur_channel = (u8)pnetwork->DSConfig;
- pmlmeinfo->bcn_interval = pnetwork->beacon_interval;
-
- /* update wireless mode */
- update_wireless_mode23a(padapter);
-
- /* update capability */
- caps = pnetwork->capability;
- update_capinfo23a(padapter, caps);
- if (caps & WLAN_CAPABILITY_ESS) {
- /* switch channel */
- set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
- rtl8723a_set_media_status(padapter, MSR_INFRA);
-
- val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ?
- 0xcc: 0xcf;
-
- rtl8723a_set_sec_cfg(padapter, val8);
-
- /* switch channel */
- /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
-
- /* here wait for receiving the beacon to start auth */
- /* and enable a timer */
- beacon_timeout = decide_wait_for_beacon_timeout23a(pmlmeinfo->bcn_interval);
- set_link_timer(pmlmeext, beacon_timeout);
- mod_timer(&padapter->mlmepriv.assoc_timer, jiffies +
- msecs_to_jiffies((REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout));
- pmlmeinfo->state = WIFI_FW_AUTH_NULL | MSR_INFRA;
- } else if (caps & WLAN_CAPABILITY_IBSS) { /* adhoc client */
- rtl8723a_set_media_status(padapter, MSR_ADHOC);
-
- rtl8723a_set_sec_cfg(padapter, 0xcf);
-
- /* switch channel */
- set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
- rtl8723a_SetBeaconRelatedRegisters(padapter);
-
- pmlmeinfo->state = MSR_ADHOC;
-
- report_join_res23a(padapter, 1);
- } else {
- /* DBG_8723A("marc: invalid cap:%x\n", caps); */
- return;
- }
-}
-
-static void start_clnt_auth(struct rtw_adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- del_timer_sync(&pmlmeext->link_timer);
-
- pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
- pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
-
- pmlmeinfo->auth_seq = 1;
- pmlmeinfo->reauth_count = 0;
- pmlmeinfo->reassoc_count = 0;
- pmlmeinfo->link_count = 0;
- pmlmeext->retry = 0;
-
- /* Because of AP's not receiving deauth before */
- /* AP may: 1)not response auth or 2)deauth us after link is complete */
- /* issue deauth before issuing auth to deal with the situation */
- /* Commented by Albert 2012/07/21 */
- /* For the Win8 P2P connection, it will be hard to have a
- successful connection if this Wi-Fi doesn't connect to it. */
- issue_deauth23a(padapter, (&pmlmeinfo->network)->MacAddress,
- WLAN_REASON_DEAUTH_LEAVING);
-
- DBG_8723A_LEVEL(_drv_always_, "start auth\n");
- issue_auth(padapter, NULL, 0);
-
- set_link_timer(pmlmeext, REAUTH_TO);
-}
-
-static void start_clnt_assoc(struct rtw_adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- del_timer_sync(&pmlmeext->link_timer);
-
- pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
- pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
-
- issue_assocreq(padapter);
-
- set_link_timer(pmlmeext, REASSOC_TO);
-}
-
-int receive_disconnect23a(struct rtw_adapter *padapter,
- unsigned char *MacAddr, unsigned short reason)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- /* check A3 */
- if (!ether_addr_equal(MacAddr, get_my_bssid23a(&pmlmeinfo->network)))
- return _SUCCESS;
-
- DBG_8723A("%s\n", __func__);
-
- if ((pmlmeinfo->state&0x03) == MSR_INFRA) {
- if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
- pmlmeinfo->state = MSR_NOLINK;
- report_del_sta_event23a(padapter, MacAddr, reason);
-
- } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) {
- pmlmeinfo->state = MSR_NOLINK;
- report_join_res23a(padapter, -2);
- }
- }
-
- return _SUCCESS;
-}
-
-static void process_80211d(struct rtw_adapter *padapter,
- struct wlan_bssid_ex *bssid)
-{
- struct registry_priv *pregistrypriv;
- struct mlme_ext_priv *pmlmeext;
- struct rt_channel_info *chplan_new;
- u8 channel;
- u8 i;
-
- pregistrypriv = &padapter->registrypriv;
- pmlmeext = &padapter->mlmeextpriv;
-
- /* Adjust channel plan by AP Country IE */
- if (pregistrypriv->enable80211d &&
- !pmlmeext->update_channel_plan_by_ap_done) {
- const u8 *ie, *p;
- struct rt_channel_plan chplan_ap;
- struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
- u8 country[4];
- u8 fcn; /* first channel number */
- u8 noc; /* number of channel */
- u8 j, k;
-
- ie = cfg80211_find_ie(WLAN_EID_COUNTRY, bssid->IEs,
- bssid->IELength);
- if (!ie || ie[1] < IEEE80211_COUNTRY_IE_MIN_LEN)
- return;
-
- p = ie + 2;
- ie += ie[1];
- ie += 2;
-
- memcpy(country, p, 3);
- country[3] = '\0';
-
- p += 3;
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
- "%s: 802.11d country =%s\n", __func__, country);
-
- i = 0;
- while ((ie - p) >= 3) {
- fcn = *(p++);
- noc = *(p++);
- p++;
-
- for (j = 0; j < noc; j++) {
- if (fcn <= 14)
- channel = fcn + j; /* 2.4 GHz */
- else
- channel = fcn + j * 4; /* 5 GHz */
-
- chplan_ap.Channel[i++] = channel;
- }
- }
- chplan_ap.Len = i;
-
- memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
- memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
- chplan_new = pmlmeext->channel_set;
-
- i = j = k = 0;
- if (pregistrypriv->wireless_mode & WIRELESS_11G) {
- do {
- if (i == MAX_CHANNEL_NUM ||
- chplan_sta[i].ChannelNum == 0 ||
- chplan_sta[i].ChannelNum > 14)
- break;
-
- if (j == chplan_ap.Len ||
- chplan_ap.Channel[j] > 14)
- break;
-
- if (chplan_sta[i].ChannelNum ==
- chplan_ap.Channel[j]) {
- chplan_new[k].ChannelNum =
- chplan_ap.Channel[j];
- chplan_new[k].ScanType = SCAN_ACTIVE;
- i++;
- j++;
- k++;
- } else if (chplan_sta[i].ChannelNum <
- chplan_ap.Channel[j]) {
- chplan_new[k].ChannelNum =
- chplan_sta[i].ChannelNum;
- chplan_new[k].ScanType =
- SCAN_PASSIVE;
- i++;
- k++;
- } else if (chplan_sta[i].ChannelNum >
- chplan_ap.Channel[j]) {
- chplan_new[k].ChannelNum =
- chplan_ap.Channel[j];
- chplan_new[k].ScanType =
- SCAN_ACTIVE;
- j++;
- k++;
- }
- } while (1);
-
- /* change AP not support channel to Passive scan */
- while (i < MAX_CHANNEL_NUM &&
- chplan_sta[i].ChannelNum != 0 &&
- chplan_sta[i].ChannelNum <= 14) {
- chplan_new[k].ChannelNum =
- chplan_sta[i].ChannelNum;
- chplan_new[k].ScanType = SCAN_PASSIVE;
- i++;
- k++;
- }
-
- /* add channel AP supported */
- while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14){
- chplan_new[k].ChannelNum = chplan_ap.Channel[j];
- chplan_new[k].ScanType = SCAN_ACTIVE;
- j++;
- k++;
- }
- } else {
- /* keep original STA 2.4G channel plan */
- while (i < MAX_CHANNEL_NUM &&
- chplan_sta[i].ChannelNum != 0 &&
- chplan_sta[i].ChannelNum <= 14) {
- chplan_new[k].ChannelNum =
- chplan_sta[i].ChannelNum;
- chplan_new[k].ScanType = chplan_sta[i].ScanType;
- i++;
- k++;
- }
-
- /* skip AP 2.4G channel plan */
- while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14)
- j++;
- }
-
- if (pregistrypriv->wireless_mode & WIRELESS_11A) {
- do {
- if (i == MAX_CHANNEL_NUM ||
- chplan_sta[i].ChannelNum == 0)
- break;
-
- if (j == chplan_ap.Len ||
- chplan_ap.Channel[j] == 0)
- break;
-
- if (chplan_sta[i].ChannelNum ==
- chplan_ap.Channel[j]) {
- chplan_new[k].ChannelNum =
- chplan_ap.Channel[j];
- chplan_new[k].ScanType = SCAN_ACTIVE;
- i++;
- j++;
- k++;
- } else if (chplan_sta[i].ChannelNum <
- chplan_ap.Channel[j]) {
- chplan_new[k].ChannelNum =
- chplan_sta[i].ChannelNum;
- chplan_new[k].ScanType = SCAN_PASSIVE;
- i++;
- k++;
- } else if (chplan_sta[i].ChannelNum >
- chplan_ap.Channel[j]) {
- chplan_new[k].ChannelNum =
- chplan_ap.Channel[j];
- chplan_new[k].ScanType = SCAN_ACTIVE;
- j++;
- k++;
- }
- } while (1);
-
- /* change AP not support channel to Passive scan */
- while (i < MAX_CHANNEL_NUM &&
- chplan_sta[i].ChannelNum != 0) {
- chplan_new[k].ChannelNum =
- chplan_sta[i].ChannelNum;
- chplan_new[k].ScanType = SCAN_PASSIVE;
- i++;
- k++;
- }
-
- /* add channel AP supported */
- while (j < chplan_ap.Len && chplan_ap.Channel[j] != 0) {
- chplan_new[k].ChannelNum = chplan_ap.Channel[j];
- chplan_new[k].ScanType = SCAN_ACTIVE;
- j++;
- k++;
- }
- } else {
- /* keep original STA 5G channel plan */
- while (i < MAX_CHANNEL_NUM &&
- chplan_sta[i].ChannelNum != 0) {
- chplan_new[k].ChannelNum =
- chplan_sta[i].ChannelNum;
- chplan_new[k].ScanType = chplan_sta[i].ScanType;
- i++;
- k++;
- }
- }
- pmlmeext->update_channel_plan_by_ap_done = 1;
- }
-
- /* If channel is used by AP, set channel scan type to active */
- channel = bssid->DSConfig;
- chplan_new = pmlmeext->channel_set;
- i = 0;
- while (i < MAX_CHANNEL_NUM && chplan_new[i].ChannelNum != 0) {
- if (chplan_new[i].ChannelNum == channel) {
- if (chplan_new[i].ScanType == SCAN_PASSIVE) {
- /* 5G Bnad 2, 3 (DFS) doesn't change
- to active scan */
- if (channel >= 52 && channel <= 144)
- break;
-
- chplan_new[i].ScanType = SCAN_ACTIVE;
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
- "%s: change channel %d scan type from passive to active\n",
- __func__, channel);
- }
- break;
- }
- i++;
- }
-}
-
-/****************************************************************************
-
-Following are the functions to report events
-
-*****************************************************************************/
-
-void report_survey_event23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
- struct cmd_obj *pcmd_obj;
- u8 *pevtcmd;
- u32 cmdsz;
- struct survey_event *psurvey_evt;
- struct C2HEvent_Header *pc2h_evt_hdr;
- struct mlme_ext_priv *pmlmeext;
- struct cmd_priv *pcmdpriv;
-
- if (!padapter)
- return;
-
- pmlmeext = &padapter->mlmeextpriv;
- pcmdpriv = &padapter->cmdpriv;
-
- pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!pcmd_obj)
- return;
-
- cmdsz = sizeof(struct survey_event) + sizeof(struct C2HEvent_Header);
- pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
- if (!pevtcmd) {
- kfree(pcmd_obj);
- return;
- }
-
- pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
- pcmd_obj->cmdsz = cmdsz;
- pcmd_obj->parmbuf = pevtcmd;
-
- pcmd_obj->rsp = NULL;
- pcmd_obj->rspsz = 0;
-
- pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
- pc2h_evt_hdr->len = sizeof(struct survey_event);
- pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
- pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
-
- psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
-
- psurvey_evt->bss = collect_bss_info(padapter, precv_frame);
- if (!psurvey_evt->bss) {
- kfree(pcmd_obj);
- kfree(pevtcmd);
- return;
- }
-
- process_80211d(padapter, psurvey_evt->bss);
-
- rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
-
- pmlmeext->sitesurvey_res.bss_cnt++;
-}
-
-void report_surveydone_event23a(struct rtw_adapter *padapter)
-{
- struct cmd_obj *pcmd_obj;
- u8 *pevtcmd;
- u32 cmdsz;
- struct surveydone_event *psurveydone_evt;
- struct C2HEvent_Header *pc2h_evt_hdr;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
- pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!pcmd_obj)
- return;
-
- cmdsz = sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header);
- pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
- if (!pevtcmd) {
- kfree(pcmd_obj);
- return;
- }
-
- pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
- pcmd_obj->cmdsz = cmdsz;
- pcmd_obj->parmbuf = pevtcmd;
-
- pcmd_obj->rsp = NULL;
- pcmd_obj->rspsz = 0;
-
- pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
- pc2h_evt_hdr->len = sizeof(struct surveydone_event);
- pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
- pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
-
- psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
- psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
-
- DBG_8723A("survey done event(%x)\n", psurveydone_evt->bss_cnt);
-
- rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
-}
-
-void report_join_res23a(struct rtw_adapter *padapter, int res)
-{
- struct cmd_obj *pcmd_obj;
- u8 *pevtcmd;
- u32 cmdsz;
- struct joinbss_event *pjoinbss_evt;
- struct C2HEvent_Header *pc2h_evt_hdr;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
- pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!pcmd_obj)
- return;
-
- cmdsz = sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header);
- pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
- if (!pevtcmd) {
- kfree(pcmd_obj);
- return;
- }
-
- pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
- pcmd_obj->cmdsz = cmdsz;
- pcmd_obj->parmbuf = pevtcmd;
-
- pcmd_obj->rsp = NULL;
- pcmd_obj->rspsz = 0;
-
- pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
- pc2h_evt_hdr->len = sizeof(struct joinbss_event);
- pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
- pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
-
- pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
- memcpy((unsigned char *)&pjoinbss_evt->network.network,
- &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
- pjoinbss_evt->network.join_res = res;
-
- DBG_8723A("report_join_res23a(%d)\n", res);
-
- rtw_joinbss_event_prehandle23a(padapter, (u8 *)&pjoinbss_evt->network);
-
- rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
-}
-
-void report_del_sta_event23a(struct rtw_adapter *padapter,
- unsigned char *MacAddr, unsigned short reason)
-{
- struct cmd_obj *pcmd_obj;
- u8 *pevtcmd;
- u32 cmdsz;
- struct sta_info *psta;
- int mac_id;
- struct stadel_event *pdel_sta_evt;
- struct C2HEvent_Header *pc2h_evt_hdr;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
- pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!pcmd_obj)
- return;
-
- cmdsz = sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header);
- pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
- if (!pevtcmd) {
- kfree(pcmd_obj);
- return;
- }
-
- pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
- pcmd_obj->cmdsz = cmdsz;
- pcmd_obj->parmbuf = pevtcmd;
-
- pcmd_obj->rsp = NULL;
- pcmd_obj->rspsz = 0;
-
- pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
- pc2h_evt_hdr->len = sizeof(struct stadel_event);
- pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
- pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
-
- pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
- ether_addr_copy((unsigned char *)&pdel_sta_evt->macaddr, MacAddr);
- memcpy((unsigned char *)pdel_sta_evt->rsvd, (unsigned char *)&reason,
- 2);
-
- psta = rtw_get_stainfo23a(&padapter->stapriv, MacAddr);
- if (psta)
- mac_id = (int)psta->mac_id;
- else
- mac_id = -1;
-
- pdel_sta_evt->mac_id = mac_id;
-
- DBG_8723A("report_del_sta_event23a: delete STA, mac_id =%d\n", mac_id);
-
- rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
-}
-
-void report_add_sta_event23a(struct rtw_adapter *padapter,
- unsigned char *MacAddr, int cam_idx)
-{
- struct cmd_obj *pcmd_obj;
- u8 *pevtcmd;
- u32 cmdsz;
- struct stassoc_event *padd_sta_evt;
- struct C2HEvent_Header *pc2h_evt_hdr;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
- pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!pcmd_obj)
- return;
-
- cmdsz = sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header);
- pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
- if (!pevtcmd) {
- kfree(pcmd_obj);
- return;
- }
-
- pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
- pcmd_obj->cmdsz = cmdsz;
- pcmd_obj->parmbuf = pevtcmd;
-
- pcmd_obj->rsp = NULL;
- pcmd_obj->rspsz = 0;
-
- pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
- pc2h_evt_hdr->len = sizeof(struct stassoc_event);
- pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
- pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
-
- padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
- ether_addr_copy((unsigned char *)&padd_sta_evt->macaddr, MacAddr);
- padd_sta_evt->cam_id = cam_idx;
-
- DBG_8723A("report_add_sta_event23a: add STA\n");
-
- rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
-}
-
-/****************************************************************************
-
-Following are the event callback functions
-
-*****************************************************************************/
-
-/* for sta/adhoc mode */
-void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- /* ERP */
- VCS_update23a(padapter, psta);
-
- /* HT */
- if (pmlmepriv->htpriv.ht_option) {
- psta->htpriv.ht_option = true;
-
- psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
-
- if (support_short_GI23a(padapter, &pmlmeinfo->ht_cap))
- psta->htpriv.sgi = true;
-
- psta->qos_option = true;
-
- } else {
- psta->htpriv.ht_option = false;
-
- psta->htpriv.ampdu_enable = false;
-
- psta->htpriv.sgi = false;
- psta->qos_option = false;
-
- }
- psta->htpriv.bwmode = pmlmeext->cur_bwmode;
- psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
-
- psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
- psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
-
- /* QoS */
- if (pmlmepriv->qos_option)
- psta->qos_option = true;
-
- psta->state = _FW_LINKED;
-}
-
-void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter,
- int join_res)
-{
- struct sta_info *psta, *psta_bmc;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- if (join_res < 0) {
- hw_var_set_mlme_join(padapter, 1);
- hw_var_set_bssid(padapter, null_addr);
-
- /* restore to initial setting. */
- update_tx_basic_rate23a(padapter,
- padapter->registrypriv.wireless_mode);
-
- goto exit_mlmeext_joinbss_event_callback23a;
- }
-
- if ((pmlmeinfo->state&0x03) == MSR_ADHOC) {
- /* for bc/mc */
- psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
- if (psta_bmc) {
- pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
- update_bmc_sta_support_rate23a(padapter, psta_bmc->mac_id);
- Update_RA_Entry23a(padapter, psta_bmc);
- }
- }
-
- /* turn on dynamic functions */
- rtl8723a_odm_support_ability_set(padapter, DYNAMIC_ALL_FUNC_ENABLE);
-
- /* update IOT-releated issue */
- update_IOT_info23a(padapter);
-
- HalSetBrateCfg23a(padapter, cur_network->SupportedRates);
-
- /* BCN interval */
- rtl8723a_set_beacon_interval(padapter, pmlmeinfo->bcn_interval);
-
- /* update capability */
- update_capinfo23a(padapter, pmlmeinfo->capability);
-
- /* WMM, Update EDCA param */
- WMMOnAssocRsp23a(padapter);
-
- /* HT */
- HTOnAssocRsp23a(padapter);
-
- /* Set cur_channel&cur_bwmode&cur_ch_offset */
- set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
- psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
- if (psta) { /* only for infra. mode */
- pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
-
- /* DBG_8723A("set_sta_rate23a\n"); */
-
- psta->wireless_mode = pmlmeext->cur_wireless_mode;
-
- /* set per sta rate after updating HT cap. */
- set_sta_rate23a(padapter, psta);
- }
-
- hw_var_set_mlme_join(padapter, 2);
-
- if ((pmlmeinfo->state&0x03) == MSR_INFRA) {
- /* correcting TSF */
- rtw_correct_TSF(padapter);
-
- /* set_link_timer(pmlmeext, DISCONNECT_TO); */
- }
-
- rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_CONNECT, 0);
-
-exit_mlmeext_joinbss_event_callback23a:
- DBG_8723A("=>%s\n", __func__);
-}
-
-void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter,
- struct sta_info *psta)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- DBG_8723A("%s\n", __func__);
-
- if ((pmlmeinfo->state & 0x03) == MSR_ADHOC) {
- /* adhoc master or sta_count>1 */
- if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
- /* nothing to do */
- } else { /* adhoc client */
- /* correcting TSF */
- rtw_correct_TSF(padapter);
-
- /* start beacon */
- if (send_beacon23a(padapter) != _SUCCESS) {
- pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
-
- pmlmeinfo->state ^= MSR_ADHOC;
-
- return;
- }
-
- pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
- }
- hw_var_set_mlme_join(padapter, 2);
- }
-
- pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
-
- /* rate radaptive */
- Update_RA_Entry23a(padapter, psta);
-
- /* update adhoc sta_info */
- update_sta_info23a(padapter, psta);
-}
-
-void mlmeext_sta_del_event_callback23a(struct rtw_adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- if (is_client_associated_to_ap23a(padapter) ||
- is_IBSS_empty23a(padapter)) {
- /* set_opmode_cmd(padapter, infra_client_with_mlme); */
-
- hw_var_set_mlme_disconnect(padapter);
- hw_var_set_bssid(padapter, null_addr);
-
- /* restore to initial setting. */
- update_tx_basic_rate23a(padapter,
- padapter->registrypriv.wireless_mode);
-
- /* switch to the 20M Hz mode after disconnect */
- pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
- pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-
- set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
- pmlmeext->cur_ch_offset,
- pmlmeext->cur_bwmode);
-
- flush_all_cam_entry23a(padapter);
-
- pmlmeinfo->state = MSR_NOLINK;
-
- /* set MSR to no link state -> infra. mode */
- rtl8723a_set_media_status(padapter, MSR_INFRA);
-
- del_timer_sync(&pmlmeext->link_timer);
- }
-}
-
-static u8 chk_ap_is_alive(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- u8 ret = false;
-
- if (sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta) &&
- sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) &&
- sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
- ret = false;
- else
- ret = true;
-
- sta_update_last_rx_pkts(psta);
- return ret;
-}
-
-void linked_status_chk23a(struct rtw_adapter *padapter)
-{
- u32 i;
- struct sta_info *psta;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- if (is_client_associated_to_ap23a(padapter)) {
- /* linked infrastructure client mode */
-
- int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
- int rx_chk_limit;
-
- rx_chk_limit = 4;
-
- psta = rtw_get_stainfo23a(pstapriv,
- pmlmeinfo->network.MacAddress);
- if (psta) {
- bool is_p2p_enable = false;
-
- if (chk_ap_is_alive(padapter, psta) == false)
- rx_chk = _FAIL;
-
- if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
- tx_chk = _FAIL;
-
- if (pmlmeext->active_keep_alive_check &&
- (rx_chk == _FAIL || tx_chk == _FAIL)) {
- u8 backup_oper_channel = 0;
-
- /* switch to correct channel of current
- network before issue keep-alive frames */
- if (rtw_get_oper_ch23a(padapter) !=
- pmlmeext->cur_channel) {
- backup_oper_channel =
- rtw_get_oper_ch23a(padapter);
- SelectChannel23a(padapter,
- pmlmeext->cur_channel);
- }
-
- if (rx_chk != _SUCCESS)
- issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
-
- if ((tx_chk != _SUCCESS &&
- pmlmeinfo->link_count++ == 0xf) ||
- rx_chk != _SUCCESS) {
- tx_chk = issue_nulldata23a(padapter,
- psta->hwaddr,
- 0, 3, 1);
- /* if tx acked and p2p disabled,
- set rx_chk _SUCCESS to reset retry
- count */
- if (tx_chk == _SUCCESS &&
- !is_p2p_enable)
- rx_chk = _SUCCESS;
- }
-
- /* back to the original operation channel */
- if (backup_oper_channel>0)
- SelectChannel23a(padapter,
- backup_oper_channel);
- } else {
- if (rx_chk != _SUCCESS) {
- if (pmlmeext->retry == 0) {
- issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
- issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
- issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
- }
- }
-
- if (tx_chk != _SUCCESS &&
- pmlmeinfo->link_count++ == 0xf)
- tx_chk = issue_nulldata23a(padapter,
- NULL, 0, 1,
- 0);
- }
-
- if (rx_chk == _FAIL) {
- pmlmeext->retry++;
- if (pmlmeext->retry > rx_chk_limit) {
- DBG_8723A_LEVEL(_drv_always_,
- "%s(%s): disconnect or "
- "roaming\n", __func__,
- padapter->pnetdev->name);
- receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress,
- WLAN_REASON_EXPIRATION_CHK);
- return;
- }
- } else
- pmlmeext->retry = 0;
-
- if (tx_chk == _FAIL)
- pmlmeinfo->link_count &= 0xf;
- else {
- pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
- pmlmeinfo->link_count = 0;
- }
-
- }
- } else if (is_client_associated_to_ibss23a(padapter)) {
- /* linked IBSS mode */
- /* for each assoc list entry to check the rx pkt counter */
- for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
- if (pmlmeinfo->FW_sta_info[i].status == 1) {
- psta = pmlmeinfo->FW_sta_info[i].psta;
-
- if (!psta)
- continue;
-
- if (pmlmeinfo->FW_sta_info[i].rx_pkt ==
- sta_rx_pkts(psta)) {
-
- if (pmlmeinfo->FW_sta_info[i].retry<3) {
- pmlmeinfo->FW_sta_info[i].retry++;
- } else {
- pmlmeinfo->FW_sta_info[i].retry = 0;
- pmlmeinfo->FW_sta_info[i].status = 0;
- report_del_sta_event23a(padapter, psta->hwaddr,
- 65535/* indicate disconnect caused by no rx */
- );
- }
- } else {
- pmlmeinfo->FW_sta_info[i].retry = 0;
- pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
- }
- }
- }
- /* set_link_timer(pmlmeext, DISCONNECT_TO); */
- }
-}
-
-static void survey_timer_hdl(unsigned long data)
-{
- struct rtw_adapter *padapter = (struct rtw_adapter *)data;
- struct cmd_obj *ph2c;
- struct sitesurvey_parm *psurveyPara;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- /* issue rtw_sitesurvey_cmd23a */
- if (pmlmeext->sitesurvey_res.state > SCAN_START) {
- if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
- pmlmeext->sitesurvey_res.channel_idx++;
-
- if (pmlmeext->scan_abort == true) {
- pmlmeext->sitesurvey_res.channel_idx =
- pmlmeext->sitesurvey_res.ch_num;
- DBG_8723A("%s idx:%d\n", __func__,
- pmlmeext->sitesurvey_res.channel_idx);
-
- pmlmeext->scan_abort = false;/* reset */
- }
-
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!ph2c)
- goto exit_survey_timer_hdl;
-
- psurveyPara = kzalloc(sizeof(struct sitesurvey_parm),
- GFP_ATOMIC);
- if (!psurveyPara) {
- kfree(ph2c);
- goto exit_survey_timer_hdl;
- }
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara,
- GEN_CMD_CODE(_SiteSurvey));
- rtw_enqueue_cmd23a(pcmdpriv, ph2c);
- }
-
-exit_survey_timer_hdl:
- return;
-}
-
-static void link_timer_hdl(unsigned long data)
-{
- struct rtw_adapter *padapter = (struct rtw_adapter *)data;
- /* static unsigned int rx_pkt = 0; */
- /* static u64 tx_cnt = 0; */
- /* struct xmit_priv *pxmitpriv = &padapter->xmitpriv; */
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- /* struct sta_priv *pstapriv = &padapter->stapriv; */
-
- if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
- DBG_8723A("link_timer_hdl:no beacon while connecting\n");
- pmlmeinfo->state = MSR_NOLINK;
- report_join_res23a(padapter, -3);
- } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
- /* re-auth timer */
- if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
- /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
- /* */
- pmlmeinfo->state = 0;
- report_join_res23a(padapter, -1);
- return;
- /* */
- /* else */
- /* */
- /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
- /* pmlmeinfo->reauth_count = 0; */
- /* */
- }
-
- DBG_8723A("link_timer_hdl: auth timeout and try again\n");
- pmlmeinfo->auth_seq = 1;
- issue_auth(padapter, NULL, 0);
- set_link_timer(pmlmeext, REAUTH_TO);
- } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
- /* re-assoc timer */
- if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
- pmlmeinfo->state = MSR_NOLINK;
- report_join_res23a(padapter, -2);
- return;
- }
-
- DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
- issue_assocreq(padapter);
- set_link_timer(pmlmeext, REASSOC_TO);
- }
-}
-
-static void addba_timer_hdl(unsigned long data)
-{
- struct sta_info *psta = (struct sta_info *)data;
- struct ht_priv *phtpriv;
-
- if (!psta)
- return;
-
- phtpriv = &psta->htpriv;
-
- if (phtpriv->ht_option && phtpriv->ampdu_enable) {
- if (phtpriv->candidate_tid_bitmap)
- phtpriv->candidate_tid_bitmap = 0x0;
- }
-}
-
-void init_addba_retry_timer23a(struct sta_info *psta)
-{
- setup_timer(&psta->addba_retry_timer, addba_timer_hdl,
- (unsigned long)psta);
-}
-
-void init_mlme_ext_timer23a(struct rtw_adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- setup_timer(&pmlmeext->survey_timer, survey_timer_hdl,
- (unsigned long)padapter);
-
- setup_timer(&pmlmeext->link_timer, link_timer_hdl,
- (unsigned long)padapter);
-}
-
-int NULL_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- return H2C_SUCCESS;
-}
-
-int setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- enum nl80211_iftype type;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- const struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
-
- switch (psetop->mode) {
- case NL80211_IFTYPE_P2P_GO:
- case NL80211_IFTYPE_AP:
- pmlmeinfo->state = MSR_AP;
- type = MSR_AP;
- break;
- case NL80211_IFTYPE_P2P_CLIENT:
- case NL80211_IFTYPE_STATION:
- /* clear state */
- pmlmeinfo->state &= ~(BIT(0)|BIT(1));
- /* set to STATION_STATE */
- pmlmeinfo->state |= MSR_INFRA;
- type = MSR_INFRA;
- break;
- case NL80211_IFTYPE_ADHOC:
- type = MSR_ADHOC;
- break;
- default:
- type = MSR_NOLINK;
- break;
- }
-
- hw_var_set_opmode(padapter, type);
- /* Set_NETYPE0_MSR(padapter, type); */
-
- return H2C_SUCCESS;
-}
-
-int createbss_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
- const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
- /* u32 initialgain; */
-
- if (pparm->ifmode == NL80211_IFTYPE_AP ||
- pparm->ifmode == NL80211_IFTYPE_P2P_GO) {
-#ifdef CONFIG_8723AU_AP_MODE
- if (pmlmeinfo->state == MSR_AP) {
- /* todo: */
- return H2C_SUCCESS;
- }
-#endif
- }
-
- /* below is for ad-hoc master */
- if (pparm->ifmode == NL80211_IFTYPE_ADHOC) {
- rtw_joinbss_reset23a(padapter);
-
- pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
- pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- pmlmeinfo->ERP_enable = 0;
- pmlmeinfo->WMM_enable = 0;
- pmlmeinfo->HT_enable = 0;
- pmlmeinfo->HT_caps_enable = 0;
- pmlmeinfo->HT_info_enable = 0;
-
- /* disable dynamic functions, such as high power, DIG */
- rtl8723a_odm_support_ability_backup(padapter);
-
- rtl8723a_odm_support_ability_clr(padapter,
- DYNAMIC_FUNC_DISABLE);
-
- /* cancel link timer */
- del_timer_sync(&pmlmeext->link_timer);
-
- /* clear CAM */
- flush_all_cam_entry23a(padapter);
-
- if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
- return H2C_PARAMETERS_ERROR;
-
- memcpy(pnetwork, pparm, sizeof(struct wlan_bssid_ex));
-
- start_create_ibss(padapter);
- }
-
- return H2C_SUCCESS;
-}
-
-int join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- struct registry_priv *pregpriv = &padapter->registrypriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
- const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
- struct ieee80211_ht_operation *pht_info;
- u32 i;
- u8 *p;
- /* u32 initialgain; */
- /* u32 acparm; */
-
- /* check already connecting to AP or not */
- if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
- if (pmlmeinfo->state & MSR_INFRA)
- issue_deauth_ex(padapter, pnetwork->MacAddress,
- WLAN_REASON_DEAUTH_LEAVING, 5, 100);
-
- pmlmeinfo->state = MSR_NOLINK;
-
- /* clear CAM */
- flush_all_cam_entry23a(padapter);
-
- del_timer_sync(&pmlmeext->link_timer);
-
- /* set MSR to nolink -> infra. mode */
- rtl8723a_set_media_status(padapter, MSR_INFRA);
-
- hw_var_set_mlme_disconnect(padapter);
- }
-
- rtw_joinbss_reset23a(padapter);
-
- pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
- pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- pmlmeinfo->ERP_enable = 0;
- pmlmeinfo->WMM_enable = 0;
- pmlmeinfo->HT_enable = 0;
- pmlmeinfo->HT_caps_enable = 0;
- pmlmeinfo->HT_info_enable = 0;
- pmlmeinfo->bwmode_updated = false;
- /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
-
- if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
- return H2C_PARAMETERS_ERROR;
-
- memcpy(pnetwork, pbuf, sizeof(struct wlan_bssid_ex));
-
- /* Check AP vendor to move rtw_joinbss_cmd23a() */
- /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pnetwork->IEs,
- pnetwork->IELength); */
-
- for (i = 0; i < pnetwork->IELength;) {
- p = pnetwork->IEs + i;
-
- switch (p[0]) {
- case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */
- if (!memcmp(p + 2, WMM_OUI23A, 4))
- pmlmeinfo->WMM_enable = 1;
- break;
-
- case WLAN_EID_HT_CAPABILITY: /* Get HT Cap IE. */
- pmlmeinfo->HT_caps_enable = 1;
- break;
-
- case WLAN_EID_HT_OPERATION: /* Get HT Info IE. */
- pmlmeinfo->HT_info_enable = 1;
-
- /* spec case only for cisco's ap because cisco's ap
- * issue assoc rsp using mcs rate @40MHz or @20MHz */
- pht_info = (struct ieee80211_ht_operation *)(p + 2);
-
- if (pregpriv->cbw40_enable &&
- (pht_info->ht_param &
- IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
- /* switch to the 40M Hz mode according to AP */
- pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
- switch (pht_info->ht_param &
- IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
- case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
- pmlmeext->cur_ch_offset =
- HAL_PRIME_CHNL_OFFSET_LOWER;
- break;
-
- case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
- pmlmeext->cur_ch_offset =
- HAL_PRIME_CHNL_OFFSET_UPPER;
- break;
-
- default:
- pmlmeext->cur_ch_offset =
- HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- break;
- }
-
- DBG_8723A("set ch/bw before connected\n");
- }
- break;
-
- default:
- break;
- }
-
- i += (p[1] + 2);
- }
-
- hw_var_set_bssid(padapter, pmlmeinfo->network.MacAddress);
- hw_var_set_mlme_join(padapter, 0);
-
- /* cancel link timer */
- del_timer_sync(&pmlmeext->link_timer);
-
- start_clnt_join(padapter);
-
- return H2C_SUCCESS;
-}
-
-int disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- const struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
-
- if (is_client_associated_to_ap23a(padapter)) {
- issue_deauth_ex(padapter, pnetwork->MacAddress,
- WLAN_REASON_DEAUTH_LEAVING,
- param->deauth_timeout_ms/100, 100);
- }
-
- /* set_opmode_cmd(padapter, infra_client_with_mlme); */
-
- /* pmlmeinfo->state = MSR_NOLINK; */
-
- hw_var_set_mlme_disconnect(padapter);
- hw_var_set_bssid(padapter, null_addr);
-
- /* restore to initial setting. */
- update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
-
- if ((pmlmeinfo->state & 0x03) == MSR_ADHOC ||
- (pmlmeinfo->state & 0x03) == MSR_AP)
- rtl8723a_set_bcn_func(padapter, 0); /* Stop BCN */
-
- /* set MSR to no link state -> infra. mode */
- rtl8723a_set_media_status(padapter, MSR_INFRA);
-
- pmlmeinfo->state = MSR_NOLINK;
-
- /* switch to the 20M Hz mode after disconnect */
- pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
- pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-
- set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
- pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
- flush_all_cam_entry23a(padapter);
-
- del_timer_sync(&pmlmeext->link_timer);
-
- rtw_free_uc_swdec_pending_queue23a(padapter);
-
- return H2C_SUCCESS;
-}
-
-static int
-rtw_scan_ch_decision(struct rtw_adapter *padapter,
- struct rtw_ieee80211_channel *out, u32 out_num,
- const struct rtw_ieee80211_channel *in, u32 in_num)
-{
- int i, j;
- int scan_ch_num = 0;
- int set_idx;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- /* clear out first */
- memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
-
- /* acquire channels from in */
- j = 0;
- for (i = 0;i<in_num;i++) {
- if (in[i].hw_value &&
- !(in[i].flags & IEEE80211_CHAN_DISABLED) &&
- (set_idx = rtw_ch_set_search_ch23a(pmlmeext->channel_set,
- in[i].hw_value)) >= 0) {
- memcpy(&out[j], &in[i],
- sizeof(struct rtw_ieee80211_channel));
-
- if (pmlmeext->channel_set[set_idx].ScanType ==
- SCAN_PASSIVE)
- out[j].flags &= IEEE80211_CHAN_NO_IR;
-
- j++;
- }
- if (j>= out_num)
- break;
- }
-
- /* if out is empty, use channel_set as default */
- if (j == 0) {
- for (i = 0;i<pmlmeext->max_chan_nums;i++) {
- out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
-
- if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
- out[i].flags &= IEEE80211_CHAN_NO_IR;
-
- j++;
- }
- }
-
- if (padapter->setband == GHZ_24) { /* 2.4G */
- for (i = 0; i < j ; i++) {
- if (out[i].hw_value > 35)
- memset(&out[i], 0,
- sizeof(struct rtw_ieee80211_channel));
- else
- scan_ch_num++;
- }
- j = scan_ch_num;
- } else if (padapter->setband == GHZ_50) { /* 5G */
- for (i = 0; i < j ; i++) {
- if (out[i].hw_value > 35) {
- memcpy(&out[scan_ch_num++], &out[i],
- sizeof(struct rtw_ieee80211_channel));
- }
- }
- j = scan_ch_num;
- } else
- {}
-
- return j;
-}
-
-int sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- const struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
- u8 bdelayscan = false;
- u32 initialgain;
- u32 i;
-
- if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
- pmlmeext->sitesurvey_res.state = SCAN_START;
- pmlmeext->sitesurvey_res.bss_cnt = 0;
- pmlmeext->sitesurvey_res.channel_idx = 0;
-
- for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
- if (pparm->ssid[i].ssid_len) {
- memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid,
- pparm->ssid[i].ssid,
- IEEE80211_MAX_SSID_LEN);
- pmlmeext->sitesurvey_res.ssid[i].ssid_len =
- pparm->ssid[i].ssid_len;
- } else {
- pmlmeext->sitesurvey_res.ssid[i].ssid_len = 0;
- }
- }
-
- pmlmeext->sitesurvey_res.ch_num =
- rtw_scan_ch_decision(padapter,
- pmlmeext->sitesurvey_res.ch,
- RTW_CHANNEL_SCAN_AMOUNT,
- pparm->ch, pparm->ch_num);
-
- pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
-
- /* issue null data if associating to the AP */
- if (is_client_associated_to_ap23a(padapter)) {
- pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
-
- /* switch to correct channel of current network
- before issue keep-alive frames */
- if (rtw_get_oper_ch23a(padapter) !=
- pmlmeext->cur_channel)
- SelectChannel23a(padapter,
- pmlmeext->cur_channel);
-
- issue_nulldata23a(padapter, NULL, 1, 3, 500);
-
- bdelayscan = true;
- }
-
- if (bdelayscan) {
- /* delay 50ms to protect nulldata(1). */
- set_survey_timer(pmlmeext, 50);
- return H2C_SUCCESS;
- }
- }
-
- if (pmlmeext->sitesurvey_res.state == SCAN_START ||
- pmlmeext->sitesurvey_res.state == SCAN_TXNULL) {
- /* disable dynamic functions, such as high power, DIG */
- rtl8723a_odm_support_ability_backup(padapter);
- rtl8723a_odm_support_ability_clr(padapter,
- DYNAMIC_FUNC_DISABLE);
-
- /* config the initial gain under scanning, need to
- write the BB registers */
- if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == true)
- initialgain = 0x30;
- else
- initialgain = 0x1E;
-
- rtl8723a_set_initial_gain(padapter, initialgain);
-
- /* set MSR to no link state */
- rtl8723a_set_media_status(padapter, MSR_NOLINK);
-
- rtl8723a_mlme_sitesurvey(padapter, 1);
-
- pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
- }
-
- rtw_site_survey(padapter);
-
- return H2C_SUCCESS;
-}
-
-int setauth_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- const struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- if (pparm->mode < 4)
- pmlmeinfo->auth_algo = pparm->mode;
-
- return H2C_SUCCESS;
-}
-
-int setkey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- unsigned short ctrl;
- const struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- /* main tx key for wep. */
- if (pparm->set_tx)
- pmlmeinfo->key_index = pparm->keyid;
-
- /* write cam */
- ctrl = BIT(15) | (pparm->algorithm) << 2 | pparm->keyid;
-
- DBG_8723A_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 "
- "WEP104-5 TKIP-2 AES-4) keyid:%d\n",
- pparm->algorithm, pparm->keyid);
- rtl8723a_cam_write(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
-
- /* allow multicast packets to driver */
- rtl8723a_on_rcr_am(padapter);
-
- return H2C_SUCCESS;
-}
-
-int set_stakey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- u16 ctrl = 0;
- u8 cam_id;/* cam_entry */
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- const struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
-
- /* cam_entry: */
- /* 0~3 for default key */
-
- /* for concurrent mode (ap+sta): */
- /* default key is disable, using sw encrypt/decrypt */
- /* cam_entry = 4 for sta mode (macid = 0) */
- /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
-
- /* for concurrent mode (sta+sta): */
- /* default key is disable, using sw encrypt/decrypt */
- /* cam_entry = 4 mapping to macid = 0 */
- /* cam_entry = 5 mapping to macid = 2 */
-
- cam_id = 4;
-
- DBG_8723A_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 "
- "WEP104-5 TKIP-2 AES-4) camid:%d\n",
- pparm->algorithm, cam_id);
- if ((pmlmeinfo->state & 0x03) == MSR_AP) {
- struct sta_info *psta;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- if (pparm->algorithm == 0) { /* clear cam entry */
- clear_cam_entry23a(padapter, pparm->id);
- return H2C_SUCCESS_RSP;
- }
-
- psta = rtw_get_stainfo23a(pstapriv, pparm->addr);
- if (psta) {
- ctrl = BIT(15) | (pparm->algorithm << 2);
-
- DBG_8723A("r871x_set_stakey_hdl23a(): enc_algorithm "
- "=%d\n", pparm->algorithm);
-
- if (psta->mac_id < 1 || psta->mac_id > (NUM_STA - 4)) {
- DBG_8723A("r871x_set_stakey_hdl23a():set_stakey"
- " failed, mac_id(aid) =%d\n",
- psta->mac_id);
- return H2C_REJECTED;
- }
-
- /* 0~3 for default key, cmd_id = macid + 3,
- macid = aid+1; */
- cam_id = psta->mac_id + 3;
-
- DBG_8723A("Write CAM, mac_addr =%pM, "
- "cam_entry =%d\n", pparm->addr, cam_id);
-
- rtl8723a_cam_write(padapter, cam_id, ctrl,
- pparm->addr, pparm->key);
-
- return H2C_SUCCESS_RSP;
- } else {
- DBG_8723A("r871x_set_stakey_hdl23a(): sta has been "
- "free\n");
- return H2C_REJECTED;
- }
- }
-
- /* below for sta mode */
-
- if (pparm->algorithm == 0) { /* clear cam entry */
- clear_cam_entry23a(padapter, pparm->id);
- return H2C_SUCCESS;
- }
-
- ctrl = BIT(15) | (pparm->algorithm << 2);
-
- rtl8723a_cam_write(padapter, cam_id, ctrl, pparm->addr, pparm->key);
-
- pmlmeinfo->enc_algo = pparm->algorithm;
-
- return H2C_SUCCESS;
-}
-
-int add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- const struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct sta_info *psta;
-
- psta = rtw_get_stainfo23a(&padapter->stapriv, pparm->addr);
-
- if (!psta)
- return H2C_SUCCESS;
-
- if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
- pmlmeinfo->HT_enable) ||
- (pmlmeinfo->state & 0x03) == MSR_AP) {
- issue_action_BA23a(padapter, pparm->addr,
- WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
- mod_timer(&psta->addba_retry_timer,
- jiffies + msecs_to_jiffies(ADDBA_TO));
- } else
- psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
-
- return H2C_SUCCESS;
-}
-
-int set_tx_beacon_cmd23a(struct rtw_adapter *padapter)
-{
- struct cmd_obj *ph2c;
- struct Tx_Beacon_param *ptxBeacon_parm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- u8 res = _SUCCESS;
- int len_diff = 0;
-
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
- if (!ph2c) {
- res = _FAIL;
- goto exit;
- }
-
- ptxBeacon_parm = kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC);
- if (!ptxBeacon_parm) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network,
- sizeof(struct wlan_bssid_ex));
-
- len_diff = update_hidden_ssid(ptxBeacon_parm->network.IEs,
- ptxBeacon_parm->network.IELength,
- pmlmeinfo->hidden_ssid_mode);
- ptxBeacon_parm->network.IELength += len_diff;
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm,
- GEN_CMD_CODE(_TX_Beacon));
-
- res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
-
-exit:
- return res;
-}
-
-int mlme_evt_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- u8 evt_code, evt_seq;
- u16 evt_sz;
- const struct C2HEvent_Header *c2h;
- void (*event_callback)(struct rtw_adapter *dev, const u8 *pbuf);
-
- c2h = (struct C2HEvent_Header *)pbuf;
- evt_sz = c2h->len;
- evt_seq = c2h->seq;
- evt_code = c2h->ID;
-
- /* checking if event code is valid */
- if (evt_code >= MAX_C2HEVT) {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
- "Event Code(%d) mismatch!\n", evt_code);
- goto _abort_event_;
- }
-
- /* checking if event size match the event parm size */
- if (wlanevents[evt_code].parmsize != 0 &&
- wlanevents[evt_code].parmsize != evt_sz) {
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
- "Event(%d) Parm Size mismatch (%d vs %d)!\n",
- evt_code, wlanevents[evt_code].parmsize, evt_sz);
- goto _abort_event_;
- }
-
- event_callback = wlanevents[evt_code].event_callback;
- event_callback(padapter, pbuf + sizeof(struct C2HEvent_Header));
-
-_abort_event_:
-
- return H2C_SUCCESS;
-}
-
-int h2c_msg_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- if (!pbuf)
- return H2C_PARAMETERS_ERROR;
-
- return H2C_SUCCESS;
-}
-
-int tx_beacon_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- if (send_beacon23a(padapter) == _FAIL) {
- DBG_8723A("issue_beacon23a, fail!\n");
- return H2C_PARAMETERS_ERROR;
- }
-#ifdef CONFIG_8723AU_AP_MODE
- else { /* tx bc/mc frames after update TIM */
- struct sta_info *psta_bmc;
- struct list_head *phead;
- struct xmit_frame *pxmitframe, *ptmp;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- /* for BC/MC Frames */
- psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
- if (!psta_bmc)
- return H2C_SUCCESS;
-
- if (pstapriv->tim_bitmap & BIT(0) && psta_bmc->sleepq_len > 0) {
- msleep(10);/* 10ms, ATIM(HIQ) Windows */
- /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
- spin_lock_bh(&pxmitpriv->lock);
-
- phead = get_list_head(&psta_bmc->sleep_q);
-
- list_for_each_entry_safe(pxmitframe, ptmp,
- phead, list) {
-
- list_del_init(&pxmitframe->list);
-
- psta_bmc->sleepq_len--;
- if (psta_bmc->sleepq_len>0)
- pxmitframe->attrib.mdata = 1;
- else
- pxmitframe->attrib.mdata = 0;
-
- pxmitframe->attrib.triggered = 1;
-
- pxmitframe->attrib.qsel = 0x11;/* HIQ */
-
- rtl8723au_hal_xmitframe_enqueue(padapter,
- pxmitframe);
- }
- /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
- spin_unlock_bh(&pxmitpriv->lock);
- }
- }
-#endif
-
- return H2C_SUCCESS;
-}
-
-int set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- const struct set_ch_parm *set_ch_parm;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- if (!pbuf)
- return H2C_PARAMETERS_ERROR;
-
- set_ch_parm = (struct set_ch_parm *)pbuf;
-
- DBG_8723A("%s(%s): ch:%u, bw:%u, ch_offset:%u\n", __func__,
- padapter->pnetdev->name, set_ch_parm->ch,
- set_ch_parm->bw, set_ch_parm->ch_offset);
-
- pmlmeext->cur_channel = set_ch_parm->ch;
- pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
- pmlmeext->cur_bwmode = set_ch_parm->bw;
-
- set_channel_bwmode23a(padapter, set_ch_parm->ch,
- set_ch_parm->ch_offset, set_ch_parm->bw);
-
- return H2C_SUCCESS;
-}
-
-int set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- const struct SetChannelPlan_param *setChannelPlan_param;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- if (!pbuf)
- return H2C_PARAMETERS_ERROR;
-
- setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
-
- pmlmeext->max_chan_nums =
- init_channel_set(padapter, setChannelPlan_param->channel_plan,
- pmlmeext->channel_set);
- init_channel_list(padapter, pmlmeext->channel_set,
- pmlmeext->max_chan_nums, &pmlmeext->channel_list);
-
- return H2C_SUCCESS;
-}
-
-int led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- struct LedBlink_param *ledBlink_param;
-
- if (!pbuf)
- return H2C_PARAMETERS_ERROR;
-
- ledBlink_param = (struct LedBlink_param *)pbuf;
-
- return H2C_SUCCESS;
-}
-
-int set_csa_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- return H2C_REJECTED;
-}
-
-/* TDLS_WRCR : write RCR DATA BIT */
-/* TDLS_SD_PTI : issue peer traffic indication */
-/* TDLS_CS_OFF : go back to the channel linked with AP,
- terminating channel switch procedure */
-/* TDLS_INIT_CH_SEN : init channel sensing, receive all data and
- mgnt frame */
-/* TDLS_DONE_CH_SEN : channel sensing and report candidate channel */
-/* TDLS_OFF_CH : first time set channel to off channel */
-/* TDLS_BASE_CH : go back tp the channel linked with AP when set
- base channel as target channel */
-/* TDLS_P_OFF_CH : periodically go to off channel */
-/* TDLS_P_BASE_CH : periodically go back to base channel */
-/* TDLS_RS_RCR : restore RCR */
-/* TDLS_CKALV_PH1 : check alive timer phase1 */
-/* TDLS_CKALV_PH2 : check alive timer phase2 */
-/* TDLS_FREE_STA : free tdls sta */
-int tdls_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
-{
- return H2C_REJECTED;
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c b/drivers/staging/rtl8723au/core/rtw_pwrctrl.c
deleted file mode 100644
index 7488a104935b..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c
+++ /dev/null
@@ -1,606 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTW_PWRCTRL_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <osdep_intf.h>
-#include <rtl8723a_cmd.h>
-#include <rtw_sreset.h>
-
-#include <rtl8723a_bt_intf.h>
-#include <usb_ops_linux.h>
-
-void ips_enter23a(struct rtw_adapter *padapter)
-{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-
- down(&pwrpriv->lock);
-
- pwrpriv->bips_processing = true;
-
- /* syn ips_mode with request */
- pwrpriv->ips_mode = pwrpriv->ips_mode_req;
-
- pwrpriv->ips_enter23a_cnts++;
- DBG_8723A("==>ips_enter23a cnts:%d\n", pwrpriv->ips_enter23a_cnts);
- rtl8723a_BT_disable_coexist(padapter);
-
- if (pwrpriv->change_rfpwrstate == rf_off) {
- pwrpriv->bpower_saving = true;
- DBG_8723A_LEVEL(_drv_always_, "nolinked power save enter\n");
-
- if (pwrpriv->ips_mode == IPS_LEVEL_2)
- pwrpriv->bkeepfwalive = true;
-
- rtw_ips_pwr_down23a(padapter);
- pwrpriv->rf_pwrstate = rf_off;
- }
- pwrpriv->bips_processing = false;
-
- up(&pwrpriv->lock);
-}
-
-int ips_leave23a(struct rtw_adapter *padapter)
-{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- int result = _SUCCESS;
- int keyid;
-
- down(&pwrpriv->lock);
-
- if (pwrpriv->rf_pwrstate == rf_off && !pwrpriv->bips_processing) {
- pwrpriv->bips_processing = true;
- pwrpriv->change_rfpwrstate = rf_on;
- pwrpriv->ips_leave23a_cnts++;
- DBG_8723A("==>ips_leave23a cnts:%d\n",
- pwrpriv->ips_leave23a_cnts);
-
- result = rtw_ips_pwr_up23a(padapter);
- if (result == _SUCCESS)
- pwrpriv->rf_pwrstate = rf_on;
-
- DBG_8723A_LEVEL(_drv_always_, "nolinked power save leave\n");
-
- if (psecuritypriv->dot11PrivacyAlgrthm ==
- WLAN_CIPHER_SUITE_WEP40 ||
- psecuritypriv->dot11PrivacyAlgrthm ==
- WLAN_CIPHER_SUITE_WEP104) {
- DBG_8723A("==>%s, channel(%d), processing(%x)\n",
- __func__, padapter->mlmeextpriv.cur_channel,
- pwrpriv->bips_processing);
- set_channel_bwmode23a(padapter,
- padapter->mlmeextpriv.cur_channel,
- HAL_PRIME_CHNL_OFFSET_DONT_CARE,
- HT_CHANNEL_WIDTH_20);
- for (keyid = 0; keyid < 4; keyid++) {
- if (pmlmepriv->key_mask & BIT(keyid)) {
- if (keyid ==
- psecuritypriv->dot11PrivacyKeyIndex)
- result = rtw_set_key23a(padapter, psecuritypriv, keyid, 1);
- else
- result = rtw_set_key23a(padapter, psecuritypriv, keyid, 0);
- }
- }
- }
-
- DBG_8723A("==> ips_leave23a.....LED(0x%08x)...\n",
- rtl8723au_read32(padapter, 0x4c));
- pwrpriv->bips_processing = false;
-
- pwrpriv->bkeepfwalive = false;
- pwrpriv->bpower_saving = false;
- }
-
- up(&pwrpriv->lock);
-
- return result;
-}
-
-
-static bool rtw_pwr_unassociated_idle(struct rtw_adapter *adapter)
-{
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct xmit_priv *pxmit_priv = &adapter->xmitpriv;
-
- bool ret = false;
-
- if (time_after_eq(adapter->pwrctrlpriv.ips_deny_time, jiffies))
- goto exit;
-
- if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) ||
- check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) ||
- check_fwstate(pmlmepriv, WIFI_AP_STATE) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)){
- goto exit;
- }
-
- if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF ||
- pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) {
- DBG_8723A_LEVEL(_drv_always_,
- "There are some pkts to transmit\n");
- DBG_8723A_LEVEL(_drv_info_, "free_xmitbuf_cnt: %d, "
- "free_xmit_extbuf_cnt: %d\n",
- pxmit_priv->free_xmitbuf_cnt,
- pxmit_priv->free_xmit_extbuf_cnt);
- goto exit;
- }
-
- ret = true;
-
-exit:
- return ret;
-}
-
-void rtw_ps_processor23a(struct rtw_adapter *padapter)
-{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- pwrpriv->ps_processing = true;
-
- if (pwrpriv->bips_processing == true)
- goto exit;
-
- if (pwrpriv->ips_mode_req == IPS_NONE)
- goto exit;
-
- if (!rtw_pwr_unassociated_idle(padapter))
- goto exit;
-
- if (pwrpriv->rf_pwrstate == rf_on &&
- (pwrpriv->pwr_state_check_cnts % 4) == 0) {
- DBG_8723A("==>%s .fw_state(%x)\n", __func__,
- get_fwstate(pmlmepriv));
- pwrpriv->change_rfpwrstate = rf_off;
- ips_enter23a(padapter);
- }
-exit:
- rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv);
- pwrpriv->ps_processing = false;
-}
-
-static void pwr_state_check_handler(unsigned long data)
-{
- struct rtw_adapter *padapter = (struct rtw_adapter *)data;
-
- rtw_ps_cmd23a(padapter);
-}
-
-/*
- *
- * Parameters
- * padapter
- * pslv power state level, only could be PS_STATE_S0 ~ PS_STATE_S4
- *
- */
-void rtw_set_rpwm23a(struct rtw_adapter *padapter, u8 pslv)
-{
- u8 rpwm;
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-
- pslv = PS_STATE(pslv);
-
- if (pwrpriv->btcoex_rfon) {
- if (pslv < PS_STATE_S4)
- pslv = PS_STATE_S3;
- }
-
- if (pwrpriv->rpwm == pslv) {
- RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
- "%s: Already set rpwm[0x%02X], new = 0x%02X!\n",
- __func__, pwrpriv->rpwm, pslv);
- return;
- }
-
- if (padapter->bSurpriseRemoved == true ||
- padapter->hw_init_completed == false) {
- RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
- "%s: SurpriseRemoved(%d) hw_init_completed(%d)\n",
- __func__, padapter->bSurpriseRemoved,
- padapter->hw_init_completed);
-
- pwrpriv->cpwm = PS_STATE_S4;
-
- return;
- }
-
- if (padapter->bDriverStopped == true) {
- RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
- "%s: change power state(0x%02X) when DriverStopped\n",
- __func__, pslv);
-
- if (pslv < PS_STATE_S2) {
- RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
- "%s: Reject to enter PS_STATE(0x%02X) lower than S2 when DriverStopped!!\n",
- __func__, pslv);
- return;
- }
- }
-
- rpwm = pslv | pwrpriv->tog;
- RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
- "rtw_set_rpwm23a: rpwm = 0x%02x cpwm = 0x%02x\n",
- rpwm, pwrpriv->cpwm);
-
- pwrpriv->rpwm = pslv;
-
- rtl8723a_set_rpwm(padapter, rpwm);
-
- pwrpriv->tog += 0x80;
- pwrpriv->cpwm = pslv;
-}
-
-static bool PS_RDY_CHECK(struct rtw_adapter *padapter)
-{
- unsigned long delta_time;
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- delta_time = jiffies - pwrpriv->DelayLPSLastTimeStamp;
-
- if (delta_time < LPS_DELAY_TIME)
- return false;
-
- if (!check_fwstate(pmlmepriv, _FW_LINKED) ||
- check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) ||
- check_fwstate(pmlmepriv, WIFI_AP_STATE) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_STATE))
- return false;
- if (pwrpriv->bInSuspend)
- return false;
- if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X &&
- !padapter->securitypriv.binstallGrpkey) {
- DBG_8723A("Group handshake still in progress !!!\n");
- return false;
- }
- if (!rtw_cfg80211_pwr_mgmt(padapter))
- return false;
-
- return true;
-}
-
-void rtw_set_ps_mode23a(struct rtw_adapter *padapter, u8 ps_mode,
- u8 smart_ps, u8 bcn_ant_mode)
-{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-
- RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
- "%s: PowerMode =%d Smart_PS =%d\n",
- __func__, ps_mode, smart_ps);
-
- if (ps_mode > PM_Card_Disable) {
- RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
- "ps_mode:%d error\n", ps_mode);
- return;
- }
-
- if (pwrpriv->pwr_mode == ps_mode) {
- if (PS_MODE_ACTIVE == ps_mode)
- return;
-
- if (pwrpriv->smart_ps == smart_ps &&
- pwrpriv->bcn_ant_mode == bcn_ant_mode)
- return;
- }
-
- if (ps_mode == PS_MODE_ACTIVE) {
- DBG_8723A("rtw_set_ps_mode23a: Leave 802.11 power save\n");
-
- pwrpriv->pwr_mode = ps_mode;
- rtw_set_rpwm23a(padapter, PS_STATE_S4);
- rtl8723a_set_FwPwrMode_cmd(padapter, ps_mode);
- pwrpriv->bFwCurrentInPSMode = false;
- } else {
- if (PS_RDY_CHECK(padapter) ||
- rtl8723a_BT_using_antenna_1(padapter)) {
- DBG_8723A("%s: Enter 802.11 power save\n", __func__);
-
- pwrpriv->bFwCurrentInPSMode = true;
- pwrpriv->pwr_mode = ps_mode;
- pwrpriv->smart_ps = smart_ps;
- pwrpriv->bcn_ant_mode = bcn_ant_mode;
- rtl8723a_set_FwPwrMode_cmd(padapter, ps_mode);
-
- rtw_set_rpwm23a(padapter, PS_STATE_S2);
- }
- }
-}
-
-/*
- * Return:
- * 0: Leave OK
- * -1: Timeout
- * -2: Other error
- */
-s32 LPS_RF_ON_check23a(struct rtw_adapter *padapter, u32 delay_ms)
-{
- unsigned long start_time, end_time;
- u8 bAwake = false;
- s32 err = 0;
-
- start_time = jiffies;
- end_time = start_time + msecs_to_jiffies(delay_ms);
-
- while (1) {
- bAwake = rtl8723a_get_fwlps_rf_on(padapter);
- if (bAwake == true)
- break;
-
- if (padapter->bSurpriseRemoved == true) {
- err = -2;
- DBG_8723A("%s: device surprise removed!!\n", __func__);
- break;
- }
-
- if (time_after(jiffies, end_time)) {
- err = -1;
- DBG_8723A("%s: Wait for FW LPS leave more than %u "
- "ms!\n", __func__, delay_ms);
- break;
- }
- udelay(100);
- }
-
- return err;
-}
-
-/* Description: */
-/* Enter the leisure power save mode. */
-void LPS_Enter23a(struct rtw_adapter *padapter)
-{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-
- if (!PS_RDY_CHECK(padapter))
- return;
-
- if (pwrpriv->bLeisurePs) {
- /* Idle for a while if we connect to AP a while ago. */
- if (pwrpriv->LpsIdleCount >= 2) { /* 4 Sec */
- if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) {
- pwrpriv->bpower_saving = true;
- DBG_8723A("%s smart_ps:%d\n", __func__,
- pwrpriv->smart_ps);
- /* For Tenda W311R IOT issue */
- rtw_set_ps_mode23a(padapter,
- pwrpriv->power_mgnt,
- pwrpriv->smart_ps, 0);
- }
- } else
- pwrpriv->LpsIdleCount++;
- }
-}
-
-/* Description: */
-/* Leave the leisure power save mode. */
-void LPS_Leave23a(struct rtw_adapter *padapter)
-{
-#define LPS_LEAVE_TIMEOUT_MS 100
-
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-
- if (pwrpriv->bLeisurePs) {
- if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
- rtw_set_ps_mode23a(padapter, PS_MODE_ACTIVE, 0, 0);
-
- if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
- LPS_RF_ON_check23a(padapter,
- LPS_LEAVE_TIMEOUT_MS);
- }
- }
-
- pwrpriv->bpower_saving = false;
-}
-
-/* Description: Leave all power save mode: LPS, FwLPS, IPS if needed. */
-/* Move code to function by tynli. 2010.03.26. */
-void LeaveAllPowerSaveMode23a(struct rtw_adapter *Adapter)
-{
- struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
- u8 enqueue = 0;
-
- /* DBG_8723A("%s.....\n", __func__); */
- if (check_fwstate(pmlmepriv, _FW_LINKED))
- rtw_lps_ctrl_wk_cmd23a(Adapter, LPS_CTRL_LEAVE, enqueue);
-}
-
-void rtw_init_pwrctrl_priv23a(struct rtw_adapter *padapter)
-{
- struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
-
- sema_init(&pwrctrlpriv->lock, 1);
- pwrctrlpriv->rf_pwrstate = rf_on;
- pwrctrlpriv->ips_enter23a_cnts = 0;
- pwrctrlpriv->ips_leave23a_cnts = 0;
- pwrctrlpriv->bips_processing = false;
-
- pwrctrlpriv->ips_mode = padapter->registrypriv.ips_mode;
- pwrctrlpriv->ips_mode_req = padapter->registrypriv.ips_mode;
-
- pwrctrlpriv->pwr_state_check_interval = RTW_PWR_STATE_CHK_INTERVAL;
- pwrctrlpriv->pwr_state_check_cnts = 0;
- pwrctrlpriv->bInSuspend = false;
- pwrctrlpriv->bkeepfwalive = false;
-
- pwrctrlpriv->LpsIdleCount = 0;
-
- /* PS_MODE_MIN; */
- pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;
- pwrctrlpriv->bLeisurePs =
- (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt)?true:false;
-
- pwrctrlpriv->bFwCurrentInPSMode = false;
-
- pwrctrlpriv->rpwm = 0;
- pwrctrlpriv->cpwm = PS_STATE_S4;
-
- pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE;
- pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps;
- pwrctrlpriv->bcn_ant_mode = 0;
-
- pwrctrlpriv->tog = 0x80;
-
- pwrctrlpriv->btcoex_rfon = false;
-
- setup_timer(&pwrctrlpriv->pwr_state_check_timer,
- pwr_state_check_handler, (unsigned long)padapter);
-}
-
-void rtw_free_pwrctrl_priv(struct rtw_adapter *adapter)
-{
-}
-
-inline void rtw_set_ips_deny23a(struct rtw_adapter *padapter, u32 ms)
-{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-
- pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ms);
-}
-
-/*
-* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend
-* @adapter: pointer to _adapter structure
-* @ips_deffer_ms: the ms will prevent from falling into IPS after wakeup
-* Return _SUCCESS or _FAIL
-*/
-
-int _rtw_pwr_wakeup23a(struct rtw_adapter *padapter, u32 ips_deffer_ms, const char *caller)
-{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- int ret = _SUCCESS;
- unsigned long start = jiffies;
- unsigned long new_deny_time;
-
- new_deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms);
-
- if (time_before(pwrpriv->ips_deny_time, new_deny_time))
- pwrpriv->ips_deny_time = new_deny_time;
-
- if (pwrpriv->ps_processing) {
- DBG_8723A("%s wait ps_processing...\n", __func__);
- while (pwrpriv->ps_processing &&
- jiffies_to_msecs(jiffies - start) <= 3000)
- msleep(10);
- if (pwrpriv->ps_processing)
- DBG_8723A("%s wait ps_processing timeout\n", __func__);
- else
- DBG_8723A("%s wait ps_processing done\n", __func__);
- }
-
- if (rtw_sreset_inprogress(padapter)) {
- DBG_8723A("%s wait sreset_inprogress...\n", __func__);
- while (rtw_sreset_inprogress(padapter) &&
- jiffies_to_msecs(jiffies - start) <= 4000)
- msleep(10);
- if (rtw_sreset_inprogress(padapter))
- DBG_8723A("%s wait sreset_inprogress timeout\n",
- __func__);
- else
- DBG_8723A("%s wait sreset_inprogress done\n", __func__);
- }
-
- if (pwrpriv->bInSuspend) {
- DBG_8723A("%s wait bInSuspend...\n", __func__);
- while (pwrpriv->bInSuspend &&
- (jiffies_to_msecs(jiffies - start) <= 3000)) {
- msleep(10);
- }
- if (pwrpriv->bInSuspend)
- DBG_8723A("%s wait bInSuspend timeout\n", __func__);
- else
- DBG_8723A("%s wait bInSuspend done\n", __func__);
- }
-
- /* System suspend is not allowed to wakeup */
- if (pwrpriv->bInSuspend) {
- ret = _FAIL;
- goto exit;
- }
-
- /* I think this should be check in IPS, LPS, autosuspend functions... */
- if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- ret = _SUCCESS;
- goto exit;
- }
-
- if (rf_off == pwrpriv->rf_pwrstate) {
- DBG_8723A("%s call ips_leave23a....\n", __func__);
- if (ips_leave23a(padapter)== _FAIL) {
- DBG_8723A("======> ips_leave23a fail.............\n");
- ret = _FAIL;
- goto exit;
- }
- }
-
- /* TODO: the following checking need to be merged... */
- if (padapter->bDriverStopped || !padapter->bup ||
- !padapter->hw_init_completed) {
- DBG_8723A("%s: bDriverStopped =%d, bup =%d, hw_init_completed "
- "=%u\n", caller, padapter->bDriverStopped,
- padapter->bup, padapter->hw_init_completed);
- ret = _FAIL;
- goto exit;
- }
-
-exit:
- new_deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms);
- if (time_before(pwrpriv->ips_deny_time, new_deny_time))
- pwrpriv->ips_deny_time = new_deny_time;
- return ret;
-}
-
-int rtw_pm_set_lps23a(struct rtw_adapter *padapter, u8 mode)
-{
- int ret = 0;
- struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
-
- if (mode < PS_MODE_NUM) {
- if (pwrctrlpriv->power_mgnt != mode) {
- if (PS_MODE_ACTIVE == mode)
- LeaveAllPowerSaveMode23a(padapter);
- else
- pwrctrlpriv->LpsIdleCount = 2;
- pwrctrlpriv->power_mgnt = mode;
- pwrctrlpriv->bLeisurePs =
- (PS_MODE_ACTIVE != pwrctrlpriv->power_mgnt) ?
- true:false;
- }
- } else
- ret = -EINVAL;
-
- return ret;
-}
-
-int rtw_pm_set_ips23a(struct rtw_adapter *padapter, u8 mode)
-{
- struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
-
- if (mode != IPS_NORMAL && mode != IPS_LEVEL_2 && mode != IPS_NONE)
- return -EINVAL;
-
- pwrctrlpriv->ips_mode_req = mode;
- if (mode == IPS_NONE) {
- DBG_8723A("%s %s\n", __func__, "IPS_NONE");
- if (padapter->bSurpriseRemoved == 0 &&
- rtw_pwr_wakeup(padapter) == _FAIL)
- return -EFAULT;
- }
-
- return 0;
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_recv.c b/drivers/staging/rtl8723au/core/rtw_recv.c
deleted file mode 100644
index 150dabc2a58d..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_recv.c
+++ /dev/null
@@ -1,2204 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTW_RECV_C_
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <recv_osdep.h>
-#include <mlme_osdep.h>
-#include <linux/ip.h>
-#include <linux/if_ether.h>
-#include <usb_ops.h>
-#include <linux/ieee80211.h>
-#include <wifi.h>
-#include <rtl8723a_recv.h>
-#include <rtl8723a_xmit.h>
-
-void rtw_signal_stat_timer_hdl23a(unsigned long data);
-
-void _rtw_init_sta_recv_priv23a(struct sta_recv_priv *psta_recvpriv)
-{
-
-
-
- spin_lock_init(&psta_recvpriv->lock);
-
- /* for (i = 0; i<MAX_RX_NUMBLKS; i++) */
- /* _rtw_init_queue23a(&psta_recvpriv->blk_strms[i]); */
-
- _rtw_init_queue23a(&psta_recvpriv->defrag_q);
-
-
-}
-
-int _rtw_init_recv_priv23a(struct recv_priv *precvpriv,
- struct rtw_adapter *padapter)
-{
- struct recv_frame *precvframe;
- int i;
- int res = _SUCCESS;
-
- spin_lock_init(&precvpriv->lock);
-
- _rtw_init_queue23a(&precvpriv->free_recv_queue);
- _rtw_init_queue23a(&precvpriv->recv_pending_queue);
- _rtw_init_queue23a(&precvpriv->uc_swdec_pending_queue);
-
- precvpriv->adapter = padapter;
-
- for (i = 0; i < NR_RECVFRAME ; i++) {
- precvframe = kzalloc(sizeof(struct recv_frame), GFP_KERNEL);
- if (!precvframe)
- break;
- INIT_LIST_HEAD(&precvframe->list);
-
- list_add_tail(&precvframe->list,
- &precvpriv->free_recv_queue.queue);
-
- precvframe->adapter = padapter;
- precvframe++;
- }
-
- precvpriv->free_recvframe_cnt = i;
- precvpriv->rx_pending_cnt = 1;
-
- res = rtl8723au_init_recv_priv(padapter);
-
- setup_timer(&precvpriv->signal_stat_timer, rtw_signal_stat_timer_hdl23a,
- (unsigned long)padapter);
-
- precvpriv->signal_stat_sampling_interval = 1000; /* ms */
-
- rtw_set_signal_stat_timer(precvpriv);
-
- return res;
-}
-
-void _rtw_free_recv_priv23a(struct recv_priv *precvpriv)
-{
- struct rtw_adapter *padapter = precvpriv->adapter;
- struct recv_frame *precvframe, *ptmp;
-
- rtw_free_uc_swdec_pending_queue23a(padapter);
-
- list_for_each_entry_safe(precvframe, ptmp,
- &precvpriv->free_recv_queue.queue, list) {
- list_del_init(&precvframe->list);
- kfree(precvframe);
- }
-
- rtl8723au_free_recv_priv(padapter);
-}
-
-struct recv_frame *rtw_alloc_recvframe23a(struct rtw_queue *pfree_recv_queue)
-{
- struct recv_frame *pframe;
- struct rtw_adapter *padapter;
- struct recv_priv *precvpriv;
-
- spin_lock_bh(&pfree_recv_queue->lock);
-
- pframe = list_first_entry_or_null(&pfree_recv_queue->queue,
- struct recv_frame, list);
- if (pframe) {
- list_del_init(&pframe->list);
- padapter = pframe->adapter;
- if (padapter) {
- precvpriv = &padapter->recvpriv;
- if (pfree_recv_queue == &precvpriv->free_recv_queue)
- precvpriv->free_recvframe_cnt--;
- }
- }
-
- spin_unlock_bh(&pfree_recv_queue->lock);
-
- return pframe;
-}
-
-int rtw_free_recvframe23a(struct recv_frame *precvframe)
-{
- struct rtw_adapter *padapter = precvframe->adapter;
- struct recv_priv *precvpriv = &padapter->recvpriv;
- struct rtw_queue *pfree_recv_queue;
-
- if (precvframe->pkt) {
- dev_kfree_skb_any(precvframe->pkt);/* free skb by driver */
- precvframe->pkt = NULL;
- }
-
- pfree_recv_queue = &precvpriv->free_recv_queue;
- spin_lock_bh(&pfree_recv_queue->lock);
-
- list_del_init(&precvframe->list);
-
- list_add_tail(&precvframe->list, get_list_head(pfree_recv_queue));
-
- if (padapter) {
- if (pfree_recv_queue == &precvpriv->free_recv_queue)
- precvpriv->free_recvframe_cnt++;
- }
-
- spin_unlock_bh(&pfree_recv_queue->lock);
-
-
-
- return _SUCCESS;
-}
-
-int rtw_enqueue_recvframe23a(struct recv_frame *precvframe, struct rtw_queue *queue)
-{
- struct rtw_adapter *padapter = precvframe->adapter;
- struct recv_priv *precvpriv = &padapter->recvpriv;
-
- spin_lock_bh(&queue->lock);
-
- list_del_init(&precvframe->list);
-
- list_add_tail(&precvframe->list, get_list_head(queue));
-
- if (padapter) {
- if (queue == &precvpriv->free_recv_queue)
- precvpriv->free_recvframe_cnt++;
- }
-
- spin_unlock_bh(&queue->lock);
-
- return _SUCCESS;
-}
-
-/*
-caller : defrag ; recvframe_chk_defrag23a in recv_thread (passive)
-pframequeue: defrag_queue : will be accessed in recv_thread (passive)
-
-using spinlock to protect
-
-*/
-
-static void rtw_free_recvframe23a_queue(struct rtw_queue *pframequeue)
-{
- struct recv_frame *hdr, *ptmp;
- struct list_head *phead;
-
- spin_lock(&pframequeue->lock);
- phead = get_list_head(pframequeue);
- list_for_each_entry_safe(hdr, ptmp, phead, list)
- rtw_free_recvframe23a(hdr);
- spin_unlock(&pframequeue->lock);
-}
-
-u32 rtw_free_uc_swdec_pending_queue23a(struct rtw_adapter *adapter)
-{
- u32 cnt = 0;
- struct recv_frame *pending_frame;
-
- while ((pending_frame = rtw_alloc_recvframe23a(&adapter->recvpriv.uc_swdec_pending_queue))) {
- rtw_free_recvframe23a(pending_frame);
- DBG_8723A("%s: dequeue uc_swdec_pending_queue\n", __func__);
- cnt++;
- }
-
- return cnt;
-}
-
-struct recv_buf *rtw_dequeue_recvbuf23a (struct rtw_queue *queue)
-{
- unsigned long irqL;
- struct recv_buf *precvbuf;
-
- spin_lock_irqsave(&queue->lock, irqL);
-
- precvbuf = list_first_entry_or_null(&queue->queue,
- struct recv_buf, list);
- if (precvbuf)
- list_del_init(&precvbuf->list);
-
- spin_unlock_irqrestore(&queue->lock, irqL);
-
- return precvbuf;
-}
-
-int recvframe_chkmic(struct rtw_adapter *adapter,
- struct recv_frame *precvframe);
-int recvframe_chkmic(struct rtw_adapter *adapter,
- struct recv_frame *precvframe) {
-
- int i, res = _SUCCESS;
- u32 datalen;
- u8 miccode[8];
- u8 bmic_err = false, brpt_micerror = true;
- u8 *pframe, *payload, *pframemic;
- u8 *mickey;
- struct sta_info *stainfo;
- struct rx_pkt_attrib *prxattrib = &precvframe->attrib;
- struct security_priv *psecuritypriv = &adapter->securitypriv;
-
- struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
-
- stainfo = rtw_get_stainfo23a(&adapter->stapriv, &prxattrib->ta[0]);
-
- if (prxattrib->encrypt == WLAN_CIPHER_SUITE_TKIP) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "recvframe_chkmic:prxattrib->encrypt == WLAN_CIPHER_SUITE_TKIP\n");
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "recvframe_chkmic:da = %pM\n", prxattrib->ra);
-
- /* calculate mic code */
- if (stainfo != NULL) {
- if (is_multicast_ether_addr(prxattrib->ra)) {
- mickey = &psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0];
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "recvframe_chkmic: bcmc key\n");
-
- if (!psecuritypriv->binstallGrpkey) {
- res = _FAIL;
- RT_TRACE(_module_rtl871x_recv_c_,
- _drv_err_,
- "recvframe_chkmic:didn't install group key!\n");
- DBG_8723A("\n recvframe_chkmic:didn't "
- "install group key!!!!!!\n");
- goto exit;
- }
- } else {
- mickey = &stainfo->dot11tkiprxmickey.skey[0];
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "recvframe_chkmic: unicast key\n");
- }
-
- /* icv_len included the mic code */
- datalen = precvframe->pkt->len-prxattrib->
- hdrlen-prxattrib->iv_len-prxattrib->icv_len - 8;
- pframe = precvframe->pkt->data;
- payload = pframe + prxattrib->hdrlen +
- prxattrib->iv_len;
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "prxattrib->iv_len =%d prxattrib->icv_len =%d\n",
- prxattrib->iv_len, prxattrib->icv_len);
-
- /* care the length of the data */
- rtw_seccalctkipmic23a(mickey, pframe, payload,
- datalen, &miccode[0],
- (unsigned char)prxattrib->priority);
-
- pframemic = payload + datalen;
-
- bmic_err = false;
-
- for (i = 0; i < 8; i++) {
- if (miccode[i] != *(pframemic + i)) {
- RT_TRACE(_module_rtl871x_recv_c_,
- _drv_err_,
- "recvframe_chkmic:miccode[%d](%02x) != *(pframemic+%d)(%02x)\n",
- i, miccode[i],
- i, *(pframemic + i));
- bmic_err = true;
- }
- }
-
- if (bmic_err == true) {
- int i;
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "*(pframemic-8)-*(pframemic-1) =%*phC\n",
- 8, pframemic - 8);
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "*(pframemic-16)-*(pframemic-9) =%*phC\n",
- 8, pframemic - 16);
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "====== demp packet (len =%d) ======\n",
- precvframe->pkt->len);
- for (i = 0; i < precvframe->pkt->len; i = i + 8) {
- RT_TRACE(_module_rtl871x_recv_c_,
- _drv_err_, "%*phC\n",
- 8, precvframe->pkt->data + i);
- }
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "====== demp packet end [len =%d]======\n",
- precvframe->pkt->len);
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "hrdlen =%d\n", prxattrib->hdrlen);
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "ra = %pM psecuritypriv->binstallGrpkey =%d\n",
- prxattrib->ra,
- psecuritypriv->binstallGrpkey);
-
- /* double check key_index for some timing
- issue, cannot compare with
- psecuritypriv->dot118021XGrpKeyid also
- cause timing issue */
- if ((is_multicast_ether_addr(prxattrib->ra)) &&
- (prxattrib->key_index !=
- pmlmeinfo->key_index))
- brpt_micerror = false;
-
- if ((prxattrib->bdecrypted == true) &&
- (brpt_micerror == true)) {
- rtw_handle_tkip_mic_err23a(adapter, (u8)is_multicast_ether_addr(prxattrib->ra));
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "mic error :prxattrib->bdecrypted =%d\n",
- prxattrib->bdecrypted);
- DBG_8723A(" mic error :prxattrib->"
- "bdecrypted =%d\n",
- prxattrib->bdecrypted);
- } else {
- RT_TRACE(_module_rtl871x_recv_c_,
- _drv_err_,
- "mic error :prxattrib->bdecrypted =%d\n",
- prxattrib->bdecrypted);
- DBG_8723A(" mic error :prxattrib->"
- "bdecrypted =%d\n",
- prxattrib->bdecrypted);
- }
-
- res = _FAIL;
- } else {
- /* mic checked ok */
- if (!psecuritypriv->bcheck_grpkey &&
- is_multicast_ether_addr(prxattrib->ra)) {
- psecuritypriv->bcheck_grpkey = 1;
- RT_TRACE(_module_rtl871x_recv_c_,
- _drv_err_,
- "psecuritypriv->bcheck_grpkey = true\n");
- }
- }
- } else {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "recvframe_chkmic: rtw_get_stainfo23a ==NULL!!!\n");
- }
-
- skb_trim(precvframe->pkt, precvframe->pkt->len - 8);
- }
-
-exit:
-
-
-
- return res;
-}
-
-/* decrypt and set the ivlen, icvlen of the recv_frame */
-struct recv_frame *decryptor(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame);
-struct recv_frame *decryptor(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
- struct rx_pkt_attrib *prxattrib = &precv_frame->attrib;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct recv_frame *return_packet = precv_frame;
- int res = _SUCCESS;
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "prxstat->decrypted =%x prxattrib->encrypt = 0x%03x\n",
- prxattrib->bdecrypted, prxattrib->encrypt);
-
- if (prxattrib->encrypt > 0) {
- u8 *iv = precv_frame->pkt->data + prxattrib->hdrlen;
-
- prxattrib->key_index = (((iv[3]) >> 6) & 0x3);
-
- if (prxattrib->key_index > WEP_KEYS) {
- DBG_8723A("prxattrib->key_index(%d) > WEP_KEYS\n",
- prxattrib->key_index);
-
- switch (prxattrib->encrypt) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- prxattrib->key_index =
- psecuritypriv->dot11PrivacyKeyIndex;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- case WLAN_CIPHER_SUITE_CCMP:
- default:
- prxattrib->key_index =
- psecuritypriv->dot118021XGrpKeyid;
- break;
- }
- }
- }
-
- if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0))) {
- psecuritypriv->hw_decrypted = 0;
- switch (prxattrib->encrypt) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- rtw_wep_decrypt23a(padapter, precv_frame);
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- res = rtw_tkip_decrypt23a(padapter, precv_frame);
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- res = rtw_aes_decrypt23a(padapter, precv_frame);
- break;
- default:
- break;
- }
- } else if (prxattrib->bdecrypted == 1 && prxattrib->encrypt > 0 &&
- (psecuritypriv->busetkipkey == 1 ||
- prxattrib->encrypt != WLAN_CIPHER_SUITE_TKIP)) {
- psecuritypriv->hw_decrypted = 1;
- }
-
- if (res == _FAIL) {
- rtw_free_recvframe23a(return_packet);
- return_packet = NULL;
- }
-
-
-
- return return_packet;
-}
-
-/* set the security information in the recv_frame */
-static struct recv_frame *portctrl(struct rtw_adapter *adapter,
- struct recv_frame *precv_frame)
-{
- u8 *psta_addr, *ptr;
- uint auth_alg;
- struct recv_frame *pfhdr;
- struct sta_info *psta;
- struct sta_priv *pstapriv ;
- struct recv_frame *prtnframe;
- u16 ether_type;
- u16 eapol_type = ETH_P_PAE;/* for Funia BD's WPA issue */
- struct rx_pkt_attrib *pattrib;
-
- pstapriv = &adapter->stapriv;
-
- auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
-
- pfhdr = precv_frame;
- pattrib = &pfhdr->attrib;
- psta_addr = pattrib->ta;
- psta = rtw_get_stainfo23a(pstapriv, psta_addr);
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "########portctrl:adapter->securitypriv.dot11AuthAlgrthm =%d\n",
- adapter->securitypriv.dot11AuthAlgrthm);
-
- prtnframe = precv_frame;
-
- if (auth_alg == dot11AuthAlgrthm_8021X) {
- /* get ether_type */
- ptr = pfhdr->pkt->data + pfhdr->attrib.hdrlen;
-
- ether_type = (ptr[6] << 8) | ptr[7];
-
- if (psta && psta->ieee8021x_blocked) {
- /* blocked */
- /* only accept EAPOL frame */
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "########portctrl:psta->ieee8021x_blocked ==1\n");
-
- if (ether_type != eapol_type) {
- /* free this frame */
- rtw_free_recvframe23a(precv_frame);
- prtnframe = NULL;
- }
- }
- }
-
- return prtnframe;
-}
-
-int recv_decache(struct recv_frame *precv_frame, u8 bretry,
- struct stainfo_rxcache *prxcache);
-int recv_decache(struct recv_frame *precv_frame, u8 bretry,
- struct stainfo_rxcache *prxcache)
-{
- int tid = precv_frame->attrib.priority;
-
- u16 seq_ctrl = ((precv_frame->attrib.seq_num & 0xffff) << 4) |
- (precv_frame->attrib.frag_num & 0xf);
-
-
-
- if (tid > 15) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
- "recv_decache, (tid>15)! seq_ctrl = 0x%x, tid = 0x%x\n",
- seq_ctrl, tid);
-
- return _FAIL;
- }
-
- if (1) { /* if (bretry) */
- if (seq_ctrl == prxcache->tid_rxseq[tid]) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
- "recv_decache, seq_ctrl = 0x%x, tid = 0x%x, tid_rxseq = 0x%x\n",
- seq_ctrl, tid, prxcache->tid_rxseq[tid]);
-
- return _FAIL;
- }
- }
-
- prxcache->tid_rxseq[tid] = seq_ctrl;
-
-
-
- return _SUCCESS;
-}
-
-void process23a_pwrbit_data(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame);
-void process23a_pwrbit_data(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
-#ifdef CONFIG_8723AU_AP_MODE
- unsigned char pwrbit;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sta_info *psta;
-
- psta = rtw_get_stainfo23a(pstapriv, pattrib->src);
-
- if (psta) {
- pwrbit = ieee80211_has_pm(hdr->frame_control);
-
- if (pwrbit) {
- if (!(psta->state & WIFI_SLEEP_STATE))
- stop_sta_xmit23a(padapter, psta);
- } else {
- if (psta->state & WIFI_SLEEP_STATE)
- wakeup_sta_to_xmit23a(padapter, psta);
- }
- }
-
-#endif
-}
-
-void process_wmmps_data(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame);
-void process_wmmps_data(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
-#ifdef CONFIG_8723AU_AP_MODE
- struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sta_info *psta;
-
- psta = rtw_get_stainfo23a(pstapriv, pattrib->src);
-
- if (!psta)
- return;
-
-
- if (!psta->qos_option)
- return;
-
- if (!(psta->qos_info & 0xf))
- return;
-
- if (psta->state & WIFI_SLEEP_STATE) {
- u8 wmmps_ac = 0;
-
- switch (pattrib->priority) {
- case 1:
- case 2:
- wmmps_ac = psta->uapsd_bk & BIT(1);
- break;
- case 4:
- case 5:
- wmmps_ac = psta->uapsd_vi & BIT(1);
- break;
- case 6:
- case 7:
- wmmps_ac = psta->uapsd_vo & BIT(1);
- break;
- case 0:
- case 3:
- default:
- wmmps_ac = psta->uapsd_be & BIT(1);
- break;
- }
-
- if (wmmps_ac) {
- if (psta->sleepq_ac_len > 0) {
- /* process received triggered frame */
- xmit_delivery_enabled_frames23a(padapter, psta);
- } else {
- /* issue one qos null frame with More data bit = 0 and the EOSP bit set (= 1) */
- issue_qos_nulldata23a(padapter, psta->hwaddr,
- (u16)pattrib->priority,
- 0, 0);
- }
- }
- }
-
-#endif
-}
-
-static void count_rx_stats(struct rtw_adapter *padapter,
- struct recv_frame *prframe, struct sta_info *sta)
-{
- int sz;
- struct sta_info *psta = NULL;
- struct stainfo_stats *pstats = NULL;
- struct rx_pkt_attrib *pattrib = & prframe->attrib;
- struct recv_priv *precvpriv = &padapter->recvpriv;
-
- sz = prframe->pkt->len;
- precvpriv->rx_bytes += sz;
-
- padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++;
-
- if ((!is_broadcast_ether_addr(pattrib->dst)) &&
- (!is_multicast_ether_addr(pattrib->dst)))
- padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++;
-
- if (sta)
- psta = sta;
- else
- psta = prframe->psta;
-
- if (psta) {
- pstats = &psta->sta_stats;
-
- pstats->rx_data_pkts++;
- pstats->rx_bytes += sz;
- }
-}
-
-static int sta2sta_data_frame(struct rtw_adapter *adapter,
- struct recv_frame *precv_frame,
- struct sta_info**psta)
-{
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- int ret = _SUCCESS;
- struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
- struct sta_priv *pstapriv = &adapter->stapriv;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- u8 *mybssid = get_bssid(pmlmepriv);
- u8 *myhwaddr = myid(&adapter->eeprompriv);
- u8 *sta_addr = NULL;
- int bmcast = is_multicast_ether_addr(pattrib->dst);
-
-
-
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
-
- /* filter packets that SA is myself or multicast or broadcast */
- if (ether_addr_equal(myhwaddr, pattrib->src)) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "SA == myself\n");
- ret = _FAIL;
- goto exit;
- }
-
- if (!ether_addr_equal(myhwaddr, pattrib->dst) && !bmcast) {
- ret = _FAIL;
- goto exit;
- }
-
- if (ether_addr_equal(pattrib->bssid, "\x0\x0\x0\x0\x0\x0") ||
- ether_addr_equal(mybssid, "\x0\x0\x0\x0\x0\x0") ||
- !ether_addr_equal(pattrib->bssid, mybssid)) {
- ret = _FAIL;
- goto exit;
- }
-
- sta_addr = pattrib->src;
- } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
- /* For Station mode, sa and bssid should always be BSSID,
- and DA is my mac-address */
- if (!ether_addr_equal(pattrib->bssid, pattrib->src)) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "bssid != TA under STATION_MODE; drop pkt\n");
- ret = _FAIL;
- goto exit;
- }
-
- sta_addr = pattrib->bssid;
-
- } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
- if (bmcast) {
- /* For AP mode, if DA == MCAST, then BSSID should be also MCAST */
- if (!is_multicast_ether_addr(pattrib->bssid)) {
- ret = _FAIL;
- goto exit;
- }
- } else { /* not mc-frame */
- /* For AP mode, if DA is non-MCAST, then it must
- be BSSID, and bssid == BSSID */
- if (!ether_addr_equal(pattrib->bssid, pattrib->dst)) {
- ret = _FAIL;
- goto exit;
- }
-
- sta_addr = pattrib->src;
- }
- } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
- ether_addr_copy(pattrib->dst, hdr->addr1);
- ether_addr_copy(pattrib->src, hdr->addr2);
- ether_addr_copy(pattrib->bssid, hdr->addr3);
- ether_addr_copy(pattrib->ra, pattrib->dst);
- ether_addr_copy(pattrib->ta, pattrib->src);
-
- sta_addr = mybssid;
- } else {
- ret = _FAIL;
- }
-
- if (bmcast)
- *psta = rtw_get_bcmc_stainfo23a(adapter);
- else
- *psta = rtw_get_stainfo23a(pstapriv, sta_addr); /* get ap_info */
-
- if (*psta == NULL) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "can't get psta under sta2sta_data_frame ; drop pkt\n");
- ret = _FAIL;
- goto exit;
- }
-
-exit:
-
- return ret;
-}
-
-int ap2sta_data_frame(struct rtw_adapter *adapter,
- struct recv_frame *precv_frame,
- struct sta_info **psta);
-int ap2sta_data_frame(struct rtw_adapter *adapter,
- struct recv_frame *precv_frame,
- struct sta_info **psta)
-{
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
- int ret = _SUCCESS;
- struct sta_priv *pstapriv = &adapter->stapriv;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- u8 *mybssid = get_bssid(pmlmepriv);
- u8 *myhwaddr = myid(&adapter->eeprompriv);
- int bmcast = is_multicast_ether_addr(pattrib->dst);
-
-
-
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
- (check_fwstate(pmlmepriv, _FW_LINKED) ||
- check_fwstate(pmlmepriv, _FW_UNDER_LINKING))) {
-
- /* filter packets that SA is myself or multicast or broadcast */
- if (ether_addr_equal(myhwaddr, pattrib->src)) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "SA == myself\n");
- ret = _FAIL;
- goto exit;
- }
-
- /* da should be for me */
- if (!ether_addr_equal(myhwaddr, pattrib->dst) && !bmcast) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "ap2sta_data_frame: compare DA failed; DA=%pM\n",
- pattrib->dst);
- ret = _FAIL;
- goto exit;
- }
-
- /* check BSSID */
- if (ether_addr_equal(pattrib->bssid, "\x0\x0\x0\x0\x0\x0") ||
- ether_addr_equal(mybssid, "\x0\x0\x0\x0\x0\x0") ||
- !ether_addr_equal(pattrib->bssid, mybssid)) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "ap2sta_data_frame: compare BSSID failed; BSSID=%pM\n",
- pattrib->bssid);
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "mybssid=%pM\n", mybssid);
-
- if (!bmcast) {
- DBG_8723A("issue_deauth23a to the nonassociated ap=%pM for the reason(7)\n",
- pattrib->bssid);
- issue_deauth23a(adapter, pattrib->bssid,
- WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
- }
-
- ret = _FAIL;
- goto exit;
- }
-
- if (bmcast)
- *psta = rtw_get_bcmc_stainfo23a(adapter);
- else
- /* get ap_info */
- *psta = rtw_get_stainfo23a(pstapriv, pattrib->bssid);
-
- if (*psta == NULL) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "ap2sta: can't get psta under STATION_MODE; drop pkt\n");
- ret = _FAIL;
- goto exit;
- }
-
- if (ieee80211_is_nullfunc(hdr->frame_control)) {
- /* No data, will not indicate to upper layer,
- temporily count it here */
- count_rx_stats(adapter, precv_frame, *psta);
- ret = RTW_RX_HANDLED;
- goto exit;
- }
-
- } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) &&
- check_fwstate(pmlmepriv, _FW_LINKED)) {
- ether_addr_copy(pattrib->dst, hdr->addr1);
- ether_addr_copy(pattrib->src, hdr->addr2);
- ether_addr_copy(pattrib->bssid, hdr->addr3);
- ether_addr_copy(pattrib->ra, pattrib->dst);
- ether_addr_copy(pattrib->ta, pattrib->src);
-
- /* */
- ether_addr_copy(pattrib->bssid, mybssid);
-
- /* get sta_info */
- *psta = rtw_get_stainfo23a(pstapriv, pattrib->bssid);
- if (*psta == NULL) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "can't get psta under MP_MODE ; drop pkt\n");
- ret = _FAIL;
- goto exit;
- }
- } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
- /* Special case */
- ret = RTW_RX_HANDLED;
- goto exit;
- } else {
- if (ether_addr_equal(myhwaddr, pattrib->dst) && !bmcast) {
- *psta = rtw_get_stainfo23a(pstapriv, pattrib->bssid);
- if (*psta == NULL) {
- DBG_8723A("issue_deauth23a to the ap=%pM for the reason(7)\n",
- pattrib->bssid);
-
- issue_deauth23a(adapter, pattrib->bssid,
- WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
- }
- }
-
- ret = _FAIL;
- }
-
-exit:
-
-
-
- return ret;
-}
-
-int sta2ap_data_frame(struct rtw_adapter *adapter,
- struct recv_frame *precv_frame,
- struct sta_info **psta);
-int sta2ap_data_frame(struct rtw_adapter *adapter,
- struct recv_frame *precv_frame,
- struct sta_info **psta)
-{
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
- struct sta_priv *pstapriv = &adapter->stapriv;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- unsigned char *mybssid = get_bssid(pmlmepriv);
- int ret = _SUCCESS;
-
-
-
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
- /* For AP mode, RA = BSSID, TX = STA(SRC_ADDR), A3 = DST_ADDR */
- if (!ether_addr_equal(pattrib->bssid, mybssid)) {
- ret = _FAIL;
- goto exit;
- }
-
- *psta = rtw_get_stainfo23a(pstapriv, pattrib->src);
- if (*psta == NULL) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "can't get psta under AP_MODE; drop pkt\n");
- DBG_8723A("issue_deauth23a to sta=%pM for the reason(7)\n",
- pattrib->src);
-
- issue_deauth23a(adapter, pattrib->src,
- WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
-
- ret = RTW_RX_HANDLED;
- goto exit;
- }
-
- process23a_pwrbit_data(adapter, precv_frame);
-
- /* We only get here if it's a data frame, so no need to
- * confirm data frame type first */
- if (ieee80211_is_data_qos(hdr->frame_control))
- process_wmmps_data(adapter, precv_frame);
-
- if (ieee80211_is_nullfunc(hdr->frame_control)) {
- /* No data, will not indicate to upper layer,
- temporily count it here */
- count_rx_stats(adapter, precv_frame, *psta);
- ret = RTW_RX_HANDLED;
- goto exit;
- }
- } else {
- u8 *myhwaddr = myid(&adapter->eeprompriv);
-
- if (!ether_addr_equal(pattrib->ra, myhwaddr)) {
- ret = RTW_RX_HANDLED;
- goto exit;
- }
- DBG_8723A("issue_deauth23a to sta=%pM for the reason(7)\n",
- pattrib->src);
- issue_deauth23a(adapter, pattrib->src,
- WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
- ret = RTW_RX_HANDLED;
- goto exit;
- }
-
-exit:
-
-
-
- return ret;
-}
-
-static int validate_recv_ctrl_frame(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
-#ifdef CONFIG_8723AU_AP_MODE
- struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-
- if (!ieee80211_is_ctl(hdr->frame_control))
- return _FAIL;
-
- /* receive the frames that ra(a1) is my address */
- if (!ether_addr_equal(hdr->addr1, myid(&padapter->eeprompriv)))
- return _FAIL;
-
- /* only handle ps-poll */
- if (ieee80211_is_pspoll(hdr->frame_control)) {
- struct ieee80211_pspoll *psp = (struct ieee80211_pspoll *)hdr;
- u16 aid;
- u8 wmmps_ac = 0;
- struct sta_info *psta = NULL;
-
- aid = le16_to_cpu(psp->aid) & 0x3fff;
- psta = rtw_get_stainfo23a(pstapriv, hdr->addr2);
-
- if (!psta || psta->aid != aid)
- return _FAIL;
-
- /* for rx pkt statistics */
- psta->sta_stats.rx_ctrl_pkts++;
-
- switch (pattrib->priority) {
- case 1:
- case 2:
- wmmps_ac = psta->uapsd_bk & BIT(0);
- break;
- case 4:
- case 5:
- wmmps_ac = psta->uapsd_vi & BIT(0);
- break;
- case 6:
- case 7:
- wmmps_ac = psta->uapsd_vo & BIT(0);
- break;
- case 0:
- case 3:
- default:
- wmmps_ac = psta->uapsd_be & BIT(0);
- break;
- }
-
- if (wmmps_ac)
- return _FAIL;
-
- if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
- DBG_8723A("%s alive check-rx ps-poll\n", __func__);
- psta->expire_to = pstapriv->expire_to;
- psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
- }
-
- if ((psta->state & WIFI_SLEEP_STATE) &&
- (pstapriv->sta_dz_bitmap & CHKBIT(psta->aid))) {
- struct list_head *xmitframe_phead;
- struct xmit_frame *pxmitframe;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- spin_lock_bh(&pxmitpriv->lock);
-
- xmitframe_phead = get_list_head(&psta->sleep_q);
- pxmitframe = list_first_entry_or_null(xmitframe_phead,
- struct xmit_frame,
- list);
- if (pxmitframe) {
- list_del_init(&pxmitframe->list);
-
- psta->sleepq_len--;
-
- if (psta->sleepq_len>0)
- pxmitframe->attrib.mdata = 1;
- else
- pxmitframe->attrib.mdata = 0;
-
- pxmitframe->attrib.triggered = 1;
-
- rtl8723au_hal_xmitframe_enqueue(padapter,
- pxmitframe);
-
- if (psta->sleepq_len == 0) {
- pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
- update_beacon23a(padapter, WLAN_EID_TIM,
- NULL, false);
- }
-
- spin_unlock_bh(&pxmitpriv->lock);
-
- } else {
- spin_unlock_bh(&pxmitpriv->lock);
-
- if (pstapriv->tim_bitmap & CHKBIT(psta->aid)) {
- if (psta->sleepq_len == 0) {
- DBG_8723A("no buffered packets "
- "to xmit\n");
-
- /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */
- issue_nulldata23a(padapter,
- psta->hwaddr,
- 0, 0, 0);
- } else {
- DBG_8723A("error!psta->sleepq"
- "_len =%d\n",
- psta->sleepq_len);
- psta->sleepq_len = 0;
- }
-
- pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
-
- update_beacon23a(padapter, WLAN_EID_TIM,
- NULL, false);
- }
- }
- }
- }
-
-#endif
- return _FAIL;
-}
-
-struct recv_frame *recvframe_chk_defrag23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame);
-static int validate_recv_mgnt_frame(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
- struct sta_info *psta;
- struct sk_buff *skb;
- struct ieee80211_hdr *hdr;
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "+validate_recv_mgnt_frame\n");
-
- precv_frame = recvframe_chk_defrag23a(padapter, precv_frame);
- if (precv_frame == NULL) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
- "%s: fragment packet\n", __func__);
- return _SUCCESS;
- }
-
- skb = precv_frame->pkt;
- hdr = (struct ieee80211_hdr *) skb->data;
-
- /* for rx pkt statistics */
- psta = rtw_get_stainfo23a(&padapter->stapriv, hdr->addr2);
- if (psta) {
- psta->sta_stats.rx_mgnt_pkts++;
-
- if (ieee80211_is_beacon(hdr->frame_control))
- psta->sta_stats.rx_beacon_pkts++;
- else if (ieee80211_is_probe_req(hdr->frame_control))
- psta->sta_stats.rx_probereq_pkts++;
- else if (ieee80211_is_probe_resp(hdr->frame_control)) {
- if (ether_addr_equal(padapter->eeprompriv.mac_addr,
- hdr->addr1))
- psta->sta_stats.rx_probersp_pkts++;
- else if (is_broadcast_ether_addr(hdr->addr1) ||
- is_multicast_ether_addr(hdr->addr1))
- psta->sta_stats.rx_probersp_bm_pkts++;
- else
- psta->sta_stats.rx_probersp_uo_pkts++;
- }
- }
-
- mgt_dispatcher23a(padapter, precv_frame);
-
- return _SUCCESS;
-}
-
-static int validate_recv_data_frame(struct rtw_adapter *adapter,
- struct recv_frame *precv_frame)
-{
- u8 bretry;
- u8 *psa, *pda;
- struct sta_info *psta = NULL;
- struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
- struct security_priv *psecuritypriv = &adapter->securitypriv;
- int ret = _SUCCESS;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-
-
-
- bretry = ieee80211_has_retry(hdr->frame_control);
- pda = ieee80211_get_DA(hdr);
- psa = ieee80211_get_SA(hdr);
-
- ether_addr_copy(pattrib->dst, pda);
- ether_addr_copy(pattrib->src, psa);
-
- switch (hdr->frame_control &
- cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
- case cpu_to_le16(0):
- ether_addr_copy(pattrib->bssid, hdr->addr3);
- ether_addr_copy(pattrib->ra, pda);
- ether_addr_copy(pattrib->ta, psa);
- ret = sta2sta_data_frame(adapter, precv_frame, &psta);
- break;
-
- case cpu_to_le16(IEEE80211_FCTL_FROMDS):
- ether_addr_copy(pattrib->bssid, hdr->addr2);
- ether_addr_copy(pattrib->ra, pda);
- ether_addr_copy(pattrib->ta, hdr->addr2);
- ret = ap2sta_data_frame(adapter, precv_frame, &psta);
- break;
-
- case cpu_to_le16(IEEE80211_FCTL_TODS):
- ether_addr_copy(pattrib->bssid, hdr->addr1);
- ether_addr_copy(pattrib->ra, hdr->addr1);
- ether_addr_copy(pattrib->ta, psa);
- ret = sta2ap_data_frame(adapter, precv_frame, &psta);
- break;
-
- case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
- /*
- * There is no BSSID in this case, but the driver has been
- * using addr1 so far, so keep it for now.
- */
- ether_addr_copy(pattrib->bssid, hdr->addr1);
- ether_addr_copy(pattrib->ra, hdr->addr1);
- ether_addr_copy(pattrib->ta, hdr->addr2);
- ret = _FAIL;
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, "case 3\n");
- break;
- }
-
- if ((ret == _FAIL) || (ret == RTW_RX_HANDLED))
- goto exit;
-
- if (!psta) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "after to_fr_ds_chk; psta == NULL\n");
- ret = _FAIL;
- goto exit;
- }
-
- precv_frame->psta = psta;
-
- pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
- if (ieee80211_has_a4(hdr->frame_control))
- pattrib->hdrlen += ETH_ALEN;
-
- /* parsing QC field */
- if (pattrib->qos == 1) {
- __le16 *qptr = (__le16 *)ieee80211_get_qos_ctl(hdr);
- u16 qos_ctrl = le16_to_cpu(*qptr);
-
- pattrib->priority = qos_ctrl & IEEE80211_QOS_CTL_TID_MASK;
- pattrib->ack_policy = (qos_ctrl >> 5) & 3;
- pattrib->amsdu =
- (qos_ctrl & IEEE80211_QOS_CTL_A_MSDU_PRESENT) >> 7;
- pattrib->hdrlen += IEEE80211_QOS_CTL_LEN;
-
- if (pattrib->priority != 0 && pattrib->priority != 3) {
- adapter->recvpriv.bIsAnyNonBEPkts = true;
- }
- } else {
- pattrib->priority = 0;
- pattrib->ack_policy = 0;
- pattrib->amsdu = 0;
- }
-
- if (pattrib->order) { /* HT-CTRL 11n */
- pattrib->hdrlen += 4;
- }
-
- precv_frame->preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority];
-
- /* decache, drop duplicate recv packets */
- if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) ==
- _FAIL) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "decache : drop pkt\n");
- ret = _FAIL;
- goto exit;
- }
-
- if (pattrib->privacy) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "validate_recv_data_frame:pattrib->privacy =%x\n",
- pattrib->privacy);
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "^^^^^^^^^^^is_multicast_ether_addr(pattrib->ra(0x%02x)) =%d^^^^^^^^^^^^^^^6\n",
- pattrib->ra[0],
- is_multicast_ether_addr(pattrib->ra));
-
- GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt,
- is_multicast_ether_addr(pattrib->ra));
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "pattrib->encrypt =%d\n", pattrib->encrypt);
-
- switch (pattrib->encrypt) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- pattrib->iv_len = IEEE80211_WEP_IV_LEN;
- pattrib->icv_len = IEEE80211_WEP_ICV_LEN;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- pattrib->iv_len = IEEE80211_TKIP_IV_LEN;
- pattrib->icv_len = IEEE80211_TKIP_ICV_LEN;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- pattrib->iv_len = IEEE80211_CCMP_HDR_LEN;
- pattrib->icv_len = IEEE80211_CCMP_MIC_LEN;
- break;
- default:
- pattrib->iv_len = 0;
- pattrib->icv_len = 0;
- break;
- }
- } else {
- pattrib->encrypt = 0;
- pattrib->iv_len = 0;
- pattrib->icv_len = 0;
- }
-
-exit:
-
-
-
- return ret;
-}
-
-static void dump_rx_pkt(struct sk_buff *skb, u16 type, int level)
-{
- int i;
- u8 *ptr;
-
- if ((level == 1) ||
- ((level == 2) && (type == IEEE80211_FTYPE_MGMT)) ||
- ((level == 3) && (type == IEEE80211_FTYPE_DATA))) {
-
- ptr = skb->data;
-
- DBG_8723A("#############################\n");
-
- for (i = 0; i < 64; i = i + 8)
- DBG_8723A("%*phC:\n", 8, ptr + i);
- DBG_8723A("#############################\n");
- }
-}
-
-static int validate_recv_frame(struct rtw_adapter *adapter,
- struct recv_frame *precv_frame)
-{
- /* shall check frame subtype, to / from ds, da, bssid */
-
- /* then call check if rx seq/frag. duplicated. */
- u8 type;
- u8 subtype;
- int retval = _SUCCESS;
- struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
- struct sk_buff *skb = precv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u8 ver;
- u8 bDumpRxPkt;
- u16 seq_ctrl, fctl;
-
- fctl = le16_to_cpu(hdr->frame_control);
- ver = fctl & IEEE80211_FCTL_VERS;
- type = fctl & IEEE80211_FCTL_FTYPE;
- subtype = fctl & IEEE80211_FCTL_STYPE;
-
- /* add version chk */
- if (ver != 0) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "validate_recv_data_frame fail! (ver!= 0)\n");
- retval = _FAIL;
- goto exit;
- }
-
- seq_ctrl = le16_to_cpu(hdr->seq_ctrl);
- pattrib->frag_num = seq_ctrl & IEEE80211_SCTL_FRAG;
- pattrib->seq_num = seq_ctrl >> 4;
-
- pattrib->pw_save = ieee80211_has_pm(hdr->frame_control);
- pattrib->mfrag = ieee80211_has_morefrags(hdr->frame_control);
- pattrib->mdata = ieee80211_has_moredata(hdr->frame_control);
- pattrib->privacy = ieee80211_has_protected(hdr->frame_control);
- pattrib->order = ieee80211_has_order(hdr->frame_control);
-
- GetHalDefVar8192CUsb(adapter, HAL_DEF_DBG_DUMP_RXPKT, &bDumpRxPkt);
-
- if (unlikely(bDumpRxPkt == 1))
- dump_rx_pkt(skb, type, bDumpRxPkt);
-
- switch (type) {
- case IEEE80211_FTYPE_MGMT:
- retval = validate_recv_mgnt_frame(adapter, precv_frame);
- if (retval == _FAIL) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "validate_recv_mgnt_frame fail\n");
- }
- retval = _FAIL; /* only data frame return _SUCCESS */
- break;
- case IEEE80211_FTYPE_CTL:
- retval = validate_recv_ctrl_frame(adapter, precv_frame);
- if (retval == _FAIL) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "validate_recv_ctrl_frame fail\n");
- }
- retval = _FAIL; /* only data frame return _SUCCESS */
- break;
- case IEEE80211_FTYPE_DATA:
- pattrib->qos = (subtype & IEEE80211_STYPE_QOS_DATA) ? 1 : 0;
- retval = validate_recv_data_frame(adapter, precv_frame);
- if (retval == _FAIL) {
- struct recv_priv *precvpriv = &adapter->recvpriv;
-
- precvpriv->rx_drop++;
- }
- break;
- default:
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "validate_recv_data_frame fail! type = 0x%x\n", type);
- retval = _FAIL;
- break;
- }
-
-exit:
- return retval;
-}
-
-/* remove the wlanhdr and add the eth_hdr */
-
-static int wlanhdr_to_ethhdr (struct recv_frame *precvframe)
-{
- u16 eth_type, len, hdrlen;
- u8 bsnaphdr;
- u8 *psnap;
- struct rtw_adapter *adapter = precvframe->adapter;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
-
- struct sk_buff *skb = precvframe->pkt;
- u8 *ptr;
- struct rx_pkt_attrib *pattrib = &precvframe->attrib;
-
-
-
- ptr = skb->data;
- hdrlen = pattrib->hdrlen;
- psnap = ptr + hdrlen;
- eth_type = (psnap[6] << 8) | psnap[7];
- /* convert hdr + possible LLC headers into Ethernet header */
- if ((ether_addr_equal(psnap, rfc1042_header) &&
- eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
- ether_addr_equal(psnap, bridge_tunnel_header)) {
- /* remove RFC1042 or Bridge-Tunnel encapsulation
- and replace EtherType */
- bsnaphdr = true;
- hdrlen += SNAP_SIZE;
- } else {
- /* Leave Ethernet header part of hdr and full payload */
- bsnaphdr = false;
- eth_type = (psnap[0] << 8) | psnap[1];
- }
-
- len = skb->len - hdrlen;
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "=== pattrib->hdrlen: %x, pattrib->iv_len:%x ===\n",
- pattrib->hdrlen, pattrib->iv_len);
-
- pattrib->eth_type = eth_type;
- if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
- ptr += hdrlen;
- *ptr = 0x87;
- *(ptr + 1) = 0x12;
-
- eth_type = 0x8712;
- /* append rx status for mp test packets */
-
- ptr = skb_pull(skb, (hdrlen - sizeof(struct ethhdr) + 2) - 24);
- memcpy(ptr, skb->head, 24);
- ptr += 24;
- } else {
- ptr = skb_pull(skb, (hdrlen - sizeof(struct ethhdr) +
- (bsnaphdr ? 2:0)));
- }
-
- ether_addr_copy(ptr, pattrib->dst);
- ether_addr_copy(ptr + ETH_ALEN, pattrib->src);
-
- if (!bsnaphdr) {
- put_unaligned_be16(len, ptr + 12);
- }
-
-
- return _SUCCESS;
-}
-
-/* perform defrag */
-struct recv_frame *recvframe_defrag(struct rtw_adapter *adapter,
- struct rtw_queue *defrag_q);
-struct recv_frame *recvframe_defrag(struct rtw_adapter *adapter,
- struct rtw_queue *defrag_q)
-{
- struct list_head *phead;
- u8 wlanhdr_offset;
- u8 curfragnum;
- struct recv_frame *pnfhdr, *ptmp;
- struct recv_frame *prframe, *pnextrframe;
- struct rtw_queue *pfree_recv_queue;
- struct sk_buff *skb;
-
- curfragnum = 0;
- pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
-
- phead = get_list_head(defrag_q);
- prframe = list_first_entry(phead, struct recv_frame, list);
- list_del_init(&prframe->list);
- skb = prframe->pkt;
-
- if (curfragnum != prframe->attrib.frag_num) {
- /* the first fragment number must be 0 */
- /* free the whole queue */
- rtw_free_recvframe23a(prframe);
- rtw_free_recvframe23a_queue(defrag_q);
-
- return NULL;
- }
-
- curfragnum++;
-
- list_for_each_entry_safe(pnfhdr, ptmp, phead, list) {
- pnextrframe = (struct recv_frame *)pnfhdr;
- /* check the fragment sequence (2nd ~n fragment frame) */
-
- if (curfragnum != pnfhdr->attrib.frag_num) {
- /* the fragment number must be increasing
- (after decache) */
- /* release the defrag_q & prframe */
- rtw_free_recvframe23a(prframe);
- rtw_free_recvframe23a_queue(defrag_q);
- return NULL;
- }
-
- curfragnum++;
-
- /* copy the 2nd~n fragment frame's payload to the
- first fragment */
- /* get the 2nd~last fragment frame's payload */
-
- wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
-
- skb_pull(pnfhdr->pkt, wlanhdr_offset);
-
- /* append to first fragment frame's tail
- (if privacy frame, pull the ICV) */
-
- skb_trim(skb, skb->len - prframe->attrib.icv_len);
-
- memcpy(skb_tail_pointer(skb), pnfhdr->pkt->data,
- pnfhdr->pkt->len);
-
- skb_put(skb, pnfhdr->pkt->len);
-
- prframe->attrib.icv_len = pnfhdr->attrib.icv_len;
- }
-
- /* free the defrag_q queue and return the prframe */
- rtw_free_recvframe23a_queue(defrag_q);
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "Performance defrag!!!!!\n");
-
- return prframe;
-}
-
-/* check if need to defrag, if needed queue the frame to defrag_q */
-struct recv_frame *recvframe_chk_defrag23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
- u8 ismfrag;
- u8 fragnum;
- u8 *psta_addr;
- struct recv_frame *pfhdr;
- struct sta_info *psta;
- struct sta_priv *pstapriv;
- struct list_head *phead;
- struct recv_frame *prtnframe = NULL;
- struct rtw_queue *pfree_recv_queue, *pdefrag_q;
-
-
-
- pstapriv = &padapter->stapriv;
-
- pfhdr = precv_frame;
-
- pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
-
- /* need to define struct of wlan header frame ctrl */
- ismfrag = pfhdr->attrib.mfrag;
- fragnum = pfhdr->attrib.frag_num;
-
- psta_addr = pfhdr->attrib.ta;
- psta = rtw_get_stainfo23a(pstapriv, psta_addr);
- if (!psta) {
- struct ieee80211_hdr *hdr =
- (struct ieee80211_hdr *) pfhdr->pkt->data;
- if (!ieee80211_is_data(hdr->frame_control)) {
- psta = rtw_get_bcmc_stainfo23a(padapter);
- pdefrag_q = &psta->sta_recvpriv.defrag_q;
- } else
- pdefrag_q = NULL;
- } else
- pdefrag_q = &psta->sta_recvpriv.defrag_q;
-
- if ((ismfrag == 0) && (fragnum == 0)) {
- prtnframe = precv_frame;/* isn't a fragment frame */
- }
-
- if (ismfrag == 1) {
- /* 0~(n-1) fragment frame */
- /* enqueue to defraf_g */
- if (pdefrag_q != NULL) {
- if (fragnum == 0) {
- /* the first fragment */
- if (!list_empty(&pdefrag_q->queue)) {
- /* free current defrag_q */
- rtw_free_recvframe23a_queue(pdefrag_q);
- }
- }
-
- /* Then enqueue the 0~(n-1) fragment into the
- defrag_q */
-
- /* spin_lock(&pdefrag_q->lock); */
- phead = get_list_head(pdefrag_q);
- list_add_tail(&pfhdr->list, phead);
- /* spin_unlock(&pdefrag_q->lock); */
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "Enqueuq: ismfrag = %d, fragnum = %d\n",
- ismfrag, fragnum);
-
- prtnframe = NULL;
-
- } else {
- /* can't find this ta's defrag_queue,
- so free this recv_frame */
- rtw_free_recvframe23a(precv_frame);
- prtnframe = NULL;
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n",
- ismfrag, fragnum);
- }
- }
-
- if ((ismfrag == 0) && (fragnum != 0)) {
- /* the last fragment frame */
- /* enqueue the last fragment */
- if (pdefrag_q != NULL) {
- /* spin_lock(&pdefrag_q->lock); */
- phead = get_list_head(pdefrag_q);
- list_add_tail(&pfhdr->list, phead);
- /* spin_unlock(&pdefrag_q->lock); */
-
- /* call recvframe_defrag to defrag */
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "defrag: ismfrag = %d, fragnum = %d\n",
- ismfrag, fragnum);
- precv_frame = recvframe_defrag(padapter, pdefrag_q);
- prtnframe = precv_frame;
- } else {
- /* can't find this ta's defrag_queue,
- so free this recv_frame */
- rtw_free_recvframe23a(precv_frame);
- prtnframe = NULL;
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n",
- ismfrag, fragnum);
- }
-
- }
-
- if ((prtnframe != NULL) && (prtnframe->attrib.privacy)) {
- /* after defrag we must check tkip mic code */
- if (recvframe_chkmic(padapter, prtnframe) == _FAIL) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "recvframe_chkmic(padapter, prtnframe) ==_FAIL\n");
- rtw_free_recvframe23a(prtnframe);
- prtnframe = NULL;
- }
- }
-
-
-
- return prtnframe;
-}
-
-int amsdu_to_msdu(struct rtw_adapter *padapter, struct recv_frame *prframe);
-int amsdu_to_msdu(struct rtw_adapter *padapter, struct recv_frame *prframe)
-{
- struct rx_pkt_attrib *pattrib;
- struct sk_buff *skb, *sub_skb;
- struct sk_buff_head skb_list;
-
- pattrib = &prframe->attrib;
-
- skb = prframe->pkt;
- skb_pull(skb, prframe->attrib.hdrlen);
- __skb_queue_head_init(&skb_list);
-
- ieee80211_amsdu_to_8023s(skb, &skb_list, NULL, 0, 0, false);
-
- while (!skb_queue_empty(&skb_list)) {
- sub_skb = __skb_dequeue(&skb_list);
-
- sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev);
- sub_skb->dev = padapter->pnetdev;
-
- sub_skb->ip_summed = CHECKSUM_NONE;
-
- netif_rx(sub_skb);
- }
-
- prframe->pkt = NULL;
- rtw_free_recvframe23a(prframe);
- return _SUCCESS;
-}
-
-int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num);
-int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num)
-{
- u8 wsize = preorder_ctrl->wsize_b;
- u16 wend = (preorder_ctrl->indicate_seq + wsize -1) & 0xFFF;
-
- /* Rx Reorder initialize condition. */
- if (preorder_ctrl->indicate_seq == 0xFFFF)
- preorder_ctrl->indicate_seq = seq_num;
-
- /* Drop out the packet which SeqNum is smaller than WinStart */
- if (SN_LESS(seq_num, preorder_ctrl->indicate_seq))
- return false;
-
- /* */
- /* Sliding window manipulation. Conditions includes: */
- /* 1. Incoming SeqNum is equal to WinStart =>Window shift 1 */
- /* 2. Incoming SeqNum is larger than the WinEnd => Window shift N */
- /* */
- if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) {
- preorder_ctrl->indicate_seq =
- (preorder_ctrl->indicate_seq + 1) & 0xFFF;
- } else if (SN_LESS(wend, seq_num)) {
- /* boundary situation, when seq_num cross 0xFFF */
- if (seq_num >= (wsize - 1))
- preorder_ctrl->indicate_seq = seq_num + 1 -wsize;
- else
- preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
- }
- return true;
-}
-
-static int enqueue_reorder_recvframe23a(struct recv_reorder_ctrl *preorder_ctrl,
- struct recv_frame *prframe)
-{
- struct rx_pkt_attrib *pattrib = &prframe->attrib;
- struct rtw_queue *ppending_recvframe_queue;
- struct list_head *phead, *plist, *ptmp;
- struct recv_frame *hdr;
- struct rx_pkt_attrib *pnextattrib;
-
- ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
- phead = get_list_head(ppending_recvframe_queue);
-
- list_for_each_safe(plist, ptmp, phead) {
- hdr = container_of(plist, struct recv_frame, list);
- pnextattrib = &hdr->attrib;
-
- if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num)) {
- continue;
- } else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) {
- /* Duplicate entry is found!! Do not insert current entry. */
- return false;
- } else {
- break;
- }
-
- }
-
- list_del_init(&prframe->list);
-
- list_add_tail(&prframe->list, plist);
-
- return true;
-}
-
-int recv_indicatepkts_in_order(struct rtw_adapter *padapter,
- struct recv_reorder_ctrl *preorder_ctrl,
- int bforced);
-int recv_indicatepkts_in_order(struct rtw_adapter *padapter,
- struct recv_reorder_ctrl *preorder_ctrl,
- int bforced)
-{
- struct list_head *phead, *plist;
- struct recv_frame *prframe;
- struct rx_pkt_attrib *pattrib;
- int bPktInBuf = false;
- struct recv_priv *precvpriv;
- struct rtw_queue *ppending_recvframe_queue;
-
- precvpriv = &padapter->recvpriv;
- ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
- phead = get_list_head(ppending_recvframe_queue);
- plist = phead->next;
-
- /* Handling some condition for forced indicate case. */
- if (bforced) {
- if (list_empty(phead)) {
- return true;
- }
-
- prframe = container_of(plist, struct recv_frame, list);
- pattrib = &prframe->attrib;
- preorder_ctrl->indicate_seq = pattrib->seq_num;
- }
-
- /* Prepare indication list and indication. */
- /* Check if there is any packet need indicate. */
- while (!list_empty(phead)) {
-
- prframe = container_of(plist, struct recv_frame, list);
- pattrib = &prframe->attrib;
-
- if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
- "recv_indicatepkts_in_order: indicate =%d seq =%d amsdu =%d\n",
- preorder_ctrl->indicate_seq,
- pattrib->seq_num, pattrib->amsdu);
-
- plist = plist->next;
- list_del_init(&prframe->list);
-
- if (SN_EQUAL(preorder_ctrl->indicate_seq,
- pattrib->seq_num)) {
- preorder_ctrl->indicate_seq =
- (preorder_ctrl->indicate_seq + 1)&0xFFF;
- }
-
- if (!pattrib->amsdu) {
- if ((padapter->bDriverStopped == false) &&
- (padapter->bSurpriseRemoved == false)) {
- rtw_recv_indicatepkt23a(padapter, prframe);
- }
- } else {
- if (amsdu_to_msdu(padapter, prframe) !=
- _SUCCESS)
- rtw_free_recvframe23a(prframe);
- }
-
- /* Update local variables. */
- bPktInBuf = false;
-
- } else {
- bPktInBuf = true;
- break;
- }
-
- }
-
- return bPktInBuf;
-}
-
-int recv_indicatepkt_reorder(struct rtw_adapter *padapter,
- struct recv_frame *prframe);
-int recv_indicatepkt_reorder(struct rtw_adapter *padapter,
- struct recv_frame *prframe)
-{
- int retval = _SUCCESS;
- struct rx_pkt_attrib *pattrib;
- struct recv_reorder_ctrl *preorder_ctrl;
- struct rtw_queue *ppending_recvframe_queue;
-
- pattrib = &prframe->attrib;
- preorder_ctrl = prframe->preorder_ctrl;
- ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
-
- if (!pattrib->amsdu) {
- /* s1. */
- wlanhdr_to_ethhdr(prframe);
-
- if ((pattrib->qos!= 1) || (pattrib->eth_type == ETH_P_ARP) ||
- (pattrib->ack_policy != 0)) {
- if ((padapter->bDriverStopped == false) &&
- (padapter->bSurpriseRemoved == false)) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
- "@@@@ recv_indicatepkt_reorder -recv_func recv_indicatepkt\n");
-
- rtw_recv_indicatepkt23a(padapter, prframe);
- return _SUCCESS;
- }
-
- return _FAIL;
- }
-
- if (preorder_ctrl->enable == false) {
- /* indicate this recv_frame */
- preorder_ctrl->indicate_seq = pattrib->seq_num;
- rtw_recv_indicatepkt23a(padapter, prframe);
-
- preorder_ctrl->indicate_seq =
- (preorder_ctrl->indicate_seq + 1) % 4096;
- return _SUCCESS;
- }
- } else {
- /* temp filter -> means didn't support A-MSDUs in a A-MPDU */
- if (preorder_ctrl->enable == false) {
- preorder_ctrl->indicate_seq = pattrib->seq_num;
- retval = amsdu_to_msdu(padapter, prframe);
-
- preorder_ctrl->indicate_seq =
- (preorder_ctrl->indicate_seq + 1) % 4096;
- return retval;
- }
- }
-
- spin_lock_bh(&ppending_recvframe_queue->lock);
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
- "recv_indicatepkt_reorder: indicate =%d seq =%d\n",
- preorder_ctrl->indicate_seq, pattrib->seq_num);
-
- /* s2. check if winstart_b(indicate_seq) needs to been updated */
- if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) {
- goto _err_exit;
- }
-
- /* s3. Insert all packet into Reorder Queue to maintain its ordering. */
- if (!enqueue_reorder_recvframe23a(preorder_ctrl, prframe)) {
- goto _err_exit;
- }
-
- /* s4. */
- /* Indication process. */
- /* After Packet dropping and Sliding Window shifting as above,
- we can now just indicate the packets */
- /* with the SeqNum smaller than latest WinStart and buffer
- other packets. */
- /* */
- /* For Rx Reorder condition: */
- /* 1. All packets with SeqNum smaller than WinStart => Indicate */
- /* 2. All packets with SeqNum larger than or equal to WinStart =>
- Buffer it. */
- /* */
-
- if (recv_indicatepkts_in_order(padapter, preorder_ctrl, false) == true) {
- mod_timer(&preorder_ctrl->reordering_ctrl_timer,
- jiffies + msecs_to_jiffies(REORDER_WAIT_TIME));
- spin_unlock_bh(&ppending_recvframe_queue->lock);
- } else {
- spin_unlock_bh(&ppending_recvframe_queue->lock);
- del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
- }
- return _SUCCESS;
-
-_err_exit:
-
- spin_unlock_bh(&ppending_recvframe_queue->lock);
- return _FAIL;
-}
-
-void rtw_reordering_ctrl_timeout_handler23a(unsigned long pcontext)
-{
- struct recv_reorder_ctrl *preorder_ctrl;
- struct rtw_adapter *padapter;
- struct rtw_queue *ppending_recvframe_queue;
-
- preorder_ctrl = (struct recv_reorder_ctrl *)pcontext;
- padapter = preorder_ctrl->padapter;
- ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
-
- if (padapter->bDriverStopped || padapter->bSurpriseRemoved) {
- return;
- }
-
- spin_lock_bh(&ppending_recvframe_queue->lock);
-
- if (recv_indicatepkts_in_order(padapter, preorder_ctrl, true) == true) {
- mod_timer(&preorder_ctrl->reordering_ctrl_timer,
- jiffies + msecs_to_jiffies(REORDER_WAIT_TIME));
- }
-
- spin_unlock_bh(&ppending_recvframe_queue->lock);
-}
-
-int process_recv_indicatepkts(struct rtw_adapter *padapter,
- struct recv_frame *prframe);
-int process_recv_indicatepkts(struct rtw_adapter *padapter,
- struct recv_frame *prframe)
-{
- int retval = _SUCCESS;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct ht_priv *phtpriv = &pmlmepriv->htpriv;
-
- if (phtpriv->ht_option == true) { /* B/G/N Mode */
- /* including perform A-MPDU Rx Ordering Buffer Control */
- if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) {
- if ((padapter->bDriverStopped == false) &&
- (padapter->bSurpriseRemoved == false)) {
- retval = _FAIL;
- return retval;
- }
- }
- } else { /* B/G mode */
- retval = wlanhdr_to_ethhdr(prframe);
- if (retval != _SUCCESS) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "wlanhdr_to_ethhdr: drop pkt\n");
- return retval;
- }
-
- if ((padapter->bDriverStopped == false) &&
- (padapter->bSurpriseRemoved == false)) {
- /* indicate this recv_frame */
- RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
- "@@@@ process_recv_indicatepkts- recv_func recv_indicatepkt\n");
- rtw_recv_indicatepkt23a(padapter, prframe);
- } else {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
- "@@@@ process_recv_indicatepkts- recv_func free_indicatepkt\n");
-
- RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
- "recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
- padapter->bDriverStopped,
- padapter->bSurpriseRemoved);
- retval = _FAIL;
- return retval;
- }
-
- }
-
- return retval;
-}
-
-static int recv_func_prehandle(struct rtw_adapter *padapter,
- struct recv_frame *rframe)
-{
- int ret;
-
- /* check the frame crtl field and decache */
- ret = validate_recv_frame(padapter, rframe);
- if (ret != _SUCCESS) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "recv_func: validate_recv_frame fail! drop pkt\n");
- rtw_free_recvframe23a(rframe);
- goto exit;
- }
-
-exit:
- return ret;
-}
-
-static int recv_func_posthandle(struct rtw_adapter *padapter,
- struct recv_frame *prframe)
-{
- int ret = _SUCCESS;
- struct recv_frame *orig_prframe = prframe;
- struct recv_priv *precvpriv = &padapter->recvpriv;
-
- /* DATA FRAME */
- prframe = decryptor(padapter, prframe);
- if (prframe == NULL) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "decryptor: drop pkt\n");
- ret = _FAIL;
- goto _recv_data_drop;
- }
-
- prframe = recvframe_chk_defrag23a(padapter, prframe);
- if (!prframe) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "recvframe_chk_defrag23a: drop pkt\n");
- goto _recv_data_drop;
- }
-
- /*
- * Pull off crypto headers
- */
- if (prframe->attrib.iv_len > 0) {
- skb_pull(prframe->pkt, prframe->attrib.iv_len);
- }
-
- if (prframe->attrib.icv_len > 0) {
- skb_trim(prframe->pkt,
- prframe->pkt->len - prframe->attrib.icv_len);
- }
-
- prframe = portctrl(padapter, prframe);
- if (!prframe) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "portctrl: drop pkt\n");
- ret = _FAIL;
- goto _recv_data_drop;
- }
-
- count_rx_stats(padapter, prframe, NULL);
-
- ret = process_recv_indicatepkts(padapter, prframe);
- if (ret != _SUCCESS) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "recv_func: process_recv_indicatepkts fail!\n");
- rtw_free_recvframe23a(orig_prframe);/* free this recv_frame */
- goto _recv_data_drop;
- }
- return ret;
-
-_recv_data_drop:
- precvpriv->rx_drop++;
- return ret;
-}
-
-int rtw_recv_entry23a(struct recv_frame *rframe)
-{
- int ret, r;
- struct rtw_adapter *padapter = rframe->adapter;
- struct rx_pkt_attrib *prxattrib = &rframe->attrib;
- struct recv_priv *recvpriv = &padapter->recvpriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_priv *mlmepriv = &padapter->mlmepriv;
-
- /* check if need to handle uc_swdec_pending_queue*/
- if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
- psecuritypriv->busetkipkey) {
- struct recv_frame *pending_frame;
-
- while ((pending_frame = rtw_alloc_recvframe23a(&padapter->recvpriv.uc_swdec_pending_queue))) {
- r = recv_func_posthandle(padapter, pending_frame);
- if (r == _SUCCESS)
- DBG_8723A("%s: dequeue uc_swdec_pending_queue\n", __func__);
- }
- }
-
- ret = recv_func_prehandle(padapter, rframe);
-
- if (ret == _SUCCESS) {
- /* check if need to enqueue into uc_swdec_pending_queue*/
- if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
- !is_multicast_ether_addr(prxattrib->ra) &&
- prxattrib->encrypt > 0 &&
- (prxattrib->bdecrypted == 0) &&
- !is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm) &&
- !psecuritypriv->busetkipkey) {
- rtw_enqueue_recvframe23a(rframe, &padapter->recvpriv.uc_swdec_pending_queue);
- DBG_8723A("%s: no key, enqueue uc_swdec_pending_queue\n", __func__);
- goto exit;
- }
-
- ret = recv_func_posthandle(padapter, rframe);
-
- recvpriv->rx_pkts++;
- }
-
-exit:
- return ret;
-}
-
-void rtw_signal_stat_timer_hdl23a(unsigned long data)
-{
- struct rtw_adapter *adapter = (struct rtw_adapter *)data;
- struct recv_priv *recvpriv = &adapter->recvpriv;
-
- u32 tmp_s, tmp_q;
- u8 avg_signal_strength = 0;
- u8 avg_signal_qual = 0;
- u32 num_signal_strength = 0;
- u32 num_signal_qual = 0;
- u8 _alpha = 3; /* this value is based on converging_constant = 5000 */
- /* and sampling_interval = 1000 */
-
- if (recvpriv->signal_strength_data.update_req == 0) {
- /* update_req is clear, means we got rx */
- avg_signal_strength = recvpriv->signal_strength_data.avg_val;
- num_signal_strength = recvpriv->signal_strength_data.total_num;
- /* after avg_vals are acquired, we can re-stat */
- /* the signal values */
- recvpriv->signal_strength_data.update_req = 1;
- }
-
- if (recvpriv->signal_qual_data.update_req == 0) {
- /* update_req is clear, means we got rx */
- avg_signal_qual = recvpriv->signal_qual_data.avg_val;
- num_signal_qual = recvpriv->signal_qual_data.total_num;
- /* after avg_vals are acquired, we can re-stat */
- /*the signal values */
- recvpriv->signal_qual_data.update_req = 1;
- }
-
- /* update value of signal_strength, rssi, signal_qual */
- if (!check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY)) {
- tmp_s = avg_signal_strength + (_alpha - 1) *
- recvpriv->signal_strength;
- if (tmp_s %_alpha)
- tmp_s = tmp_s / _alpha + 1;
- else
- tmp_s = tmp_s / _alpha;
- if (tmp_s > 100)
- tmp_s = 100;
-
- tmp_q = avg_signal_qual + (_alpha - 1) * recvpriv->signal_qual;
- if (tmp_q %_alpha)
- tmp_q = tmp_q / _alpha + 1;
- else
- tmp_q = tmp_q / _alpha;
- if (tmp_q > 100)
- tmp_q = 100;
-
- recvpriv->signal_strength = tmp_s;
- recvpriv->signal_qual = tmp_q;
-
- DBG_8723A("%s signal_strength:%3u, signal_qual:%3u, "
- "num_signal_strength:%u, num_signal_qual:%u\n",
- __func__, recvpriv->signal_strength,
- recvpriv->signal_qual, num_signal_strength,
- num_signal_qual);
- }
-
- rtw_set_signal_stat_timer(recvpriv);
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_security.c b/drivers/staging/rtl8723au/core/rtw_security.c
deleted file mode 100644
index 5a4cfdf1ebd4..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_security.c
+++ /dev/null
@@ -1,1630 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTW_SECURITY_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <wifi.h>
-#include <osdep_intf.h>
-
-/* WEP related ===== */
-
-#define CRC32_POLY 0x04c11db7
-
-struct arc4context {
- u32 x;
- u32 y;
- u8 state[256];
-};
-
-static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len)
-{
- u32 t, u;
- u32 keyindex;
- u32 stateindex;
- u8 *state;
- u32 counter;
-
- state = parc4ctx->state;
- parc4ctx->x = 0;
- parc4ctx->y = 0;
- for (counter = 0; counter < 256; counter++)
- state[counter] = (u8)counter;
- keyindex = 0;
- stateindex = 0;
- for (counter = 0; counter < 256; counter++) {
- t = state[counter];
- stateindex = (stateindex + key[keyindex] + t) & 0xff;
- u = state[stateindex];
- state[stateindex] = (u8)t;
- state[counter] = (u8)u;
- if (++keyindex >= key_len)
- keyindex = 0;
- }
-
-}
-
-static u32 arcfour_byte(struct arc4context *parc4ctx)
-{
- u32 x;
- u32 y;
- u32 sx, sy;
- u8 *state;
-
- state = parc4ctx->state;
- x = (parc4ctx->x + 1) & 0xff;
- sx = state[x];
- y = (sx + parc4ctx->y) & 0xff;
- sy = state[y];
- parc4ctx->x = x;
- parc4ctx->y = y;
- state[y] = (u8)sx;
- state[x] = (u8)sy;
-
- return state[(sx + sy) & 0xff];
-}
-
-static void arcfour_encrypt(struct arc4context *parc4ctx, u8 *dest,
- u8 *src, u32 len)
-{
- u32 i;
-
- for (i = 0; i < len; i++)
- dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);
-}
-
-static int bcrc32initialized;
-static u32 crc32_table[256];
-
-static u8 crc32_reverseBit(u8 data)
-{
- u8 retval = ((data << 7) & 0x80) | ((data << 5) & 0x40) |
- ((data << 3) & 0x20) | ((data << 1) & 0x10) |
- ((data >> 1) & 0x08) | ((data >> 3) & 0x04) |
- ((data >> 5) & 0x02) | ((data >> 7) & 0x01);
- return retval;
-}
-
-static void crc32_init(void)
-{
- int i, j;
- u32 c;
- u8 *p, *p1;
- u8 k;
-
- if (bcrc32initialized == 1)
- return;
-
- p = (u8 *) &c;
- c = 0x12340000;
-
- for (i = 0; i < 256; ++i) {
- k = crc32_reverseBit((u8)i);
-
- for (c = ((u32)k) << 24, j = 8; j > 0; --j)
- c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1);
-
- p1 = (u8 *)&crc32_table[i];
-
- p1[0] = crc32_reverseBit(p[3]);
- p1[1] = crc32_reverseBit(p[2]);
- p1[2] = crc32_reverseBit(p[1]);
- p1[3] = crc32_reverseBit(p[0]);
- }
-
- bcrc32initialized = 1;
-}
-
-static u32 getcrc32(u8 *buf, int len)
-{
- u8 *p;
- u32 crc;
-
- if (bcrc32initialized == 0)
- crc32_init();
-
- crc = 0xffffffff; /* preload shift register, per CRC-32 spec */
-
- for (p = buf; len > 0; ++p, --len)
- crc = crc32_table[(crc ^ *p) & 0xff] ^ (crc >> 8);
-
- return ~crc; /* transmit complement, per CRC-32 spec */
-}
-
-/* Need to consider the fragment situation */
-void rtw_wep_encrypt23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe)
-{
- /* exclude ICV */
- __le32 crc;
- struct arc4context mycontext;
- int curfragnum, length, index;
- u32 keylength;
- u8 *pframe, *payload, *iv; /* wepkey */
- u8 wepkey[16];
- u8 hw_hdr_offset = 0;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- if (!pxmitframe->buf_addr)
- return;
-
- hw_hdr_offset = TXDESC_OFFSET;
-
- pframe = pxmitframe->buf_addr + hw_hdr_offset;
-
- /* start to encrypt each fragment */
- if (pattrib->encrypt != WLAN_CIPHER_SUITE_WEP40 &&
- pattrib->encrypt != WLAN_CIPHER_SUITE_WEP104)
- return;
-
- index = psecuritypriv->dot11PrivacyKeyIndex;
- keylength = psecuritypriv->wep_key[index].keylen;
-
- for (curfragnum = 0; curfragnum < pattrib->nr_frags ; curfragnum++) {
- iv = pframe + pattrib->hdrlen;
- memcpy(&wepkey[0], iv, 3);
- memcpy(&wepkey[3], &psecuritypriv->wep_key[index].key,
- keylength);
- payload = pframe + pattrib->iv_len + pattrib->hdrlen;
-
- if ((curfragnum + 1) == pattrib->nr_frags) {
- /* the last fragment */
- length = pattrib->last_txcmdsz - pattrib->hdrlen -
- pattrib->iv_len - pattrib->icv_len;
-
- crc = cpu_to_le32(getcrc32(payload, length));
-
- arcfour_init(&mycontext, wepkey, 3 + keylength);
- arcfour_encrypt(&mycontext, payload, payload, length);
- arcfour_encrypt(&mycontext, payload + length,
- (char *)&crc, 4);
- } else {
- length = pxmitpriv->frag_len - pattrib->hdrlen -
- pattrib->iv_len - pattrib->icv_len;
- crc = cpu_to_le32(getcrc32(payload, length));
- arcfour_init(&mycontext, wepkey, 3 + keylength);
- arcfour_encrypt(&mycontext, payload, payload, length);
- arcfour_encrypt(&mycontext, payload + length,
- (char *)&crc, 4);
-
- pframe += pxmitpriv->frag_len;
- pframe = PTR_ALIGN(pframe, 4);
- }
- }
-
-}
-
-void rtw_wep_decrypt23a(struct rtw_adapter *padapter,
- struct recv_frame *precvframe)
-{
- /* exclude ICV */
- u32 actual_crc, expected_crc;
- struct arc4context mycontext;
- int length;
- u32 keylength;
- u8 *pframe, *payload, *iv, wepkey[16];
- u8 keyindex;
- struct rx_pkt_attrib *prxattrib = &precvframe->attrib;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct sk_buff *skb = precvframe->pkt;
-
- pframe = skb->data;
-
- /* start to decrypt recvframe */
- if (prxattrib->encrypt != WLAN_CIPHER_SUITE_WEP40 &&
- prxattrib->encrypt != WLAN_CIPHER_SUITE_WEP104)
- return;
-
- iv = pframe + prxattrib->hdrlen;
- /* keyindex = (iv[3]&0x3); */
- keyindex = prxattrib->key_index;
- keylength = psecuritypriv->wep_key[keyindex].keylen;
- memcpy(&wepkey[0], iv, 3);
- /* memcpy(&wepkey[3], &psecuritypriv->dot11DefKey[psecuritypriv->dot11PrivacyKeyIndex].skey[0], keylength); */
- memcpy(&wepkey[3], &psecuritypriv->wep_key[keyindex].key, keylength);
- length = skb->len - prxattrib->hdrlen - prxattrib->iv_len;
-
- payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;
-
- /* decrypt payload include icv */
- arcfour_init(&mycontext, wepkey, 3 + keylength);
- arcfour_encrypt(&mycontext, payload, payload, length);
-
- /* calculate icv and compare the icv */
- actual_crc = getcrc32(payload, length - 4);
- expected_crc = get_unaligned_le32(&payload[length - 4]);
-
- if (actual_crc != expected_crc) {
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
- "%s:icv CRC mismatch: "
- "actual: %08x, expected: %08x\n",
- __func__, actual_crc, expected_crc);
- }
-}
-
-/* 3 ===== TKIP related ===== */
-
-static u32 secmicgetuint32(u8 *p)
-/* Convert from Byte[] to u32 in a portable way */
-{
- s32 i;
- u32 res = 0;
-
- for (i = 0; i < 4; i++)
- res |= ((u32)(*p++)) << (8 * i);
-
- return res;
-}
-
-static void secmicputuint32(u8 *p, u32 val)
-/* Convert from long to Byte[] in a portable way */
-{
- long i;
-
- for (i = 0; i < 4; i++) {
- *p++ = (u8) (val & 0xff);
- val >>= 8;
- }
-
-}
-
-static void secmicclear(struct mic_data *pmicdata)
-{
-/* Reset the state to the empty message. */
-
- pmicdata->L = pmicdata->K0;
- pmicdata->R = pmicdata->K1;
- pmicdata->nBytesInM = 0;
- pmicdata->M = 0;
-
-}
-
-void rtw_secmicsetkey23a(struct mic_data *pmicdata, u8 *key)
-{
- /* Set the key */
-
- pmicdata->K0 = secmicgetuint32(key);
- pmicdata->K1 = secmicgetuint32(key + 4);
- /* and reset the message */
- secmicclear(pmicdata);
-
-}
-
-void rtw_secmicappend23abyte23a(struct mic_data *pmicdata, u8 b)
-{
-
- /* Append the byte to our word-sized buffer */
- pmicdata->M |= ((unsigned long)b) << (8 * pmicdata->nBytesInM);
- pmicdata->nBytesInM++;
- /* Process the word if it is full. */
- if (pmicdata->nBytesInM >= 4) {
- pmicdata->L ^= pmicdata->M;
- pmicdata->R ^= ROL32(pmicdata->L, 17);
- pmicdata->L += pmicdata->R;
- pmicdata->R ^= ((pmicdata->L & 0xff00ff00) >> 8) | ((pmicdata->L & 0x00ff00ff) << 8);
- pmicdata->L += pmicdata->R;
- pmicdata->R ^= ROL32(pmicdata->L, 3);
- pmicdata->L += pmicdata->R;
- pmicdata->R ^= ROR32(pmicdata->L, 2);
- pmicdata->L += pmicdata->R;
- /* Clear the buffer */
- pmicdata->M = 0;
- pmicdata->nBytesInM = 0;
- }
-
-}
-
-void rtw_secmicappend23a(struct mic_data *pmicdata, u8 *src, u32 nbytes)
-{
-
- /* This is simple */
- while (nbytes > 0) {
- rtw_secmicappend23abyte23a(pmicdata, *src++);
- nbytes--;
- }
-
-}
-
-void rtw_secgetmic23a(struct mic_data *pmicdata, u8 *dst)
-{
-
- /* Append the minimum padding */
- rtw_secmicappend23abyte23a(pmicdata, 0x5a);
- rtw_secmicappend23abyte23a(pmicdata, 0);
- rtw_secmicappend23abyte23a(pmicdata, 0);
- rtw_secmicappend23abyte23a(pmicdata, 0);
- rtw_secmicappend23abyte23a(pmicdata, 0);
- /* and then zeroes until the length is a multiple of 4 */
- while (pmicdata->nBytesInM != 0)
- rtw_secmicappend23abyte23a(pmicdata, 0);
- /* The appendByte function has already computed the result. */
- secmicputuint32(dst, pmicdata->L);
- secmicputuint32(dst + 4, pmicdata->R);
- /* Reset to the empty message. */
- secmicclear(pmicdata);
-
-}
-
-void rtw_seccalctkipmic23a(u8 *key, u8 *header, u8 *data, u32 data_len,
- u8 *mic_code, u8 pri)
-{
-
- struct mic_data micdata;
- u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
-
- rtw_secmicsetkey23a(&micdata, key);
- priority[0] = pri;
-
- /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
- if (header[1]&1) { /* ToDS == 1 */
- rtw_secmicappend23a(&micdata, &header[16], 6); /* DA */
- if (header[1]&2) /* From Ds == 1 */
- rtw_secmicappend23a(&micdata, &header[24], 6);
- else
- rtw_secmicappend23a(&micdata, &header[10], 6);
- } else { /* ToDS == 0 */
- rtw_secmicappend23a(&micdata, &header[4], 6); /* DA */
- if (header[1]&2) /* From Ds == 1 */
- rtw_secmicappend23a(&micdata, &header[16], 6);
- else
- rtw_secmicappend23a(&micdata, &header[10], 6);
-
- }
- rtw_secmicappend23a(&micdata, &priority[0], 4);
-
- rtw_secmicappend23a(&micdata, data, data_len);
-
- rtw_secgetmic23a(&micdata, mic_code);
-
-}
-
-/* macros for extraction/creation of unsigned char/unsigned short values */
-#define RotR1(v16) ((((v16) >> 1) & 0x7FFF) ^ (((v16) & 1) << 15))
-#define Lo8(v16) ((u8)((v16) & 0x00FF))
-#define Hi8(v16) ((u8)(((v16) >> 8) & 0x00FF))
-#define Lo16(v32) ((u16)((v32) & 0xFFFF))
-#define Hi16(v32) ((u16)(((v32) >> 16) & 0xFFFF))
-#define Mk16(hi, lo) ((lo) ^ (((u16)(hi)) << 8))
-
-/* select the Nth 16-bit word of the temporal key unsigned char array TK[] */
-#define TK16(N) Mk16(tk[2 * (N) + 1], tk[2 * (N)])
-
-/* S-box lookup: 16 bits --> 16 bits */
-#define _S_(v16) (Sbox1[0][Lo8(v16)] ^ Sbox1[1][Hi8(v16)])
-
-/* fixed algorithm "parameters" */
-#define PHASE1_LOOP_CNT 8 /* this needs to be "big enough" */
-#define TA_SIZE 6 /* 48-bit transmitter address */
-#define TK_SIZE 16 /* 128-bit temporal key */
-#define P1K_SIZE 10 /* 80-bit Phase1 key */
-#define RC4_KEY_SIZE 16 /* 128-bit RC4KEY (104 bits unknown) */
-
-/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
-static const unsigned short Sbox1[2][256] = {
- /* Sbox for hash (can be in ROM) */
- {
- 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
- 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
- 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
- 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
- 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
- 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
- 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
- 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
- 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
- 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
- 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
- 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
- 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
- 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
- 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
- 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
- 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
- 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
- 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
- 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
- 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
- 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
- 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
- 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
- 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
- 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
- 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
- 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
- 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
- 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
- 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
- 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
- },
- { /* second half of table is unsigned char-reversed version of first! */
- 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
- 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
- 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
- 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
- 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
- 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
- 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
- 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
- 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
- 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
- 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
- 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
- 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
- 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
- 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
- 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
- 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
- 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
- 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
- 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
- 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
- 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
- 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
- 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
- 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
- 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
- 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
- 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
- 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
- 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
- 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
- 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
- }
-};
-
- /*
-**********************************************************************
-* Routine: Phase 1 -- generate P1K, given TA, TK, IV32
-*
-* Inputs:
-* tk[] = temporal key [128 bits]
-* ta[] = transmitter's MAC address [ 48 bits]
-* iv32 = upper 32 bits of IV [ 32 bits]
-* Output:
-* p1k[] = Phase 1 key [ 80 bits]
-*
-* Note:
-* This function only needs to be called every 2**16 packets,
-* although in theory it could be called every packet.
-*
-**********************************************************************
-*/
-static void phase1(u16 *p1k, const u8 *tk, const u8 *ta, u32 iv32)
-{
- int i;
-
- /* Initialize the 80 bits of P1K[] from IV32 and TA[0..5] */
- p1k[0] = Lo16(iv32);
- p1k[1] = Hi16(iv32);
- p1k[2] = Mk16(ta[1], ta[0]); /* use TA[] as little-endian */
- p1k[3] = Mk16(ta[3], ta[2]);
- p1k[4] = Mk16(ta[5], ta[4]);
-
- /* Now compute an unbalanced Feistel cipher with 80-bit block */
- /* size on the 80-bit block P1K[], using the 128-bit key TK[] */
- for (i = 0; i < PHASE1_LOOP_CNT; i++) {
- /* Each add operation here is mod 2**16 */
- p1k[0] += _S_(p1k[4] ^ TK16((i & 1) + 0));
- p1k[1] += _S_(p1k[0] ^ TK16((i & 1) + 2));
- p1k[2] += _S_(p1k[1] ^ TK16((i & 1) + 4));
- p1k[3] += _S_(p1k[2] ^ TK16((i & 1) + 6));
- p1k[4] += _S_(p1k[3] ^ TK16((i & 1) + 0));
- p1k[4] += (unsigned short) i; /* avoid "slide attacks" */
- }
-
-}
-
-/*
-**********************************************************************
-* Routine: Phase 2 -- generate RC4KEY, given TK, P1K, IV16
-*
-* Inputs:
-* tk[] = Temporal key [128 bits]
-* p1k[] = Phase 1 output key [ 80 bits]
-* iv16 = low 16 bits of IV counter [ 16 bits]
-* Output:
-* rc4key[] = the key used to encrypt the packet [128 bits]
-*
-* Note:
-* The value {TA, IV32, IV16} for Phase1/Phase2 must be unique
-* across all packets using the same key TK value. Then, for a
-* given value of TK[], this TKIP48 construction guarantees that
-* the final RC4KEY value is unique across all packets.
-*
-* Suggested implementation optimization: if PPK[] is "overlaid"
-* appropriately on RC4KEY[], there is no need for the final
-* for loop below that copies the PPK[] result into RC4KEY[].
-*
-**********************************************************************
-*/
-static void phase2(u8 *rc4key, const u8 *tk, const u16 *p1k, u16 iv16)
-{
- int i;
- u16 PPK[6]; /* temporary key for mixing */
-
- /* Note: all adds in the PPK[] equations below are mod 2**16 */
- for (i = 0; i < 5; i++)
- PPK[i] = p1k[i]; /* first, copy P1K to PPK */
-
- PPK[5] = p1k[4] + iv16; /* next, add in IV16 */
-
- /* Bijective non-linear mixing of the 96 bits of PPK[0..5] */
- PPK[0] += _S_(PPK[5] ^ TK16(0)); /* Mix key in each "round" */
- PPK[1] += _S_(PPK[0] ^ TK16(1));
- PPK[2] += _S_(PPK[1] ^ TK16(2));
- PPK[3] += _S_(PPK[2] ^ TK16(3));
- PPK[4] += _S_(PPK[3] ^ TK16(4));
- PPK[5] += _S_(PPK[4] ^ TK16(5)); /* Total # S-box lookups == 6 */
-
- /* Final sweep: bijective, "linear". Rotates kill LSB correlations */
- PPK[0] += RotR1(PPK[5] ^ TK16(6));
- PPK[1] += RotR1(PPK[0] ^ TK16(7)); /* Use all of TK[] in Phase2 */
- PPK[2] += RotR1(PPK[1]);
- PPK[3] += RotR1(PPK[2]);
- PPK[4] += RotR1(PPK[3]);
- PPK[5] += RotR1(PPK[4]);
- /* Note: At this point, for a given key TK[0..15], the 96-bit output */
- /* value PPK[0..5] is guaranteed to be unique, as a function */
- /* of the 96-bit "input" value {TA, IV32, IV16}. That is, */
- /* P1K is now a keyed permutation of {TA, IV32, IV16}. */
-
- /* Set RC4KEY[0..3], which includes "cleartext" portion of RC4 key */
- rc4key[0] = Hi8(iv16); /* RC4KEY[0..2] is the WEP IV */
- rc4key[1] = (Hi8(iv16) | 0x20) & 0x7F; /* Help avoid weak (FMS) keys */
- rc4key[2] = Lo8(iv16);
- rc4key[3] = Lo8((PPK[5] ^ TK16(0)) >> 1);
-
- /* Copy 96 bits of PPK[0..5] to RC4KEY[4..15] (little-endian) */
- for (i = 0; i < 6; i++) {
- rc4key[4 + 2 * i] = Lo8(PPK[i]);
- rc4key[5 + 2 * i] = Hi8(PPK[i]);
- }
-
-}
-
-/* The hlen isn't include the IV */
-int rtw_tkip_encrypt23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe)
-{
- u16 pnl;
- u32 pnh;
- u8 rc4key[16];
- u8 ttkey[16];
- __le32 crc;
- u8 hw_hdr_offset = 0;
- struct arc4context mycontext;
- int curfragnum, length;
- u8 *pframe, *payload, *iv, *prwskey;
- union pn48 dot11txpn;
- struct sta_info *stainfo;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- int res = _SUCCESS;
-
- if (pattrib->encrypt != WLAN_CIPHER_SUITE_TKIP)
- return _FAIL;
-
- if (!pxmitframe->buf_addr)
- return _FAIL;
-
- hw_hdr_offset = TXDESC_OFFSET;
-
- pframe = pxmitframe->buf_addr + hw_hdr_offset;
-
- if (pattrib->psta)
- stainfo = pattrib->psta;
- else {
- DBG_8723A("%s, call rtw_get_stainfo()\n", __func__);
- stainfo = rtw_get_stainfo23a(&padapter->stapriv,
- &pattrib->ra[0]);
- }
-
- if (!stainfo) {
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
- "%s: stainfo == NULL!!!\n", __func__);
- DBG_8723A("%s, psta == NUL\n", __func__);
- return _FAIL;
- }
-
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
- "%s: stainfo!= NULL!!!\n", __func__);
-
- if (!(stainfo->state & _FW_LINKED)) {
- DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, stainfo->state);
- return _FAIL;
- }
-
- if (is_multicast_ether_addr(pattrib->ra))
- prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
- else
- prwskey = &stainfo->dot118021x_UncstKey.skey[0];
-
- /* 4 start to encrypt each fragment */
- for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
- iv = pframe + pattrib->hdrlen;
- payload = pframe + pattrib->iv_len + pattrib->hdrlen;
-
- GET_TKIP_PN(iv, dot11txpn);
-
- pnl = (u16)(dot11txpn.val);
- pnh = (u32)(dot11txpn.val>>16);
-
- phase1((u16 *)&ttkey[0], prwskey, &pattrib->ta[0], pnh);
-
- phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl);
-
- if ((curfragnum + 1) == pattrib->nr_frags) { /* 4 the last fragment */
- length = (pattrib->last_txcmdsz -
- pattrib->hdrlen -
- pattrib->iv_len -
- pattrib->icv_len);
-
- RT_TRACE(_module_rtl871x_security_c_, _drv_info_,
- "pattrib->iv_len =%x, pattrib->icv_len =%x\n",
- pattrib->iv_len,
- pattrib->icv_len);
- crc = cpu_to_le32(getcrc32(payload, length));
-
- arcfour_init(&mycontext, rc4key, 16);
- arcfour_encrypt(&mycontext, payload, payload, length);
- arcfour_encrypt(&mycontext, payload + length,
- (char *)&crc, 4);
-
- } else {
- length = (pxmitpriv->frag_len -
- pattrib->hdrlen -
- pattrib->iv_len -
- pattrib->icv_len);
-
- crc = cpu_to_le32(getcrc32(payload, length));
- arcfour_init(&mycontext, rc4key, 16);
- arcfour_encrypt(&mycontext, payload, payload, length);
- arcfour_encrypt(&mycontext, payload + length,
- (char *)&crc, 4);
-
- pframe += pxmitpriv->frag_len;
- pframe = PTR_ALIGN(pframe, 4);
- }
- }
-
- return res;
-}
-
-/* The hlen isn't include the IV */
-int rtw_tkip_decrypt23a(struct rtw_adapter *padapter,
- struct recv_frame *precvframe)
-{
- u16 pnl;
- u32 pnh;
- u8 rc4key[16];
- u8 ttkey[16];
- u32 actual_crc, expected_crc;
- struct arc4context mycontext;
- int length;
- u8 *pframe, *payload, *iv, *prwskey;
- union pn48 dot11txpn;
- struct sta_info *stainfo;
- struct rx_pkt_attrib *prxattrib = &precvframe->attrib;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct sk_buff *skb = precvframe->pkt;
- int res = _SUCCESS;
-
- if (prxattrib->encrypt != WLAN_CIPHER_SUITE_TKIP)
- return _FAIL;
-
- pframe = skb->data;
-
- stainfo = rtw_get_stainfo23a(&padapter->stapriv,
- &prxattrib->ta[0]);
- if (!stainfo) {
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
- "%s: stainfo == NULL!!!\n", __func__);
- return _FAIL;
- }
-
- /* 4 start to decrypt recvframe */
- if (is_multicast_ether_addr(prxattrib->ra)) {
- if (psecuritypriv->binstallGrpkey == 0) {
- res = _FAIL;
- DBG_8723A("%s:rx bc/mc packets, but didn't install group key!!!!!!!!!!\n", __func__);
- goto exit;
- }
- prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
- } else {
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
- "%s: stainfo!= NULL!!!\n", __func__);
- prwskey = &stainfo->dot118021x_UncstKey.skey[0];
- }
-
- iv = pframe + prxattrib->hdrlen;
- payload = pframe + prxattrib->iv_len + prxattrib->hdrlen;
- length = skb->len - prxattrib->hdrlen - prxattrib->iv_len;
-
- GET_TKIP_PN(iv, dot11txpn);
-
- pnl = (u16)(dot11txpn.val);
- pnh = (u32)(dot11txpn.val>>16);
-
- phase1((u16 *)&ttkey[0], prwskey, &prxattrib->ta[0], pnh);
- phase2(&rc4key[0], prwskey, (unsigned short *)&ttkey[0], pnl);
-
- /* 4 decrypt payload include icv */
- arcfour_init(&mycontext, rc4key, 16);
- arcfour_encrypt(&mycontext, payload, payload, length);
-
- actual_crc = getcrc32(payload, length - 4);
- expected_crc = get_unaligned_le32(&payload[length - 4]);
-
- if (actual_crc != expected_crc) {
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
- "%s:icv CRC mismatch: "
- "actual: %08x, expected: %08x\n",
- __func__, actual_crc, expected_crc);
- res = _FAIL;
- }
-
-exit:
- return res;
-}
-
-/* 3 ===== AES related ===== */
-
-#define MAX_MSG_SIZE 2048
-/*****************************/
-/******** SBOX Table *********/
-/*****************************/
-
-static u8 sbox_table[256] = {
- 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
- 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
- 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
- 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
- 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
- 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
- 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
- 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
- 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
- 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
- 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
- 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
- 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
- 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
- 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
- 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
- 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
- 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
- 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
- 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
- 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
- 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
- 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
- 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
- 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
- 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
- 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
- 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
- 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
- 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
- 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
- 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-};
-
-/*****************************/
-/**** Function Prototypes ****/
-/*****************************/
-
-static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists,
- int qc_exists);
-
-static void xor_128(u8 *a, u8 *b, u8 *out)
-{
- int i;
-
- for (i = 0; i < 16; i++)
- out[i] = a[i] ^ b[i];
-}
-
-static void xor_32(u8 *a, u8 *b, u8 *out)
-{
- int i;
-
- for (i = 0; i < 4; i++)
- out[i] = a[i] ^ b[i];
-}
-
-static u8 sbox(u8 a)
-{
- return sbox_table[(int)a];
-}
-
-static void next_key(u8 *key, int round)
-{
- u8 rcon;
- u8 sbox_key[4];
- u8 rcon_table[12] = {
- 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
- 0x1b, 0x36, 0x36, 0x36
- };
-
- sbox_key[0] = sbox(key[13]);
- sbox_key[1] = sbox(key[14]);
- sbox_key[2] = sbox(key[15]);
- sbox_key[3] = sbox(key[12]);
-
- rcon = rcon_table[round];
-
- xor_32(&key[0], sbox_key, &key[0]);
- key[0] = key[0] ^ rcon;
-
- xor_32(&key[4], &key[0], &key[4]);
- xor_32(&key[8], &key[4], &key[8]);
- xor_32(&key[12], &key[8], &key[12]);
-
-}
-
-static void byte_sub(u8 *in, u8 *out)
-{
- int i;
-
- for (i = 0; i < 16; i++)
- out[i] = sbox(in[i]);
-}
-
-static void shift_row(u8 *in, u8 *out)
-{
-
- out[0] = in[0];
- out[1] = in[5];
- out[2] = in[10];
- out[3] = in[15];
- out[4] = in[4];
- out[5] = in[9];
- out[6] = in[14];
- out[7] = in[3];
- out[8] = in[8];
- out[9] = in[13];
- out[10] = in[2];
- out[11] = in[7];
- out[12] = in[12];
- out[13] = in[1];
- out[14] = in[6];
- out[15] = in[11];
-
-}
-
-static void mix_column(u8 *in, u8 *out)
-{
- int i;
- u8 add1b[4];
- u8 add1bf7[4];
- u8 rotl[4];
- u8 swap_halfs[4];
- u8 andf7[4];
- u8 rotr[4];
- u8 temp[4];
- u8 tempb[4];
-
- for (i = 0; i < 4; i++) {
- if ((in[i] & 0x80) == 0x80)
- add1b[i] = 0x1b;
- else
- add1b[i] = 0x00;
- }
-
- swap_halfs[0] = in[2]; /* Swap halfs */
- swap_halfs[1] = in[3];
- swap_halfs[2] = in[0];
- swap_halfs[3] = in[1];
-
- rotl[0] = in[3]; /* Rotate left 8 bits */
- rotl[1] = in[0];
- rotl[2] = in[1];
- rotl[3] = in[2];
-
- andf7[0] = in[0] & 0x7f;
- andf7[1] = in[1] & 0x7f;
- andf7[2] = in[2] & 0x7f;
- andf7[3] = in[3] & 0x7f;
-
- for (i = 3; i > 0; i--) { /* logical shift left 1 bit */
- andf7[i] = andf7[i] << 1;
- if ((andf7[i - 1] & 0x80) == 0x80)
- andf7[i] = (andf7[i] | 0x01);
- }
- andf7[0] = andf7[0] << 1;
- andf7[0] = andf7[0] & 0xfe;
-
- xor_32(add1b, andf7, add1bf7);
-
- xor_32(in, add1bf7, rotr);
-
- temp[0] = rotr[0]; /* Rotate right 8 bits */
- rotr[0] = rotr[1];
- rotr[1] = rotr[2];
- rotr[2] = rotr[3];
- rotr[3] = temp[0];
-
- xor_32(add1bf7, rotr, temp);
- xor_32(swap_halfs, rotl, tempb);
- xor_32(temp, tempb, out);
-
-}
-
-static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)
-{
- int round;
- int i;
- u8 intermediatea[16];
- u8 intermediateb[16];
- u8 round_key[16];
-
- for (i = 0; i < 16; i++)
- round_key[i] = key[i];
-
- for (round = 0; round < 11; round++) {
- if (round == 0) {
- xor_128(round_key, data, ciphertext);
- next_key(round_key, round);
- } else if (round == 10) {
- byte_sub(ciphertext, intermediatea);
- shift_row(intermediatea, intermediateb);
- xor_128(intermediateb, round_key, ciphertext);
- } else { /* 1 - 9 */
- byte_sub(ciphertext, intermediatea);
- shift_row(intermediatea, intermediateb);
- mix_column(&intermediateb[0], &intermediatea[0]);
- mix_column(&intermediateb[4], &intermediatea[4]);
- mix_column(&intermediateb[8], &intermediatea[8]);
- mix_column(&intermediateb[12], &intermediatea[12]);
- xor_128(intermediatea, round_key, ciphertext);
- next_key(round_key, round);
- }
- }
-
-}
-
-/************************************************/
-/* construct_mic_iv() */
-/* Builds the MIC IV from header fields and PN */
-/************************************************/
-static void construct_mic_iv(u8 *mic_iv, int qc_exists, int a4_exists, u8 *mpdu,
- uint payload_length, u8 *pn_vector)
-{
- int i;
-
- mic_iv[0] = 0x59;
- if (qc_exists && a4_exists)
- mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
- if (qc_exists && !a4_exists)
- mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
- if (!qc_exists)
- mic_iv[1] = 0x00;
- for (i = 2; i < 8; i++)
- mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
- for (i = 8; i < 14; i++)
- mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
- mic_iv[14] = (unsigned char)(payload_length / 256);
- mic_iv[15] = (unsigned char)(payload_length % 256);
-}
-
-/************************************************/
-/* construct_mic_header1() */
-/* Builds the first MIC header block from */
-/* header fields. */
-/************************************************/
-static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu)
-{
- mic_header1[0] = (u8)((header_length - 2) / 256);
- mic_header1[1] = (u8)((header_length - 2) % 256);
- mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
- mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
- mic_header1[4] = mpdu[4]; /* A1 */
- mic_header1[5] = mpdu[5];
- mic_header1[6] = mpdu[6];
- mic_header1[7] = mpdu[7];
- mic_header1[8] = mpdu[8];
- mic_header1[9] = mpdu[9];
- mic_header1[10] = mpdu[10]; /* A2 */
- mic_header1[11] = mpdu[11];
- mic_header1[12] = mpdu[12];
- mic_header1[13] = mpdu[13];
- mic_header1[14] = mpdu[14];
- mic_header1[15] = mpdu[15];
-
-}
-
-/************************************************/
-/* construct_mic_header2() */
-/* Builds the last MIC header block from */
-/* header fields. */
-/************************************************/
-static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists,
- int qc_exists)
-{
- int i;
-
- for (i = 0; i < 16; i++)
- mic_header2[i] = 0x00;
-
- mic_header2[0] = mpdu[16]; /* A3 */
- mic_header2[1] = mpdu[17];
- mic_header2[2] = mpdu[18];
- mic_header2[3] = mpdu[19];
- mic_header2[4] = mpdu[20];
- mic_header2[5] = mpdu[21];
-
- mic_header2[6] = 0x00;
- mic_header2[7] = 0x00; /* mpdu[23]; */
-
- if (!qc_exists && a4_exists) {
- for (i = 0; i < 6; i++)
- mic_header2[8+i] = mpdu[24+i]; /* A4 */
- }
-
- if (qc_exists && !a4_exists) {
- mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
- mic_header2[9] = mpdu[25] & 0x00;
- }
-
- if (qc_exists && a4_exists) {
- for (i = 0; i < 6; i++)
- mic_header2[8+i] = mpdu[24+i]; /* A4 */
-
- mic_header2[14] = mpdu[30] & 0x0f;
- mic_header2[15] = mpdu[31] & 0x00;
- }
-
-}
-
-/************************************************/
-/* construct_mic_header2() */
-/* Builds the last MIC header block from */
-/* header fields. */
-/************************************************/
-static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists,
- u8 *mpdu, u8 *pn_vector, int c)
-{
- int i = 0;
-
- for (i = 0; i < 16; i++)
- ctr_preload[i] = 0x00;
-
- i = 0;
-
- ctr_preload[0] = 0x01; /* flag */
- if (qc_exists && a4_exists)
- ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
- if (qc_exists && !a4_exists)
- ctr_preload[1] = mpdu[24] & 0x0f;
-
- for (i = 2; i < 8; i++)
- ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
- for (i = 8; i < 14; i++)
- ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
- ctr_preload[14] = (unsigned char) (c / 256); /* Ctr */
- ctr_preload[15] = (unsigned char) (c % 256);
-
-}
-
-/************************************/
-/* bitwise_xor() */
-/* A 128 bit, bitwise exclusive or */
-/************************************/
-static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)
-{
- int i;
-
- for (i = 0; i < 16; i++)
- out[i] = ina[i] ^ inb[i];
-}
-
-static int aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen)
-{
- uint qc_exists, a4_exists, i, j, payload_remainder,
- num_blocks, payload_index;
- u8 pn_vector[6];
- u8 mic_iv[16];
- u8 mic_header1[16];
- u8 mic_header2[16];
- u8 ctr_preload[16];
- /* Intermediate Buffers */
- u8 chain_buffer[16];
- u8 aes_out[16];
- u8 padded_buffer[16];
- u8 mic[8];
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)pframe;
- u16 frsubtype = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE;
-
- memset((void *)mic_iv, 0, 16);
- memset((void *)mic_header1, 0, 16);
- memset((void *)mic_header2, 0, 16);
- memset((void *)ctr_preload, 0, 16);
- memset((void *)chain_buffer, 0, 16);
- memset((void *)aes_out, 0, 16);
- memset((void *)padded_buffer, 0, 16);
-
- if ((hdrlen == sizeof(struct ieee80211_hdr_3addr) ||
- (hdrlen == sizeof(struct ieee80211_qos_hdr))))
- a4_exists = 0;
- else
- a4_exists = 1;
-
- if (ieee80211_is_data(hdr->frame_control)) {
- if ((frsubtype == IEEE80211_STYPE_DATA_CFACK) ||
- (frsubtype == IEEE80211_STYPE_DATA_CFPOLL) ||
- (frsubtype == IEEE80211_STYPE_DATA_CFACKPOLL)) {
- qc_exists = 1;
- if (hdrlen != sizeof(struct ieee80211_qos_hdr))
- hdrlen += 2;
- } else if ((frsubtype == IEEE80211_STYPE_QOS_DATA) ||
- (frsubtype == IEEE80211_STYPE_QOS_DATA_CFACK) ||
- (frsubtype == IEEE80211_STYPE_QOS_DATA_CFPOLL) ||
- (frsubtype == IEEE80211_STYPE_QOS_DATA_CFACKPOLL)) {
- if (hdrlen != sizeof(struct ieee80211_qos_hdr))
- hdrlen += 2;
- qc_exists = 1;
- } else {
- qc_exists = 0;
- }
- } else {
- qc_exists = 0;
- }
- pn_vector[0] = pframe[hdrlen];
- pn_vector[1] = pframe[hdrlen + 1];
- pn_vector[2] = pframe[hdrlen + 4];
- pn_vector[3] = pframe[hdrlen + 5];
- pn_vector[4] = pframe[hdrlen + 6];
- pn_vector[5] = pframe[hdrlen + 7];
-
- construct_mic_iv(mic_iv, qc_exists, a4_exists, pframe, plen, pn_vector);
-
- construct_mic_header1(mic_header1, hdrlen, pframe);
- construct_mic_header2(mic_header2, pframe, a4_exists, qc_exists);
-
- payload_remainder = plen % 16;
- num_blocks = plen / 16;
-
- /* Find start of payload */
- payload_index = hdrlen + 8;
-
- /* Calculate MIC */
- aes128k128d(key, mic_iv, aes_out);
- bitwise_xor(aes_out, mic_header1, chain_buffer);
- aes128k128d(key, chain_buffer, aes_out);
- bitwise_xor(aes_out, mic_header2, chain_buffer);
- aes128k128d(key, chain_buffer, aes_out);
-
- for (i = 0; i < num_blocks; i++) {
- bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
-
- payload_index += 16;
- aes128k128d(key, chain_buffer, aes_out);
- }
-
- /* Add on the final payload block if it needs padding */
- if (payload_remainder > 0) {
- for (j = 0; j < 16; j++)
- padded_buffer[j] = 0x00;
- for (j = 0; j < payload_remainder; j++)
- padded_buffer[j] = pframe[payload_index++];
- bitwise_xor(aes_out, padded_buffer, chain_buffer);
- aes128k128d(key, chain_buffer, aes_out);
- }
-
- for (j = 0; j < 8; j++)
- mic[j] = aes_out[j];
-
- /* Insert MIC into payload */
- for (j = 0; j < 8; j++)
- pframe[payload_index + j] = mic[j];
-
- payload_index = hdrlen + 8;
- for (i = 0; i < num_blocks; i++) {
- construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
- pframe, pn_vector, i + 1);
- aes128k128d(key, ctr_preload, aes_out);
- bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
- for (j = 0; j < 16; j++)
- pframe[payload_index++] = chain_buffer[j];
- }
-
- if (payload_remainder > 0) {
- /* If there is a short final block, then pad it,
- * encrypt it and copy the unpadded part back
- */
- construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe,
- pn_vector, num_blocks + 1);
-
- for (j = 0; j < 16; j++)
- padded_buffer[j] = 0x00;
- for (j = 0; j < payload_remainder; j++)
- padded_buffer[j] = pframe[payload_index + j];
- aes128k128d(key, ctr_preload, aes_out);
- bitwise_xor(aes_out, padded_buffer, chain_buffer);
- for (j = 0; j < payload_remainder; j++)
- pframe[payload_index++] = chain_buffer[j];
- }
-
- /* Encrypt the MIC */
- construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe,
- pn_vector, 0);
-
- for (j = 0; j < 16; j++)
- padded_buffer[j] = 0x00;
- for (j = 0; j < 8; j++)
- padded_buffer[j] = pframe[j + hdrlen + 8 + plen];
-
- aes128k128d(key, ctr_preload, aes_out);
- bitwise_xor(aes_out, padded_buffer, chain_buffer);
- for (j = 0; j < 8; j++)
- pframe[payload_index++] = chain_buffer[j];
-
- return _SUCCESS;
-}
-
-int rtw_aes_encrypt23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe)
-{ /* exclude ICV */
- /* Intermediate Buffers */
- int curfragnum, length;
- u8 *pframe, *prwskey;
- u8 hw_hdr_offset = 0;
- struct sta_info *stainfo;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- int res = _SUCCESS;
-
- if (!pxmitframe->buf_addr)
- return _FAIL;
-
- hw_hdr_offset = TXDESC_OFFSET;
-
- pframe = pxmitframe->buf_addr + hw_hdr_offset;
-
- /* 4 start to encrypt each fragment */
- if (pattrib->encrypt != WLAN_CIPHER_SUITE_CCMP)
- return _FAIL;
-
- if (pattrib->psta) {
- stainfo = pattrib->psta;
- } else {
- DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
- stainfo = rtw_get_stainfo23a(&padapter->stapriv, &pattrib->ra[0]);
- }
-
- if (!stainfo) {
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
- "%s: stainfo == NULL!!!\n", __func__);
- DBG_8723A("%s, psta == NUL\n", __func__);
- res = _FAIL;
- goto out;
- }
- if (!(stainfo->state & _FW_LINKED)) {
- DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
- __func__, stainfo->state);
- return _FAIL;
- }
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
- "%s: stainfo!= NULL!!!\n", __func__);
-
- if (is_multicast_ether_addr(pattrib->ra))
- prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
- else
- prwskey = &stainfo->dot118021x_UncstKey.skey[0];
-
- for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
- /* 4 the last fragment */
- if ((curfragnum + 1) == pattrib->nr_frags) {
- length = pattrib->last_txcmdsz -
- pattrib->hdrlen-pattrib->iv_len -
- pattrib->icv_len;
-
- aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
- } else {
- length = pxmitpriv->frag_len-pattrib->hdrlen -
- pattrib->iv_len - pattrib->icv_len;
-
- aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
- pframe += pxmitpriv->frag_len;
- pframe = PTR_ALIGN(pframe, 4);
- }
- }
-out:
- return res;
-}
-
-static int aes_decipher(u8 *key, uint hdrlen, u8 *pframe, uint plen)
-{
- static u8 message[MAX_MSG_SIZE];
- uint qc_exists, a4_exists, i, j, payload_remainder,
- num_blocks, payload_index;
- int res = _SUCCESS;
- u8 pn_vector[6];
- u8 mic_iv[16];
- u8 mic_header1[16];
- u8 mic_header2[16];
- u8 ctr_preload[16];
- /* Intermediate Buffers */
- u8 chain_buffer[16];
- u8 aes_out[16];
- u8 padded_buffer[16];
- u8 mic[8];
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)pframe;
- u16 frsubtype = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE;
-
- memset((void *)mic_iv, 0, 16);
- memset((void *)mic_header1, 0, 16);
- memset((void *)mic_header2, 0, 16);
- memset((void *)ctr_preload, 0, 16);
- memset((void *)chain_buffer, 0, 16);
- memset((void *)aes_out, 0, 16);
- memset((void *)padded_buffer, 0, 16);
-
- /* start to decrypt the payload */
-
- num_blocks = (plen - 8) / 16; /* plen including llc, payload_length and mic) */
-
- payload_remainder = (plen - 8) % 16;
-
- pn_vector[0] = pframe[hdrlen];
- pn_vector[1] = pframe[hdrlen + 1];
- pn_vector[2] = pframe[hdrlen + 4];
- pn_vector[3] = pframe[hdrlen + 5];
- pn_vector[4] = pframe[hdrlen + 6];
- pn_vector[5] = pframe[hdrlen + 7];
-
- if ((hdrlen == sizeof(struct ieee80211_hdr_3addr) ||
- (hdrlen == sizeof(struct ieee80211_qos_hdr))))
- a4_exists = 0;
- else
- a4_exists = 1;
-
- if (ieee80211_is_data(hdr->frame_control)) {
- if ((frsubtype == IEEE80211_STYPE_DATA_CFACK) ||
- (frsubtype == IEEE80211_STYPE_DATA_CFPOLL) ||
- (frsubtype == IEEE80211_STYPE_DATA_CFACKPOLL)) {
- qc_exists = 1;
- if (hdrlen != sizeof(struct ieee80211_hdr_3addr))
- hdrlen += 2;
- } else if ((frsubtype == IEEE80211_STYPE_QOS_DATA) ||
- (frsubtype == IEEE80211_STYPE_QOS_DATA_CFACK) ||
- (frsubtype == IEEE80211_STYPE_QOS_DATA_CFPOLL) ||
- (frsubtype == IEEE80211_STYPE_QOS_DATA_CFACKPOLL)) {
- if (hdrlen != sizeof(struct ieee80211_hdr_3addr))
- hdrlen += 2;
- qc_exists = 1;
- } else {
- qc_exists = 0;
- }
- } else {
- qc_exists = 0;
- }
-
- /* now, decrypt pframe with hdrlen offset and plen long */
-
- payload_index = hdrlen + 8; /* 8 is for extiv */
-
- for (i = 0; i < num_blocks; i++) {
- construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
- pframe, pn_vector, i + 1);
-
- aes128k128d(key, ctr_preload, aes_out);
- bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);
-
- for (j = 0; j < 16; j++)
- pframe[payload_index++] = chain_buffer[j];
- }
-
- if (payload_remainder > 0) {
- /* If there is a short final block, then pad it,
- * encrypt it and copy the unpadded part back
- */
- construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pframe,
- pn_vector, num_blocks + 1);
-
- for (j = 0; j < 16; j++)
- padded_buffer[j] = 0x00;
- for (j = 0; j < payload_remainder; j++)
- padded_buffer[j] = pframe[payload_index + j];
- aes128k128d(key, ctr_preload, aes_out);
- bitwise_xor(aes_out, padded_buffer, chain_buffer);
- for (j = 0; j < payload_remainder; j++)
- pframe[payload_index++] = chain_buffer[j];
- }
-
- /* start to calculate the mic */
- if ((hdrlen + plen + 8) <= MAX_MSG_SIZE)
- memcpy(message, pframe, (hdrlen + plen + 8)); /* 8 is for ext iv len */
-
- pn_vector[0] = pframe[hdrlen];
- pn_vector[1] = pframe[hdrlen + 1];
- pn_vector[2] = pframe[hdrlen + 4];
- pn_vector[3] = pframe[hdrlen + 5];
- pn_vector[4] = pframe[hdrlen + 6];
- pn_vector[5] = pframe[hdrlen + 7];
-
- construct_mic_iv(mic_iv, qc_exists, a4_exists, message,
- plen - 8, pn_vector);
-
- construct_mic_header1(mic_header1, hdrlen, message);
- construct_mic_header2(mic_header2, message, a4_exists, qc_exists);
-
- payload_remainder = (plen - 8) % 16;
- num_blocks = (plen - 8) / 16;
-
- /* Find start of payload */
- payload_index = hdrlen + 8;
-
- /* Calculate MIC */
- aes128k128d(key, mic_iv, aes_out);
- bitwise_xor(aes_out, mic_header1, chain_buffer);
- aes128k128d(key, chain_buffer, aes_out);
- bitwise_xor(aes_out, mic_header2, chain_buffer);
- aes128k128d(key, chain_buffer, aes_out);
-
- for (i = 0; i < num_blocks; i++) {
- bitwise_xor(aes_out, &message[payload_index], chain_buffer);
-
- payload_index += 16;
- aes128k128d(key, chain_buffer, aes_out);
- }
-
- /* Add on the final payload block if it needs padding */
- if (payload_remainder > 0) {
- for (j = 0; j < 16; j++)
- padded_buffer[j] = 0x00;
- for (j = 0; j < payload_remainder; j++)
- padded_buffer[j] = message[payload_index++];
- bitwise_xor(aes_out, padded_buffer, chain_buffer);
- aes128k128d(key, chain_buffer, aes_out);
- }
-
- for (j = 0 ; j < 8; j++)
- mic[j] = aes_out[j];
-
- /* Insert MIC into payload */
- for (j = 0; j < 8; j++)
- message[payload_index + j] = mic[j];
-
- payload_index = hdrlen + 8;
- for (i = 0; i < num_blocks; i++) {
- construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
- message, pn_vector, i + 1);
- aes128k128d(key, ctr_preload, aes_out);
- bitwise_xor(aes_out, &message[payload_index], chain_buffer);
- for (j = 0; j < 16; j++)
- message[payload_index++] = chain_buffer[j];
- }
-
- if (payload_remainder > 0) {
- /* If there is a short final block, then pad it,
- * encrypt it and copy the unpadded part back
- */
- construct_ctr_preload(ctr_preload, a4_exists, qc_exists,
- message, pn_vector, num_blocks + 1);
-
- for (j = 0; j < 16; j++)
- padded_buffer[j] = 0x00;
- for (j = 0; j < payload_remainder; j++)
- padded_buffer[j] = message[payload_index + j];
- aes128k128d(key, ctr_preload, aes_out);
- bitwise_xor(aes_out, padded_buffer, chain_buffer);
- for (j = 0; j < payload_remainder; j++)
- message[payload_index++] = chain_buffer[j];
- }
-
- /* Encrypt the MIC */
- construct_ctr_preload(ctr_preload, a4_exists, qc_exists, message,
- pn_vector, 0);
-
- for (j = 0; j < 16; j++)
- padded_buffer[j] = 0x00;
- for (j = 0; j < 8; j++)
- padded_buffer[j] = message[j + hdrlen + 8 + plen - 8];
-
- aes128k128d(key, ctr_preload, aes_out);
- bitwise_xor(aes_out, padded_buffer, chain_buffer);
- for (j = 0; j < 8; j++)
- message[payload_index++] = chain_buffer[j];
-
- /* compare the mic */
- for (i = 0; i < 8; i++) {
- if (pframe[hdrlen + 8 + plen - 8 + i] != message[hdrlen + 8 + plen - 8 + i]) {
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
- "%s:mic check error mic[%d]: pframe(%x) != message(%x)\n",
- __func__, i,
- pframe[hdrlen + 8 + plen - 8 + i],
- message[hdrlen + 8 + plen - 8 + i]);
- DBG_8723A("%s:mic check error mic[%d]: pframe(%x) != message(%x)\n",
- __func__, i,
- pframe[hdrlen + 8 + plen - 8 + i],
- message[hdrlen + 8 + plen - 8 + i]);
- res = _FAIL;
- }
- }
- return res;
-}
-
-int rtw_aes_decrypt23a(struct rtw_adapter *padapter,
- struct recv_frame *precvframe)
-{ /* exclude ICV */
- struct sta_info *stainfo;
- struct rx_pkt_attrib *prxattrib = &precvframe->attrib;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct sk_buff *skb = precvframe->pkt;
- int length;
- u8 *pframe, *prwskey;
- int res = _SUCCESS;
-
- pframe = skb->data;
- /* 4 start to encrypt each fragment */
- if (prxattrib->encrypt != WLAN_CIPHER_SUITE_CCMP)
- return _FAIL;
-
- stainfo = rtw_get_stainfo23a(&padapter->stapriv, &prxattrib->ta[0]);
- if (!stainfo) {
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
- "%s: stainfo == NULL!!!\n", __func__);
- res = _FAIL;
- goto exit;
- }
-
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
- "%s: stainfo!= NULL!!!\n", __func__);
-
- if (is_multicast_ether_addr(prxattrib->ra)) {
- /* in concurrent we should use sw decrypt in
- * group key, so we remove this message
- */
- if (!psecuritypriv->binstallGrpkey) {
- res = _FAIL;
- DBG_8723A("%s:rx bc/mc packets, but didn't install "
- "group key!!!!!!!!!!\n", __func__);
- goto exit;
- }
- prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
- if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) {
- DBG_8723A("not match packet_index =%d, install_index ="
- "%d\n", prxattrib->key_index,
- psecuritypriv->dot118021XGrpKeyid);
- res = _FAIL;
- goto exit;
- }
- } else {
- prwskey = &stainfo->dot118021x_UncstKey.skey[0];
- }
-
- length = skb->len - prxattrib->hdrlen - prxattrib->iv_len;
-
- res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length);
-exit:
- return res;
-}
-
-void rtw_use_tkipkey_handler23a(void *function_context)
-{
- struct rtw_adapter *padapter = function_context;
-
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
- "^^^%s ^^^\n", __func__);
- padapter->securitypriv.busetkipkey = 1;
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_,
- "^^^%s padapter->securitypriv.busetkipkey =%d^^^\n",
- __func__, padapter->securitypriv.busetkipkey);
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_sreset.c b/drivers/staging/rtl8723au/core/rtw_sreset.c
deleted file mode 100644
index 29a29d92a6ac..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_sreset.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-#include <rtw_sreset.h>
-#include <usb_ops_linux.h>
-
-void rtw_sreset_init(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
- mutex_init(&psrtpriv->silentreset_mutex);
- psrtpriv->silent_reset_inprogress = false;
- psrtpriv->last_tx_time = 0;
- psrtpriv->last_tx_complete_time = 0;
-}
-
-void rtw_sreset_reset_value(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
- psrtpriv->silent_reset_inprogress = false;
- psrtpriv->last_tx_time = 0;
- psrtpriv->last_tx_complete_time = 0;
-}
-
-bool rtw_sreset_inprogress(struct rtw_adapter *padapter)
-{
- struct rtw_adapter *primary_adapter = GET_PRIMARY_ADAPTER(padapter);
- struct hal_data_8723a *pHalData = GET_HAL_DATA(primary_adapter);
-
- return pHalData->srestpriv.silent_reset_inprogress;
-}
-
-static void sreset_restore_security_station(struct rtw_adapter *padapter)
-{
- struct mlme_priv *mlmepriv = &padapter->mlmepriv;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sta_info *psta;
- struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info;
- u8 val8;
-
- if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)
- val8 = 0xcc;
- else
- val8 = 0xcf;
-
- rtl8723a_set_sec_cfg(padapter, val8);
-
- if (padapter->securitypriv.dot11PrivacyAlgrthm ==
- WLAN_CIPHER_SUITE_TKIP ||
- padapter->securitypriv.dot11PrivacyAlgrthm ==
- WLAN_CIPHER_SUITE_CCMP) {
- psta = rtw_get_stainfo23a(pstapriv, get_bssid(mlmepriv));
- if (psta == NULL) {
- /* DEBUG_ERR(("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
- } else {
- /* pairwise key */
- rtw_setstakey_cmd23a(padapter, (unsigned char *)psta, true);
- /* group key */
- rtw_set_key23a(padapter,&padapter->securitypriv, padapter->securitypriv.dot118021XGrpKeyid, 0);
- }
- }
-}
-
-static void sreset_restore_network_station(struct rtw_adapter *padapter)
-{
- struct mlme_priv *mlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- u8 threshold;
-
- rtw_setopmode_cmd23a(padapter, NL80211_IFTYPE_STATION);
-
- /* TH = 1 => means that invalidate usb rx aggregation */
- /* TH = 0 => means that validate usb rx aggregation, use init value. */
- if (mlmepriv->htpriv.ht_option) {
- if (padapter->registrypriv.wifi_spec == 1)
- threshold = 1;
- else
- threshold = 0;
- } else
- threshold = 1;
-
- rtl8723a_set_rxdma_agg_pg_th(padapter, threshold);
-
- set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
- pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
- hw_var_set_bssid(padapter, pmlmeinfo->network.MacAddress);
- hw_var_set_mlme_join(padapter, 0);
-
- rtl8723a_set_media_status(padapter, pmlmeinfo->state & 0x3);
-
- mlmeext_joinbss_event_callback23a(padapter, 1);
- /* restore Sequence No. */
- rtl8723au_write8(padapter, REG_NQOS_SEQ, padapter->xmitpriv.nqos_ssn);
-
- sreset_restore_security_station(padapter);
-}
-
-static void sreset_restore_network_status(struct rtw_adapter *padapter)
-{
- struct mlme_priv *mlmepriv = &padapter->mlmepriv;
-
- if (check_fwstate(mlmepriv, WIFI_STATION_STATE)) {
- DBG_8723A("%s(%s): fwstate:0x%08x - WIFI_STATION_STATE\n",
- __func__, padapter->pnetdev->name,
- get_fwstate(mlmepriv));
- sreset_restore_network_station(padapter);
-#ifdef CONFIG_8723AU_AP_MODE
- } else if (check_fwstate(mlmepriv, WIFI_AP_STATE)) {
- DBG_8723A("%s(%s): fwstate:0x%08x - WIFI_AP_STATE\n",
- __func__, padapter->pnetdev->name,
- get_fwstate(mlmepriv));
- rtw_ap_restore_network(padapter);
-#endif
- } else if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE)) {
- DBG_8723A("%s(%s): fwstate:0x%08x - WIFI_ADHOC_STATE\n",
- __func__, padapter->pnetdev->name,
- get_fwstate(mlmepriv));
- } else {
- DBG_8723A("%s(%s): fwstate:0x%08x - ???\n", __func__,
- padapter->pnetdev->name, get_fwstate(mlmepriv));
- }
-}
-
-static void sreset_stop_adapter(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- if (padapter == NULL)
- return;
-
- DBG_8723A("%s(%s)\n", __func__, padapter->pnetdev->name);
-
- if (!rtw_netif_queue_stopped(padapter->pnetdev))
- netif_tx_stop_all_queues(padapter->pnetdev);
-
- rtw_cancel_all_timer23a(padapter);
-
- /* TODO: OS and HCI independent */
- tasklet_kill(&pxmitpriv->xmit_tasklet);
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
- rtw_scan_abort23a(padapter);
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
- rtw23a_join_to_handler((unsigned long)padapter);
-}
-
-static void sreset_start_adapter(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- if (padapter == NULL)
- return;
-
- DBG_8723A("%s(%s)\n", __func__, padapter->pnetdev->name);
-
- if (check_fwstate(pmlmepriv, _FW_LINKED))
- sreset_restore_network_status(padapter);
-
- /* TODO: OS and HCI independent */
- tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
-
- mod_timer(&padapter->mlmepriv.dynamic_chk_timer,
- jiffies + msecs_to_jiffies(2000));
-
- if (rtw_netif_queue_stopped(padapter->pnetdev))
- netif_tx_wake_all_queues(padapter->pnetdev);
-}
-
-void rtw_sreset_reset(struct rtw_adapter *active_adapter)
-{
- struct rtw_adapter *padapter = GET_PRIMARY_ADAPTER(active_adapter);
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- unsigned long start = jiffies;
-
- DBG_8723A("%s\n", __func__);
-
- mutex_lock(&psrtpriv->silentreset_mutex);
- psrtpriv->silent_reset_inprogress = true;
- pwrpriv->change_rfpwrstate = rf_off;
-
- sreset_stop_adapter(padapter);
-
- ips_enter23a(padapter);
- ips_leave23a(padapter);
-
- sreset_start_adapter(padapter);
- psrtpriv->silent_reset_inprogress = false;
- mutex_unlock(&psrtpriv->silentreset_mutex);
-
- DBG_8723A("%s done in %d ms\n", __func__,
- jiffies_to_msecs(jiffies - start));
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_sta_mgt.c b/drivers/staging/rtl8723au/core/rtw_sta_mgt.c
deleted file mode 100644
index a9b778c45d44..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_sta_mgt.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTW_STA_MGT_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <recv_osdep.h>
-#include <xmit_osdep.h>
-#include <mlme_osdep.h>
-#include <sta_info.h>
-#include <rtl8723a_hal.h>
-
-static const u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-static void _rtw_init_stainfo(struct sta_info *psta)
-{
- memset((u8 *)psta, 0, sizeof(struct sta_info));
- spin_lock_init(&psta->lock);
- INIT_LIST_HEAD(&psta->list);
- INIT_LIST_HEAD(&psta->hash_list);
- _rtw_init_queue23a(&psta->sleep_q);
- psta->sleepq_len = 0;
- _rtw_init_sta_xmit_priv23a(&psta->sta_xmitpriv);
- _rtw_init_sta_recv_priv23a(&psta->sta_recvpriv);
-#ifdef CONFIG_8723AU_AP_MODE
- INIT_LIST_HEAD(&psta->asoc_list);
- INIT_LIST_HEAD(&psta->auth_list);
- psta->expire_to = 0;
- psta->flags = 0;
- psta->capability = 0;
- psta->bpairwise_key_installed = false;
- psta->nonerp_set = 0;
- psta->no_short_slot_time_set = 0;
- psta->no_short_preamble_set = 0;
- psta->no_ht_gf_set = 0;
- psta->no_ht_set = 0;
- psta->ht_20mhz_set = 0;
- psta->keep_alive_trycnt = 0;
-#endif /* CONFIG_8723AU_AP_MODE */
-}
-
-int _rtw_init_sta_priv23a(struct sta_priv *pstapriv)
-{
- int i;
-
- spin_lock_init(&pstapriv->sta_hash_lock);
- pstapriv->asoc_sta_count = 0;
- for (i = 0; i < NUM_STA; i++)
- INIT_LIST_HEAD(&pstapriv->sta_hash[i]);
-
-#ifdef CONFIG_8723AU_AP_MODE
- pstapriv->sta_dz_bitmap = 0;
- pstapriv->tim_bitmap = 0;
- INIT_LIST_HEAD(&pstapriv->asoc_list);
- INIT_LIST_HEAD(&pstapriv->auth_list);
- spin_lock_init(&pstapriv->asoc_list_lock);
- spin_lock_init(&pstapriv->auth_list_lock);
- pstapriv->asoc_list_cnt = 0;
- pstapriv->auth_list_cnt = 0;
- pstapriv->auth_to = 3; /* 3*2 = 6 sec */
- pstapriv->assoc_to = 3;
- /* pstapriv->expire_to = 900; 900*2 = 1800 sec = 30 min,
- expire after no any traffic. */
- /* pstapriv->expire_to = 30; 30*2 = 60 sec = 1 min,
- expire after no any traffic. */
- pstapriv->expire_to = 3; /* 3*2 = 6 sec */
- pstapriv->max_num_sta = NUM_STA;
-#endif
- return _SUCCESS;
-}
-
-int _rtw_free_sta_priv23a(struct sta_priv *pstapriv)
-{
- struct list_head *phead;
- struct sta_info *psta, *ptmp;
- struct recv_reorder_ctrl *preorder_ctrl;
- int index;
-
- if (pstapriv) {
- /* delete all reordering_ctrl_timer */
- spin_lock_bh(&pstapriv->sta_hash_lock);
- for (index = 0; index < NUM_STA; index++) {
- phead = &pstapriv->sta_hash[index];
- list_for_each_entry_safe(psta, ptmp, phead, hash_list) {
- int i;
-
- for (i = 0; i < 16 ; i++) {
- preorder_ctrl = &psta->recvreorder_ctrl[i];
- del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
- }
- }
- }
- spin_unlock_bh(&pstapriv->sta_hash_lock);
- /*===============================*/
- }
- return _SUCCESS;
-}
-
-struct sta_info *
-rtw_alloc_stainfo23a(struct sta_priv *pstapriv, const u8 *hwaddr, gfp_t gfp)
-{
- struct list_head *phash_list;
- struct sta_info *psta;
- struct recv_reorder_ctrl *preorder_ctrl;
- s32 index;
- int i = 0;
- u16 wRxSeqInitialValue = 0xffff;
-
- psta = kmalloc(sizeof(struct sta_info), gfp);
- if (!psta)
- return NULL;
-
- spin_lock_bh(&pstapriv->sta_hash_lock);
-
- _rtw_init_stainfo(psta);
-
- psta->padapter = pstapriv->padapter;
-
- ether_addr_copy(psta->hwaddr, hwaddr);
-
- index = wifi_mac_hash(hwaddr);
-
- RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
- "rtw_alloc_stainfo23a: index = %x\n", index);
- if (index >= NUM_STA) {
- RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
- "ERROR => rtw_alloc_stainfo23a: index >= NUM_STA\n");
- psta = NULL;
- goto exit;
- }
- phash_list = &pstapriv->sta_hash[index];
-
- list_add_tail(&psta->hash_list, phash_list);
-
- pstapriv->asoc_sta_count++;
-
-/* For the SMC router, the sequence number of first packet of WPS
- handshake will be 0. */
-/* In this case, this packet will be dropped by recv_decache function
- if we use the 0x00 as the default value for tid_rxseq variable. */
-/* So, we initialize the tid_rxseq variable as the 0xffff. */
-
- for (i = 0; i < 16; i++)
- memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i],
- &wRxSeqInitialValue, 2);
-
- RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
- "alloc number_%d stainfo with hwaddr = %pM\n",
- pstapriv->asoc_sta_count, hwaddr);
-
- init_addba_retry_timer23a(psta);
-
- /* for A-MPDU Rx reordering buffer control */
- for (i = 0; i < 16; i++) {
- preorder_ctrl = &psta->recvreorder_ctrl[i];
-
- preorder_ctrl->padapter = pstapriv->padapter;
-
- preorder_ctrl->enable = false;
-
- preorder_ctrl->indicate_seq = 0xffff;
- preorder_ctrl->wend_b = 0xffff;
- /* preorder_ctrl->wsize_b = (NR_RECVBUFF-2); */
- preorder_ctrl->wsize_b = 64;/* 64; */
-
- _rtw_init_queue23a(&preorder_ctrl->pending_recvframe_queue);
-
- rtw_init_recv_timer23a(preorder_ctrl);
- }
- /* init for DM */
- psta->rssi_stat.UndecoratedSmoothedPWDB = (-1);
- psta->rssi_stat.UndecoratedSmoothedCCK = (-1);
-
- /* init for the sequence number of received management frame */
- psta->RxMgmtFrameSeqNum = 0xffff;
-exit:
- spin_unlock_bh(&pstapriv->sta_hash_lock);
- return psta;
-}
-
-/* using pstapriv->sta_hash_lock to protect */
-int rtw_free_stainfo23a(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- struct recv_reorder_ctrl *preorder_ctrl;
- struct sta_xmit_priv *pstaxmitpriv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct hw_xmit *phwxmit;
- int i;
-
- if (!psta)
- goto exit;
-
- spin_lock_bh(&psta->lock);
- psta->state &= ~_FW_LINKED;
- spin_unlock_bh(&psta->lock);
-
- pstaxmitpriv = &psta->sta_xmitpriv;
-
- spin_lock_bh(&pxmitpriv->lock);
-
- rtw_free_xmitframe_queue23a(pxmitpriv, &psta->sleep_q);
- psta->sleepq_len = 0;
-
- /* vo */
- rtw_free_xmitframe_queue23a(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
- list_del_init(&pstaxmitpriv->vo_q.tx_pending);
- phwxmit = pxmitpriv->hwxmits;
- phwxmit->accnt -= pstaxmitpriv->vo_q.qcnt;
- pstaxmitpriv->vo_q.qcnt = 0;
-
- /* vi */
- rtw_free_xmitframe_queue23a(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
- list_del_init(&pstaxmitpriv->vi_q.tx_pending);
- phwxmit = pxmitpriv->hwxmits+1;
- phwxmit->accnt -= pstaxmitpriv->vi_q.qcnt;
- pstaxmitpriv->vi_q.qcnt = 0;
-
- /* be */
- rtw_free_xmitframe_queue23a(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
- list_del_init(&pstaxmitpriv->be_q.tx_pending);
- phwxmit = pxmitpriv->hwxmits+2;
- phwxmit->accnt -= pstaxmitpriv->be_q.qcnt;
- pstaxmitpriv->be_q.qcnt = 0;
-
- /* bk */
- rtw_free_xmitframe_queue23a(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
- list_del_init(&pstaxmitpriv->bk_q.tx_pending);
- phwxmit = pxmitpriv->hwxmits+3;
- phwxmit->accnt -= pstaxmitpriv->bk_q.qcnt;
- pstaxmitpriv->bk_q.qcnt = 0;
-
- spin_unlock_bh(&pxmitpriv->lock);
-
- list_del_init(&psta->hash_list);
- RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
- "free number_%d stainfo with hwaddr = %pM\n",
- pstapriv->asoc_sta_count, psta->hwaddr);
- pstapriv->asoc_sta_count--;
-
- /* re-init sta_info; 20061114 will be init in alloc_stainfo */
- /* _rtw_init_sta_xmit_priv23a(&psta->sta_xmitpriv); */
- /* _rtw_init_sta_recv_priv23a(&psta->sta_recvpriv); */
-
- del_timer_sync(&psta->addba_retry_timer);
-
- /* for A-MPDU Rx reordering buffer control,
- cancel reordering_ctrl_timer */
- for (i = 0; i < 16; i++) {
- struct list_head *phead, *plist;
- struct recv_frame *prframe;
- struct rtw_queue *ppending_recvframe_queue;
-
- preorder_ctrl = &psta->recvreorder_ctrl[i];
-
- del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
-
- ppending_recvframe_queue =
- &preorder_ctrl->pending_recvframe_queue;
-
- spin_lock_bh(&ppending_recvframe_queue->lock);
- phead = get_list_head(ppending_recvframe_queue);
- plist = phead->next;
-
- while (!list_empty(phead)) {
- prframe = container_of(plist, struct recv_frame, list);
- plist = plist->next;
- list_del_init(&prframe->list);
- rtw_free_recvframe23a(prframe);
- }
- spin_unlock_bh(&ppending_recvframe_queue->lock);
- }
- if (!(psta->state & WIFI_AP_STATE))
- rtl8723a_SetHalODMVar(padapter, HAL_ODM_STA_INFO, psta, false);
-#ifdef CONFIG_8723AU_AP_MODE
- spin_lock_bh(&pstapriv->auth_list_lock);
- if (!list_empty(&psta->auth_list)) {
- list_del_init(&psta->auth_list);
- pstapriv->auth_list_cnt--;
- }
- spin_unlock_bh(&pstapriv->auth_list_lock);
-
- psta->expire_to = 0;
-
- psta->sleepq_ac_len = 0;
- psta->qos_info = 0;
-
- psta->max_sp_len = 0;
- psta->uapsd_bk = 0;
- psta->uapsd_be = 0;
- psta->uapsd_vi = 0;
- psta->uapsd_vo = 0;
-
- psta->has_legacy_ac = 0;
-
- pstapriv->sta_dz_bitmap &= ~CHKBIT(psta->aid);
- pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
-
- if ((psta->aid > 0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
- pstapriv->sta_aid[psta->aid - 1] = NULL;
- psta->aid = 0;
- }
-#endif /* CONFIG_8723AU_AP_MODE */
-
- kfree(psta);
-exit:
- return _SUCCESS;
-}
-
-/* free all stainfo which in sta_hash[all] */
-void rtw_free_all_stainfo23a(struct rtw_adapter *padapter)
-{
- struct list_head *phead;
- struct sta_info *psta, *ptmp;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo23a(padapter);
- s32 index;
-
- if (pstapriv->asoc_sta_count == 1)
- return;
-
- spin_lock_bh(&pstapriv->sta_hash_lock);
- for (index = 0; index < NUM_STA; index++) {
- phead = &pstapriv->sta_hash[index];
- list_for_each_entry_safe(psta, ptmp, phead, hash_list) {
- if (pbcmc_stainfo != psta)
- rtw_free_stainfo23a(padapter, psta);
- }
- }
- spin_unlock_bh(&pstapriv->sta_hash_lock);
-}
-
-/* any station allocated can be searched by hash list */
-struct sta_info *rtw_get_stainfo23a(struct sta_priv *pstapriv, const u8 *hwaddr)
-{
- struct list_head *phead;
- struct sta_info *pos, *psta = NULL;
- u32 index;
- const u8 *addr;
-
- if (!hwaddr)
- return NULL;
-
- if (is_multicast_ether_addr(hwaddr))
- addr = bc_addr;
- else
- addr = hwaddr;
-
- index = wifi_mac_hash(addr);
-
- spin_lock_bh(&pstapriv->sta_hash_lock);
- phead = &pstapriv->sta_hash[index];
- list_for_each_entry(pos, phead, hash_list) {
- psta = pos;
-
- /* if found the matched address */
- if (ether_addr_equal(psta->hwaddr, addr))
- break;
-
- psta = NULL;
- }
- spin_unlock_bh(&pstapriv->sta_hash_lock);
- return psta;
-}
-
-int rtw_init_bcmc_stainfo23a(struct rtw_adapter *padapter)
-{
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sta_info *psta;
- struct tx_servq *ptxservq;
- int res = _SUCCESS;
-
- psta = rtw_alloc_stainfo23a(pstapriv, bc_addr, GFP_KERNEL);
- if (!psta) {
- res = _FAIL;
- RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
- "rtw_alloc_stainfo23a fail\n");
- return res;
- }
- /* default broadcast & multicast use macid 1 */
- psta->mac_id = 1;
-
- ptxservq = &psta->sta_xmitpriv.be_q;
- return _SUCCESS;
-}
-
-struct sta_info *rtw_get_bcmc_stainfo23a(struct rtw_adapter *padapter)
-{
- struct sta_info *psta;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- psta = rtw_get_stainfo23a(pstapriv, bc_addr);
- return psta;
-}
-
-bool rtw_access_ctrl23a(struct rtw_adapter *padapter, u8 *mac_addr)
-{
- bool res = true;
-#ifdef CONFIG_8723AU_AP_MODE
- struct list_head *phead;
- struct rtw_wlan_acl_node *paclnode;
- bool match = false;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
- struct rtw_queue *pacl_node_q = &pacl_list->acl_node_q;
-
- spin_lock_bh(&pacl_node_q->lock);
- phead = get_list_head(pacl_node_q);
- list_for_each_entry(paclnode, phead, list) {
- if (ether_addr_equal(paclnode->addr, mac_addr)) {
- if (paclnode->valid) {
- match = true;
- break;
- }
- }
- }
- spin_unlock_bh(&pacl_node_q->lock);
-
- if (pacl_list->mode == 1)/* accept unless in deny list */
- res = (match) ? false : true;
- else if (pacl_list->mode == 2)/* deny unless in accept list */
- res = (match) ? true : false;
- else
- res = true;
-#endif
- return res;
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c
deleted file mode 100644
index 694cf17f82cf..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c
+++ /dev/null
@@ -1,1537 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTW_WLAN_UTIL_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <linux/ieee80211.h>
-#include <wifi.h>
-#include <rtl8723a_spec.h>
-
-static unsigned char ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f};
-static unsigned char ARTHEROS_OUI2[] = {0x00, 0x13, 0x74};
-
-static unsigned char BROADCOM_OUI1[] = {0x00, 0x10, 0x18};
-static unsigned char BROADCOM_OUI2[] = {0x00, 0x0a, 0xf7};
-
-static unsigned char CISCO_OUI[] = {0x00, 0x40, 0x96};
-static unsigned char MARVELL_OUI[] = {0x00, 0x50, 0x43};
-static unsigned char RALINK_OUI[] = {0x00, 0x0c, 0x43};
-static unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
-static unsigned char AIRGOCAP_OUI[] = {0x00, 0x0a, 0xf5};
-static unsigned char EPIGRAM_OUI[] = {0x00, 0x90, 0x4c};
-
-static unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
-static unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
-
-#define R2T_PHY_DELAY 0
-
-/* define WAIT_FOR_BCN_TO_MIN 3000 */
-#define WAIT_FOR_BCN_TO_MIN 6000
-#define WAIT_FOR_BCN_TO_MAX 20000
-
-static u8 rtw_basic_rate_cck[4] = {
- IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK
-};
-
-static u8 rtw_basic_rate_ofdm[3] = {
- IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
-};
-
-static u8 rtw_basic_rate_mix[7] = {
- IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
- IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
-};
-
-int cckrates_included23a(unsigned char *rate, int ratelen)
-{
- int i;
-
- for (i = 0; i < ratelen; i++) {
- if (((rate[i]) & 0x7f) == 2 || ((rate[i]) & 0x7f) == 4 ||
- ((rate[i]) & 0x7f) == 11 || ((rate[i]) & 0x7f) == 22)
- return true;
- }
-
- return false;
-}
-
-int cckratesonly_included23a(unsigned char *rate, int ratelen)
-{
- int i;
-
- for (i = 0; i < ratelen; i++) {
- if (((rate[i]) & 0x7f) != 2 && ((rate[i]) & 0x7f) != 4 &&
- ((rate[i]) & 0x7f) != 11 && ((rate[i]) & 0x7f) != 22)
- return false;
- }
-
- return true;
-}
-
-unsigned char networktype_to_raid23a(unsigned char network_type)
-{
- unsigned char raid;
-
- switch (network_type) {
- case WIRELESS_11B:
- raid = RATR_INX_WIRELESS_B;
- break;
- case WIRELESS_11A:
- case WIRELESS_11G:
- raid = RATR_INX_WIRELESS_G;
- break;
- case WIRELESS_11BG:
- raid = RATR_INX_WIRELESS_GB;
- break;
- case WIRELESS_11_24N:
- case WIRELESS_11_5N:
- raid = RATR_INX_WIRELESS_N;
- break;
- case WIRELESS_11A_5N:
- case WIRELESS_11G_24N:
- raid = RATR_INX_WIRELESS_NG;
- break;
- case WIRELESS_11BG_24N:
- raid = RATR_INX_WIRELESS_NGB;
- break;
- default:
- raid = RATR_INX_WIRELESS_GB;
- break;
- }
- return raid;
-}
-
-u8 judge_network_type23a(struct rtw_adapter *padapter,
- unsigned char *rate, int ratelen)
-{
- u8 network_type = 0;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- if (pmlmeext->cur_channel > 14) {
- if (pmlmeinfo->HT_enable)
- network_type = WIRELESS_11_5N;
- network_type |= WIRELESS_11A;
- } else {
- if (pmlmeinfo->HT_enable)
- network_type = WIRELESS_11_24N;
-
- if ((cckratesonly_included23a(rate, ratelen)) == true)
- network_type |= WIRELESS_11B;
- else if ((cckrates_included23a(rate, ratelen)) == true)
- network_type |= WIRELESS_11BG;
- else
- network_type |= WIRELESS_11G;
- }
- return network_type;
-}
-
-static unsigned char ratetbl_val_2wifirate(unsigned char rate)
-{
- unsigned char val = 0;
-
- switch (rate & 0x7f) {
- case 0:
- val = IEEE80211_CCK_RATE_1MB;
- break;
- case 1:
- val = IEEE80211_CCK_RATE_2MB;
- break;
- case 2:
- val = IEEE80211_CCK_RATE_5MB;
- break;
- case 3:
- val = IEEE80211_CCK_RATE_11MB;
- break;
- case 4:
- val = IEEE80211_OFDM_RATE_6MB;
- break;
- case 5:
- val = IEEE80211_OFDM_RATE_9MB;
- break;
- case 6:
- val = IEEE80211_OFDM_RATE_12MB;
- break;
- case 7:
- val = IEEE80211_OFDM_RATE_18MB;
- break;
- case 8:
- val = IEEE80211_OFDM_RATE_24MB;
- break;
- case 9:
- val = IEEE80211_OFDM_RATE_36MB;
- break;
- case 10:
- val = IEEE80211_OFDM_RATE_48MB;
- break;
- case 11:
- val = IEEE80211_OFDM_RATE_54MB;
- break;
- }
- return val;
-}
-
-static int is_basicrate(struct rtw_adapter *padapter, unsigned char rate)
-{
- int i;
- unsigned char val;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- for (i = 0; i < NumRates; i++) {
- val = pmlmeext->basicrate[i];
-
- if (val != 0xff && val != 0xfe) {
- if (rate == ratetbl_val_2wifirate(val))
- return true;
- }
- }
-
- return false;
-}
-
-static unsigned int ratetbl2rateset(struct rtw_adapter *padapter,
- unsigned char *rateset)
-{
- int i;
- unsigned char rate;
- unsigned int len = 0;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- for (i = 0; i < NumRates; i++) {
- rate = pmlmeext->datarate[i];
-
- switch (rate) {
- case 0xff:
- return len;
- case 0xfe:
- continue;
- default:
- rate = ratetbl_val_2wifirate(rate);
-
- if (is_basicrate(padapter, rate) == true)
- rate |= IEEE80211_BASIC_RATE_MASK;
-
- rateset[len] = rate;
- len++;
- break;
- }
- }
- return len;
-}
-
-void get_rate_set23a(struct rtw_adapter *padapter,
- unsigned char *pbssrate, int *bssrate_len)
-{
- unsigned char supportedrates[NumRates];
-
- memset(supportedrates, 0, NumRates);
- *bssrate_len = ratetbl2rateset(padapter, supportedrates);
- memcpy(pbssrate, supportedrates, *bssrate_len);
-}
-
-void UpdateBrateTbl23a(struct rtw_adapter *Adapter, u8 *mBratesOS)
-{
- u8 i;
- u8 rate;
-
- /* 1M, 2M, 5.5M, 11M, 6M, 12M, 24M are mandatory. */
- for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
- rate = mBratesOS[i] & 0x7f;
- switch (rate) {
- case IEEE80211_CCK_RATE_1MB:
- case IEEE80211_CCK_RATE_2MB:
- case IEEE80211_CCK_RATE_5MB:
- case IEEE80211_CCK_RATE_11MB:
- case IEEE80211_OFDM_RATE_6MB:
- case IEEE80211_OFDM_RATE_12MB:
- case IEEE80211_OFDM_RATE_24MB:
- mBratesOS[i] |= IEEE80211_BASIC_RATE_MASK;
- break;
- default:
- break;
- }
- }
-}
-
-void Update23aTblForSoftAP(u8 *bssrateset, u32 bssratelen)
-{
- u8 i;
- u8 rate;
-
- for (i = 0; i < bssratelen; i++) {
- rate = bssrateset[i] & 0x7f;
- switch (rate) {
- case IEEE80211_CCK_RATE_1MB:
- case IEEE80211_CCK_RATE_2MB:
- case IEEE80211_CCK_RATE_5MB:
- case IEEE80211_CCK_RATE_11MB:
- bssrateset[i] |= IEEE80211_BASIC_RATE_MASK;
- break;
- }
- }
-}
-
-inline u8 rtw_get_oper_ch23a(struct rtw_adapter *adapter)
-{
- return adapter_to_dvobj(adapter)->oper_channel;
-}
-
-inline void rtw_set_oper_ch23a(struct rtw_adapter *adapter, u8 ch)
-{
- adapter_to_dvobj(adapter)->oper_channel = ch;
-}
-
-inline void rtw_set_oper_bw23a(struct rtw_adapter *adapter, u8 bw)
-{
- adapter_to_dvobj(adapter)->oper_bwmode = bw;
-}
-
-inline void rtw_set_oper_ch23aoffset23a(struct rtw_adapter *adapter, u8 offset)
-{
- adapter_to_dvobj(adapter)->oper_ch_offset = offset;
-}
-
-void SelectChannel23a(struct rtw_adapter *padapter, unsigned char channel)
-{
- mutex_lock(&adapter_to_dvobj(padapter)->setch_mutex);
-
- /* saved channel info */
- rtw_set_oper_ch23a(padapter, channel);
-
- PHY_SwChnl8723A(padapter, channel);
-
- mutex_unlock(&adapter_to_dvobj(padapter)->setch_mutex);
-}
-
-static void set_bwmode(struct rtw_adapter *padapter, unsigned short bwmode,
- unsigned char channel_offset)
-{
- mutex_lock(&adapter_to_dvobj(padapter)->setbw_mutex);
-
- /* saved bw info */
- rtw_set_oper_bw23a(padapter, bwmode);
- rtw_set_oper_ch23aoffset23a(padapter, channel_offset);
-
- PHY_SetBWMode23a8723A(padapter, (enum ht_channel_width)bwmode,
- channel_offset);
-
- mutex_unlock(&adapter_to_dvobj(padapter)->setbw_mutex);
-}
-
-void set_channel_bwmode23a(struct rtw_adapter *padapter, unsigned char channel,
- unsigned char channel_offset, unsigned short bwmode)
-{
- u8 center_ch;
-
- if (bwmode == HT_CHANNEL_WIDTH_20 ||
- channel_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) {
- /* SelectChannel23a(padapter, channel); */
- center_ch = channel;
- } else {
- /* switch to the proper channel */
- if (channel_offset == HAL_PRIME_CHNL_OFFSET_LOWER) {
- /* SelectChannel23a(padapter, channel + 2); */
- center_ch = channel + 2;
- } else {
- /* SelectChannel23a(padapter, channel - 2); */
- center_ch = channel - 2;
- }
- }
-
- /* set Channel */
- mutex_lock(&adapter_to_dvobj(padapter)->setch_mutex);
-
- /* saved channel/bw info */
- rtw_set_oper_ch23a(padapter, channel);
- rtw_set_oper_bw23a(padapter, bwmode);
- rtw_set_oper_ch23aoffset23a(padapter, channel_offset);
-
- PHY_SwChnl8723A(padapter, center_ch); /* set center channel */
-
- mutex_unlock(&adapter_to_dvobj(padapter)->setch_mutex);
-
- set_bwmode(padapter, bwmode, channel_offset);
-}
-
-inline u8 *get_my_bssid23a(struct wlan_bssid_ex *pnetwork)
-{
- return pnetwork->MacAddress;
-}
-
-bool is_client_associated_to_ap23a(struct rtw_adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext;
- struct mlme_ext_info *pmlmeinfo;
-
- if (!padapter)
- return false;
-
- pmlmeext = &padapter->mlmeextpriv;
- pmlmeinfo = &pmlmeext->mlmext_info;
-
- if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS &&
- (pmlmeinfo->state & 0x03) == MSR_INFRA)
- return true;
- else
- return false;
-}
-
-bool is_client_associated_to_ibss23a(struct rtw_adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS &&
- (pmlmeinfo->state & 0x03) == MSR_ADHOC)
- return true;
- else
- return false;
-}
-
-bool is_IBSS_empty23a(struct rtw_adapter *padapter)
-{
- unsigned int i;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
- if (pmlmeinfo->FW_sta_info[i].status == 1)
- return false;
- }
-
- return true;
-}
-
-unsigned int decide_wait_for_beacon_timeout23a(unsigned int bcn_interval)
-{
- if ((bcn_interval << 2) < WAIT_FOR_BCN_TO_MIN)
- return WAIT_FOR_BCN_TO_MIN;
- else if ((bcn_interval << 2) > WAIT_FOR_BCN_TO_MAX)
- return WAIT_FOR_BCN_TO_MAX;
- else
- return bcn_interval << 2;
-}
-
-void clear_cam_entry23a(struct rtw_adapter *padapter, u8 entry)
-{
- unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- unsigned char null_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00};
-
- rtl8723a_cam_write(padapter, entry, 0, null_sta, null_key);
-}
-
-int allocate_fw_sta_entry23a(struct rtw_adapter *padapter)
-{
- unsigned int mac_id;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- for (mac_id = IBSS_START_MAC_ID; mac_id < NUM_STA; mac_id++) {
- if (pmlmeinfo->FW_sta_info[mac_id].status == 0) {
- pmlmeinfo->FW_sta_info[mac_id].status = 1;
- pmlmeinfo->FW_sta_info[mac_id].retry = 0;
- break;
- }
- }
-
- return mac_id;
-}
-
-void flush_all_cam_entry23a(struct rtw_adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- rtl8723a_cam_invalidate_all(padapter);
-
- memset(pmlmeinfo->FW_sta_info, 0, sizeof(pmlmeinfo->FW_sta_info));
-}
-
-int WMM_param_handler23a(struct rtw_adapter *padapter, const u8 *p)
-{
- /* struct registry_priv *pregpriv = &padapter->registrypriv; */
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- if (pmlmepriv->qos_option == 0) {
- pmlmeinfo->WMM_enable = 0;
- return _FAIL;
- }
-
- pmlmeinfo->WMM_enable = 1;
- memcpy(&pmlmeinfo->WMM_param, p + 2 + 6,
- sizeof(struct WMM_para_element));
- return true;
-}
-
-void WMMOnAssocRsp23a(struct rtw_adapter *padapter)
-{
- u8 ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime;
- u8 acm_mask;
- u16 TXOP;
- u32 acParm, i;
- u32 edca[4], inx[4];
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct registry_priv *pregpriv = &padapter->registrypriv;
-
- if (pmlmeinfo->WMM_enable == 0) {
- padapter->mlmepriv.acm_mask = 0;
- return;
- }
-
- acm_mask = 0;
-
- if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
- aSifsTime = 10;
- else
- aSifsTime = 16;
-
- for (i = 0; i < 4; i++) {
- ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03;
- ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01;
-
- /* AIFS = AIFSN * slot time + SIFS - r2t phy delay */
- AIFS = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN & 0x0f) *
- pmlmeinfo->slotTime + aSifsTime;
-
- ECWMin = pmlmeinfo->WMM_param.ac_param[i].CW & 0x0f;
- ECWMax = (pmlmeinfo->WMM_param.ac_param[i].CW & 0xf0) >> 4;
- TXOP = le16_to_cpu(pmlmeinfo->WMM_param.ac_param[i].TXOP_limit);
-
- acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
-
- switch (ACI) {
- case 0x0:
- rtl8723a_set_ac_param_be(padapter, acParm);
- acm_mask |= (ACM? BIT(1):0);
- edca[XMIT_BE_QUEUE] = acParm;
- break;
- case 0x1:
- rtl8723a_set_ac_param_bk(padapter, acParm);
- /* acm_mask |= (ACM? BIT(0):0); */
- edca[XMIT_BK_QUEUE] = acParm;
- break;
- case 0x2:
- rtl8723a_set_ac_param_vi(padapter, acParm);
- acm_mask |= (ACM? BIT(2):0);
- edca[XMIT_VI_QUEUE] = acParm;
- break;
- case 0x3:
- rtl8723a_set_ac_param_vo(padapter, acParm);
- acm_mask |= (ACM? BIT(3):0);
- edca[XMIT_VO_QUEUE] = acParm;
- break;
- }
-
- DBG_8723A("WMM(%x): %x, %x\n", ACI, ACM, acParm);
- }
-
- if (padapter->registrypriv.acm_method == 1)
- rtl8723a_set_acm_ctrl(padapter, acm_mask);
- else
- padapter->mlmepriv.acm_mask = acm_mask;
-
- inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
-
- if (pregpriv->wifi_spec == 1) {
- u32 j, change_inx = false;
-
- /* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */
- for (i = 0; i < 4; i++) {
- for (j = i+1; j < 4; j++) {
- /* compare CW and AIFS */
- if ((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF)) {
- change_inx = true;
- } else if ((edca[j] & 0xFFFF) ==
- (edca[i] & 0xFFFF)) {
- /* compare TXOP */
- if ((edca[j] >> 16) > (edca[i] >> 16))
- change_inx = true;
- }
-
- if (change_inx) {
- swap(edca[i], edca[j]);
- swap(inx[i], inx[j]);
- change_inx = false;
- }
- }
- }
- }
-
- for (i = 0; i<4; i++) {
- pxmitpriv->wmm_para_seq[i] = inx[i];
- DBG_8723A("wmm_para_seq(%d): %d\n", i,
- pxmitpriv->wmm_para_seq[i]);
- }
-}
-
-static void bwmode_update_check(struct rtw_adapter *padapter, const u8 *p)
-{
- struct ieee80211_ht_operation *pHT_info;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct registry_priv *pregistrypriv = &padapter->registrypriv;
- struct ht_priv *phtpriv = &pmlmepriv->htpriv;
- unsigned char new_bwmode;
- unsigned char new_ch_offset;
-
- if (!p)
- return;
- if (!phtpriv->ht_option)
- return;
- if (p[1] != sizeof(struct ieee80211_ht_operation))
- return;
-
- pHT_info = (struct ieee80211_ht_operation *)(p + 2);
-
- if ((pHT_info->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) &&
- pregistrypriv->cbw40_enable) {
- new_bwmode = HT_CHANNEL_WIDTH_40;
-
- switch (pHT_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET){
- case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
- new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
- break;
- case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
- new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
- break;
- default:
- new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- break;
- }
- } else {
- new_bwmode = HT_CHANNEL_WIDTH_20;
- new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- }
-
- if (new_bwmode != pmlmeext->cur_bwmode ||
- new_ch_offset != pmlmeext->cur_ch_offset) {
- pmlmeinfo->bwmode_updated = true;
-
- pmlmeext->cur_bwmode = new_bwmode;
- pmlmeext->cur_ch_offset = new_ch_offset;
-
- /* update HT info also */
- HT_info_handler23a(padapter, p);
- } else
- pmlmeinfo->bwmode_updated = false;
-
- if (pmlmeinfo->bwmode_updated) {
- struct sta_info *psta;
- struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
- pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
-
- /* update ap's stainfo */
- psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
- if (psta) {
- struct ht_priv *phtpriv_sta = &psta->htpriv;
-
- if (phtpriv_sta->ht_option) {
- /* bwmode */
- phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
- phtpriv_sta->ch_offset =
- pmlmeext->cur_ch_offset;
- } else {
- phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
- phtpriv_sta->ch_offset =
- HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- }
- }
- }
-}
-
-void HT_caps_handler23a(struct rtw_adapter *padapter, const u8 *p)
-{
- unsigned int i;
- u8 rf_type;
- u8 max_AMPDU_len, min_MPDU_spacing;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct ht_priv *phtpriv = &pmlmepriv->htpriv;
- struct ieee80211_ht_cap *cap;
- u8 *dstcap;
-
- if (!p)
- return;
-
- if (!phtpriv->ht_option)
- return;
-
- pmlmeinfo->HT_caps_enable = 1;
-
- cap = &pmlmeinfo->ht_cap;
- dstcap = (u8 *)cap;
- for (i = 0; i < p[1]; i++) {
- if (i != 2) {
- dstcap[i] &= p[i + 2];
- } else {
- /* modify from fw by Thomas 2010/11/17 */
- if ((cap->ampdu_params_info &
- IEEE80211_HT_AMPDU_PARM_FACTOR) >
- (p[i + 2] & IEEE80211_HT_AMPDU_PARM_FACTOR))
- max_AMPDU_len = p[i + 2] &
- IEEE80211_HT_AMPDU_PARM_FACTOR;
- else
- max_AMPDU_len = cap->ampdu_params_info &
- IEEE80211_HT_AMPDU_PARM_FACTOR;
-
- if ((cap->ampdu_params_info &
- IEEE80211_HT_AMPDU_PARM_DENSITY) >
- (p[i + 2] & IEEE80211_HT_AMPDU_PARM_DENSITY))
- min_MPDU_spacing = cap->ampdu_params_info &
- IEEE80211_HT_AMPDU_PARM_DENSITY;
- else
- min_MPDU_spacing = p[i + 2] &
- IEEE80211_HT_AMPDU_PARM_DENSITY;
-
- cap->ampdu_params_info =
- max_AMPDU_len | min_MPDU_spacing;
- }
- }
-
- rf_type = rtl8723a_get_rf_type(padapter);
-
- /* update the MCS rates */
- for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
- if (rf_type == RF_1T1R || rf_type == RF_1T2R)
- cap->mcs.rx_mask[i] &= MCS_rate_1R23A[i];
- else
- cap->mcs.rx_mask[i] &= MCS_rate_2R23A[i];
- }
-}
-
-void HT_info_handler23a(struct rtw_adapter *padapter, const u8 *p)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct ht_priv *phtpriv = &pmlmepriv->htpriv;
-
- if (!p)
- return;
-
- if (!phtpriv->ht_option)
- return;
-
- if (p[1] != sizeof(struct ieee80211_ht_operation))
- return;
-
- pmlmeinfo->HT_info_enable = 1;
- memcpy(&pmlmeinfo->HT_info, p + 2, p[1]);
-}
-
-void HTOnAssocRsp23a(struct rtw_adapter *padapter)
-{
- unsigned char max_AMPDU_len;
- unsigned char min_MPDU_spacing;
- /* struct registry_priv *pregpriv = &padapter->registrypriv; */
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- DBG_8723A("%s\n", __func__);
-
- if (pmlmeinfo->HT_info_enable && pmlmeinfo->HT_caps_enable)
- pmlmeinfo->HT_enable = 1;
- else {
- pmlmeinfo->HT_enable = 0;
- /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
- pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
- return;
- }
-
- /* handle A-MPDU parameter field */
- /*
- AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
- AMPDU_para [4:2]:Min MPDU Start Spacing
- */
- max_AMPDU_len = pmlmeinfo->ht_cap.ampdu_params_info &
- IEEE80211_HT_AMPDU_PARM_FACTOR;
-
- min_MPDU_spacing =
- (pmlmeinfo->ht_cap.ampdu_params_info &
- IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2;
-
- rtl8723a_set_ampdu_min_space(padapter, min_MPDU_spacing);
- rtl8723a_set_ampdu_factor(padapter, max_AMPDU_len);
-}
-
-void ERP_IE_handler23a(struct rtw_adapter *padapter, const u8 *p)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- if (p[1] > 1)
- return;
-
- pmlmeinfo->ERP_enable = 1;
- memcpy(&pmlmeinfo->ERP_IE, p + 2, p[1]);
-}
-
-void VCS_update23a(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- struct registry_priv *pregpriv = &padapter->registrypriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- switch (pregpriv->vrtl_carrier_sense) { /* 0:off 1:on 2:auto */
- case 0: /* off */
- psta->rtsen = 0;
- psta->cts2self = 0;
- break;
- case 1: /* on */
- if (pregpriv->vcs_type == RTS_CTS) {
- psta->rtsen = 1;
- psta->cts2self = 0;
- } else {
- psta->rtsen = 0;
- psta->cts2self = 1;
- }
- break;
- case 2: /* auto */
- default:
- if (pmlmeinfo->ERP_enable && pmlmeinfo->ERP_IE & BIT(1)) {
- if (pregpriv->vcs_type == RTS_CTS) {
- psta->rtsen = 1;
- psta->cts2self = 0;
- } else {
- psta->rtsen = 0;
- psta->cts2self = 1;
- }
- } else {
- psta->rtsen = 0;
- psta->cts2self = 0;
- }
- break;
- }
-}
-
-int rtw_check_bcn_info23a(struct rtw_adapter *Adapter,
- struct ieee80211_mgmt *mgmt, u32 pkt_len)
-{
- struct wlan_network *cur_network = &Adapter->mlmepriv.cur_network;
- struct ieee80211_ht_operation *pht_info;
- unsigned short val16;
- u8 crypto, bcn_channel;
- int group_cipher = 0, pairwise_cipher = 0, is_8021x = 0, r;
- int pie_len, ssid_len, privacy;
- const u8 *p, *ssid;
-
- if (!is_client_associated_to_ap23a(Adapter))
- return _SUCCESS;
-
- if (unlikely(!ieee80211_is_beacon(mgmt->frame_control))) {
- printk(KERN_WARNING "%s: received a non beacon frame!\n",
- __func__);
- return _FAIL;
- }
-
- if (!ether_addr_equal(cur_network->network.MacAddress, mgmt->bssid)) {
- DBG_8723A("%s: linked but recv other bssid bcn %pM %pM\n",
- __func__, mgmt->bssid,
- cur_network->network.MacAddress);
- return _FAIL;
- }
-
- /* check bw and channel offset */
- /* parsing HT_CAP_IE */
- pie_len = pkt_len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
-
- /* Checking for channel */
- p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, mgmt->u.beacon.variable,
- pie_len);
- if (p)
- bcn_channel = p[2];
- else {
- /* In 5G, some ap do not have DSSET IE checking HT
- info for channel */
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
- mgmt->u.beacon.variable, pie_len);
-
- if (p && p[1] > 0) {
- pht_info = (struct ieee80211_ht_operation *)(p + 2);
- bcn_channel = pht_info->primary_chan;
- } else { /* we don't find channel IE, so don't check it */
- DBG_8723A("Oops: %s we don't find channel IE, so don't "
- "check it\n", __func__);
- bcn_channel = Adapter->mlmeextpriv.cur_channel;
- }
- }
- if (bcn_channel != Adapter->mlmeextpriv.cur_channel) {
- DBG_8723A("%s beacon channel:%d cur channel:%d disconnect\n",
- __func__, bcn_channel,
- Adapter->mlmeextpriv.cur_channel);
- goto _mismatch;
- }
-
- /* checking SSID */
- p = cfg80211_find_ie(WLAN_EID_SSID, mgmt->u.beacon.variable, pie_len);
- if (p && p[1]) {
- ssid = p + 2;
- ssid_len = p[1];
- } else {
- DBG_8723A("%s marc: cannot find SSID for survey event\n",
- __func__);
- ssid = NULL;
- ssid_len = 0;
- }
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "%s bssid.Ssid.Ssid:%s bssid.Ssid.SsidLength:%d cur_network->network.Ssid.Ssid:%s len:%d\n",
- __func__, ssid, ssid_len, cur_network->network.Ssid.ssid,
- cur_network->network.Ssid.ssid_len);
-
- if (ssid_len != cur_network->network.Ssid.ssid_len || ssid_len > 32 ||
- (ssid_len &&
- memcmp(ssid, cur_network->network.Ssid.ssid, ssid_len))) {
- DBG_8723A("%s(), SSID is not match return FAIL\n", __func__);
- goto _mismatch;
- }
-
- /* check encryption info */
- val16 = le16_to_cpu(mgmt->u.beacon.capab_info);
-
- if (val16 & WLAN_CAPABILITY_PRIVACY)
- privacy = 1;
- else
- privacy = 0;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "%s(): cur_network->network.Privacy is %d, bssid.Privacy is %d\n",
- __func__, cur_network->network.Privacy, privacy);
- if (cur_network->network.Privacy != privacy) {
- DBG_8723A("%s(), privacy is not match return FAIL\n", __func__);
- goto _mismatch;
- }
-
- p = cfg80211_find_ie(WLAN_EID_RSN, mgmt->u.beacon.variable, pie_len);
- if (p && p[1]) {
- crypto = ENCRYP_PROTOCOL_WPA2;
- if (p && p[1]) {
- r = rtw_parse_wpa2_ie23a(p, p[1] + 2, &group_cipher,
- &pairwise_cipher, &is_8021x);
- if (r == _SUCCESS)
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "%s pnetwork->pairwise_cipher: %d, pnetwork->group_cipher: %d, is_802x : %d\n",
- __func__, pairwise_cipher,
- group_cipher, is_8021x);
- }
- } else {
- p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WPA,
- mgmt->u.beacon.variable, pie_len);
- if (p && p[1]) {
- crypto = ENCRYP_PROTOCOL_WPA;
- r = rtw_parse_wpa_ie23a(p, p[1] + 2, &group_cipher,
- &pairwise_cipher, &is_8021x);
- if (r == _SUCCESS)
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- "%s pnetwork->pairwise_cipher: %d, group_cipher is %d, is_8021x is %d\n",
- __func__, pairwise_cipher,
- group_cipher, is_8021x);
- } else {
- if (privacy)
- crypto = ENCRYP_PROTOCOL_WEP;
- else
- crypto = ENCRYP_PROTOCOL_OPENSYS;
- }
- }
-
- if (cur_network->BcnInfo.encryp_protocol != crypto) {
- DBG_8723A("%s(): encryption mismatch, return FAIL\n", __func__);
- goto _mismatch;
- }
-
- if (crypto == ENCRYP_PROTOCOL_WPA || crypto == ENCRYP_PROTOCOL_WPA2) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- "%s cur_network->group_cipher is %d: %d\n", __func__,
- cur_network->BcnInfo.group_cipher, group_cipher);
- if (pairwise_cipher != cur_network->BcnInfo.pairwise_cipher ||
- group_cipher != cur_network->BcnInfo.group_cipher) {
- DBG_8723A("%s pairwise_cipher(%x:%x) or group_cipher "
- "(%x:%x) is not match, return FAIL\n",
- __func__, pairwise_cipher,
- cur_network->BcnInfo.pairwise_cipher,
- group_cipher,
- cur_network->BcnInfo.group_cipher);
- goto _mismatch;
- }
-
- if (is_8021x != cur_network->BcnInfo.is_8021x) {
- DBG_8723A("%s authentication is not match, return "
- "FAIL\n", __func__);
- goto _mismatch;
- }
- }
-
- return _SUCCESS;
-
-_mismatch:
-
- return _FAIL;
-}
-
-void update_beacon23a_info(struct rtw_adapter *padapter,
- struct ieee80211_mgmt *mgmt,
- uint pkt_len, struct sta_info *psta)
-{
- unsigned int len;
- const u8 *p;
-
- len = pkt_len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
-
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, mgmt->u.beacon.variable,
- len);
- if (p)
- bwmode_update_check(padapter, p);
-
- p = cfg80211_find_ie(WLAN_EID_ERP_INFO, mgmt->u.beacon.variable, len);
- if (p) {
- ERP_IE_handler23a(padapter, p);
- VCS_update23a(padapter, psta);
- }
-}
-
-bool is_ap_in_tkip23a(struct rtw_adapter *padapter)
-{
- u32 i;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
- const u8 *p;
-
- if (cur_network->capability & WLAN_CAPABILITY_PRIVACY) {
- for (i = 0; i < pmlmeinfo->network.IELength;) {
- p = pmlmeinfo->network.IEs + i;
-
- switch (p[0]) {
- case WLAN_EID_VENDOR_SPECIFIC:
- if (!memcmp(p + 2, RTW_WPA_OUI23A_TYPE, 4) &&
- !memcmp(p + 2 + 12, WPA_TKIP_CIPHER, 4))
- return true;
- break;
- case WLAN_EID_RSN:
- if (!memcmp(p + 2 + 8, RSN_TKIP_CIPHER, 4))
- return true;
- break;
- default:
- break;
- }
- i += (p[1] + 2);
- }
- return false;
- } else
- return false;
-}
-
-bool should_forbid_n_rate23a(struct rtw_adapter *padapter)
-{
- u32 i;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_bssid_ex *cur_network = &pmlmepriv->cur_network.network;
- const u8 *p;
-
- if (cur_network->capability & WLAN_CAPABILITY_PRIVACY) {
- for (i = 0; i < cur_network->IELength;) {
- p = cur_network->IEs + i;
-
- switch (p[0]) {
- case WLAN_EID_VENDOR_SPECIFIC:
- if (!memcmp(p + 2, RTW_WPA_OUI23A_TYPE, 4) &&
- (!memcmp(p + 2 + 12,
- WPA_CIPHER_SUITE_CCMP23A, 4) ||
- !memcmp(p + 2 + 16,
- WPA_CIPHER_SUITE_CCMP23A, 4)))
- return false;
- break;
- case WLAN_EID_RSN:
- if (!memcmp(p + 2 + 8,
- RSN_CIPHER_SUITE_CCMP23A, 4) ||
- !memcmp(p + 2 + 12,
- RSN_CIPHER_SUITE_CCMP23A, 4))
- return false;
- default:
- break;
- }
-
- i += (p[1] + 2);
- }
- return true;
- } else {
- return false;
- }
-}
-
-bool is_ap_in_wep23a(struct rtw_adapter *padapter)
-{
- u32 i;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
- const u8 *p;
-
- if (cur_network->capability & WLAN_CAPABILITY_PRIVACY) {
- for (i = 0; i < pmlmeinfo->network.IELength;) {
- p = pmlmeinfo->network.IEs + i;
-
- switch (p[0]) {
- case WLAN_EID_VENDOR_SPECIFIC:
- if (!memcmp(p + 2, RTW_WPA_OUI23A_TYPE, 4))
- return false;
- break;
- case WLAN_EID_RSN:
- return false;
-
- default:
- break;
- }
-
- i += (p[1] + 2);
- }
-
- return true;
- } else
- return false;
-}
-
-static int wifirate2_ratetbl_inx23a(unsigned char rate)
-{
- int inx = 0;
-
- rate = rate & 0x7f;
-
- switch (rate) {
- case 54*2:
- inx = 11;
- break;
- case 48*2:
- inx = 10;
- break;
- case 36*2:
- inx = 9;
- break;
- case 24*2:
- inx = 8;
- break;
- case 18*2:
- inx = 7;
- break;
- case 12*2:
- inx = 6;
- break;
- case 9*2:
- inx = 5;
- break;
- case 6*2:
- inx = 4;
- break;
- case 11*2:
- inx = 3;
- break;
- case 11:
- inx = 2;
- break;
- case 2*2:
- inx = 1;
- break;
- case 1*2:
- inx = 0;
- break;
- }
- return inx;
-}
-
-unsigned int update_basic_rate23a(unsigned char *ptn, unsigned int ptn_sz)
-{
- unsigned int i, num_of_rate;
- unsigned int mask = 0;
-
- num_of_rate = (ptn_sz > NumRates)? NumRates: ptn_sz;
-
- for (i = 0; i < num_of_rate; i++) {
- if ((*(ptn + i)) & 0x80)
- mask |= 0x1 << wifirate2_ratetbl_inx23a(*(ptn + i));
- }
- return mask;
-}
-
-unsigned int update_supported_rate23a(unsigned char *ptn, unsigned int ptn_sz)
-{
- unsigned int i, num_of_rate;
- unsigned int mask = 0;
-
- num_of_rate = (ptn_sz > NumRates) ? NumRates : ptn_sz;
-
- for (i = 0; i < num_of_rate; i++)
- mask |= 0x1 << wifirate2_ratetbl_inx23a(*(ptn + i));
- return mask;
-}
-
-unsigned int update_MSC_rate23a(struct ieee80211_ht_cap *pHT_caps)
-{
- unsigned int mask;
-
- mask = pHT_caps->mcs.rx_mask[0] << 12 |
- pHT_caps->mcs.rx_mask[1] << 20;
-
- return mask;
-}
-
-int support_short_GI23a(struct rtw_adapter *padapter,
- struct ieee80211_ht_cap *pHT_caps)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- unsigned char bit_offset;
-
- if (!pmlmeinfo->HT_enable)
- return _FAIL;
- if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK)
- return _FAIL;
- bit_offset = (pmlmeext->cur_bwmode & HT_CHANNEL_WIDTH_40)? 6: 5;
-
- if (pHT_caps->cap_info & cpu_to_le16(0x1 << bit_offset))
- return _SUCCESS;
- else
- return _FAIL;
-}
-
-unsigned char get_highest_rate_idx23a(u32 mask)
-{
- int i;
- unsigned char rate_idx = 0;
-
- for (i = 27; i >= 0; i--) {
- if (mask & BIT(i)) {
- rate_idx = i;
- break;
- }
- }
- return rate_idx;
-}
-
-void Update_RA_Entry23a(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- rtw_hal_update_ra_mask23a(psta, 0);
-}
-
-static void enable_rate_adaptive(struct rtw_adapter *padapter,
- struct sta_info *psta)
-{
- Update_RA_Entry23a(padapter, psta);
-}
-
-void set_sta_rate23a(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- /* rate adaptive */
- enable_rate_adaptive(padapter, psta);
-}
-
-/* Update RRSR and Rate for USERATE */
-void update_tx_basic_rate23a(struct rtw_adapter *padapter, u8 wirelessmode)
-{
- unsigned char supported_rates[NDIS_802_11_LENGTH_RATES_EX];
-
- memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
-
- if (wirelessmode == WIRELESS_11B) {
- memcpy(supported_rates, rtw_basic_rate_cck, 4);
- } else if (wirelessmode & WIRELESS_11B) {
- memcpy(supported_rates, rtw_basic_rate_mix, 7);
- } else {
- memcpy(supported_rates, rtw_basic_rate_ofdm, 3);
- }
-
- if (wirelessmode & WIRELESS_11B)
- update_mgnt_tx_rate23a(padapter, IEEE80211_CCK_RATE_1MB);
- else
- update_mgnt_tx_rate23a(padapter, IEEE80211_OFDM_RATE_6MB);
-
- HalSetBrateCfg23a(padapter, supported_rates);
-}
-
-unsigned char check_assoc_AP23a(u8 *pframe, uint len)
-{
- int i;
- u8 epigram_vendor_flag;
- u8 ralink_vendor_flag;
- const u8 *p;
-
- epigram_vendor_flag = 0;
- ralink_vendor_flag = 0;
-
- for (i = 0; i < len;) {
- p = pframe + i;
-
- switch (p[0]) {
- case WLAN_EID_VENDOR_SPECIFIC:
- if (!memcmp(p + 2, ARTHEROS_OUI1, 3) ||
- !memcmp(p + 2, ARTHEROS_OUI2, 3)) {
- DBG_8723A("link to Artheros AP\n");
- return HT_IOT_PEER_ATHEROS;
- } else if (!memcmp(p + 2, BROADCOM_OUI1, 3) ||
- !memcmp(p + 2, BROADCOM_OUI2, 3)) {
- DBG_8723A("link to Broadcom AP\n");
- return HT_IOT_PEER_BROADCOM;
- } else if (!memcmp(p + 2, MARVELL_OUI, 3)) {
- DBG_8723A("link to Marvell AP\n");
- return HT_IOT_PEER_MARVELL;
- } else if (!memcmp(p + 2, RALINK_OUI, 3)) {
- if (!ralink_vendor_flag)
- ralink_vendor_flag = 1;
- else {
- DBG_8723A("link to Ralink AP\n");
- return HT_IOT_PEER_RALINK;
- }
- } else if (!memcmp(p + 2, CISCO_OUI, 3)) {
- DBG_8723A("link to Cisco AP\n");
- return HT_IOT_PEER_CISCO;
- } else if (!memcmp(p + 2, REALTEK_OUI, 3)) {
- DBG_8723A("link to Realtek 96B\n");
- return HT_IOT_PEER_REALTEK;
- } else if (!memcmp(p + 2, AIRGOCAP_OUI, 3)) {
- DBG_8723A("link to Airgo Cap\n");
- return HT_IOT_PEER_AIRGO;
- } else if (!memcmp(p + 2, EPIGRAM_OUI, 3)) {
- epigram_vendor_flag = 1;
- if (ralink_vendor_flag) {
- DBG_8723A("link to Tenda W311R AP\n");
- return HT_IOT_PEER_TENDA;
- } else
- DBG_8723A("Capture EPIGRAM_OUI\n");
- } else
- break;
- default:
- break;
- }
-
- i += (p[1] + 2);
- }
-
- if (ralink_vendor_flag && !epigram_vendor_flag) {
- DBG_8723A("link to Ralink AP\n");
- return HT_IOT_PEER_RALINK;
- } else if (ralink_vendor_flag && epigram_vendor_flag) {
- DBG_8723A("link to Tenda W311R AP\n");
- return HT_IOT_PEER_TENDA;
- } else {
- DBG_8723A("link to new AP\n");
- return HT_IOT_PEER_UNKNOWN;
- }
-}
-
-void update_IOT_info23a(struct rtw_adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- switch (pmlmeinfo->assoc_AP_vendor) {
- case HT_IOT_PEER_MARVELL:
- pmlmeinfo->turboMode_cts2self = 1;
- pmlmeinfo->turboMode_rtsen = 0;
- break;
- case HT_IOT_PEER_RALINK:
- pmlmeinfo->turboMode_cts2self = 0;
- pmlmeinfo->turboMode_rtsen = 1;
- /* disable high power */
- rtl8723a_odm_support_ability_clr(padapter, (u32)
- ~DYNAMIC_BB_DYNAMIC_TXPWR);
- break;
- case HT_IOT_PEER_REALTEK:
- /* rtw_write16(padapter, 0x4cc, 0xffff); */
- /* rtw_write16(padapter, 0x546, 0x01c0); */
- /* disable high power */
- rtl8723a_odm_support_ability_clr(padapter, (u32)
- ~DYNAMIC_BB_DYNAMIC_TXPWR);
- break;
- default:
- pmlmeinfo->turboMode_cts2self = 0;
- pmlmeinfo->turboMode_rtsen = 1;
- break;
- }
-}
-
-void update_capinfo23a(struct rtw_adapter *Adapter, u16 updateCap)
-{
- struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- if (updateCap & cShortPreamble) {
- /* Short Preamble */
- if (pmlmeinfo->preamble_mode != PREAMBLE_SHORT) {
- /* PREAMBLE_LONG or PREAMBLE_AUTO */
- pmlmeinfo->preamble_mode = PREAMBLE_SHORT;
- rtl8723a_ack_preamble(Adapter, true);
- }
- } else { /* Long Preamble */
- if (pmlmeinfo->preamble_mode != PREAMBLE_LONG) {
- /* PREAMBLE_SHORT or PREAMBLE_AUTO */
- pmlmeinfo->preamble_mode = PREAMBLE_LONG;
- rtl8723a_ack_preamble(Adapter, false);
- }
- }
- if (updateCap & cIBSS) {
- /* Filen: See 802.11-2007 p.91 */
- pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
- } else {
- /* Filen: See 802.11-2007 p.90 */
- if (pmlmeext->cur_wireless_mode &
- (WIRELESS_11G | WIRELESS_11_24N)) {
- if (updateCap & cShortSlotTime) { /* Short Slot Time */
- if (pmlmeinfo->slotTime != SHORT_SLOT_TIME)
- pmlmeinfo->slotTime = SHORT_SLOT_TIME;
- } else { /* Long Slot Time */
- if (pmlmeinfo->slotTime != NON_SHORT_SLOT_TIME)
- pmlmeinfo->slotTime =
- NON_SHORT_SLOT_TIME;
- }
- } else if (pmlmeext->cur_wireless_mode &
- (WIRELESS_11A | WIRELESS_11_5N)) {
- pmlmeinfo->slotTime = SHORT_SLOT_TIME;
- } else {
- /* B Mode */
- pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
- }
- }
- rtl8723a_set_slot_time(Adapter, pmlmeinfo->slotTime);
-}
-
-void update_wireless_mode23a(struct rtw_adapter *padapter)
-{
- int ratelen, network_type = 0;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
- unsigned char *rate = cur_network->SupportedRates;
-
- ratelen = rtw_get_rateset_len23a(cur_network->SupportedRates);
-
- if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable))
- pmlmeinfo->HT_enable = 1;
-
- if (pmlmeext->cur_channel > 14) {
- if (pmlmeinfo->HT_enable)
- network_type = WIRELESS_11_5N;
- network_type |= WIRELESS_11A;
- } else {
- if (pmlmeinfo->HT_enable)
- network_type = WIRELESS_11_24N;
-
- if (cckratesonly_included23a(rate, ratelen) == true)
- network_type |= WIRELESS_11B;
- else if (cckrates_included23a(rate, ratelen) == true)
- network_type |= WIRELESS_11BG;
- else
- network_type |= WIRELESS_11G;
- }
-
- pmlmeext->cur_wireless_mode =
- network_type & padapter->registrypriv.wireless_mode;
-
- /* 0x0808 -> for CCK, 0x0a0a -> for OFDM */
- /* change this value if having IOT issues. */
- rtl8723a_set_resp_sifs(padapter, 0x08, 0x08, 0x0a, 0x0a);
-
- if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
- update_mgnt_tx_rate23a(padapter, IEEE80211_CCK_RATE_1MB);
- else
- update_mgnt_tx_rate23a(padapter, IEEE80211_OFDM_RATE_6MB);
-}
-
-void update_bmc_sta_support_rate23a(struct rtw_adapter *padapter, u32 mac_id)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
- /* Only B, B/G, and B/G/N AP could use CCK rate */
- memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates),
- rtw_basic_rate_cck, 4);
- } else {
- memcpy(pmlmeinfo->FW_sta_info[mac_id].SupportedRates,
- rtw_basic_rate_ofdm, 3);
- }
-}
-
-int update_sta_support_rate23a(struct rtw_adapter *padapter, u8 *pvar_ie,
- uint var_ie_len, int cam_idx)
-{
- int supportRateNum = 0;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- const u8 *p;
-
- p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, pvar_ie, var_ie_len);
- if (!p)
- return _FAIL;
-
- memcpy(pmlmeinfo->FW_sta_info[cam_idx].SupportedRates, p + 2, p[1]);
- supportRateNum = p[1];
-
- p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, pvar_ie, var_ie_len);
- if (p)
- memcpy(pmlmeinfo->FW_sta_info[cam_idx].SupportedRates +
- supportRateNum, p + 2, p[1]);
- return _SUCCESS;
-}
-
-void process_addba_req23a(struct rtw_adapter *padapter,
- u8 *paddba_req, u8 *addr)
-{
- struct sta_info *psta;
- u16 tid, start_seq, param;
- struct recv_reorder_ctrl *preorder_ctrl;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct ADDBA_request *preq = (struct ADDBA_request *)paddba_req;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- psta = rtw_get_stainfo23a(pstapriv, addr);
-
- if (psta) {
- start_seq = le16_to_cpu(preq->BA_starting_seqctrl) >> 4;
-
- param = le16_to_cpu(preq->BA_para_set);
- tid = (param >> 2) & 0x0f;
-
- preorder_ctrl = &psta->recvreorder_ctrl[tid];
-
- preorder_ctrl->indicate_seq = 0xffff;
-
- preorder_ctrl->enable = (pmlmeinfo->bAcceptAddbaReq == true) ?
- true : false;
- }
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_xmit.c b/drivers/staging/rtl8723au/core/rtw_xmit.c
deleted file mode 100644
index 3de40cfa5f3b..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_xmit.c
+++ /dev/null
@@ -1,2341 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTW_XMIT_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <wifi.h>
-#include <osdep_intf.h>
-#include <linux/ip.h>
-#include <usb_ops.h>
-#include <rtl8723a_xmit.h>
-
-static void _init_txservq(struct tx_servq *ptxservq)
-{
-
- INIT_LIST_HEAD(&ptxservq->tx_pending);
- _rtw_init_queue23a(&ptxservq->sta_pending);
- ptxservq->qcnt = 0;
-
-}
-
-void _rtw_init_sta_xmit_priv23a(struct sta_xmit_priv *psta_xmitpriv)
-{
-
- spin_lock_init(&psta_xmitpriv->lock);
-
- /* for (i = 0 ; i < MAX_NUMBLKS; i++) */
- /* _init_txservq(&psta_xmitpriv->blk_q[i]); */
-
- _init_txservq(&psta_xmitpriv->be_q);
- _init_txservq(&psta_xmitpriv->bk_q);
- _init_txservq(&psta_xmitpriv->vi_q);
- _init_txservq(&psta_xmitpriv->vo_q);
- INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
- INIT_LIST_HEAD(&psta_xmitpriv->apsd);
-
-}
-
-int _rtw_init_xmit_priv23a(struct xmit_priv *pxmitpriv,
- struct rtw_adapter *padapter)
-{
- int i;
- struct xmit_buf *pxmitbuf;
- struct xmit_frame *pxframe;
- int res = _SUCCESS;
- u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
- u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
-
- spin_lock_init(&pxmitpriv->lock);
- spin_lock_init(&pxmitpriv->lock_sctx);
- sema_init(&pxmitpriv->xmit_sema, 0);
- sema_init(&pxmitpriv->terminate_xmitthread_sema, 0);
-
- pxmitpriv->adapter = padapter;
-
- _rtw_init_queue23a(&pxmitpriv->be_pending);
- _rtw_init_queue23a(&pxmitpriv->bk_pending);
- _rtw_init_queue23a(&pxmitpriv->vi_pending);
- _rtw_init_queue23a(&pxmitpriv->vo_pending);
- _rtw_init_queue23a(&pxmitpriv->bm_pending);
-
- _rtw_init_queue23a(&pxmitpriv->free_xmit_queue);
-
- for (i = 0; i < NR_XMITFRAME; i++) {
- pxframe = kzalloc(sizeof(struct xmit_frame), GFP_KERNEL);
- if (!pxframe)
- break;
- INIT_LIST_HEAD(&pxframe->list);
-
- pxframe->padapter = padapter;
- pxframe->frame_tag = NULL_FRAMETAG;
-
- list_add_tail(&pxframe->list,
- &pxmitpriv->free_xmit_queue.queue);
- }
-
- pxmitpriv->free_xmitframe_cnt = i;
-
- pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
-
- /* init xmit_buf */
- _rtw_init_queue23a(&pxmitpriv->free_xmitbuf_queue);
- INIT_LIST_HEAD(&pxmitpriv->xmitbuf_list);
- _rtw_init_queue23a(&pxmitpriv->pending_xmitbuf_queue);
-
- for (i = 0; i < NR_XMITBUFF; i++) {
- pxmitbuf = kzalloc(sizeof(struct xmit_buf), GFP_KERNEL);
- if (!pxmitbuf)
- goto fail;
- INIT_LIST_HEAD(&pxmitbuf->list);
- INIT_LIST_HEAD(&pxmitbuf->list2);
-
- pxmitbuf->padapter = padapter;
-
- /* Tx buf allocation may fail sometimes, so sleep and retry. */
- res = rtw_os_xmit_resource_alloc23a(padapter, pxmitbuf,
- (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
- if (res == _FAIL) {
- goto fail;
- }
-
- list_add_tail(&pxmitbuf->list,
- &pxmitpriv->free_xmitbuf_queue.queue);
- list_add_tail(&pxmitbuf->list2,
- &pxmitpriv->xmitbuf_list);
- }
-
- pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
-
- /* init xframe_ext queue, the same count as extbuf */
- _rtw_init_queue23a(&pxmitpriv->free_xframe_ext_queue);
-
- for (i = 0; i < num_xmit_extbuf; i++) {
- pxframe = kzalloc(sizeof(struct xmit_frame), GFP_KERNEL);
- if (!pxframe)
- break;
- INIT_LIST_HEAD(&pxframe->list);
-
- pxframe->padapter = padapter;
- pxframe->frame_tag = NULL_FRAMETAG;
-
- pxframe->pkt = NULL;
-
- pxframe->buf_addr = NULL;
- pxframe->pxmitbuf = NULL;
-
- pxframe->ext_tag = 1;
-
- list_add_tail(&pxframe->list,
- &pxmitpriv->free_xframe_ext_queue.queue);
- }
- pxmitpriv->free_xframe_ext_cnt = i;
-
- /* Init xmit extension buff */
- _rtw_init_queue23a(&pxmitpriv->free_xmit_extbuf_queue);
- INIT_LIST_HEAD(&pxmitpriv->xmitextbuf_list);
-
- for (i = 0; i < num_xmit_extbuf; i++) {
- pxmitbuf = kzalloc(sizeof(struct xmit_buf), GFP_KERNEL);
- if (!pxmitbuf)
- goto fail;
- INIT_LIST_HEAD(&pxmitbuf->list);
- INIT_LIST_HEAD(&pxmitbuf->list2);
-
- pxmitbuf->padapter = padapter;
-
- /* Tx buf allocation may fail sometimes, so sleep and retry. */
- res = rtw_os_xmit_resource_alloc23a(padapter, pxmitbuf,
- max_xmit_extbuf_size + XMITBUF_ALIGN_SZ);
- if (res == _FAIL) {
- goto exit;
- }
-
- list_add_tail(&pxmitbuf->list,
- &pxmitpriv->free_xmit_extbuf_queue.queue);
- list_add_tail(&pxmitbuf->list2,
- &pxmitpriv->xmitextbuf_list);
- }
-
- pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf;
-
- rtw_alloc_hwxmits23a(padapter);
- rtw_init_hwxmits23a(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
-
- for (i = 0; i < 4; i ++)
- pxmitpriv->wmm_para_seq[i] = i;
-
- sema_init(&pxmitpriv->tx_retevt, 0);
-
- pxmitpriv->ack_tx = false;
- mutex_init(&pxmitpriv->ack_tx_mutex);
- rtw_sctx_init23a(&pxmitpriv->ack_tx_ops, 0);
- tasklet_init(&padapter->xmitpriv.xmit_tasklet,
- (void(*)(unsigned long))rtl8723au_xmit_tasklet,
- (unsigned long)padapter);
-
-exit:
-
- return res;
-fail:
- goto exit;
-}
-
-void _rtw_free_xmit_priv23a(struct xmit_priv *pxmitpriv)
-{
- struct rtw_adapter *padapter = pxmitpriv->adapter;
- struct xmit_frame *pxframe, *ptmp;
- struct xmit_buf *pxmitbuf, *ptmp2;
-
- list_for_each_entry_safe(pxframe, ptmp,
- &pxmitpriv->free_xmit_queue.queue, list) {
- list_del_init(&pxframe->list);
- rtw_os_xmit_complete23a(padapter, pxframe);
- kfree(pxframe);
- }
-
- list_for_each_entry_safe(pxmitbuf, ptmp2,
- &pxmitpriv->xmitbuf_list, list2) {
- list_del_init(&pxmitbuf->list2);
- rtw_os_xmit_resource_free23a(padapter, pxmitbuf);
- kfree(pxmitbuf);
- }
-
- /* free xframe_ext queue, the same count as extbuf */
- list_for_each_entry_safe(pxframe, ptmp,
- &pxmitpriv->free_xframe_ext_queue.queue,
- list) {
- list_del_init(&pxframe->list);
- rtw_os_xmit_complete23a(padapter, pxframe);
- kfree(pxframe);
- }
-
- /* free xmit extension buff */
- list_for_each_entry_safe(pxmitbuf, ptmp2,
- &pxmitpriv->xmitextbuf_list, list2) {
- list_del_init(&pxmitbuf->list2);
- rtw_os_xmit_resource_free23a(padapter, pxmitbuf);
- kfree(pxmitbuf);
- }
-
- rtw_free_hwxmits23a(padapter);
- mutex_destroy(&pxmitpriv->ack_tx_mutex);
-}
-
-static void update_attrib_vcs_info(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe)
-{
- u32 sz;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct sta_info *psta = pattrib->psta;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- if (pattrib->psta) {
- psta = pattrib->psta;
- } else {
- DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
- psta = rtw_get_stainfo23a(&padapter->stapriv, &pattrib->ra[0]);
- }
-
- if (psta == NULL) {
- DBG_8723A("%s, psta == NUL\n", __func__);
- return;
- }
-
- if (!(psta->state &_FW_LINKED)) {
- DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
- return;
- }
-
- if (pattrib->nr_frags != 1)
- sz = padapter->xmitpriv.frag_len;
- else /* no frag */
- sz = pattrib->last_txcmdsz;
-
- /* (1) RTS_Threshold is compared to the MPDU, not MSDU. */
- /* (2) If there are more than one frag in this MSDU, only the first frag uses protection frame. */
- /* Other fragments are protected by previous fragment. */
- /* So we only need to check the length of first fragment. */
- if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N || padapter->registrypriv.wifi_spec) {
- if (sz > padapter->registrypriv.rts_thresh) {
- pattrib->vcs_mode = RTS_CTS;
- } else {
- if (psta->rtsen)
- pattrib->vcs_mode = RTS_CTS;
- else if (psta->cts2self)
- pattrib->vcs_mode = CTS_TO_SELF;
- else
- pattrib->vcs_mode = NONE_VCS;
- }
- } else {
- while (true) {
- /* IOT action */
- if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS &&
- pattrib->ampdu_en &&
- padapter->securitypriv.dot11PrivacyAlgrthm ==
- WLAN_CIPHER_SUITE_CCMP) {
- pattrib->vcs_mode = CTS_TO_SELF;
- break;
- }
-
- /* check ERP protection */
- if (psta->rtsen || psta->cts2self) {
- if (psta->rtsen)
- pattrib->vcs_mode = RTS_CTS;
- else if (psta->cts2self)
- pattrib->vcs_mode = CTS_TO_SELF;
-
- break;
- }
-
- /* check HT op mode */
- if (pattrib->ht_en) {
- u8 HTOpMode = pmlmeinfo->HT_protection;
-
- if ((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) ||
- (!pmlmeext->cur_bwmode && HTOpMode == 3)) {
- pattrib->vcs_mode = RTS_CTS;
- break;
- }
- }
-
- /* check rts */
- if (sz > padapter->registrypriv.rts_thresh) {
- pattrib->vcs_mode = RTS_CTS;
- break;
- }
-
- /* to do list: check MIMO power save condition. */
-
- /* check AMPDU aggregation for TXOP */
- if (pattrib->ampdu_en) {
- pattrib->vcs_mode = RTS_CTS;
- break;
- }
-
- pattrib->vcs_mode = NONE_VCS;
- break;
- }
- }
-}
-
-static void update_attrib_phy_info(struct pkt_attrib *pattrib, struct sta_info *psta)
-{
- /*if (psta->rtsen)
- pattrib->vcs_mode = RTS_CTS;
- else if (psta->cts2self)
- pattrib->vcs_mode = CTS_TO_SELF;
- else
- pattrib->vcs_mode = NONE_VCS;*/
-
- pattrib->mdata = 0;
- pattrib->eosp = 0;
- pattrib->triggered = 0;
-
- /* qos_en, ht_en, init rate, , bw, ch_offset, sgi */
- pattrib->qos_en = psta->qos_option;
-
- pattrib->raid = psta->raid;
- pattrib->ht_en = psta->htpriv.ht_option;
- pattrib->bwmode = psta->htpriv.bwmode;
- pattrib->ch_offset = psta->htpriv.ch_offset;
- pattrib->sgi = psta->htpriv.sgi;
- pattrib->ampdu_en = false;
-
- pattrib->retry_ctrl = false;
-}
-
-u8 qos_acm23a(u8 acm_mask, u8 priority)
-{
- u8 change_priority = priority;
-
- switch (priority) {
- case 0:
- case 3:
- if (acm_mask & BIT(1))
- change_priority = 1;
- break;
- case 1:
- case 2:
- break;
- case 4:
- case 5:
- if (acm_mask & BIT(2))
- change_priority = 0;
- break;
- case 6:
- case 7:
- if (acm_mask & BIT(3))
- change_priority = 5;
- break;
- default:
- DBG_8723A("qos_acm23a(): invalid pattrib->priority: %d!!!\n",
- priority);
- change_priority = 0;
- break;
- }
-
- return change_priority;
-}
-
-static void set_qos(struct sk_buff *skb, struct pkt_attrib *pattrib)
-{
- u8 *pframe = skb->data;
- struct iphdr *ip_hdr;
- u8 UserPriority = 0;
-
- /* get UserPriority from IP hdr */
- if (pattrib->ether_type == ETH_P_IP) {
- ip_hdr = (struct iphdr *)(pframe + ETH_HLEN);
- UserPriority = ip_hdr->tos >> 5;
- } else if (pattrib->ether_type == ETH_P_PAE) {
- /* "When priority processing of data frames is supported, */
- /* a STA's SME should send EAPOL-Key frames at the highest
- priority." */
- UserPriority = 7;
- }
-
- pattrib->priority = UserPriority;
- pattrib->hdrlen = sizeof(struct ieee80211_qos_hdr);
- pattrib->type = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
-}
-
-static int update_attrib(struct rtw_adapter *padapter,
- struct sk_buff *skb, struct pkt_attrib *pattrib)
-{
- struct sta_info *psta = NULL;
- int bmcast;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- int res = _SUCCESS;
- struct ethhdr *ehdr = (struct ethhdr *) skb->data;
-
- pattrib->ether_type = ntohs(ehdr->h_proto);
-
- ether_addr_copy(pattrib->dst, ehdr->h_dest);
- ether_addr_copy(pattrib->src, ehdr->h_source);
-
- pattrib->pctrl = 0;
-
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
- ether_addr_copy(pattrib->ra, pattrib->dst);
- ether_addr_copy(pattrib->ta, pattrib->src);
- } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
- ether_addr_copy(pattrib->ra, get_bssid(pmlmepriv));
- ether_addr_copy(pattrib->ta, pattrib->src);
- } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
- ether_addr_copy(pattrib->ra, pattrib->dst);
- ether_addr_copy(pattrib->ta, get_bssid(pmlmepriv));
- }
-
- pattrib->pktlen = skb->len - ETH_HLEN;
-
- if (pattrib->ether_type == ETH_P_IP) {
- /* The following is for DHCP and ARP packet, we use cck1M
- to tx these packets and let LPS awake some time */
- /* to prevent DHCP protocol fail */
- pattrib->dhcp_pkt = 0;
- /* MINIMUM_DHCP_PACKET_SIZE) { */
- if (pattrib->pktlen > 282 + 24) {
- if (pattrib->ether_type == ETH_P_IP) {/* IP header */
- u8 *pframe = skb->data;
-
- pframe += ETH_HLEN;
-
- if ((pframe[21] == 68 && pframe[23] == 67) ||
- (pframe[21] == 67 && pframe[23] == 68)) {
- /* 68 : UDP BOOTP client */
- /* 67 : UDP BOOTP server */
- RT_TRACE(_module_rtl871x_xmit_c_,
- _drv_err_,
- "======================update_attrib: get DHCP Packet\n");
- pattrib->dhcp_pkt = 1;
- }
- }
- }
- } else if (pattrib->ether_type == ETH_P_PAE) {
- DBG_8723A_LEVEL(_drv_always_, "send eapol packet\n");
- }
-
- if ((pattrib->ether_type == ETH_P_PAE) || (pattrib->dhcp_pkt == 1)) {
- rtw_set_scan_deny(padapter, 3000);
- }
-
- /* If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */
- if ((pattrib->ether_type == ETH_P_ARP) ||
- (pattrib->ether_type == ETH_P_PAE) || (pattrib->dhcp_pkt == 1)) {
- rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
- }
-
- bmcast = is_multicast_ether_addr(pattrib->ra);
-
- /* get sta_info */
- if (bmcast) {
- psta = rtw_get_bcmc_stainfo23a(padapter);
- } else {
- psta = rtw_get_stainfo23a(pstapriv, pattrib->ra);
- if (psta == NULL) { /* if we cannot get psta => drrp the pkt */
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_,
- "update_attrib => get sta_info fail, ra:%pM\n",
- pattrib->ra);
- res = _FAIL;
- goto exit;
- } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) &&
- (!(psta->state & _FW_LINKED))) {
- res = _FAIL;
- goto exit;
- }
- }
-
- if (psta) {
- pattrib->mac_id = psta->mac_id;
- /* DBG_8723A("%s ==> mac_id(%d)\n", __func__, pattrib->mac_id); */
- pattrib->psta = psta;
- } else {
- /* if we cannot get psta => drop the pkt */
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_,
- "update_attrib => get sta_info fail, ra:%pM\n",
- pattrib->ra);
- res = _FAIL;
- goto exit;
- }
-
- pattrib->ack_policy = 0;
- /* get ether_hdr_len */
-
- /* pattrib->ether_type == 0x8100) ? (14 + 4): 14; vlan tag */
- pattrib->pkt_hdrlen = ETH_HLEN;
-
- pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
- pattrib->type = IEEE80211_FTYPE_DATA;
- pattrib->priority = 0;
-
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE | WIFI_ADHOC_STATE |
- WIFI_ADHOC_MASTER_STATE)) {
- if (psta->qos_option)
- set_qos(skb, pattrib);
- } else {
- if (pmlmepriv->qos_option) {
- set_qos(skb, pattrib);
-
- if (pmlmepriv->acm_mask != 0) {
- pattrib->priority = qos_acm23a(pmlmepriv->acm_mask,
- pattrib->priority);
- }
- }
- }
-
- if (psta->ieee8021x_blocked == true) {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "psta->ieee8021x_blocked == true\n");
-
- pattrib->encrypt = 0;
-
- if ((pattrib->ether_type != ETH_P_PAE) &&
- !check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "psta->ieee8021x_blocked == true, pattrib->ether_type(%.4x) != 0x888e\n",
- pattrib->ether_type);
- res = _FAIL;
- goto exit;
- }
- } else {
- GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
-
- switch (psecuritypriv->dot11AuthAlgrthm) {
- case dot11AuthAlgrthm_Open:
- case dot11AuthAlgrthm_Shared:
- case dot11AuthAlgrthm_Auto:
- pattrib->key_idx =
- (u8)psecuritypriv->dot11PrivacyKeyIndex;
- break;
- case dot11AuthAlgrthm_8021X:
- if (bmcast)
- pattrib->key_idx =
- (u8)psecuritypriv->dot118021XGrpKeyid;
- else
- pattrib->key_idx = 0;
- break;
- default:
- pattrib->key_idx = 0;
- break;
- }
-
- }
-
- switch (pattrib->encrypt) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- pattrib->iv_len = IEEE80211_WEP_IV_LEN;
- pattrib->icv_len = IEEE80211_WEP_ICV_LEN;
- break;
-
- case WLAN_CIPHER_SUITE_TKIP:
- pattrib->iv_len = IEEE80211_TKIP_IV_LEN;
- pattrib->icv_len = IEEE80211_TKIP_ICV_LEN;
-
- if (!padapter->securitypriv.busetkipkey) {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "padapter->securitypriv.busetkipkey(%d) == false drop packet\n",
- padapter->securitypriv.busetkipkey);
- res = _FAIL;
- goto exit;
- }
-
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "pattrib->encrypt =%d (WLAN_CIPHER_SUITE_CCMP)\n",
- pattrib->encrypt);
- pattrib->iv_len = IEEE80211_CCMP_HDR_LEN;
- pattrib->icv_len = IEEE80211_CCMP_MIC_LEN;
- break;
-
- default:
- pattrib->iv_len = 0;
- pattrib->icv_len = 0;
- break;
- }
-
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "update_attrib: encrypt =%d\n", pattrib->encrypt);
-
- if (pattrib->encrypt && !psecuritypriv->hw_decrypted) {
- pattrib->bswenc = true;
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "update_attrib: encrypt =%d bswenc = true\n",
- pattrib->encrypt);
- } else {
- pattrib->bswenc = false;
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "update_attrib: bswenc = false\n");
- }
- update_attrib_phy_info(pattrib, psta);
-
-exit:
-
- return res;
-}
-
-static int xmitframe_addmic(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe) {
- struct mic_data micdata;
- struct sta_info *stainfo;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- int curfragnum, length;
- u8 *pframe, *payload, mic[8];
- u8 priority[4]= {0x0, 0x0, 0x0, 0x0};
- u8 hw_hdr_offset = 0;
- int bmcst = is_multicast_ether_addr(pattrib->ra);
-
- if (pattrib->psta) {
- stainfo = pattrib->psta;
- } else {
- DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
- stainfo = rtw_get_stainfo23a(&padapter->stapriv, &pattrib->ra[0]);
- }
-
- if (!stainfo) {
- DBG_8723A("%s, psta == NUL\n", __func__);
- return _FAIL;
- }
-
- if (!(stainfo->state &_FW_LINKED)) {
- DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
- __func__, stainfo->state);
- return _FAIL;
- }
-
- hw_hdr_offset = TXDESC_OFFSET;
-
- if (pattrib->encrypt == WLAN_CIPHER_SUITE_TKIP) {
- /* encode mic code */
- if (stainfo) {
- u8 null_key[16]={0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0};
-
- pframe = pxmitframe->buf_addr + hw_hdr_offset;
-
- if (bmcst) {
- if (!memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16)) {
- return _FAIL;
- }
- /* start to calculate the mic code */
- rtw_secmicsetkey23a(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
- } else {
- if (!memcmp(&stainfo->dot11tkiptxmickey.skey[0],
- null_key, 16)) {
- return _FAIL;
- }
- /* start to calculate the mic code */
- rtw_secmicsetkey23a(&micdata, &stainfo->dot11tkiptxmickey.skey[0]);
- }
-
- if (pframe[1] & 1) { /* ToDS == 1 */
- /* DA */
- rtw_secmicappend23a(&micdata, &pframe[16], 6);
- if (pframe[1] & 2) /* From Ds == 1 */
- rtw_secmicappend23a(&micdata,
- &pframe[24], 6);
- else
- rtw_secmicappend23a(&micdata,
- &pframe[10], 6);
- } else { /* ToDS == 0 */
- /* DA */
- rtw_secmicappend23a(&micdata, &pframe[4], 6);
- if (pframe[1] & 2) /* From Ds == 1 */
- rtw_secmicappend23a(&micdata,
- &pframe[16], 6);
- else
- rtw_secmicappend23a(&micdata,
- &pframe[10], 6);
- }
-
- /* if (pmlmepriv->qos_option == 1) */
- if (pattrib->qos_en)
- priority[0] = (u8)pxmitframe->attrib.priority;
-
- rtw_secmicappend23a(&micdata, &priority[0], 4);
-
- payload = pframe;
-
- for (curfragnum = 0; curfragnum < pattrib->nr_frags;
- curfragnum++) {
- payload = PTR_ALIGN(payload, 4);
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "=== curfragnum =%d, pframe = 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,!!!\n",
- curfragnum, *payload, *(payload + 1),
- *(payload + 2), *(payload + 3),
- *(payload + 4), *(payload + 5),
- *(payload + 6), *(payload + 7));
-
- payload = payload + pattrib->hdrlen +
- pattrib->iv_len;
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "curfragnum =%d pattrib->hdrlen =%d pattrib->iv_len =%d\n",
- curfragnum,
- pattrib->hdrlen, pattrib->iv_len);
- if ((curfragnum + 1) == pattrib->nr_frags) {
- length = pattrib->last_txcmdsz -
- pattrib->hdrlen -
- pattrib->iv_len -
- ((pattrib->bswenc) ?
- pattrib->icv_len : 0);
- rtw_secmicappend23a(&micdata, payload,
- length);
- payload = payload + length;
- } else {
- length = pxmitpriv->frag_len -
- pattrib->hdrlen -
- pattrib->iv_len -
- ((pattrib->bswenc) ?
- pattrib->icv_len : 0);
- rtw_secmicappend23a(&micdata, payload,
- length);
- payload = payload + length +
- pattrib->icv_len;
- RT_TRACE(_module_rtl871x_xmit_c_,
- _drv_err_,
- "curfragnum =%d length =%d pattrib->icv_len =%d\n",
- curfragnum, length,
- pattrib->icv_len);
- }
- }
- rtw_secgetmic23a(&micdata, &mic[0]);
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "xmitframe_addmic: before add mic code!!\n");
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "xmitframe_addmic: pattrib->last_txcmdsz =%d!!!\n",
- pattrib->last_txcmdsz);
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "xmitframe_addmic: mic[0]= 0x%.2x , mic[1]=0x%.2x , mic[2]= 0x%.2x , mic[3]= 0x%.2x\nmic[4]= 0x%.2x , mic[5]= 0x%.2x , mic[6]= 0x%.2x , mic[7]= 0x%.2x !!!!\n",
- mic[0], mic[1], mic[2], mic[3],
- mic[4], mic[5], mic[6], mic[7]);
- /* add mic code and add the mic code length
- in last_txcmdsz */
-
- memcpy(payload, &mic[0], 8);
- pattrib->last_txcmdsz += 8;
-
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "======== last pkt ========\n");
- payload = payload - pattrib->last_txcmdsz + 8;
- for (curfragnum = 0; curfragnum < pattrib->last_txcmdsz;
- curfragnum = curfragnum + 8) {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "%.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x\n",
- *(payload + curfragnum),
- *(payload + curfragnum + 1),
- *(payload + curfragnum + 2),
- *(payload + curfragnum + 3),
- *(payload + curfragnum + 4),
- *(payload + curfragnum + 5),
- *(payload + curfragnum + 6),
- *(payload + curfragnum + 7));
- }
- } else {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "xmitframe_addmic: rtw_get_stainfo23a ==NULL!!!\n");
- }
- }
-
- return _SUCCESS;
-}
-
-static int xmitframe_swencrypt(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe)
-{
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
-
- /* if ((psecuritypriv->sw_encrypt)||(pattrib->bswenc)) */
- if (pattrib->bswenc) {
- /* DBG_8723A("start xmitframe_swencrypt\n"); */
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_,
- "### xmitframe_swencrypt\n");
- switch (pattrib->encrypt) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- rtw_wep_encrypt23a(padapter, pxmitframe);
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- rtw_tkip_encrypt23a(padapter, pxmitframe);
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- rtw_aes_encrypt23a(padapter, pxmitframe);
- break;
- default:
- break;
- }
-
- } else {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_,
- "### xmitframe_hwencrypt\n");
- }
-
- return _SUCCESS;
-}
-
-static int rtw_make_wlanhdr(struct rtw_adapter *padapter, u8 *hdr,
- struct pkt_attrib *pattrib)
-{
- struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
- struct ieee80211_qos_hdr *qoshdr;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- u8 qos_option = false;
- int res = _SUCCESS;
-
- struct sta_info *psta;
-
- int bmcst = is_multicast_ether_addr(pattrib->ra);
-
- if (pattrib->psta) {
- psta = pattrib->psta;
- } else {
- DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
- if (bmcst) {
- psta = rtw_get_bcmc_stainfo23a(padapter);
- } else {
- psta = rtw_get_stainfo23a(&padapter->stapriv, pattrib->ra);
- }
- }
-
- if (psta == NULL) {
- DBG_8723A("%s, psta == NUL\n", __func__);
- return _FAIL;
- }
-
- if (!(psta->state &_FW_LINKED)) {
- DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
- return _FAIL;
- }
-
- memset(hdr, 0, WLANHDR_OFFSET);
-
- pwlanhdr->frame_control = cpu_to_le16(pattrib->type);
-
- if (pattrib->type & IEEE80211_FTYPE_DATA) {
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
- /* to_ds = 1, fr_ds = 0; */
- /* Data transfer to AP */
- pwlanhdr->frame_control |=
- cpu_to_le16(IEEE80211_FCTL_TODS);
- ether_addr_copy(pwlanhdr->addr1, get_bssid(pmlmepriv));
- ether_addr_copy(pwlanhdr->addr2, pattrib->src);
- ether_addr_copy(pwlanhdr->addr3, pattrib->dst);
-
- if (pmlmepriv->qos_option)
- qos_option = true;
-
- } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
- /* to_ds = 0, fr_ds = 1; */
- pwlanhdr->frame_control |=
- cpu_to_le16(IEEE80211_FCTL_FROMDS);
- ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
- ether_addr_copy(pwlanhdr->addr2, get_bssid(pmlmepriv));
- ether_addr_copy(pwlanhdr->addr3, pattrib->src);
-
- if (psta->qos_option)
- qos_option = true;
- } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
- ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
- ether_addr_copy(pwlanhdr->addr2, pattrib->src);
- ether_addr_copy(pwlanhdr->addr3, get_bssid(pmlmepriv));
-
- if (psta->qos_option)
- qos_option = true;
- }
- else {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "fw_state:%x is not allowed to xmit frame\n",
- get_fwstate(pmlmepriv));
- res = _FAIL;
- goto exit;
- }
- if (pattrib->mdata)
- pwlanhdr->frame_control |=
- cpu_to_le16(IEEE80211_FCTL_MOREDATA);
- if (pattrib->encrypt)
- pwlanhdr->frame_control |=
- cpu_to_le16(IEEE80211_FCTL_PROTECTED);
- if (qos_option) {
- qoshdr = (struct ieee80211_qos_hdr *)hdr;
-
- qoshdr->qos_ctrl = cpu_to_le16(
- pattrib->priority & IEEE80211_QOS_CTL_TID_MASK);
-
- qoshdr->qos_ctrl |= cpu_to_le16(
- (pattrib->ack_policy << 5) &
- IEEE80211_QOS_CTL_ACK_POLICY_MASK);
-
- if (pattrib->eosp)
- qoshdr->qos_ctrl |=
- cpu_to_le16(IEEE80211_QOS_CTL_EOSP);
- }
- /* TODO: fill HT Control Field */
-
- /* Update Seq Num will be handled by f/w */
- if (psta) {
- psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
- psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
- pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
- /* We dont need to worry about frag bits here */
- pwlanhdr->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(
- pattrib->seqnum));
- /* check if enable ampdu */
- if (pattrib->ht_en && psta->htpriv.ampdu_enable) {
- if (pattrib->priority >= 16)
- printk(KERN_WARNING "%s: Invalid "
- "pattrib->priority %i\n",
- __func__, pattrib->priority);
- if (psta->htpriv.agg_enable_bitmap &
- BIT(pattrib->priority))
- pattrib->ampdu_en = true;
- }
- /* re-check if enable ampdu by BA_starting_seqctrl */
- if (pattrib->ampdu_en) {
- u16 tx_seq;
-
- tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f];
-
- /* check BA_starting_seqctrl */
- if (SN_LESS(pattrib->seqnum, tx_seq)) {
- /* DBG_8723A("tx ampdu seqnum(%d) < tx_seq(%d)\n", pattrib->seqnum, tx_seq); */
- pattrib->ampdu_en = false;/* AGG BK */
- } else if (SN_EQUAL(pattrib->seqnum, tx_seq)) {
- psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq+1)&0xfff;
- pattrib->ampdu_en = true;/* AGG EN */
- } else {
- /* DBG_8723A("tx ampdu over run\n"); */
- psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum+1)&0xfff;
- pattrib->ampdu_en = true;/* AGG EN */
- }
- }
- }
- }
-exit:
- return res;
-}
-
-s32 rtw_txframes_pending23a(struct rtw_adapter *padapter)
-{
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- return (!list_empty(&pxmitpriv->be_pending.queue)) ||
- (!list_empty(&pxmitpriv->bk_pending.queue)) ||
- (!list_empty(&pxmitpriv->vi_pending.queue)) ||
- (!list_empty(&pxmitpriv->vo_pending.queue));
-}
-
-s32 rtw_txframes_sta_ac_pending23a(struct rtw_adapter *padapter,
- struct pkt_attrib *pattrib)
-{
- struct sta_info *psta;
- struct tx_servq *ptxservq;
- int priority = pattrib->priority;
-
- if (pattrib->psta) {
- psta = pattrib->psta;
- } else {
- DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
- psta = rtw_get_stainfo23a(&padapter->stapriv, &pattrib->ra[0]);
- }
- if (psta == NULL) {
- DBG_8723A("%s, psta == NUL\n", __func__);
- return 0;
- }
- if (!(psta->state &_FW_LINKED)) {
- DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__,
- psta->state);
- return 0;
- }
- switch (priority) {
- case 1:
- case 2:
- ptxservq = &psta->sta_xmitpriv.bk_q;
- break;
- case 4:
- case 5:
- ptxservq = &psta->sta_xmitpriv.vi_q;
- break;
- case 6:
- case 7:
- ptxservq = &psta->sta_xmitpriv.vo_q;
- break;
- case 0:
- case 3:
- default:
- ptxservq = &psta->sta_xmitpriv.be_q;
- break;
- }
- return ptxservq->qcnt;
-}
-
-/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header
- * IEEE LLC/SNAP header contains 8 octets
- * First 3 octets comprise the LLC portion
- * SNAP portion, 5 octets, is divided into two fields:
- * Organizationally Unique Identifier(OUI), 3 octets,
- * type, defined by that organization, 2 octets.
- */
-static int rtw_put_snap(u8 *data, u16 h_proto)
-{
- if (h_proto == ETH_P_IPX || h_proto == ETH_P_AARP)
- ether_addr_copy(data, bridge_tunnel_header);
- else
- ether_addr_copy(data, rfc1042_header);
-
- data += ETH_ALEN;
- put_unaligned_be16(h_proto, data);
- return ETH_ALEN + sizeof(u16);
-}
-
-/*
-
-This sub-routine will perform all the following:
-
-1. remove 802.3 header.
-2. create wlan_header, based on the info in pxmitframe
-3. append sta's iv/ext-iv
-4. append LLC
-5. move frag chunk from pframe to pxmitframe->mem
-6. apply sw-encrypt, if necessary.
-
-*/
-int rtw_xmitframe_coalesce23a(struct rtw_adapter *padapter, struct sk_buff *skb,
- struct xmit_frame *pxmitframe)
-{
- struct sta_info *psta;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct ieee80211_hdr *hdr;
- s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
- u8 *pframe, *mem_start;
- u8 hw_hdr_offset;
- u8 *pbuf_start;
- u8 *pdata = skb->data;
- int data_len = skb->len;
- s32 bmcst = is_multicast_ether_addr(pattrib->ra);
- int res = _SUCCESS;
-
- if (pattrib->psta)
- psta = pattrib->psta;
- else {
- DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
- psta = rtw_get_stainfo23a(&padapter->stapriv, pattrib->ra);
- }
-
- if (!psta) {
- DBG_8723A("%s, psta == NUL\n", __func__);
- return _FAIL;
- }
-
- if (!(psta->state &_FW_LINKED)) {
- DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
- __func__, psta->state);
- return _FAIL;
- }
-
- if (!pxmitframe->buf_addr) {
- DBG_8723A("==> %s buf_addr == NULL\n", __func__);
- return _FAIL;
- }
-
- pbuf_start = pxmitframe->buf_addr;
-
- hw_hdr_offset = TXDESC_OFFSET;
-
- mem_start = pbuf_start + hw_hdr_offset;
-
- if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "%s: rtw_make_wlanhdr fail; drop pkt\n", __func__);
- res = _FAIL;
- goto exit;
- }
-
- pdata += pattrib->pkt_hdrlen;
- data_len -= pattrib->pkt_hdrlen;
-
- frg_inx = 0;
- frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */
-
- while (1) {
- llc_sz = 0;
-
- mpdu_len = frg_len;
-
- pframe = mem_start;
- hdr = (struct ieee80211_hdr *)mem_start;
-
- pframe += pattrib->hdrlen;
- mpdu_len -= pattrib->hdrlen;
-
- /* adding icv, if necessary... */
- if (pattrib->iv_len) {
- if (psta) {
- switch (pattrib->encrypt) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- WEP_IV(pattrib->iv, psta->dot11txpn,
- pattrib->key_idx);
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- if (bmcst)
- TKIP_IV(pattrib->iv,
- psta->dot11txpn,
- pattrib->key_idx);
- else
- TKIP_IV(pattrib->iv,
- psta->dot11txpn, 0);
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- if (bmcst)
- AES_IV(pattrib->iv,
- psta->dot11txpn,
- pattrib->key_idx);
- else
- AES_IV(pattrib->iv,
- psta->dot11txpn, 0);
- break;
- }
- }
-
- memcpy(pframe, pattrib->iv, pattrib->iv_len);
-
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_,
- "rtw_xmiaframe_coalesce23a: keyid =%d pattrib->iv[3]=%.2x pframe =%.2x %.2x %.2x %.2x\n",
- padapter->securitypriv.dot11PrivacyKeyIndex,
- pattrib->iv[3], *pframe, *(pframe+1),
- *(pframe+2), *(pframe+3));
- pframe += pattrib->iv_len;
- mpdu_len -= pattrib->iv_len;
- }
- if (frg_inx == 0) {
- llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
- pframe += llc_sz;
- mpdu_len -= llc_sz;
- }
-
- if (pattrib->icv_len > 0 && pattrib->bswenc)
- mpdu_len -= pattrib->icv_len;
-
- if (bmcst)
- /* don't do fragment to broadcast/multicast packets */
- mem_sz = min_t(s32, data_len, pattrib->pktlen);
- else
- mem_sz = min_t(s32, data_len, mpdu_len);
-
- memcpy(pframe, pdata, mem_sz);
-
- pframe += mem_sz;
- pdata += mem_sz;
- data_len -= mem_sz;
-
- if ((pattrib->icv_len >0) && (pattrib->bswenc)) {
- memcpy(pframe, pattrib->icv, pattrib->icv_len);
- pframe += pattrib->icv_len;
- }
-
- frg_inx++;
-
- if (bmcst || data_len <= 0) {
- pattrib->nr_frags = frg_inx;
-
- pattrib->last_txcmdsz = pattrib->hdrlen +
- pattrib->iv_len +
- ((pattrib->nr_frags == 1) ?
- llc_sz : 0) +
- ((pattrib->bswenc) ?
- pattrib->icv_len : 0) + mem_sz;
- hdr->frame_control &=
- ~cpu_to_le16(IEEE80211_FCTL_MOREFRAGS);
-
- break;
- } else {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "%s: There're still something in packet!\n",
- __func__);
- }
- hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREFRAGS);
-
- mem_start = PTR_ALIGN(pframe, 4) + hw_hdr_offset;
- memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
- }
-
- if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "xmitframe_addmic(padapter, pxmitframe) == _FAIL\n");
- DBG_8723A("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n");
- res = _FAIL;
- goto exit;
- }
-
- xmitframe_swencrypt(padapter, pxmitframe);
-
- if (bmcst == false)
- update_attrib_vcs_info(padapter, pxmitframe);
- else
- pattrib->vcs_mode = NONE_VCS;
-
-exit:
- return res;
-}
-
-void rtw_update_protection23a(struct rtw_adapter *padapter, u8 *ie, uint ie_len)
-{
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct registry_priv *pregistrypriv = &padapter->registrypriv;
- uint protection;
- const u8 *p;
-
- switch (pregistrypriv->vrtl_carrier_sense) {
- case DISABLE_VCS:
- pxmitpriv->vcs = NONE_VCS;
- break;
- case ENABLE_VCS:
- break;
- case AUTO_VCS:
- default:
- p = cfg80211_find_ie(WLAN_EID_ERP_INFO, ie, ie_len);
- if (!p)
- pxmitpriv->vcs = NONE_VCS;
- else {
- protection = (*(p + 2)) & BIT(1);
- if (protection) {
- if (pregistrypriv->vcs_type == RTS_CTS)
- pxmitpriv->vcs = RTS_CTS;
- else
- pxmitpriv->vcs = CTS_TO_SELF;
- } else {
- pxmitpriv->vcs = NONE_VCS;
- }
- }
- break;
- }
-}
-
-void rtw_count_tx_stats23a(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe, int sz)
-{
- struct sta_info *psta = NULL;
- struct stainfo_stats *pstats = NULL;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- if (pxmitframe->frame_tag == DATA_FRAMETAG) {
- pxmitpriv->tx_bytes += sz;
- pmlmepriv->LinkDetectInfo.NumTxOkInPeriod++;
-
- psta = pxmitframe->attrib.psta;
- if (psta) {
- pstats = &psta->sta_stats;
- pstats->tx_pkts++;
- pstats->tx_bytes += sz;
- }
- }
-}
-
-struct xmit_buf *rtw_alloc_xmitbuf23a_ext(struct xmit_priv *pxmitpriv)
-{
- unsigned long irqL;
- struct xmit_buf *pxmitbuf = NULL;
- struct list_head *phead;
- struct rtw_queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
-
- spin_lock_irqsave(&pfree_queue->lock, irqL);
-
- phead = get_list_head(pfree_queue);
-
- if (!list_empty(phead)) {
- pxmitbuf = list_first_entry(phead, struct xmit_buf, list);
-
- list_del_init(&pxmitbuf->list);
-
- pxmitpriv->free_xmit_extbuf_cnt--;
- pxmitbuf->priv_data = NULL;
- pxmitbuf->ext_tag = true;
-
- if (pxmitbuf->sctx) {
- DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__);
- rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
- }
- }
-
- spin_unlock_irqrestore(&pfree_queue->lock, irqL);
-
- return pxmitbuf;
-}
-
-int rtw_free_xmitbuf_ext23a(struct xmit_priv *pxmitpriv,
- struct xmit_buf *pxmitbuf)
-{
- unsigned long irqL;
- struct rtw_queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
-
- if (pxmitbuf == NULL)
- return _FAIL;
-
- spin_lock_irqsave(&pfree_queue->lock, irqL);
-
- list_del_init(&pxmitbuf->list);
-
- list_add_tail(&pxmitbuf->list, get_list_head(pfree_queue));
- pxmitpriv->free_xmit_extbuf_cnt++;
-
- spin_unlock_irqrestore(&pfree_queue->lock, irqL);
-
- return _SUCCESS;
-}
-
-struct xmit_buf *rtw_alloc_xmitbuf23a(struct xmit_priv *pxmitpriv)
-{
- unsigned long irqL;
- struct xmit_buf *pxmitbuf = NULL;
- struct list_head *phead;
- struct rtw_queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
-
- /* DBG_8723A("+rtw_alloc_xmitbuf23a\n"); */
-
- spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
-
- phead = get_list_head(pfree_xmitbuf_queue);
-
- if (!list_empty(phead)) {
- pxmitbuf = list_first_entry(phead, struct xmit_buf, list);
-
- list_del_init(&pxmitbuf->list);
-
- pxmitpriv->free_xmitbuf_cnt--;
- pxmitbuf->priv_data = NULL;
- pxmitbuf->ext_tag = false;
- pxmitbuf->flags = XMIT_VO_QUEUE;
-
- if (pxmitbuf->sctx) {
- DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__);
- rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
- }
- }
-
- spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
-
- return pxmitbuf;
-}
-
-int rtw_free_xmitbuf23a(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
-{
- unsigned long irqL;
- struct rtw_queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
-
- /* DBG_8723A("+rtw_free_xmitbuf23a\n"); */
-
- if (pxmitbuf == NULL)
- return _FAIL;
-
- if (pxmitbuf->sctx) {
- DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__);
- rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE);
- }
-
- if (pxmitbuf->ext_tag) {
- rtw_free_xmitbuf_ext23a(pxmitpriv, pxmitbuf);
- } else {
- spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
-
- list_del_init(&pxmitbuf->list);
-
- list_add_tail(&pxmitbuf->list,
- get_list_head(pfree_xmitbuf_queue));
-
- pxmitpriv->free_xmitbuf_cnt++;
- spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
- }
-
- return _SUCCESS;
-}
-
-static void rtw_init_xmitframe(struct xmit_frame *pxframe)
-{
- if (pxframe != NULL) {
- /* default value setting */
- pxframe->buf_addr = NULL;
- pxframe->pxmitbuf = NULL;
-
- memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
- /* pxframe->attrib.psta = NULL; */
-
- pxframe->frame_tag = DATA_FRAMETAG;
-
- pxframe->pkt = NULL;
- pxframe->pkt_offset = 1;/* default use pkt_offset to fill tx desc */
-
- pxframe->ack_report = 0;
- }
-}
-
-/*
-Calling context:
-1. OS_TXENTRY
-2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
-
-If we turn on USE_RXTHREAD, then, no need for critical section.
-Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
-
-Must be very very cautious...
-
-*/
-static struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)
-{
- struct xmit_frame *pxframe;
- struct rtw_queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
-
- spin_lock_bh(&pfree_xmit_queue->lock);
-
- pxframe = list_first_entry_or_null(&pfree_xmit_queue->queue,
- struct xmit_frame, list);
- if (!pxframe) {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "rtw_alloc_xmitframe:%d\n",
- pxmitpriv->free_xmitframe_cnt);
- } else {
- list_del_init(&pxframe->list);
- pxmitpriv->free_xmitframe_cnt--;
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "rtw_alloc_xmitframe():free_xmitframe_cnt =%d\n",
- pxmitpriv->free_xmitframe_cnt);
- }
-
- spin_unlock_bh(&pfree_xmit_queue->lock);
-
- rtw_init_xmitframe(pxframe);
-
- return pxframe;
-}
-
-struct xmit_frame *rtw_alloc_xmitframe23a_ext(struct xmit_priv *pxmitpriv)
-{
- struct xmit_frame *pxframe;
- struct rtw_queue *queue = &pxmitpriv->free_xframe_ext_queue;
-
- spin_lock_bh(&queue->lock);
-
- pxframe = list_first_entry_or_null(&queue->queue,
- struct xmit_frame, list);
- if (!pxframe) {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "rtw_alloc_xmitframe23a_ext:%d\n",
- pxmitpriv->free_xframe_ext_cnt);
- } else {
- list_del_init(&pxframe->list);
- pxmitpriv->free_xframe_ext_cnt--;
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "rtw_alloc_xmitframe23a_ext():free_xmitframe_cnt =%d\n",
- pxmitpriv->free_xframe_ext_cnt);
- }
-
- spin_unlock_bh(&queue->lock);
-
- rtw_init_xmitframe(pxframe);
-
- return pxframe;
-}
-
-s32 rtw_free_xmitframe23a(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
-{
- struct rtw_queue *queue = NULL;
- struct rtw_adapter *padapter = pxmitpriv->adapter;
- struct sk_buff *pndis_pkt = NULL;
-
- if (pxmitframe == NULL) {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "====== rtw_free_xmitframe23a():pxmitframe == NULL!!!!!!!!!!\n");
- goto exit;
- }
-
- if (pxmitframe->pkt) {
- pndis_pkt = pxmitframe->pkt;
- pxmitframe->pkt = NULL;
- }
-
- if (pxmitframe->ext_tag == 0)
- queue = &pxmitpriv->free_xmit_queue;
- else if (pxmitframe->ext_tag == 1)
- queue = &pxmitpriv->free_xframe_ext_queue;
-
- if (!queue)
- goto check_pkt_complete;
- spin_lock_bh(&queue->lock);
-
- list_del_init(&pxmitframe->list);
- list_add_tail(&pxmitframe->list, get_list_head(queue));
- if (pxmitframe->ext_tag == 0) {
- pxmitpriv->free_xmitframe_cnt++;
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_,
- "rtw_free_xmitframe23a():free_xmitframe_cnt =%d\n",
- pxmitpriv->free_xmitframe_cnt);
- } else if (pxmitframe->ext_tag == 1) {
- pxmitpriv->free_xframe_ext_cnt++;
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_,
- "rtw_free_xmitframe23a():free_xframe_ext_cnt =%d\n",
- pxmitpriv->free_xframe_ext_cnt);
- }
-
- spin_unlock_bh(&queue->lock);
-
-check_pkt_complete:
-
- if (pndis_pkt)
- rtw_os_pkt_complete23a(padapter, pndis_pkt);
-
-exit:
-
- return _SUCCESS;
-}
-
-void rtw_free_xmitframe_queue23a(struct xmit_priv *pxmitpriv,
- struct rtw_queue *pframequeue)
-{
- struct list_head *phead;
- struct xmit_frame *pxmitframe, *ptmp;
-
- spin_lock_bh(&pframequeue->lock);
- phead = get_list_head(pframequeue);
- list_for_each_entry_safe(pxmitframe, ptmp, phead, list)
- rtw_free_xmitframe23a(pxmitpriv, pxmitframe);
- spin_unlock_bh(&pframequeue->lock);
-
-}
-
-int rtw_xmitframe_enqueue23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe)
-{
- if (rtw_xmit23a_classifier(padapter, pxmitframe) == _FAIL) {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "rtw_xmitframe_enqueue23a: drop xmit pkt for classifier fail\n");
- return _FAIL;
- }
-
- return _SUCCESS;
-}
-
-static struct xmit_frame *
-dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit,
- struct tx_servq *ptxservq, struct rtw_queue *pframe_queue)
-{
- struct list_head *phead;
- struct xmit_frame *pxmitframe = NULL;
-
- phead = get_list_head(pframe_queue);
-
- if (!list_empty(phead)) {
- pxmitframe = list_first_entry(phead, struct xmit_frame, list);
- list_del_init(&pxmitframe->list);
- ptxservq->qcnt--;
- }
- return pxmitframe;
-}
-
-struct xmit_frame *
-rtw_dequeue_xframe23a(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i,
- int entry)
-{
- struct list_head *sta_phead;
- struct hw_xmit *phwxmit;
- struct tx_servq *ptxservq = NULL, *ptmp;
- struct rtw_queue *pframe_queue = NULL;
- struct xmit_frame *pxmitframe = NULL;
- struct rtw_adapter *padapter = pxmitpriv->adapter;
- struct registry_priv *pregpriv = &padapter->registrypriv;
- int i, inx[4];
-
- inx[0] = 0;
- inx[1] = 1;
- inx[2] = 2;
- inx[3] = 3;
- if (pregpriv->wifi_spec == 1) {
- int j;
-
- for (j = 0; j < 4; j++)
- inx[j] = pxmitpriv->wmm_para_seq[j];
- }
-
- spin_lock_bh(&pxmitpriv->lock);
-
- for (i = 0; i < entry; i++) {
- phwxmit = phwxmit_i + inx[i];
-
- sta_phead = get_list_head(phwxmit->sta_queue);
- list_for_each_entry_safe(ptxservq, ptmp, sta_phead,
- tx_pending) {
- pframe_queue = &ptxservq->sta_pending;
-
- pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
-
- if (pxmitframe) {
- phwxmit->accnt--;
-
- /* Remove sta node when there is no pending packets. */
- /* must be done after get_next and
- before break */
- if (list_empty(&pframe_queue->queue))
- list_del_init(&ptxservq->tx_pending);
- goto exit;
- }
- }
- }
-exit:
- spin_unlock_bh(&pxmitpriv->lock);
- return pxmitframe;
-}
-
-struct tx_servq *rtw_get_sta_pending23a(struct rtw_adapter *padapter, struct sta_info *psta, int up, u8 *ac)
-{
- struct tx_servq *ptxservq = NULL;
-
- switch (up) {
- case 1:
- case 2:
- ptxservq = &psta->sta_xmitpriv.bk_q;
- *(ac) = 3;
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "rtw_get_sta_pending23a : BK\n");
- break;
- case 4:
- case 5:
- ptxservq = &psta->sta_xmitpriv.vi_q;
- *(ac) = 1;
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "rtw_get_sta_pending23a : VI\n");
- break;
- case 6:
- case 7:
- ptxservq = &psta->sta_xmitpriv.vo_q;
- *(ac) = 0;
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "rtw_get_sta_pending23a : VO\n");
- break;
- case 0:
- case 3:
- default:
- ptxservq = &psta->sta_xmitpriv.be_q;
- *(ac) = 2;
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "rtw_get_sta_pending23a : BE\n");
- break;
- }
- return ptxservq;
-}
-
-/*
- * Will enqueue pxmitframe to the proper queue,
- * and indicate it to xx_pending list.....
- */
-int rtw_xmit23a_classifier(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe)
-{
- struct sta_info *psta;
- struct tx_servq *ptxservq;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
- u8 ac_index;
- int res = _SUCCESS;
-
- if (pattrib->psta) {
- psta = pattrib->psta;
- } else {
- DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
- psta = rtw_get_stainfo23a(pstapriv, pattrib->ra);
- }
- if (psta == NULL) {
- res = _FAIL;
- DBG_8723A("rtw_xmit23a_classifier: psta == NULL\n");
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "rtw_xmit23a_classifier: psta == NULL\n");
- goto exit;
- }
- if (!(psta->state & _FW_LINKED)) {
- DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__,
- psta->state);
- return _FAIL;
- }
- ptxservq = rtw_get_sta_pending23a(padapter, psta, pattrib->priority,
- (u8 *)(&ac_index));
-
- if (list_empty(&ptxservq->tx_pending)) {
- list_add_tail(&ptxservq->tx_pending,
- get_list_head(phwxmits[ac_index].sta_queue));
- }
-
- list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
- ptxservq->qcnt++;
- phwxmits[ac_index].accnt++;
-exit:
- return res;
-}
-
-void rtw_alloc_hwxmits23a(struct rtw_adapter *padapter)
-{
- struct hw_xmit *hwxmits;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- int size;
-
- pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
-
- size = sizeof(struct hw_xmit) * (pxmitpriv->hwxmit_entry + 1);
- pxmitpriv->hwxmits = kzalloc(size, GFP_KERNEL);
-
- hwxmits = pxmitpriv->hwxmits;
-
- if (pxmitpriv->hwxmit_entry == 5) {
- /* pxmitpriv->bmc_txqueue.head = 0; */
- /* hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue; */
- hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
-
- /* pxmitpriv->vo_txqueue.head = 0; */
- /* hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; */
- hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
-
- /* pxmitpriv->vi_txqueue.head = 0; */
- /* hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; */
- hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
-
- /* pxmitpriv->bk_txqueue.head = 0; */
- /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
- hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
-
- /* pxmitpriv->be_txqueue.head = 0; */
- /* hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; */
- hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
-
- } else if (pxmitpriv->hwxmit_entry == 4) {
-
- /* pxmitpriv->vo_txqueue.head = 0; */
- /* hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; */
- hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
-
- /* pxmitpriv->vi_txqueue.head = 0; */
- /* hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; */
- hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
-
- /* pxmitpriv->be_txqueue.head = 0; */
- /* hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; */
- hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
-
- /* pxmitpriv->bk_txqueue.head = 0; */
- /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */
- hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
- } else {
-
- }
-}
-
-void rtw_free_hwxmits23a(struct rtw_adapter *padapter)
-{
- struct hw_xmit *hwxmits;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- hwxmits = pxmitpriv->hwxmits;
- kfree(hwxmits);
-}
-
-void rtw_init_hwxmits23a(struct hw_xmit *phwxmit, int entry)
-{
- int i;
-
- for (i = 0; i < entry; i++, phwxmit++)
- phwxmit->accnt = 0;
-}
-
-u32 rtw_get_ff_hwaddr23a(struct xmit_frame *pxmitframe)
-{
- u32 addr;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
-
- switch (pattrib->qsel) {
- case 0:
- case 3:
- addr = BE_QUEUE_INX;
- break;
- case 1:
- case 2:
- addr = BK_QUEUE_INX;
- break;
- case 4:
- case 5:
- addr = VI_QUEUE_INX;
- break;
- case 6:
- case 7:
- addr = VO_QUEUE_INX;
- break;
- case 0x10:
- addr = BCN_QUEUE_INX;
- break;
- case 0x11:/* BC/MC in PS (HIQ) */
- addr = HIGH_QUEUE_INX;
- break;
- case 0x12:
- default:
- addr = MGT_QUEUE_INX;
- break;
- }
-
- return addr;
-}
-
-/*
- * The main transmit(tx) entry
- *
- * Return
- * 1 enqueue
- * 0 success, hardware will handle this xmit frame(packet)
- * <0 fail
- */
-int rtw_xmit23a(struct rtw_adapter *padapter, struct sk_buff *skb)
-{
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct xmit_frame *pxmitframe = NULL;
- int res;
-
- pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
-
- if (pxmitframe == NULL) {
- RT_TRACE(_module_xmit_osdep_c_, _drv_err_,
- "rtw_xmit23a: no more pxmitframe\n");
- return -1;
- }
-
- res = update_attrib(padapter, skb, &pxmitframe->attrib);
-
- if (res == _FAIL) {
- RT_TRACE(_module_xmit_osdep_c_, _drv_err_,
- "rtw_xmit23a: update attrib fail\n");
- rtw_free_xmitframe23a(pxmitpriv, pxmitframe);
- return -1;
- }
- pxmitframe->pkt = skb;
-
- pxmitframe->attrib.qsel = pxmitframe->attrib.priority;
-
-#ifdef CONFIG_8723AU_AP_MODE
- spin_lock_bh(&pxmitpriv->lock);
- if (xmitframe_enqueue_for_sleeping_sta23a(padapter, pxmitframe)) {
- spin_unlock_bh(&pxmitpriv->lock);
- return 1;
- }
- spin_unlock_bh(&pxmitpriv->lock);
-#endif
-
- if (rtl8723au_hal_xmit(padapter, pxmitframe) == false)
- return 1;
-
- return 0;
-}
-
-#if defined(CONFIG_8723AU_AP_MODE)
-
-int xmitframe_enqueue_for_sleeping_sta23a(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe)
-{
- int ret = false;
- struct sta_info *psta = NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- int bmcst = is_multicast_ether_addr(pattrib->ra);
-
- if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
- return ret;
-
- if (pattrib->psta) {
- psta = pattrib->psta;
- } else {
- DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
- psta = rtw_get_stainfo23a(pstapriv, pattrib->ra);
- }
-
- if (psta == NULL) {
- DBG_8723A("%s, psta == NUL\n", __func__);
- return false;
- }
-
- if (!(psta->state & _FW_LINKED)) {
- DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__,
- psta->state);
- return false;
- }
-
- if (pattrib->triggered == 1) {
- if (bmcst)
- pattrib->qsel = 0x11;/* HIQ */
- return ret;
- }
-
- if (bmcst) {
- spin_lock_bh(&psta->sleep_q.lock);
-
- if (pstapriv->sta_dz_bitmap) {
- /* if anyone sta is in ps mode */
- list_del_init(&pxmitframe->list);
-
- /* spin_lock_bh(&psta->sleep_q.lock); */
-
- list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
-
- psta->sleepq_len++;
-
- pstapriv->tim_bitmap |= BIT(0);/* */
- pstapriv->sta_dz_bitmap |= BIT(0);
-
- /* DBG_8723A("enqueue, sq_len =%d, tim =%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
-
- /* tx bc/mc packets after update bcn */
- update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
-
- /* spin_unlock_bh(&psta->sleep_q.lock); */
-
- ret = true;
-
- }
-
- spin_unlock_bh(&psta->sleep_q.lock);
-
- return ret;
-
- }
-
- spin_lock_bh(&psta->sleep_q.lock);
-
- if (psta->state&WIFI_SLEEP_STATE) {
- u8 wmmps_ac = 0;
-
- if (pstapriv->sta_dz_bitmap & CHKBIT(psta->aid)) {
- list_del_init(&pxmitframe->list);
-
- /* spin_lock_bh(&psta->sleep_q.lock); */
-
- list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
-
- psta->sleepq_len++;
-
- switch (pattrib->priority) {
- case 1:
- case 2:
- wmmps_ac = psta->uapsd_bk & BIT(0);
- break;
- case 4:
- case 5:
- wmmps_ac = psta->uapsd_vi & BIT(0);
- break;
- case 6:
- case 7:
- wmmps_ac = psta->uapsd_vo & BIT(0);
- break;
- case 0:
- case 3:
- default:
- wmmps_ac = psta->uapsd_be & BIT(0);
- break;
- }
-
- if (wmmps_ac)
- psta->sleepq_ac_len++;
-
- if (((psta->has_legacy_ac) && (!wmmps_ac)) ||
- ((!psta->has_legacy_ac) && (wmmps_ac))) {
- pstapriv->tim_bitmap |= CHKBIT(psta->aid);
-
- if (psta->sleepq_len == 1) {
- /* update BCN for TIM IE */
- update_beacon23a(padapter, WLAN_EID_TIM,
- NULL, false);
- }
- }
-
- /* spin_unlock_bh(&psta->sleep_q.lock); */
-
- /* if (psta->sleepq_len > (NR_XMITFRAME>>3)) */
- /* */
- /* wakeup_sta_to_xmit23a(padapter, psta); */
- /* */
-
- ret = true;
-
- }
-
- }
-
- spin_unlock_bh(&psta->sleep_q.lock);
-
- return ret;
-}
-
-static void
-dequeue_xmitframes_to_sleeping_queue(struct rtw_adapter *padapter,
- struct sta_info *psta,
- struct rtw_queue *pframequeue)
-{
- int ret;
- struct list_head *phead;
- u8 ac_index;
- struct tx_servq *ptxservq;
- struct pkt_attrib *pattrib;
- struct xmit_frame *pxmitframe, *ptmp;
- struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
-
- phead = get_list_head(pframequeue);
- list_for_each_entry_safe(pxmitframe, ptmp, phead, list) {
- ret = xmitframe_enqueue_for_sleeping_sta23a(padapter, pxmitframe);
-
- if (ret == true) {
- pattrib = &pxmitframe->attrib;
-
- ptxservq = rtw_get_sta_pending23a(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
-
- ptxservq->qcnt--;
- phwxmits[ac_index].accnt--;
- } else {
- /* DBG_8723A("xmitframe_enqueue_for_sleeping_sta23a return false\n"); */
- }
- }
-}
-
-void stop_sta_xmit23a(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- struct sta_info *psta_bmc;
- struct sta_xmit_priv *pstaxmitpriv;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- pstaxmitpriv = &psta->sta_xmitpriv;
-
- /* for BC/MC Frames */
- psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
-
- spin_lock_bh(&pxmitpriv->lock);
-
- psta->state |= WIFI_SLEEP_STATE;
-
- pstapriv->sta_dz_bitmap |= CHKBIT(psta->aid);
-
- dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
- list_del_init(&pstaxmitpriv->vo_q.tx_pending);
-
- dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
- list_del_init(&pstaxmitpriv->vi_q.tx_pending);
-
- dequeue_xmitframes_to_sleeping_queue(padapter, psta,
- &pstaxmitpriv->be_q.sta_pending);
- list_del_init(&pstaxmitpriv->be_q.tx_pending);
-
- dequeue_xmitframes_to_sleeping_queue(padapter, psta,
- &pstaxmitpriv->bk_q.sta_pending);
- list_del_init(&pstaxmitpriv->bk_q.tx_pending);
-
- /* for BC/MC Frames */
- pstaxmitpriv = &psta_bmc->sta_xmitpriv;
- dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc,
- &pstaxmitpriv->be_q.sta_pending);
- list_del_init(&pstaxmitpriv->be_q.tx_pending);
-
- spin_unlock_bh(&pxmitpriv->lock);
-}
-
-void wakeup_sta_to_xmit23a(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- u8 update_mask = 0, wmmps_ac = 0;
- struct sta_info *psta_bmc;
- struct list_head *phead;
- struct xmit_frame *pxmitframe = NULL, *ptmp;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- spin_lock_bh(&pxmitpriv->lock);
- phead = get_list_head(&psta->sleep_q);
- list_for_each_entry_safe(pxmitframe, ptmp, phead, list) {
- list_del_init(&pxmitframe->list);
-
- switch (pxmitframe->attrib.priority) {
- case 1:
- case 2:
- wmmps_ac = psta->uapsd_bk & BIT(1);
- break;
- case 4:
- case 5:
- wmmps_ac = psta->uapsd_vi & BIT(1);
- break;
- case 6:
- case 7:
- wmmps_ac = psta->uapsd_vo & BIT(1);
- break;
- case 0:
- case 3:
- default:
- wmmps_ac = psta->uapsd_be & BIT(1);
- break;
- }
-
- psta->sleepq_len--;
- if (psta->sleepq_len > 0)
- pxmitframe->attrib.mdata = 1;
- else
- pxmitframe->attrib.mdata = 0;
-
- if (wmmps_ac) {
- psta->sleepq_ac_len--;
- if (psta->sleepq_ac_len > 0) {
- pxmitframe->attrib.mdata = 1;
- pxmitframe->attrib.eosp = 0;
- } else {
- pxmitframe->attrib.mdata = 0;
- pxmitframe->attrib.eosp = 1;
- }
- }
-
- pxmitframe->attrib.triggered = 1;
- rtl8723au_hal_xmitframe_enqueue(padapter, pxmitframe);
- }
-
- if (psta->sleepq_len == 0) {
- pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
-
- /* update BCN for TIM IE */
- update_mask = BIT(0);
-
- if (psta->state&WIFI_SLEEP_STATE)
- psta->state ^= WIFI_SLEEP_STATE;
-
- if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
- psta->expire_to = pstapriv->expire_to;
- psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
- }
-
- pstapriv->sta_dz_bitmap &= ~CHKBIT(psta->aid);
- }
- /* spin_unlock_bh(&psta->sleep_q.lock); */
- spin_unlock_bh(&pxmitpriv->lock);
-
- /* for BC/MC Frames */
- psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
- if (!psta_bmc)
- return;
-
- if ((pstapriv->sta_dz_bitmap&0xfffe) == 0x0) {
- /* no any sta in ps mode */
- spin_lock_bh(&pxmitpriv->lock);
- phead = get_list_head(&psta_bmc->sleep_q);
- list_for_each_entry_safe(pxmitframe, ptmp, phead, list) {
- list_del_init(&pxmitframe->list);
-
- psta_bmc->sleepq_len--;
- if (psta_bmc->sleepq_len > 0)
- pxmitframe->attrib.mdata = 1;
- else
- pxmitframe->attrib.mdata = 0;
-
- pxmitframe->attrib.triggered = 1;
- rtl8723au_hal_xmitframe_enqueue(padapter, pxmitframe);
- }
- if (psta_bmc->sleepq_len == 0) {
- pstapriv->tim_bitmap &= ~BIT(0);
- pstapriv->sta_dz_bitmap &= ~BIT(0);
-
- /* update BCN for TIM IE */
- /* update_BCNTIM(padapter); */
- update_mask |= BIT(1);
- }
- /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
- spin_unlock_bh(&pxmitpriv->lock);
- }
-
- if (update_mask)
- update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
-}
-
-void xmit_delivery_enabled_frames23a(struct rtw_adapter *padapter,
- struct sta_info *psta)
-{
- u8 wmmps_ac = 0;
- struct list_head *phead;
- struct xmit_frame *pxmitframe, *ptmp;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- /* spin_lock_bh(&psta->sleep_q.lock); */
- spin_lock_bh(&pxmitpriv->lock);
- phead = get_list_head(&psta->sleep_q);
- list_for_each_entry_safe(pxmitframe, ptmp, phead, list) {
- switch (pxmitframe->attrib.priority) {
- case 1:
- case 2:
- wmmps_ac = psta->uapsd_bk & BIT(1);
- break;
- case 4:
- case 5:
- wmmps_ac = psta->uapsd_vi & BIT(1);
- break;
- case 6:
- case 7:
- wmmps_ac = psta->uapsd_vo & BIT(1);
- break;
- case 0:
- case 3:
- default:
- wmmps_ac = psta->uapsd_be & BIT(1);
- break;
- }
-
- if (!wmmps_ac)
- continue;
-
- list_del_init(&pxmitframe->list);
-
- psta->sleepq_len--;
- psta->sleepq_ac_len--;
-
- if (psta->sleepq_ac_len > 0) {
- pxmitframe->attrib.mdata = 1;
- pxmitframe->attrib.eosp = 0;
- } else {
- pxmitframe->attrib.mdata = 0;
- pxmitframe->attrib.eosp = 1;
- }
-
- pxmitframe->attrib.triggered = 1;
-
- rtl8723au_hal_xmitframe_enqueue(padapter, pxmitframe);
-
- if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) &&
- (wmmps_ac)) {
- pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
-
- /* update BCN for TIM IE */
- update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
- }
- }
- spin_unlock_bh(&pxmitpriv->lock);
-}
-
-#endif
-
-void rtw_sctx_init23a(struct submit_ctx *sctx, int timeout_ms)
-{
- sctx->timeout_ms = timeout_ms;
- init_completion(&sctx->done);
- sctx->status = RTW_SCTX_SUBMITTED;
-}
-
-int rtw_sctx_wait23a(struct submit_ctx *sctx)
-{
- int ret = _FAIL;
- unsigned long expire;
- int status = 0;
-
- expire = sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) :
- MAX_SCHEDULE_TIMEOUT;
- if (!wait_for_completion_timeout(&sctx->done, expire)) {
- /* timeout, do something?? */
- status = RTW_SCTX_DONE_TIMEOUT;
- DBG_8723A("%s timeout\n", __func__);
- } else {
- status = sctx->status;
- }
-
- if (status == RTW_SCTX_DONE_SUCCESS)
- ret = _SUCCESS;
-
- return ret;
-}
-
-static bool rtw_sctx_chk_waring_status(int status)
-{
- switch (status) {
- case RTW_SCTX_DONE_UNKNOWN:
- case RTW_SCTX_DONE_BUF_ALLOC:
- case RTW_SCTX_DONE_BUF_FREE:
- case RTW_SCTX_DONE_DRV_STOP:
- case RTW_SCTX_DONE_DEV_REMOVE:
- return true;
- default:
- return false;
- }
-}
-
-void rtw23a_sctx_done_err(struct submit_ctx **sctx, int status)
-{
- if (*sctx) {
- if (rtw_sctx_chk_waring_status(status))
- DBG_8723A("%s status:%d\n", __func__, status);
- (*sctx)->status = status;
- complete(&(*sctx)->done);
- *sctx = NULL;
- }
-}
-
-int rtw_ack_tx_wait23a(struct xmit_priv *pxmitpriv, u32 timeout_ms)
-{
- struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
-
- pack_tx_ops->timeout_ms = timeout_ms;
- pack_tx_ops->status = RTW_SCTX_SUBMITTED;
-
- return rtw_sctx_wait23a(pack_tx_ops);
-}
-
diff --git a/drivers/staging/rtl8723au/hal/Hal8723PwrSeq.c b/drivers/staging/rtl8723au/hal/Hal8723PwrSeq.c
deleted file mode 100644
index 747f86cddeb9..000000000000
--- a/drivers/staging/rtl8723au/hal/Hal8723PwrSeq.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-#include "Hal8723PwrSeq.h"
-
-/*
- drivers should parse below arrays and do the corresponding actions
-*/
-/* 3 Power on Array */
-struct wlan_pwr_cfg rtl8723AU_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STEPS+RTL8723A_TRANS_END_STEPS] = {
- RTL8723A_TRANS_CARDEMU_TO_ACT
- RTL8723A_TRANS_END
-};
-
-/* 3 Radio off GPIO Array */
-struct wlan_pwr_cfg rtl8723AU_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_END_STEPS] = {
- RTL8723A_TRANS_ACT_TO_CARDEMU
- RTL8723A_TRANS_END
-};
-
-/* 3 Card Disable Array */
-struct wlan_pwr_cfg rtl8723AU_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723A_TRANS_END_STEPS] = {
- RTL8723A_TRANS_ACT_TO_CARDEMU
- RTL8723A_TRANS_CARDEMU_TO_CARDDIS
- RTL8723A_TRANS_END
-};
-
-/* 3 Card Enable Array */
-struct wlan_pwr_cfg rtl8723AU_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723A_TRANS_END_STEPS] = {
- RTL8723A_TRANS_CARDDIS_TO_CARDEMU
- RTL8723A_TRANS_CARDEMU_TO_ACT
- RTL8723A_TRANS_END
-};
-
-/* 3 Suspend Array */
-struct wlan_pwr_cfg rtl8723AU_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8723A_TRANS_END_STEPS] = {
- RTL8723A_TRANS_ACT_TO_CARDEMU
- RTL8723A_TRANS_CARDEMU_TO_SUS
- RTL8723A_TRANS_END
-};
-
-/* 3 Resume Array */
-struct wlan_pwr_cfg rtl8723AU_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8723A_TRANS_END_STEPS] = {
- RTL8723A_TRANS_SUS_TO_CARDEMU
- RTL8723A_TRANS_CARDEMU_TO_ACT
- RTL8723A_TRANS_END
-};
-
-/* 3 HWPDN Array */
-struct wlan_pwr_cfg rtl8723AU_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723A_TRANS_END_STEPS] = {
- RTL8723A_TRANS_ACT_TO_CARDEMU
- RTL8723A_TRANS_CARDEMU_TO_PDN
- RTL8723A_TRANS_END
-};
-
-/* 3 Enter LPS */
-struct wlan_pwr_cfg rtl8723AU_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STEPS+RTL8723A_TRANS_END_STEPS] = {
- /* FW behavior */
- RTL8723A_TRANS_ACT_TO_LPS
- RTL8723A_TRANS_END
-};
-
-/* 3 Leave LPS */
-struct wlan_pwr_cfg rtl8723AU_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STEPS+RTL8723A_TRANS_END_STEPS] = {
- /* FW behavior */
- RTL8723A_TRANS_LPS_TO_ACT
- RTL8723A_TRANS_END
-};
diff --git a/drivers/staging/rtl8723au/hal/Hal8723UHWImg_CE.c b/drivers/staging/rtl8723au/hal/Hal8723UHWImg_CE.c
deleted file mode 100644
index 56833da63ced..000000000000
--- a/drivers/staging/rtl8723au/hal/Hal8723UHWImg_CE.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-/*Created on 2013/01/14, 15:51*/
-#include "odm_precomp.h"
-
-u32 Rtl8723UPHY_REG_Array_PG[Rtl8723UPHY_REG_Array_PGLength] = {
- 0xe00, 0xffffffff, 0x0a0c0c0c,
- 0xe04, 0xffffffff, 0x02040608,
- 0xe08, 0x0000ff00, 0x00000000,
- 0x86c, 0xffffff00, 0x00000000,
- 0xe10, 0xffffffff, 0x0a0c0d0e,
- 0xe14, 0xffffffff, 0x02040608,
- 0xe18, 0xffffffff, 0x0a0c0d0e,
- 0xe1c, 0xffffffff, 0x02040608,
- 0x830, 0xffffffff, 0x0a0c0c0c,
- 0x834, 0xffffffff, 0x02040608,
- 0x838, 0xffffff00, 0x00000000,
- 0x86c, 0x000000ff, 0x00000000,
- 0x83c, 0xffffffff, 0x0a0c0d0e,
- 0x848, 0xffffffff, 0x02040608,
- 0x84c, 0xffffffff, 0x0a0c0d0e,
- 0x868, 0xffffffff, 0x02040608,
- 0xe00, 0xffffffff, 0x00000000,
- 0xe04, 0xffffffff, 0x00000000,
- 0xe08, 0x0000ff00, 0x00000000,
- 0x86c, 0xffffff00, 0x00000000,
- 0xe10, 0xffffffff, 0x00000000,
- 0xe14, 0xffffffff, 0x00000000,
- 0xe18, 0xffffffff, 0x00000000,
- 0xe1c, 0xffffffff, 0x00000000,
- 0x830, 0xffffffff, 0x00000000,
- 0x834, 0xffffffff, 0x00000000,
- 0x838, 0xffffff00, 0x00000000,
- 0x86c, 0x000000ff, 0x00000000,
- 0x83c, 0xffffffff, 0x00000000,
- 0x848, 0xffffffff, 0x00000000,
- 0x84c, 0xffffffff, 0x00000000,
- 0x868, 0xffffffff, 0x00000000,
- 0xe00, 0xffffffff, 0x04040404,
- 0xe04, 0xffffffff, 0x00020204,
- 0xe08, 0x0000ff00, 0x00000000,
- 0x86c, 0xffffff00, 0x00000000,
- 0xe10, 0xffffffff, 0x06060606,
- 0xe14, 0xffffffff, 0x00020406,
- 0xe18, 0xffffffff, 0x00000000,
- 0xe1c, 0xffffffff, 0x00000000,
- 0x830, 0xffffffff, 0x04040404,
- 0x834, 0xffffffff, 0x00020204,
- 0x838, 0xffffff00, 0x00000000,
- 0x86c, 0x000000ff, 0x00000000,
- 0x83c, 0xffffffff, 0x06060606,
- 0x848, 0xffffffff, 0x00020406,
- 0x84c, 0xffffffff, 0x00000000,
- 0x868, 0xffffffff, 0x00000000,
- 0xe00, 0xffffffff, 0x00000000,
- 0xe04, 0xffffffff, 0x00000000,
- 0xe08, 0x0000ff00, 0x00000000,
- 0x86c, 0xffffff00, 0x00000000,
- 0xe10, 0xffffffff, 0x00000000,
- 0xe14, 0xffffffff, 0x00000000,
- 0xe18, 0xffffffff, 0x00000000,
- 0xe1c, 0xffffffff, 0x00000000,
- 0x830, 0xffffffff, 0x00000000,
- 0x834, 0xffffffff, 0x00000000,
- 0x838, 0xffffff00, 0x00000000,
- 0x86c, 0x000000ff, 0x00000000,
- 0x83c, 0xffffffff, 0x00000000,
- 0x848, 0xffffffff, 0x00000000,
- 0x84c, 0xffffffff, 0x00000000,
- 0x868, 0xffffffff, 0x00000000,
- 0xe00, 0xffffffff, 0x00000000,
- 0xe04, 0xffffffff, 0x00000000,
- 0xe08, 0x0000ff00, 0x00000000,
- 0x86c, 0xffffff00, 0x00000000,
- 0xe10, 0xffffffff, 0x00000000,
- 0xe14, 0xffffffff, 0x00000000,
- 0xe18, 0xffffffff, 0x00000000,
- 0xe1c, 0xffffffff, 0x00000000,
- 0x830, 0xffffffff, 0x00000000,
- 0x834, 0xffffffff, 0x00000000,
- 0x838, 0xffffff00, 0x00000000,
- 0x86c, 0x000000ff, 0x00000000,
- 0x83c, 0xffffffff, 0x00000000,
- 0x848, 0xffffffff, 0x00000000,
- 0x84c, 0xffffffff, 0x00000000,
- 0x868, 0xffffffff, 0x00000000,
- 0xe00, 0xffffffff, 0x04040404,
- 0xe04, 0xffffffff, 0x00020204,
- 0xe08, 0x0000ff00, 0x00000000,
- 0x86c, 0xffffff00, 0x00000000,
- 0xe10, 0xffffffff, 0x00000000,
- 0xe14, 0xffffffff, 0x00000000,
- 0xe18, 0xffffffff, 0x00000000,
- 0xe1c, 0xffffffff, 0x00000000,
- 0x830, 0xffffffff, 0x04040404,
- 0x834, 0xffffffff, 0x00020204,
- 0x838, 0xffffff00, 0x00000000,
- 0x86c, 0x000000ff, 0x00000000,
- 0x83c, 0xffffffff, 0x00000000,
- 0x848, 0xffffffff, 0x00000000,
- 0x84c, 0xffffffff, 0x00000000,
- 0x868, 0xffffffff, 0x00000000,
- 0xe00, 0xffffffff, 0x00000000,
- 0xe04, 0xffffffff, 0x00000000,
- 0xe08, 0x0000ff00, 0x00000000,
- 0x86c, 0xffffff00, 0x00000000,
- 0xe10, 0xffffffff, 0x00000000,
- 0xe14, 0xffffffff, 0x00000000,
- 0xe18, 0xffffffff, 0x00000000,
- 0xe1c, 0xffffffff, 0x00000000,
- 0x830, 0xffffffff, 0x00000000,
- 0x834, 0xffffffff, 0x00000000,
- 0x838, 0xffffff00, 0x00000000,
- 0x86c, 0x000000ff, 0x00000000,
- 0x83c, 0xffffffff, 0x00000000,
- 0x848, 0xffffffff, 0x00000000,
- 0x84c, 0xffffffff, 0x00000000,
- 0x868, 0xffffffff, 0x00000000,
- };
-
-u32 Rtl8723UMACPHY_Array_PG[Rtl8723UMACPHY_Array_PGLength] = {
- 0x0,
-};
diff --git a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c
deleted file mode 100644
index 3f9ec9e00e16..000000000000
--- a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c
+++ /dev/null
@@ -1,1097 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-/* Description: */
-/* This file is for 92CE/92CU dynamic mechanism only */
-
-/* include files */
-
-#include "odm_precomp.h"
-#include <usb_ops_linux.h>
-
-#define DPK_DELTA_MAPPING_NUM 13
-#define index_mapping_HP_NUM 15
-/* 091212 chiyokolin */
-static void
-odm_TXPowerTrackingCallback_ThermalMeter_92C(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
- u8 ThermalValue = 0, delta, delta_LCK, delta_IQK, delta_HP;
- int ele_A, ele_D, TempCCk, X, value32;
- int Y, ele_C;
- s8 OFDM_index[2], CCK_index = 0, OFDM_index_old[2] = {0};
- s8 CCK_index_old = 0;
- int i = 0;
- u8 OFDM_min_index = 6, rf; /* OFDM BB Swing should be less than +3.0dB*/
- u8 ThermalValue_HP_count = 0;
- u32 ThermalValue_HP = 0;
- s32 index_mapping_HP[index_mapping_HP_NUM] = {
- 0, 1, 3, 4, 6,
- 7, 9, 10, 12, 13,
- 15, 16, 18, 19, 21
- };
- s8 index_HP;
-
- pdmpriv->TXPowerTrackingCallbackCnt++; /* cosa add for debug */
- pdmpriv->bTXPowerTrackingInit = true;
-
- if (pHalData->CurrentChannel == 14 && !pdmpriv->bCCKinCH14)
- pdmpriv->bCCKinCH14 = true;
- else if (pHalData->CurrentChannel != 14 && pdmpriv->bCCKinCH14)
- pdmpriv->bCCKinCH14 = false;
-
- ThermalValue = (u8)PHY_QueryRFReg(Adapter, RF_PATH_A, RF_T_METER,
- 0x1f);/* 0x24: RF Reg[4:0] */
-
- rtl8723a_phy_ap_calibrate(Adapter, (ThermalValue -
- pHalData->EEPROMThermalMeter));
-
- if (pHalData->rf_type == RF_2T2R)
- rf = 2;
- else
- rf = 1;
-
- if (ThermalValue) {
- /* Query OFDM path A default setting */
- ele_D = rtl8723au_read32(Adapter, rOFDM0_XATxIQImbalance) &
- bMaskOFDM_D;
- for (i = 0; i < OFDM_TABLE_SIZE_92C; i++) {
- /* find the index */
- if (ele_D == (OFDMSwingTable23A[i]&bMaskOFDM_D)) {
- OFDM_index_old[0] = (u8)i;
- break;
- }
- }
-
- /* Query OFDM path B default setting */
- if (pHalData->rf_type == RF_2T2R) {
- ele_D = rtl8723au_read32(Adapter,
- rOFDM0_XBTxIQImbalance);
- ele_D &= bMaskOFDM_D;
- for (i = 0; i < OFDM_TABLE_SIZE_92C; i++) { /* find the index */
- if (ele_D == (OFDMSwingTable23A[i]&bMaskOFDM_D)) {
- OFDM_index_old[1] = (u8)i;
- break;
- }
- }
- }
-
- /* Query CCK default setting From 0xa24 */
- TempCCk = rtl8723au_read32(Adapter, rCCK0_TxFilter2) & bMaskCCK;
- for (i = 0 ; i < CCK_TABLE_SIZE ; i++) {
- if (pdmpriv->bCCKinCH14) {
- if (!memcmp(&TempCCk,
- &CCKSwingTable_Ch1423A[i][2], 4)) {
- CCK_index_old = (u8)i;
- break;
- }
- } else {
- if (!memcmp(&TempCCk,
- &CCKSwingTable_Ch1_Ch1323A[i][2], 4)) {
- CCK_index_old = (u8)i;
- break;
- }
- }
- }
-
- if (!pdmpriv->ThermalValue) {
- pdmpriv->ThermalValue = pHalData->EEPROMThermalMeter;
- pdmpriv->ThermalValue_LCK = ThermalValue;
- pdmpriv->ThermalValue_IQK = ThermalValue;
- pdmpriv->ThermalValue_DPK = pHalData->EEPROMThermalMeter;
-
- for (i = 0; i < rf; i++) {
- pdmpriv->OFDM_index_HP[i] = OFDM_index_old[i];
- pdmpriv->OFDM_index[i] = OFDM_index_old[i];
- }
- pdmpriv->CCK_index_HP = CCK_index_old;
- pdmpriv->CCK_index = CCK_index_old;
- }
-
- if (pHalData->BoardType == BOARD_USB_High_PA) {
- pdmpriv->ThermalValue_HP[pdmpriv->ThermalValue_HP_index] = ThermalValue;
- pdmpriv->ThermalValue_HP_index++;
- if (pdmpriv->ThermalValue_HP_index == HP_THERMAL_NUM)
- pdmpriv->ThermalValue_HP_index = 0;
-
- for (i = 0; i < HP_THERMAL_NUM; i++) {
- if (pdmpriv->ThermalValue_HP[i]) {
- ThermalValue_HP += pdmpriv->ThermalValue_HP[i];
- ThermalValue_HP_count++;
- }
- }
-
- if (ThermalValue_HP_count)
- ThermalValue = (u8)(ThermalValue_HP / ThermalValue_HP_count);
- }
-
- delta = (ThermalValue > pdmpriv->ThermalValue) ?
- (ThermalValue - pdmpriv->ThermalValue) :
- (pdmpriv->ThermalValue - ThermalValue);
- if (pHalData->BoardType == BOARD_USB_High_PA) {
- if (pdmpriv->bDoneTxpower)
- delta_HP = (ThermalValue > pdmpriv->ThermalValue) ?
- (ThermalValue - pdmpriv->ThermalValue) :
- (pdmpriv->ThermalValue - ThermalValue);
- else
- delta_HP = ThermalValue > pHalData->EEPROMThermalMeter ?
- (ThermalValue - pHalData->EEPROMThermalMeter) :
- (pHalData->EEPROMThermalMeter - ThermalValue);
- } else {
- delta_HP = 0;
- }
- delta_LCK = (ThermalValue > pdmpriv->ThermalValue_LCK) ?
- (ThermalValue - pdmpriv->ThermalValue_LCK) :
- (pdmpriv->ThermalValue_LCK - ThermalValue);
- delta_IQK = (ThermalValue > pdmpriv->ThermalValue_IQK) ?
- (ThermalValue - pdmpriv->ThermalValue_IQK) :
- (pdmpriv->ThermalValue_IQK - ThermalValue);
-
- if (delta_LCK > 1) {
- pdmpriv->ThermalValue_LCK = ThermalValue;
- rtl8723a_phy_lc_calibrate(Adapter);
- }
-
- if ((delta > 0 || delta_HP > 0) && pdmpriv->TxPowerTrackControl) {
- if (pHalData->BoardType == BOARD_USB_High_PA) {
- pdmpriv->bDoneTxpower = true;
- delta_HP = ThermalValue > pHalData->EEPROMThermalMeter ?
- (ThermalValue - pHalData->EEPROMThermalMeter) :
- (pHalData->EEPROMThermalMeter - ThermalValue);
-
- if (delta_HP > index_mapping_HP_NUM-1)
- index_HP = index_mapping_HP[index_mapping_HP_NUM-1];
- else
- index_HP = index_mapping_HP[delta_HP];
-
- if (ThermalValue > pHalData->EEPROMThermalMeter) {
- /* set larger Tx power */
- for (i = 0; i < rf; i++)
- OFDM_index[i] = pdmpriv->OFDM_index_HP[i] - index_HP;
- CCK_index = pdmpriv->CCK_index_HP - index_HP;
- } else {
- for (i = 0; i < rf; i++)
- OFDM_index[i] = pdmpriv->OFDM_index_HP[i] + index_HP;
- CCK_index = pdmpriv->CCK_index_HP + index_HP;
- }
-
- delta_HP = (ThermalValue > pdmpriv->ThermalValue) ?
- (ThermalValue - pdmpriv->ThermalValue) :
- (pdmpriv->ThermalValue - ThermalValue);
- } else {
- if (ThermalValue > pdmpriv->ThermalValue) {
- for (i = 0; i < rf; i++)
- pdmpriv->OFDM_index[i] -= delta;
- pdmpriv->CCK_index -= delta;
- } else {
- for (i = 0; i < rf; i++)
- pdmpriv->OFDM_index[i] += delta;
- pdmpriv->CCK_index += delta;
- }
- }
-
- /* no adjust */
- if (pHalData->BoardType != BOARD_USB_High_PA) {
- if (ThermalValue > pHalData->EEPROMThermalMeter) {
- for (i = 0; i < rf; i++)
- OFDM_index[i] = pdmpriv->OFDM_index[i]+1;
- CCK_index = pdmpriv->CCK_index+1;
- } else {
- for (i = 0; i < rf; i++)
- OFDM_index[i] = pdmpriv->OFDM_index[i];
- CCK_index = pdmpriv->CCK_index;
- }
- }
- for (i = 0; i < rf; i++) {
- if (OFDM_index[i] > (OFDM_TABLE_SIZE_92C-1))
- OFDM_index[i] = (OFDM_TABLE_SIZE_92C-1);
- else if (OFDM_index[i] < OFDM_min_index)
- OFDM_index[i] = OFDM_min_index;
- }
-
- if (CCK_index > (CCK_TABLE_SIZE-1))
- CCK_index = CCK_TABLE_SIZE-1;
- else if (CCK_index < 0)
- CCK_index = 0;
- }
-
- if (pdmpriv->TxPowerTrackControl &&
- (delta != 0 || delta_HP != 0)) {
- /* Adujst OFDM Ant_A according to IQK result */
- ele_D = (OFDMSwingTable23A[OFDM_index[0]] & 0xFFC00000)>>22;
- X = pdmpriv->RegE94;
- Y = pdmpriv->RegE9C;
-
- if (X != 0) {
- if ((X & 0x00000200) != 0)
- X = X | 0xFFFFFC00;
- ele_A = ((X * ele_D)>>8)&0x000003FF;
-
- /* new element C = element D x Y */
- if ((Y & 0x00000200) != 0)
- Y = Y | 0xFFFFFC00;
- ele_C = ((Y * ele_D)>>8)&0x000003FF;
-
- /* write new elements A, C, D to regC80 and regC94, element B is always 0 */
- value32 = (ele_D<<22)|((ele_C&0x3F)<<16)|ele_A;
- rtl8723au_write32(Adapter,
- rOFDM0_XATxIQImbalance,
- value32);
-
- value32 = (ele_C&0x000003C0)>>6;
- PHY_SetBBReg(Adapter, rOFDM0_XCTxAFE, bMaskH4Bits, value32);
-
- value32 = ((X * ele_D)>>7)&0x01;
- PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold,
- BIT(31), value32);
-
- value32 = ((Y * ele_D)>>7)&0x01;
- PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold,
- BIT(29), value32);
- } else {
- rtl8723au_write32(Adapter,
- rOFDM0_XATxIQImbalance,
- OFDMSwingTable23A[OFDM_index[0]]);
- PHY_SetBBReg(Adapter, rOFDM0_XCTxAFE,
- bMaskH4Bits, 0x00);
- PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold,
- BIT(31) | BIT(29), 0x00);
- }
-
- /* Adjust CCK according to IQK result */
- if (!pdmpriv->bCCKinCH14) {
- rtl8723au_write8(Adapter, 0xa22, CCKSwingTable_Ch1_Ch1323A[CCK_index][0]);
- rtl8723au_write8(Adapter, 0xa23, CCKSwingTable_Ch1_Ch1323A[CCK_index][1]);
- rtl8723au_write8(Adapter, 0xa24, CCKSwingTable_Ch1_Ch1323A[CCK_index][2]);
- rtl8723au_write8(Adapter, 0xa25, CCKSwingTable_Ch1_Ch1323A[CCK_index][3]);
- rtl8723au_write8(Adapter, 0xa26, CCKSwingTable_Ch1_Ch1323A[CCK_index][4]);
- rtl8723au_write8(Adapter, 0xa27, CCKSwingTable_Ch1_Ch1323A[CCK_index][5]);
- rtl8723au_write8(Adapter, 0xa28, CCKSwingTable_Ch1_Ch1323A[CCK_index][6]);
- rtl8723au_write8(Adapter, 0xa29, CCKSwingTable_Ch1_Ch1323A[CCK_index][7]);
- } else {
- rtl8723au_write8(Adapter, 0xa22, CCKSwingTable_Ch1423A[CCK_index][0]);
- rtl8723au_write8(Adapter, 0xa23, CCKSwingTable_Ch1423A[CCK_index][1]);
- rtl8723au_write8(Adapter, 0xa24, CCKSwingTable_Ch1423A[CCK_index][2]);
- rtl8723au_write8(Adapter, 0xa25, CCKSwingTable_Ch1423A[CCK_index][3]);
- rtl8723au_write8(Adapter, 0xa26, CCKSwingTable_Ch1423A[CCK_index][4]);
- rtl8723au_write8(Adapter, 0xa27, CCKSwingTable_Ch1423A[CCK_index][5]);
- rtl8723au_write8(Adapter, 0xa28, CCKSwingTable_Ch1423A[CCK_index][6]);
- rtl8723au_write8(Adapter, 0xa29, CCKSwingTable_Ch1423A[CCK_index][7]);
- }
-
- if (pHalData->rf_type == RF_2T2R) {
- ele_D = (OFDMSwingTable23A[(u8)OFDM_index[1]] & 0xFFC00000)>>22;
-
- /* new element A = element D x X */
- X = pdmpriv->RegEB4;
- Y = pdmpriv->RegEBC;
-
- if (X != 0) {
- if ((X & 0x00000200) != 0) /* consider minus */
- X = X | 0xFFFFFC00;
- ele_A = ((X * ele_D)>>8)&0x000003FF;
-
- /* new element C = element D x Y */
- if ((Y & 0x00000200) != 0)
- Y = Y | 0xFFFFFC00;
- ele_C = ((Y * ele_D)>>8)&0x00003FF;
-
- /* write new elements A, C, D to regC88 and regC9C, element B is always 0 */
- value32 = (ele_D<<22)|((ele_C&0x3F)<<16) | ele_A;
- rtl8723au_write32(Adapter, rOFDM0_XBTxIQImbalance, value32);
-
- value32 = (ele_C&0x000003C0)>>6;
- PHY_SetBBReg(Adapter, rOFDM0_XDTxAFE, bMaskH4Bits, value32);
-
- value32 = ((X * ele_D)>>7)&0x01;
- PHY_SetBBReg(Adapter,
- rOFDM0_ECCAThreshold,
- BIT(27), value32);
-
- value32 = ((Y * ele_D)>>7)&0x01;
- PHY_SetBBReg(Adapter,
- rOFDM0_ECCAThreshold,
- BIT(25), value32);
- } else {
- rtl8723au_write32(Adapter,
- rOFDM0_XBTxIQImbalance,
- OFDMSwingTable23A[OFDM_index[1]]);
- PHY_SetBBReg(Adapter,
- rOFDM0_XDTxAFE,
- bMaskH4Bits, 0x00);
- PHY_SetBBReg(Adapter,
- rOFDM0_ECCAThreshold,
- BIT(27) | BIT(25), 0x00);
- }
- }
-
- }
- if (delta_IQK > 3) {
- pdmpriv->ThermalValue_IQK = ThermalValue;
- rtl8723a_phy_iq_calibrate(Adapter, false);
- }
-
- /* update thermal meter value */
- if (pdmpriv->TxPowerTrackControl)
- pdmpriv->ThermalValue = ThermalValue;
- }
- pdmpriv->TXPowercount = 0;
-}
-
-/* Description: */
-/* - Dispatch TxPower Tracking direct call ONLY for 92s. */
-/* - We shall NOT schedule Workitem within PASSIVE LEVEL, which will cause system resource */
-/* leakage under some platform. */
-/* Assumption: */
-/* PASSIVE_LEVEL when this routine is called. */
-static void ODM_TXPowerTracking92CDirectCall(struct rtw_adapter *Adapter)
-{
- odm_TXPowerTrackingCallback_ThermalMeter_92C(Adapter);
-}
-
-void rtl8723a_odm_check_tx_power_tracking(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
-
- if (!pdmpriv->TM_Trigger) { /* at least delay 1 sec */
- PHY_SetRFReg(Adapter, RF_PATH_A, RF_T_METER, bRFRegOffsetMask, 0x60);
-
- pdmpriv->TM_Trigger = 1;
- return;
- } else {
- ODM_TXPowerTracking92CDirectCall(Adapter);
- pdmpriv->TM_Trigger = 0;
- }
-}
-
-/* IQK */
-#define MAX_TOLERANCE 5
-#define IQK_DELAY_TIME 1 /* ms */
-
-static u8 _PHY_PathA_IQK(struct rtw_adapter *pAdapter, bool configPathB)
-{
- u32 regEAC, regE94, regE9C, regEA4;
- u8 result = 0x00;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
-
- /* path-A IQK setting */
- rtl8723au_write32(pAdapter, rTx_IQK_Tone_A, 0x10008c1f);
- rtl8723au_write32(pAdapter, rRx_IQK_Tone_A, 0x10008c1f);
- rtl8723au_write32(pAdapter, rTx_IQK_PI_A, 0x82140102);
-
- rtl8723au_write32(pAdapter, rRx_IQK_PI_A, configPathB ? 0x28160202 :
- IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)?0x28160202:0x28160502);
-
- /* path-B IQK setting */
- if (configPathB) {
- rtl8723au_write32(pAdapter, rTx_IQK_Tone_B, 0x10008c22);
- rtl8723au_write32(pAdapter, rRx_IQK_Tone_B, 0x10008c22);
- rtl8723au_write32(pAdapter, rTx_IQK_PI_B, 0x82140102);
- rtl8723au_write32(pAdapter, rRx_IQK_PI_B, 0x28160202);
- }
-
- /* LO calibration setting */
- rtl8723au_write32(pAdapter, rIQK_AGC_Rsp, 0x001028d1);
-
- /* One shot, path A LOK & IQK */
- rtl8723au_write32(pAdapter, rIQK_AGC_Pts, 0xf9000000);
- rtl8723au_write32(pAdapter, rIQK_AGC_Pts, 0xf8000000);
-
- /* delay x ms */
- /* PlatformStallExecution(IQK_DELAY_TIME*1000); */
- udelay(IQK_DELAY_TIME*1000);
-
- /* Check failed */
- regEAC = rtl8723au_read32(pAdapter, rRx_Power_After_IQK_A_2);
- regE94 = rtl8723au_read32(pAdapter, rTx_Power_Before_IQK_A);
- regE9C = rtl8723au_read32(pAdapter, rTx_Power_After_IQK_A);
- regEA4 = rtl8723au_read32(pAdapter, rRx_Power_Before_IQK_A_2);
-
- if (!(regEAC & BIT(28)) &&
- (((regE94 & 0x03FF0000)>>16) != 0x142) &&
- (((regE9C & 0x03FF0000)>>16) != 0x42))
- result |= 0x01;
- else /* if Tx not OK, ignore Rx */
- return result;
-
- if (!(regEAC & BIT(27)) && /* if Tx is OK, check whether Rx is OK */
- (((regEA4 & 0x03FF0000)>>16) != 0x132) &&
- (((regEAC & 0x03FF0000)>>16) != 0x36))
- result |= 0x02;
- else
- DBG_8723A("Path A Rx IQK fail!!\n");
- return result;
-}
-
-static u8 _PHY_PathB_IQK(struct rtw_adapter *pAdapter)
-{
- u32 regEAC, regEB4, regEBC, regEC4, regECC;
- u8 result = 0x00;
-
- /* One shot, path B LOK & IQK */
- rtl8723au_write32(pAdapter, rIQK_AGC_Cont, 0x00000002);
- rtl8723au_write32(pAdapter, rIQK_AGC_Cont, 0x00000000);
-
- /* delay x ms */
- udelay(IQK_DELAY_TIME*1000);
-
- /* Check failed */
- regEAC = rtl8723au_read32(pAdapter, rRx_Power_After_IQK_A_2);
- regEB4 = rtl8723au_read32(pAdapter, rTx_Power_Before_IQK_B);
- regEBC = rtl8723au_read32(pAdapter, rTx_Power_After_IQK_B);
- regEC4 = rtl8723au_read32(pAdapter, rRx_Power_Before_IQK_B_2);
- regECC = rtl8723au_read32(pAdapter, rRx_Power_After_IQK_B_2);
-
- if (!(regEAC & BIT(31)) &&
- (((regEB4 & 0x03FF0000)>>16) != 0x142) &&
- (((regEBC & 0x03FF0000)>>16) != 0x42))
- result |= 0x01;
- else
- return result;
-
- if (!(regEAC & BIT(30)) &&
- (((regEC4 & 0x03FF0000)>>16) != 0x132) &&
- (((regECC & 0x03FF0000)>>16) != 0x36))
- result |= 0x02;
- else
- DBG_8723A("Path B Rx IQK fail!!\n");
- return result;
-}
-
-static void _PHY_PathAFillIQKMatrix(struct rtw_adapter *pAdapter,
- bool bIQKOK,
- int result[][8],
- u8 final_candidate,
- bool bTxOnly
- )
-{
- u32 Oldval_0, X, TX0_A, reg;
- s32 Y, TX0_C;
-
- DBG_8723A("Path A IQ Calibration %s !\n", (bIQKOK)?"Success":"Failed");
-
- if (final_candidate == 0xFF) {
- return;
- } else if (bIQKOK) {
- Oldval_0 = rtl8723au_read32(pAdapter, rOFDM0_XATxIQImbalance);
- Oldval_0 = (Oldval_0 >> 22) & 0x3FF;
-
- X = result[final_candidate][0];
- if ((X & 0x00000200) != 0)
- X = X | 0xFFFFFC00;
- TX0_A = (X * Oldval_0) >> 8;
- PHY_SetBBReg(pAdapter, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A);
- PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(31),
- ((X * Oldval_0>>7) & 0x1));
-
- Y = result[final_candidate][1];
- if ((Y & 0x00000200) != 0)
- Y = Y | 0xFFFFFC00;
- TX0_C = (Y * Oldval_0) >> 8;
- PHY_SetBBReg(pAdapter, rOFDM0_XCTxAFE, 0xF0000000,
- ((TX0_C&0x3C0)>>6));
- PHY_SetBBReg(pAdapter, rOFDM0_XATxIQImbalance, 0x003F0000,
- (TX0_C&0x3F));
- PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(29),
- ((Y * Oldval_0>>7) & 0x1));
-
- if (bTxOnly) {
- DBG_8723A("_PHY_PathAFillIQKMatrix only Tx OK\n");
- return;
- }
-
- reg = result[final_candidate][2];
- PHY_SetBBReg(pAdapter, rOFDM0_XARxIQImbalance, 0x3FF, reg);
-
- reg = result[final_candidate][3] & 0x3F;
- PHY_SetBBReg(pAdapter, rOFDM0_XARxIQImbalance, 0xFC00, reg);
-
- reg = (result[final_candidate][3] >> 6) & 0xF;
- PHY_SetBBReg(pAdapter, rOFDM0_RxIQExtAnta, 0xF0000000, reg);
- }
-}
-
-static void _PHY_PathBFillIQKMatrix(struct rtw_adapter *pAdapter, bool bIQKOK, int result[][8], u8 final_candidate, bool bTxOnly)
-{
- u32 Oldval_1, X, TX1_A, reg;
- s32 Y, TX1_C;
-
- DBG_8723A("Path B IQ Calibration %s !\n", (bIQKOK)?"Success":"Failed");
-
- if (final_candidate == 0xFF) {
- return;
- } else if (bIQKOK) {
- Oldval_1 = rtl8723au_read32(pAdapter, rOFDM0_XBTxIQImbalance);
- Oldval_1 = (Oldval_1 >> 22) & 0x3FF;
-
- X = result[final_candidate][4];
- if ((X & 0x00000200) != 0)
- X = X | 0xFFFFFC00;
- TX1_A = (X * Oldval_1) >> 8;
- PHY_SetBBReg(pAdapter, rOFDM0_XBTxIQImbalance, 0x3FF, TX1_A);
- PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(27),
- ((X * Oldval_1 >> 7) & 0x1));
-
- Y = result[final_candidate][5];
- if ((Y & 0x00000200) != 0)
- Y = Y | 0xFFFFFC00;
- TX1_C = (Y * Oldval_1) >> 8;
- PHY_SetBBReg(pAdapter, rOFDM0_XDTxAFE, 0xF0000000,
- ((TX1_C & 0x3C0) >> 6));
- PHY_SetBBReg(pAdapter, rOFDM0_XBTxIQImbalance, 0x003F0000,
- (TX1_C & 0x3F));
- PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(25),
- ((Y * Oldval_1 >> 7) & 0x1));
-
- if (bTxOnly)
- return;
-
- reg = result[final_candidate][6];
- PHY_SetBBReg(pAdapter, rOFDM0_XBRxIQImbalance, 0x3FF, reg);
-
- reg = result[final_candidate][7] & 0x3F;
- PHY_SetBBReg(pAdapter, rOFDM0_XBRxIQImbalance, 0xFC00, reg);
-
- reg = (result[final_candidate][7] >> 6) & 0xF;
- PHY_SetBBReg(pAdapter, rOFDM0_AGCRSSITable, 0x0000F000, reg);
- }
-}
-
-static void _PHY_SaveADDARegisters(struct rtw_adapter *pAdapter, u32 *ADDAReg, u32 *ADDABackup, u32 RegisterNum)
-{
- u32 i;
-
- for (i = 0 ; i < RegisterNum ; i++) {
- ADDABackup[i] = rtl8723au_read32(pAdapter, ADDAReg[i]);
- }
-}
-
-static void _PHY_SaveMACRegisters(struct rtw_adapter *pAdapter, u32 *MACReg,
- u32 *MACBackup)
-{
- u32 i;
-
- for (i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++) {
- MACBackup[i] = rtl8723au_read8(pAdapter, MACReg[i]);
- }
- MACBackup[i] = rtl8723au_read32(pAdapter, MACReg[i]);
-}
-
-static void _PHY_ReloadADDARegisters(struct rtw_adapter *pAdapter,
- u32 *ADDAReg, u32 *ADDABackup,
- u32 RegiesterNum)
-{
- u32 i;
-
- for (i = 0 ; i < RegiesterNum ; i++) {
- rtl8723au_write32(pAdapter, ADDAReg[i], ADDABackup[i]);
- }
-}
-
-static void _PHY_ReloadMACRegisters(struct rtw_adapter *pAdapter,
- u32 *MACReg, u32 *MACBackup)
-{
- u32 i;
-
- for (i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++)
- rtl8723au_write8(pAdapter, MACReg[i], (u8)MACBackup[i]);
-
- rtl8723au_write32(pAdapter, MACReg[i], MACBackup[i]);
-}
-
-static void _PHY_PathADDAOn(struct rtw_adapter *pAdapter, u32 *ADDAReg,
- bool isPathAOn, bool is2T)
-{
- u32 pathOn;
- u32 i;
-
- pathOn = isPathAOn ? 0x04db25a4 : 0x0b1b25a4;
- if (!is2T) {
- pathOn = 0x0bdb25a0;
- rtl8723au_write32(pAdapter, ADDAReg[0], 0x0b1b25a0);
- } else {
- rtl8723au_write32(pAdapter, ADDAReg[0], pathOn);
- }
-
- for (i = 1 ; i < IQK_ADDA_REG_NUM ; i++)
- rtl8723au_write32(pAdapter, ADDAReg[i], pathOn);
-}
-
-static void _PHY_MACSettingCalibration(struct rtw_adapter *pAdapter,
- u32 *MACReg, u32 *MACBackup)
-{
- u32 i = 0;
-
- rtl8723au_write8(pAdapter, MACReg[i], 0x3F);
-
- for (i = 1 ; i < (IQK_MAC_REG_NUM - 1); i++) {
- rtl8723au_write8(pAdapter, MACReg[i],
- (u8)(MACBackup[i] & ~BIT(3)));
- }
- rtl8723au_write8(pAdapter, MACReg[i], (u8)(MACBackup[i] & ~BIT(5)));
-}
-
-static void _PHY_PathAStandBy(struct rtw_adapter *pAdapter)
-{
- rtl8723au_write32(pAdapter, rFPGA0_IQK, 0x0);
- rtl8723au_write32(pAdapter, 0x840, 0x00010000);
- rtl8723au_write32(pAdapter, rFPGA0_IQK, 0x80800000);
-}
-
-static void _PHY_PIModeSwitch(struct rtw_adapter *pAdapter, bool PIMode)
-{
- u32 mode;
-
- mode = PIMode ? 0x01000100 : 0x01000000;
- rtl8723au_write32(pAdapter, 0x820, mode);
- rtl8723au_write32(pAdapter, 0x828, mode);
-}
-
-/*
-return false => do IQK again
-*/
-static bool _PHY_SimularityCompare(struct rtw_adapter *pAdapter, int result[][8], u8 c1, u8 c2)
-{
- u32 i, j, diff, SimularityBitMap, bound = 0;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
- u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
- bool bResult = true;
-
- if (pHalData->rf_type == RF_2T2R)
- bound = 8;
- else
- bound = 4;
-
- SimularityBitMap = 0;
-
- for (i = 0; i < bound; i++) {
- diff = (result[c1][i] > result[c2][i]) ? (result[c1][i] - result[c2][i]) : (result[c2][i] - result[c1][i]);
- if (diff > MAX_TOLERANCE) {
- if ((i == 2 || i == 6) && !SimularityBitMap) {
- if (result[c1][i]+result[c1][i+1] == 0)
- final_candidate[(i/4)] = c2;
- else if (result[c2][i]+result[c2][i+1] == 0)
- final_candidate[(i/4)] = c1;
- else
- SimularityBitMap = SimularityBitMap|(1<<i);
- } else {
- SimularityBitMap = SimularityBitMap|(1<<i);
- }
- }
- }
-
- if (SimularityBitMap == 0) {
- for (i = 0; i < (bound/4); i++) {
- if (final_candidate[i] != 0xFF) {
- for (j = i*4; j < (i+1)*4-2; j++)
- result[3][j] = result[final_candidate[i]][j];
- bResult = false;
- }
- }
- return bResult;
- } else if (!(SimularityBitMap & 0x0F)) {
- /* path A OK */
- for (i = 0; i < 4; i++)
- result[3][i] = result[c1][i];
- return false;
- } else if (!(SimularityBitMap & 0xF0) && pHalData->rf_type == RF_2T2R) {
- /* path B OK */
- for (i = 4; i < 8; i++)
- result[3][i] = result[c1][i];
- return false;
- } else {
- return false;
- }
-}
-
-static void _PHY_IQCalibrate(struct rtw_adapter *pAdapter, int result[][8], u8 t, bool is2T)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
- u32 i;
- u8 PathAOK, PathBOK;
- u32 ADDA_REG[IQK_ADDA_REG_NUM] = {
- rFPGA0_XCD_SwitchControl, rBlue_Tooth,
- rRx_Wait_CCA, rTx_CCK_RFON,
- rTx_CCK_BBON, rTx_OFDM_RFON,
- rTx_OFDM_BBON, rTx_To_Rx,
- rTx_To_Tx, rRx_CCK,
- rRx_OFDM, rRx_Wait_RIFS,
- rRx_TO_Rx, rStandby,
- rSleep, rPMPD_ANAEN
- };
-
- u32 IQK_MAC_REG[IQK_MAC_REG_NUM] = {
- REG_TXPAUSE, REG_BCN_CTRL,
- REG_BCN_CTRL_1, REG_GPIO_MUXCFG
- };
-
- u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
- rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar,
- rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB,
- rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE,
- rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD
- };
-
- const u32 retryCount = 2;
-
- /* Note: IQ calibration must be performed after loading */
- /* PHY_REG.txt , and radio_a, radio_b.txt */
-
- u32 bbvalue;
-
- if (t == 0) {
- bbvalue = rtl8723au_read32(pAdapter, rFPGA0_RFMOD);
-
- /* Save ADDA parameters, turn Path A ADDA on */
- _PHY_SaveADDARegisters(pAdapter, ADDA_REG, pdmpriv->ADDA_backup, IQK_ADDA_REG_NUM);
- _PHY_SaveMACRegisters(pAdapter, IQK_MAC_REG, pdmpriv->IQK_MAC_backup);
- _PHY_SaveADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup, IQK_BB_REG_NUM);
- }
- _PHY_PathADDAOn(pAdapter, ADDA_REG, true, is2T);
-
- if (t == 0)
- pdmpriv->bRfPiEnable = (u8)
- PHY_QueryBBReg(pAdapter, rFPGA0_XA_HSSIParameter1,
- BIT(8));
-
- if (!pdmpriv->bRfPiEnable) {
- /* Switch BB to PI mode to do IQ Calibration. */
- _PHY_PIModeSwitch(pAdapter, true);
- }
-
- PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, BIT(24), 0x00);
- rtl8723au_write32(pAdapter, rOFDM0_TRxPathEnable, 0x03a05600);
- rtl8723au_write32(pAdapter, rOFDM0_TRMuxPar, 0x000800e4);
- rtl8723au_write32(pAdapter, rFPGA0_XCD_RFInterfaceSW, 0x22204000);
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0x01);
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0x01);
- PHY_SetBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, BIT(10), 0x00);
- PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT(10), 0x00);
-
- if (is2T) {
- rtl8723au_write32(pAdapter,
- rFPGA0_XA_LSSIParameter, 0x00010000);
- rtl8723au_write32(pAdapter,
- rFPGA0_XB_LSSIParameter, 0x00010000);
- }
-
- /* MAC settings */
- _PHY_MACSettingCalibration(pAdapter, IQK_MAC_REG, pdmpriv->IQK_MAC_backup);
-
- /* Page B init */
- rtl8723au_write32(pAdapter, rConfig_AntA, 0x00080000);
-
- if (is2T)
- rtl8723au_write32(pAdapter, rConfig_AntB, 0x00080000);
-
- /* IQ calibration setting */
- rtl8723au_write32(pAdapter, rFPGA0_IQK, 0x80800000);
- rtl8723au_write32(pAdapter, rTx_IQK, 0x01007c00);
- rtl8723au_write32(pAdapter, rRx_IQK, 0x01004800);
-
- for (i = 0 ; i < retryCount ; i++) {
- PathAOK = _PHY_PathA_IQK(pAdapter, is2T);
- if (PathAOK == 0x03) {
- DBG_8723A("Path A IQK Success!!\n");
- result[t][0] = (rtl8723au_read32(pAdapter, rTx_Power_Before_IQK_A)&0x3FF0000)>>16;
- result[t][1] = (rtl8723au_read32(pAdapter, rTx_Power_After_IQK_A)&0x3FF0000)>>16;
- result[t][2] = (rtl8723au_read32(pAdapter, rRx_Power_Before_IQK_A_2)&0x3FF0000)>>16;
- result[t][3] = (rtl8723au_read32(pAdapter, rRx_Power_After_IQK_A_2)&0x3FF0000)>>16;
- break;
- } else if (i == (retryCount-1) && PathAOK == 0x01) {
- /* Tx IQK OK */
- DBG_8723A("Path A IQK Only Tx Success!!\n");
-
- result[t][0] = (rtl8723au_read32(pAdapter, rTx_Power_Before_IQK_A)&0x3FF0000)>>16;
- result[t][1] = (rtl8723au_read32(pAdapter, rTx_Power_After_IQK_A)&0x3FF0000)>>16;
- }
- }
-
- if (0x00 == PathAOK) {
- DBG_8723A("Path A IQK failed!!\n");
- }
-
- if (is2T) {
- _PHY_PathAStandBy(pAdapter);
-
- /* Turn Path B ADDA on */
- _PHY_PathADDAOn(pAdapter, ADDA_REG, false, is2T);
-
- for (i = 0 ; i < retryCount ; i++) {
- PathBOK = _PHY_PathB_IQK(pAdapter);
- if (PathBOK == 0x03) {
- DBG_8723A("Path B IQK Success!!\n");
- result[t][4] = (rtl8723au_read32(pAdapter, rTx_Power_Before_IQK_B)&0x3FF0000)>>16;
- result[t][5] = (rtl8723au_read32(pAdapter, rTx_Power_After_IQK_B)&0x3FF0000)>>16;
- result[t][6] = (rtl8723au_read32(pAdapter, rRx_Power_Before_IQK_B_2)&0x3FF0000)>>16;
- result[t][7] = (rtl8723au_read32(pAdapter, rRx_Power_After_IQK_B_2)&0x3FF0000)>>16;
- break;
- } else if (i == (retryCount - 1) && PathBOK == 0x01) {
- /* Tx IQK OK */
- DBG_8723A("Path B Only Tx IQK Success!!\n");
- result[t][4] = (rtl8723au_read32(pAdapter, rTx_Power_Before_IQK_B)&0x3FF0000)>>16;
- result[t][5] = (rtl8723au_read32(pAdapter, rTx_Power_After_IQK_B)&0x3FF0000)>>16;
- }
- }
-
- if (0x00 == PathBOK) {
- DBG_8723A("Path B IQK failed!!\n");
- }
- }
-
- /* Back to BB mode, load original value */
- rtl8723au_write32(pAdapter, rFPGA0_IQK, 0);
-
- if (t != 0) {
- if (!pdmpriv->bRfPiEnable) {
- /* Switch back BB to SI mode after finish IQ Calibration. */
- _PHY_PIModeSwitch(pAdapter, false);
- }
-
- /* Reload ADDA power saving parameters */
- _PHY_ReloadADDARegisters(pAdapter, ADDA_REG, pdmpriv->ADDA_backup, IQK_ADDA_REG_NUM);
-
- /* Reload MAC parameters */
- _PHY_ReloadMACRegisters(pAdapter, IQK_MAC_REG, pdmpriv->IQK_MAC_backup);
-
- /* Reload BB parameters */
- _PHY_ReloadADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup, IQK_BB_REG_NUM);
-
- /* Restore RX initial gain */
- rtl8723au_write32(pAdapter,
- rFPGA0_XA_LSSIParameter, 0x00032ed3);
- if (is2T) {
- rtl8723au_write32(pAdapter,
- rFPGA0_XB_LSSIParameter, 0x00032ed3);
- }
-
- /* load 0xe30 IQC default value */
- rtl8723au_write32(pAdapter, rTx_IQK_Tone_A, 0x01008c00);
- rtl8723au_write32(pAdapter, rRx_IQK_Tone_A, 0x01008c00);
-
- }
-}
-
-static void _PHY_LCCalibrate(struct rtw_adapter *pAdapter, bool is2T)
-{
- u8 tmpReg;
- u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal;
-
- /* Check continuous TX and Packet TX */
- tmpReg = rtl8723au_read8(pAdapter, 0xd03);
-
- if ((tmpReg&0x70) != 0) {
- /* Deal with contisuous TX case */
- /* disable all continuous TX */
- rtl8723au_write8(pAdapter, 0xd03, tmpReg&0x8F);
- } else {
- /* Deal with Packet TX case */
- /* block all queues */
- rtl8723au_write8(pAdapter, REG_TXPAUSE, 0xFF);
- }
-
- if ((tmpReg&0x70) != 0) {
- /* 1. Read original RF mode */
- /* Path-A */
- RF_Amode = PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_AC, bMask12Bits);
-
- /* Path-B */
- if (is2T)
- RF_Bmode = PHY_QueryRFReg(pAdapter, RF_PATH_B, RF_AC, bMask12Bits);
-
- /* 2. Set RF mode = standby mode */
- /* Path-A */
- PHY_SetRFReg(pAdapter, RF_PATH_A, RF_AC, bMask12Bits, (RF_Amode&0x8FFFF)|0x10000);
-
- /* Path-B */
- if (is2T)
- PHY_SetRFReg(pAdapter, RF_PATH_B, RF_AC, bMask12Bits, (RF_Bmode&0x8FFFF)|0x10000);
- }
-
- /* 3. Read RF reg18 */
- LC_Cal = PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_CHNLBW, bMask12Bits);
-
- /* 4. Set LC calibration begin */
- PHY_SetRFReg(pAdapter, RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal|0x08000);
-
- msleep(100);
-
- /* Restore original situation */
- if ((tmpReg&0x70) != 0) { /* Deal with contuous TX case */
- /* Path-A */
- rtl8723au_write8(pAdapter, 0xd03, tmpReg);
- PHY_SetRFReg(pAdapter, RF_PATH_A, RF_AC, bMask12Bits, RF_Amode);
-
- /* Path-B */
- if (is2T)
- PHY_SetRFReg(pAdapter, RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode);
- } else /* Deal with Packet TX case */
- rtl8723au_write8(pAdapter, REG_TXPAUSE, 0x00);
-}
-
-/* Analog Pre-distortion calibration */
-#define APK_BB_REG_NUM 8
-#define APK_CURVE_REG_NUM 4
-#define PATH_NUM 2
-
-void rtl8723a_phy_iq_calibrate(struct rtw_adapter *pAdapter, bool bReCovery)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
- s32 result[4][8]; /* last is final result */
- u8 i, final_candidate;
- bool bPathAOK, bPathBOK;
- s32 RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4;
- s32 RegECC, RegTmp = 0;
- bool is12simular, is13simular, is23simular;
- bool bStartContTx = false, bSingleTone = false;
- bool bCarrierSuppression = false;
- u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = {
- rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance,
- rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable,
- rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance,
- rOFDM0_XCTxAFE, rOFDM0_XDTxAFE,
- rOFDM0_RxIQExtAnta
- };
-
- /* ignore IQK when continuous Tx */
- if (bStartContTx || bSingleTone || bCarrierSuppression)
- return;
-
- if (bReCovery) {
- _PHY_ReloadADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup_recover, 9);
- return;
- }
- DBG_8723A("IQK:Start!!!\n");
-
- for (i = 0; i < 8; i++) {
- result[0][i] = 0;
- result[1][i] = 0;
- result[2][i] = 0;
- result[3][i] = 0;
- }
- final_candidate = 0xff;
- bPathAOK = false;
- bPathBOK = false;
- is12simular = false;
- is23simular = false;
- is13simular = false;
-
- for (i = 0; i < 3; i++) {
- if (pHalData->rf_type == RF_2T2R)
- _PHY_IQCalibrate(pAdapter, result, i, true);
- else /* For 88C 1T1R */
- _PHY_IQCalibrate(pAdapter, result, i, false);
-
- if (i == 1) {
- is12simular = _PHY_SimularityCompare(pAdapter, result, 0, 1);
- if (is12simular) {
- final_candidate = 0;
- break;
- }
- }
-
- if (i == 2) {
- is13simular = _PHY_SimularityCompare(pAdapter, result, 0, 2);
- if (is13simular) {
- final_candidate = 0;
- break;
- }
-
- is23simular = _PHY_SimularityCompare(pAdapter, result, 1, 2);
- if (is23simular) {
- final_candidate = 1;
- } else {
- for (i = 0; i < 8; i++)
- RegTmp += result[3][i];
-
- if (RegTmp != 0)
- final_candidate = 3;
- else
- final_candidate = 0xFF;
- }
- }
- }
-
- for (i = 0; i < 4; i++) {
- RegE94 = result[i][0];
- RegE9C = result[i][1];
- RegEA4 = result[i][2];
- RegEAC = result[i][3];
- RegEB4 = result[i][4];
- RegEBC = result[i][5];
- RegEC4 = result[i][6];
- RegECC = result[i][7];
- }
-
- if (final_candidate != 0xff) {
- RegE94 = result[final_candidate][0];
- pdmpriv->RegE94 = RegE94;
- RegE9C = result[final_candidate][1];
- pdmpriv->RegE9C = RegE9C;
- RegEA4 = result[final_candidate][2];
- RegEAC = result[final_candidate][3];
- RegEB4 = result[final_candidate][4];
- pdmpriv->RegEB4 = RegEB4;
- RegEBC = result[final_candidate][5];
- pdmpriv->RegEBC = RegEBC;
- RegEC4 = result[final_candidate][6];
- RegECC = result[final_candidate][7];
- DBG_8723A("IQK: final_candidate is %x\n", final_candidate);
- DBG_8723A("IQK: RegE94 =%x RegE9C =%x RegEA4 =%x RegEAC =%x RegEB4 =%x RegEBC =%x RegEC4 =%x RegECC =%x\n ",
- RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC);
- bPathAOK = bPathBOK = true;
- } else {
- RegE94 = RegEB4 = pdmpriv->RegE94 = pdmpriv->RegEB4 = 0x100; /* X default value */
- RegE9C = RegEBC = pdmpriv->RegE9C = pdmpriv->RegEBC = 0x0; /* Y default value */
- }
-
- if ((RegE94 != 0)/*&&(RegEA4 != 0)*/)
- _PHY_PathAFillIQKMatrix(pAdapter, bPathAOK, result, final_candidate, (RegEA4 == 0));
-
- if (pHalData->rf_type == RF_2T2R) {
- if ((RegEB4 != 0)/*&&(RegEC4 != 0)*/)
- _PHY_PathBFillIQKMatrix(pAdapter, bPathBOK, result,
- final_candidate, (RegEC4 == 0));
- }
-
- _PHY_SaveADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup_recover, 9);
-}
-
-void rtl8723a_phy_lc_calibrate(struct rtw_adapter *pAdapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
- struct mlme_ext_priv *pmlmeext = &pAdapter->mlmeextpriv;
- bool bStartContTx = false, bSingleTone = false, bCarrierSuppression = false;
-
- /* ignore IQK when continuous Tx */
- if (bStartContTx || bSingleTone || bCarrierSuppression)
- return;
-
- if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
- return;
-
- if (pHalData->rf_type == RF_2T2R)
- _PHY_LCCalibrate(pAdapter, true);
- else /* For 88C 1T1R */
- _PHY_LCCalibrate(pAdapter, false);
-}
-
-void
-rtl8723a_phy_ap_calibrate(struct rtw_adapter *pAdapter, char delta)
-{
-}
diff --git a/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c b/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c
deleted file mode 100644
index 8d3ea6c0cbe6..000000000000
--- a/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/******************************************************************************
-*
-* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of version 2 of the GNU General Public License 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.
-*
-******************************************************************************/
-
-#include "odm_precomp.h"
-
-static bool CheckCondition(const u32 Condition, const u32 Hex)
-{
- u32 _board = (Hex & 0x000000FF);
- u32 _interface = (Hex & 0x0000FF00) >> 8;
- u32 _platform = (Hex & 0x00FF0000) >> 16;
- u32 cond = Condition;
-
- if (Condition == 0xCDCDCDCD)
- return true;
-
- cond = Condition & 0x000000FF;
- if ((_board == cond) && cond != 0x00)
- return false;
-
- cond = Condition & 0x0000FF00;
- cond >>= 8;
- if ((_interface & cond) == 0 && cond != 0x07)
- return false;
-
- cond = Condition & 0x00FF0000;
- cond >>= 16;
- if ((_platform & cond) == 0 && cond != 0x0F)
- return false;
- return true;
-}
-
-/******************************************************************************
-* AGC_TAB_1T.TXT
-******************************************************************************/
-
-static u32 Array_AGC_TAB_1T_8723A[] = {
- 0xC78, 0x7B000001,
- 0xC78, 0x7B010001,
- 0xC78, 0x7B020001,
- 0xC78, 0x7B030001,
- 0xC78, 0x7B040001,
- 0xC78, 0x7B050001,
- 0xC78, 0x7A060001,
- 0xC78, 0x79070001,
- 0xC78, 0x78080001,
- 0xC78, 0x77090001,
- 0xC78, 0x760A0001,
- 0xC78, 0x750B0001,
- 0xC78, 0x740C0001,
- 0xC78, 0x730D0001,
- 0xC78, 0x720E0001,
- 0xC78, 0x710F0001,
- 0xC78, 0x70100001,
- 0xC78, 0x6F110001,
- 0xC78, 0x6E120001,
- 0xC78, 0x6D130001,
- 0xC78, 0x6C140001,
- 0xC78, 0x6B150001,
- 0xC78, 0x6A160001,
- 0xC78, 0x69170001,
- 0xC78, 0x68180001,
- 0xC78, 0x67190001,
- 0xC78, 0x661A0001,
- 0xC78, 0x651B0001,
- 0xC78, 0x641C0001,
- 0xC78, 0x631D0001,
- 0xC78, 0x621E0001,
- 0xC78, 0x611F0001,
- 0xC78, 0x60200001,
- 0xC78, 0x49210001,
- 0xC78, 0x48220001,
- 0xC78, 0x47230001,
- 0xC78, 0x46240001,
- 0xC78, 0x45250001,
- 0xC78, 0x44260001,
- 0xC78, 0x43270001,
- 0xC78, 0x42280001,
- 0xC78, 0x41290001,
- 0xC78, 0x402A0001,
- 0xC78, 0x262B0001,
- 0xC78, 0x252C0001,
- 0xC78, 0x242D0001,
- 0xC78, 0x232E0001,
- 0xC78, 0x222F0001,
- 0xC78, 0x21300001,
- 0xC78, 0x20310001,
- 0xC78, 0x06320001,
- 0xC78, 0x05330001,
- 0xC78, 0x04340001,
- 0xC78, 0x03350001,
- 0xC78, 0x02360001,
- 0xC78, 0x01370001,
- 0xC78, 0x00380001,
- 0xC78, 0x00390001,
- 0xC78, 0x003A0001,
- 0xC78, 0x003B0001,
- 0xC78, 0x003C0001,
- 0xC78, 0x003D0001,
- 0xC78, 0x003E0001,
- 0xC78, 0x003F0001,
- 0xC78, 0x7B400001,
- 0xC78, 0x7B410001,
- 0xC78, 0x7B420001,
- 0xC78, 0x7B430001,
- 0xC78, 0x7B440001,
- 0xC78, 0x7B450001,
- 0xC78, 0x7A460001,
- 0xC78, 0x79470001,
- 0xC78, 0x78480001,
- 0xC78, 0x77490001,
- 0xC78, 0x764A0001,
- 0xC78, 0x754B0001,
- 0xC78, 0x744C0001,
- 0xC78, 0x734D0001,
- 0xC78, 0x724E0001,
- 0xC78, 0x714F0001,
- 0xC78, 0x70500001,
- 0xC78, 0x6F510001,
- 0xC78, 0x6E520001,
- 0xC78, 0x6D530001,
- 0xC78, 0x6C540001,
- 0xC78, 0x6B550001,
- 0xC78, 0x6A560001,
- 0xC78, 0x69570001,
- 0xC78, 0x68580001,
- 0xC78, 0x67590001,
- 0xC78, 0x665A0001,
- 0xC78, 0x655B0001,
- 0xC78, 0x645C0001,
- 0xC78, 0x635D0001,
- 0xC78, 0x625E0001,
- 0xC78, 0x615F0001,
- 0xC78, 0x60600001,
- 0xC78, 0x49610001,
- 0xC78, 0x48620001,
- 0xC78, 0x47630001,
- 0xC78, 0x46640001,
- 0xC78, 0x45650001,
- 0xC78, 0x44660001,
- 0xC78, 0x43670001,
- 0xC78, 0x42680001,
- 0xC78, 0x41690001,
- 0xC78, 0x406A0001,
- 0xC78, 0x266B0001,
- 0xC78, 0x256C0001,
- 0xC78, 0x246D0001,
- 0xC78, 0x236E0001,
- 0xC78, 0x226F0001,
- 0xC78, 0x21700001,
- 0xC78, 0x20710001,
- 0xC78, 0x06720001,
- 0xC78, 0x05730001,
- 0xC78, 0x04740001,
- 0xC78, 0x03750001,
- 0xC78, 0x02760001,
- 0xC78, 0x01770001,
- 0xC78, 0x00780001,
- 0xC78, 0x00790001,
- 0xC78, 0x007A0001,
- 0xC78, 0x007B0001,
- 0xC78, 0x007C0001,
- 0xC78, 0x007D0001,
- 0xC78, 0x007E0001,
- 0xC78, 0x007F0001,
- 0xC78, 0x3800001E,
- 0xC78, 0x3801001E,
- 0xC78, 0x3802001E,
- 0xC78, 0x3803001E,
- 0xC78, 0x3804001E,
- 0xC78, 0x3805001E,
- 0xC78, 0x3806001E,
- 0xC78, 0x3807001E,
- 0xC78, 0x3808001E,
- 0xC78, 0x3C09001E,
- 0xC78, 0x3E0A001E,
- 0xC78, 0x400B001E,
- 0xC78, 0x440C001E,
- 0xC78, 0x480D001E,
- 0xC78, 0x4C0E001E,
- 0xC78, 0x500F001E,
- 0xC78, 0x5210001E,
- 0xC78, 0x5611001E,
- 0xC78, 0x5A12001E,
- 0xC78, 0x5E13001E,
- 0xC78, 0x6014001E,
- 0xC78, 0x6015001E,
- 0xC78, 0x6016001E,
- 0xC78, 0x6217001E,
- 0xC78, 0x6218001E,
- 0xC78, 0x6219001E,
- 0xC78, 0x621A001E,
- 0xC78, 0x621B001E,
- 0xC78, 0x621C001E,
- 0xC78, 0x621D001E,
- 0xC78, 0x621E001E,
- 0xC78, 0x621F001E,
-};
-
-#define READ_NEXT_PAIR(v1, v2, i) \
- do { \
- i += 2; v1 = Array[i]; v2 = Array[i+1]; \
- } while (0)
-
-void ODM_ReadAndConfig_AGC_TAB_1T_8723A(struct dm_odm_t *pDM_Odm)
-{
- u32 hex;
- u32 i;
- u8 platform = 0x04;
- u8 board = pDM_Odm->BoardType;
- u32 ArrayLen = ARRAY_SIZE(Array_AGC_TAB_1T_8723A);
- u32 *Array = Array_AGC_TAB_1T_8723A;
-
- hex = board;
- hex += ODM_ITRF_USB << 8;
- hex += platform << 16;
- hex += 0xFF000000;
- for (i = 0; i < ArrayLen; i += 2) {
- u32 v1 = Array[i];
- u32 v2 = Array[i+1];
-
- /* This (offset, data) pair meets the condition. */
- if (v1 < 0xCDCDCDCD) {
- odm_ConfigBB_AGC_8723A(pDM_Odm, v1, v2);
- continue;
- } else {
- if (!CheckCondition(Array[i], hex)) {
- /* Discard the following (offset, data) pairs */
- READ_NEXT_PAIR(v1, v2, i);
- while (v2 != 0xDEAD &&
- v2 != 0xCDEF &&
- v2 != 0xCDCD && i < ArrayLen - 2)
- READ_NEXT_PAIR(v1, v2, i);
- i -= 2; /* prevent from for-loop += 2 */
- } else {
- /* Configure matched pairs and skip to
- end of if-else. */
- READ_NEXT_PAIR(v1, v2, i);
- while (v2 != 0xDEAD &&
- v2 != 0xCDEF &&
- v2 != 0xCDCD && i < ArrayLen - 2) {
- odm_ConfigBB_AGC_8723A(pDM_Odm, v1, v2);
- READ_NEXT_PAIR(v1, v2, i);
- }
- while (v2 != 0xDEAD && i < ArrayLen - 2)
- READ_NEXT_PAIR(v1, v2, i);
- }
- }
- }
-}
-
-/******************************************************************************
-* PHY_REG_1T.TXT
-******************************************************************************/
-
-static u32 Array_PHY_REG_1T_8723A[] = {
- 0x800, 0x80040000,
- 0x804, 0x00000003,
- 0x808, 0x0000FC00,
- 0x80C, 0x0000000A,
- 0x810, 0x10001331,
- 0x814, 0x020C3D10,
- 0x818, 0x02200385,
- 0x81C, 0x00000000,
- 0x820, 0x01000100,
- 0x824, 0x00390004,
- 0x828, 0x00000000,
- 0x82C, 0x00000000,
- 0x830, 0x00000000,
- 0x834, 0x00000000,
- 0x838, 0x00000000,
- 0x83C, 0x00000000,
- 0x840, 0x00010000,
- 0x844, 0x00000000,
- 0x848, 0x00000000,
- 0x84C, 0x00000000,
- 0x850, 0x00000000,
- 0x854, 0x00000000,
- 0x858, 0x569A569A,
- 0x85C, 0x001B25A4,
- 0x860, 0x66F60110,
- 0x864, 0x061F0130,
- 0x868, 0x00000000,
- 0x86C, 0x32323200,
- 0x870, 0x07000760,
- 0x874, 0x22004000,
- 0x878, 0x00000808,
- 0x87C, 0x00000000,
- 0x880, 0xC0083070,
- 0x884, 0x000004D5,
- 0x888, 0x00000000,
- 0x88C, 0xCCC000C0,
- 0x890, 0x00000800,
- 0x894, 0xFFFFFFFE,
- 0x898, 0x40302010,
- 0x89C, 0x00706050,
- 0x900, 0x00000000,
- 0x904, 0x00000023,
- 0x908, 0x00000000,
- 0x90C, 0x81121111,
- 0xA00, 0x00D047C8,
- 0xA04, 0x80FF000C,
- 0xA08, 0x8C838300,
- 0xA0C, 0x2E68120F,
- 0xA10, 0x9500BB78,
- 0xA14, 0x11144028,
- 0xA18, 0x00881117,
- 0xA1C, 0x89140F00,
- 0xA20, 0x1A1B0000,
- 0xA24, 0x090E1317,
- 0xA28, 0x00000204,
- 0xA2C, 0x00D30000,
- 0xA70, 0x101FBF00,
- 0xA74, 0x00000007,
- 0xA78, 0x00000900,
- 0xC00, 0x48071D40,
- 0xC04, 0x03A05611,
- 0xC08, 0x000000E4,
- 0xC0C, 0x6C6C6C6C,
- 0xC10, 0x08800000,
- 0xC14, 0x40000100,
- 0xC18, 0x08800000,
- 0xC1C, 0x40000100,
- 0xC20, 0x00000000,
- 0xC24, 0x00000000,
- 0xC28, 0x00000000,
- 0xC2C, 0x00000000,
- 0xC30, 0x69E9AC44,
- 0xFF0F011F, 0xABCD,
- 0xC34, 0x469652CF,
- 0xCDCDCDCD, 0xCDCD,
- 0xC34, 0x469652AF,
- 0xFF0F011F, 0xDEAD,
- 0xC38, 0x49795994,
- 0xC3C, 0x0A97971C,
- 0xC40, 0x1F7C403F,
- 0xC44, 0x000100B7,
- 0xC48, 0xEC020107,
- 0xC4C, 0x007F037F,
- 0xC50, 0x69543420,
- 0xC54, 0x43BC0094,
- 0xC58, 0x69543420,
- 0xC5C, 0x433C0094,
- 0xC60, 0x00000000,
- 0xFF0F011F, 0xABCD,
- 0xC64, 0x7116848B,
- 0xCDCDCDCD, 0xCDCD,
- 0xC64, 0x7112848B,
- 0xFF0F011F, 0xDEAD,
- 0xC68, 0x47C00BFF,
- 0xC6C, 0x00000036,
- 0xC70, 0x2C7F000D,
- 0xC74, 0x018610DB,
- 0xC78, 0x0000001F,
- 0xC7C, 0x00B91612,
- 0xC80, 0x40000100,
- 0xC84, 0x20F60000,
- 0xC88, 0x40000100,
- 0xC8C, 0x20200000,
- 0xC90, 0x00121820,
- 0xC94, 0x00000000,
- 0xC98, 0x00121820,
- 0xC9C, 0x00007F7F,
- 0xCA0, 0x00000000,
- 0xCA4, 0x00000080,
- 0xCA8, 0x00000000,
- 0xCAC, 0x00000000,
- 0xCB0, 0x00000000,
- 0xCB4, 0x00000000,
- 0xCB8, 0x00000000,
- 0xCBC, 0x28000000,
- 0xCC0, 0x00000000,
- 0xCC4, 0x00000000,
- 0xCC8, 0x00000000,
- 0xCCC, 0x00000000,
- 0xCD0, 0x00000000,
- 0xCD4, 0x00000000,
- 0xCD8, 0x64B22427,
- 0xCDC, 0x00766932,
- 0xCE0, 0x00222222,
- 0xCE4, 0x00000000,
- 0xCE8, 0x37644302,
- 0xCEC, 0x2F97D40C,
- 0xD00, 0x00080740,
- 0xD04, 0x00020401,
- 0xD08, 0x0000907F,
- 0xD0C, 0x20010201,
- 0xD10, 0xA0633333,
- 0xD14, 0x3333BC43,
- 0xD18, 0x7A8F5B6B,
- 0xD2C, 0xCC979975,
- 0xD30, 0x00000000,
- 0xD34, 0x80608000,
- 0xD38, 0x00000000,
- 0xD3C, 0x00027293,
- 0xD40, 0x00000000,
- 0xD44, 0x00000000,
- 0xD48, 0x00000000,
- 0xD4C, 0x00000000,
- 0xD50, 0x6437140A,
- 0xD54, 0x00000000,
- 0xD58, 0x00000000,
- 0xD5C, 0x30032064,
- 0xD60, 0x4653DE68,
- 0xD64, 0x04518A3C,
- 0xD68, 0x00002101,
- 0xD6C, 0x2A201C16,
- 0xD70, 0x1812362E,
- 0xD74, 0x322C2220,
- 0xD78, 0x000E3C24,
- 0xE00, 0x2A2A2A2A,
- 0xE04, 0x2A2A2A2A,
- 0xE08, 0x03902A2A,
- 0xE10, 0x2A2A2A2A,
- 0xE14, 0x2A2A2A2A,
- 0xE18, 0x2A2A2A2A,
- 0xE1C, 0x2A2A2A2A,
- 0xE28, 0x00000000,
- 0xE30, 0x1000DC1F,
- 0xE34, 0x10008C1F,
- 0xE38, 0x02140102,
- 0xE3C, 0x681604C2,
- 0xE40, 0x01007C00,
- 0xE44, 0x01004800,
- 0xE48, 0xFB000000,
- 0xE4C, 0x000028D1,
- 0xE50, 0x1000DC1F,
- 0xE54, 0x10008C1F,
- 0xE58, 0x02140102,
- 0xE5C, 0x28160D05,
- 0xE60, 0x00000008,
- 0xE68, 0x001B25A4,
- 0xE6C, 0x631B25A0,
- 0xE70, 0x631B25A0,
- 0xE74, 0x081B25A0,
- 0xE78, 0x081B25A0,
- 0xE7C, 0x081B25A0,
- 0xE80, 0x081B25A0,
- 0xE84, 0x631B25A0,
- 0xE88, 0x081B25A0,
- 0xE8C, 0x631B25A0,
- 0xED0, 0x631B25A0,
- 0xED4, 0x631B25A0,
- 0xED8, 0x631B25A0,
- 0xEDC, 0x001B25A0,
- 0xEE0, 0x001B25A0,
- 0xEEC, 0x6B1B25A0,
- 0xF14, 0x00000003,
- 0xF4C, 0x00000000,
- 0xF00, 0x00000300,
-};
-
-void ODM_ReadAndConfig_PHY_REG_1T_8723A(struct dm_odm_t *pDM_Odm)
-{
- u32 hex = 0;
- u32 i = 0;
- u8 platform = 0x04;
- u8 board = pDM_Odm->BoardType;
- u32 ArrayLen = ARRAY_SIZE(Array_PHY_REG_1T_8723A);
- u32 *Array = Array_PHY_REG_1T_8723A;
-
- hex += board;
- hex += ODM_ITRF_USB << 8;
- hex += platform << 16;
- hex += 0xFF000000;
- for (i = 0; i < ArrayLen; i += 2) {
- u32 v1 = Array[i];
- u32 v2 = Array[i+1];
-
- /* This (offset, data) pair meets the condition. */
- if (v1 < 0xCDCDCDCD) {
- odm_ConfigBB_PHY_8723A(pDM_Odm, v1, v2);
- continue;
- } else {
- if (!CheckCondition(Array[i], hex)) {
- /* Discard the following (offset, data) pairs */
- READ_NEXT_PAIR(v1, v2, i);
- while (v2 != 0xDEAD &&
- v2 != 0xCDEF &&
- v2 != 0xCDCD && i < ArrayLen - 2)
- READ_NEXT_PAIR(v1, v2, i);
- i -= 2; /* prevent from for-loop += 2 */
- } else {
- /* Configure matched pairs and skip to
- end of if-else. */
- READ_NEXT_PAIR(v1, v2, i);
- while (v2 != 0xDEAD &&
- v2 != 0xCDEF &&
- v2 != 0xCDCD && i < ArrayLen - 2) {
- odm_ConfigBB_PHY_8723A(pDM_Odm, v1, v2);
- READ_NEXT_PAIR(v1, v2, i);
- }
- while (v2 != 0xDEAD && i < ArrayLen - 2)
- READ_NEXT_PAIR(v1, v2, i);
- }
- }
- }
-}
-
-/******************************************************************************
-* PHY_REG_MP.TXT
-******************************************************************************/
-
-static u32 Array_PHY_REG_MP_8723A[] = {
- 0xC30, 0x69E9AC4A,
- 0xC3C, 0x0A979718,
-};
-
-void ODM_ReadAndConfig_PHY_REG_MP_8723A(struct dm_odm_t *pDM_Odm)
-{
- u32 hex = 0;
- u32 i;
- u8 platform = 0x04;
- u8 board = pDM_Odm->BoardType;
- u32 ArrayLen = ARRAY_SIZE(Array_PHY_REG_MP_8723A);
- u32 *Array = Array_PHY_REG_MP_8723A;
-
- hex += board;
- hex += ODM_ITRF_USB << 8;
- hex += platform << 16;
- hex += 0xFF000000;
- for (i = 0; i < ArrayLen; i += 2) {
- u32 v1 = Array[i];
- u32 v2 = Array[i+1];
-
- /* This (offset, data) pair meets the condition. */
- if (v1 < 0xCDCDCDCD) {
- odm_ConfigBB_PHY_8723A(pDM_Odm, v1, v2);
- continue;
- } else {
- if (!CheckCondition(Array[i], hex)) {
- /* Discard the following (offset, data) pairs */
- READ_NEXT_PAIR(v1, v2, i);
- while (v2 != 0xDEAD &&
- v2 != 0xCDEF &&
- v2 != 0xCDCD && i < ArrayLen - 2)
- READ_NEXT_PAIR(v1, v2, i);
- i -= 2; /* prevent from for-loop += 2 */
- } else {
- /* Configure matched pairs and skip to
- end of if-else. */
- READ_NEXT_PAIR(v1, v2, i);
- while (v2 != 0xDEAD &&
- v2 != 0xCDEF &&
- v2 != 0xCDCD && i < ArrayLen - 2) {
- odm_ConfigBB_PHY_8723A(pDM_Odm, v1, v2);
- READ_NEXT_PAIR(v1, v2, i);
- }
- while (v2 != 0xDEAD && i < ArrayLen - 2)
- READ_NEXT_PAIR(v1, v2, i);
- }
- }
- }
-}
diff --git a/drivers/staging/rtl8723au/hal/HalHWImg8723A_MAC.c b/drivers/staging/rtl8723au/hal/HalHWImg8723A_MAC.c
deleted file mode 100644
index 9bf685905e68..000000000000
--- a/drivers/staging/rtl8723au/hal/HalHWImg8723A_MAC.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/******************************************************************************
-*
-* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of version 2 of the GNU General Public License 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.
-*
-******************************************************************************/
-
-#include "odm_precomp.h"
-
-static bool CheckCondition(const u32 Condition, const u32 Hex)
-{
- u32 _board = (Hex & 0x000000FF);
- u32 _interface = (Hex & 0x0000FF00) >> 8;
- u32 _platform = (Hex & 0x00FF0000) >> 16;
- u32 cond = Condition;
-
- if (Condition == 0xCDCDCDCD)
- return true;
-
- cond = Condition & 0x000000FF;
- if ((_board == cond) && cond != 0x00)
- return false;
-
- cond = Condition & 0x0000FF00;
- cond >>= 8;
- if ((_interface & cond) == 0 && cond != 0x07)
- return false;
-
- cond = Condition & 0x00FF0000;
- cond >>= 16;
- if ((_platform & cond) == 0 && cond != 0x0F)
- return false;
- return true;
-}
-
-/******************************************************************************
-* MAC_REG.TXT
-******************************************************************************/
-
-static u32 Array_MAC_REG_8723A[] = {
- 0x420, 0x00000080,
- 0x423, 0x00000000,
- 0x430, 0x00000000,
- 0x431, 0x00000000,
- 0x432, 0x00000000,
- 0x433, 0x00000001,
- 0x434, 0x00000004,
- 0x435, 0x00000005,
- 0x436, 0x00000006,
- 0x437, 0x00000007,
- 0x438, 0x00000000,
- 0x439, 0x00000000,
- 0x43A, 0x00000000,
- 0x43B, 0x00000001,
- 0x43C, 0x00000004,
- 0x43D, 0x00000005,
- 0x43E, 0x00000006,
- 0x43F, 0x00000007,
- 0x440, 0x0000005D,
- 0x441, 0x00000001,
- 0x442, 0x00000000,
- 0x444, 0x00000015,
- 0x445, 0x000000F0,
- 0x446, 0x0000000F,
- 0x447, 0x00000000,
- 0x458, 0x00000041,
- 0x459, 0x000000A8,
- 0x45A, 0x00000072,
- 0x45B, 0x000000B9,
- 0x460, 0x00000066,
- 0x461, 0x00000066,
- 0x462, 0x00000008,
- 0x463, 0x00000003,
- 0x4C8, 0x000000FF,
- 0x4C9, 0x00000008,
- 0x4CC, 0x000000FF,
- 0x4CD, 0x000000FF,
- 0x4CE, 0x00000001,
- 0x500, 0x00000026,
- 0x501, 0x000000A2,
- 0x502, 0x0000002F,
- 0x503, 0x00000000,
- 0x504, 0x00000028,
- 0x505, 0x000000A3,
- 0x506, 0x0000005E,
- 0x507, 0x00000000,
- 0x508, 0x0000002B,
- 0x509, 0x000000A4,
- 0x50A, 0x0000005E,
- 0x50B, 0x00000000,
- 0x50C, 0x0000004F,
- 0x50D, 0x000000A4,
- 0x50E, 0x00000000,
- 0x50F, 0x00000000,
- 0x512, 0x0000001C,
- 0x514, 0x0000000A,
- 0x515, 0x00000010,
- 0x516, 0x0000000A,
- 0x517, 0x00000010,
- 0x51A, 0x00000016,
- 0x524, 0x0000000F,
- 0x525, 0x0000004F,
- 0x546, 0x00000040,
- 0x547, 0x00000000,
- 0x550, 0x00000010,
- 0x551, 0x00000010,
- 0x559, 0x00000002,
- 0x55A, 0x00000002,
- 0x55D, 0x000000FF,
- 0x605, 0x00000030,
- 0x608, 0x0000000E,
- 0x609, 0x0000002A,
- 0x652, 0x00000020,
- 0x63C, 0x0000000A,
- 0x63D, 0x0000000A,
- 0x63E, 0x0000000E,
- 0x63F, 0x0000000E,
- 0x66E, 0x00000005,
- 0x700, 0x00000021,
- 0x701, 0x00000043,
- 0x702, 0x00000065,
- 0x703, 0x00000087,
- 0x708, 0x00000021,
- 0x709, 0x00000043,
- 0x70A, 0x00000065,
- 0x70B, 0x00000087,
-};
-
-void ODM_ReadAndConfig_MAC_REG_8723A(struct dm_odm_t *pDM_Odm)
-{
- #define READ_NEXT_PAIR(v1, v2, i) \
- do { \
- i += 2; v1 = Array[i]; v2 = Array[i+1]; \
- } while (0)
-
- u32 hex = 0;
- u32 i = 0;
- u8 platform = 0x04;
- u8 board = pDM_Odm->BoardType;
- u32 ArrayLen = ARRAY_SIZE(Array_MAC_REG_8723A);
- u32 *Array = Array_MAC_REG_8723A;
-
- hex += board;
- hex += ODM_ITRF_USB << 8;
- hex += platform << 16;
- hex += 0xFF000000;
- for (i = 0; i < ArrayLen; i += 2) {
- u32 v1 = Array[i];
- u32 v2 = Array[i+1];
-
- /* This (offset, data) pair meets the condition. */
- if (v1 < 0xCDCDCDCD) {
- odm_ConfigMAC_8723A(pDM_Odm, v1, (u8)v2);
- continue;
- } else {
- if (!CheckCondition(Array[i], hex)) {
- /* Discard the following (offset, data) pairs. */
- READ_NEXT_PAIR(v1, v2, i);
- while (v2 != 0xDEAD &&
- v2 != 0xCDEF &&
- v2 != 0xCDCD && i < ArrayLen - 2)
- READ_NEXT_PAIR(v1, v2, i);
- i -= 2; /* prevent from for-loop += 2 */
- } else {
- /* Configure matched pairs and skip to end of if-else. */
- READ_NEXT_PAIR(v1, v2, i);
- while (v2 != 0xDEAD &&
- v2 != 0xCDEF &&
- v2 != 0xCDCD && i < ArrayLen - 2) {
- odm_ConfigMAC_8723A(pDM_Odm, v1, (u8)v2);
- READ_NEXT_PAIR(v1, v2, i);
- }
-
- while (v2 != 0xDEAD && i < ArrayLen - 2)
- READ_NEXT_PAIR(v1, v2, i);
- }
- }
- }
-}
diff --git a/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c b/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c
deleted file mode 100644
index 286f3ea3d263..000000000000
--- a/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/******************************************************************************
-*
-* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of version 2 of the GNU General Public License 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.
-*
-******************************************************************************/
-
-#include "odm_precomp.h"
-
-static bool CheckCondition(const u32 Condition, const u32 Hex)
-{
- u32 _board = (Hex & 0x000000FF);
- u32 _interface = (Hex & 0x0000FF00) >> 8;
- u32 _platform = (Hex & 0x00FF0000) >> 16;
- u32 cond = Condition;
-
- if (Condition == 0xCDCDCDCD)
- return true;
-
- cond = Condition & 0x000000FF;
- if ((_board == cond) && cond != 0x00)
- return false;
-
- cond = Condition & 0x0000FF00;
- cond >>= 8;
- if ((_interface & cond) == 0 && cond != 0x07)
- return false;
-
- cond = Condition & 0x00FF0000;
- cond >>= 16;
- if ((_platform & cond) == 0 && cond != 0x0F)
- return false;
- return true;
-}
-
-/******************************************************************************
-* RadioA_1T.TXT
-******************************************************************************/
-
-static u32 Array_RadioA_1T_8723A[] = {
- 0x000, 0x00030159,
- 0x001, 0x00031284,
- 0x002, 0x00098000,
- 0xFF0F011F, 0xABCD,
- 0x003, 0x00018C63,
- 0xCDCDCDCD, 0xCDCD,
- 0x003, 0x00039C63,
- 0xFF0F011F, 0xDEAD,
- 0x004, 0x000210E7,
- 0x009, 0x0002044F,
- 0x00A, 0x0001A3F1,
- 0x00B, 0x00014787,
- 0x00C, 0x000896FE,
- 0x00D, 0x0000E02C,
- 0x00E, 0x00039CE7,
- 0x00F, 0x00000451,
- 0x019, 0x00000000,
- 0x01A, 0x00030355,
- 0x01B, 0x00060A00,
- 0x01C, 0x000FC378,
- 0x01D, 0x000A1250,
- 0x01E, 0x0000024F,
- 0x01F, 0x00000000,
- 0x020, 0x0000B614,
- 0x021, 0x0006C000,
- 0x022, 0x00000000,
- 0x023, 0x00001558,
- 0x024, 0x00000060,
- 0x025, 0x00000483,
- 0x026, 0x0004F000,
- 0x027, 0x000EC7D9,
- 0x028, 0x00057730,
- 0x029, 0x00004783,
- 0x02A, 0x00000001,
- 0x02B, 0x00021334,
- 0x02A, 0x00000000,
- 0x02B, 0x00000054,
- 0x02A, 0x00000001,
- 0x02B, 0x00000808,
- 0x02B, 0x00053333,
- 0x02C, 0x0000000C,
- 0x02A, 0x00000002,
- 0x02B, 0x00000808,
- 0x02B, 0x0005B333,
- 0x02C, 0x0000000D,
- 0x02A, 0x00000003,
- 0x02B, 0x00000808,
- 0x02B, 0x00063333,
- 0x02C, 0x0000000D,
- 0x02A, 0x00000004,
- 0x02B, 0x00000808,
- 0x02B, 0x0006B333,
- 0x02C, 0x0000000D,
- 0x02A, 0x00000005,
- 0x02B, 0x00000808,
- 0x02B, 0x00073333,
- 0x02C, 0x0000000D,
- 0x02A, 0x00000006,
- 0x02B, 0x00000709,
- 0x02B, 0x0005B333,
- 0x02C, 0x0000000D,
- 0x02A, 0x00000007,
- 0x02B, 0x00000709,
- 0x02B, 0x00063333,
- 0x02C, 0x0000000D,
- 0x02A, 0x00000008,
- 0x02B, 0x0000060A,
- 0x02B, 0x0004B333,
- 0x02C, 0x0000000D,
- 0x02A, 0x00000009,
- 0x02B, 0x0000060A,
- 0x02B, 0x00053333,
- 0x02C, 0x0000000D,
- 0x02A, 0x0000000A,
- 0x02B, 0x0000060A,
- 0x02B, 0x0005B333,
- 0x02C, 0x0000000D,
- 0x02A, 0x0000000B,
- 0x02B, 0x0000060A,
- 0x02B, 0x00063333,
- 0x02C, 0x0000000D,
- 0x02A, 0x0000000C,
- 0x02B, 0x0000060A,
- 0x02B, 0x0006B333,
- 0x02C, 0x0000000D,
- 0x02A, 0x0000000D,
- 0x02B, 0x0000060A,
- 0x02B, 0x00073333,
- 0x02C, 0x0000000D,
- 0x02A, 0x0000000E,
- 0x02B, 0x0000050B,
- 0x02B, 0x00066666,
- 0x02C, 0x0000001A,
- 0x02A, 0x000E0000,
- 0x010, 0x0004000F,
- 0x011, 0x000E31FC,
- 0x010, 0x0006000F,
- 0x011, 0x000FF9F8,
- 0x010, 0x0002000F,
- 0x011, 0x000203F9,
- 0x010, 0x0003000F,
- 0x011, 0x000FF500,
- 0x010, 0x00000000,
- 0x011, 0x00000000,
- 0x010, 0x0008000F,
- 0x011, 0x0003F100,
- 0x010, 0x0009000F,
- 0x011, 0x00023100,
- 0x012, 0x00032000,
- 0x012, 0x00071000,
- 0x012, 0x000B0000,
- 0x012, 0x000FC000,
- 0x013, 0x000287B3,
- 0x013, 0x000244B7,
- 0x013, 0x000204AB,
- 0x013, 0x0001C49F,
- 0x013, 0x00018493,
- 0x013, 0x0001429B,
- 0x013, 0x00010299,
- 0x013, 0x0000C29C,
- 0x013, 0x000081A0,
- 0x013, 0x000040AC,
- 0x013, 0x00000020,
- 0x014, 0x0001944C,
- 0x014, 0x00059444,
- 0x014, 0x0009944C,
- 0x014, 0x000D9444,
- 0xFF0F011F, 0xABCD,
- 0x015, 0x0000F424,
- 0x015, 0x0004F424,
- 0x015, 0x0008F424,
- 0x015, 0x000CF424,
- 0xCDCDCDCD, 0xCDCD,
- 0x015, 0x0000F474,
- 0x015, 0x0004F477,
- 0x015, 0x0008F455,
- 0x015, 0x000CF455,
- 0xFF0F011F, 0xDEAD,
- 0x016, 0x00000339,
- 0x016, 0x00040339,
- 0x016, 0x00080339,
- 0xFF0F011F, 0xABCD,
- 0x016, 0x000C0356,
- 0xCDCDCDCD, 0xCDCD,
- 0x016, 0x000C0366,
- 0xFF0F011F, 0xDEAD,
- 0x000, 0x00010159,
- 0x018, 0x0000F401,
- 0x0FE, 0x00000000,
- 0x0FE, 0x00000000,
- 0x01F, 0x00000003,
- 0x0FE, 0x00000000,
- 0x0FE, 0x00000000,
- 0x01E, 0x00000247,
- 0x01F, 0x00000000,
- 0x000, 0x00030159,
-};
-
-void ODM_ReadAndConfig_RadioA_1T_8723A(struct dm_odm_t *pDM_Odm)
-{
- #define READ_NEXT_PAIR(v1, v2, i) \
- do { \
- i += 2; v1 = Array[i]; v2 = Array[i+1];\
- } while (0)
-
- u32 hex = 0;
- u32 i = 0;
- u8 platform = 0x04;
- u8 board = pDM_Odm->BoardType;
- u32 ArrayLen = ARRAY_SIZE(Array_RadioA_1T_8723A);
- u32 *Array = Array_RadioA_1T_8723A;
-
- hex += board;
- hex += ODM_ITRF_USB << 8;
- hex += platform << 16;
- hex += 0xFF000000;
-
- for (i = 0; i < ArrayLen; i += 2) {
- u32 v1 = Array[i];
- u32 v2 = Array[i+1];
-
- /* This (offset, data) pair meets the condition. */
- if (v1 < 0xCDCDCDCD) {
- odm_ConfigRFReg_8723A(pDM_Odm, v1, v2, RF_PATH_A, v1);
- continue;
- } else {
- if (!CheckCondition(Array[i], hex)) {
- /* Discard the following (offset, data) pairs. */
- READ_NEXT_PAIR(v1, v2, i);
- while (v2 != 0xDEAD &&
- v2 != 0xCDEF &&
- v2 != 0xCDCD && i < ArrayLen - 2)
- READ_NEXT_PAIR(v1, v2, i);
- i -= 2; /* prevent from for-loop += 2 */
- } else {
- /* Configure matched pairs and skip to end of if-else. */
- READ_NEXT_PAIR(v1, v2, i);
- while (v2 != 0xDEAD &&
- v2 != 0xCDEF &&
- v2 != 0xCDCD && i < ArrayLen - 2) {
- odm_ConfigRFReg_8723A(pDM_Odm, v1, v2,
- RF_PATH_A, v1);
- READ_NEXT_PAIR(v1, v2, i);
- }
-
- while (v2 != 0xDEAD && i < ArrayLen - 2)
- READ_NEXT_PAIR(v1, v2, i);
- }
- }
- }
-}
diff --git a/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c b/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c
deleted file mode 100644
index 0a3d96e840cc..000000000000
--- a/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-/*++
-Copyright (c) Realtek Semiconductor Corp. All rights reserved.
-
-Module Name:
- HalPwrSeqCmd.c
-
-Abstract:
- Implement HW Power sequence configuration CMD handling routine for
- Realtek devices.
-
-Major Change History:
- When Who What
- ---------- --------------- -------------------------------
- 2011-10-26 Lucas Modify to be compatible with SD4-CE driver.
- 2011-07-07 Roger Create.
-
---*/
-#include <HalPwrSeqCmd.h>
-#include <usb_ops_linux.h>
-
-/* */
-/* Description: */
-/* This routine deal with the Power Configuration CMDs parsing
- for RTL8723/RTL8188E Series IC. */
-/* */
-/* Assumption: */
-/* We should follow specific format which was released from
- HW SD. */
-/* */
-/* 2011.07.07, added by Roger. */
-/* */
-u8 HalPwrSeqCmdParsing23a(struct rtw_adapter *padapter, u8 CutVersion,
- u8 FabVersion, u8 InterfaceType,
- struct wlan_pwr_cfg PwrSeqCmd[])
-{
- struct wlan_pwr_cfg PwrCfgCmd;
- u8 bPollingBit;
- u32 AryIdx = 0;
- u8 value;
- u32 offset;
- u32 pollingCount = 0; /* polling autoload done. */
- u32 maxPollingCnt = 5000;
-
- do {
- PwrCfgCmd = PwrSeqCmd[AryIdx];
-
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "HalPwrSeqCmdParsing23a: offset(%#x) cut_msk(%#x) fab_msk(%#x) interface_msk(%#x) base(%#x) cmd(%#x) msk(%#x) value(%#x)\n",
- GET_PWR_CFG_OFFSET(PwrCfgCmd),
- GET_PWR_CFG_CUT_MASK(PwrCfgCmd),
- GET_PWR_CFG_FAB_MASK(PwrCfgCmd),
- GET_PWR_CFG_INTF_MASK(PwrCfgCmd),
- GET_PWR_CFG_BASE(PwrCfgCmd),
- GET_PWR_CFG_CMD(PwrCfgCmd),
- GET_PWR_CFG_MASK(PwrCfgCmd),
- GET_PWR_CFG_VALUE(PwrCfgCmd));
-
- /* 2 Only Handle the command whose FAB, CUT, and Interface are
- matched */
- if ((GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) &&
- (GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) &&
- (GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)) {
- switch (GET_PWR_CFG_CMD(PwrCfgCmd)) {
- case PWR_CMD_READ:
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "HalPwrSeqCmdParsing23a: PWR_CMD_READ\n");
- break;
-
- case PWR_CMD_WRITE:
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "HalPwrSeqCmdParsing23a: PWR_CMD_WRITE\n");
- offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
-
- /* Read the value from system register */
- value = rtl8723au_read8(padapter, offset);
-
- value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd));
- value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) &
- GET_PWR_CFG_MASK(PwrCfgCmd));
-
- /* Write the value back to system register */
- rtl8723au_write8(padapter, offset, value);
- break;
-
- case PWR_CMD_POLLING:
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "HalPwrSeqCmdParsing23a: PWR_CMD_POLLING\n");
-
- bPollingBit = false;
- offset = GET_PWR_CFG_OFFSET(PwrCfgCmd);
- do {
- value = rtl8723au_read8(padapter,
- offset);
-
- value &= GET_PWR_CFG_MASK(PwrCfgCmd);
- if (value ==
- (GET_PWR_CFG_VALUE(PwrCfgCmd) &
- GET_PWR_CFG_MASK(PwrCfgCmd)))
- bPollingBit = true;
- else
- udelay(10);
-
- if (pollingCount++ > maxPollingCnt) {
- DBG_8723A("Fail to polling "
- "Offset[%#x]\n",
- offset);
- return false;
- }
- } while (!bPollingBit);
-
- break;
-
- case PWR_CMD_DELAY:
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "HalPwrSeqCmdParsing23a: PWR_CMD_DELAY\n");
- if (GET_PWR_CFG_VALUE(PwrCfgCmd) ==
- PWRSEQ_DELAY_US)
- udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd));
- else
- udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd) *
- 1000);
- break;
-
- case PWR_CMD_END:
- /* When this command is parsed, end
- the process */
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "HalPwrSeqCmdParsing23a: PWR_CMD_END\n");
- return true;
-
- default:
- RT_TRACE(_module_hal_init_c_, _drv_err_,
- "HalPwrSeqCmdParsing23a: Unknown CMD!!\n");
- break;
- }
- }
-
- AryIdx++; /* Add Array Index */
- } while (1);
-
- return true;
-}
diff --git a/drivers/staging/rtl8723au/hal/hal_com.c b/drivers/staging/rtl8723au/hal/hal_com.c
deleted file mode 100644
index 9d7b11b63957..000000000000
--- a/drivers/staging/rtl8723au/hal/hal_com.c
+++ /dev/null
@@ -1,853 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#include <osdep_service.h>
-#include <drv_types.h>
-
-#include <hal_intf.h>
-#include <hal_com.h>
-#include <rtl8723a_hal.h>
-#include <usb_ops_linux.h>
-
-#define _HAL_INIT_C_
-
-#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
-
-/* return the final channel plan decision */
-/* hw_channel_plan: channel plan from HW (efuse/eeprom) */
-/* sw_channel_plan: channel plan from SW (registry/module param) */
-/* def_channel_plan: channel plan used when the former two is invalid */
-u8 hal_com_get_channel_plan23a(struct rtw_adapter *padapter, u8 hw_channel_plan,
- u8 sw_channel_plan, u8 def_channel_plan,
- bool AutoLoadFail)
-{
- u8 swConfig;
- u8 chnlPlan;
-
- swConfig = true;
- if (!AutoLoadFail) {
- if (!rtw_is_channel_plan_valid(sw_channel_plan))
- swConfig = false;
- if (hw_channel_plan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
- swConfig = false;
- }
-
- if (swConfig == true)
- chnlPlan = sw_channel_plan;
- else
- chnlPlan = hw_channel_plan & (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
-
- if (!rtw_is_channel_plan_valid(chnlPlan))
- chnlPlan = def_channel_plan;
-
- return chnlPlan;
-}
-
-u8 MRateToHwRate23a(u8 rate)
-{
- u8 ret = DESC_RATE1M;
-
- switch (rate) {
- /* CCK and OFDM non-HT rates */
- case IEEE80211_CCK_RATE_1MB:
- ret = DESC_RATE1M;
- break;
- case IEEE80211_CCK_RATE_2MB:
- ret = DESC_RATE2M;
- break;
- case IEEE80211_CCK_RATE_5MB:
- ret = DESC_RATE5_5M;
- break;
- case IEEE80211_CCK_RATE_11MB:
- ret = DESC_RATE11M;
- break;
- case IEEE80211_OFDM_RATE_6MB:
- ret = DESC_RATE6M;
- break;
- case IEEE80211_OFDM_RATE_9MB:
- ret = DESC_RATE9M;
- break;
- case IEEE80211_OFDM_RATE_12MB:
- ret = DESC_RATE12M;
- break;
- case IEEE80211_OFDM_RATE_18MB:
- ret = DESC_RATE18M;
- break;
- case IEEE80211_OFDM_RATE_24MB:
- ret = DESC_RATE24M;
- break;
- case IEEE80211_OFDM_RATE_36MB:
- ret = DESC_RATE36M;
- break;
- case IEEE80211_OFDM_RATE_48MB:
- ret = DESC_RATE48M;
- break;
- case IEEE80211_OFDM_RATE_54MB:
- ret = DESC_RATE54M;
- break;
-
- /* HT rates since here */
- /* case MGN_MCS0: ret = DESC_RATEMCS0; break; */
- /* case MGN_MCS1: ret = DESC_RATEMCS1; break; */
- /* case MGN_MCS2: ret = DESC_RATEMCS2; break; */
- /* case MGN_MCS3: ret = DESC_RATEMCS3; break; */
- /* case MGN_MCS4: ret = DESC_RATEMCS4; break; */
- /* case MGN_MCS5: ret = DESC_RATEMCS5; break; */
- /* case MGN_MCS6: ret = DESC_RATEMCS6; break; */
- /* case MGN_MCS7: ret = DESC_RATEMCS7; break; */
-
- default:
- break;
- }
- return ret;
-}
-
-void HalSetBrateCfg23a(struct rtw_adapter *padapter, u8 *mBratesOS)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 i, is_brate, brate;
- u16 brate_cfg = 0;
- u8 rate_index;
-
- for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
- is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
- brate = mBratesOS[i] & 0x7f;
-
- if (is_brate) {
- switch (brate) {
- case IEEE80211_CCK_RATE_1MB:
- brate_cfg |= RATE_1M;
- break;
- case IEEE80211_CCK_RATE_2MB:
- brate_cfg |= RATE_2M;
- break;
- case IEEE80211_CCK_RATE_5MB:
- brate_cfg |= RATE_5_5M;
- break;
- case IEEE80211_CCK_RATE_11MB:
- brate_cfg |= RATE_11M;
- break;
- case IEEE80211_OFDM_RATE_6MB:
- brate_cfg |= RATE_6M;
- break;
- case IEEE80211_OFDM_RATE_9MB:
- brate_cfg |= RATE_9M;
- break;
- case IEEE80211_OFDM_RATE_12MB:
- brate_cfg |= RATE_12M;
- break;
- case IEEE80211_OFDM_RATE_18MB:
- brate_cfg |= RATE_18M;
- break;
- case IEEE80211_OFDM_RATE_24MB:
- brate_cfg |= RATE_24M;
- break;
- case IEEE80211_OFDM_RATE_36MB:
- brate_cfg |= RATE_36M;
- break;
- case IEEE80211_OFDM_RATE_48MB:
- brate_cfg |= RATE_48M;
- break;
- case IEEE80211_OFDM_RATE_54MB:
- brate_cfg |= RATE_54M;
- break;
- }
- }
- }
-
- /* 2007.01.16, by Emily */
- /* Select RRSR (in Legacy-OFDM and CCK) */
- /* For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M,
- and 1M from the Basic rate. */
- /* We do not use other rates. */
- /* 2011.03.30 add by Luke Lee */
- /* CCK 2M ACK should be disabled for some BCM and Atheros AP IOT */
- /* because CCK 2M has poor TXEVM */
- /* CCK 5.5M & 11M ACK should be enabled for better
- performance */
-
- brate_cfg = (brate_cfg | 0xd) & 0x15d;
- pHalData->BasicRateSet = brate_cfg;
- brate_cfg |= 0x01; /* default enable 1M ACK rate */
- DBG_8723A("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", brate_cfg);
-
- /* Set RRSR rate table. */
- rtl8723au_write8(padapter, REG_RRSR, brate_cfg & 0xff);
- rtl8723au_write8(padapter, REG_RRSR + 1, (brate_cfg >> 8) & 0xff);
- rtl8723au_write8(padapter, REG_RRSR + 2,
- rtl8723au_read8(padapter, REG_RRSR + 2) & 0xf0);
-
- rate_index = 0;
- /* Set RTS initial rate */
- while (brate_cfg > 0x1) {
- brate_cfg >>= 1;
- rate_index++;
- }
- /* Ziv - Check */
- rtl8723au_write8(padapter, REG_INIRTS_RATE_SEL, rate_index);
-}
-
-static void _OneOutPipeMapping(struct rtw_adapter *pAdapter)
-{
- struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
-
- pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */
- pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0]; /* VI */
- pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0]; /* BE */
- pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0]; /* BK */
-
- pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */
- pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */
- pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */
- pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD */
-}
-
-static void _TwoOutPipeMapping(struct rtw_adapter *pAdapter, bool bWIFICfg)
-{
- struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
-
- if (bWIFICfg) { /* WMM */
- /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */
- /* 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
- /* 0:H, 1:L */
- pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1]; /* VO */
- pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0]; /* VI */
- pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1]; /* BE */
- pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0]; /* BK */
-
- pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */
- pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */
- pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */
- pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/
- } else { /* typical setting */
- /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */
- /* 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
- /* 0:H, 1:L */
- pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */
- pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0]; /* VI */
- pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1]; /* BE */
- pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1]; /* BK */
-
- pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */
- pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */
- pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */
- pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/
- }
-}
-
-static void _ThreeOutPipeMapping(struct rtw_adapter *pAdapter, bool bWIFICfg)
-{
- struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
-
- if (bWIFICfg) { /* for WMM */
- /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */
- /* 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
- /* 0:H, 1:N, 2:L */
- pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */
- pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1]; /* VI */
- pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2]; /* BE */
- pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1]; /* BK */
-
- pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */
- pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */
- pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */
- pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/
- } else { /* typical setting */
- /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */
- /* 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
- /* 0:H, 1:N, 2:L */
- pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */
- pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1]; /* VI */
- pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2]; /* BE */
- pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2]; /* BK */
-
- pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */
- pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */
- pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */
- pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/
- }
-}
-
-bool Hal_MappingOutPipe23a(struct rtw_adapter *pAdapter, u8 NumOutPipe)
-{
- struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
- bool bWIFICfg = (pregistrypriv->wifi_spec) ? true : false;
- bool result = true;
-
- switch (NumOutPipe) {
- case 2:
- _TwoOutPipeMapping(pAdapter, bWIFICfg);
- break;
- case 3:
- _ThreeOutPipeMapping(pAdapter, bWIFICfg);
- break;
- case 1:
- _OneOutPipeMapping(pAdapter);
- break;
- default:
- result = false;
- break;
- }
-
- return result;
-}
-
-/*
-* C2H event format:
-* Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID
-* BITS [127:120] [119:16] [15:8] [7:4] [3:0]
-*/
-
-void c2h_evt_clear23a(struct rtw_adapter *adapter)
-{
- rtl8723au_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
-}
-
-int c2h_evt_read23a(struct rtw_adapter *adapter, u8 *buf)
-{
- int ret = _FAIL;
- struct c2h_evt_hdr *c2h_evt;
- int i;
- u8 trigger;
-
- if (buf == NULL)
- goto exit;
-
- trigger = rtl8723au_read8(adapter, REG_C2HEVT_CLEAR);
-
- if (trigger == C2H_EVT_HOST_CLOSE)
- goto exit; /* Not ready */
- if (trigger != C2H_EVT_FW_CLOSE)
- goto clear_evt; /* Not a valid value */
-
- c2h_evt = (struct c2h_evt_hdr *)buf;
-
- memset(c2h_evt, 0, 16);
-
- *buf = rtl8723au_read8(adapter, REG_C2HEVT_MSG_NORMAL);
- *(buf + 1) = rtl8723au_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);
-
- RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read23a(): ",
- &c2h_evt, sizeof(c2h_evt));
-
- if (0) {
- DBG_8723A("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n",
- __func__, c2h_evt->id, c2h_evt->plen, c2h_evt->seq,
- trigger);
- }
-
- /* Read the content */
- for (i = 0; i < c2h_evt->plen; i++)
- c2h_evt->payload[i] = rtl8723au_read8(adapter,
- REG_C2HEVT_MSG_NORMAL +
- sizeof(*c2h_evt) + i);
-
- RT_PRINT_DATA(_module_hal_init_c_, _drv_info_,
- "c2h_evt_read23a(): Command Content:\n", c2h_evt->payload,
- c2h_evt->plen);
-
- ret = _SUCCESS;
-
-clear_evt:
- /*
- * Clear event to notify FW we have read the command.
- * If this field isn't clear, the FW won't update the
- * next command message.
- */
- c2h_evt_clear23a(adapter);
-exit:
- return ret;
-}
-
-void
-rtl8723a_set_ampdu_min_space(struct rtw_adapter *padapter, u8 MinSpacingToSet)
-{
- u8 SecMinSpace;
-
- if (MinSpacingToSet <= 7) {
- switch (padapter->securitypriv.dot11PrivacyAlgrthm) {
- case 0:
- case WLAN_CIPHER_SUITE_CCMP:
- SecMinSpace = 0;
- break;
-
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- case WLAN_CIPHER_SUITE_TKIP:
- SecMinSpace = 6;
- break;
- default:
- SecMinSpace = 7;
- break;
- }
-
- if (MinSpacingToSet < SecMinSpace)
- MinSpacingToSet = SecMinSpace;
-
- MinSpacingToSet |=
- rtl8723au_read8(padapter, REG_AMPDU_MIN_SPACE) & 0xf8;
- rtl8723au_write8(padapter, REG_AMPDU_MIN_SPACE,
- MinSpacingToSet);
- }
-}
-
-void rtl8723a_set_ampdu_factor(struct rtw_adapter *padapter, u8 FactorToSet)
-{
- u8 RegToSet_Normal[4] = { 0x41, 0xa8, 0x72, 0xb9 };
- u8 MaxAggNum;
- u8 *pRegToSet;
- u8 index = 0;
-
- pRegToSet = RegToSet_Normal; /* 0xb972a841; */
-
- if (rtl8723a_BT_enabled(padapter) &&
- rtl8723a_BT_using_antenna_1(padapter))
- MaxAggNum = 0x8;
- else
- MaxAggNum = 0xF;
-
- if (FactorToSet <= 3) {
- FactorToSet = 1 << (FactorToSet + 2);
- if (FactorToSet > MaxAggNum)
- FactorToSet = MaxAggNum;
-
- for (index = 0; index < 4; index++) {
- if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4))
- pRegToSet[index] = (pRegToSet[index] & 0x0f) |
- (FactorToSet << 4);
-
- if ((pRegToSet[index] & 0x0f) > FactorToSet)
- pRegToSet[index] = (pRegToSet[index] & 0xf0) |
- FactorToSet;
-
- rtl8723au_write8(padapter, REG_AGGLEN_LMT + index,
- pRegToSet[index]);
- }
- }
-}
-
-void rtl8723a_set_acm_ctrl(struct rtw_adapter *padapter, u8 ctrl)
-{
- u8 hwctrl = 0;
-
- if (ctrl != 0) {
- hwctrl |= AcmHw_HwEn;
-
- if (ctrl & BIT(1)) /* BE */
- hwctrl |= AcmHw_BeqEn;
-
- if (ctrl & BIT(2)) /* VI */
- hwctrl |= AcmHw_ViqEn;
-
- if (ctrl & BIT(3)) /* VO */
- hwctrl |= AcmHw_VoqEn;
- }
-
- DBG_8723A("[HW_VAR_ACM_CTRL] Write 0x%02X\n", hwctrl);
- rtl8723au_write8(padapter, REG_ACMHWCTRL, hwctrl);
-}
-
-void rtl8723a_set_media_status(struct rtw_adapter *padapter, u8 status)
-{
- u8 val8;
-
- val8 = rtl8723au_read8(padapter, MSR) & 0x0c;
- val8 |= status;
- rtl8723au_write8(padapter, MSR, val8);
-}
-
-void rtl8723a_set_media_status1(struct rtw_adapter *padapter, u8 status)
-{
- u8 val8;
-
- val8 = rtl8723au_read8(padapter, MSR) & 0x03;
- val8 |= status << 2;
- rtl8723au_write8(padapter, MSR, val8);
-}
-
-void rtl8723a_set_bcn_func(struct rtw_adapter *padapter, u8 val)
-{
- if (val)
- SetBcnCtrlReg23a(padapter, EN_BCN_FUNCTION | EN_TXBCN_RPT, 0);
- else
- SetBcnCtrlReg23a(padapter, 0, EN_BCN_FUNCTION | EN_TXBCN_RPT);
-}
-
-void rtl8723a_check_bssid(struct rtw_adapter *padapter, u8 val)
-{
- u32 val32;
-
- val32 = rtl8723au_read32(padapter, REG_RCR);
- if (val)
- val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
- else
- val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
- rtl8723au_write32(padapter, REG_RCR, val32);
-}
-
-void rtl8723a_mlme_sitesurvey(struct rtw_adapter *padapter, u8 flag)
-{
- if (flag) { /* under sitesurvey */
- u32 v32;
-
- /* config RCR to receive different BSSID & not
- to receive data frame */
- v32 = rtl8723au_read32(padapter, REG_RCR);
- v32 &= ~(RCR_CBSSID_BCN);
- rtl8723au_write32(padapter, REG_RCR, v32);
- /* reject all data frame */
- rtl8723au_write16(padapter, REG_RXFLTMAP2, 0);
-
- /* disable update TSF */
- SetBcnCtrlReg23a(padapter, DIS_TSF_UDT, 0);
- } else { /* sitesurvey done */
-
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo;
- u32 v32;
-
- pmlmeinfo = &pmlmeext->mlmext_info;
-
- if ((is_client_associated_to_ap23a(padapter) == true) ||
- ((pmlmeinfo->state & 0x03) == MSR_ADHOC) ||
- ((pmlmeinfo->state & 0x03) == MSR_AP)) {
- /* enable to rx data frame */
- rtl8723au_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
-
- /* enable update TSF */
- SetBcnCtrlReg23a(padapter, 0, DIS_TSF_UDT);
- }
-
- v32 = rtl8723au_read32(padapter, REG_RCR);
- v32 |= RCR_CBSSID_BCN;
- rtl8723au_write32(padapter, REG_RCR, v32);
- }
-
- rtl8723a_BT_wifiscan_notify(padapter, flag ? true : false);
-}
-
-void rtl8723a_on_rcr_am(struct rtw_adapter *padapter)
-{
- rtl8723au_write32(padapter, REG_RCR,
- rtl8723au_read32(padapter, REG_RCR) | RCR_AM);
- DBG_8723A("%s, %d, RCR = %x\n", __func__, __LINE__,
- rtl8723au_read32(padapter, REG_RCR));
-}
-
-void rtl8723a_off_rcr_am(struct rtw_adapter *padapter)
-{
- rtl8723au_write32(padapter, REG_RCR,
- rtl8723au_read32(padapter, REG_RCR) & (~RCR_AM));
- DBG_8723A("%s, %d, RCR = %x\n", __func__, __LINE__,
- rtl8723au_read32(padapter, REG_RCR));
-}
-
-void rtl8723a_set_slot_time(struct rtw_adapter *padapter, u8 slottime)
-{
- u8 u1bAIFS, aSifsTime;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- rtl8723au_write8(padapter, REG_SLOT, slottime);
-
- if (pmlmeinfo->WMM_enable == 0) {
- if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
- aSifsTime = 10;
- else
- aSifsTime = 16;
-
- u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
-
- /* <Roger_EXP> Temporary removed, 2008.06.20. */
- rtl8723au_write8(padapter, REG_EDCA_VO_PARAM, u1bAIFS);
- rtl8723au_write8(padapter, REG_EDCA_VI_PARAM, u1bAIFS);
- rtl8723au_write8(padapter, REG_EDCA_BE_PARAM, u1bAIFS);
- rtl8723au_write8(padapter, REG_EDCA_BK_PARAM, u1bAIFS);
- }
-}
-
-void rtl8723a_ack_preamble(struct rtw_adapter *padapter, u8 bShortPreamble)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 regTmp;
-
- /* Joseph marked out for Netgear 3500 TKIP
- channel 7 issue.(Temporarily) */
- regTmp = (pHalData->nCur40MhzPrimeSC) << 5;
- /* regTmp = 0; */
- if (bShortPreamble)
- regTmp |= 0x80;
- rtl8723au_write8(padapter, REG_RRSR + 2, regTmp);
-}
-
-void rtl8723a_set_sec_cfg(struct rtw_adapter *padapter, u8 sec)
-{
- rtl8723au_write8(padapter, REG_SECCFG, sec);
-}
-
-void rtl8723a_cam_empty_entry(struct rtw_adapter *padapter, u8 ucIndex)
-{
- u8 i;
- u32 ulCommand = 0;
- u32 ulContent = 0;
- u32 ulEncAlgo = CAM_AES;
-
- for (i = 0; i < CAM_CONTENT_COUNT; i++) {
- /* filled id in CAM config 2 byte */
- if (i == 0) {
- ulContent |= (ucIndex & 0x03) |
- ((u16) (ulEncAlgo) << 2);
- /* ulContent |= CAM_VALID; */
- } else {
- ulContent = 0;
- }
- /* polling bit, and No Write enable, and address */
- ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
- ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
- /* write content 0 is equall to mark invalid */
- /* delay_ms(40); */
- rtl8723au_write32(padapter, WCAMI, ulContent);
- /* delay_ms(40); */
- rtl8723au_write32(padapter, REG_CAMCMD, ulCommand);
- }
-}
-
-void rtl8723a_cam_invalidate_all(struct rtw_adapter *padapter)
-{
- rtl8723au_write32(padapter, REG_CAMCMD, CAM_POLLINIG | BIT(30));
-}
-
-void rtl8723a_cam_write(struct rtw_adapter *padapter,
- u8 entry, u16 ctrl, const u8 *mac, const u8 *key)
-{
- u32 cmd;
- unsigned int i, val, addr;
- int j;
-
- addr = entry << 3;
-
- for (j = 5; j >= 0; j--) {
- switch (j) {
- case 0:
- val = ctrl | (mac[0] << 16) | (mac[1] << 24);
- break;
- case 1:
- val = mac[2] | (mac[3] << 8) |
- (mac[4] << 16) | (mac[5] << 24);
- break;
- default:
- i = (j - 2) << 2;
- val = key[i] | (key[i+1] << 8) |
- (key[i+2] << 16) | (key[i+3] << 24);
- break;
- }
-
- rtl8723au_write32(padapter, WCAMI, val);
- cmd = CAM_POLLINIG | CAM_WRITE | (addr + j);
- rtl8723au_write32(padapter, REG_CAMCMD, cmd);
-
- /* DBG_8723A("%s => cam write: %x, %x\n", __func__, cmd, val);*/
- }
-}
-
-void rtl8723a_fifo_cleanup(struct rtw_adapter *padapter)
-{
-#define RW_RELEASE_EN BIT(18)
-#define RXDMA_IDLE BIT(17)
-
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- u8 trycnt = 100;
-
- /* pause tx */
- rtl8723au_write8(padapter, REG_TXPAUSE, 0xff);
-
- /* keep sn */
- padapter->xmitpriv.nqos_ssn = rtl8723au_read8(padapter, REG_NQOS_SEQ);
-
- if (pwrpriv->bkeepfwalive != true) {
- u32 v32;
-
- /* RX DMA stop */
- v32 = rtl8723au_read32(padapter, REG_RXPKT_NUM);
- v32 |= RW_RELEASE_EN;
- rtl8723au_write32(padapter, REG_RXPKT_NUM, v32);
- do {
- v32 = rtl8723au_read32(padapter,
- REG_RXPKT_NUM) & RXDMA_IDLE;
- if (!v32)
- break;
- } while (trycnt--);
- if (trycnt == 0)
- DBG_8723A("Stop RX DMA failed......\n");
-
- /* RQPN Load 0 */
- rtl8723au_write16(padapter, REG_RQPN_NPQ, 0);
- rtl8723au_write32(padapter, REG_RQPN, 0x80000000);
- mdelay(10);
- }
-}
-
-void rtl8723a_bcn_valid(struct rtw_adapter *padapter)
-{
- /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2,
- write 1 to clear, Clear by sw */
- rtl8723au_write8(padapter, REG_TDECTRL + 2,
- rtl8723au_read8(padapter, REG_TDECTRL + 2) | BIT(0));
-}
-
-bool rtl8723a_get_bcn_valid(struct rtw_adapter *padapter)
-{
- bool retval;
-
- retval = (rtl8723au_read8(padapter, REG_TDECTRL + 2) & BIT(0)) ? true : false;
-
- return retval;
-}
-
-void rtl8723a_set_beacon_interval(struct rtw_adapter *padapter, u16 interval)
-{
- rtl8723au_write16(padapter, REG_BCN_INTERVAL, interval);
-}
-
-void rtl8723a_set_resp_sifs(struct rtw_adapter *padapter,
- u8 r2t1, u8 r2t2, u8 t2t1, u8 t2t2)
-{
- /* SIFS_Timer = 0x0a0a0808; */
- /* RESP_SIFS for CCK */
- /* SIFS_T2T_CCK (0x08) */
- rtl8723au_write8(padapter, REG_R2T_SIFS, r2t1);
- /* SIFS_R2T_CCK(0x08) */
- rtl8723au_write8(padapter, REG_R2T_SIFS + 1, r2t2);
- /* RESP_SIFS for OFDM */
- /* SIFS_T2T_OFDM (0x0a) */
- rtl8723au_write8(padapter, REG_T2T_SIFS, t2t1);
- /* SIFS_R2T_OFDM(0x0a) */
- rtl8723au_write8(padapter, REG_T2T_SIFS + 1, t2t2);
-}
-
-void rtl8723a_set_ac_param_vo(struct rtw_adapter *padapter, u32 vo)
-{
- rtl8723au_write32(padapter, REG_EDCA_VO_PARAM, vo);
-}
-
-void rtl8723a_set_ac_param_vi(struct rtw_adapter *padapter, u32 vi)
-{
- rtl8723au_write32(padapter, REG_EDCA_VI_PARAM, vi);
-}
-
-void rtl8723a_set_ac_param_be(struct rtw_adapter *padapter, u32 be)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- pHalData->AcParam_BE = be;
- rtl8723au_write32(padapter, REG_EDCA_BE_PARAM, be);
-}
-
-void rtl8723a_set_ac_param_bk(struct rtw_adapter *padapter, u32 bk)
-{
- rtl8723au_write32(padapter, REG_EDCA_BK_PARAM, bk);
-}
-
-void rtl8723a_set_rxdma_agg_pg_th(struct rtw_adapter *padapter, u8 val)
-{
- rtl8723au_write8(padapter, REG_RXDMA_AGG_PG_TH, val);
-}
-
-void rtl8723a_set_initial_gain(struct rtw_adapter *padapter, u32 rx_gain)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct dig_t *pDigTable = &pHalData->odmpriv.DM_DigTable;
-
- if (rx_gain == 0xff) /* restore rx gain */
- ODM_Write_DIG23a(&pHalData->odmpriv, pDigTable->BackupIGValue);
- else {
- pDigTable->BackupIGValue = pDigTable->CurIGValue;
- ODM_Write_DIG23a(&pHalData->odmpriv, rx_gain);
- }
-}
-
-void rtl8723a_odm_support_ability_restore(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- pHalData->odmpriv.SupportAbility = pHalData->odmpriv.BK_SupportAbility;
-}
-
-void rtl8723a_odm_support_ability_backup(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- pHalData->odmpriv.BK_SupportAbility = pHalData->odmpriv.SupportAbility;
-}
-
-void rtl8723a_odm_support_ability_set(struct rtw_adapter *padapter, u32 val)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (val == DYNAMIC_ALL_FUNC_ENABLE)
- pHalData->odmpriv.SupportAbility = pHalData->dmpriv.InitODMFlag;
- else
- pHalData->odmpriv.SupportAbility |= val;
-}
-
-void rtl8723a_odm_support_ability_clr(struct rtw_adapter *padapter, u32 val)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- pHalData->odmpriv.SupportAbility &= val;
-}
-
-void rtl8723a_set_rpwm(struct rtw_adapter *padapter, u8 val)
-{
- rtl8723au_write8(padapter, REG_USB_HRPWM, val);
-}
-
-u8 rtl8723a_get_rf_type(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- return pHalData->rf_type;
-}
-
-bool rtl8723a_get_fwlps_rf_on(struct rtw_adapter *padapter)
-{
- bool retval;
- u32 valRCR;
-
- /* When we halt NIC, we should check if FW LPS is leave. */
-
- if ((padapter->bSurpriseRemoved == true) ||
- (padapter->pwrctrlpriv.rf_pwrstate == rf_off)) {
- /* If it is in HW/SW Radio OFF or IPS state, we do
- not check Fw LPS Leave, because Fw is unload. */
- retval = true;
- } else {
- valRCR = rtl8723au_read32(padapter, REG_RCR);
- if (valRCR & 0x00070000)
- retval = false;
- else
- retval = true;
- }
-
- return retval;
-}
-
-bool rtl8723a_chk_hi_queue_empty(struct rtw_adapter *padapter)
-{
- u32 hgq;
-
- hgq = rtl8723au_read32(padapter, REG_HGQ_INFORMATION);
-
- return ((hgq & 0x0000ff00) == 0) ? true : false;
-}
diff --git a/drivers/staging/rtl8723au/hal/hal_intf.c b/drivers/staging/rtl8723au/hal/hal_intf.c
deleted file mode 100644
index 5383e692546f..000000000000
--- a/drivers/staging/rtl8723au/hal/hal_intf.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-#define _HAL_INTF_C_
-#include <osdep_service.h>
-#include <drv_types.h>
-
-#include <hal_intf.h>
-
-#include <rtl8723a_hal.h>
-
-void rtw_hal_update_ra_mask23a(struct sta_info *psta, u8 rssi_level)
-{
- struct rtw_adapter *padapter;
- struct mlme_priv *pmlmepriv;
-
- if (!psta)
- return;
-
- padapter = psta->padapter;
-
- pmlmepriv = &padapter->mlmepriv;
-
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-#ifdef CONFIG_8723AU_AP_MODE
- add_RATid23a(padapter, psta, rssi_level);
-#endif
- } else
- rtl8723a_update_ramask(padapter, psta->mac_id, rssi_level);
-}
diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c
deleted file mode 100644
index e279c34b3fc6..000000000000
--- a/drivers/staging/rtl8723au/hal/odm.c
+++ /dev/null
@@ -1,1732 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-#include "odm_precomp.h"
-#include "usb_ops_linux.h"
-
-static const u16 dB_Invert_Table[8][12] = {
- {1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4},
- {4, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16},
- {18, 20, 22, 25, 28, 32, 35, 40, 45, 50, 56, 63},
- {71, 79, 89, 100, 112, 126, 141, 158, 178, 200, 224, 251},
- {282, 316, 355, 398, 447, 501, 562, 631, 708, 794, 891, 1000},
- {1122, 1259, 1413, 1585, 1778, 1995, 2239, 2512, 2818, 3162, 3548, 3981},
- {4467, 5012, 5623, 6310, 7079, 7943, 8913, 10000, 11220, 12589, 14125, 15849},
- {17783, 19953, 22387, 25119, 28184, 31623, 35481, 39811, 44668, 50119, 56234, 65535}
-};
-
-static u32 EDCAParam[HT_IOT_PEER_MAX][3] = { /* UL DL */
- {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 0:unknown AP */
- {0xa44f, 0x5ea44f, 0x5e431c}, /* 1:realtek AP */
- {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 2:unknown AP => realtek_92SE */
- {0x5ea32b, 0x5ea42b, 0x5e4322}, /* 3:broadcom AP */
- {0x5ea422, 0x00a44f, 0x00a44f}, /* 4:ralink AP */
- {0x5ea322, 0x00a630, 0x00a44f}, /* 5:atheros AP */
- {0x5e4322, 0x5e4322, 0x5e4322},/* 6:cisco AP */
- {0x5ea44f, 0x00a44f, 0x5ea42b}, /* 8:marvell AP */
- {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 10:unknown AP => 92U AP */
- {0x5ea42b, 0xa630, 0x5e431c}, /* 11:airgocap AP */
-};
-
-/* EDCA Parameter for AP/ADSL by Mingzhi 2011-11-22 */
-
-/* Global var */
-u32 OFDMSwingTable23A[OFDM_TABLE_SIZE_92D] = {
- 0x7f8001fe, /* 0, +6.0dB */
- 0x788001e2, /* 1, +5.5dB */
- 0x71c001c7, /* 2, +5.0dB */
- 0x6b8001ae, /* 3, +4.5dB */
- 0x65400195, /* 4, +4.0dB */
- 0x5fc0017f, /* 5, +3.5dB */
- 0x5a400169, /* 6, +3.0dB */
- 0x55400155, /* 7, +2.5dB */
- 0x50800142, /* 8, +2.0dB */
- 0x4c000130, /* 9, +1.5dB */
- 0x47c0011f, /* 10, +1.0dB */
- 0x43c0010f, /* 11, +0.5dB */
- 0x40000100, /* 12, +0dB */
- 0x3c8000f2, /* 13, -0.5dB */
- 0x390000e4, /* 14, -1.0dB */
- 0x35c000d7, /* 15, -1.5dB */
- 0x32c000cb, /* 16, -2.0dB */
- 0x300000c0, /* 17, -2.5dB */
- 0x2d4000b5, /* 18, -3.0dB */
- 0x2ac000ab, /* 19, -3.5dB */
- 0x288000a2, /* 20, -4.0dB */
- 0x26000098, /* 21, -4.5dB */
- 0x24000090, /* 22, -5.0dB */
- 0x22000088, /* 23, -5.5dB */
- 0x20000080, /* 24, -6.0dB */
- 0x1e400079, /* 25, -6.5dB */
- 0x1c800072, /* 26, -7.0dB */
- 0x1b00006c, /* 27. -7.5dB */
- 0x19800066, /* 28, -8.0dB */
- 0x18000060, /* 29, -8.5dB */
- 0x16c0005b, /* 30, -9.0dB */
- 0x15800056, /* 31, -9.5dB */
- 0x14400051, /* 32, -10.0dB */
- 0x1300004c, /* 33, -10.5dB */
- 0x12000048, /* 34, -11.0dB */
- 0x11000044, /* 35, -11.5dB */
- 0x10000040, /* 36, -12.0dB */
- 0x0f00003c,/* 37, -12.5dB */
- 0x0e400039,/* 38, -13.0dB */
- 0x0d800036,/* 39, -13.5dB */
- 0x0cc00033,/* 40, -14.0dB */
- 0x0c000030,/* 41, -14.5dB */
- 0x0b40002d,/* 42, -15.0dB */
-};
-
-u8 CCKSwingTable_Ch1_Ch1323A[CCK_TABLE_SIZE][8] = {
- {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */
- {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */
- {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */
- {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */
- {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */
- {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */
- {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */
- {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */
- {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */
- {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */
- {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */
- {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */
- {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */
- {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */
- {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */
- {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */
- {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
- {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */
- {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */
- {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */
- {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB */
- {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB */
- {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB */
- {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB */
- {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB */
- {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB */
- {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB */
- {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB */
- {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB */
- {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB */
- {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB */
- {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB */
- {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB */
-};
-
-u8 CCKSwingTable_Ch1423A[CCK_TABLE_SIZE][8] = {
- {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */
- {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */
- {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */
- {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */
- {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */
- {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */
- {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */
- {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */
- {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */
- {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */
- {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */
- {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */
- {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */
- {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */
- {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */
- {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */
- {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
- {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */
- {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */
- {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */
- {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB */
- {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB */
- {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB */
- {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB */
- {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB */
- {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB */
- {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB */
- {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB */
- {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB */
- {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB */
- {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB */
- {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB */
- {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB */
-};
-
-/* Local Function predefine. */
-
-/* START------------COMMON INFO RELATED--------------- */
-void odm_CommonInfoSelfInit23a(struct dm_odm_t *pDM_Odm);
-
-static void odm_CommonInfoSelfUpdate(struct hal_data_8723a *pHalData);
-
-void odm_CmnInfoInit_Debug23a(struct dm_odm_t *pDM_Odm);
-
-void odm_CmnInfoUpdate_Debug23a(struct dm_odm_t *pDM_Odm);
-
-/* START---------------DIG--------------------------- */
-void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm);
-
-void odm_DIG23aInit(struct dm_odm_t *pDM_Odm);
-
-void odm_DIG23a(struct rtw_adapter *adapter);
-
-void odm_CCKPacketDetectionThresh23a(struct dm_odm_t *pDM_Odm);
-/* END---------------DIG--------------------------- */
-
-/* START-------BB POWER SAVE----------------------- */
-void odm23a_DynBBPSInit(struct dm_odm_t *pDM_Odm);
-
-
-/* END---------BB POWER SAVE----------------------- */
-
-void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm);
-
-static void odm_RSSIMonitorCheck(struct dm_odm_t *pDM_Odm);
-void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm);
-
-static void odm_RefreshRateAdaptiveMask(struct dm_odm_t *pDM_Odm);
-
-void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm);
-
-static void odm_TXPowerTrackingInit(struct dm_odm_t *pDM_Odm);
-
-static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm);
-static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm);
-
-#define RxDefaultAnt1 0x65a9
-#define RxDefaultAnt2 0x569a
-
-bool odm_StaDefAntSel(struct dm_odm_t *pDM_Odm,
- u32 OFDM_Ant1_Cnt,
- u32 OFDM_Ant2_Cnt,
- u32 CCK_Ant1_Cnt,
- u32 CCK_Ant2_Cnt,
- u8 *pDefAnt
- );
-
-void odm_SetRxIdleAnt(struct dm_odm_t *pDM_Odm,
- u8 Ant,
- bool bDualPath
-);
-
-/* 3 Export Interface */
-
-/* 2011/09/21 MH Add to describe different team necessary resource allocate?? */
-void ODM23a_DMInit(struct dm_odm_t *pDM_Odm)
-{
- /* For all IC series */
- odm_CommonInfoSelfInit23a(pDM_Odm);
- odm_CmnInfoInit_Debug23a(pDM_Odm);
- odm_DIG23aInit(pDM_Odm);
- odm_RateAdaptiveMaskInit23a(pDM_Odm);
-
- odm23a_DynBBPSInit(pDM_Odm);
- odm_DynamicTxPower23aInit(pDM_Odm);
- odm_TXPowerTrackingInit(pDM_Odm);
- ODM_EdcaTurboInit23a(pDM_Odm);
-}
-
-/* 2011/09/20 MH This is the entry pointer for all team to execute HW out source DM. */
-/* You can not add any dummy function here, be care, you can only use DM structure */
-/* to perform any new ODM_DM. */
-void ODM_DMWatchdog23a(struct rtw_adapter *adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(adapter);
- struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
- struct pwrctrl_priv *pwrctrlpriv = &adapter->pwrctrlpriv;
-
- /* 2012.05.03 Luke: For all IC series */
- odm_CmnInfoUpdate_Debug23a(pDM_Odm);
- odm_CommonInfoSelfUpdate(pHalData);
- odm_FalseAlarmCounterStatistics23a(pDM_Odm);
- odm_RSSIMonitorCheck(pDM_Odm);
-
- /* 8723A or 8189ES platform */
- /* NeilChen--2012--08--24-- */
- /* Fix Leave LPS issue */
- if ((pDM_Odm->Adapter->pwrctrlpriv.pwr_mode != PS_MODE_ACTIVE) &&/* in LPS mode */
- (pDM_Odm->SupportICType & ODM_RTL8723A)) {
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("----Step1: odm_DIG23a is in LPS mode\n"));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("---Step2: 8723AS is in LPS mode\n"));
- odm_DIG23abyRSSI_LPS(pDM_Odm);
- } else {
- odm_DIG23a(adapter);
- }
-
- odm_CCKPacketDetectionThresh23a(pDM_Odm);
-
- if (pwrctrlpriv->bpower_saving)
- return;
-
- odm_RefreshRateAdaptiveMask(pDM_Odm);
-
-
- odm_EdcaTurboCheck23a(pDM_Odm);
-}
-
-/* */
-/* Init /.. Fixed HW value. Only init time. */
-/* */
-void ODM_CmnInfoInit23a(struct dm_odm_t *pDM_Odm,
- enum odm_cmninfo CmnInfo,
- u32 Value
- )
-{
- /* ODM_RT_TRACE(pDM_Odm,); */
-
- /* */
- /* This section is used for init value */
- /* */
- switch (CmnInfo) {
- /* Fixed ODM value. */
- case ODM_CMNINFO_MP_TEST_CHIP:
- pDM_Odm->bIsMPChip = (u8)Value;
- break;
- case ODM_CMNINFO_IC_TYPE:
- pDM_Odm->SupportICType = Value;
- break;
- case ODM_CMNINFO_CUT_VER:
- pDM_Odm->CutVersion = (u8)Value;
- break;
- case ODM_CMNINFO_FAB_VER:
- pDM_Odm->FabVersion = (u8)Value;
- break;
- case ODM_CMNINFO_BOARD_TYPE:
- pDM_Odm->BoardType = (u8)Value;
- break;
- case ODM_CMNINFO_EXT_LNA:
- pDM_Odm->ExtLNA = (u8)Value;
- break;
- case ODM_CMNINFO_EXT_PA:
- pDM_Odm->ExtPA = (u8)Value;
- break;
- case ODM_CMNINFO_EXT_TRSW:
- pDM_Odm->ExtTRSW = (u8)Value;
- break;
- case ODM_CMNINFO_BINHCT_TEST:
- pDM_Odm->bInHctTest = (bool)Value;
- break;
- case ODM_CMNINFO_BWIFI_TEST:
- pDM_Odm->bWIFITest = (bool)Value;
- break;
- case ODM_CMNINFO_SMART_CONCURRENT:
- pDM_Odm->bDualMacSmartConcurrent = (bool)Value;
- break;
- /* To remove the compiler warning, must add an empty default statement to handle the other values. */
- default:
- /* do nothing */
- break;
- }
-}
-
-void ODM_CmnInfoPtrArrayHook23a(struct dm_odm_t *pDM_Odm, enum odm_cmninfo CmnInfo,
- u16 Index, void *pValue)
-{
- /* Hook call by reference pointer. */
- switch (CmnInfo) {
- /* Dynamic call by reference pointer. */
- case ODM_CMNINFO_STA_STATUS:
- pDM_Odm->pODM_StaInfo[Index] = (struct sta_info *)pValue;
- break;
- /* To remove the compiler warning, must add an empty default statement to handle the other values. */
- default:
- /* do nothing */
- break;
- }
-}
-
-/* Update Band/CHannel/.. The values are dynamic but non-per-packet. */
-void ODM_CmnInfoUpdate23a(struct dm_odm_t *pDM_Odm, u32 CmnInfo, u64 Value)
-{
- /* This init variable may be changed in run time. */
- switch (CmnInfo) {
- case ODM_CMNINFO_WIFI_DIRECT:
- pDM_Odm->bWIFI_Direct = (bool)Value;
- break;
- case ODM_CMNINFO_WIFI_DISPLAY:
- pDM_Odm->bWIFI_Display = (bool)Value;
- break;
- case ODM_CMNINFO_LINK:
- pDM_Odm->bLinked = (bool)Value;
- break;
- case ODM_CMNINFO_RSSI_MIN:
- pDM_Odm->RSSI_Min = (u8)Value;
- break;
- case ODM_CMNINFO_DBG_COMP:
- pDM_Odm->DebugComponents = Value;
- break;
- case ODM_CMNINFO_DBG_LEVEL:
- pDM_Odm->DebugLevel = (u32)Value;
- break;
- case ODM_CMNINFO_RA_THRESHOLD_HIGH:
- pDM_Odm->RateAdaptive.HighRSSIThresh = (u8)Value;
- break;
- case ODM_CMNINFO_RA_THRESHOLD_LOW:
- pDM_Odm->RateAdaptive.LowRSSIThresh = (u8)Value;
- break;
- }
-
-}
-
-void odm_CommonInfoSelfInit23a(struct dm_odm_t *pDM_Odm)
-{
- u32 val32;
-
- val32 = rtl8723au_read32(pDM_Odm->Adapter, rFPGA0_XA_HSSIParameter2);
- if (val32 & BIT(9))
- pDM_Odm->bCckHighPower = true;
- else
- pDM_Odm->bCckHighPower = false;
-
- pDM_Odm->RFPathRxEnable =
- rtl8723au_read32(pDM_Odm->Adapter, rOFDM0_TRxPathEnable) & 0x0F;
-
- ODM_InitDebugSetting23a(pDM_Odm);
-}
-
-static void odm_CommonInfoSelfUpdate(struct hal_data_8723a *pHalData)
-{
- struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
- struct sta_info *pEntry;
- u8 EntryCnt = 0;
- u8 i;
-
- for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
- pEntry = pDM_Odm->pODM_StaInfo[i];
- if (pEntry)
- EntryCnt++;
- }
- if (EntryCnt == 1)
- pDM_Odm->bOneEntryOnly = true;
- else
- pDM_Odm->bOneEntryOnly = false;
-}
-
-void odm_CmnInfoInit_Debug23a(struct dm_odm_t *pDM_Odm)
-{
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoInit_Debug23a ==>\n"));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportAbility = 0x%x\n", pDM_Odm->SupportAbility));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportICType = 0x%x\n", pDM_Odm->SupportICType));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("CutVersion =%d\n", pDM_Odm->CutVersion));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("FabVersion =%d\n", pDM_Odm->FabVersion));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("BoardType =%d\n", pDM_Odm->BoardType));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtLNA =%d\n", pDM_Odm->ExtLNA));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtPA =%d\n", pDM_Odm->ExtPA));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtTRSW =%d\n", pDM_Odm->ExtTRSW));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bInHctTest =%d\n", pDM_Odm->bInHctTest));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bWIFITest =%d\n", pDM_Odm->bWIFITest));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bDualMacSmartConcurrent =%d\n", pDM_Odm->bDualMacSmartConcurrent));
-
-}
-
-void odm_CmnInfoUpdate_Debug23a(struct dm_odm_t *pDM_Odm)
-{
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoUpdate_Debug23a ==>\n"));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bWIFI_Direct =%d\n", pDM_Odm->bWIFI_Direct));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bWIFI_Display =%d\n", pDM_Odm->bWIFI_Display));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bLinked =%d\n", pDM_Odm->bLinked));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("RSSI_Min =%d\n", pDM_Odm->RSSI_Min));
-}
-
-void ODM_Write_DIG23a(struct dm_odm_t *pDM_Odm, u8 CurrentIGI)
-{
- struct rtw_adapter *adapter = pDM_Odm->Adapter;
- struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
- u32 val32;
-
- if (pDM_DigTable->CurIGValue != CurrentIGI) {
- val32 = rtl8723au_read32(adapter, ODM_REG_IGI_A_11N);
- val32 &= ~ODM_BIT_IGI_11N;
- val32 |= CurrentIGI;
- rtl8723au_write32(adapter, ODM_REG_IGI_A_11N, val32);
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
- ("CurrentIGI(0x%02x). \n", CurrentIGI));
- pDM_DigTable->CurIGValue = CurrentIGI;
- }
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
- ("ODM_Write_DIG23a():CurrentIGI = 0x%x \n", CurrentIGI));
-}
-
-/* Need LPS mode for CE platform --2012--08--24--- */
-/* 8723AS/8189ES */
-void odm_DIG23abyRSSI_LPS(struct dm_odm_t *pDM_Odm)
-{
- struct rtw_adapter *pAdapter = pDM_Odm->Adapter;
- struct false_alarm_stats *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
- u8 RSSI_Lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */
- u8 bFwCurrentInPSMode = false;
- u8 CurrentIGI = pDM_Odm->RSSI_Min;
-
- if (!(pDM_Odm->SupportICType & ODM_RTL8723A))
- return;
-
- CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG;
- bFwCurrentInPSMode = pAdapter->pwrctrlpriv.bFwCurrentInPSMode;
-
- /* Using FW PS mode to make IGI */
- if (bFwCurrentInPSMode) {
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
- ("---Neil---odm_DIG23a is in LPS mode\n"));
- /* Adjust by FA in LPS MODE */
- if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS)
- CurrentIGI = CurrentIGI+2;
- else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS)
- CurrentIGI = CurrentIGI+1;
- else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS)
- CurrentIGI = CurrentIGI-1;
- } else {
- CurrentIGI = RSSI_Lower;
- }
-
- /* Lower bound checking */
-
- /* RSSI Lower bound check */
- if ((pDM_Odm->RSSI_Min-10) > DM_DIG_MIN_NIC)
- RSSI_Lower = (pDM_Odm->RSSI_Min-10);
- else
- RSSI_Lower = DM_DIG_MIN_NIC;
-
- /* Upper and Lower Bound checking */
- if (CurrentIGI > DM_DIG_MAX_NIC)
- CurrentIGI = DM_DIG_MAX_NIC;
- else if (CurrentIGI < RSSI_Lower)
- CurrentIGI = RSSI_Lower;
-
- ODM_Write_DIG23a(pDM_Odm, CurrentIGI);
-}
-
-void odm_DIG23aInit(struct dm_odm_t *pDM_Odm)
-{
- struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
- u32 val32;
-
- val32 = rtl8723au_read32(pDM_Odm->Adapter, ODM_REG_IGI_A_11N);
- pDM_DigTable->CurIGValue = val32 & ODM_BIT_IGI_11N;
-
- pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW;
- pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH;
- pDM_DigTable->FALowThresh = DM_FALSEALARM_THRESH_LOW;
- pDM_DigTable->FAHighThresh = DM_FALSEALARM_THRESH_HIGH;
- if (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) {
- pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
- pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
- } else {
- pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
- pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
- }
- pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT;
- pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX;
- pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN;
- pDM_DigTable->PreCCK_CCAThres = 0xFF;
- pDM_DigTable->CurCCK_CCAThres = 0x83;
- pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC;
- pDM_DigTable->LargeFAHit = 0;
- pDM_DigTable->Recover_cnt = 0;
- pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC;
- pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC;
- pDM_DigTable->bMediaConnect_0 = false;
- pDM_DigTable->bMediaConnect_1 = false;
-}
-
-void odm_DIG23a(struct rtw_adapter *adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(adapter);
- struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
- struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
- struct false_alarm_stats *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
- u8 DIG_Dynamic_MIN;
- u8 DIG_MaxOfMin;
- bool FirstConnect, FirstDisConnect;
- u8 dm_dig_max, dm_dig_min;
- u8 CurrentIGI = pDM_DigTable->CurIGValue;
-
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
- ("odm_DIG23a() ==>\n"));
- if (adapter->mlmepriv.bScanInProcess) {
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
- ("odm_DIG23a() Return: In Scan Progress \n"));
- return;
- }
-
- DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0;
- FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_0);
- FirstDisConnect = (!pDM_Odm->bLinked) &&
- (pDM_DigTable->bMediaConnect_0);
-
- /* 1 Boundary Decision */
- if ((pDM_Odm->SupportICType & ODM_RTL8723A) &&
- (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR || pDM_Odm->ExtLNA)) {
- dm_dig_max = DM_DIG_MAX_NIC_HP;
- dm_dig_min = DM_DIG_MIN_NIC_HP;
- DIG_MaxOfMin = DM_DIG_MAX_AP_HP;
- } else {
- dm_dig_max = DM_DIG_MAX_NIC;
- dm_dig_min = DM_DIG_MIN_NIC;
- DIG_MaxOfMin = DM_DIG_MAX_AP;
- }
-
- if (pDM_Odm->bLinked) {
- /* 2 8723A Series, offset need to be 10 */
- if (pDM_Odm->SupportICType == ODM_RTL8723A) {
- /* 2 Upper Bound */
- if ((pDM_Odm->RSSI_Min + 10) > DM_DIG_MAX_NIC)
- pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
- else if ((pDM_Odm->RSSI_Min + 10) < DM_DIG_MIN_NIC)
- pDM_DigTable->rx_gain_range_max = DM_DIG_MIN_NIC;
- else
- pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + 10;
-
- /* 2 If BT is Concurrent, need to set Lower Bound */
- DIG_Dynamic_MIN = DM_DIG_MIN_NIC;
- } else {
- /* 2 Modify DIG upper bound */
- if ((pDM_Odm->RSSI_Min + 20) > dm_dig_max)
- pDM_DigTable->rx_gain_range_max = dm_dig_max;
- else if ((pDM_Odm->RSSI_Min + 20) < dm_dig_min)
- pDM_DigTable->rx_gain_range_max = dm_dig_min;
- else
- pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + 20;
-
- /* 2 Modify DIG lower bound */
- if (pDM_Odm->bOneEntryOnly) {
- if (pDM_Odm->RSSI_Min < dm_dig_min)
- DIG_Dynamic_MIN = dm_dig_min;
- else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin)
- DIG_Dynamic_MIN = DIG_MaxOfMin;
- else
- DIG_Dynamic_MIN = pDM_Odm->RSSI_Min;
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
- ("odm_DIG23a() : bOneEntryOnly = true, DIG_Dynamic_MIN = 0x%x\n",
- DIG_Dynamic_MIN));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
- ("odm_DIG23a() : pDM_Odm->RSSI_Min =%d\n",
- pDM_Odm->RSSI_Min));
- } else {
- DIG_Dynamic_MIN = dm_dig_min;
- }
- }
- } else {
- pDM_DigTable->rx_gain_range_max = dm_dig_max;
- DIG_Dynamic_MIN = dm_dig_min;
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a() : No Link\n"));
- }
-
- /* 1 Modify DIG lower bound, deal with abnormally large false alarm */
- if (pFalseAlmCnt->Cnt_all > 10000) {
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
- ("dm_DIG(): Abnornally false alarm case. \n"));
-
- if (pDM_DigTable->LargeFAHit != 3)
- pDM_DigTable->LargeFAHit++;
- if (pDM_DigTable->ForbiddenIGI < CurrentIGI) {
- pDM_DigTable->ForbiddenIGI = CurrentIGI;
- pDM_DigTable->LargeFAHit = 1;
- }
-
- if (pDM_DigTable->LargeFAHit >= 3) {
- if ((pDM_DigTable->ForbiddenIGI+1) > pDM_DigTable->rx_gain_range_max)
- pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max;
- else
- pDM_DigTable->rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1);
- pDM_DigTable->Recover_cnt = 3600; /* 3600 = 2hr */
- }
- } else {
- /* Recovery mechanism for IGI lower bound */
- if (pDM_DigTable->Recover_cnt != 0) {
- pDM_DigTable->Recover_cnt--;
- } else {
- if (pDM_DigTable->LargeFAHit < 3) {
- if ((pDM_DigTable->ForbiddenIGI - 1) < DIG_Dynamic_MIN) {
- pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
- pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
- ("odm_DIG23a(): Normal Case: At Lower Bound\n"));
- } else {
- pDM_DigTable->ForbiddenIGI--;
- pDM_DigTable->rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1);
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD,
- ("odm_DIG23a(): Normal Case: Approach Lower Bound\n"));
- }
- } else {
- pDM_DigTable->LargeFAHit = 0;
- }
- }
- }
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): pDM_DigTable->LargeFAHit =%d\n", pDM_DigTable->LargeFAHit));
-
- /* 1 Adjust initial gain by false alarm */
- if (pDM_Odm->bLinked) {
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): DIG AfterLink\n"));
- if (FirstConnect) {
- CurrentIGI = pDM_Odm->RSSI_Min;
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: First Connect\n"));
- } else {
- if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2)
- CurrentIGI = CurrentIGI + 4;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */
- else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1)
- CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */
- else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0)
- CurrentIGI = CurrentIGI - 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue-1; */
- }
- } else {
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): DIG BeforeLink\n"));
- if (FirstDisConnect) {
- CurrentIGI = pDM_DigTable->rx_gain_range_min;
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): First DisConnect \n"));
- } else {
- /* 2012.03.30 LukeLee: enable DIG before link but with very high thresholds */
- if (pFalseAlmCnt->Cnt_all > 10000)
- CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */
- else if (pFalseAlmCnt->Cnt_all > 8000)
- CurrentIGI = CurrentIGI + 1;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */
- else if (pFalseAlmCnt->Cnt_all < 500)
- CurrentIGI = CurrentIGI - 1;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue-1; */
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): England DIG \n"));
- }
- }
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): DIG End Adjust IGI\n"));
- /* 1 Check initial gain by upper/lower bound */
- if (CurrentIGI > pDM_DigTable->rx_gain_range_max)
- CurrentIGI = pDM_DigTable->rx_gain_range_max;
- if (CurrentIGI < pDM_DigTable->rx_gain_range_min)
- CurrentIGI = pDM_DigTable->rx_gain_range_min;
-
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): rx_gain_range_max = 0x%x, rx_gain_range_min = 0x%x\n",
- pDM_DigTable->rx_gain_range_max, pDM_DigTable->rx_gain_range_min));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): TotalFA =%d\n", pFalseAlmCnt->Cnt_all));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): CurIGValue = 0x%x\n", CurrentIGI));
-
- /* 2 High power RSSI threshold */
-
- ODM_Write_DIG23a(pDM_Odm, CurrentIGI);/* ODM_Write_DIG23a(pDM_Odm, pDM_DigTable->CurIGValue); */
- pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked;
- pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN;
-}
-
-/* 3 ============================================================ */
-/* 3 FASLE ALARM CHECK */
-/* 3 ============================================================ */
-
-void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm)
-{
- struct rtw_adapter *adapter = pDM_Odm->Adapter;
- struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
- u32 ret_value, val32;
-
- /* hold ofdm counter */
- /* hold page C counter */
- val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_HOLDC_11N);
- val32 |= BIT(31);
- rtl8723au_write32(adapter, ODM_REG_OFDM_FA_HOLDC_11N, val32);
- /* hold page D counter */
- val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTD_11N);
- val32 |= BIT(31);
- rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTD_11N, val32);
- ret_value = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_TYPE1_11N);
- FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff);
- FalseAlmCnt->Cnt_SB_Search_fail = (ret_value & 0xffff0000)>>16;
- ret_value = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_TYPE2_11N);
- FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff);
- FalseAlmCnt->Cnt_Parity_Fail = (ret_value & 0xffff0000)>>16;
- ret_value = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_TYPE3_11N);
- FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff);
- FalseAlmCnt->Cnt_Crc8_fail = (ret_value & 0xffff0000)>>16;
- ret_value = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_TYPE4_11N);
- FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff);
-
- FalseAlmCnt->Cnt_Ofdm_fail = FalseAlmCnt->Cnt_Parity_Fail +
- FalseAlmCnt->Cnt_Rate_Illegal +
- FalseAlmCnt->Cnt_Crc8_fail +
- FalseAlmCnt->Cnt_Mcs_fail +
- FalseAlmCnt->Cnt_Fast_Fsync +
- FalseAlmCnt->Cnt_SB_Search_fail;
- /* hold cck counter */
- val32 = rtl8723au_read32(adapter, ODM_REG_CCK_FA_RST_11N);
- val32 |= (BIT(12) | BIT(14));
- rtl8723au_write32(adapter, ODM_REG_CCK_FA_RST_11N, val32);
-
- ret_value = rtl8723au_read32(adapter, ODM_REG_CCK_FA_LSB_11N) & 0xff;
- FalseAlmCnt->Cnt_Cck_fail = ret_value;
- ret_value = rtl8723au_read32(adapter, ODM_REG_CCK_FA_MSB_11N) >> 16;
- FalseAlmCnt->Cnt_Cck_fail += (ret_value & 0xff00);
-
- ret_value = rtl8723au_read32(adapter, ODM_REG_CCK_CCA_CNT_11N);
- FalseAlmCnt->Cnt_CCK_CCA =
- ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8);
-
- FalseAlmCnt->Cnt_all = (FalseAlmCnt->Cnt_Fast_Fsync +
- FalseAlmCnt->Cnt_SB_Search_fail +
- FalseAlmCnt->Cnt_Parity_Fail +
- FalseAlmCnt->Cnt_Rate_Illegal +
- FalseAlmCnt->Cnt_Crc8_fail +
- FalseAlmCnt->Cnt_Mcs_fail +
- FalseAlmCnt->Cnt_Cck_fail);
-
- FalseAlmCnt->Cnt_CCA_all =
- FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA;
-
- if (pDM_Odm->SupportICType >= ODM_RTL8723A) {
- /* reset false alarm counter registers */
- val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTC_11N);
- val32 |= BIT(31);
- rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTC_11N, val32);
- val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTC_11N);
- val32 &= ~BIT(31);
- rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTC_11N, val32);
-
- val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTD_11N);
- val32 |= BIT(27);
- rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTD_11N, val32);
- val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTD_11N);
- val32 &= ~BIT(27);
- rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTD_11N, val32);
-
- /* update ofdm counter */
- /* update page C counter */
- val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_HOLDC_11N);
- val32 &= ~BIT(31);
- rtl8723au_write32(adapter, ODM_REG_OFDM_FA_HOLDC_11N, val32);
-
- /* update page D counter */
- val32 = rtl8723au_read32(adapter, ODM_REG_OFDM_FA_RSTD_11N);
- val32 &= ~BIT(31);
- rtl8723au_write32(adapter, ODM_REG_OFDM_FA_RSTD_11N, val32);
-
- /* reset CCK CCA counter */
- val32 = rtl8723au_read32(adapter, ODM_REG_CCK_FA_RST_11N);
- val32 &= ~(BIT(12) | BIT(13) | BIT(14) | BIT(15));
- rtl8723au_write32(adapter, ODM_REG_CCK_FA_RST_11N, val32);
-
- val32 = rtl8723au_read32(adapter, ODM_REG_CCK_FA_RST_11N);
- val32 |= (BIT(13) | BIT(15));
- rtl8723au_write32(adapter, ODM_REG_CCK_FA_RST_11N, val32);
- }
-
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
- ("Enter odm_FalseAlarmCounterStatistics23a\n"));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
- ("Cnt_Fast_Fsync =%d, Cnt_SB_Search_fail =%d\n",
- FalseAlmCnt->Cnt_Fast_Fsync,
- FalseAlmCnt->Cnt_SB_Search_fail));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
- ("Cnt_Parity_Fail =%d, Cnt_Rate_Illegal =%d\n",
- FalseAlmCnt->Cnt_Parity_Fail,
- FalseAlmCnt->Cnt_Rate_Illegal));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
- ("Cnt_Crc8_fail =%d, Cnt_Mcs_fail =%d\n",
- FalseAlmCnt->Cnt_Crc8_fail, FalseAlmCnt->Cnt_Mcs_fail));
-
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
- ("Cnt_Cck_fail =%d\n", FalseAlmCnt->Cnt_Cck_fail));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
- ("Cnt_Ofdm_fail =%d\n", FalseAlmCnt->Cnt_Ofdm_fail));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
- ("Total False Alarm =%d\n", FalseAlmCnt->Cnt_all));
-}
-
-/* 3 ============================================================ */
-/* 3 CCK Packet Detect Threshold */
-/* 3 ============================================================ */
-
-void odm_CCKPacketDetectionThresh23a(struct dm_odm_t *pDM_Odm)
-{
- struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt;
- u8 CurCCK_CCAThres;
-
- if (pDM_Odm->ExtLNA)
- return;
-
- if (pDM_Odm->bLinked) {
- if (pDM_Odm->RSSI_Min > 25) {
- CurCCK_CCAThres = 0xcd;
- } else if (pDM_Odm->RSSI_Min <= 25 && pDM_Odm->RSSI_Min > 10) {
- CurCCK_CCAThres = 0x83;
- } else {
- if (FalseAlmCnt->Cnt_Cck_fail > 1000)
- CurCCK_CCAThres = 0x83;
- else
- CurCCK_CCAThres = 0x40;
- }
- } else {
- if (FalseAlmCnt->Cnt_Cck_fail > 1000)
- CurCCK_CCAThres = 0x83;
- else
- CurCCK_CCAThres = 0x40;
- }
-
- ODM_Write_CCK_CCA_Thres23a(pDM_Odm, CurCCK_CCAThres);
-}
-
-void ODM_Write_CCK_CCA_Thres23a(struct dm_odm_t *pDM_Odm, u8 CurCCK_CCAThres)
-{
- struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
-
- if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres)
- rtl8723au_write8(pDM_Odm->Adapter, ODM_REG(CCK_CCA, pDM_Odm),
- CurCCK_CCAThres);
- pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres;
- pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres;
-}
-
-/* 3 ============================================================ */
-/* 3 BB Power Save */
-/* 3 ============================================================ */
-void odm23a_DynBBPSInit(struct dm_odm_t *pDM_Odm)
-{
- struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable;
-
- pDM_PSTable->PreCCAState = CCA_MAX;
- pDM_PSTable->CurCCAState = CCA_MAX;
- pDM_PSTable->PreRFState = RF_MAX;
- pDM_PSTable->CurRFState = RF_MAX;
- pDM_PSTable->Rssi_val_min = 0;
- pDM_PSTable->initialize = 0;
-}
-
-
-void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal)
-{
- struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable;
- struct rtw_adapter *adapter = pDM_Odm->Adapter;
- u32 val32;
- u8 Rssi_Up_bound = 30;
- u8 Rssi_Low_bound = 25;
- if (pDM_PSTable->initialize == 0) {
-
- pDM_PSTable->Reg874 =
- rtl8723au_read32(adapter, 0x874) & 0x1CC000;
- pDM_PSTable->RegC70 =
- rtl8723au_read32(adapter, 0xc70) & BIT(3);
- pDM_PSTable->Reg85C =
- rtl8723au_read32(adapter, 0x85c) & 0xFF000000;
- pDM_PSTable->RegA74 = rtl8723au_read32(adapter, 0xa74) & 0xF000;
- pDM_PSTable->initialize = 1;
- }
-
- if (!bForceInNormal) {
- if (pDM_Odm->RSSI_Min != 0xFF) {
- if (pDM_PSTable->PreRFState == RF_Normal) {
- if (pDM_Odm->RSSI_Min >= Rssi_Up_bound)
- pDM_PSTable->CurRFState = RF_Save;
- else
- pDM_PSTable->CurRFState = RF_Normal;
- } else {
- if (pDM_Odm->RSSI_Min <= Rssi_Low_bound)
- pDM_PSTable->CurRFState = RF_Normal;
- else
- pDM_PSTable->CurRFState = RF_Save;
- }
- } else {
- pDM_PSTable->CurRFState = RF_MAX;
- }
- } else {
- pDM_PSTable->CurRFState = RF_Normal;
- }
-
- if (pDM_PSTable->PreRFState != pDM_PSTable->CurRFState) {
- if (pDM_PSTable->CurRFState == RF_Save) {
- /* <tynli_note> 8723 RSSI report will be wrong.
- * Set 0x874[5]= 1 when enter BB power saving mode. */
- /* Suggested by SD3 Yu-Nan. 2011.01.20. */
- /* Reg874[5]= 1b'1 */
- if (pDM_Odm->SupportICType == ODM_RTL8723A) {
- val32 = rtl8723au_read32(adapter, 0x874);
- val32 |= BIT(5);
- rtl8723au_write32(adapter, 0x874, val32);
- }
- /* Reg874[20:18]= 3'b010 */
- val32 = rtl8723au_read32(adapter, 0x874);
- val32 &= ~(BIT(18) | BIT(20));
- val32 |= BIT(19);
- rtl8723au_write32(adapter, 0x874, val32);
- /* RegC70[3]= 1'b0 */
- val32 = rtl8723au_read32(adapter, 0xc70);
- val32 &= ~BIT(3);
- rtl8723au_write32(adapter, 0xc70, val32);
- /* Reg85C[31:24]= 0x63 */
- val32 = rtl8723au_read32(adapter, 0x85c);
- val32 &= 0x00ffffff;
- val32 |= 0x63000000;
- rtl8723au_write32(adapter, 0x85c, val32);
- /* Reg874[15:14]= 2'b10 */
- val32 = rtl8723au_read32(adapter, 0x874);
- val32 &= ~BIT(14);
- val32 |= BIT(15);
- rtl8723au_write32(adapter, 0x874, val32);
- /* RegA75[7:4]= 0x3 */
- val32 = rtl8723au_read32(adapter, 0xa74);
- val32 &= ~(BIT(14) | BIT(15));
- val32 |= (BIT(12) | BIT(13));
- rtl8723au_write32(adapter, 0xa74, val32);
- /* Reg818[28]= 1'b0 */
- val32 = rtl8723au_read32(adapter, 0x818);
- val32 &= ~BIT(28);
- rtl8723au_write32(adapter, 0x818, val32);
- /* Reg818[28]= 1'b1 */
- val32 = rtl8723au_read32(adapter, 0x818);
- val32 |= BIT(28);
- rtl8723au_write32(adapter, 0x818, val32);
- } else {
- val32 = rtl8723au_read32(adapter, 0x874);
- val32 |= pDM_PSTable->Reg874;
- rtl8723au_write32(adapter, 0x874, val32);
-
- val32 = rtl8723au_read32(adapter, 0xc70);
- val32 |= pDM_PSTable->RegC70;
- rtl8723au_write32(adapter, 0xc70, val32);
-
- val32 = rtl8723au_read32(adapter, 0x85c);
- val32 |= pDM_PSTable->Reg85C;
- rtl8723au_write32(adapter, 0x85c, val32);
-
- val32 = rtl8723au_read32(adapter, 0xa74);
- val32 |= pDM_PSTable->RegA74;
- rtl8723au_write32(adapter, 0xa74, val32);
-
- val32 = rtl8723au_read32(adapter, 0x818);
- val32 &= ~BIT(28);
- rtl8723au_write32(adapter, 0x818, val32);
-
- /* Reg874[5]= 1b'0 */
- if (pDM_Odm->SupportICType == ODM_RTL8723A) {
- val32 = rtl8723au_read32(adapter, 0x874);
- val32 &= ~BIT(5);
- rtl8723au_write32(adapter, 0x874, val32);
- }
- }
- pDM_PSTable->PreRFState = pDM_PSTable->CurRFState;
- }
-}
-
-/* 3 ============================================================ */
-/* 3 RATR MASK */
-/* 3 ============================================================ */
-/* 3 ============================================================ */
-/* 3 Rate Adaptive */
-/* 3 ============================================================ */
-
-void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm)
-{
- struct odm_rate_adapt *pOdmRA = &pDM_Odm->RateAdaptive;
-
- pOdmRA->Type = DM_Type_ByDriver;
-
- pOdmRA->RATRState = DM_RATR_STA_INIT;
- pOdmRA->HighRSSIThresh = 50;
- pOdmRA->LowRSSIThresh = 20;
-}
-
-u32 ODM_Get_Rate_Bitmap23a(struct hal_data_8723a *pHalData, u32 macid,
- u32 ra_mask, u8 rssi_level)
-{
- struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
- struct sta_info *pEntry;
- u32 rate_bitmap = 0x0fffffff;
- u8 WirelessMode;
-
- pEntry = pDM_Odm->pODM_StaInfo[macid];
- if (!pEntry)
- return ra_mask;
-
- WirelessMode = pEntry->wireless_mode;
-
- switch (WirelessMode) {
- case ODM_WM_B:
- if (ra_mask & 0x0000000c) /* 11M or 5.5M enable */
- rate_bitmap = 0x0000000d;
- else
- rate_bitmap = 0x0000000f;
- break;
- case (ODM_WM_A|ODM_WM_G):
- if (rssi_level == DM_RATR_STA_HIGH)
- rate_bitmap = 0x00000f00;
- else
- rate_bitmap = 0x00000ff0;
- break;
- case (ODM_WM_B|ODM_WM_G):
- if (rssi_level == DM_RATR_STA_HIGH)
- rate_bitmap = 0x00000f00;
- else if (rssi_level == DM_RATR_STA_MIDDLE)
- rate_bitmap = 0x00000ff0;
- else
- rate_bitmap = 0x00000ff5;
- break;
- case (ODM_WM_B|ODM_WM_G|ODM_WM_N24G):
- case (ODM_WM_A|ODM_WM_B|ODM_WM_G|ODM_WM_N24G):
- if (pHalData->rf_type == RF_1T2R ||
- pHalData->rf_type == RF_1T1R) {
- if (rssi_level == DM_RATR_STA_HIGH) {
- rate_bitmap = 0x000f0000;
- } else if (rssi_level == DM_RATR_STA_MIDDLE) {
- rate_bitmap = 0x000ff000;
- } else {
- if (pHalData->CurrentChannelBW ==
- HT_CHANNEL_WIDTH_40)
- rate_bitmap = 0x000ff015;
- else
- rate_bitmap = 0x000ff005;
- }
- } else {
- if (rssi_level == DM_RATR_STA_HIGH) {
- rate_bitmap = 0x0f8f0000;
- } else if (rssi_level == DM_RATR_STA_MIDDLE) {
- rate_bitmap = 0x0f8ff000;
- } else {
- if (pHalData->CurrentChannelBW ==
- HT_CHANNEL_WIDTH_40)
- rate_bitmap = 0x0f8ff015;
- else
- rate_bitmap = 0x0f8ff005;
- }
- }
- break;
- default:
- /* case WIRELESS_11_24N: */
- /* case WIRELESS_11_5N: */
- if (pHalData->rf_type == RF_1T2R)
- rate_bitmap = 0x000fffff;
- else
- rate_bitmap = 0x0fffffff;
- break;
- }
-
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD,
- (" ==> rssi_level:0x%02x, WirelessMode:0x%02x, rate_bitmap:0x%08x \n",
- rssi_level, WirelessMode, rate_bitmap));
-
- return rate_bitmap;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: odm_RefreshRateAdaptiveMask()
- *
- * Overview: Update rate table mask according to rssi
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- *When Who Remark
- *05/27/2009 hpfan Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-static void odm_RefreshRateAdaptiveMask(struct dm_odm_t *pDM_Odm)
-{
- struct rtw_adapter *pAdapter = pDM_Odm->Adapter;
- u32 smoothed;
- u8 i;
-
- if (pAdapter->bDriverStopped) {
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_TRACE,
- ("<---- %s: driver is going to unload\n",
- __func__));
- return;
- }
-
- for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
- struct sta_info *pstat = pDM_Odm->pODM_StaInfo[i];
- if (pstat) {
- smoothed = pstat->rssi_stat.UndecoratedSmoothedPWDB;
- if (ODM_RAStateCheck23a(pDM_Odm, smoothed, false,
- &pstat->rssi_level)) {
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK,
- ODM_DBG_LOUD,
- ("RSSI:%d, RSSI_LEVEL:%d\n",
- smoothed,
- pstat->rssi_level));
- rtw_hal_update_ra_mask23a(pstat,
- pstat->rssi_level);
- }
- }
- }
-}
-
-/* Return Value: bool */
-/* - true: RATRState is changed. */
-bool ODM_RAStateCheck23a(struct dm_odm_t *pDM_Odm, s32 RSSI, bool bForceUpdate,
- u8 *pRATRState)
-{
- struct odm_rate_adapt *pRA = &pDM_Odm->RateAdaptive;
- const u8 GoUpGap = 5;
- u8 HighRSSIThreshForRA = pRA->HighRSSIThresh;
- u8 LowRSSIThreshForRA = pRA->LowRSSIThresh;
- u8 RATRState;
-
- /* Threshold Adjustment: */
- /* when RSSI state trends to go up one or two levels, make sure RSSI is high enough. */
- /* Here GoUpGap is added to solve the boundary's level alternation issue. */
- switch (*pRATRState) {
- case DM_RATR_STA_INIT:
- case DM_RATR_STA_HIGH:
- break;
- case DM_RATR_STA_MIDDLE:
- HighRSSIThreshForRA += GoUpGap;
- break;
- case DM_RATR_STA_LOW:
- HighRSSIThreshForRA += GoUpGap;
- LowRSSIThreshForRA += GoUpGap;
- break;
- default:
- ODM_RT_ASSERT(pDM_Odm, false, ("wrong rssi level setting %d !",
- *pRATRState));
- break;
- }
-
- /* Decide RATRState by RSSI. */
- if (RSSI > HighRSSIThreshForRA)
- RATRState = DM_RATR_STA_HIGH;
- else if (RSSI > LowRSSIThreshForRA)
- RATRState = DM_RATR_STA_MIDDLE;
- else
- RATRState = DM_RATR_STA_LOW;
-
- if (*pRATRState != RATRState || bForceUpdate) {
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD,
- ("RSSI Level %d -> %d\n", *pRATRState, RATRState));
- *pRATRState = RATRState;
- return true;
- }
- return false;
-}
-
-/* 3 ============================================================ */
-/* 3 Dynamic Tx Power */
-/* 3 ============================================================ */
-
-void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm)
-{
- struct rtw_adapter *Adapter = pDM_Odm->Adapter;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
-
- /*
- * This is never changed, so we should be able to clean up the
- * code checking for different values in rtl8723a_rf6052.c
- */
- pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal;
-}
-
-static void
-FindMinimumRSSI(struct rtw_adapter *pAdapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
- struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
-
- /* 1 1.Determine the minimum RSSI */
-
- if (!pDM_Odm->bLinked && !pdmpriv->EntryMinUndecoratedSmoothedPWDB)
- pdmpriv->MinUndecoratedPWDBForDM = 0;
- else
- pdmpriv->MinUndecoratedPWDBForDM =
- pdmpriv->EntryMinUndecoratedSmoothedPWDB;
-}
-
-static void odm_RSSIMonitorCheck(struct dm_odm_t *pDM_Odm)
-{
- struct rtw_adapter *Adapter = pDM_Odm->Adapter;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
- int i;
- int MaxDB = 0, MinDB = 0xff;
- u8 sta_cnt = 0;
- u32 tmpdb;
- u32 PWDB_rssi[NUM_STA] = {0};/* 0~15]:MACID, [16~31]:PWDB_rssi */
- struct sta_info *psta;
-
- if (!pDM_Odm->bLinked)
- return;
-
- for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
- psta = pDM_Odm->pODM_StaInfo[i];
- if (psta) {
- if (psta->rssi_stat.UndecoratedSmoothedPWDB < MinDB)
- MinDB = psta->rssi_stat.UndecoratedSmoothedPWDB;
-
- if (psta->rssi_stat.UndecoratedSmoothedPWDB > MaxDB)
- MaxDB = psta->rssi_stat.UndecoratedSmoothedPWDB;
-
- if (psta->rssi_stat.UndecoratedSmoothedPWDB != -1) {
- tmpdb = psta->rssi_stat.UndecoratedSmoothedPWDB;
- PWDB_rssi[sta_cnt++] = psta->mac_id |
- (tmpdb << 16);
- }
- }
- }
-
- for (i = 0; i < sta_cnt; i++) {
- if (PWDB_rssi[i] != (0))
- rtl8723a_set_rssi_cmd(Adapter, PWDB_rssi[i]);
- }
-
- pdmpriv->EntryMaxUndecoratedSmoothedPWDB = MaxDB;
-
- if (MinDB != 0xff) /* If associated entry is found */
- pdmpriv->EntryMinUndecoratedSmoothedPWDB = MinDB;
- else
- pdmpriv->EntryMinUndecoratedSmoothedPWDB = 0;
-
- FindMinimumRSSI(Adapter);/* get pdmpriv->MinUndecoratedPWDBForDM */
-
- ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_RSSI_MIN,
- pdmpriv->MinUndecoratedPWDBForDM);
-}
-
-/* endif */
-/* 3 ============================================================ */
-/* 3 Tx Power Tracking */
-/* 3 ============================================================ */
-
-static void odm_TXPowerTrackingInit(struct dm_odm_t *pDM_Odm)
-{
- struct rtw_adapter *Adapter = pDM_Odm->Adapter;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
-
- pdmpriv->bTXPowerTracking = true;
- pdmpriv->TXPowercount = 0;
- pdmpriv->bTXPowerTrackingInit = false;
- pdmpriv->TxPowerTrackControl = true;
- MSG_8723A("pdmpriv->TxPowerTrackControl = %d\n",
- pdmpriv->TxPowerTrackControl);
-
- pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = true;
-}
-
-/* EDCA Turbo */
-static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm)
-{
- struct rtw_adapter *Adapter = pDM_Odm->Adapter;
-
- pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false;
- Adapter->recvpriv.bIsAnyNonBEPkts = false;
-
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
- ("Orginial VO PARAM: 0x%x\n",
- rtl8723au_read32(Adapter, ODM_EDCA_VO_PARAM)));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
- ("Orginial VI PARAM: 0x%x\n",
- rtl8723au_read32(Adapter, ODM_EDCA_VI_PARAM)));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
- ("Orginial BE PARAM: 0x%x\n",
- rtl8723au_read32(Adapter, ODM_EDCA_BE_PARAM)));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
- ("Orginial BK PARAM: 0x%x\n",
- rtl8723au_read32(Adapter, ODM_EDCA_BK_PARAM)));
-}
-
-static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm)
-{
- struct rtw_adapter *Adapter = pDM_Odm->Adapter;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct xmit_priv *pxmitpriv = &Adapter->xmitpriv;
- struct recv_priv *precvpriv = &Adapter->recvpriv;
- struct registry_priv *pregpriv = &Adapter->registrypriv;
- struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- u32 trafficIndex;
- u32 edca_param;
- u64 cur_tx_bytes;
- u64 cur_rx_bytes;
-
- /* For AP/ADSL use struct rtl8723a_priv * */
- /* For CE/NIC use struct rtw_adapter * */
-
- /*
- * 2011/09/29 MH In HW integration first stage, we provide 4
- * different handle to operate at the same time. In the stage2/3,
- * we need to prive universal interface and merge all HW dynamic
- * mechanism.
- */
-
- if ((pregpriv->wifi_spec == 1))/* (pmlmeinfo->HT_enable == 0)) */
- goto dm_CheckEdcaTurbo_EXIT;
-
- if (pmlmeinfo->assoc_AP_vendor >= HT_IOT_PEER_MAX)
- goto dm_CheckEdcaTurbo_EXIT;
-
- if (rtl8723a_BT_disable_EDCA_turbo(Adapter))
- goto dm_CheckEdcaTurbo_EXIT;
-
- /* Check if the status needs to be changed. */
- if (!precvpriv->bIsAnyNonBEPkts) {
- cur_tx_bytes = pxmitpriv->tx_bytes - pxmitpriv->last_tx_bytes;
- cur_rx_bytes = precvpriv->rx_bytes - precvpriv->last_rx_bytes;
-
- /* traffic, TX or RX */
- if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK) ||
- (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS)) {
- if (cur_tx_bytes > (cur_rx_bytes << 2)) {
- /* Uplink TP is present. */
- trafficIndex = UP_LINK;
- } else { /* Balance TP is present. */
- trafficIndex = DOWN_LINK;
- }
- } else {
- if (cur_rx_bytes > (cur_tx_bytes << 2)) {
- /* Downlink TP is present. */
- trafficIndex = DOWN_LINK;
- } else { /* Balance TP is present. */
- trafficIndex = UP_LINK;
- }
- }
-
- if ((pDM_Odm->DM_EDCA_Table.prv_traffic_idx != trafficIndex) ||
- (!pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA)) {
- if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_CISCO) &&
- (pmlmeext->cur_wireless_mode & WIRELESS_11_24N))
- edca_param = EDCAParam[pmlmeinfo->assoc_AP_vendor][trafficIndex];
- else
- edca_param = EDCAParam[HT_IOT_PEER_UNKNOWN][trafficIndex];
- rtl8723au_write32(Adapter, REG_EDCA_BE_PARAM,
- edca_param);
-
- pDM_Odm->DM_EDCA_Table.prv_traffic_idx = trafficIndex;
- }
-
- pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = true;
- } else {
- /* Turn Off EDCA turbo here. */
- /* Restore original EDCA according to the declaration of AP. */
- if (pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) {
- rtl8723au_write32(Adapter, REG_EDCA_BE_PARAM,
- pHalData->AcParam_BE);
- pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false;
- }
- }
-
-dm_CheckEdcaTurbo_EXIT:
- /* Set variables for next time. */
- precvpriv->bIsAnyNonBEPkts = false;
- pxmitpriv->last_tx_bytes = pxmitpriv->tx_bytes;
- precvpriv->last_rx_bytes = precvpriv->rx_bytes;
-}
-
-u32 GetPSDData(struct dm_odm_t *pDM_Odm, unsigned int point,
- u8 initial_gain_psd)
-{
- struct rtw_adapter *adapter = pDM_Odm->Adapter;
- u32 psd_report, val32;
-
- /* Set DCO frequency index, offset = (40MHz/SamplePts)*point */
- val32 = rtl8723au_read32(adapter, 0x808);
- val32 &= ~0x3ff;
- val32 |= (point & 0x3ff);
- rtl8723au_write32(adapter, 0x808, val32);
-
- /* Start PSD calculation, Reg808[22]= 0->1 */
- val32 = rtl8723au_read32(adapter, 0x808);
- val32 |= BIT(22);
- rtl8723au_write32(adapter, 0x808, val32);
- /* Need to wait for HW PSD report */
- udelay(30);
- val32 = rtl8723au_read32(adapter, 0x808);
- val32 &= ~BIT(22);
- rtl8723au_write32(adapter, 0x808, val32);
- /* Read PSD report, Reg8B4[15:0] */
- psd_report = rtl8723au_read32(adapter, 0x8B4) & 0x0000FFFF;
-
- psd_report = (u32)(ConvertTo_dB23a(psd_report)) +
- (u32)(initial_gain_psd-0x1c);
-
- return psd_report;
-}
-
-u32 ConvertTo_dB23a(u32 Value)
-{
- u8 i;
- u8 j;
- u32 dB;
-
- Value = Value & 0xFFFF;
-
- for (i = 0; i < 8; i++) {
- if (Value <= dB_Invert_Table[i][11])
- break;
- }
-
- if (i >= 8)
- return 96; /* maximum 96 dB */
-
- for (j = 0; j < 12; j++) {
- if (Value <= dB_Invert_Table[i][j])
- break;
- }
-
- dB = i*12 + j + 1;
-
- return dB;
-}
-
-/* */
-/* Description: */
-/* Set Single/Dual Antenna default setting for products that do not
- * do detection in advance. */
-/* */
-/* Added by Joseph, 2012.03.22 */
-/* */
-void ODM_SingleDualAntennaDefaultSetting(struct dm_odm_t *pDM_Odm)
-{
- struct sw_ant_sw *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table;
-
- pDM_SWAT_Table->ANTA_ON = true;
- pDM_SWAT_Table->ANTB_ON = true;
-}
-
-/* 2 8723A ANT DETECT */
-
-static void odm_PHY_SaveAFERegisters(struct dm_odm_t *pDM_Odm, u32 *AFEReg,
- u32 *AFEBackup, u32 RegisterNum)
-{
- u32 i;
-
- for (i = 0 ; i < RegisterNum ; i++)
- AFEBackup[i] = rtl8723au_read32(pDM_Odm->Adapter, AFEReg[i]);
-}
-
-static void odm_PHY_ReloadAFERegisters(struct dm_odm_t *pDM_Odm, u32 *AFEReg,
- u32 *AFEBackup, u32 RegiesterNum)
-{
- u32 i;
-
- for (i = 0 ; i < RegiesterNum; i++)
- rtl8723au_write32(pDM_Odm->Adapter, AFEReg[i], AFEBackup[i]);
-}
-
-/* 2 8723A ANT DETECT */
-/* Description: */
-/* Implement IQK single tone for RF DPK loopback and BB PSD scanning. */
-/* This function is cooperated with BB team Neil. */
-bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode)
-{
- struct sw_ant_sw *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table;
- struct rtw_adapter *adapter = pDM_Odm->Adapter;
- u32 CurrentChannel, RfLoopReg;
- u8 n;
- u32 Reg88c, Regc08, Reg874, Regc50, val32;
- u8 initial_gain = 0x5a;
- u32 PSD_report_tmp;
- u32 AntA_report = 0x0, AntB_report = 0x0, AntO_report = 0x0;
- bool bResult = true;
- u32 AFE_Backup[16];
- u32 AFE_REG_8723A[16] = {
- rRx_Wait_CCA, rTx_CCK_RFON,
- rTx_CCK_BBON, rTx_OFDM_RFON,
- rTx_OFDM_BBON, rTx_To_Rx,
- rTx_To_Tx, rRx_CCK,
- rRx_OFDM, rRx_Wait_RIFS,
- rRx_TO_Rx, rStandby,
- rSleep, rPMPD_ANAEN,
- rFPGA0_XCD_SwitchControl, rBlue_Tooth};
-
- if (!(pDM_Odm->SupportICType & ODM_RTL8723A))
- return bResult;
-
- if (!(pDM_Odm->SupportAbility&ODM_BB_ANT_DIV))
- return bResult;
- /* 1 Backup Current RF/BB Settings */
-
- CurrentChannel = ODM_GetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL,
- bRFRegOffsetMask);
- RfLoopReg = ODM_GetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask);
- /* change to Antenna A */
- val32 = rtl8723au_read32(adapter, rFPGA0_XA_RFInterfaceOE);
- val32 &= ~0x300;
- val32 |= 0x100; /* Enable antenna A */
- rtl8723au_write32(adapter, rFPGA0_XA_RFInterfaceOE, val32);
-
- /* Step 1: USE IQK to transmitter single tone */
-
- udelay(10);
-
- /* Store A Path Register 88c, c08, 874, c50 */
- Reg88c = rtl8723au_read32(adapter, rFPGA0_AnalogParameter4);
- Regc08 = rtl8723au_read32(adapter, rOFDM0_TRMuxPar);
- Reg874 = rtl8723au_read32(adapter, rFPGA0_XCD_RFInterfaceSW);
- Regc50 = rtl8723au_read32(adapter, rOFDM0_XAAGCCore1);
-
- /* Store AFE Registers */
- odm_PHY_SaveAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16);
-
- /* Set PSD 128 pts */
- val32 = rtl8723au_read32(adapter, rFPGA0_PSDFunction);
- val32 &= ~(BIT(14) | BIT(15));
- rtl8723au_write32(adapter, rFPGA0_PSDFunction, val32);
-
- /* To SET CH1 to do */
- ODM_SetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask, 0x01);
-
- /* AFE all on step */
- rtl8723au_write32(adapter, rRx_Wait_CCA, 0x6FDB25A4);
- rtl8723au_write32(adapter, rTx_CCK_RFON, 0x6FDB25A4);
- rtl8723au_write32(adapter, rTx_CCK_BBON, 0x6FDB25A4);
- rtl8723au_write32(adapter, rTx_OFDM_RFON, 0x6FDB25A4);
- rtl8723au_write32(adapter, rTx_OFDM_BBON, 0x6FDB25A4);
- rtl8723au_write32(adapter, rTx_To_Rx, 0x6FDB25A4);
- rtl8723au_write32(adapter, rTx_To_Tx, 0x6FDB25A4);
- rtl8723au_write32(adapter, rRx_CCK, 0x6FDB25A4);
- rtl8723au_write32(adapter, rRx_OFDM, 0x6FDB25A4);
- rtl8723au_write32(adapter, rRx_Wait_RIFS, 0x6FDB25A4);
- rtl8723au_write32(adapter, rRx_TO_Rx, 0x6FDB25A4);
- rtl8723au_write32(adapter, rStandby, 0x6FDB25A4);
- rtl8723au_write32(adapter, rSleep, 0x6FDB25A4);
- rtl8723au_write32(adapter, rPMPD_ANAEN, 0x6FDB25A4);
- rtl8723au_write32(adapter, rFPGA0_XCD_SwitchControl, 0x6FDB25A4);
- rtl8723au_write32(adapter, rBlue_Tooth, 0x6FDB25A4);
-
- /* 3 wire Disable */
- rtl8723au_write32(adapter, rFPGA0_AnalogParameter4, 0xCCF000C0);
-
- /* BB IQK Setting */
- rtl8723au_write32(adapter, rOFDM0_TRMuxPar, 0x000800E4);
- rtl8723au_write32(adapter, rFPGA0_XCD_RFInterfaceSW, 0x22208000);
-
- /* IQK setting tone@ 4.34Mhz */
- rtl8723au_write32(adapter, rTx_IQK_Tone_A, 0x10008C1C);
- rtl8723au_write32(adapter, rTx_IQK, 0x01007c00);
-
- /* Page B init */
- rtl8723au_write32(adapter, rConfig_AntA, 0x00080000);
- rtl8723au_write32(adapter, rConfig_AntA, 0x0f600000);
- rtl8723au_write32(adapter, rRx_IQK, 0x01004800);
- rtl8723au_write32(adapter, rRx_IQK_Tone_A, 0x10008c1f);
- rtl8723au_write32(adapter, rTx_IQK_PI_A, 0x82150008);
- rtl8723au_write32(adapter, rRx_IQK_PI_A, 0x28150008);
- rtl8723au_write32(adapter, rIQK_AGC_Rsp, 0x001028d0);
-
- /* RF loop Setting */
- ODM_SetRFReg(pDM_Odm, RF_PATH_A, 0x0, 0xFFFFF, 0x50008);
-
- /* IQK Single tone start */
- rtl8723au_write32(adapter, rFPGA0_IQK, 0x80800000);
- rtl8723au_write32(adapter, rIQK_AGC_Pts, 0xf8000000);
- udelay(1000);
- PSD_report_tmp = 0x0;
-
- for (n = 0; n < 2; n++) {
- PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain);
- if (PSD_report_tmp > AntA_report)
- AntA_report = PSD_report_tmp;
- }
-
- PSD_report_tmp = 0x0;
-
- val32 = rtl8723au_read32(adapter, rFPGA0_XA_RFInterfaceOE);
- val32 &= ~0x300;
- val32 |= 0x200; /* Enable antenna B */
- rtl8723au_write32(adapter, rFPGA0_XA_RFInterfaceOE, val32);
- udelay(10);
-
- for (n = 0; n < 2; n++) {
- PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain);
- if (PSD_report_tmp > AntB_report)
- AntB_report = PSD_report_tmp;
- }
-
- /* change to open case */
- /* change to Ant A and B all open case */
- val32 = rtl8723au_read32(adapter, rFPGA0_XA_RFInterfaceOE);
- val32 &= ~0x300;
- rtl8723au_write32(adapter, rFPGA0_XA_RFInterfaceOE, val32);
- udelay(10);
-
- for (n = 0; n < 2; n++) {
- PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain);
- if (PSD_report_tmp > AntO_report)
- AntO_report = PSD_report_tmp;
- }
-
- /* Close IQK Single Tone function */
- rtl8723au_write32(adapter, rFPGA0_IQK, 0x00000000);
- PSD_report_tmp = 0x0;
-
- /* 1 Return to antanna A */
- val32 = rtl8723au_read32(adapter, rFPGA0_XA_RFInterfaceOE);
- val32 &= ~0x300;
- val32 |= 0x100; /* Enable antenna A */
- rtl8723au_write32(adapter, rFPGA0_XA_RFInterfaceOE, val32);
- rtl8723au_write32(adapter, rFPGA0_AnalogParameter4, Reg88c);
- rtl8723au_write32(adapter, rOFDM0_TRMuxPar, Regc08);
- rtl8723au_write32(adapter, rFPGA0_XCD_RFInterfaceSW, Reg874);
- val32 = rtl8723au_read32(adapter, rOFDM0_XAAGCCore1);
- val32 &= ~0x7f;
- val32 |= 0x40;
- rtl8723au_write32(adapter, rOFDM0_XAAGCCore1, val32);
-
- rtl8723au_write32(adapter, rOFDM0_XAAGCCore1, Regc50);
- ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask,
- CurrentChannel);
- ODM_SetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask, RfLoopReg);
-
- /* Reload AFE Registers */
- odm_PHY_ReloadAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16);
-
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
- ("psd_report_A[%d]= %d \n", 2416, AntA_report));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
- ("psd_report_B[%d]= %d \n", 2416, AntB_report));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
- ("psd_report_O[%d]= %d \n", 2416, AntO_report));
-
- /* 2 Test Ant B based on Ant A is ON */
- if (mode == ANTTESTB) {
- if (AntA_report >= 100) {
- if (AntB_report > (AntA_report+1)) {
- pDM_SWAT_Table->ANTB_ON = false;
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Single Antenna A\n"));
- } else {
- pDM_SWAT_Table->ANTB_ON = true;
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Dual Antenna is A and B\n"));
- }
- } else {
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Need to check again\n"));
- pDM_SWAT_Table->ANTB_ON = false; /* Set Antenna B off as default */
- bResult = false;
- }
- } else if (mode == ANTTESTALL) {
- /* 2 Test Ant A and B based on DPDT Open */
- if ((AntO_report >= 100) & (AntO_report < 118)) {
- if (AntA_report > (AntO_report+1)) {
- pDM_SWAT_Table->ANTA_ON = false;
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,
- ODM_DBG_LOUD, ("Ant A is OFF"));
- } else {
- pDM_SWAT_Table->ANTA_ON = true;
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,
- ODM_DBG_LOUD, ("Ant A is ON"));
- }
-
- if (AntB_report > (AntO_report+2)) {
- pDM_SWAT_Table->ANTB_ON = false;
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,
- ODM_DBG_LOUD, ("Ant B is OFF"));
- } else {
- pDM_SWAT_Table->ANTB_ON = true;
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV,
- ODM_DBG_LOUD, ("Ant B is ON"));
- }
- }
- } else {
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
- ("ODM_SingleDualAntennaDetection(): Need to check again\n"));
- /* Set Antenna A on as default */
- pDM_SWAT_Table->ANTA_ON = true;
- /* Set Antenna B off as default */
- pDM_SWAT_Table->ANTB_ON = false;
- bResult = false;
- }
-
- return bResult;
-}
diff --git a/drivers/staging/rtl8723au/hal/odm_HWConfig.c b/drivers/staging/rtl8723au/hal/odm_HWConfig.c
deleted file mode 100644
index 0562f61bd1dc..000000000000
--- a/drivers/staging/rtl8723au/hal/odm_HWConfig.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-/* */
-/* include files */
-/* */
-
-#include "odm_precomp.h"
-
-static u8 odm_QueryRxPwrPercentage(s8 AntPower)
-{
- if ((AntPower <= -100) || (AntPower >= 20))
- return 0;
- else if (AntPower >= 0)
- return 100;
- else
- return 100 + AntPower;
-}
-
-static s32 odm_SignalScaleMapping_92CSeries(struct dm_odm_t *pDM_Odm, s32 CurrSig)
-{
- s32 RetSig = 0;
-
- if (CurrSig >= 51 && CurrSig <= 100)
- RetSig = 100;
- else if (CurrSig >= 41 && CurrSig <= 50)
- RetSig = 80 + ((CurrSig - 40)*2);
- else if (CurrSig >= 31 && CurrSig <= 40)
- RetSig = 66 + (CurrSig - 30);
- else if (CurrSig >= 21 && CurrSig <= 30)
- RetSig = 54 + (CurrSig - 20);
- else if (CurrSig >= 10 && CurrSig <= 20)
- RetSig = 42 + (((CurrSig - 10) * 2) / 3);
- else if (CurrSig >= 5 && CurrSig <= 9)
- RetSig = 22 + (((CurrSig - 5) * 3) / 2);
- else if (CurrSig >= 1 && CurrSig <= 4)
- RetSig = 6 + (((CurrSig - 1) * 3) / 2);
- else
- RetSig = CurrSig;
-
- return RetSig;
-}
-
-static s32 odm_SignalScaleMapping(struct dm_odm_t *pDM_Odm, s32 CurrSig)
-{
- return odm_SignalScaleMapping_92CSeries(pDM_Odm, CurrSig);
-}
-
-static u8
-odm_EVMdbToPercentage(
- s8 Value
- )
-{
- /* */
- /* -33dB~0dB to 0%~99% */
- /* */
- s8 ret_val;
-
- ret_val = Value;
-
- if (ret_val >= 0)
- ret_val = 0;
- if (ret_val <= -33)
- ret_val = -33;
-
- ret_val = 0 - ret_val;
- ret_val *= 3;
-
- if (ret_val == 99)
- ret_val = 100;
-
- return ret_val;
-}
-
-static void odm_RxPhyStatus92CSeries_Parsing(struct dm_odm_t *pDM_Odm,
- struct phy_info *pPhyInfo,
- u8 *pPhyStatus,
- struct odm_packet_info *pPktinfo)
-{
- struct phy_status_rpt *pPhyStaRpt = (struct phy_status_rpt *)pPhyStatus;
- u8 i, Max_spatial_stream;
- s8 rx_pwr[4], rx_pwr_all = 0;
- u8 EVM, PWDB_ALL = 0, PWDB_ALL_BT;
- u8 RSSI, total_rssi = 0;
- u8 isCCKrate = 0;
- u8 rf_rx_num = 0;
- u8 cck_highpwr = 0;
-
- isCCKrate = (pPktinfo->Rate <= DESC92C_RATE11M) ? true : false;
- pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = -1;
- pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1;
-
- if (isCCKrate) {
- u8 report;
- u8 cck_agc_rpt;
-
- pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK++;
- /* (1)Hardware does not provide RSSI for CCK */
- /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */
-
- cck_highpwr = pDM_Odm->bCckHighPower;
-
- cck_agc_rpt = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a;
-
- /* The RSSI formula should be modified according to the gain table */
- if (!cck_highpwr) {
- report = (cck_agc_rpt & 0xc0)>>6;
- switch (report) {
- /* Modify the RF RNA gain value to -40, -20, -2, 14 by Jenyu's suggestion */
- /* Note: different RF with the different RNA gain. */
- case 0x3:
- rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
- break;
- case 0x2:
- rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
- break;
- case 0x1:
- rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
- break;
- case 0x0:
- rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
- break;
- }
- } else {
- report = (cck_agc_rpt & 0x60)>>5;
- switch (report) {
- case 0x3:
- rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f)<<1);
- break;
- case 0x2:
- rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f)<<1);
- break;
- case 0x1:
- rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f)<<1);
- break;
- case 0x0:
- rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f)<<1);
- break;
- }
- }
-
- PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all);
-
- /* Modification for ext-LNA board */
- if (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) {
- if ((cck_agc_rpt>>7) == 0) {
- PWDB_ALL = (PWDB_ALL > 94) ? 100 : (PWDB_ALL+6);
- } else {
- if (PWDB_ALL > 38)
- PWDB_ALL -= 16;
- else
- PWDB_ALL = (PWDB_ALL <= 16) ? (PWDB_ALL>>2) : (PWDB_ALL-12);
- }
-
- /* CCK modification */
- if (PWDB_ALL > 25 && PWDB_ALL <= 60)
- PWDB_ALL += 6;
- } else { /* Modification for int-LNA board */
- if (PWDB_ALL > 99)
- PWDB_ALL -= 8;
- else if (PWDB_ALL > 50 && PWDB_ALL <= 68)
- PWDB_ALL += 4;
- }
- pPhyInfo->RxPWDBAll = PWDB_ALL;
- pPhyInfo->BTRxRSSIPercentage = PWDB_ALL;
- pPhyInfo->RecvSignalPower = rx_pwr_all;
- /* (3) Get Signal Quality (EVM) */
- if (pPktinfo->bPacketMatchBSSID) {
- u8 SQ, SQ_rpt;
-
- SQ_rpt = pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all;
-
- if (SQ_rpt > 64)
- SQ = 0;
- else if (SQ_rpt < 20)
- SQ = 100;
- else
- SQ = ((64-SQ_rpt) * 100) / 44;
-
- pPhyInfo->SignalQuality = SQ;
- pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = SQ;
- pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1;
- }
- } else { /* is OFDM rate */
- pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM++;
-
- /* (1)Get RSSI for HT rate */
-
- for (i = RF_PATH_A; i < RF_PATH_MAX; i++) {
- /* 2008/01/30 MH we will judge RF RX path now. */
- if (pDM_Odm->RFPathRxEnable & BIT(i))
- rf_rx_num++;
-
- rx_pwr[i] = ((pPhyStaRpt->path_agc[i].gain & 0x3F)*2) - 110;
-
- pPhyInfo->RxPwr[i] = rx_pwr[i];
-
- /* Translate DBM to percentage. */
- RSSI = odm_QueryRxPwrPercentage(rx_pwr[i]);
- total_rssi += RSSI;
-
- /* Modification for ext-LNA board */
- if (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) {
- if ((pPhyStaRpt->path_agc[i].trsw) == 1)
- RSSI = (RSSI > 94) ? 100 : (RSSI+6);
- else
- RSSI = (RSSI <= 16) ? (RSSI>>3) : (RSSI-16);
-
- if ((RSSI <= 34) && (RSSI >= 4))
- RSSI -= 4;
- }
-
- pPhyInfo->RxMIMOSignalStrength[i] = (u8) RSSI;
-
- /* Get Rx snr value in DB */
- pPhyInfo->RxSNR[i] = pDM_Odm->PhyDbgInfo.RxSNRdB[i] = (s32)(pPhyStaRpt->path_rxsnr[i]/2);
- }
-
- /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */
- rx_pwr_all = (((pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all) >> 1) & 0x7f)-110;
-
- PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all);
- PWDB_ALL_BT = PWDB_ALL;
-
- pPhyInfo->RxPWDBAll = PWDB_ALL;
- pPhyInfo->BTRxRSSIPercentage = PWDB_ALL_BT;
- pPhyInfo->RxPower = rx_pwr_all;
- pPhyInfo->RecvSignalPower = rx_pwr_all;
-
- /* (3)EVM of HT rate */
- if (pPktinfo->Rate >= DESC92C_RATEMCS8 && pPktinfo->Rate <= DESC92C_RATEMCS15)
- Max_spatial_stream = 2; /* both spatial stream make sense */
- else
- Max_spatial_stream = 1; /* only spatial stream 1 makes sense */
-
- for (i = 0; i < Max_spatial_stream; i++) {
- /* Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment */
- /* fill most significant bit to "zero" when doing shifting operation which may change a negative */
- /* value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. */
- EVM = odm_EVMdbToPercentage((pPhyStaRpt->stream_rxevm[i])); /* dbm */
-
- if (pPktinfo->bPacketMatchBSSID) {
- if (i == RF_PATH_A) {
- /* Fill value in RFD, Get the first spatial stream only */
- pPhyInfo->SignalQuality = (u8)(EVM & 0xff);
- }
- pPhyInfo->RxMIMOSignalQuality[i] = (u8)(EVM & 0xff);
- }
- }
- }
- /* UI BSS List signal strength(in percentage), make it good looking, from 0~100. */
- /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
- if (isCCKrate) {
- pPhyInfo->SignalStrength = (u8)(odm_SignalScaleMapping(pDM_Odm, PWDB_ALL));/* PWDB_ALL; */
- } else {
- if (rf_rx_num != 0)
- pPhyInfo->SignalStrength = (u8)(odm_SignalScaleMapping(pDM_Odm, total_rssi /= rf_rx_num));
- }
-}
-
-static void odm_Process_RSSIForDM(struct dm_odm_t *pDM_Odm,
- struct phy_info *pPhyInfo,
- struct odm_packet_info *pPktinfo)
-{
- s32 UndecoratedSmoothedPWDB, UndecoratedSmoothedCCK;
- s32 UndecoratedSmoothedOFDM, RSSI_Ave;
- u8 isCCKrate = 0;
- u8 RSSI_max, RSSI_min, i;
- u32 OFDM_pkt = 0;
- u32 Weighting = 0;
- struct sta_info *pEntry;
-
- if (pPktinfo->StationID == 0xFF)
- return;
-
- pEntry = pDM_Odm->pODM_StaInfo[pPktinfo->StationID];
- if (!pEntry)
- return;
- if ((!pPktinfo->bPacketMatchBSSID))
- return;
-
- isCCKrate = (pPktinfo->Rate <= DESC92C_RATE11M) ? true : false;
-
- /* Smart Antenna Debug Message------------------*/
-
- UndecoratedSmoothedCCK = pEntry->rssi_stat.UndecoratedSmoothedCCK;
- UndecoratedSmoothedOFDM = pEntry->rssi_stat.UndecoratedSmoothedOFDM;
- UndecoratedSmoothedPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB;
-
- if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) {
- if (!isCCKrate) { /* ofdm rate */
- if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_B] == 0) {
- RSSI_Ave = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
- } else {
- if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_A] > pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]) {
- RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
- RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B];
- } else {
- RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B];
- RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
- }
- if ((RSSI_max - RSSI_min) < 3)
- RSSI_Ave = RSSI_max;
- else if ((RSSI_max - RSSI_min) < 6)
- RSSI_Ave = RSSI_max - 1;
- else if ((RSSI_max - RSSI_min) < 10)
- RSSI_Ave = RSSI_max - 2;
- else
- RSSI_Ave = RSSI_max - 3;
- }
-
- /* 1 Process OFDM RSSI */
- if (UndecoratedSmoothedOFDM <= 0) {
- /* initialize */
- UndecoratedSmoothedOFDM = pPhyInfo->RxPWDBAll;
- } else {
- if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedOFDM) {
- UndecoratedSmoothedOFDM =
- (((UndecoratedSmoothedOFDM)*(Rx_Smooth_Factor-1)) +
- (RSSI_Ave)) / (Rx_Smooth_Factor);
- UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM + 1;
- } else {
- UndecoratedSmoothedOFDM =
- (((UndecoratedSmoothedOFDM)*(Rx_Smooth_Factor-1)) +
- (RSSI_Ave)) / (Rx_Smooth_Factor);
- }
- }
- pEntry->rssi_stat.PacketMap =
- (pEntry->rssi_stat.PacketMap<<1) | BIT(0);
- } else {
- RSSI_Ave = pPhyInfo->RxPWDBAll;
-
- /* 1 Process CCK RSSI */
- if (UndecoratedSmoothedCCK <= 0) {
- /* initialize */
- UndecoratedSmoothedCCK = pPhyInfo->RxPWDBAll;
- } else {
- if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedCCK) {
- UndecoratedSmoothedCCK =
- (((UndecoratedSmoothedCCK)*(Rx_Smooth_Factor-1)) +
- (pPhyInfo->RxPWDBAll)) / (Rx_Smooth_Factor);
- UndecoratedSmoothedCCK = UndecoratedSmoothedCCK + 1;
- } else {
- UndecoratedSmoothedCCK =
- (((UndecoratedSmoothedCCK)*(Rx_Smooth_Factor-1)) +
- (pPhyInfo->RxPWDBAll)) / (Rx_Smooth_Factor);
- }
- }
- pEntry->rssi_stat.PacketMap = pEntry->rssi_stat.PacketMap<<1;
- }
-
- /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
- if (pEntry->rssi_stat.ValidBit >= 64)
- pEntry->rssi_stat.ValidBit = 64;
- else
- pEntry->rssi_stat.ValidBit++;
-
- for (i = 0; i < pEntry->rssi_stat.ValidBit; i++)
- OFDM_pkt +=
- (u8)(pEntry->rssi_stat.PacketMap>>i) & BIT(0);
-
- if (pEntry->rssi_stat.ValidBit == 64) {
- Weighting = ((OFDM_pkt<<4) > 64)?64:(OFDM_pkt<<4);
- UndecoratedSmoothedPWDB = (Weighting*UndecoratedSmoothedOFDM+(64-Weighting)*UndecoratedSmoothedCCK)>>6;
- } else {
- if (pEntry->rssi_stat.ValidBit != 0)
- UndecoratedSmoothedPWDB = (OFDM_pkt*UndecoratedSmoothedOFDM+(pEntry->rssi_stat.ValidBit-OFDM_pkt)*UndecoratedSmoothedCCK)/pEntry->rssi_stat.ValidBit;
- else
- UndecoratedSmoothedPWDB = 0;
- }
- pEntry->rssi_stat.UndecoratedSmoothedCCK = UndecoratedSmoothedCCK;
- pEntry->rssi_stat.UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM;
- pEntry->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;
- }
-}
-
-void ODM_PhyStatusQuery23a(struct dm_odm_t *pDM_Odm, struct phy_info *pPhyInfo,
- u8 *pPhyStatus, struct odm_packet_info *pPktinfo)
-{
- odm_RxPhyStatus92CSeries_Parsing(pDM_Odm, pPhyInfo,
- pPhyStatus, pPktinfo);
-
- odm_Process_RSSIForDM(pDM_Odm, pPhyInfo, pPktinfo);
-}
diff --git a/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c b/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c
deleted file mode 100644
index a63c6cb88bc9..000000000000
--- a/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-#include "odm_precomp.h"
-#include "usb_ops_linux.h"
-
-void
-odm_ConfigRFReg_8723A(
- struct dm_odm_t *pDM_Odm,
- u32 Addr,
- u32 Data,
- enum RF_RADIO_PATH RF_PATH,
- u32 RegAddr
- )
-{
- if (Addr == 0xfe) {
- msleep(50);
- } else if (Addr == 0xfd) {
- mdelay(5);
- } else if (Addr == 0xfc) {
- mdelay(1);
- } else if (Addr == 0xfb) {
- udelay(50);
- } else if (Addr == 0xfa) {
- udelay(5);
- } else if (Addr == 0xf9) {
- udelay(1);
- } else {
- ODM_SetRFReg(pDM_Odm, RF_PATH, RegAddr, bRFRegOffsetMask, Data);
- /* Add 1us delay between BB/RF register setting. */
- udelay(1);
- }
-}
-
-void odm_ConfigMAC_8723A(struct dm_odm_t *pDM_Odm, u32 addr, u8 data)
-{
- rtl8723au_write8(pDM_Odm->Adapter, addr, data);
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD,
- ("===> %s: [MAC_REG] %08X %08X\n", __func__, addr, data));
-}
-
-void odm_ConfigBB_AGC_8723A(struct dm_odm_t *pDM_Odm, u32 addr, u32 data)
-{
- rtl8723au_write32(pDM_Odm->Adapter, addr, data);
- /* Add 1us delay between BB/RF register setting. */
- udelay(1);
-
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD,
- ("===> %s: [AGC_TAB] %08X %08X\n", __func__, addr, data));
-}
-
-void
-odm_ConfigBB_PHY_8723A(struct dm_odm_t *pDM_Odm, u32 addr, u32 data)
-{
- if (addr == 0xfe)
- msleep(50);
- else if (addr == 0xfd)
- mdelay(5);
- else if (addr == 0xfc)
- mdelay(1);
- else if (addr == 0xfb)
- udelay(50);
- else if (addr == 0xfa)
- udelay(5);
- else if (addr == 0xf9)
- udelay(1);
- else if (addr == 0xa24)
- pDM_Odm->RFCalibrateInfo.RegA24 = data;
- rtl8723au_write32(pDM_Odm->Adapter, addr, data);
-
- /* Add 1us delay between BB/RF register setting. */
- udelay(1);
-
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD,
- ("===> %s: [PHY_REG] %08X %08X\n", __func__, addr, data));
-}
diff --git a/drivers/staging/rtl8723au/hal/odm_debug.c b/drivers/staging/rtl8723au/hal/odm_debug.c
deleted file mode 100644
index cb2bdda6b0eb..000000000000
--- a/drivers/staging/rtl8723au/hal/odm_debug.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-#include "odm_precomp.h"
-
-void ODM_InitDebugSetting23a(struct dm_odm_t *pDM_Odm)
-{
- pDM_Odm->DebugLevel = ODM_DBG_TRACE;
- pDM_Odm->DebugComponents = 0;
-}
-
-u32 GlobalDebugLevel23A;
-
-void rt_trace(int comp, int level, const char *fmt, ...)
-{
- struct va_format vaf;
- va_list args;
-
- va_start(args, fmt);
-
- vaf.fmt = fmt;
- vaf.va = &args;
-
- pr_info(DRIVER_PREFIX " [0x%08x,%d] %pV", comp, level, &vaf);
-
- va_end(args);
-}
diff --git a/drivers/staging/rtl8723au/hal/odm_interface.c b/drivers/staging/rtl8723au/hal/odm_interface.c
deleted file mode 100644
index d8f67902708e..000000000000
--- a/drivers/staging/rtl8723au/hal/odm_interface.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-/* */
-/* include files */
-/* */
-
-#include "odm_precomp.h"
-/* */
-/* ODM IO Relative API. */
-/* */
-#include <usb_ops_linux.h>
-
-void ODM_SetRFReg(
- struct dm_odm_t *pDM_Odm,
- enum RF_RADIO_PATH eRFPath,
- u32 RegAddr,
- u32 BitMask,
- u32 Data
- )
-{
- struct rtw_adapter *Adapter = pDM_Odm->Adapter;
-
- PHY_SetRFReg(Adapter, eRFPath, RegAddr, BitMask, Data);
-}
-
-u32 ODM_GetRFReg(
- struct dm_odm_t *pDM_Odm,
- enum RF_RADIO_PATH eRFPath,
- u32 RegAddr,
- u32 BitMask
- )
-{
- struct rtw_adapter *Adapter = pDM_Odm->Adapter;
-
- return PHY_QueryRFReg(Adapter, eRFPath, RegAddr, BitMask);
-}
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c
deleted file mode 100644
index bfcbd7a349cf..000000000000
--- a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c
+++ /dev/null
@@ -1,11265 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#include <drv_types.h>
-#include <rtl8723a_hal.h>
-#include <usb_ops_linux.h>
-
-#define DIS_PS_RX_BCN
-
-u32 BTCoexDbgLevel = _bt_dbg_off_;
-
-#define RTPRINT(_Comp, _Level, Fmt)\
-do {\
- if ((BTCoexDbgLevel == _bt_dbg_on_)) {\
- printk Fmt;\
- } \
-} while (0)
-
-#define RTPRINT_ADDR(dbgtype, dbgflag, printstr, _Ptr)\
-if ((BTCoexDbgLevel == _bt_dbg_on_)) {\
- u32 __i; \
- u8 *ptr = (u8 *)_Ptr; \
- printk printstr; \
- printk(" "); \
- for (__i = 0; __i < 6; __i++) \
- printk("%02X%s", ptr[__i], (__i == 5)?"":"-"); \
- printk("\n"); \
-}
-#define RTPRINT_DATA(dbgtype, dbgflag, _TitleString, _HexData, _HexDataLen)\
-if ((BTCoexDbgLevel == _bt_dbg_on_)) {\
- u32 __i; \
- u8 *ptr = (u8 *)_HexData; \
- printk(_TitleString); \
- for (__i = 0; __i < (u32)_HexDataLen; __i++) { \
- printk("%02X%s", ptr[__i], (((__i + 1) % 4) == 0)?" ":" ");\
- if (((__i + 1) % 16) == 0) \
- printk("\n"); \
- } \
- printk("\n"); \
-}
-/* Added by Annie, 2005-11-22. */
-#define MAX_STR_LEN 64
-/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. */
-#define PRINTABLE(_ch) (_ch >= ' ' && _ch <= '~')
-#define RT_PRINT_STR(_Comp, _Level, _TitleString, _Ptr, _Len) \
- { \
- u32 __i; \
- u8 buffer[MAX_STR_LEN]; \
- u32 length = (_Len < MAX_STR_LEN) ? _Len : (MAX_STR_LEN-1);\
- memset(buffer, 0, MAX_STR_LEN); \
- memcpy(buffer, (u8 *)_Ptr, length); \
- for (__i = 0; __i < length; __i++) { \
- if (!PRINTABLE(buffer[__i])) \
- buffer[__i] = '?'; \
- } \
- buffer[length] = '\0'; \
- printk(_TitleString); \
- printk(": %d, <%s>\n", _Len, buffer); \
- }
-
-#define DCMD_Printf(...)
-#define RT_ASSERT(...)
-
-
-#define GetDefaultAdapter(padapter) padapter
-
-#define PlatformZeroMemory(ptr, sz) memset(ptr, 0, sz)
-
-#define GET_UNDECORATED_AVERAGE_RSSI(padapter) \
- (GET_HAL_DATA(padapter)->dmpriv.EntryMinUndecoratedSmoothedPWDB)
-#define RT_RF_CHANGE_SOURCE u32
-
-enum {
- RT_JOIN_INFRA = 1,
- RT_JOIN_IBSS = 2,
- RT_START_IBSS = 3,
- RT_NO_ACTION = 4,
-};
-
-/* power saving */
-
-/* ===== Below this line is sync from SD7 driver COMMOM/BT.c ===== */
-
-static u8 BT_Operation(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- if (pBtMgnt->BtOperationOn)
- return true;
- else
- return false;
-}
-
-static u8 BT_IsLegalChannel(struct rtw_adapter *padapter, u8 channel)
-{
- struct rt_channel_info *pChanneList = NULL;
- u8 channelLen, i;
-
- pChanneList = padapter->mlmeextpriv.channel_set;
- channelLen = padapter->mlmeextpriv.max_chan_nums;
-
- for (i = 0; i < channelLen; i++) {
- RTPRINT(FIOCTL, IOCTL_STATE,
- ("Check if chnl(%d) in channel plan contains bt target chnl(%d) for BT connection\n",
- pChanneList[i].ChannelNum, channel));
- if ((channel == pChanneList[i].ChannelNum) ||
- (channel == pChanneList[i].ChannelNum + 2))
- return channel;
- }
- return 0;
-}
-
-void BT_SignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi, u8 *rssi_bt)
-{
- BTDM_SignalCompensation(padapter, rssi_wifi, rssi_bt);
-}
-
-void rtl8723a_BT_wifiscan_notify(struct rtw_adapter *padapter, u8 scanType)
-{
- BTHCI_WifiScanNotify(padapter, scanType);
- BTDM_CheckAntSelMode(padapter);
- BTDM_WifiScanNotify(padapter, scanType);
-}
-
-void rtl8723a_BT_wifiassociate_notify(struct rtw_adapter *padapter, u8 action)
-{
- /* action : */
- /* true = associate start */
- /* false = associate finished */
- if (action)
- BTDM_CheckAntSelMode(padapter);
-
- BTDM_WifiAssociateNotify(padapter, action);
-}
-
-void BT_HaltProcess(struct rtw_adapter *padapter)
-{
- BTDM_ForHalt(padapter);
-}
-
-/* ===== End of sync from SD7 driver COMMOM/BT.c ===== */
-
-#define i64fmt "ll"
-#define UINT64_C(v) (v)
-
-#define FillOctetString(_os, _octet, _len) \
- (_os).Octet = (u8 *)(_octet); \
- (_os).Length = (_len);
-
-static enum rt_status PlatformIndicateBTEvent(
- struct rtw_adapter *padapter,
- void *pEvntData,
- u32 dataLen
- )
-{
- enum rt_status rt_status = RT_STATUS_FAILURE;
-
- RTPRINT(FIOCTL, IOCTL_BT_EVENT_DETAIL, ("BT event start, %d bytes data to Transferred!!\n", dataLen));
- RTPRINT_DATA(FIOCTL, IOCTL_BT_EVENT_DETAIL, "To transfer Hex Data :\n",
- pEvntData, dataLen);
-
- BT_EventParse(padapter, pEvntData, dataLen);
-
- printk(KERN_WARNING "%s: Linux has no way to report BT event!!\n", __func__);
-
- RTPRINT(FIOCTL, IOCTL_BT_EVENT_DETAIL, ("BT event end, %s\n",
- (rt_status == RT_STATUS_SUCCESS) ? "SUCCESS" : "FAIL"));
-
- return rt_status;
-}
-
-/* ===== Below this line is sync from SD7 driver COMMOM/bt_hci.c ===== */
-
-static u8 bthci_GetLocalChannel(struct rtw_adapter *padapter)
-{
- return padapter->mlmeextpriv.cur_channel;
-}
-
-static u8 bthci_GetCurrentEntryNum(struct rtw_adapter *padapter, u8 PhyHandle)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- u8 i;
-
- for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) {
- if ((pBTInfo->BtAsocEntry[i].bUsed) &&
- (pBTInfo->BtAsocEntry[i].PhyLinkCmdData.BtPhyLinkhandle == PhyHandle))
- return i;
- }
-
- return 0xFF;
-}
-
-static void bthci_DecideBTChannel(struct rtw_adapter *padapter, u8 EntryNum)
-{
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct mlme_priv *pmlmepriv;
- struct bt_30info *pBTInfo;
- struct bt_mgnt *pBtMgnt;
- struct bt_hci_info *pBtHciInfo;
- struct chnl_txpower_triple *pTriple_subband = NULL;
- struct common_triple *pTriple;
- u8 i, j, localchnl, firstRemoteLegalChnlInTriplet = 0;
- u8 regulatory_skipLen = 0;
- u8 subbandTripletCnt = 0;
-
- pmlmepriv = &padapter->mlmepriv;
- pBTInfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTInfo->BtMgnt;
- pBtHciInfo = &pBTInfo->BtHciInfo;
-
- pBtMgnt->CheckChnlIsSuit = true;
- localchnl = bthci_GetLocalChannel(padapter);
-
- pTriple = (struct common_triple *)
- &pBtHciInfo->BTPreChnllist[COUNTRY_STR_LEN];
-
- /* contains country string, len is 3 */
- for (i = 0; i < (pBtHciInfo->BtPreChnlListLen-COUNTRY_STR_LEN); i += 3, pTriple++) {
- /* */
- /* check every triplet, an triplet may be */
- /* regulatory extension identifier or sub-band triplet */
- /* */
- if (pTriple->byte_1st == 0xc9) {
- /* Regulatory Extension Identifier, skip it */
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO),
- ("Find Regulatory ID, regulatory class = %d\n", pTriple->byte_2nd));
- regulatory_skipLen += 3;
- pTriple_subband = NULL;
- continue;
- } else { /* Sub-band triplet */
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Find Sub-band triplet \n"));
- subbandTripletCnt++;
- pTriple_subband = (struct chnl_txpower_triple *)pTriple;
- /* if remote first legal channel not found, then find first remote channel */
- /* and it's legal for our channel plan. */
-
- /* search the sub-band triplet and find if remote channel is legal to our channel plan. */
- for (j = pTriple_subband->FirstChnl; j < (pTriple_subband->FirstChnl+pTriple_subband->NumChnls); j++) {
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), (" Check if chnl(%d) is legal\n", j));
- if (BT_IsLegalChannel(padapter, j)) {
- /* remote channel is legal for our channel plan. */
- firstRemoteLegalChnlInTriplet = j;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO),
- ("Find first remote legal channel : %d\n",
- firstRemoteLegalChnlInTriplet));
-
- /* If we find a remote legal channel in the sub-band triplet */
- /* and only BT connection is established(local not connect to any AP or IBSS), */
- /* then we just switch channel to remote channel. */
- if (!(check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_ADHOC_STATE|WIFI_AP_STATE) ||
- BTHCI_HsConnectionEstablished(padapter))) {
- pBtMgnt->BTChannel = firstRemoteLegalChnlInTriplet;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Remote legal channel (%d) is selected, Local not connect to any!!\n", pBtMgnt->BTChannel));
- return;
- } else {
- if ((localchnl >= firstRemoteLegalChnlInTriplet) &&
- (localchnl < (pTriple_subband->FirstChnl+pTriple_subband->NumChnls))) {
- pBtMgnt->BTChannel = localchnl;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Local channel (%d) is selected, wifi or BT connection exists\n", pBtMgnt->BTChannel));
- return;
- }
- }
- break;
- }
- }
- }
- }
-
- if (subbandTripletCnt) {
- /* if any preferred channel triplet exists */
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("There are %d sub band triplet exists, ", subbandTripletCnt));
- if (firstRemoteLegalChnlInTriplet == 0) {
- /* no legal channel is found, reject the connection. */
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("no legal channel is found!!\n"));
- } else {
- /* Remote Legal channel is found but not match to local */
- /* wifi connection exists), so reject the connection. */
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO),
- ("Remote Legal channel is found but not match to local(wifi connection exists)!!\n"));
- }
- pBtMgnt->CheckChnlIsSuit = false;
- } else {
- /* There are not any preferred channel triplet exists */
- /* Use current legal channel as the bt channel. */
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("No sub band triplet exists!!\n"));
- }
- pBtMgnt->BTChannel = localchnl;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Local channel (%d) is selected!!\n", pBtMgnt->BTChannel));
-}
-
-/* Success:return true */
-/* Fail:return false */
-static u8 bthci_GetAssocInfo(struct rtw_adapter *padapter, u8 EntryNum)
-{
- struct bt_30info *pBTInfo;
- struct bt_hci_info *pBtHciInfo;
- u8 tempBuf[256];
- u8 i = 0;
- u8 BaseMemoryShift = 0;
- u16 TotalLen = 0;
- struct amp_assoc_structure *pAmpAsoc;
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("GetAssocInfo start\n"));
- pBTInfo = GET_BT_INFO(padapter);
- pBtHciInfo = &pBTInfo->BtHciInfo;
-
- if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar == 0) {
- if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocRemLen < (MAX_AMP_ASSOC_FRAG_LEN))
- TotalLen = pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocRemLen;
- else if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocRemLen == (MAX_AMP_ASSOC_FRAG_LEN))
- TotalLen = MAX_AMP_ASSOC_FRAG_LEN;
- } else if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar > 0)
- TotalLen = pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar;
-
- while ((pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar >= BaseMemoryShift) || TotalLen > BaseMemoryShift) {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("GetAssocInfo, TotalLen =%d, BaseMemoryShift =%d\n", TotalLen, BaseMemoryShift));
- memcpy(tempBuf,
- (u8 *)pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocfragment+BaseMemoryShift,
- TotalLen-BaseMemoryShift);
- RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_DETAIL, "GetAssocInfo :\n",
- tempBuf, TotalLen-BaseMemoryShift);
-
- pAmpAsoc = (struct amp_assoc_structure *)tempBuf;
- le16_to_cpus(&pAmpAsoc->Length);
- BaseMemoryShift += 3 + pAmpAsoc->Length;
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("TypeID = 0x%x, ", pAmpAsoc->TypeID));
- RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD, "Hex Data: \n", pAmpAsoc->Data, pAmpAsoc->Length);
- switch (pAmpAsoc->TypeID) {
- case AMP_MAC_ADDR:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> AMP_MAC_ADDR\n"));
- if (pAmpAsoc->Length > 6)
- return false;
- memcpy(pBTInfo->BtAsocEntry[EntryNum].BTRemoteMACAddr, pAmpAsoc->Data, 6);
- RTPRINT_ADDR(FIOCTL, IOCTL_BT_HCICMD, ("Remote Mac address \n"), pBTInfo->BtAsocEntry[EntryNum].BTRemoteMACAddr);
- break;
- case AMP_PREFERRED_CHANNEL_LIST:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> AMP_PREFERRED_CHANNEL_LIST\n"));
- pBtHciInfo->BtPreChnlListLen = pAmpAsoc->Length;
- memcpy(pBtHciInfo->BTPreChnllist,
- pAmpAsoc->Data,
- pBtHciInfo->BtPreChnlListLen);
- RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD, "Preferred channel list : \n", pBtHciInfo->BTPreChnllist, pBtHciInfo->BtPreChnlListLen);
- bthci_DecideBTChannel(padapter, EntryNum);
- break;
- case AMP_CONNECTED_CHANNEL:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> AMP_CONNECTED_CHANNEL\n"));
- pBtHciInfo->BTConnectChnlListLen = pAmpAsoc->Length;
- memcpy(pBtHciInfo->BTConnectChnllist,
- pAmpAsoc->Data,
- pBtHciInfo->BTConnectChnlListLen);
- break;
- case AMP_80211_PAL_CAP_LIST:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> AMP_80211_PAL_CAP_LIST\n"));
- pBTInfo->BtAsocEntry[EntryNum].BTCapability = *(u32 *)(pAmpAsoc->Data);
- if (pBTInfo->BtAsocEntry[EntryNum].BTCapability & 0x00000001) {
- /* TODO: */
-
- /* Signifies PAL capable of utilizing received activity reports. */
- }
- if (pBTInfo->BtAsocEntry[EntryNum].BTCapability & 0x00000002) {
- /* TODO: */
- /* Signifies PAL is capable of utilizing scheduling information received in an activity reports. */
- }
- break;
- case AMP_80211_PAL_VISION:
- pBtHciInfo->BTPalVersion = *(u8 *)(pAmpAsoc->Data);
- pBtHciInfo->BTPalCompanyID = *(u16 *)(((u8 *)(pAmpAsoc->Data))+1);
- pBtHciInfo->BTPalsubversion = *(u16 *)(((u8 *)(pAmpAsoc->Data))+3);
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("==> AMP_80211_PAL_VISION PalVersion 0x%x, PalCompanyID 0x%x, Palsubversion 0x%x\n",
- pBtHciInfo->BTPalVersion,
- pBtHciInfo->BTPalCompanyID,
- pBtHciInfo->BTPalsubversion));
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> Unsupport TypeID !!\n"));
- break;
- }
- i++;
- }
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("GetAssocInfo end\n"));
-
- return true;
-}
-
-static u8 bthci_AddEntry(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo;
- struct bt_mgnt *pBtMgnt;
- u8 i;
-
- pBTInfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTInfo->BtMgnt;
-
- for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) {
- if (pBTInfo->BtAsocEntry[i].bUsed == false) {
- pBTInfo->BtAsocEntry[i].bUsed = true;
- pBtMgnt->CurrentConnectEntryNum = i;
- break;
- }
- }
-
- if (i == MAX_BT_ASOC_ENTRY_NUM) {
- RTPRINT(FIOCTL, IOCTL_STATE, ("bthci_AddEntry(), Add entry fail!!\n"));
- return false;
- }
- return true;
-}
-
-static u8 bthci_DiscardTxPackets(struct rtw_adapter *padapter, u16 LLH)
-{
- return false;
-}
-
-static u8
-bthci_CheckLogLinkBehavior(
- struct rtw_adapter *padapter,
- struct hci_flow_spec TxFlowSpec
- )
-{
- u8 ID = TxFlowSpec.Identifier;
- u8 ServiceType = TxFlowSpec.ServiceType;
- u16 MaxSDUSize = TxFlowSpec.MaximumSDUSize;
- u32 SDUInterArrivatime = TxFlowSpec.SDUInterArrivalTime;
- u8 match = false;
-
- switch (ID) {
- case 1:
- if (ServiceType == BT_LL_BE) {
- match = true;
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = TX best effort flowspec\n"));
- } else if ((ServiceType == BT_LL_GU) && (MaxSDUSize == 0xffff)) {
- match = true;
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = RX guaranteed latency flowspec\n"));
- } else if ((ServiceType == BT_LL_GU) && (MaxSDUSize == 2500)) {
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = RX guaranteed Large latency flowspec\n"));
- }
- break;
- case 2:
- if (ServiceType == BT_LL_BE) {
- match = true;
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = RX best effort flowspec\n"));
-
- }
- break;
- case 3:
- if ((ServiceType == BT_LL_GU) && (MaxSDUSize == 1492)) {
- match = true;
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = TX guaranteed latency flowspec\n"));
- } else if ((ServiceType == BT_LL_GU) && (MaxSDUSize == 2500)) {
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = TX guaranteed Large latency flowspec\n"));
- }
- break;
- case 4:
- if (ServiceType == BT_LL_BE) {
- if ((SDUInterArrivatime == 0xffffffff) && (ServiceType == BT_LL_BE) && (MaxSDUSize == 1492)) {
- match = true;
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = TX/RX aggregated best effort flowspec\n"));
- }
- } else if (ServiceType == BT_LL_GU) {
- if (SDUInterArrivatime == 100) {
- match = true;
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = TX/RX guaranteed bandwidth flowspec\n"));
- }
- }
- break;
- default:
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = Unknow Type !!!!!!!!\n"));
- break;
- }
-
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO),
- ("ID = 0x%x, ServiceType = 0x%x, MaximumSDUSize = 0x%x, SDUInterArrivalTime = 0x%x, AccessLatency = 0x%x, FlushTimeout = 0x%x\n",
- TxFlowSpec.Identifier, TxFlowSpec.ServiceType, MaxSDUSize,
- SDUInterArrivatime, TxFlowSpec.AccessLatency, TxFlowSpec.FlushTimeout));
- return match;
-}
-
-static u16 bthci_AssocMACAddr(struct rtw_adapter *padapter, void *pbuf)
-{
- struct amp_assoc_structure *pAssoStrc = (struct amp_assoc_structure *)pbuf;
- pAssoStrc->TypeID = AMP_MAC_ADDR;
- pAssoStrc->Length = 0x06;
- memcpy(&pAssoStrc->Data[0], padapter->eeprompriv.mac_addr, 6);
- RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO),
- ("AssocMACAddr : \n"), pAssoStrc, pAssoStrc->Length+3);
-
- return pAssoStrc->Length + 3;
-}
-
-static u16
-bthci_PALCapabilities(
- struct rtw_adapter *padapter,
- void *pbuf
- )
-{
- struct amp_assoc_structure *pAssoStrc = (struct amp_assoc_structure *)pbuf;
-
- pAssoStrc->TypeID = AMP_80211_PAL_CAP_LIST;
- pAssoStrc->Length = 0x04;
-
- pAssoStrc->Data[0] = 0x00;
- pAssoStrc->Data[1] = 0x00;
-
- RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("PALCapabilities:\n"), pAssoStrc, pAssoStrc->Length+3);
- RTPRINT(FIOCTL, IOCTL_BT_LOGO, ("PALCapabilities \n"));
-
- RTPRINT(FIOCTL, IOCTL_BT_LOGO, (" TypeID = 0x%x,\n Length = 0x%x,\n Content = 0x0000\n",
- pAssoStrc->TypeID,
- pAssoStrc->Length));
-
- return pAssoStrc->Length + 3;
-}
-
-static u16 bthci_AssocPreferredChannelList(struct rtw_adapter *padapter,
- void *pbuf, u8 EntryNum)
-{
- struct bt_30info *pBTInfo;
- struct amp_assoc_structure *pAssoStrc;
- struct amp_pref_chnl_regulatory *pReg;
- struct chnl_txpower_triple *pTriple;
- char ctrString[3] = {'X', 'X', 'X'};
- u32 len = 0;
- u8 preferredChnl;
-
- pBTInfo = GET_BT_INFO(padapter);
- pAssoStrc = (struct amp_assoc_structure *)pbuf;
- pReg = (struct amp_pref_chnl_regulatory *)&pAssoStrc->Data[3];
-
- preferredChnl = bthci_GetLocalChannel(padapter);
- pAssoStrc->TypeID = AMP_PREFERRED_CHANNEL_LIST;
-
- /* locale unknown */
- memcpy(&pAssoStrc->Data[0], &ctrString[0], 3);
- pReg->reXId = 201;
- pReg->regulatoryClass = 254;
- pReg->coverageClass = 0;
- len += 6;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD | IOCTL_BT_LOGO), ("PREFERRED_CHNL_LIST\n"));
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD | IOCTL_BT_LOGO), ("XXX, 201, 254, 0\n"));
- /* at the following, chnl 1~11 should be contained */
- pTriple = (struct chnl_txpower_triple *)&pAssoStrc->Data[len];
-
- /* (1) if any wifi or bt HS connection exists */
- if ((pBTInfo->BtAsocEntry[EntryNum].AMPRole == AMP_BTAP_CREATOR) ||
- (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE |
- WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE |
- WIFI_AP_STATE)) ||
- BTHCI_HsConnectionEstablished(padapter)) {
- pTriple->FirstChnl = preferredChnl;
- pTriple->NumChnls = 1;
- pTriple->MaxTxPowerInDbm = 20;
- len += 3;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD | IOCTL_BT_LOGO), ("First Channel = %d, Channel Num = %d, MaxDbm = %d\n",
- pTriple->FirstChnl,
- pTriple->NumChnls,
- pTriple->MaxTxPowerInDbm));
- }
-
- pAssoStrc->Length = (u16)len;
- RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD, ("AssocPreferredChannelList : \n"), pAssoStrc, pAssoStrc->Length+3);
-
- return pAssoStrc->Length + 3;
-}
-
-static u16 bthci_AssocPALVer(struct rtw_adapter *padapter, void *pbuf)
-{
- struct amp_assoc_structure *pAssoStrc = (struct amp_assoc_structure *)pbuf;
- u8 *pu1Tmp;
- u16 *pu2Tmp;
-
- pAssoStrc->TypeID = AMP_80211_PAL_VISION;
- pAssoStrc->Length = 0x5;
- pu1Tmp = &pAssoStrc->Data[0];
- *pu1Tmp = 0x1; /* PAL Version */
- pu2Tmp = (u16 *)&pAssoStrc->Data[1];
- *pu2Tmp = 0x5D; /* SIG Company identifier of 802.11 PAL vendor */
- pu2Tmp = (u16 *)&pAssoStrc->Data[3];
- *pu2Tmp = 0x1; /* PAL Sub-version specifier */
-
- RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("AssocPALVer : \n"), pAssoStrc, pAssoStrc->Length+3);
- RTPRINT(FIOCTL, IOCTL_BT_LOGO, ("AssocPALVer \n"));
-
- RTPRINT(FIOCTL, IOCTL_BT_LOGO, (" TypeID = 0x%x,\n Length = 0x%x,\n PAL Version = 0x01,\n PAL vendor = 0x01,\n PAL Sub-version specifier = 0x01\n",
- pAssoStrc->TypeID,
- pAssoStrc->Length));
- return pAssoStrc->Length + 3;
-}
-
-static u8 bthci_CheckRfStateBeforeConnect(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo;
- enum rt_rf_power_state RfState;
-
- pBTInfo = GET_BT_INFO(padapter);
-
- RfState = padapter->pwrctrlpriv.rf_pwrstate;
-
- if (RfState != rf_on) {
- mod_timer(&pBTInfo->BTPsDisableTimer,
- jiffies + msecs_to_jiffies(50));
- return false;
- }
- return true;
-}
-
-static void bthci_ResponderStartToScan(struct rtw_adapter *padapter)
-{
-}
-
-static u8 bthci_PhyLinkConnectionInProgress(struct rtw_adapter *padapter, u8 PhyLinkHandle)
-{
- struct bt_30info *pBTInfo;
- struct bt_mgnt *pBtMgnt;
-
- pBTInfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTInfo->BtMgnt;
-
- if (pBtMgnt->bPhyLinkInProgress &&
- (pBtMgnt->BtCurrentPhyLinkhandle == PhyLinkHandle))
- return true;
- return false;
-}
-
-static void bthci_ResetFlowSpec(struct rtw_adapter *padapter, u8 EntryNum, u8 index)
-{
- struct bt_30info *pBTinfo;
-
- pBTinfo = GET_BT_INFO(padapter);
-
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].BtLogLinkhandle = 0;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].BtPhyLinkhandle = 0;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].bLLCompleteEventIsSet = false;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].bLLCancelCMDIsSetandComplete = false;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].BtTxFlowSpecID = 0;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].TxPacketCount = 0;
-
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.Identifier = 0x01;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.ServiceType = SERVICE_BEST_EFFORT;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.MaximumSDUSize = 0xffff;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.SDUInterArrivalTime = 0xffffffff;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.AccessLatency = 0xffffffff;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.FlushTimeout = 0xffffffff;
-
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.Identifier = 0x01;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.ServiceType = SERVICE_BEST_EFFORT;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.MaximumSDUSize = 0xffff;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.SDUInterArrivalTime = 0xffffffff;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.AccessLatency = 0xffffffff;
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.FlushTimeout = 0xffffffff;
-}
-
-static void bthci_ResetEntry(struct rtw_adapter *padapter, u8 EntryNum)
-{
- struct bt_30info *pBTinfo;
- struct bt_mgnt *pBtMgnt;
- u8 j;
-
- pBTinfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTinfo->BtMgnt;
-
- pBTinfo->BtAsocEntry[EntryNum].bUsed = false;
- pBTinfo->BtAsocEntry[EntryNum].BtCurrentState = HCI_STATE_DISCONNECTED;
- pBTinfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTED;
-
- pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocRemLen = 0;
- pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.BtPhyLinkhandle = 0;
- if (pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocfragment != NULL)
- memset(pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocfragment, 0, TOTAL_ALLOCIATE_ASSOC_LEN);
- pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar = 0;
-
- pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyType = 0;
- pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle = 0;
- memset(pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKey, 0,
- pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen);
- pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen = 0;
-
- /* 0x640; 0.625ms*1600 = 1000ms, 0.625ms*16000 = 10000ms */
- pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.LinkSuperversionTimeout = 0x3e80;
-
- pBTinfo->BtAsocEntry[EntryNum].AMPRole = AMP_BTAP_NONE;
-
- pBTinfo->BtAsocEntry[EntryNum].mAssoc = false;
- pBTinfo->BtAsocEntry[EntryNum].b4waySuccess = false;
-
- /* Reset BT WPA */
- pBTinfo->BtAsocEntry[EntryNum].KeyReplayCounter = 0;
- pBTinfo->BtAsocEntry[EntryNum].BTWPAAuthState = STATE_WPA_AUTH_UNINITIALIZED;
-
- pBTinfo->BtAsocEntry[EntryNum].bSendSupervisionPacket = false;
- pBTinfo->BtAsocEntry[EntryNum].NoRxPktCnt = 0;
- pBTinfo->BtAsocEntry[EntryNum].ShortRangeMode = 0;
- pBTinfo->BtAsocEntry[EntryNum].rxSuvpPktCnt = 0;
-
- for (j = 0; j < MAX_LOGICAL_LINK_NUM; j++)
- bthci_ResetFlowSpec(padapter, EntryNum, j);
-
- pBtMgnt->BTAuthCount = 0;
- pBtMgnt->BTAsocCount = 0;
- pBtMgnt->BTCurrentConnectType = BT_DISCONNECT;
- pBtMgnt->BTReceiveConnectPkt = BT_DISCONNECT;
-
- HALBT_RemoveKey(padapter, EntryNum);
-}
-
-static void bthci_RemoveEntryByEntryNum(struct rtw_adapter *padapter, u8 EntryNum)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- bthci_ResetEntry(padapter, EntryNum);
-
- if (pBtMgnt->CurrentBTConnectionCnt > 0)
- pBtMgnt->CurrentBTConnectionCnt--;
-
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], CurrentBTConnectionCnt = %d!!\n",
- pBtMgnt->CurrentBTConnectionCnt));
-
- if (pBtMgnt->CurrentBTConnectionCnt > 0) {
- pBtMgnt->BtOperationOn = true;
- } else {
- pBtMgnt->BtOperationOn = false;
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], Bt Operation OFF!!\n"));
- }
-
- if (!pBtMgnt->BtOperationOn) {
- del_timer_sync(&pBTInfo->BTHCIDiscardAclDataTimer);
- del_timer_sync(&pBTInfo->BTBeaconTimer);
- pBtMgnt->bStartSendSupervisionPkt = false;
- }
-}
-
-static u8
-bthci_CommandCompleteHeader(
- u8 *pbuf,
- u16 OGF,
- u16 OCF,
- enum hci_status status
- )
-{
- struct packet_irp_hcievent_data *PPacketIrpEvent = (struct packet_irp_hcievent_data *)pbuf;
- u8 NumHCI_Comm = 0x1;
-
- PPacketIrpEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
- PPacketIrpEvent->Data[0] = NumHCI_Comm; /* packet # */
- PPacketIrpEvent->Data[1] = HCIOPCODELOW(OCF, OGF);
- PPacketIrpEvent->Data[2] = HCIOPCODEHIGHT(OCF, OGF);
-
- if (OGF == OGF_EXTENSION) {
- if (OCF == HCI_SET_RSSI_VALUE) {
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT_PERIODICAL),
- ("[BT event], CommandComplete, Num_HCI_Comm = 0x%x, Opcode = 0x%02x%02x, status = 0x%x, OGF = 0x%x, OCF = 0x%x\n",
- NumHCI_Comm, (HCIOPCODEHIGHT(OCF, OGF)), (HCIOPCODELOW(OCF, OGF)), status, OGF, OCF));
- } else {
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_EXT),
- ("[BT event], CommandComplete, Num_HCI_Comm = 0x%x, Opcode = 0x%02x%02x, status = 0x%x, OGF = 0x%x, OCF = 0x%x\n",
- NumHCI_Comm, (HCIOPCODEHIGHT(OCF, OGF)), (HCIOPCODELOW(OCF, OGF)), status, OGF, OCF));
- }
- } else {
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO),
- ("[BT event], CommandComplete, Num_HCI_Comm = 0x%x, Opcode = 0x%02x%02x, status = 0x%x, OGF = 0x%x, OCF = 0x%x\n",
- NumHCI_Comm, (HCIOPCODEHIGHT(OCF, OGF)), (HCIOPCODELOW(OCF, OGF)), status, OGF, OCF));
- }
- return 3;
-}
-
-static u8 bthci_ExtensionEventHeaderRtk(u8 *pbuf, u8 extensionEvent)
-{
- struct packet_irp_hcievent_data *PPacketIrpEvent = (struct packet_irp_hcievent_data *)pbuf;
- PPacketIrpEvent->EventCode = HCI_EVENT_EXTENSION_RTK;
- PPacketIrpEvent->Data[0] = extensionEvent; /* extension event code */
-
- return 1;
-}
-
-static enum rt_status
-bthci_IndicateEvent(
- struct rtw_adapter *padapter,
- void *pEvntData,
- u32 dataLen
- )
-{
- return PlatformIndicateBTEvent(padapter, pEvntData, dataLen);
-}
-
-static void
-bthci_EventWriteRemoteAmpAssoc(
- struct rtw_adapter *padapter,
- enum hci_status status,
- u8 PLHandle
- )
-{
- u8 localBuf[TmpLocalBufSize] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_STATUS_PARAMETERS,
- HCI_WRITE_REMOTE_AMP_ASSOC,
- status);
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("PhyLinkHandle = 0x%x, status = %d\n", PLHandle, status));
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- pRetPar[1] = PLHandle;
- len += 2;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-}
-
-static void
-bthci_EventEnhancedFlushComplete(
- struct rtw_adapter *padapter,
- u16 LLH
- )
-{
- u8 localBuf[4] = "";
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("EventEnhancedFlushComplete, LLH = 0x%x\n", LLH));
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_ENHANCED_FLUSH_COMPLETE;
- PPacketIrpEvent->Length = 2;
- /* Logical link handle */
- PPacketIrpEvent->Data[0] = TWOBYTE_LOWBYTE(LLH);
- PPacketIrpEvent->Data[1] = TWOBYTE_HIGHTBYTE(LLH);
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 4);
-}
-
-static void
-bthci_EventShortRangeModeChangeComplete(
- struct rtw_adapter *padapter,
- enum hci_status HciStatus,
- u8 ShortRangeState,
- u8 EntryNum
- )
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 localBuf[5] = "";
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_SHORT_RANGE_MODE_CHANGE_COMPLETE)) {
- RTPRINT(FIOCTL, IOCTL_BT_EVENT,
- ("[BT event], Short Range Mode Change Complete, Ignore to send this event due to event mask page 2\n"));
- return;
- }
- RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Short Range Mode Change Complete, Status = %d\n , PLH = 0x%x\n, Short_Range_Mode_State = 0x%x\n",
- HciStatus, pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle, ShortRangeState));
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_SHORT_RANGE_MODE_CHANGE_COMPLETE;
- PPacketIrpEvent->Length = 3;
- PPacketIrpEvent->Data[0] = HciStatus;
- PPacketIrpEvent->Data[1] = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle;
- PPacketIrpEvent->Data[2] = ShortRangeState;
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 5);
-}
-
-static void bthci_EventSendFlowSpecModifyComplete(struct rtw_adapter *padapter,
- enum hci_status HciStatus,
- u16 logicHandle)
-{
- u8 localBuf[5] = "";
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
-
- if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_FLOW_SPEC_MODIFY_COMPLETE)) {
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO),
- ("[BT event], Flow Spec Modify Complete, Ignore to send this event due to event mask page 2\n"));
- return;
- }
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO),
- ("[BT event], Flow Spec Modify Complete, status = 0x%x, LLH = 0x%x\n", HciStatus, logicHandle));
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_FLOW_SPEC_MODIFY_COMPLETE;
- PPacketIrpEvent->Length = 3;
-
- PPacketIrpEvent->Data[0] = HciStatus;
- /* Logical link handle */
- PPacketIrpEvent->Data[1] = TWOBYTE_LOWBYTE(logicHandle);
- PPacketIrpEvent->Data[2] = TWOBYTE_HIGHTBYTE(logicHandle);
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 5);
-}
-
-static void
-bthci_EventExtWifiScanNotify(
- struct rtw_adapter *padapter,
- u8 scanType
- )
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- u8 len = 0;
- u8 localBuf[7] = "";
- u8 *pRetPar;
- u8 *pu1Temp;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- if (!pBtMgnt->BtOperationOn)
- return;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_ExtensionEventHeaderRtk(&localBuf[0], HCI_EVENT_EXT_WIFI_SCAN_NOTIFY);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pu1Temp = (u8 *)&pRetPar[0];
- *pu1Temp = scanType;
- len += 1;
-
- PPacketIrpEvent->Length = len;
-
- if (bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2) == RT_STATUS_SUCCESS) {
- RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Wifi scan notify, scan type = %d\n",
- scanType));
- }
-}
-
-static void
-bthci_EventAMPReceiverReport(
- struct rtw_adapter *padapter,
- u8 Reason
- )
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
-
- if (pBtHciInfo->bTestNeedReport) {
- u8 localBuf[20] = "";
- u32 *pu4Temp;
- u16 *pu2Temp;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), (" HCI_EVENT_AMP_RECEIVER_REPORT\n"));
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_AMP_RECEIVER_REPORT;
- PPacketIrpEvent->Length = 2;
-
- PPacketIrpEvent->Data[0] = pBtHciInfo->TestCtrType;
-
- PPacketIrpEvent->Data[1] = Reason;
-
- pu4Temp = (u32 *)&PPacketIrpEvent->Data[2];
- *pu4Temp = pBtHciInfo->TestEventType;
-
- pu2Temp = (u16 *)&PPacketIrpEvent->Data[6];
- *pu2Temp = pBtHciInfo->TestNumOfFrame;
-
- pu2Temp = (u16 *)&PPacketIrpEvent->Data[8];
- *pu2Temp = pBtHciInfo->TestNumOfErrFrame;
-
- pu4Temp = (u32 *)&PPacketIrpEvent->Data[10];
- *pu4Temp = pBtHciInfo->TestNumOfBits;
-
- pu4Temp = (u32 *)&PPacketIrpEvent->Data[14];
- *pu4Temp = pBtHciInfo->TestNumOfErrBits;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 20);
-
- /* Return to Idel state with RX and TX off. */
-
- }
-
- pBtHciInfo->TestNumOfFrame = 0x00;
-}
-
-static void
-bthci_EventChannelSelected(
- struct rtw_adapter *padapter,
- u8 EntryNum
- )
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 localBuf[3] = "";
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_CHANNEL_SELECT)) {
- RTPRINT(FIOCTL, IOCTL_BT_EVENT,
- ("[BT event], Channel Selected, Ignore to send this event due to event mask page 2\n"));
- return;
- }
-
- RTPRINT(FIOCTL, IOCTL_BT_EVENT|IOCTL_STATE,
- ("[BT event], Channel Selected, PhyLinkHandle %d\n",
- pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle));
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_CHANNEL_SELECT;
- PPacketIrpEvent->Length = 1;
- PPacketIrpEvent->Data[0] = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle;
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 3);
-}
-
-static void
-bthci_EventDisconnectPhyLinkComplete(
- struct rtw_adapter *padapter,
- enum hci_status HciStatus,
- enum hci_status Reason,
- u8 EntryNum
- )
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 localBuf[5] = "";
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_DISCONNECT_PHY_LINK_COMPLETE)) {
- RTPRINT(FIOCTL, IOCTL_BT_EVENT,
- ("[BT event], Disconnect Physical Link Complete, Ignore to send this event due to event mask page 2\n"));
- return;
- }
- RTPRINT(FIOCTL, IOCTL_BT_EVENT,
- ("[BT event], Disconnect Physical Link Complete, Status = 0x%x, PLH = 0x%x Reason = 0x%x\n",
- HciStatus, pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle, Reason));
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_DISCONNECT_PHY_LINK_COMPLETE;
- PPacketIrpEvent->Length = 3;
- PPacketIrpEvent->Data[0] = HciStatus;
- PPacketIrpEvent->Data[1] = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle;
- PPacketIrpEvent->Data[2] = Reason;
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 5);
-}
-
-static void
-bthci_EventPhysicalLinkComplete(
- struct rtw_adapter *padapter,
- enum hci_status HciStatus,
- u8 EntryNum,
- u8 PLHandle
- )
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
- u8 localBuf[4] = "";
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u8 PL_handle;
-
- pBtMgnt->bPhyLinkInProgress = false;
- pBtDbg->dbgHciInfo.hciCmdPhyLinkStatus = HciStatus;
- if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_PHY_LINK_COMPLETE)) {
- RTPRINT(FIOCTL, IOCTL_BT_EVENT,
- ("[BT event], Physical Link Complete, Ignore to send this event due to event mask page 2\n"));
- return;
- }
-
- if (EntryNum == 0xff) {
- /* connection not started yet, just use the input physical link handle to response. */
- PL_handle = PLHandle;
- } else {
- /* connection is under progress, use the phy link handle we recorded. */
- PL_handle = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle;
- pBTInfo->BtAsocEntry[EntryNum].bNeedPhysLinkCompleteEvent = false;
- }
-
- RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Physical Link Complete, Status = 0x%x PhyLinkHandle = 0x%x\n", HciStatus,
- PL_handle));
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_PHY_LINK_COMPLETE;
- PPacketIrpEvent->Length = 2;
-
- PPacketIrpEvent->Data[0] = HciStatus;
- PPacketIrpEvent->Data[1] = PL_handle;
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 4);
-
-}
-
-static void
-bthci_EventCommandStatus(
- struct rtw_adapter *padapter,
- u8 OGF,
- u16 OCF,
- enum hci_status HciStatus
- )
-{
-
- u8 localBuf[6] = "";
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u8 Num_Hci_Comm = 0x1;
- RTPRINT(FIOCTL, IOCTL_BT_EVENT,
- ("[BT event], CommandStatus, Opcode = 0x%02x%02x, OGF = 0x%x, OCF = 0x%x, Status = 0x%x, Num_HCI_COMM = 0x%x\n",
- (HCIOPCODEHIGHT(OCF, OGF)), (HCIOPCODELOW(OCF, OGF)), OGF, OCF, HciStatus, Num_Hci_Comm));
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_COMMAND_STATUS;
- PPacketIrpEvent->Length = 4;
- PPacketIrpEvent->Data[0] = HciStatus; /* current pending */
- PPacketIrpEvent->Data[1] = Num_Hci_Comm; /* packet # */
- PPacketIrpEvent->Data[2] = HCIOPCODELOW(OCF, OGF);
- PPacketIrpEvent->Data[3] = HCIOPCODEHIGHT(OCF, OGF);
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 6);
-
-}
-
-static void
-bthci_EventLogicalLinkComplete(
- struct rtw_adapter *padapter,
- enum hci_status HciStatus,
- u8 PhyLinkHandle,
- u16 LogLinkHandle,
- u8 LogLinkIndex,
- u8 EntryNum
- )
-{
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 localBuf[7] = "";
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_LOGICAL_LINK_COMPLETE)) {
- RTPRINT(FIOCTL, IOCTL_BT_EVENT,
- ("[BT event], Logical Link Complete, Ignore to send this event due to event mask page 2\n"));
- return;
- }
- RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Logical Link Complete, PhyLinkHandle = 0x%x, LogLinkHandle = 0x%x, Status = 0x%x\n",
- PhyLinkHandle, LogLinkHandle, HciStatus));
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_LOGICAL_LINK_COMPLETE;
- PPacketIrpEvent->Length = 5;
-
- PPacketIrpEvent->Data[0] = HciStatus;/* status code */
- /* Logical link handle */
- PPacketIrpEvent->Data[1] = TWOBYTE_LOWBYTE(LogLinkHandle);
- PPacketIrpEvent->Data[2] = TWOBYTE_HIGHTBYTE(LogLinkHandle);
- /* Physical link handle */
- PPacketIrpEvent->Data[3] = TWOBYTE_LOWBYTE(PhyLinkHandle);
- /* corresponding Tx flow spec ID */
- if (HciStatus == HCI_STATUS_SUCCESS) {
- PPacketIrpEvent->Data[4] =
- pBTInfo->BtAsocEntry[EntryNum].LogLinkCmdData[LogLinkIndex].Tx_Flow_Spec.Identifier;
- } else {
- PPacketIrpEvent->Data[4] = 0x0;
- }
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 7);
-}
-
-static void
-bthci_EventDisconnectLogicalLinkComplete(
- struct rtw_adapter *padapter,
- enum hci_status HciStatus,
- u16 LogLinkHandle,
- enum hci_status Reason
- )
-{
- u8 localBuf[6] = "";
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_DISCONNECT_LOGICAL_LINK_COMPLETE)) {
- RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Disconnect Logical Link Complete, Ignore to send this event due to event mask page 2\n"));
- return;
- }
- RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Disconnect Logical Link Complete, Status = 0x%x, LLH = 0x%x Reason = 0x%x\n", HciStatus, LogLinkHandle, Reason));
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_DISCONNECT_LOGICAL_LINK_COMPLETE;
- PPacketIrpEvent->Length = 4;
-
- PPacketIrpEvent->Data[0] = HciStatus;
- /* Logical link handle */
- PPacketIrpEvent->Data[1] = TWOBYTE_LOWBYTE(LogLinkHandle);
- PPacketIrpEvent->Data[2] = TWOBYTE_HIGHTBYTE(LogLinkHandle);
- /* Disconnect reason */
- PPacketIrpEvent->Data[3] = Reason;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 6);
-}
-
-static void
-bthci_EventFlushOccurred(
- struct rtw_adapter *padapter,
- u16 LogLinkHandle
- )
-{
- u8 localBuf[4] = "";
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("bthci_EventFlushOccurred(), LLH = 0x%x\n", LogLinkHandle));
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_FLUSH_OCCRUED;
- PPacketIrpEvent->Length = 2;
- /* Logical link handle */
- PPacketIrpEvent->Data[0] = TWOBYTE_LOWBYTE(LogLinkHandle);
- PPacketIrpEvent->Data[1] = TWOBYTE_HIGHTBYTE(LogLinkHandle);
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 4);
-}
-
-static enum hci_status
-bthci_BuildPhysicalLink(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd,
- u16 OCF
-)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- u8 EntryNum, PLH;
-
- /* Send HCI Command status event to AMP. */
- bthci_EventCommandStatus(padapter,
- LINK_CONTROL_COMMANDS,
- OCF,
- HCI_STATUS_SUCCESS);
-
- PLH = *((u8 *)pHciCmd->Data);
-
- /* Check if resource or bt connection is under progress, if yes, reject the link creation. */
- if (!bthci_AddEntry(padapter)) {
- status = HCI_STATUS_CONNECT_RJT_LIMIT_RESOURCE;
- bthci_EventPhysicalLinkComplete(padapter, status, INVALID_ENTRY_NUM, PLH);
- return status;
- }
-
- EntryNum = pBtMgnt->CurrentConnectEntryNum;
- pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle = PLH;
- pBtMgnt->BtCurrentPhyLinkhandle = PLH;
-
- if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocfragment == NULL) {
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Create/Accept PhysicalLink, AMP controller is busy\n"));
- status = HCI_STATUS_CONTROLLER_BUSY;
- bthci_EventPhysicalLinkComplete(padapter, status, INVALID_ENTRY_NUM, PLH);
- return status;
- }
-
- /* Record Key and the info */
- pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen = (*((u8 *)pHciCmd->Data+1));
- pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyType = (*((u8 *)pHciCmd->Data+2));
- memcpy(pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKey,
- (((u8 *)pHciCmd->Data+3)), pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen);
- memcpy(pBTInfo->BtAsocEntry[EntryNum].PMK, pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKey, PMK_LEN);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("BuildPhysicalLink, EntryNum = %d, PLH = 0x%x KeyLen = 0x%x, KeyType = 0x%x\n",
- EntryNum, pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle,
- pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen,
- pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyType));
- RTPRINT_DATA(FIOCTL, (IOCTL_BT_LOGO|IOCTL_BT_HCICMD), ("BtAMPKey\n"), pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKey,
- pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen);
- RTPRINT_DATA(FIOCTL, (IOCTL_BT_LOGO|IOCTL_BT_HCICMD), ("PMK\n"), pBTInfo->BtAsocEntry[EntryNum].PMK,
- PMK_LEN);
-
- if (OCF == HCI_CREATE_PHYSICAL_LINK) {
- /* These macros require braces */
- BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_CREATE_PHY_LINK, EntryNum);
- } else if (OCF == HCI_ACCEPT_PHYSICAL_LINK) {
- BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_ACCEPT_PHY_LINK, EntryNum);
- }
-
- return status;
-}
-
-static void
-bthci_BuildLogicalLink(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd,
- u16 OCF
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTinfo->BtMgnt;
- u8 PhyLinkHandle, EntryNum;
- static u16 AssignLogHandle = 1;
-
- struct hci_flow_spec TxFlowSpec;
- struct hci_flow_spec RxFlowSpec;
- u32 MaxSDUSize, ArriveTime, Bandwidth;
-
- PhyLinkHandle = *((u8 *)pHciCmd->Data);
-
- EntryNum = bthci_GetCurrentEntryNum(padapter, PhyLinkHandle);
-
- memcpy(&TxFlowSpec,
- &pHciCmd->Data[1], sizeof(struct hci_flow_spec));
- memcpy(&RxFlowSpec,
- &pHciCmd->Data[17], sizeof(struct hci_flow_spec));
-
- MaxSDUSize = TxFlowSpec.MaximumSDUSize;
- ArriveTime = TxFlowSpec.SDUInterArrivalTime;
-
- if (bthci_CheckLogLinkBehavior(padapter, TxFlowSpec) && bthci_CheckLogLinkBehavior(padapter, RxFlowSpec))
- Bandwidth = BTTOTALBANDWIDTH;
- else if (MaxSDUSize == 0xffff && ArriveTime == 0xffffffff)
- Bandwidth = BTTOTALBANDWIDTH;
- else
- Bandwidth = MaxSDUSize*8*1000/(ArriveTime+244);
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD,
- ("BuildLogicalLink, PhyLinkHandle = 0x%x, MaximumSDUSize = 0x%x, SDUInterArrivalTime = 0x%x, Bandwidth = 0x%x\n",
- PhyLinkHandle, MaxSDUSize, ArriveTime, Bandwidth));
-
- if (EntryNum == 0xff) {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Invalid Physical Link handle = 0x%x, status = HCI_STATUS_UNKNOW_CONNECT_ID, return\n", PhyLinkHandle));
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
-
- /* When we receive Create/Accept logical link command, we should send command status event first. */
- bthci_EventCommandStatus(padapter,
- LINK_CONTROL_COMMANDS,
- OCF,
- status);
- return;
- }
-
- if (!pBtMgnt->bLogLinkInProgress) {
- if (bthci_PhyLinkConnectionInProgress(padapter, PhyLinkHandle)) {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Physical link connection in progress, status = HCI_STATUS_CMD_DISALLOW, return\n"));
- status = HCI_STATUS_CMD_DISALLOW;
-
- pBtMgnt->bPhyLinkInProgressStartLL = true;
- /* When we receive Create/Accept logical link command, we should send command status event first. */
- bthci_EventCommandStatus(padapter,
- LINK_CONTROL_COMMANDS,
- OCF,
- status);
-
- return;
- }
-
- if (Bandwidth > BTTOTALBANDWIDTH) {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("status = HCI_STATUS_QOS_REJECT, Bandwidth = 0x%x, return\n", Bandwidth));
- status = HCI_STATUS_QOS_REJECT;
-
- /* When we receive Create/Accept logical link command, we should send command status event first. */
- bthci_EventCommandStatus(padapter,
- LINK_CONTROL_COMMANDS,
- OCF,
- status);
- } else {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("status = HCI_STATUS_SUCCESS\n"));
- status = HCI_STATUS_SUCCESS;
-
- /* When we receive Create/Accept logical link command, we should send command status event first. */
- bthci_EventCommandStatus(padapter,
- LINK_CONTROL_COMMANDS,
- OCF,
- status);
-
- }
-
- if (pBTinfo->BtAsocEntry[EntryNum].BtCurrentState != HCI_STATE_CONNECTED) {
- bthci_EventLogicalLinkComplete(padapter,
- HCI_STATUS_CMD_DISALLOW, 0, 0, 0, EntryNum);
- } else {
- u8 i, find = 0;
-
- pBtMgnt->bLogLinkInProgress = true;
-
- /* find an unused logical link index and copy the data */
- for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
- if (pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtLogLinkhandle == 0) {
- enum hci_status LogCompEventstatus = HCI_STATUS_SUCCESS;
-
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtPhyLinkhandle = *((u8 *)pHciCmd->Data);
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtLogLinkhandle = AssignLogHandle;
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("BuildLogicalLink, EntryNum = %d, physical link handle = 0x%x, logical link handle = 0x%x\n",
- EntryNum, pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle,
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtLogLinkhandle));
- memcpy(&pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].Tx_Flow_Spec,
- &TxFlowSpec, sizeof(struct hci_flow_spec));
- memcpy(&pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].Rx_Flow_Spec,
- &RxFlowSpec, sizeof(struct hci_flow_spec));
-
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].bLLCompleteEventIsSet = false;
-
- if (pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].bLLCancelCMDIsSetandComplete)
- LogCompEventstatus = HCI_STATUS_UNKNOW_CONNECT_ID;
- bthci_EventLogicalLinkComplete(padapter,
- LogCompEventstatus,
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtPhyLinkhandle,
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtLogLinkhandle, i, EntryNum);
-
- pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].bLLCompleteEventIsSet = true;
-
- find = 1;
- pBtMgnt->BtCurrentLogLinkhandle = AssignLogHandle;
- AssignLogHandle++;
- break;
- }
- }
-
- if (!find) {
- bthci_EventLogicalLinkComplete(padapter,
- HCI_STATUS_CONNECT_RJT_LIMIT_RESOURCE, 0, 0, 0, EntryNum);
- }
- pBtMgnt->bLogLinkInProgress = false;
- }
- } else {
- bthci_EventLogicalLinkComplete(padapter,
- HCI_STATUS_CONTROLLER_BUSY, 0, 0, 0, EntryNum);
- }
-
-}
-
-static void
-bthci_StartBeaconAndConnect(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd,
- u8 CurrentAssocNum
- )
-{
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("StartBeaconAndConnect, CurrentAssocNum =%d, AMPRole =%d\n",
- CurrentAssocNum,
- pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole));
-
- if (!pBtMgnt->CheckChnlIsSuit) {
- bthci_EventPhysicalLinkComplete(padapter, HCI_STATUS_CONNECT_REJ_NOT_SUIT_CHNL_FOUND, CurrentAssocNum, INVALID_PL_HANDLE);
- bthci_RemoveEntryByEntryNum(padapter, CurrentAssocNum);
- return;
- }
-
- if (pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole == AMP_BTAP_CREATOR) {
- snprintf((char *)pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsidBuf, 32,
- "AMP-%pMF", padapter->eeprompriv.mac_addr);
- } else if (pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole == AMP_BTAP_JOINER) {
- snprintf((char *)pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsidBuf, 32,
- "AMP-%pMF", pBTInfo->BtAsocEntry[CurrentAssocNum].BTRemoteMACAddr);
- }
-
- FillOctetString(pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsid, pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsidBuf, 21);
- pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsid.Length = 21;
-
- /* To avoid set the start ap or connect twice, or the original connection will be disconnected. */
- if (!pBtMgnt->bBTConnectInProgress) {
- pBtMgnt->bBTConnectInProgress = true;
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress ON!!\n"));
- BTHCI_SM_WITH_INFO(padapter, HCI_STATE_STARTING, STATE_CMD_MAC_START_COMPLETE, CurrentAssocNum);
-
- /* 20100325 Joseph: Check RF ON/OFF. */
- /* If RF OFF, it reschedule connecting operation after 50ms. */
- if (!bthci_CheckRfStateBeforeConnect(padapter))
- return;
-
- if (pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole == AMP_BTAP_CREATOR) {
- /* These macros need braces */
- BTHCI_SM_WITH_INFO(padapter, HCI_STATE_CONNECTING, STATE_CMD_MAC_CONNECT_COMPLETE, CurrentAssocNum);
- } else if (pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole == AMP_BTAP_JOINER) {
- bthci_ResponderStartToScan(padapter);
- }
- }
- RT_PRINT_STR(_module_rtl871x_mlme_c_, _drv_notice_,
- "StartBeaconAndConnect, SSID:\n",
- pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].BTSsid.Octet,
- pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].BTSsid.Length);
-}
-
-static void bthci_ResetBtMgnt(struct bt_mgnt *pBtMgnt)
-{
- pBtMgnt->BtOperationOn = false;
- pBtMgnt->bBTConnectInProgress = false;
- pBtMgnt->bLogLinkInProgress = false;
- pBtMgnt->bPhyLinkInProgress = false;
- pBtMgnt->bPhyLinkInProgressStartLL = false;
- pBtMgnt->DisconnectEntryNum = 0xff;
- pBtMgnt->bStartSendSupervisionPkt = false;
- pBtMgnt->JoinerNeedSendAuth = false;
- pBtMgnt->CurrentBTConnectionCnt = 0;
- pBtMgnt->BTCurrentConnectType = BT_DISCONNECT;
- pBtMgnt->BTReceiveConnectPkt = BT_DISCONNECT;
- pBtMgnt->BTAuthCount = 0;
- pBtMgnt->btLogoTest = 0;
-}
-
-static void bthci_ResetBtHciInfo(struct bt_hci_info *pBtHciInfo)
-{
- pBtHciInfo->BTEventMask = 0;
- pBtHciInfo->BTEventMaskPage2 = 0;
- pBtHciInfo->ConnAcceptTimeout = 10000;
- pBtHciInfo->PageTimeout = 0x30;
- pBtHciInfo->LocationDomainAware = 0x0;
- pBtHciInfo->LocationDomain = 0x5858;
- pBtHciInfo->LocationDomainOptions = 0x58;
- pBtHciInfo->LocationOptions = 0x0;
- pBtHciInfo->FlowControlMode = 0x1; /* 0:Packet based data flow control mode(BR/EDR), 1: Data block based data flow control mode(AMP). */
-
- pBtHciInfo->enFlush_LLH = 0;
- pBtHciInfo->FLTO_LLH = 0;
-
- /* Test command only */
- pBtHciInfo->bTestIsEnd = true;
- pBtHciInfo->bInTestMode = false;
- pBtHciInfo->bTestNeedReport = false;
- pBtHciInfo->TestScenario = 0xff;
- pBtHciInfo->TestReportInterval = 0x01;
- pBtHciInfo->TestCtrType = 0x5d;
- pBtHciInfo->TestEventType = 0x00;
- pBtHciInfo->TestNumOfFrame = 0;
- pBtHciInfo->TestNumOfErrFrame = 0;
- pBtHciInfo->TestNumOfBits = 0;
- pBtHciInfo->TestNumOfErrBits = 0;
-}
-
-static void bthci_ResetBtSec(struct rtw_adapter *padapter, struct bt_security *pBtSec)
-{
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
-
- /* Set BT used HW or SW encrypt !! */
- if (GET_HAL_DATA(padapter)->bBTMode)
- pBtSec->bUsedHwEncrypt = true;
- else
- pBtSec->bUsedHwEncrypt = false;
- RT_TRACE(_module_rtl871x_security_c_, _drv_info_,
- "%s: bUsedHwEncrypt =%d\n", __func__, pBtSec->bUsedHwEncrypt);
-
- pBtSec->RSNIE.Octet = pBtSec->RSNIEBuf;
-}
-
-static void bthci_ResetBtExtInfo(struct bt_mgnt *pBtMgnt)
-{
- u8 i;
-
- for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) {
- pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle = 0;
- pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = 0;
- pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = 0;
- pBtMgnt->ExtConfig.linkInfo[i].BTProfile = BT_PROFILE_NONE;
- pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec = BT_SPEC_2_1_EDR;
- pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI = 0;
- pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile = BT_PROFILE_NONE;
- pBtMgnt->ExtConfig.linkInfo[i].linkRole = BT_LINK_MASTER;
- }
-
- pBtMgnt->ExtConfig.CurrentConnectHandle = 0;
- pBtMgnt->ExtConfig.CurrentIncomingTrafficMode = 0;
- pBtMgnt->ExtConfig.CurrentOutgoingTrafficMode = 0;
- pBtMgnt->ExtConfig.MIN_BT_RSSI = 0;
- pBtMgnt->ExtConfig.NumberOfHandle = 0;
- pBtMgnt->ExtConfig.NumberOfSCO = 0;
- pBtMgnt->ExtConfig.CurrentBTStatus = 0;
- pBtMgnt->ExtConfig.HCIExtensionVer = 0;
-
- pBtMgnt->ExtConfig.bManualControl = false;
- pBtMgnt->ExtConfig.bBTBusy = false;
- pBtMgnt->ExtConfig.bBTA2DPBusy = false;
-}
-
-static enum hci_status bthci_CmdReset(struct rtw_adapter *_padapter, u8 bNeedSendEvent)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct rtw_adapter *padapter;
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTInfo;
- struct bt_mgnt *pBtMgnt;
- struct bt_hci_info *pBtHciInfo;
- struct bt_security *pBtSec;
- struct bt_dgb *pBtDbg;
- u8 i;
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_CmdReset()\n"));
-
- padapter = GetDefaultAdapter(_padapter);
- pBTInfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTInfo->BtMgnt;
- pBtHciInfo = &pBTInfo->BtHciInfo;
- pBtSec = &pBTInfo->BtSec;
- pBtDbg = &pBTInfo->BtDbg;
-
- pBTInfo->padapter = padapter;
-
- for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++)
- bthci_ResetEntry(padapter, i);
-
- bthci_ResetBtMgnt(pBtMgnt);
- bthci_ResetBtHciInfo(pBtHciInfo);
- bthci_ResetBtSec(padapter, pBtSec);
-
- pBtMgnt->BTChannel = BT_Default_Chnl;
- pBtMgnt->CheckChnlIsSuit = true;
-
- pBTInfo->BTBeaconTmrOn = false;
-
- pBtMgnt->bCreateSpportQos = true;
-
- del_timer_sync(&pBTInfo->BTHCIDiscardAclDataTimer);
- del_timer_sync(&pBTInfo->BTBeaconTimer);
-
- HALBT_SetRtsCtsNoLenLimit(padapter);
- /* */
- /* Maybe we need to take care Group != AES case !! */
- /* now we Pairwise and Group all used AES !! */
-
- bthci_ResetBtExtInfo(pBtMgnt);
-
- /* send command complete event here when all data are received. */
- if (bNeedSendEvent) {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_RESET,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdWriteRemoteAMPAssoc(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
- u8 CurrentAssocNum;
- u8 PhyLinkHandle;
-
- pBtDbg->dbgHciInfo.hciCmdCntWriteRemoteAmpAssoc++;
- PhyLinkHandle = *((u8 *)pHciCmd->Data);
- CurrentAssocNum = bthci_GetCurrentEntryNum(padapter, PhyLinkHandle);
-
- if (CurrentAssocNum == 0xff) {
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("WriteRemoteAMPAssoc, No such Handle in the Entry\n"));
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
- bthci_EventWriteRemoteAmpAssoc(padapter, status, PhyLinkHandle);
- return status;
- }
-
- if (pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocfragment == NULL) {
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("WriteRemoteAMPAssoc, AMP controller is busy\n"));
- status = HCI_STATUS_CONTROLLER_BUSY;
- bthci_EventWriteRemoteAmpAssoc(padapter, status, PhyLinkHandle);
- return status;
- }
-
- pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.BtPhyLinkhandle = PhyLinkHandle;/* u8 *)pHciCmd->Data); */
- pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.LenSoFar = *((u16 *)((u8 *)pHciCmd->Data+1));
- pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen = *((u16 *)((u8 *)pHciCmd->Data+3));
-
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("WriteRemoteAMPAssoc, LenSoFar = 0x%x, AssocRemLen = 0x%x\n",
- pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.LenSoFar,
- pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen));
-
- RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO),
- ("WriteRemoteAMPAssoc fragment \n"),
- pHciCmd->Data,
- pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen+5);
- if ((pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen) > MAX_AMP_ASSOC_FRAG_LEN) {
- memcpy(((u8 *)pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocfragment+(pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.LenSoFar*(sizeof(u8)))),
- (u8 *)pHciCmd->Data+5,
- MAX_AMP_ASSOC_FRAG_LEN);
- } else {
- memcpy((u8 *)(pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocfragment)+(pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.LenSoFar*(sizeof(u8))),
- ((u8 *)pHciCmd->Data+5),
- (pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen));
-
- RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), "WriteRemoteAMPAssoc :\n",
- pHciCmd->Data+5, pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen);
-
- if (!bthci_GetAssocInfo(padapter, CurrentAssocNum))
- status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE;
-
- bthci_EventWriteRemoteAmpAssoc(padapter, status, PhyLinkHandle);
-
- bthci_StartBeaconAndConnect(padapter, pHciCmd, CurrentAssocNum);
- }
-
- return status;
-}
-
-/* 7.3.13 */
-static enum hci_status bthci_CmdReadConnectionAcceptTimeout(struct rtw_adapter *padapter)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 localBuf[8] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u16 *pu2Temp;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_READ_CONNECTION_ACCEPT_TIMEOUT,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- pu2Temp = (u16 *)&pRetPar[1]; /* Conn_Accept_Timeout */
- *pu2Temp = pBtHciInfo->ConnAcceptTimeout;
- len += 3;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-/* 7.3.14 */
-static enum hci_status
-bthci_CmdWriteConnectionAcceptTimeout(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u16 *pu2Temp;
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- pu2Temp = (u16 *)&pHciCmd->Data[0];
- pBtHciInfo->ConnAcceptTimeout = *pu2Temp;
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("ConnAcceptTimeout = 0x%x",
- pBtHciInfo->ConnAcceptTimeout));
-
- /* send command complete event here when all data are received. */
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdReadPageTimeout(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 localBuf[8] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u16 *pu2Temp;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_READ_PAGE_TIMEOUT,
- status);
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Read PageTimeout = 0x%x\n", pBtHciInfo->PageTimeout));
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- pu2Temp = (u16 *)&pRetPar[1]; /* Page_Timeout */
- *pu2Temp = pBtHciInfo->PageTimeout;
- len += 3;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdWritePageTimeout(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u16 *pu2Temp;
-
- pu2Temp = (u16 *)&pHciCmd->Data[0];
- pBtHciInfo->PageTimeout = *pu2Temp;
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Write PageTimeout = 0x%x\n",
- pBtHciInfo->PageTimeout));
-
- /* send command complete event here when all data are received. */
- {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_WRITE_PAGE_TIMEOUT,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdReadLinkSupervisionTimeout(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
- u8 physicalLinkHandle, EntryNum;
-
- physicalLinkHandle = *((u8 *)pHciCmd->Data);
-
- EntryNum = bthci_GetCurrentEntryNum(padapter, physicalLinkHandle);
-
- if (EntryNum == 0xff) {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLinkSupervisionTimeout, No such Handle in the Entry\n"));
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
- return status;
- }
-
- if (pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle != physicalLinkHandle)
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
-
- {
- u8 localBuf[10] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u16 *pu2Temp;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_READ_LINK_SUPERVISION_TIMEOUT,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status;
- pRetPar[1] = pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle;
- pRetPar[2] = 0;
- pu2Temp = (u16 *)&pRetPar[3]; /* Conn_Accept_Timeout */
- *pu2Temp = pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.LinkSuperversionTimeout;
- len += 5;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdWriteLinkSupervisionTimeout(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
- u8 physicalLinkHandle, EntryNum;
-
- physicalLinkHandle = *((u8 *)pHciCmd->Data);
-
- EntryNum = bthci_GetCurrentEntryNum(padapter, physicalLinkHandle);
-
- if (EntryNum == 0xff) {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("WriteLinkSupervisionTimeout, No such Handle in the Entry\n"));
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
- } else {
- if (pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle != physicalLinkHandle) {
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
- } else {
- pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.LinkSuperversionTimeout = *((u16 *)(((u8 *)pHciCmd->Data)+2));
- RTPRINT(FIOCTL, IOCTL_STATE, ("BT Write LinkSuperversionTimeout[%d] = 0x%x\n",
- EntryNum, pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.LinkSuperversionTimeout));
- }
- }
-
- {
- u8 localBuf[8] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_WRITE_LINK_SUPERVISION_TIMEOUT,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status;
- pRetPar[1] = pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle;
- pRetPar[2] = 0;
- len += 3;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdEnhancedFlush(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTinfo->BtHciInfo;
- u16 logicHandle;
- u8 Packet_Type;
-
- logicHandle = *((u16 *)&pHciCmd->Data[0]);
- Packet_Type = pHciCmd->Data[2];
-
- if (Packet_Type != 0)
- status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE;
- else
- pBtHciInfo->enFlush_LLH = logicHandle;
-
- if (bthci_DiscardTxPackets(padapter, pBtHciInfo->enFlush_LLH))
- bthci_EventFlushOccurred(padapter, pBtHciInfo->enFlush_LLH);
-
- /* should send command status event */
- bthci_EventCommandStatus(padapter,
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_ENHANCED_FLUSH,
- status);
-
- if (pBtHciInfo->enFlush_LLH) {
- bthci_EventEnhancedFlushComplete(padapter, pBtHciInfo->enFlush_LLH);
- pBtHciInfo->enFlush_LLH = 0;
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdReadLogicalLinkAcceptTimeout(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 localBuf[8] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u16 *pu2Temp;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status;
-
- pu2Temp = (u16 *)&pRetPar[1]; /* Conn_Accept_Timeout */
- *pu2Temp = pBtHciInfo->LogicalAcceptTimeout;
- len += 3;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdWriteLogicalLinkAcceptTimeout(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- pBtHciInfo->LogicalAcceptTimeout = *((u16 *)pHciCmd->Data);
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status;
-
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- return status;
-}
-
-static enum hci_status
-bthci_CmdSetEventMask(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 *pu8Temp;
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- pu8Temp = (u8 *)&pHciCmd->Data[0];
- pBtHciInfo->BTEventMask = *pu8Temp;
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("BTEventMask = 0x%"i64fmt"x\n",
- pBtHciInfo->BTEventMask));
-
- /* send command complete event here when all data are received. */
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_SET_EVENT_MASK,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-/* 7.3.69 */
-static enum hci_status
-bthci_CmdSetEventMaskPage2(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 *pu8Temp;
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- pu8Temp = (u8 *)&pHciCmd->Data[0];
- pBtHciInfo->BTEventMaskPage2 = *pu8Temp;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("BTEventMaskPage2 = 0x%"i64fmt"x\n",
- pBtHciInfo->BTEventMaskPage2));
-
- /* send command complete event here when all data are received. */
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_SET_EVENT_MASK_PAGE_2,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdReadLocationData(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 localBuf[12] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u16 *pu2Temp;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_READ_LOCATION_DATA,
- status);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DomainAware = 0x%x\n", pBtHciInfo->LocationDomainAware));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Domain = 0x%x\n", pBtHciInfo->LocationDomain));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DomainOptions = 0x%x\n", pBtHciInfo->LocationDomainOptions));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Options = 0x%x\n", pBtHciInfo->LocationOptions));
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status;
-
- pRetPar[1] = pBtHciInfo->LocationDomainAware; /* 0x0; Location_Domain_Aware */
- pu2Temp = (u16 *)&pRetPar[2]; /* Location_Domain */
- *pu2Temp = pBtHciInfo->LocationDomain; /* 0x5858; */
- pRetPar[4] = pBtHciInfo->LocationDomainOptions; /* 0x58; Location_Domain_Options */
- pRetPar[5] = pBtHciInfo->LocationOptions; /* 0x0; Location_Options */
- len += 6;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- return status;
-}
-
-static enum hci_status
-bthci_CmdWriteLocationData(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u16 *pu2Temp;
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- pBtHciInfo->LocationDomainAware = pHciCmd->Data[0];
- pu2Temp = (u16 *)&pHciCmd->Data[1];
- pBtHciInfo->LocationDomain = *pu2Temp;
- pBtHciInfo->LocationDomainOptions = pHciCmd->Data[3];
- pBtHciInfo->LocationOptions = pHciCmd->Data[4];
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DomainAware = 0x%x\n", pBtHciInfo->LocationDomainAware));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Domain = 0x%x\n", pBtHciInfo->LocationDomain));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DomainOptions = 0x%x\n", pBtHciInfo->LocationDomainOptions));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Options = 0x%x\n", pBtHciInfo->LocationOptions));
-
- /* send command complete event here when all data are received. */
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_WRITE_LOCATION_DATA,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdReadFlowControlMode(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 localBuf[7] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_READ_FLOW_CONTROL_MODE,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status;
- pRetPar[1] = pBtHciInfo->FlowControlMode; /* Flow Control Mode */
- len += 2;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- return status;
-}
-
-static enum hci_status
-bthci_CmdWriteFlowControlMode(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- pBtHciInfo->FlowControlMode = pHciCmd->Data[0];
-
- /* send command complete event here when all data are received. */
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_WRITE_FLOW_CONTROL_MODE,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdReadBestEffortFlushTimeout(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
- u16 i, j, logicHandle;
- u32 BestEffortFlushTimeout = 0xffffffff;
- u8 find = 0;
-
- logicHandle = *((u16 *)pHciCmd->Data);
- /* find an matched logical link index and copy the data */
- for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) {
- for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
- if (pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle == logicHandle) {
- BestEffortFlushTimeout = pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BestEffortFlushTimeout;
- find = 1;
- break;
- }
- }
- }
-
- if (!find)
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
-
- {
- u8 localBuf[10] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u32 *pu4Temp;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status;
- pu4Temp = (u32 *)&pRetPar[1]; /* Best_Effort_Flush_Timeout */
- *pu4Temp = BestEffortFlushTimeout;
- len += 5;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
- return status;
-}
-
-static enum hci_status
-bthci_CmdWriteBestEffortFlushTimeout(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
- u16 i, j, logicHandle;
- u32 BestEffortFlushTimeout = 0xffffffff;
- u8 find = 0;
-
- logicHandle = *((u16 *)pHciCmd->Data);
- BestEffortFlushTimeout = *((u32 *)(pHciCmd->Data+1));
-
- /* find an matched logical link index and copy the data */
- for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) {
- for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
- if (pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle == logicHandle) {
- pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BestEffortFlushTimeout = BestEffortFlushTimeout;
- find = 1;
- break;
- }
- }
- }
-
- if (!find)
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
-
- {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status;
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
- return status;
-}
-
-static enum hci_status
-bthci_CmdShortRangeMode(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- u8 PhyLinkHandle, EntryNum, ShortRangeMode;
-
- PhyLinkHandle = pHciCmd->Data[0];
- ShortRangeMode = pHciCmd->Data[1];
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("PLH = 0x%x, Short_Range_Mode = 0x%x\n", PhyLinkHandle, ShortRangeMode));
-
- EntryNum = bthci_GetCurrentEntryNum(padapter, PhyLinkHandle);
- if (EntryNum != 0xff) {
- pBTInfo->BtAsocEntry[EntryNum].ShortRangeMode = ShortRangeMode;
- } else {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("No such PLH(0x%x)\n", PhyLinkHandle));
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
- }
-
- bthci_EventCommandStatus(padapter,
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_SHORT_RANGE_MODE,
- status);
-
- bthci_EventShortRangeModeChangeComplete(padapter, status, ShortRangeMode, EntryNum);
-
- return status;
-}
-
-static enum hci_status bthci_CmdReadLocalSupportedCommands(struct rtw_adapter *padapter)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- u8 localBuf[TmpLocalBufSize] = "";
- u8 *pRetPar, *pSupportedCmds;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- /* send command complete event here when all data are received. */
- PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_INFORMATIONAL_PARAMETERS,
- HCI_READ_LOCAL_SUPPORTED_COMMANDS,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 1;
- pSupportedCmds = &pRetPar[1];
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[5]= 0xc0\nBit [6]= Set Event Mask, [7]= Reset\n"));
- pSupportedCmds[5] = 0xc0;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[6]= 0x01\nBit [0]= Set Event Filter\n"));
- pSupportedCmds[6] = 0x01;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[7]= 0x0c\nBit [2]= Read Connection Accept Timeout, [3]= Write Connection Accept Timeout\n"));
- pSupportedCmds[7] = 0x0c;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[10]= 0x80\nBit [7]= Host Number Of Completed Packets\n"));
- pSupportedCmds[10] = 0x80;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[11]= 0x03\nBit [0]= Read Link Supervision Timeout, [1]= Write Link Supervision Timeout\n"));
- pSupportedCmds[11] = 0x03;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[14]= 0xa8\nBit [3]= Read Local Version Information, [5]= Read Local Supported Features, [7]= Read Buffer Size\n"));
- pSupportedCmds[14] = 0xa8;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[15]= 0x1c\nBit [2]= Read Failed Contact Count, [3]= Reset Failed Contact Count, [4]= Get Link Quality\n"));
- pSupportedCmds[15] = 0x1c;
- /* pSupportedCmds[16] = 0x04; */
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[19]= 0x40\nBit [6]= Enhanced Flush\n"));
- pSupportedCmds[19] = 0x40;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[21]= 0xff\nBit [0]= Create Physical Link, [1]= Accept Physical Link, [2]= Disconnect Physical Link, [3]= Create Logical Link\n"));
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), (" [4]= Accept Logical Link, [5]= Disconnect Logical Link, [6]= Logical Link Cancel, [7]= Flow Spec Modify\n"));
- pSupportedCmds[21] = 0xff;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[22]= 0xff\nBit [0]= Read Logical Link Accept Timeout, [1]= Write Logical Link Accept Timeout, [2]= Set Event Mask Page 2, [3]= Read Location Data\n"));
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), (" [4]= Write Location Data, [5]= Read Local AMP Info, [6]= Read Local AMP_ASSOC, [7]= Write Remote AMP_ASSOC\n"));
- pSupportedCmds[22] = 0xff;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[23]= 0x07\nBit [0]= Read Flow Control Mode, [1]= Write Flow Control Mode, [2]= Read Data Block Size\n"));
- pSupportedCmds[23] = 0x07;
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[24]= 0x1c\nBit [2]= Read Best Effort Flush Timeout, [3]= Write Best Effort Flush Timeout, [4]= Short Range Mode\n"));
- pSupportedCmds[24] = 0x1c;
- len += 64;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-static enum hci_status bthci_CmdReadLocalSupportedFeatures(struct rtw_adapter *padapter)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- u8 localBuf[TmpLocalBufSize] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- /* send command complete event here when all data are received. */
- PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_INFORMATIONAL_PARAMETERS,
- HCI_READ_LOCAL_SUPPORTED_FEATURES,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 9;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- return status;
-}
-
-static enum hci_status bthci_CmdReadLocalAMPAssoc(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
- u8 PhyLinkHandle, EntryNum;
-
- pBtDbg->dbgHciInfo.hciCmdCntReadLocalAmpAssoc++;
- PhyLinkHandle = *((u8 *)pHciCmd->Data);
- EntryNum = bthci_GetCurrentEntryNum(padapter, PhyLinkHandle);
-
- if ((EntryNum == 0xff) && PhyLinkHandle != 0) {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLocalAMPAssoc, EntryNum = %d !!!!!, physical link handle = 0x%x\n",
- EntryNum, PhyLinkHandle));
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
- } else if (pBtMgnt->bPhyLinkInProgressStartLL) {
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
- pBtMgnt->bPhyLinkInProgressStartLL = false;
- } else {
- pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.BtPhyLinkhandle = *((u8 *)pHciCmd->Data);
- pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar = *((u16 *)((u8 *)pHciCmd->Data+1));
- pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.MaxRemoteASSOCLen = *((u16 *)((u8 *)pHciCmd->Data+3));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("ReadLocalAMPAssoc, LenSoFar =%d, MaxRemoteASSOCLen =%d\n",
- pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar,
- pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.MaxRemoteASSOCLen));
- }
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLocalAMPAssoc, EntryNum = %d !!!!!, physical link handle = 0x%x, LengthSoFar = %x \n",
- EntryNum, PhyLinkHandle, pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar));
-
- /* send command complete event here when all data are received. */
- {
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- /* PVOID buffer = padapter->IrpHCILocalbuf.Ptr; */
- u8 localBuf[TmpLocalBufSize] = "";
- u16 *pRemainLen;
- u32 totalLen = 0;
- u16 typeLen = 0, remainLen = 0, ret_index = 0;
- u8 *pRetPar;
-
- PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
- /* PPacketIrpEvent = (struct packet_irp_hcievent_data *)(buffer); */
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- totalLen += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_STATUS_PARAMETERS,
- HCI_READ_LOCAL_AMP_ASSOC,
- status);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLocalAMPAssoc, Remaining_Len =%d \n", remainLen));
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[totalLen];
- pRetPar[0] = status; /* status */
- pRetPar[1] = *((u8 *)pHciCmd->Data);
- pRemainLen = (u16 *)&pRetPar[2]; /* AMP_ASSOC_Remaining_Length */
- totalLen += 4; /* 0]~[3] */
- ret_index = 4;
-
- typeLen = bthci_AssocMACAddr(padapter, &pRetPar[ret_index]);
- totalLen += typeLen;
- remainLen += typeLen;
- ret_index += typeLen;
- typeLen = bthci_AssocPreferredChannelList(padapter, &pRetPar[ret_index], EntryNum);
- totalLen += typeLen;
- remainLen += typeLen;
- ret_index += typeLen;
- typeLen = bthci_PALCapabilities(padapter, &pRetPar[ret_index]);
- totalLen += typeLen;
- remainLen += typeLen;
- ret_index += typeLen;
- typeLen = bthci_AssocPALVer(padapter, &pRetPar[ret_index]);
- totalLen += typeLen;
- remainLen += typeLen;
- PPacketIrpEvent->Length = (u8)totalLen;
- *pRemainLen = remainLen; /* AMP_ASSOC_Remaining_Length */
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLocalAMPAssoc, Remaining_Len =%d \n", remainLen));
- RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("AMP_ASSOC_fragment : \n"), PPacketIrpEvent->Data, totalLen);
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, totalLen+2);
- }
-
- return status;
-}
-
-static enum hci_status bthci_CmdReadFailedContactCounter(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
-
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 localBuf[TmpLocalBufSize] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u16 handle;
-
- handle = *((u16 *)pHciCmd->Data);
- /* send command complete event here when all data are received. */
- PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_STATUS_PARAMETERS,
- HCI_READ_FAILED_CONTACT_COUNTER,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- pRetPar[1] = TWOBYTE_LOWBYTE(handle);
- pRetPar[2] = TWOBYTE_HIGHTBYTE(handle);
- pRetPar[3] = TWOBYTE_LOWBYTE(pBtHciInfo->FailContactCount);
- pRetPar[4] = TWOBYTE_HIGHTBYTE(pBtHciInfo->FailContactCount);
- len += 5;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdResetFailedContactCounter(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u16 handle;
- u8 localBuf[TmpLocalBufSize] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- handle = *((u16 *)pHciCmd->Data);
- pBtHciInfo->FailContactCount = 0;
-
- /* send command complete event here when all data are received. */
- PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
- /* PPacketIrpEvent = (struct packet_irp_hcievent_data *)(buffer); */
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_STATUS_PARAMETERS,
- HCI_RESET_FAILED_CONTACT_COUNTER,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- pRetPar[1] = TWOBYTE_LOWBYTE(handle);
- pRetPar[2] = TWOBYTE_HIGHTBYTE(handle);
- len += 3;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- return status;
-}
-
-/* */
-/* BT 3.0+HS [Vol 2] 7.4.1 */
-/* */
-static enum hci_status
-bthci_CmdReadLocalVersionInformation(
- struct rtw_adapter *padapter
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- /* send command complete event here when all data are received. */
- u8 localBuf[TmpLocalBufSize] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u16 *pu2Temp;
-
- PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_INFORMATIONAL_PARAMETERS,
- HCI_READ_LOCAL_VERSION_INFORMATION,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- pRetPar[1] = 0x05; /* HCI_Version */
- pu2Temp = (u16 *)&pRetPar[2]; /* HCI_Revision */
- *pu2Temp = 0x0001;
- pRetPar[4] = 0x05; /* LMP/PAL_Version */
- pu2Temp = (u16 *)&pRetPar[5]; /* Manufacturer_Name */
- *pu2Temp = 0x005d;
- pu2Temp = (u16 *)&pRetPar[7]; /* LMP/PAL_Subversion */
- *pu2Temp = 0x0001;
- len += 9;
- PPacketIrpEvent->Length = len;
-
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("LOCAL_VERSION_INFORMATION\n"));
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("Status %x\n", status));
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("HCI_Version = 0x05\n"));
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("HCI_Revision = 0x0001\n"));
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("LMP/PAL_Version = 0x05\n"));
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("Manufacturer_Name = 0x0001\n"));
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("LMP/PAL_Subversion = 0x0001\n"));
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-/* 7.4.7 */
-static enum hci_status bthci_CmdReadDataBlockSize(struct rtw_adapter *padapter)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- u8 localBuf[TmpLocalBufSize] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u16 *pu2Temp;
-
- PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_INFORMATIONAL_PARAMETERS,
- HCI_READ_DATA_BLOCK_SIZE,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = HCI_STATUS_SUCCESS; /* status */
- pu2Temp = (u16 *)&pRetPar[1]; /* Max_ACL_Data_Packet_Length */
- *pu2Temp = Max80211PALPDUSize;
-
- pu2Temp = (u16 *)&pRetPar[3]; /* Data_Block_Length */
- *pu2Temp = Max80211PALPDUSize;
- pu2Temp = (u16 *)&pRetPar[5]; /* Total_Num_Data_Blocks */
- *pu2Temp = BTTotalDataBlockNum;
- len += 7;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-/* 7.4.5 */
-static enum hci_status bthci_CmdReadBufferSize(struct rtw_adapter *padapter)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- u8 localBuf[TmpLocalBufSize] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u16 *pu2Temp;
-
- PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
- /* PPacketIrpEvent = (struct packet_irp_hcievent_data *)(buffer); */
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_INFORMATIONAL_PARAMETERS,
- HCI_READ_BUFFER_SIZE,
- status);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Synchronous_Data_Packet_Length = 0x%x\n", BTSynDataPacketLength));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Total_Num_ACL_Data_Packets = 0x%x\n", BTTotalDataBlockNum));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Total_Num_Synchronous_Data_Packets = 0x%x\n", BTTotalDataBlockNum));
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- pu2Temp = (u16 *)&pRetPar[1]; /* HC_ACL_Data_Packet_Length */
- *pu2Temp = Max80211PALPDUSize;
-
- pRetPar[3] = BTSynDataPacketLength; /* HC_Synchronous_Data_Packet_Length */
- pu2Temp = (u16 *)&pRetPar[4]; /* HC_Total_Num_ACL_Data_Packets */
- *pu2Temp = BTTotalDataBlockNum;
- pu2Temp = (u16 *)&pRetPar[6]; /* HC_Total_Num_Synchronous_Data_Packets */
- *pu2Temp = BTTotalDataBlockNum;
- len += 8;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-static enum hci_status bthci_CmdReadLocalAMPInfo(struct rtw_adapter *padapter)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct pwrctrl_priv *ppwrctrl = &padapter->pwrctrlpriv;
- u8 localBuf[TmpLocalBufSize] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u16 *pu2Temp;
- u32 *pu4Temp;
- u32 TotalBandwidth = BTTOTALBANDWIDTH, MaxBandGUBandwidth = BTMAXBANDGUBANDWIDTH;
- u8 ControlType = 0x01, AmpStatus = 0x01;
- u32 MaxFlushTimeout = 10000, BestEffortFlushTimeout = 5000;
- u16 MaxPDUSize = Max80211PALPDUSize, PalCap = 0x1, AmpAssocLen = Max80211AMPASSOCLen, MinLatency = 20;
-
- if ((ppwrctrl->rfoff_reason & RF_CHANGE_BY_HW) ||
- (ppwrctrl->rfoff_reason & RF_CHANGE_BY_SW)) {
- AmpStatus = AMP_STATUS_NO_CAPACITY_FOR_BT;
- }
-
- PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
- /* PPacketIrpEvent = (struct packet_irp_hcievent_data *)(buffer); */
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_STATUS_PARAMETERS,
- HCI_READ_LOCAL_AMP_INFO,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- pRetPar[1] = AmpStatus; /* AMP_Status */
- pu4Temp = (u32 *)&pRetPar[2]; /* Total_Bandwidth */
- *pu4Temp = TotalBandwidth; /* 0x19bfcc00;0x7530; */
- pu4Temp = (u32 *)&pRetPar[6]; /* Max_Guaranteed_Bandwidth */
- *pu4Temp = MaxBandGUBandwidth; /* 0x19bfcc00;0x4e20; */
- pu4Temp = (u32 *)&pRetPar[10]; /* Min_Latency */
- *pu4Temp = MinLatency; /* 150; */
- pu4Temp = (u32 *)&pRetPar[14]; /* Max_PDU_Size */
- *pu4Temp = MaxPDUSize;
- pRetPar[18] = ControlType; /* Controller_Type */
- pu2Temp = (u16 *)&pRetPar[19]; /* PAL_Capabilities */
- *pu2Temp = PalCap;
- pu2Temp = (u16 *)&pRetPar[21]; /* AMP_ASSOC_Length */
- *pu2Temp = AmpAssocLen;
- pu4Temp = (u32 *)&pRetPar[23]; /* Max_Flush_Timeout */
- *pu4Temp = MaxFlushTimeout;
- pu4Temp = (u32 *)&pRetPar[27]; /* Best_Effort_Flush_Timeout */
- *pu4Temp = BestEffortFlushTimeout;
- len += 31;
- PPacketIrpEvent->Length = len;
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("AmpStatus = 0x%x\n",
- AmpStatus));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("TotalBandwidth = 0x%x, MaxBandGUBandwidth = 0x%x, MinLatency = 0x%x, \n MaxPDUSize = 0x%x, ControlType = 0x%x\n",
- TotalBandwidth, MaxBandGUBandwidth, MinLatency, MaxPDUSize, ControlType));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("PalCap = 0x%x, AmpAssocLen = 0x%x, MaxFlushTimeout = 0x%x, BestEffortFlushTimeout = 0x%x\n",
- PalCap, AmpAssocLen, MaxFlushTimeout, BestEffortFlushTimeout));
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- return status;
-}
-
-static enum hci_status
-bthci_CmdCreatePhysicalLink(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
-
- pBtDbg->dbgHciInfo.hciCmdCntCreatePhyLink++;
-
- return bthci_BuildPhysicalLink(padapter,
- pHciCmd, HCI_CREATE_PHYSICAL_LINK);
-}
-
-static enum hci_status
-bthci_CmdReadLinkQuality(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- u16 PLH;
- u8 EntryNum, LinkQuality = 0x55;
-
- PLH = *((u16 *)&pHciCmd->Data[0]);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("PLH = 0x%x\n", PLH));
-
- EntryNum = bthci_GetCurrentEntryNum(padapter, (u8)PLH);
- if (EntryNum == 0xff) {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("No such PLH(0x%x)\n", PLH));
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
- }
-
- {
- u8 localBuf[11] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_STATUS_PARAMETERS,
- HCI_READ_LINK_QUALITY,
- status);
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, (" PLH = 0x%x\n Link Quality = 0x%x\n", PLH, LinkQuality));
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- *((u16 *)&pRetPar[1]) = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle; /* Handle */
- pRetPar[3] = 0x55; /* Link Quailty */
- len += 4;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdCreateLogicalLink(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
-
- pBtDbg->dbgHciInfo.hciCmdCntCreateLogLink++;
-
- bthci_BuildLogicalLink(padapter, pHciCmd,
- HCI_CREATE_LOGICAL_LINK);
-
- return HCI_STATUS_SUCCESS;
-}
-
-static enum hci_status
-bthci_CmdAcceptLogicalLink(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
-
- pBtDbg->dbgHciInfo.hciCmdCntAcceptLogLink++;
-
- bthci_BuildLogicalLink(padapter, pHciCmd,
- HCI_ACCEPT_LOGICAL_LINK);
-
- return HCI_STATUS_SUCCESS;
-}
-
-static enum hci_status
-bthci_CmdDisconnectLogicalLink(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTinfo->BtMgnt;
- struct bt_dgb *pBtDbg = &pBTinfo->BtDbg;
- u16 logicHandle;
- u8 i, j, find = 0, LogLinkCount = 0;
-
- pBtDbg->dbgHciInfo.hciCmdCntDisconnectLogLink++;
-
- logicHandle = *((u16 *)pHciCmd->Data);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DisconnectLogicalLink, logicHandle = 0x%x\n", logicHandle));
-
- /* find an created logical link index and clear the data */
- for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) {
- for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
- if (pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle == logicHandle) {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DisconnectLogicalLink, logicHandle is matched 0x%x\n", logicHandle));
- bthci_ResetFlowSpec(padapter, j, i);
- find = 1;
- pBtMgnt->DisconnectEntryNum = j;
- break;
- }
- }
- }
-
- if (!find)
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
-
- /* To check each */
- for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
- if (pBTinfo->BtAsocEntry[pBtMgnt->DisconnectEntryNum].LogLinkCmdData[i].BtLogLinkhandle != 0)
- LogLinkCount++;
- }
-
- /* When we receive Create logical link command, we should send command status event first. */
- bthci_EventCommandStatus(padapter,
- LINK_CONTROL_COMMANDS,
- HCI_DISCONNECT_LOGICAL_LINK,
- status);
- /* */
- /* When we determines the logical link is established, we should send command complete event. */
- /* */
- if (status == HCI_STATUS_SUCCESS) {
- bthci_EventDisconnectLogicalLinkComplete(padapter, status,
- logicHandle, HCI_STATUS_CONNECT_TERMINATE_LOCAL_HOST);
- }
-
- if (LogLinkCount == 0)
- mod_timer(&pBTinfo->BTDisconnectPhyLinkTimer,
- jiffies + msecs_to_jiffies(100));
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdLogicalLinkCancel(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTinfo->BtMgnt;
- u8 CurrentEntryNum, CurrentLogEntryNum;
-
- u8 physicalLinkHandle, TxFlowSpecID, i;
- u16 CurrentLogicalHandle;
-
- physicalLinkHandle = *((u8 *)pHciCmd->Data);
- TxFlowSpecID = *(((u8 *)pHciCmd->Data)+1);
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("LogicalLinkCancel, physicalLinkHandle = 0x%x, TxFlowSpecID = 0x%x\n",
- physicalLinkHandle, TxFlowSpecID));
-
- CurrentEntryNum = pBtMgnt->CurrentConnectEntryNum;
- CurrentLogicalHandle = pBtMgnt->BtCurrentLogLinkhandle;
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("CurrentEntryNum = 0x%x, CurrentLogicalHandle = 0x%x\n",
- CurrentEntryNum, CurrentLogicalHandle));
-
- CurrentLogEntryNum = 0xff;
- for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
- if ((CurrentLogicalHandle == pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[i].BtLogLinkhandle) &&
- (physicalLinkHandle == pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[i].BtPhyLinkhandle)) {
- CurrentLogEntryNum = i;
- break;
- }
- }
-
- if (CurrentLogEntryNum == 0xff) {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("LogicalLinkCancel, CurrentLogEntryNum == 0xff !!!!\n"));
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
- return status;
- } else {
- if (pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[CurrentLogEntryNum].bLLCompleteEventIsSet) {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("LogicalLinkCancel, LLCompleteEventIsSet!!!!\n"));
- status = HCI_STATUS_ACL_CONNECT_EXISTS;
- }
- }
-
- {
- u8 localBuf[8] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- LINK_CONTROL_COMMANDS,
- HCI_LOGICAL_LINK_CANCEL,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- pRetPar[1] = pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[CurrentLogEntryNum].BtPhyLinkhandle;
- pRetPar[2] = pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[CurrentLogEntryNum].BtTxFlowSpecID;
- len += 3;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[CurrentLogEntryNum].bLLCancelCMDIsSetandComplete = true;
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdFlowSpecModify(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
- u8 i, j, find = 0;
- u16 logicHandle;
-
- logicHandle = *((u16 *)pHciCmd->Data);
- /* find an matched logical link index and copy the data */
- for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) {
- for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
- if (pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle == logicHandle) {
- memcpy(&pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].Tx_Flow_Spec,
- &pHciCmd->Data[2], sizeof(struct hci_flow_spec));
- memcpy(&pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].Rx_Flow_Spec,
- &pHciCmd->Data[18], sizeof(struct hci_flow_spec));
-
- bthci_CheckLogLinkBehavior(padapter, pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].Tx_Flow_Spec);
- find = 1;
- break;
- }
- }
- }
- RTPRINT(FIOCTL, IOCTL_BT_LOGO, ("FlowSpecModify, LLH = 0x%x, \n", logicHandle));
-
- /* When we receive Flow Spec Modify command, we should send command status event first. */
- bthci_EventCommandStatus(padapter,
- LINK_CONTROL_COMMANDS,
- HCI_FLOW_SPEC_MODIFY,
- HCI_STATUS_SUCCESS);
-
- if (!find)
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
-
- bthci_EventSendFlowSpecModifyComplete(padapter, status, logicHandle);
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdAcceptPhysicalLink(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
-
- pBtDbg->dbgHciInfo.hciCmdCntAcceptPhyLink++;
-
- return bthci_BuildPhysicalLink(padapter,
- pHciCmd, HCI_ACCEPT_PHYSICAL_LINK);
-}
-
-static enum hci_status
-bthci_CmdDisconnectPhysicalLink(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
- u8 PLH, CurrentEntryNum, PhysLinkDisconnectReason;
-
- pBtDbg->dbgHciInfo.hciCmdCntDisconnectPhyLink++;
-
- PLH = *((u8 *)pHciCmd->Data);
- PhysLinkDisconnectReason = *((u8 *)pHciCmd->Data+1);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_DISCONNECT_PHYSICAL_LINK PhyHandle = 0x%x, Reason = 0x%x\n",
- PLH, PhysLinkDisconnectReason));
-
- CurrentEntryNum = bthci_GetCurrentEntryNum(padapter, PLH);
-
- if (CurrentEntryNum == 0xff) {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD,
- ("DisconnectPhysicalLink, No such Handle in the Entry\n"));
- status = HCI_STATUS_UNKNOW_CONNECT_ID;
- } else {
- pBTInfo->BtAsocEntry[CurrentEntryNum].PhyLinkDisconnectReason =
- (enum hci_status)PhysLinkDisconnectReason;
- }
- /* Send HCI Command status event to AMP. */
- bthci_EventCommandStatus(padapter, LINK_CONTROL_COMMANDS,
- HCI_DISCONNECT_PHYSICAL_LINK, status);
-
- if (status != HCI_STATUS_SUCCESS)
- return status;
-
- /* The macros below require { and } in the if statement */
- if (pBTInfo->BtAsocEntry[CurrentEntryNum].BtCurrentState == HCI_STATE_DISCONNECTED) {
- BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_DISCONNECT_PHY_LINK, CurrentEntryNum);
- } else {
- BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTING, STATE_CMD_DISCONNECT_PHY_LINK, CurrentEntryNum);
- }
- return status;
-}
-
-static enum hci_status
-bthci_CmdSetACLLinkDataFlowMode(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- u8 localBuf[8] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u16 *pu2Temp;
-
- pBtMgnt->ExtConfig.CurrentConnectHandle = *((u16 *)pHciCmd->Data);
- pBtMgnt->ExtConfig.CurrentIncomingTrafficMode = *((u8 *)pHciCmd->Data)+2;
- pBtMgnt->ExtConfig.CurrentOutgoingTrafficMode = *((u8 *)pHciCmd->Data)+3;
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("Connection Handle = 0x%x, Incoming Traffic mode = 0x%x, Outgoing Traffic mode = 0x%x",
- pBtMgnt->ExtConfig.CurrentConnectHandle,
- pBtMgnt->ExtConfig.CurrentIncomingTrafficMode,
- pBtMgnt->ExtConfig.CurrentOutgoingTrafficMode));
-
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_EXTENSION,
- HCI_SET_ACL_LINK_DATA_FLOW_MODE,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
-
- pu2Temp = (u16 *)&pRetPar[1];
- *pu2Temp = pBtMgnt->ExtConfig.CurrentConnectHandle;
- len += 3;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- return status;
-}
-
-static enum hci_status
-bthci_CmdSetACLLinkStatus(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
- u8 i;
- u8 *pTriple;
-
- pBtDbg->dbgHciInfo.hciCmdCntSetAclLinkStatus++;
- RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "SetACLLinkStatus, Hex Data :\n",
- &pHciCmd->Data[0], pHciCmd->Length);
-
- /* Only Core Stack v251 and later version support this command. */
- pBtMgnt->bSupportProfile = true;
-
- pBtMgnt->ExtConfig.NumberOfHandle = *((u8 *)pHciCmd->Data);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("NumberOfHandle = 0x%x\n", pBtMgnt->ExtConfig.NumberOfHandle));
-
- pTriple = &pHciCmd->Data[1];
- for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) {
- pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle = *((u16 *)&pTriple[0]);
- pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = pTriple[2];
- pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = pTriple[3];
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT,
- ("Connection_Handle = 0x%x, Incoming Traffic mode = 0x%x, Outgoing Traffic Mode = 0x%x\n",
- pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle,
- pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode,
- pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode));
- pTriple += 4;
- }
-
- {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_EXTENSION,
- HCI_SET_ACL_LINK_STATUS,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
-
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdSetSCOLinkStatus(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
-
- pBtDbg->dbgHciInfo.hciCmdCntSetScoLinkStatus++;
- pBtMgnt->ExtConfig.NumberOfSCO = *((u8 *)pHciCmd->Data);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("NumberOfSCO = 0x%x\n",
- pBtMgnt->ExtConfig.NumberOfSCO));
-
- {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_EXTENSION,
- HCI_SET_SCO_LINK_STATUS,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
-
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdSetRSSIValue(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- s8 min_bt_rssi = 0;
- u8 i;
- for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) {
- if (pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle == *((u16 *)&pHciCmd->Data[0])) {
- pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI = (s8)(pHciCmd->Data[2]);
- RTPRINT(FIOCTL, IOCTL_BT_EVENT_PERIODICAL,
- ("Connection_Handle = 0x%x, RSSI = %d \n",
- pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle,
- pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI));
- }
- /* get the minimum bt rssi value */
- if (pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI <= min_bt_rssi)
- min_bt_rssi = pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI;
- }
-
- pBtMgnt->ExtConfig.MIN_BT_RSSI = min_bt_rssi;
- RTPRINT(FBT, BT_TRACE, ("[bt rssi], the min rssi is %d\n", min_bt_rssi));
-
- {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_EXTENSION,
- HCI_SET_RSSI_VALUE,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
-
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdSetCurrentBluetoothStatus(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- pBtMgnt->ExtConfig.CurrentBTStatus = *((u8 *)&pHciCmd->Data[0]);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("SetCurrentBluetoothStatus, CurrentBTStatus = 0x%x\n",
- pBtMgnt->ExtConfig.CurrentBTStatus));
-
- {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_EXTENSION,
- HCI_SET_CURRENT_BLUETOOTH_STATUS,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 1;
-
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdExtensionVersionNotify(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
-
- pBtDbg->dbgHciInfo.hciCmdCntExtensionVersionNotify++;
- RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "ExtensionVersionNotify, Hex Data :\n",
- &pHciCmd->Data[0], pHciCmd->Length);
-
- pBtMgnt->ExtConfig.HCIExtensionVer = *((u16 *)&pHciCmd->Data[0]);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCIExtensionVer = 0x%x\n", pBtMgnt->ExtConfig.HCIExtensionVer));
-
- {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_EXTENSION,
- HCI_EXTENSION_VERSION_NOTIFY,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
-
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdLinkStatusNotify(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
- u8 i;
- u8 *pTriple;
-
- pBtDbg->dbgHciInfo.hciCmdCntLinkStatusNotify++;
- RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "LinkStatusNotify, Hex Data :\n",
- &pHciCmd->Data[0], pHciCmd->Length);
-
- /* Current only RTL8723 support this command. */
- pBtMgnt->bSupportProfile = true;
-
- pBtMgnt->ExtConfig.NumberOfHandle = *((u8 *)pHciCmd->Data);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("NumberOfHandle = 0x%x\n", pBtMgnt->ExtConfig.NumberOfHandle));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCIExtensionVer = %d\n", pBtMgnt->ExtConfig.HCIExtensionVer));
-
- pTriple = &pHciCmd->Data[1];
- for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) {
- if (pBtMgnt->ExtConfig.HCIExtensionVer < 1) {
- pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle = *((u16 *)&pTriple[0]);
- pBtMgnt->ExtConfig.linkInfo[i].BTProfile = pTriple[2];
- pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec = pTriple[3];
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT,
- ("Connection_Handle = 0x%x, BTProfile =%d, BTSpec =%d\n",
- pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle,
- pBtMgnt->ExtConfig.linkInfo[i].BTProfile,
- pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec));
- pTriple += 4;
- } else if (pBtMgnt->ExtConfig.HCIExtensionVer >= 1) {
- pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle = *((u16 *)&pTriple[0]);
- pBtMgnt->ExtConfig.linkInfo[i].BTProfile = pTriple[2];
- pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec = pTriple[3];
- pBtMgnt->ExtConfig.linkInfo[i].linkRole = pTriple[4];
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT,
- ("Connection_Handle = 0x%x, BTProfile =%d, BTSpec =%d, LinkRole =%d\n",
- pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle,
- pBtMgnt->ExtConfig.linkInfo[i].BTProfile,
- pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec,
- pBtMgnt->ExtConfig.linkInfo[i].linkRole));
- pTriple += 5;
- }
-
- }
- BTHCI_UpdateBTProfileRTKToMoto(padapter);
- {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_EXTENSION,
- HCI_LINK_STATUS_NOTIFY,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
-
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdBtOperationNotify(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "Bt Operation notify, Hex Data :\n",
- &pHciCmd->Data[0], pHciCmd->Length);
-
- pBtMgnt->ExtConfig.btOperationCode = *((u8 *)pHciCmd->Data);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("btOperationCode = 0x%x\n", pBtMgnt->ExtConfig.btOperationCode));
- switch (pBtMgnt->ExtConfig.btOperationCode) {
- case HCI_BT_OP_NONE:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Operation None!!\n"));
- break;
- case HCI_BT_OP_INQUIRY_START:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Inquire start!!\n"));
- break;
- case HCI_BT_OP_INQUIRY_FINISH:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Inquire finished!!\n"));
- break;
- case HCI_BT_OP_PAGING_START:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Paging is started!!\n"));
- break;
- case HCI_BT_OP_PAGING_SUCCESS:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Paging complete successfully!!\n"));
- break;
- case HCI_BT_OP_PAGING_UNSUCCESS:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Paging complete unsuccessfully!!\n"));
- break;
- case HCI_BT_OP_PAIRING_START:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Pairing start!!\n"));
- break;
- case HCI_BT_OP_PAIRING_FINISH:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Pairing finished!!\n"));
- break;
- case HCI_BT_OP_BT_DEV_ENABLE:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : BT Device is enabled!!\n"));
- break;
- case HCI_BT_OP_BT_DEV_DISABLE:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : BT Device is disabled!!\n"));
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Unknown, error!!\n"));
- break;
- }
- BTDM_AdjustForBtOperation(padapter);
- {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_EXTENSION,
- HCI_BT_OPERATION_NOTIFY,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
-
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdEnableWifiScanNotify(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "Enable Wifi scan notify, Hex Data :\n",
- &pHciCmd->Data[0], pHciCmd->Length);
-
- pBtMgnt->ExtConfig.bEnableWifiScanNotify = *((u8 *)pHciCmd->Data);
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("bEnableWifiScanNotify = %d\n", pBtMgnt->ExtConfig.bEnableWifiScanNotify));
-
- {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_EXTENSION,
- HCI_ENABLE_WIFI_SCAN_NOTIFY,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
-
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdWIFICurrentChannel(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- u8 chnl = pmlmeext->cur_channel;
-
- if (pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) {
- if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
- chnl += 2;
- else if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
- chnl -= 2;
- }
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("Current Channel = 0x%x\n", chnl));
-
- {
- u8 localBuf[8] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_EXTENSION,
- HCI_WIFI_CURRENT_CHANNEL,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- pRetPar[1] = chnl; /* current channel */
- len += 2;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdWIFICurrentBandwidth(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- enum ht_channel_width bw;
- u8 CurrentBW = 0;
-
- bw = padapter->mlmeextpriv.cur_bwmode;
-
- if (bw == HT_CHANNEL_WIDTH_20)
- CurrentBW = 0;
- else if (bw == HT_CHANNEL_WIDTH_40)
- CurrentBW = 1;
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("Current BW = 0x%x\n",
- CurrentBW));
-
- {
- u8 localBuf[8] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_EXTENSION,
- HCI_WIFI_CURRENT_BANDWIDTH,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- pRetPar[1] = CurrentBW; /* current BW */
- len += 2;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdWIFIConnectionStatus(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- u8 connectStatus = HCI_WIFI_NOT_CONNECTED;
-
- if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE)) {
- if (padapter->stapriv.asoc_sta_count >= 3)
- connectStatus = HCI_WIFI_CONNECTED;
- else
- connectStatus = HCI_WIFI_NOT_CONNECTED;
- } else if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_ASOC_STATE)) {
- connectStatus = HCI_WIFI_CONNECTED;
- } else if (check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING)) {
- connectStatus = HCI_WIFI_CONNECT_IN_PROGRESS;
- } else {
- connectStatus = HCI_WIFI_NOT_CONNECTED;
- }
-
- {
- u8 localBuf[8] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_EXTENSION,
- HCI_WIFI_CONNECTION_STATUS,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- pRetPar[1] = connectStatus; /* connect status */
- len += 2;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdEnableDeviceUnderTestMode(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
-
- pBtHciInfo->bInTestMode = true;
- pBtHciInfo->bTestIsEnd = false;
-
- /* send command complete event here when all data are received. */
- {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_TESTING_COMMANDS,
- HCI_ENABLE_DEVICE_UNDER_TEST_MODE,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdAMPTestEnd(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
-
- if (!pBtHciInfo->bInTestMode) {
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Not in Test mode, return status = HCI_STATUS_CMD_DISALLOW\n"));
- status = HCI_STATUS_CMD_DISALLOW;
- return status;
- }
-
- pBtHciInfo->bTestIsEnd = true;
-
- del_timer_sync(&pBTInfo->BTTestSendPacketTimer);
-
- rtl8723a_check_bssid(padapter, true);
-
- /* send command complete event here when all data are received. */
- {
- u8 localBuf[4] = "";
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("AMP Test End Event \n"));
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_AMP_TEST_END;
- PPacketIrpEvent->Length = 2;
-
- PPacketIrpEvent->Data[0] = status;
- PPacketIrpEvent->Data[1] = pBtHciInfo->TestScenario;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 4);
- }
-
- bthci_EventAMPReceiverReport(padapter, 0x01);
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdAMPTestCommand(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
-
- if (!pBtHciInfo->bInTestMode) {
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Not in Test mode, return status = HCI_STATUS_CMD_DISALLOW\n"));
- status = HCI_STATUS_CMD_DISALLOW;
- return status;
- }
-
- pBtHciInfo->TestScenario = *((u8 *)pHciCmd->Data);
-
- if (pBtHciInfo->TestScenario == 0x01)
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("TX Single Test \n"));
- else if (pBtHciInfo->TestScenario == 0x02)
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Receive Frame Test \n"));
- else
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("No Such Test !!!!!!!!!!!!!!!!!! \n"));
-
- if (pBtHciInfo->bTestIsEnd) {
- u8 localBuf[5] = "";
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("AMP Test End Event \n"));
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_AMP_TEST_END;
- PPacketIrpEvent->Length = 2;
-
- PPacketIrpEvent->Data[0] = status;
- PPacketIrpEvent->Data[1] = pBtHciInfo->TestScenario ;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 4);
-
- /* Return to Idel state with RX and TX off. */
-
- return status;
- }
-
- /* should send command status event */
- bthci_EventCommandStatus(padapter,
- OGF_TESTING_COMMANDS,
- HCI_AMP_TEST_COMMAND,
- status);
-
- /* The HCI_AMP_Start Test Event shall be generated when the */
- /* HCI_AMP_Test_Command has completed and the first data is ready to be sent */
- /* or received. */
-
- {
- u8 localBuf[5] = "";
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), (" HCI_AMP_Start Test Event \n"));
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- PPacketIrpEvent->EventCode = HCI_EVENT_AMP_START_TEST;
- PPacketIrpEvent->Length = 2;
-
- PPacketIrpEvent->Data[0] = status;
- PPacketIrpEvent->Data[1] = pBtHciInfo->TestScenario ;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, 4);
-
- /* Return to Idel state with RX and TX off. */
- }
-
- if (pBtHciInfo->TestScenario == 0x01) {
- /*
- When in a transmitter test scenario and the frames/bursts count have been
- transmitted the HCI_AMP_Test_End event shall be sent.
- */
- mod_timer(&pBTInfo->BTTestSendPacketTimer,
- jiffies + msecs_to_jiffies(50));
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("TX Single Test \n"));
- } else if (pBtHciInfo->TestScenario == 0x02) {
- rtl8723a_check_bssid(padapter, false);
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Receive Frame Test \n"));
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdEnableAMPReceiverReports(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
-
- if (!pBtHciInfo->bInTestMode) {
- status = HCI_STATUS_CMD_DISALLOW;
- /* send command complete event here when all data are received. */
- {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_TESTING_COMMANDS,
- HCI_ENABLE_AMP_RECEIVER_REPORTS,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
- return status;
- }
-
- pBtHciInfo->bTestNeedReport = *((u8 *)pHciCmd->Data);
- pBtHciInfo->TestReportInterval = (*((u8 *)pHciCmd->Data+2));
-
- bthci_EventAMPReceiverReport(padapter, 0x00);
-
- /* send command complete event here when all data are received. */
- {
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_TESTING_COMMANDS,
- HCI_ENABLE_AMP_RECEIVER_REPORTS,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
- }
-
- return status;
-}
-
-static enum hci_status
-bthci_CmdHostBufferSize(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- enum hci_status status = HCI_STATUS_SUCCESS;
- u8 localBuf[6] = "";
- u8 *pRetPar;
- u8 len = 0;
-
- pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].ACLPacketsData.ACLDataPacketLen = *((u16 *)pHciCmd->Data);
- pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].SyncDataPacketLen = *((u8 *)(pHciCmd->Data+2));
- pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].TotalNumACLDataPackets = *((u16 *)(pHciCmd->Data+3));
- pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].TotalSyncNumDataPackets = *((u16 *)(pHciCmd->Data+5));
-
- /* send command complete event here when all data are received. */
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- len += bthci_CommandCompleteHeader(&localBuf[0],
- OGF_SET_EVENT_MASK_COMMAND,
- HCI_HOST_BUFFER_SIZE,
- status);
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[len];
- pRetPar[0] = status; /* status */
- len += 1;
- PPacketIrpEvent->Length = len;
-
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-
- return status;
-}
-
-static enum hci_status
-bthci_UnknownCMD(struct rtw_adapter *padapter, struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_UNKNOW_HCI_CMD;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
-
- pBtDbg->dbgHciInfo.hciCmdCntUnknown++;
- bthci_EventCommandStatus(padapter,
- (u8)pHciCmd->OGF,
- pHciCmd->OCF,
- status);
-
- return status;
-}
-
-static enum hci_status
-bthci_HandleOGFInformationalParameters(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
-
- switch (pHciCmd->OCF) {
- case HCI_READ_LOCAL_VERSION_INFORMATION:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_VERSION_INFORMATION\n"));
- status = bthci_CmdReadLocalVersionInformation(padapter);
- break;
- case HCI_READ_LOCAL_SUPPORTED_COMMANDS:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_SUPPORTED_COMMANDS\n"));
- status = bthci_CmdReadLocalSupportedCommands(padapter);
- break;
- case HCI_READ_LOCAL_SUPPORTED_FEATURES:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_SUPPORTED_FEATURES\n"));
- status = bthci_CmdReadLocalSupportedFeatures(padapter);
- break;
- case HCI_READ_BUFFER_SIZE:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_BUFFER_SIZE\n"));
- status = bthci_CmdReadBufferSize(padapter);
- break;
- case HCI_READ_DATA_BLOCK_SIZE:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_DATA_BLOCK_SIZE\n"));
- status = bthci_CmdReadDataBlockSize(padapter);
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_HandleOGFInformationalParameters(), Unknown case = 0x%x\n", pHciCmd->OCF));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n"));
- status = bthci_UnknownCMD(padapter, pHciCmd);
- break;
- }
- return status;
-}
-
-static enum hci_status
-bthci_HandleOGFSetEventMaskCMD(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
-
- switch (pHciCmd->OCF) {
- case HCI_SET_EVENT_MASK:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SET_EVENT_MASK\n"));
- status = bthci_CmdSetEventMask(padapter, pHciCmd);
- break;
- case HCI_RESET:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_RESET\n"));
- status = bthci_CmdReset(padapter, true);
- break;
- case HCI_READ_CONNECTION_ACCEPT_TIMEOUT:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_CONNECTION_ACCEPT_TIMEOUT\n"));
- status = bthci_CmdReadConnectionAcceptTimeout(padapter);
- break;
- case HCI_SET_EVENT_FILTER:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SET_EVENT_FILTER\n"));
- break;
- case HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT\n"));
- status = bthci_CmdWriteConnectionAcceptTimeout(padapter, pHciCmd);
- break;
- case HCI_READ_PAGE_TIMEOUT:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_PAGE_TIMEOUT\n"));
- status = bthci_CmdReadPageTimeout(padapter, pHciCmd);
- break;
- case HCI_WRITE_PAGE_TIMEOUT:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_PAGE_TIMEOUT\n"));
- status = bthci_CmdWritePageTimeout(padapter, pHciCmd);
- break;
- case HCI_HOST_NUMBER_OF_COMPLETED_PACKETS:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_HOST_NUMBER_OF_COMPLETED_PACKETS\n"));
- break;
- case HCI_READ_LINK_SUPERVISION_TIMEOUT:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LINK_SUPERVISION_TIMEOUT\n"));
- status = bthci_CmdReadLinkSupervisionTimeout(padapter, pHciCmd);
- break;
- case HCI_WRITE_LINK_SUPERVISION_TIMEOUT:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_LINK_SUPERVISION_TIMEOUT\n"));
- status = bthci_CmdWriteLinkSupervisionTimeout(padapter, pHciCmd);
- break;
- case HCI_ENHANCED_FLUSH:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ENHANCED_FLUSH\n"));
- status = bthci_CmdEnhancedFlush(padapter, pHciCmd);
- break;
- case HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT\n"));
- status = bthci_CmdReadLogicalLinkAcceptTimeout(padapter, pHciCmd);
- break;
- case HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT\n"));
- status = bthci_CmdWriteLogicalLinkAcceptTimeout(padapter, pHciCmd);
- break;
- case HCI_SET_EVENT_MASK_PAGE_2:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SET_EVENT_MASK_PAGE_2\n"));
- status = bthci_CmdSetEventMaskPage2(padapter, pHciCmd);
- break;
- case HCI_READ_LOCATION_DATA:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCATION_DATA\n"));
- status = bthci_CmdReadLocationData(padapter, pHciCmd);
- break;
- case HCI_WRITE_LOCATION_DATA:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_LOCATION_DATA\n"));
- status = bthci_CmdWriteLocationData(padapter, pHciCmd);
- break;
- case HCI_READ_FLOW_CONTROL_MODE:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_FLOW_CONTROL_MODE\n"));
- status = bthci_CmdReadFlowControlMode(padapter, pHciCmd);
- break;
- case HCI_WRITE_FLOW_CONTROL_MODE:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_FLOW_CONTROL_MODE\n"));
- status = bthci_CmdWriteFlowControlMode(padapter, pHciCmd);
- break;
- case HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT\n"));
- status = bthci_CmdReadBestEffortFlushTimeout(padapter, pHciCmd);
- break;
- case HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT\n"));
- status = bthci_CmdWriteBestEffortFlushTimeout(padapter, pHciCmd);
- break;
- case HCI_SHORT_RANGE_MODE:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SHORT_RANGE_MODE\n"));
- status = bthci_CmdShortRangeMode(padapter, pHciCmd);
- break;
- case HCI_HOST_BUFFER_SIZE:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_HOST_BUFFER_SIZE\n"));
- status = bthci_CmdHostBufferSize(padapter, pHciCmd);
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_HandleOGFSetEventMaskCMD(), Unknown case = 0x%x\n", pHciCmd->OCF));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n"));
- status = bthci_UnknownCMD(padapter, pHciCmd);
- break;
- }
- return status;
-}
-
-static enum hci_status
-bthci_HandleOGFStatusParameters(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
-
- switch (pHciCmd->OCF) {
- case HCI_READ_FAILED_CONTACT_COUNTER:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_FAILED_CONTACT_COUNTER\n"));
- status = bthci_CmdReadFailedContactCounter(padapter, pHciCmd);
- break;
- case HCI_RESET_FAILED_CONTACT_COUNTER:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_RESET_FAILED_CONTACT_COUNTER\n"));
- status = bthci_CmdResetFailedContactCounter(padapter, pHciCmd);
- break;
- case HCI_READ_LINK_QUALITY:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LINK_QUALITY\n"));
- status = bthci_CmdReadLinkQuality(padapter, pHciCmd);
- break;
- case HCI_READ_RSSI:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_RSSI\n"));
- break;
- case HCI_READ_LOCAL_AMP_INFO:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_AMP_INFO\n"));
- status = bthci_CmdReadLocalAMPInfo(padapter);
- break;
- case HCI_READ_LOCAL_AMP_ASSOC:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_AMP_ASSOC\n"));
- status = bthci_CmdReadLocalAMPAssoc(padapter, pHciCmd);
- break;
- case HCI_WRITE_REMOTE_AMP_ASSOC:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_REMOTE_AMP_ASSOC\n"));
- status = bthci_CmdWriteRemoteAMPAssoc(padapter, pHciCmd);
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_HandleOGFStatusParameters(), Unknown case = 0x%x\n", pHciCmd->OCF));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n"));
- status = bthci_UnknownCMD(padapter, pHciCmd);
- break;
- }
- return status;
-}
-
-static enum hci_status
-bthci_HandleOGFLinkControlCMD(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
-
- switch (pHciCmd->OCF) {
- case HCI_CREATE_PHYSICAL_LINK:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_CREATE_PHYSICAL_LINK\n"));
- status = bthci_CmdCreatePhysicalLink(padapter, pHciCmd);
- break;
- case HCI_ACCEPT_PHYSICAL_LINK:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ACCEPT_PHYSICAL_LINK\n"));
- status = bthci_CmdAcceptPhysicalLink(padapter, pHciCmd);
- break;
- case HCI_DISCONNECT_PHYSICAL_LINK:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_DISCONNECT_PHYSICAL_LINK\n"));
- status = bthci_CmdDisconnectPhysicalLink(padapter, pHciCmd);
- break;
- case HCI_CREATE_LOGICAL_LINK:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_CREATE_LOGICAL_LINK\n"));
- status = bthci_CmdCreateLogicalLink(padapter, pHciCmd);
- break;
- case HCI_ACCEPT_LOGICAL_LINK:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ACCEPT_LOGICAL_LINK\n"));
- status = bthci_CmdAcceptLogicalLink(padapter, pHciCmd);
- break;
- case HCI_DISCONNECT_LOGICAL_LINK:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_DISCONNECT_LOGICAL_LINK\n"));
- status = bthci_CmdDisconnectLogicalLink(padapter, pHciCmd);
- break;
- case HCI_LOGICAL_LINK_CANCEL:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_LOGICAL_LINK_CANCEL\n"));
- status = bthci_CmdLogicalLinkCancel(padapter, pHciCmd);
- break;
- case HCI_FLOW_SPEC_MODIFY:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_FLOW_SPEC_MODIFY\n"));
- status = bthci_CmdFlowSpecModify(padapter, pHciCmd);
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_HandleOGFLinkControlCMD(), Unknown case = 0x%x\n", pHciCmd->OCF));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n"));
- status = bthci_UnknownCMD(padapter, pHciCmd);
- break;
- }
- return status;
-}
-
-static enum hci_status
-bthci_HandleOGFTestingCMD(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- switch (pHciCmd->OCF) {
- case HCI_ENABLE_DEVICE_UNDER_TEST_MODE:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ENABLE_DEVICE_UNDER_TEST_MODE\n"));
- bthci_CmdEnableDeviceUnderTestMode(padapter, pHciCmd);
- break;
- case HCI_AMP_TEST_END:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_AMP_TEST_END\n"));
- bthci_CmdAMPTestEnd(padapter, pHciCmd);
- break;
- case HCI_AMP_TEST_COMMAND:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_AMP_TEST_COMMAND\n"));
- bthci_CmdAMPTestCommand(padapter, pHciCmd);
- break;
- case HCI_ENABLE_AMP_RECEIVER_REPORTS:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ENABLE_AMP_RECEIVER_REPORTS\n"));
- bthci_CmdEnableAMPReceiverReports(padapter, pHciCmd);
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n"));
- status = bthci_UnknownCMD(padapter, pHciCmd);
- break;
- }
- return status;
-}
-
-static enum hci_status
-bthci_HandleOGFExtension(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd)
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- switch (pHciCmd->OCF) {
- case HCI_SET_ACL_LINK_DATA_FLOW_MODE:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_SET_ACL_LINK_DATA_FLOW_MODE\n"));
- status = bthci_CmdSetACLLinkDataFlowMode(padapter, pHciCmd);
- break;
- case HCI_SET_ACL_LINK_STATUS:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_SET_ACL_LINK_STATUS\n"));
- status = bthci_CmdSetACLLinkStatus(padapter, pHciCmd);
- break;
- case HCI_SET_SCO_LINK_STATUS:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_SET_SCO_LINK_STATUS\n"));
- status = bthci_CmdSetSCOLinkStatus(padapter, pHciCmd);
- break;
- case HCI_SET_RSSI_VALUE:
- RTPRINT(FIOCTL, IOCTL_BT_EVENT_PERIODICAL, ("HCI_SET_RSSI_VALUE\n"));
- status = bthci_CmdSetRSSIValue(padapter, pHciCmd);
- break;
- case HCI_SET_CURRENT_BLUETOOTH_STATUS:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_SET_CURRENT_BLUETOOTH_STATUS\n"));
- status = bthci_CmdSetCurrentBluetoothStatus(padapter, pHciCmd);
- break;
- /* The following is for RTK8723 */
-
- case HCI_EXTENSION_VERSION_NOTIFY:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_EXTENSION_VERSION_NOTIFY\n"));
- status = bthci_CmdExtensionVersionNotify(padapter, pHciCmd);
- break;
- case HCI_LINK_STATUS_NOTIFY:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_LINK_STATUS_NOTIFY\n"));
- status = bthci_CmdLinkStatusNotify(padapter, pHciCmd);
- break;
- case HCI_BT_OPERATION_NOTIFY:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_BT_OPERATION_NOTIFY\n"));
- status = bthci_CmdBtOperationNotify(padapter, pHciCmd);
- break;
- case HCI_ENABLE_WIFI_SCAN_NOTIFY:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_ENABLE_WIFI_SCAN_NOTIFY\n"));
- status = bthci_CmdEnableWifiScanNotify(padapter, pHciCmd);
- break;
-
- /* The following is for IVT */
- case HCI_WIFI_CURRENT_CHANNEL:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_WIFI_CURRENT_CHANNEL\n"));
- status = bthci_CmdWIFICurrentChannel(padapter, pHciCmd);
- break;
- case HCI_WIFI_CURRENT_BANDWIDTH:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_WIFI_CURRENT_BANDWIDTH\n"));
- status = bthci_CmdWIFICurrentBandwidth(padapter, pHciCmd);
- break;
- case HCI_WIFI_CONNECTION_STATUS:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_WIFI_CONNECTION_STATUS\n"));
- status = bthci_CmdWIFIConnectionStatus(padapter, pHciCmd);
- break;
-
- default:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_UNKNOWN_COMMAND\n"));
- status = bthci_UnknownCMD(padapter, pHciCmd);
- break;
- }
- return status;
-}
-
-static void
-bthci_StateStarting(struct rtw_adapter *padapter,
- enum hci_state_with_cmd StateCmd, u8 EntryNum)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Starting], "));
- switch (StateCmd) {
- case STATE_CMD_CONNECT_ACCEPT_TIMEOUT:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_CONNECT_ACCEPT_TIMEOUT\n"));
- pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_CONNECT_ACCEPT_TIMEOUT;
- pBtMgnt->bNeedNotifyAMPNoCap = true;
- BTHCI_DisconnectPeer(padapter, EntryNum);
- break;
- case STATE_CMD_DISCONNECT_PHY_LINK:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n"));
-
- bthci_EventDisconnectPhyLinkComplete(padapter,
- HCI_STATUS_SUCCESS,
- pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason,
- EntryNum);
-
- del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
-
- pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_UNKNOW_CONNECT_ID;
-
- BTHCI_DisconnectPeer(padapter, EntryNum);
- break;
- case STATE_CMD_MAC_START_COMPLETE:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_START_COMPLETE\n"));
- if (pBTInfo->BtAsocEntry[EntryNum].AMPRole == AMP_BTAP_CREATOR)
- bthci_EventChannelSelected(padapter, EntryNum);
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd));
- break;
- }
-}
-
-static void
-bthci_StateConnecting(struct rtw_adapter *padapter,
- enum hci_state_with_cmd StateCmd, u8 EntryNum)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Connecting], "));
- switch (StateCmd) {
- case STATE_CMD_CONNECT_ACCEPT_TIMEOUT:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_CONNECT_ACCEPT_TIMEOUT\n"));
- pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_CONNECT_ACCEPT_TIMEOUT;
- pBtMgnt->bNeedNotifyAMPNoCap = true;
- BTHCI_DisconnectPeer(padapter, EntryNum);
- break;
- case STATE_CMD_MAC_CONNECT_COMPLETE:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_CONNECT_COMPLETE\n"));
-
- if (pBTInfo->BtAsocEntry[EntryNum].AMPRole == AMP_BTAP_JOINER) {
- RT_TRACE(_module_rtl871x_security_c_, _drv_info_,
- "StateConnecting\n");
- }
- break;
- case STATE_CMD_DISCONNECT_PHY_LINK:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n"));
-
- bthci_EventDisconnectPhyLinkComplete(padapter,
- HCI_STATUS_SUCCESS,
- pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason,
- EntryNum);
-
- pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_UNKNOW_CONNECT_ID;
-
- del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
-
- BTHCI_DisconnectPeer(padapter, EntryNum);
-
- break;
- case STATE_CMD_MAC_CONNECT_CANCEL_INDICATE:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_CONNECT_CANCEL_INDICATE\n"));
- pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_CONTROLLER_BUSY;
- /* Because this state cmd is caused by the BTHCI_EventAMPStatusChange(), */
- /* we don't need to send event in the following BTHCI_DisconnectPeer() again. */
- pBtMgnt->bNeedNotifyAMPNoCap = false;
- BTHCI_DisconnectPeer(padapter, EntryNum);
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd));
- break;
- }
-}
-
-static void
-bthci_StateConnected(struct rtw_adapter *padapter,
- enum hci_state_with_cmd StateCmd, u8 EntryNum)
-{
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- u8 i;
- u16 logicHandle = 0;
-
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Connected], "));
- switch (StateCmd) {
- case STATE_CMD_DISCONNECT_PHY_LINK:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n"));
-
- /* When we are trying to disconnect the phy link, we should disconnect log link first, */
- for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
- if (pBTInfo->BtAsocEntry[EntryNum].LogLinkCmdData->BtLogLinkhandle != 0) {
- logicHandle = pBTInfo->BtAsocEntry[EntryNum].LogLinkCmdData->BtLogLinkhandle;
-
- bthci_EventDisconnectLogicalLinkComplete(padapter, HCI_STATUS_SUCCESS,
- logicHandle, pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason);
-
- pBTInfo->BtAsocEntry[EntryNum].LogLinkCmdData->BtLogLinkhandle = 0;
- }
- }
-
- bthci_EventDisconnectPhyLinkComplete(padapter,
- HCI_STATUS_SUCCESS,
- pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason,
- EntryNum);
-
- del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
-
- BTHCI_DisconnectPeer(padapter, EntryNum);
- break;
-
- case STATE_CMD_MAC_DISCONNECT_INDICATE:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_DISCONNECT_INDICATE\n"));
-
- bthci_EventDisconnectPhyLinkComplete(padapter,
- HCI_STATUS_SUCCESS,
- /* TODO: Remote Host not local host */
- HCI_STATUS_CONNECT_TERMINATE_LOCAL_HOST,
- EntryNum);
- BTHCI_DisconnectPeer(padapter, EntryNum);
-
- break;
- case STATE_CMD_ENTER_STATE:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_ENTER_STATE\n"));
-
- if (pBtMgnt->bBTConnectInProgress) {
- pBtMgnt->bBTConnectInProgress = false;
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress OFF!!\n"));
- }
- pBTInfo->BtAsocEntry[EntryNum].BtCurrentState = HCI_STATE_CONNECTED;
- pBTInfo->BtAsocEntry[EntryNum].b4waySuccess = true;
- pBtMgnt->bStartSendSupervisionPkt = true;
-
- /* for rate adaptive */
-
- rtl8723a_update_ramask(padapter,
- MAX_FW_SUPPORT_MACID_NUM-1-EntryNum, 0);
-
- HalSetBrateCfg23a(padapter, padapter->mlmepriv.cur_network.network.SupportedRates);
- BTDM_SetFwChnlInfo(padapter, RT_MEDIA_CONNECT);
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd));
- break;
- }
-}
-
-static void
-bthci_StateAuth(struct rtw_adapter *padapter, enum hci_state_with_cmd StateCmd,
- u8 EntryNum)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Authenticating], "));
- switch (StateCmd) {
- case STATE_CMD_CONNECT_ACCEPT_TIMEOUT:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_CONNECT_ACCEPT_TIMEOUT\n"));
- pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_CONNECT_ACCEPT_TIMEOUT;
- pBtMgnt->bNeedNotifyAMPNoCap = true;
- BTHCI_DisconnectPeer(padapter, EntryNum);
- break;
- case STATE_CMD_DISCONNECT_PHY_LINK:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n"));
- bthci_EventDisconnectPhyLinkComplete(padapter,
- HCI_STATUS_SUCCESS,
- pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason,
- EntryNum);
-
- pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_UNKNOW_CONNECT_ID;
-
- del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
-
- BTHCI_DisconnectPeer(padapter, EntryNum);
- break;
- case STATE_CMD_4WAY_FAILED:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_4WAY_FAILED\n"));
-
- pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_AUTH_FAIL;
- pBtMgnt->bNeedNotifyAMPNoCap = true;
-
- BTHCI_DisconnectPeer(padapter, EntryNum);
-
- del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
- break;
- case STATE_CMD_4WAY_SUCCESSED:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_4WAY_SUCCESSED\n"));
-
- bthci_EventPhysicalLinkComplete(padapter, HCI_STATUS_SUCCESS, EntryNum, INVALID_PL_HANDLE);
-
- del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
-
- BTHCI_SM_WITH_INFO(padapter, HCI_STATE_CONNECTED, STATE_CMD_ENTER_STATE, EntryNum);
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd));
- break;
- }
-}
-
-static void
-bthci_StateDisconnecting(struct rtw_adapter *padapter,
- enum hci_state_with_cmd StateCmd, u8 EntryNum)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Disconnecting], "));
- switch (StateCmd) {
- case STATE_CMD_MAC_CONNECT_CANCEL_INDICATE:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_CONNECT_CANCEL_INDICATE\n"));
- if (pBTInfo->BtAsocEntry[EntryNum].bNeedPhysLinkCompleteEvent) {
- bthci_EventPhysicalLinkComplete(padapter,
- pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus,
- EntryNum, INVALID_PL_HANDLE);
- }
-
- if (pBtMgnt->bBTConnectInProgress) {
- pBtMgnt->bBTConnectInProgress = false;
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress OFF!!\n"));
- }
-
- BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_ENTER_STATE, EntryNum);
- break;
- case STATE_CMD_DISCONNECT_PHY_LINK:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n"));
-
- bthci_EventDisconnectPhyLinkComplete(padapter,
- HCI_STATUS_SUCCESS,
- pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason,
- EntryNum);
-
- del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
-
- BTHCI_DisconnectPeer(padapter, EntryNum);
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd));
- break;
- }
-}
-
-static void
-bthci_StateDisconnected(struct rtw_adapter *padapter,
- enum hci_state_with_cmd StateCmd, u8 EntryNum)
-{
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Disconnected], "));
- switch (StateCmd) {
- case STATE_CMD_CREATE_PHY_LINK:
- case STATE_CMD_ACCEPT_PHY_LINK:
- if (StateCmd == STATE_CMD_CREATE_PHY_LINK)
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_CREATE_PHY_LINK\n"));
- else
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_ACCEPT_PHY_LINK\n"));
-
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT PS], Disable IPS and LPS\n"));
- ips_leave23a(padapter);
- LPS_Leave23a(padapter);
-
- pBtMgnt->bPhyLinkInProgress = true;
- pBtMgnt->BTCurrentConnectType = BT_DISCONNECT;
- pBtMgnt->CurrentBTConnectionCnt++;
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], CurrentBTConnectionCnt = %d\n",
- pBtMgnt->CurrentBTConnectionCnt));
- pBtMgnt->BtOperationOn = true;
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], Bt Operation ON!! CurrentConnectEntryNum = %d\n",
- pBtMgnt->CurrentConnectEntryNum));
-
- if (pBtMgnt->bBTConnectInProgress) {
- bthci_EventPhysicalLinkComplete(padapter, HCI_STATUS_CONTROLLER_BUSY, INVALID_ENTRY_NUM, pBtMgnt->BtCurrentPhyLinkhandle);
- bthci_RemoveEntryByEntryNum(padapter, EntryNum);
- return;
- }
-
- if (StateCmd == STATE_CMD_CREATE_PHY_LINK)
- pBTInfo->BtAsocEntry[EntryNum].AMPRole = AMP_BTAP_CREATOR;
- else
- pBTInfo->BtAsocEntry[EntryNum].AMPRole = AMP_BTAP_JOINER;
-
- /* 1. MAC not yet in selected channel */
- while (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR)) {
- RTPRINT(FIOCTL, IOCTL_STATE, ("Scan/Roaming/Wifi Link is in Progress, wait 200 ms\n"));
- mdelay(200);
- }
- /* 2. MAC already in selected channel */
- RTPRINT(FIOCTL, IOCTL_STATE, ("Channel is Ready\n"));
- mod_timer(&pBTInfo->BTHCIJoinTimeoutTimer,
- jiffies + msecs_to_jiffies(pBtHciInfo->ConnAcceptTimeout));
-
- pBTInfo->BtAsocEntry[EntryNum].bNeedPhysLinkCompleteEvent = true;
- break;
- case STATE_CMD_DISCONNECT_PHY_LINK:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n"));
-
- del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
-
- bthci_EventDisconnectPhyLinkComplete(padapter,
- HCI_STATUS_SUCCESS,
- pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason,
- EntryNum);
-
- if (pBTInfo->BtAsocEntry[EntryNum].bNeedPhysLinkCompleteEvent) {
- bthci_EventPhysicalLinkComplete(padapter,
- HCI_STATUS_UNKNOW_CONNECT_ID,
- EntryNum, INVALID_PL_HANDLE);
- }
-
- if (pBtMgnt->bBTConnectInProgress) {
- pBtMgnt->bBTConnectInProgress = false;
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress OFF!!\n"));
- }
- BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_ENTER_STATE, EntryNum);
- bthci_RemoveEntryByEntryNum(padapter, EntryNum);
- break;
- case STATE_CMD_ENTER_STATE:
- RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_ENTER_STATE\n"));
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd));
- break;
- }
-}
-
-void BTHCI_EventParse(struct rtw_adapter *padapter, void *pEvntData, u32 dataLen)
-{
-}
-
-u8 BTHCI_HsConnectionEstablished(struct rtw_adapter *padapter)
-{
- u8 bBtConnectionExist = false;
- struct bt_30info *pBtinfo = GET_BT_INFO(padapter);
- u8 i;
-
- for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) {
- if (pBtinfo->BtAsocEntry[i].b4waySuccess) {
- bBtConnectionExist = true;
- break;
- }
- }
-
-/*RTPRINT(FIOCTL, IOCTL_STATE, (" BTHCI_HsConnectionEstablished(), connection exist = %d\n", bBtConnectionExist)); */
-
- return bBtConnectionExist;
-}
-
-static u8
-BTHCI_CheckProfileExist(struct rtw_adapter *padapter,
- enum bt_traffic_mode_profile Profile)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- u8 IsPRofile = false;
- u8 i = 0;
-
- for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) {
- if (pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile == Profile) {
- IsPRofile = true;
- break;
- }
- }
-
- return IsPRofile;
-}
-
-void BTHCI_UpdateBTProfileRTKToMoto(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- u8 i = 0;
-
- pBtMgnt->ExtConfig.NumberOfSCO = 0;
-
- for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) {
- pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile = BT_PROFILE_NONE;
-
- if (pBtMgnt->ExtConfig.linkInfo[i].BTProfile == BT_PROFILE_SCO)
- pBtMgnt->ExtConfig.NumberOfSCO++;
-
- pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile = pBtMgnt->ExtConfig.linkInfo[i].BTProfile;
- switch (pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile) {
- case BT_PROFILE_SCO:
- break;
- case BT_PROFILE_PAN:
- pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = BT_MOTOR_EXT_BE;
- pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = BT_MOTOR_EXT_BE;
- break;
- case BT_PROFILE_A2DP:
- pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = BT_MOTOR_EXT_GULB;
- pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = BT_MOTOR_EXT_GULB;
- break;
- case BT_PROFILE_HID:
- pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = BT_MOTOR_EXT_GUL;
- pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = BT_MOTOR_EXT_BE;
- break;
- default:
- break;
- }
- }
-
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RTK, NumberOfHandle = %d, NumberOfSCO = %d\n",
- pBtMgnt->ExtConfig.NumberOfHandle, pBtMgnt->ExtConfig.NumberOfSCO));
-}
-
-void BTHCI_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- if (pBtMgnt->ExtConfig.bEnableWifiScanNotify)
- bthci_EventExtWifiScanNotify(padapter, scanType);
-}
-
-void
-BTHCI_StateMachine(
- struct rtw_adapter *padapter,
- u8 StateToEnter,
- enum hci_state_with_cmd StateCmd,
- u8 EntryNum
- )
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- if (EntryNum == 0xff) {
- RTPRINT(FIOCTL, IOCTL_STATE, (" StateMachine, error EntryNum = 0x%x \n", EntryNum));
- return;
- }
- RTPRINT(FIOCTL, IOCTL_STATE, (" StateMachine, EntryNum = 0x%x, CurrentState = 0x%x, BtNextState = 0x%x, StateCmd = 0x%x , StateToEnter = 0x%x\n",
- EntryNum, pBTInfo->BtAsocEntry[EntryNum].BtCurrentState, pBTInfo->BtAsocEntry[EntryNum].BtNextState, StateCmd, StateToEnter));
-
- if (pBTInfo->BtAsocEntry[EntryNum].BtNextState & StateToEnter) {
- pBTInfo->BtAsocEntry[EntryNum].BtCurrentState = StateToEnter;
-
- switch (StateToEnter) {
- case HCI_STATE_STARTING:
- pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTING | HCI_STATE_CONNECTING;
- bthci_StateStarting(padapter, StateCmd, EntryNum);
- break;
- case HCI_STATE_CONNECTING:
- pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_CONNECTING | HCI_STATE_DISCONNECTING | HCI_STATE_AUTHENTICATING;
- bthci_StateConnecting(padapter, StateCmd, EntryNum);
- break;
- case HCI_STATE_AUTHENTICATING:
- pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTING | HCI_STATE_CONNECTED;
- bthci_StateAuth(padapter, StateCmd, EntryNum);
- break;
- case HCI_STATE_CONNECTED:
- pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_CONNECTED | HCI_STATE_DISCONNECTING;
- bthci_StateConnected(padapter, StateCmd, EntryNum);
- break;
- case HCI_STATE_DISCONNECTING:
- pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTED | HCI_STATE_DISCONNECTING;
- bthci_StateDisconnecting(padapter, StateCmd, EntryNum);
- break;
- case HCI_STATE_DISCONNECTED:
- pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTED | HCI_STATE_STARTING | HCI_STATE_CONNECTING;
- bthci_StateDisconnected(padapter, StateCmd, EntryNum);
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_STATE, (" StateMachine, Unknown state to enter!!!\n"));
- break;
- }
- } else {
- RTPRINT(FIOCTL, IOCTL_STATE, (" StateMachine, Wrong state to enter\n"));
- }
-
- /* 20100325 Joseph: Disable/Enable IPS/LPS according to BT status. */
- if (!pBtMgnt->bBTConnectInProgress && !pBtMgnt->BtOperationOn) {
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT PS], ips_enter23a()\n"));
- ips_enter23a(padapter);
- }
-}
-
-void BTHCI_DisconnectPeer(struct rtw_adapter *padapter, u8 EntryNum)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, (" BTHCI_DisconnectPeer()\n"));
-
- BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTING, STATE_CMD_MAC_CONNECT_CANCEL_INDICATE, EntryNum);
-
- if (pBTInfo->BtAsocEntry[EntryNum].bUsed) {
-/*BTPKT_SendDeauthentication(padapter, pBTInfo->BtAsocEntry[EntryNum].BTRemoteMACAddr, unspec_reason); not porting yet */
- }
-
- if (pBtMgnt->bBTConnectInProgress) {
- pBtMgnt->bBTConnectInProgress = false;
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress OFF!!\n"));
- }
-
- bthci_RemoveEntryByEntryNum(padapter, EntryNum);
-
- if (pBtMgnt->bNeedNotifyAMPNoCap) {
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT AMPStatus], set to invalid in BTHCI_DisconnectPeer()\n"));
- BTHCI_EventAMPStatusChange(padapter, AMP_STATUS_NO_CAPACITY_FOR_BT);
- }
-}
-
-void BTHCI_EventNumOfCompletedDataBlocks(struct rtw_adapter *padapter)
-{
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
- u8 localBuf[TmpLocalBufSize] = "";
- u8 *pRetPar, *pTriple;
- u8 len = 0, i, j, handleNum = 0;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u16 *pu2Temp, *pPackets, *pHandle, *pDblocks;
- u8 sent = 0;
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
-
- if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_NUM_OF_COMPLETE_DATA_BLOCKS)) {
- RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Num Of Completed DataBlocks, Ignore to send NumOfCompletedDataBlocksEvent due to event mask page 2\n"));
- return;
- }
-
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[0];
- pTriple = &pRetPar[3];
- for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) {
-
- for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
- if (pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle) {
- handleNum++;
- pHandle = (u16 *)&pTriple[0]; /* Handle[i] */
- pPackets = (u16 *)&pTriple[2]; /* Num_Of_Completed_Packets[i] */
- pDblocks = (u16 *)&pTriple[4]; /* Num_Of_Completed_Blocks[i] */
- *pHandle = pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle;
- *pPackets = (u16)pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].TxPacketCount;
- *pDblocks = (u16)pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].TxPacketCount;
- if (pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].TxPacketCount) {
- sent = 1;
- RTPRINT(FIOCTL, IOCTL_BT_EVENT_DETAIL,
- ("[BT event], Num Of Completed DataBlocks, Handle = 0x%x, Num_Of_Completed_Packets = 0x%x, Num_Of_Completed_Blocks = 0x%x\n",
- *pHandle, *pPackets, *pDblocks));
- }
- pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].TxPacketCount = 0;
- len += 6;
- pTriple += len;
- }
- }
- }
-
- pRetPar[2] = handleNum; /* Number_of_Handles */
- len += 1;
- pu2Temp = (u16 *)&pRetPar[0];
- *pu2Temp = BTTotalDataBlockNum;
- len += 2;
-
- PPacketIrpEvent->EventCode = HCI_EVENT_NUM_OF_COMPLETE_DATA_BLOCKS;
- PPacketIrpEvent->Length = len;
- if (handleNum && sent)
- bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
-}
-
-void BTHCI_EventAMPStatusChange(struct rtw_adapter *padapter, u8 AMP_Status)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct packet_irp_hcievent_data *PPacketIrpEvent;
- u8 len = 0;
- u8 localBuf[7] = "";
- u8 *pRetPar;
-
- if (AMP_Status == AMP_STATUS_NO_CAPACITY_FOR_BT) {
- pBtMgnt->BTNeedAMPStatusChg = true;
- pBtMgnt->bNeedNotifyAMPNoCap = false;
-
- BTHCI_DisconnectAll(padapter);
- } else if (AMP_Status == AMP_STATUS_FULL_CAPACITY_FOR_BT) {
- pBtMgnt->BTNeedAMPStatusChg = false;
- }
-
- PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
- /* Return parameters starts from here */
- pRetPar = &PPacketIrpEvent->Data[0];
-
- pRetPar[0] = 0; /* Status */
- len += 1;
- pRetPar[1] = AMP_Status; /* AMP_Status */
- len += 1;
-
- PPacketIrpEvent->EventCode = HCI_EVENT_AMP_STATUS_CHANGE;
- PPacketIrpEvent->Length = len;
- if (bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2) == RT_STATUS_SUCCESS)
- RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_STATE), ("[BT event], AMP Status Change, AMP_Status = %d\n", AMP_Status));
-}
-
-void BTHCI_DisconnectAll(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- u8 i;
-
- RTPRINT(FIOCTL, IOCTL_STATE, (" DisconnectALL()\n"));
-
- for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) {
- if (pBTInfo->BtAsocEntry[i].b4waySuccess) {
- BTHCI_SM_WITH_INFO(padapter, HCI_STATE_CONNECTED, STATE_CMD_DISCONNECT_PHY_LINK, i);
- } else if (pBTInfo->BtAsocEntry[i].bUsed) {
- if (pBTInfo->BtAsocEntry[i].BtCurrentState == HCI_STATE_CONNECTING) {
- BTHCI_SM_WITH_INFO(padapter, HCI_STATE_CONNECTING, STATE_CMD_MAC_CONNECT_CANCEL_INDICATE, i);
- } else if (pBTInfo->BtAsocEntry[i].BtCurrentState == HCI_STATE_DISCONNECTING) {
- BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTING, STATE_CMD_MAC_CONNECT_CANCEL_INDICATE, i);
- }
- }
- }
-}
-
-enum hci_status
-BTHCI_HandleHCICMD(
- struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd
- )
-{
- enum hci_status status = HCI_STATUS_SUCCESS;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
-
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("\n"));
- RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("HCI Command start, OGF = 0x%x, OCF = 0x%x, Length = 0x%x\n",
- pHciCmd->OGF, pHciCmd->OCF, pHciCmd->Length));
- if (pHciCmd->Length) {
- RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), "HCI Command, Hex Data :\n",
- &pHciCmd->Data[0], pHciCmd->Length);
- }
- if (pHciCmd->OGF == OGF_EXTENSION) {
- if (pHciCmd->OCF == HCI_SET_RSSI_VALUE)
- RTPRINT(FIOCTL, IOCTL_BT_EVENT_PERIODICAL, ("[BT cmd], "));
- else
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[BT cmd], "));
- } else {
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("[BT cmd], "));
- }
-
- pBtDbg->dbgHciInfo.hciCmdCnt++;
-
- switch (pHciCmd->OGF) {
- case LINK_CONTROL_COMMANDS:
- status = bthci_HandleOGFLinkControlCMD(padapter, pHciCmd);
- break;
- case HOLD_MODE_COMMAND:
- break;
- case OGF_SET_EVENT_MASK_COMMAND:
- status = bthci_HandleOGFSetEventMaskCMD(padapter, pHciCmd);
- break;
- case OGF_INFORMATIONAL_PARAMETERS:
- status = bthci_HandleOGFInformationalParameters(padapter, pHciCmd);
- break;
- case OGF_STATUS_PARAMETERS:
- status = bthci_HandleOGFStatusParameters(padapter, pHciCmd);
- break;
- case OGF_TESTING_COMMANDS:
- status = bthci_HandleOGFTestingCMD(padapter, pHciCmd);
- break;
- case OGF_EXTENSION:
- status = bthci_HandleOGFExtension(padapter, pHciCmd);
- break;
- default:
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI Command(), Unknown OGF = 0x%x\n", pHciCmd->OGF));
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n"));
- status = bthci_UnknownCMD(padapter, pHciCmd);
- break;
- }
- RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("HCI Command execution end!!\n"));
-
- return status;
-}
-
-/* ===== End of sync from SD7 driver COMMOM/bt_hci.c ===== */
-
-static const char *const BtStateString[] = {
- "BT_DISABLED",
- "BT_NO_CONNECTION",
- "BT_CONNECT_IDLE",
- "BT_INQ_OR_PAG",
- "BT_ACL_ONLY_BUSY",
- "BT_SCO_ONLY_BUSY",
- "BT_ACL_SCO_BUSY",
- "BT_ACL_INQ_OR_PAG",
- "BT_STATE_NOT_DEFINED"
-};
-
-/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc87231Ant.c ===== */
-
-static void btdm_SetFwIgnoreWlanAct(struct rtw_adapter *padapter, u8 bEnable)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 H2C_Parameter[1] = {0};
-
- if (bEnable) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Ignore Wlan_Act !!\n"));
- H2C_Parameter[0] |= BIT(0); /* function enable */
- pHalData->bt_coexist.bFWCoexistAllOff = false;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT don't ignore Wlan_Act !!\n"));
- }
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, write 0x25 = 0x%02x\n",
- H2C_Parameter[0]));
-
- FillH2CCmd(padapter, BT_IGNORE_WLAN_ACT_EID, 1, H2C_Parameter);
-}
-
-static void btdm_NotifyFwScan(struct rtw_adapter *padapter, u8 scanType)
-{
- u8 H2C_Parameter[1] = {0};
-
- if (scanType == true)
- H2C_Parameter[0] = 0x1;
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Notify FW for wifi scan, write 0x3b = 0x%02x\n",
- H2C_Parameter[0]));
-
- FillH2CCmd(padapter, 0x3b, 1, H2C_Parameter);
-}
-
-static void btdm_1AntSetPSMode(struct rtw_adapter *padapter,
- u8 enable, u8 smartps, u8 mode)
-{
- struct pwrctrl_priv *pwrctrl;
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Current LPS(%s, %d), smartps =%d\n", enable == true?"ON":"OFF", mode, smartps));
-
- pwrctrl = &padapter->pwrctrlpriv;
-
- if (enable == true) {
- rtw_set_ps_mode23a(padapter, PS_MODE_MIN, smartps, mode);
- } else {
- rtw_set_ps_mode23a(padapter, PS_MODE_ACTIVE, 0, 0);
- LPS_RF_ON_check23a(padapter, 100);
- }
-}
-
-static void btdm_1AntTSFSwitch(struct rtw_adapter *padapter, u8 enable)
-{
- u8 oldVal, newVal;
-
- oldVal = rtl8723au_read8(padapter, 0x550);
-
- if (enable)
- newVal = oldVal | EN_BCN_FUNCTION;
- else
- newVal = oldVal & ~EN_BCN_FUNCTION;
-
- if (oldVal != newVal)
- rtl8723au_write8(padapter, 0x550, newVal);
-}
-
-static u8 btdm_Is1AntPsTdmaStateChange(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_1ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
-
- if ((pBtdm8723->bPrePsTdmaOn != pBtdm8723->bCurPsTdmaOn) ||
- (pBtdm8723->prePsTdma != pBtdm8723->curPsTdma))
- return true;
- else
- return false;
-}
-
-/* Before enter TDMA, make sure Power Saving is enable! */
-static void
-btdm_1AntPsTdma(
- struct rtw_adapter *padapter,
- u8 bTurnOn,
- u8 type
- )
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_1ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
-
- pBtdm8723->bCurPsTdmaOn = bTurnOn;
- pBtdm8723->curPsTdma = type;
- if (bTurnOn) {
- switch (type) {
- case 1: /* A2DP Level-1 or FTP/OPP */
- default:
- if (btdm_Is1AntPsTdmaStateChange(padapter)) {
- /* wide duration for WiFi */
- BTDM_SetFw3a(padapter, 0xd3, 0x1a, 0x1a, 0x0, 0x58);
- }
- break;
- case 2: /* A2DP Level-2 */
- if (btdm_Is1AntPsTdmaStateChange(padapter)) {
- /* normal duration for WiFi */
- BTDM_SetFw3a(padapter, 0xd3, 0x12, 0x12, 0x0, 0x58);
- }
- break;
- case 3: /* BT FTP/OPP */
- if (btdm_Is1AntPsTdmaStateChange(padapter)) {
- /* normal duration for WiFi */
- BTDM_SetFw3a(padapter, 0xd3, 0x30, 0x03, 0x10, 0x58);
-
- }
- break;
- case 4: /* for wifi scan & BT is connected */
- if (btdm_Is1AntPsTdmaStateChange(padapter)) {
- /* protect 3 beacons in 3-beacon period & no Tx pause at BT slot */
- BTDM_SetFw3a(padapter, 0x93, 0x15, 0x03, 0x14, 0x0);
- }
- break;
- case 5: /* for WiFi connected-busy & BT is Non-Connected-Idle */
- if (btdm_Is1AntPsTdmaStateChange(padapter)) {
- /* SCO mode, Ant fixed at WiFi, WLAN_Act toggle */
- BTDM_SetFw3a(padapter, 0x61, 0x15, 0x03, 0x31, 0x00);
- }
- break;
- case 9: /* ACL high-retry type - 2 */
- if (btdm_Is1AntPsTdmaStateChange(padapter)) {
- /* narrow duration for WiFi */
- BTDM_SetFw3a(padapter, 0xd3, 0xa, 0xa, 0x0, 0x58); /* narrow duration for WiFi */
- }
- break;
- case 10: /* for WiFi connect idle & BT ACL busy or WiFi Connected-Busy & BT is Inquiry */
- if (btdm_Is1AntPsTdmaStateChange(padapter))
- BTDM_SetFw3a(padapter, 0x13, 0xa, 0xa, 0x0, 0x40);
- break;
- case 11: /* ACL high-retry type - 3 */
- if (btdm_Is1AntPsTdmaStateChange(padapter)) {
- /* narrow duration for WiFi */
- BTDM_SetFw3a(padapter, 0xd3, 0x05, 0x05, 0x00, 0x58);
- }
- break;
- case 12: /* for WiFi Connected-Busy & BT is Connected-Idle */
- if (btdm_Is1AntPsTdmaStateChange(padapter)) {
- /* Allow High-Pri BT */
- BTDM_SetFw3a(padapter, 0xeb, 0x0a, 0x03, 0x31, 0x18);
- }
- break;
- case 20: /* WiFi only busy , TDMA mode for power saving */
- if (btdm_Is1AntPsTdmaStateChange(padapter))
- BTDM_SetFw3a(padapter, 0x13, 0x25, 0x25, 0x00, 0x00);
- break;
- case 27: /* WiFi DHCP/Site Survey & BT SCO busy */
- if (btdm_Is1AntPsTdmaStateChange(padapter))
- BTDM_SetFw3a(padapter, 0xa3, 0x25, 0x03, 0x31, 0x98);
- break;
- case 28: /* WiFi DHCP/Site Survey & BT idle */
- if (btdm_Is1AntPsTdmaStateChange(padapter))
- BTDM_SetFw3a(padapter, 0x69, 0x25, 0x03, 0x31, 0x00);
- break;
- case 29: /* WiFi DHCP/Site Survey & BT ACL busy */
- if (btdm_Is1AntPsTdmaStateChange(padapter)) {
- BTDM_SetFw3a(padapter, 0xeb, 0x1a, 0x1a, 0x01, 0x18);
- rtl8723au_write32(padapter, 0x6c0, 0x5afa5afa);
- rtl8723au_write32(padapter, 0x6c4, 0x5afa5afa);
- }
- break;
- case 30: /* WiFi idle & BT Inquiry */
- if (btdm_Is1AntPsTdmaStateChange(padapter))
- BTDM_SetFw3a(padapter, 0x93, 0x15, 0x03, 0x14, 0x00);
- break;
- case 31: /* BT HID */
- if (btdm_Is1AntPsTdmaStateChange(padapter))
- BTDM_SetFw3a(padapter, 0xd3, 0x1a, 0x1a, 0x00, 0x58);
- break;
- case 32: /* BT SCO & Inquiry */
- if (btdm_Is1AntPsTdmaStateChange(padapter))
- BTDM_SetFw3a(padapter, 0xab, 0x0a, 0x03, 0x11, 0x98);
- break;
- case 33: /* BT SCO & WiFi site survey */
- if (btdm_Is1AntPsTdmaStateChange(padapter))
- BTDM_SetFw3a(padapter, 0xa3, 0x25, 0x03, 0x30, 0x98);
- break;
- case 34: /* BT HID & WiFi site survey */
- if (btdm_Is1AntPsTdmaStateChange(padapter))
- BTDM_SetFw3a(padapter, 0xd3, 0x1a, 0x1a, 0x00, 0x18);
- break;
- case 35: /* BT HID & WiFi Connecting */
- if (btdm_Is1AntPsTdmaStateChange(padapter))
- BTDM_SetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0x00, 0x18);
- break;
- }
- } else {
- /* disable PS-TDMA */
- switch (type) {
- case 8:
- if (btdm_Is1AntPsTdmaStateChange(padapter)) {
- /* Antenna control by PTA, 0x870 = 0x310 */
- BTDM_SetFw3a(padapter, 0x8, 0x0, 0x0, 0x0, 0x0);
- }
- break;
- case 0:
- default:
- if (btdm_Is1AntPsTdmaStateChange(padapter)) {
- /* Antenna control by PTA, 0x870 = 0x310 */
- BTDM_SetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0);
- }
- /* Switch Antenna to BT */
- rtl8723au_write16(padapter, 0x860, 0x210);
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], 0x860 = 0x210, Switch Antenna to BT\n"));
- break;
- case 9:
- if (btdm_Is1AntPsTdmaStateChange(padapter)) {
- /* Antenna control by PTA, 0x870 = 0x310 */
- BTDM_SetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0);
- }
- /* Switch Antenna to WiFi */
- rtl8723au_write16(padapter, 0x860, 0x110);
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], 0x860 = 0x110, Switch Antenna to WiFi\n"));
- break;
- }
- }
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Current TDMA(%s, %d)\n",
- pBtdm8723->bCurPsTdmaOn?"ON":"OFF", pBtdm8723->curPsTdma));
-
- /* update pre state */
- pBtdm8723->bPrePsTdmaOn = pBtdm8723->bCurPsTdmaOn;
- pBtdm8723->prePsTdma = pBtdm8723->curPsTdma;
-}
-
-static void
-_btdm_1AntSetPSTDMA(struct rtw_adapter *padapter, u8 bPSEn, u8 smartps,
- u8 psOption, u8 bTDMAOn, u8 tdmaType)
-{
- struct pwrctrl_priv *pwrctrl;
- struct hal_data_8723a *pHalData;
- struct btdm_8723a_1ant *pBtdm8723;
- u8 psMode;
- u8 bSwitchPS;
-
- if (!check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) &&
- (get_fwstate(&padapter->mlmepriv) != WIFI_NULL_STATE)) {
- btdm_1AntPsTdma(padapter, bTDMAOn, tdmaType);
- return;
- }
- psOption &= ~BIT(0);
-
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], Set LPS(%s, %d) TDMA(%s, %d)\n",
- bPSEn == true?"ON":"OFF", psOption,
- bTDMAOn == true?"ON":"OFF", tdmaType));
-
- pwrctrl = &padapter->pwrctrlpriv;
- pHalData = GET_HAL_DATA(padapter);
- pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
-
- if (bPSEn) {
- if (pBtdm8723->bWiFiHalt) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Enable PS Fail, WiFi in Halt!!\n"));
- return;
- }
-
- if (pwrctrl->bInSuspend) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Enable PS Fail, WiFi in Suspend!!\n"));
- return;
- }
-
- if (padapter->bDriverStopped) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Enable PS Fail, WiFi driver stopped!!\n"));
- return;
- }
-
- if (padapter->bSurpriseRemoved) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Enable PS Fail, WiFi Surprise Removed!!\n"));
- return;
- }
-
- psMode = PS_MODE_MIN;
- } else {
- psMode = PS_MODE_ACTIVE;
- psOption = 0;
- }
-
- if (psMode != pwrctrl->pwr_mode) {
- bSwitchPS = true;
- } else if (psMode != PS_MODE_ACTIVE) {
- if (psOption != pwrctrl->bcn_ant_mode)
- bSwitchPS = true;
- else if (smartps != pwrctrl->smart_ps)
- bSwitchPS = true;
- else
- bSwitchPS = false;
- } else {
- bSwitchPS = false;
- }
-
- if (bSwitchPS) {
- /* disable TDMA */
- if (pBtdm8723->bCurPsTdmaOn) {
- if (!bTDMAOn) {
- btdm_1AntPsTdma(padapter, false, tdmaType);
- } else {
- if (!rtl8723a_BT_enabled(padapter) ||
- (pHalData->bt_coexist.halCoex8723.c2hBtInfo == BT_INFO_STATE_NO_CONNECTION) ||
- (pHalData->bt_coexist.halCoex8723.c2hBtInfo == BT_INFO_STATE_CONNECT_IDLE) ||
- (tdmaType == 29))
- btdm_1AntPsTdma(padapter, false, 9);
- else
- btdm_1AntPsTdma(padapter, false, 0);
- }
- }
-
- /* change Power Save State */
- btdm_1AntSetPSMode(padapter, bPSEn, smartps, psOption);
- }
-
- btdm_1AntPsTdma(padapter, bTDMAOn, tdmaType);
-}
-
-static void
-btdm_1AntSetPSTDMA(struct rtw_adapter *padapter, u8 bPSEn,
- u8 psOption, u8 bTDMAOn, u8 tdmaType)
-{
- _btdm_1AntSetPSTDMA(padapter, bPSEn, 0, psOption, bTDMAOn, tdmaType);
-}
-
-static void btdm_1AntWifiParaAdjust(struct rtw_adapter *padapter, u8 bEnable)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_1ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
-
- if (bEnable) {
- pBtdm8723->curWifiPara = 1;
- if (pBtdm8723->preWifiPara != pBtdm8723->curWifiPara)
- BTDM_SetSwPenaltyTxRateAdaptive(padapter, BT_TX_RATE_ADAPTIVE_LOW_PENALTY);
- } else {
- pBtdm8723->curWifiPara = 2;
- if (pBtdm8723->preWifiPara != pBtdm8723->curWifiPara)
- BTDM_SetSwPenaltyTxRateAdaptive(padapter, BT_TX_RATE_ADAPTIVE_NORMAL);
- }
-
-}
-
-static void btdm_1AntPtaParaReload(struct rtw_adapter *padapter)
-{
- /* PTA parameter */
- rtl8723au_write8(padapter, 0x6cc, 0x0); /* 1-Ant coex */
- rtl8723au_write32(padapter, 0x6c8, 0xffff); /* wifi break table */
- rtl8723au_write32(padapter, 0x6c4, 0x55555555); /* coex table */
-
- /* Antenna switch control parameter */
- rtl8723au_write32(padapter, 0x858, 0xaaaaaaaa);
- if (IS_8723A_A_CUT(GET_HAL_DATA(padapter)->VersionID)) {
- /* SPDT(connected with TRSW) control by hardware PTA */
- rtl8723au_write32(padapter, 0x870, 0x0);
- rtl8723au_write8(padapter, 0x40, 0x24);
- } else {
- rtl8723au_write8(padapter, 0x40, 0x20);
- /* set antenna at bt side if ANTSW is software control */
- rtl8723au_write16(padapter, 0x860, 0x210);
- /* SPDT(connected with TRSW) control by hardware PTA */
- rtl8723au_write32(padapter, 0x870, 0x300);
- /* ANTSW keep by GNT_BT */
- rtl8723au_write32(padapter, 0x874, 0x22804000);
- }
-
- /* coexistence parameters */
- rtl8723au_write8(padapter, 0x778, 0x1); /* enable RTK mode PTA */
-
- /* BT don't ignore WLAN_Act */
- btdm_SetFwIgnoreWlanAct(padapter, false);
-}
-
-/*
- * Return
- *1: upgrade (add WiFi duration time)
- *0: keep
- *-1: downgrade (add BT duration time)
- */
-static s8 btdm_1AntTdmaJudgement(struct rtw_adapter *padapter, u8 retry)
-{
- struct hal_data_8723a *pHalData;
- struct btdm_8723a_1ant *pBtdm8723;
- static s8 up, dn, m = 1, WaitCount;
- s8 ret;
-
- pHalData = GET_HAL_DATA(padapter);
- pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
- ret = 0;
-
- if (pBtdm8723->psTdmaMonitorCnt == 0) {
- up = 0;
- dn = 0;
- m = 1;
- WaitCount = 0;
- } else {
- WaitCount++;
- }
-
- if (retry == 0) {
- /* no retry in the last 2-second duration */
- up++;
- dn--;
- if (dn < 0)
- dn = 0;
- if (up >= 3*m) {
- /* retry = 0 in consecutive 3m*(2s), add WiFi duration */
- ret = 1;
- up = 0;
- dn = 0;
- WaitCount = 0;
- }
- } else if (retry <= 3) {
- /* retry<= 3 in the last 2-second duration */
- up--;
- dn++;
- if (up < 0)
- up = 0;
-
- if (dn == 2) {
- /* retry<= 3 in consecutive 2*(2s), minus WiFi duration (add BT duration) */
- ret = -1;
-
- /* record how many time downgrad WiFi duration */
- if (WaitCount <= 2)
- m++;
- else
- m = 1;
- /* the max number of m is 20 */
- /* the longest time of upgrade WiFi duration is 20*3*2s = 120s */
- if (m >= 20)
- m = 20;
- up = 0;
- dn = 0;
- WaitCount = 0;
- }
- } else {
- /* retry count > 3 */
- /* retry>3, minus WiFi duration (add BT duration) */
- ret = -1;
-
- /* record how many time downgrad WiFi duration */
- if (WaitCount == 1)
- m++;
- else
- m = 1;
- if (m >= 20)
- m = 20;
-
- up = 0;
- dn = 0;
- WaitCount = 0;
- }
- return ret;
-}
-
-static void btdm_1AntTdmaDurationAdjustForACL(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_1ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
-
- if (pBtdm8723->psTdmaGlobalCnt != pBtdm8723->psTdmaMonitorCnt) {
- pBtdm8723->psTdmaMonitorCnt = 0;
- pBtdm8723->psTdmaGlobalCnt = 0;
- }
- if (pBtdm8723->psTdmaMonitorCnt == 0) {
- btdm_1AntSetPSTDMA(padapter, true, 0, true, 2);
- pBtdm8723->psTdmaDuAdjType = 2;
- } else {
- /* Now we only have 4 level Ps Tdma, */
- /* if that's not the following 4 level(will changed by wifi scan, dhcp...), */
- /* then we have to adjust it back to the previous record one. */
- if ((pBtdm8723->curPsTdma != 1) &&
- (pBtdm8723->curPsTdma != 2) &&
- (pBtdm8723->curPsTdma != 9) &&
- (pBtdm8723->curPsTdma != 11)) {
- btdm_1AntSetPSTDMA(padapter, true, 0, true, pBtdm8723->psTdmaDuAdjType);
- } else {
- s32 judge;
-
- judge = btdm_1AntTdmaJudgement(padapter, pHalData->bt_coexist.halCoex8723.btRetryCnt);
- if (judge == -1) {
- if (pBtdm8723->curPsTdma == 1) {
- /* Decrease WiFi duration for high BT retry */
- if (pHalData->bt_coexist.halCoex8723.btInfoExt)
- pBtdm8723->psTdmaDuAdjType = 9;
- else
- pBtdm8723->psTdmaDuAdjType = 2;
- btdm_1AntSetPSTDMA(padapter, true, 0, true, pBtdm8723->psTdmaDuAdjType);
- } else if (pBtdm8723->curPsTdma == 2) {
- btdm_1AntSetPSTDMA(padapter, true, 0, true, 9);
- pBtdm8723->psTdmaDuAdjType = 9;
- } else if (pBtdm8723->curPsTdma == 9) {
- btdm_1AntSetPSTDMA(padapter, true, 0, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- }
- } else if (judge == 1) {
- if (pBtdm8723->curPsTdma == 11) {
- btdm_1AntSetPSTDMA(padapter, true, 0, true, 9);
- pBtdm8723->psTdmaDuAdjType = 9;
- } else if (pBtdm8723->curPsTdma == 9) {
- if (pHalData->bt_coexist.halCoex8723.btInfoExt)
- pBtdm8723->psTdmaDuAdjType = 9;
- else
- pBtdm8723->psTdmaDuAdjType = 2;
- btdm_1AntSetPSTDMA(padapter, true, 0, true, pBtdm8723->psTdmaDuAdjType);
- } else if (pBtdm8723->curPsTdma == 2) {
- if (pHalData->bt_coexist.halCoex8723.btInfoExt)
- pBtdm8723->psTdmaDuAdjType = 9;
- else
- pBtdm8723->psTdmaDuAdjType = 1;
- btdm_1AntSetPSTDMA(padapter, true, 0, true, pBtdm8723->psTdmaDuAdjType);
- }
- }
- }
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], ACL current TDMA(%s, %d)\n",
- (pBtdm8723->bCurPsTdmaOn ? "ON" : "OFF"), pBtdm8723->curPsTdma));
- }
- pBtdm8723->psTdmaMonitorCnt++;
-}
-
-static void btdm_1AntCoexProcessForWifiConnect(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv;
- struct hal_data_8723a *pHalData;
- struct bt_coexist_8723a *pBtCoex;
- struct btdm_8723a_1ant *pBtdm8723;
- u8 BtState;
-
- pmlmepriv = &padapter->mlmepriv;
- pHalData = GET_HAL_DATA(padapter);
- pBtCoex = &pHalData->bt_coexist.halCoex8723;
- pBtdm8723 = &pBtCoex->btdm1Ant;
- BtState = pBtCoex->c2hBtInfo;
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], WiFi is %s\n",
- BTDM_IsWifiBusy(padapter)?"Busy":"IDLE"));
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT is %s\n",
- BtStateString[BtState]));
-
- padapter->pwrctrlpriv.btcoex_rfon = false;
-
- if (!BTDM_IsWifiBusy(padapter) &&
- !check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) &&
- (BtState == BT_INFO_STATE_NO_CONNECTION ||
- BtState == BT_INFO_STATE_CONNECT_IDLE)) {
- switch (BtState) {
- case BT_INFO_STATE_NO_CONNECTION:
- _btdm_1AntSetPSTDMA(padapter, true, 2, 0x26, false, 9);
- break;
- case BT_INFO_STATE_CONNECT_IDLE:
- _btdm_1AntSetPSTDMA(padapter, true, 2, 0x26, false, 0);
- break;
- }
- } else {
- switch (BtState) {
- case BT_INFO_STATE_NO_CONNECTION:
- case BT_INFO_STATE_CONNECT_IDLE:
- /* WiFi is Busy */
- btdm_1AntSetPSTDMA(padapter, false, 0, true, 5);
- rtl8723au_write32(padapter, 0x6c0, 0x5a5a5a5a);
- rtl8723au_write32(padapter, 0x6c4, 0x5a5a5a5a);
- break;
- case BT_INFO_STATE_ACL_INQ_OR_PAG:
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], BT PROFILE is "
- "BT_INFO_STATE_ACL_INQ_OR_PAG\n"));
- case BT_INFO_STATE_INQ_OR_PAG:
- padapter->pwrctrlpriv.btcoex_rfon = true;
- btdm_1AntSetPSTDMA(padapter, true, 0, true, 30);
- break;
- case BT_INFO_STATE_SCO_ONLY_BUSY:
- case BT_INFO_STATE_ACL_SCO_BUSY:
- if (true == pBtCoex->bC2hBtInquiryPage)
- btdm_1AntSetPSTDMA(padapter, false, 0,
- true, 32);
- else {
-#ifdef BTCOEX_CMCC_TEST
- btdm_1AntSetPSTDMA(padapter, false, 0,
- true, 23);
-#else /* !BTCOEX_CMCC_TEST */
- btdm_1AntSetPSTDMA(padapter, false, 0,
- false, 8);
- rtl8723au_write32(padapter, 0x6c0, 0x5a5a5a5a);
- rtl8723au_write32(padapter, 0x6c4, 0x5a5a5a5a);
-#endif /* !BTCOEX_CMCC_TEST */
- }
- break;
- case BT_INFO_STATE_ACL_ONLY_BUSY:
- padapter->pwrctrlpriv.btcoex_rfon = true;
- if (pBtCoex->c2hBtProfile == BT_INFO_HID) {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], BT PROFILE is HID\n"));
- btdm_1AntSetPSTDMA(padapter, true, 0, true, 31);
- } else if (pBtCoex->c2hBtProfile == BT_INFO_FTP) {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], BT PROFILE is FTP/OPP\n"));
- btdm_1AntSetPSTDMA(padapter, true, 0, true, 3);
- } else if (pBtCoex->c2hBtProfile == (BT_INFO_A2DP|BT_INFO_FTP)) {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], BT PROFILE is A2DP_FTP\n"));
- btdm_1AntSetPSTDMA(padapter, true, 0, true, 11);
- } else {
- if (pBtCoex->c2hBtProfile == BT_INFO_A2DP)
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], BT PROFILE is "
- "A2DP\n"));
- else
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], BT PROFILE is "
- "UNKNOWN(0x%02X)! Use A2DP "
- "Profile\n",
- pBtCoex->c2hBtProfile));
- btdm_1AntTdmaDurationAdjustForACL(padapter);
- }
- break;
- }
- }
-
- pBtdm8723->psTdmaGlobalCnt++;
-}
-
-static void
-btdm_1AntUpdateHalRAMask(struct rtw_adapter *padapter, u32 mac_id, u32 filter)
-{
- u8 init_rate = 0;
- u8 raid, arg;
- u32 mask;
- u8 shortGIrate = false;
- int supportRateNum = 0;
- struct sta_info *psta;
- struct hal_data_8723a *pHalData;
- struct dm_priv *pdmpriv;
- struct mlme_ext_priv *pmlmeext;
- struct mlme_ext_info *pmlmeinfo;
- struct wlan_bssid_ex *cur_network;
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, MACID =%d, filter = 0x%08x!!\n",
- __func__, mac_id, filter));
-
- pHalData = GET_HAL_DATA(padapter);
- pdmpriv = &pHalData->dmpriv;
- pmlmeext = &padapter->mlmeextpriv;
- pmlmeinfo = &pmlmeext->mlmext_info;
- cur_network = &pmlmeinfo->network;
-
- if (mac_id >= NUM_STA) { /* CAM_SIZE */
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, MACID =%d illegal!!\n",
- __func__, mac_id));
- return;
- }
-
- psta = pmlmeinfo->FW_sta_info[mac_id].psta;
- if (!psta) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, Can't find station!!\n",
- __func__));
- return;
- }
-
- raid = psta->raid;
-
- switch (mac_id) {
- case 0:/* for infra mode */
- supportRateNum =
- rtw_get_rateset_len23a(cur_network->SupportedRates);
- mask = update_supported_rate23a(cur_network->SupportedRates,
- supportRateNum);
- mask |= (pmlmeinfo->HT_enable) ?
- update_MSC_rate23a(&pmlmeinfo->ht_cap):0;
- if (support_short_GI23a(padapter, &pmlmeinfo->ht_cap))
- shortGIrate = true;
- break;
- case 1:/* for broadcast/multicast */
- supportRateNum = rtw_get_rateset_len23a(
- pmlmeinfo->FW_sta_info[mac_id].SupportedRates);
- mask = update_basic_rate23a(cur_network->SupportedRates,
- supportRateNum);
- break;
- default: /* for each sta in IBSS */
- supportRateNum = rtw_get_rateset_len23a(
- pmlmeinfo->FW_sta_info[mac_id].SupportedRates);
- mask = update_supported_rate23a(cur_network->SupportedRates,
- supportRateNum);
- break;
- }
- mask |= ((raid<<28)&0xf0000000);
- mask &= 0xffffffff;
- mask &= ~filter;
- init_rate = get_highest_rate_idx23a(mask)&0x3f;
-
- arg = mac_id&0x1f;/* MACID */
- arg |= BIT(7);
- if (true == shortGIrate)
- arg |= BIT(5);
-
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], Update FW RAID entry, MASK = 0x%08x, "
- "arg = 0x%02x\n", mask, arg));
-
- rtl8723a_set_raid_cmd(padapter, mask, arg);
-
- psta->init_rate = init_rate;
- pdmpriv->INIDATA_RATE[mac_id] = init_rate;
-}
-
-static void
-btdm_1AntUpdateHalRAMaskForSCO(struct rtw_adapter *padapter, u8 forceUpdate)
-{
- struct btdm_8723a_1ant *pBtdm8723;
- struct sta_priv *pstapriv;
- struct wlan_bssid_ex *cur_network;
- struct sta_info *psta;
- u32 macid;
- u32 filter = 0;
-
- pBtdm8723 = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant;
-
- if (pBtdm8723->bRAChanged == true && forceUpdate == false)
- return;
-
- pstapriv = &padapter->stapriv;
- cur_network = &padapter->mlmeextpriv.mlmext_info.network;
- psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
- macid = psta->mac_id;
-
- filter |= BIT(_1M_RATE_);
- filter |= BIT(_2M_RATE_);
- filter |= BIT(_5M_RATE_);
- filter |= BIT(_11M_RATE_);
- filter |= BIT(_6M_RATE_);
- filter |= BIT(_9M_RATE_);
-
- btdm_1AntUpdateHalRAMask(padapter, macid, filter);
-
- pBtdm8723->bRAChanged = true;
-}
-
-static void btdm_1AntRecoverHalRAMask(struct rtw_adapter *padapter)
-{
- struct btdm_8723a_1ant *pBtdm8723;
- struct sta_priv *pstapriv;
- struct wlan_bssid_ex *cur_network;
- struct sta_info *psta;
-
- pBtdm8723 = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant;
-
- if (pBtdm8723->bRAChanged == false)
- return;
-
- pstapriv = &padapter->stapriv;
- cur_network = &padapter->mlmeextpriv.mlmext_info.network;
- psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
-
- Update_RA_Entry23a(padapter, psta);
-
- pBtdm8723->bRAChanged = false;
-}
-
-static void
-btdm_1AntBTStateChangeHandler(struct rtw_adapter *padapter,
- enum bt_state_1ant oldState,
- enum bt_state_1ant newState)
-{
- struct hal_data_8723a *phaldata;
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT state change, %s => %s\n",
- BtStateString[oldState],
- BtStateString[newState]));
-
- /* BT default ignore wlan active, */
- /* WiFi MUST disable this when BT is enable */
- if (newState > BT_INFO_STATE_DISABLED)
- btdm_SetFwIgnoreWlanAct(padapter, false);
-
- if ((check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) &&
- (BTDM_IsWifiConnectionExist(padapter))) {
- if ((newState == BT_INFO_STATE_SCO_ONLY_BUSY) ||
- (newState == BT_INFO_STATE_ACL_SCO_BUSY)) {
- btdm_1AntUpdateHalRAMaskForSCO(padapter, false);
- } else {
- /* Recover original RA setting */
- btdm_1AntRecoverHalRAMask(padapter);
- }
- } else {
- phaldata = GET_HAL_DATA(padapter);
- phaldata->bt_coexist.halCoex8723.btdm1Ant.bRAChanged = false;
- }
-
- if (oldState == newState)
- return;
-
- if (oldState == BT_INFO_STATE_ACL_ONLY_BUSY) {
- struct hal_data_8723a *Hal = GET_HAL_DATA(padapter);
- Hal->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCnt = 0;
- Hal->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCntForSCO = 0;
- }
-
- if ((oldState == BT_INFO_STATE_SCO_ONLY_BUSY) ||
- (oldState == BT_INFO_STATE_ACL_SCO_BUSY)) {
- struct hal_data_8723a *Hal = GET_HAL_DATA(padapter);
- Hal->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCntForSCO = 0;
- }
-
- /* Active 2Ant mechanism when BT Connected */
- if ((oldState == BT_INFO_STATE_DISABLED) ||
- (oldState == BT_INFO_STATE_NO_CONNECTION)) {
- if ((newState != BT_INFO_STATE_DISABLED) &&
- (newState != BT_INFO_STATE_NO_CONNECTION)) {
- BTDM_SetSwRfRxLpfCorner(padapter,
- BT_RF_RX_LPF_CORNER_SHRINK);
- BTDM_AGCTable(padapter, BT_AGCTABLE_ON);
- BTDM_BBBackOffLevel(padapter, BT_BB_BACKOFF_ON);
- }
- } else {
- if ((newState == BT_INFO_STATE_DISABLED) ||
- (newState == BT_INFO_STATE_NO_CONNECTION)) {
- BTDM_SetSwRfRxLpfCorner(padapter,
- BT_RF_RX_LPF_CORNER_RESUME);
- BTDM_AGCTable(padapter, BT_AGCTABLE_OFF);
- BTDM_BBBackOffLevel(padapter, BT_BB_BACKOFF_OFF);
- }
- }
-}
-
-static void btdm_1AntBtCoexistHandler(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct bt_coexist_8723a *pBtCoex8723;
- struct btdm_8723a_1ant *pBtdm8723;
-
- pHalData = GET_HAL_DATA(padapter);
- pBtCoex8723 = &pHalData->bt_coexist.halCoex8723;
- pBtdm8723 = &pBtCoex8723->btdm1Ant;
- padapter->pwrctrlpriv.btcoex_rfon = false;
- if (!rtl8723a_BT_enabled(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT is disabled\n"));
-
- if (BTDM_IsWifiConnectionExist(padapter)) {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], wifi is connected\n"));
-
- if (BTDM_IsWifiBusy(padapter)) {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], Wifi is busy\n"));
- btdm_1AntSetPSTDMA(padapter, false, 0,
- false, 9);
- } else {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], Wifi is idle\n"));
- _btdm_1AntSetPSTDMA(padapter, true, 2, 1,
- false, 9);
- }
- } else {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], wifi is disconnected\n"));
-
- btdm_1AntSetPSTDMA(padapter, false, 0, false, 9);
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT is enabled\n"));
-
- if (BTDM_IsWifiConnectionExist(padapter)) {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], wifi is connected\n"));
-
- btdm_1AntWifiParaAdjust(padapter, true);
- btdm_1AntCoexProcessForWifiConnect(padapter);
- } else {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], wifi is disconnected\n"));
-
- /* Antenna switch at BT side(0x870 = 0x300,
- 0x860 = 0x210) after PSTDMA off */
- btdm_1AntWifiParaAdjust(padapter, false);
- btdm_1AntSetPSTDMA(padapter, false, 0, false, 0);
- }
- }
-
- btdm_1AntBTStateChangeHandler(padapter, pBtCoex8723->prec2hBtInfo,
- pBtCoex8723->c2hBtInfo);
- pBtCoex8723->prec2hBtInfo = pBtCoex8723->c2hBtInfo;
-}
-
-void BTDM_1AntSignalCompensation(struct rtw_adapter *padapter,
- u8 *rssi_wifi, u8 *rssi_bt)
-{
- struct hal_data_8723a *pHalData;
- struct btdm_8723a_1ant *pBtdm8723;
- u8 RSSI_WiFi_Cmpnstn, RSSI_BT_Cmpnstn;
-
- pHalData = GET_HAL_DATA(padapter);
- pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
- RSSI_WiFi_Cmpnstn = 0;
- RSSI_BT_Cmpnstn = 0;
-
- switch (pBtdm8723->curPsTdma) {
- case 1: /* WiFi 52ms */
- RSSI_WiFi_Cmpnstn = 11; /* 22*0.48 */
- break;
- case 2: /* WiFi 36ms */
- RSSI_WiFi_Cmpnstn = 14; /* 22*0.64 */
- break;
- case 9: /* WiFi 20ms */
- RSSI_WiFi_Cmpnstn = 18; /* 22*0.80 */
- break;
- case 11: /* WiFi 10ms */
- RSSI_WiFi_Cmpnstn = 20; /* 22*0.90 */
- break;
- case 4: /* WiFi 21ms */
- RSSI_WiFi_Cmpnstn = 17; /* 22*0.79 */
- break;
- case 16: /* WiFi 24ms */
- RSSI_WiFi_Cmpnstn = 18; /* 22*0.76 */
- break;
- case 18: /* WiFi 37ms */
- RSSI_WiFi_Cmpnstn = 14; /* 22*0.64 */
- break;
- case 23: /* Level-1, Antenna switch to BT at all time */
- case 24: /* Level-2, Antenna switch to BT at all time */
- case 25: /* Level-3a, Antenna switch to BT at all time */
- case 26: /* Level-3b, Antenna switch to BT at all time */
- case 27: /* Level-3b, Antenna switch to BT at all time */
- case 33: /* BT SCO & WiFi site survey */
- RSSI_WiFi_Cmpnstn = 22;
- break;
- default:
- break;
- }
-
- if (rssi_wifi && RSSI_WiFi_Cmpnstn) {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], 1AntSgnlCmpnstn, case %d, WiFiCmpnstn "
- "=%d(%d => %d)\n", pBtdm8723->curPsTdma,
- RSSI_WiFi_Cmpnstn, *rssi_wifi,
- *rssi_wifi+RSSI_WiFi_Cmpnstn));
- *rssi_wifi += RSSI_WiFi_Cmpnstn;
- }
-
- if (rssi_bt && RSSI_BT_Cmpnstn) {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], 1AntSgnlCmpnstn, case %d, BTCmpnstn "
- "=%d(%d => %d)\n", pBtdm8723->curPsTdma,
- RSSI_BT_Cmpnstn, *rssi_bt, *rssi_bt+RSSI_BT_Cmpnstn));
- *rssi_bt += RSSI_BT_Cmpnstn;
- }
-}
-
-static void BTDM_1AntParaInit(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct bt_coexist_8723a *pBtCoex;
- struct btdm_8723a_1ant *pBtdm8723;
-
- pHalData = GET_HAL_DATA(padapter);
- pBtCoex = &pHalData->bt_coexist.halCoex8723;
- pBtdm8723 = &pBtCoex->btdm1Ant;
-
- /* Enable counter statistics */
- rtl8723au_write8(padapter, 0x76e, 0x4);
- btdm_1AntPtaParaReload(padapter);
-
- pBtdm8723->wifiRssiThresh = 48;
-
- pBtdm8723->bWiFiHalt = false;
- pBtdm8723->bRAChanged = false;
-
- if ((pBtCoex->c2hBtInfo != BT_INFO_STATE_DISABLED) &&
- (pBtCoex->c2hBtInfo != BT_INFO_STATE_NO_CONNECTION)) {
- BTDM_SetSwRfRxLpfCorner(padapter, BT_RF_RX_LPF_CORNER_SHRINK);
- BTDM_AGCTable(padapter, BT_AGCTABLE_ON);
- BTDM_BBBackOffLevel(padapter, BT_BB_BACKOFF_ON);
- }
-}
-
-static void BTDM_1AntForHalt(struct rtw_adapter *padapter)
-{
- RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for halt\n"));
-
- GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant.bWiFiHalt =
- true;
-
- btdm_1AntWifiParaAdjust(padapter, false);
-
- /* don't use btdm_1AntSetPSTDMA() here */
- /* it will call rtw_set_ps_mode23a() and request pwrpriv->lock. */
- /* This will lead to deadlock, if this function is called in IPS */
- /* Lucas@20130205 */
- btdm_1AntPsTdma(padapter, false, 0);
-
- btdm_SetFwIgnoreWlanAct(padapter, true);
-}
-
-static void BTDM_1AntLpsLeave(struct rtw_adapter *padapter)
-{
- RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for LPS Leave\n"));
-
- /* Prevent from entering LPS again */
- GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant.bWiFiHalt =
- true;
-
- btdm_1AntSetPSTDMA(padapter, false, 0, false, 8);
-/*btdm_1AntPsTdma(padapter, false, 8); */
-}
-
-static void BTDM_1AntWifiAssociateNotify(struct rtw_adapter *padapter, u8 type)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- RTPRINT(FBT, BT_TRACE,
- ("\n[BTCoex], 1Ant for associate, type =%d\n", type));
-
- if (type) {
- rtl8723a_CheckAntenna_Selection(padapter);
- if (!rtl8723a_BT_enabled(padapter))
- btdm_1AntSetPSTDMA(padapter, false, 0, false, 9);
- else {
- struct bt_coexist_8723a *pBtCoex;
- u8 BtState;
-
- pBtCoex = &pHalData->bt_coexist.halCoex8723;
- BtState = pBtCoex->c2hBtInfo;
-
- btdm_1AntTSFSwitch(padapter, true);
-
- if (BtState == BT_INFO_STATE_NO_CONNECTION ||
- BtState == BT_INFO_STATE_CONNECT_IDLE) {
- btdm_1AntSetPSTDMA(padapter, false, 0,
- true, 28);
- } else if (BtState == BT_INFO_STATE_SCO_ONLY_BUSY ||
- BtState == BT_INFO_STATE_ACL_SCO_BUSY) {
- btdm_1AntSetPSTDMA(padapter, false, 0,
- false, 8);
- rtl8723au_write32(padapter, 0x6c0, 0x5a5a5a5a);
- rtl8723au_write32(padapter, 0x6c4, 0x5a5a5a5a);
- } else if (BtState == BT_INFO_STATE_ACL_ONLY_BUSY ||
- BtState == BT_INFO_STATE_ACL_INQ_OR_PAG) {
- if (pBtCoex->c2hBtProfile == BT_INFO_HID)
- btdm_1AntSetPSTDMA(padapter, false, 0,
- true, 35);
- else
- btdm_1AntSetPSTDMA(padapter, false, 0,
- true, 29);
- }
- }
- } else {
- if (!rtl8723a_BT_enabled(padapter)) {
- if (!BTDM_IsWifiConnectionExist(padapter)) {
- btdm_1AntPsTdma(padapter, false, 0);
- btdm_1AntTSFSwitch(padapter, false);
- }
- }
-
- btdm_1AntBtCoexistHandler(padapter);
- }
-}
-
-static void
-BTDM_1AntMediaStatusNotify(struct rtw_adapter *padapter,
- enum rt_media_status mstatus)
-{
- struct bt_coexist_8723a *pBtCoex;
-
- pBtCoex = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723;
-
- RTPRINT(FBT, BT_TRACE,
- ("\n\n[BTCoex]******************************\n"));
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], MediaStatus, WiFi %s !!\n",
- mstatus == RT_MEDIA_CONNECT?"CONNECT":"DISCONNECT"));
- RTPRINT(FBT, BT_TRACE, ("[BTCoex]******************************\n"));
-
- if (RT_MEDIA_CONNECT == mstatus) {
- if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) {
- if (pBtCoex->c2hBtInfo == BT_INFO_STATE_SCO_ONLY_BUSY ||
- pBtCoex->c2hBtInfo == BT_INFO_STATE_ACL_SCO_BUSY)
- btdm_1AntUpdateHalRAMaskForSCO(padapter, true);
- }
-
- padapter->pwrctrlpriv.DelayLPSLastTimeStamp = jiffies;
- BTDM_1AntForDhcp(padapter);
- } else {
- /* DBG_8723A("%s rtl8723a_DeinitAntenna_Selection\n",
- __func__); */
- rtl8723a_DeinitAntenna_Selection(padapter);
- btdm_1AntBtCoexistHandler(padapter);
- pBtCoex->btdm1Ant.bRAChanged = false;
- }
-}
-
-void BTDM_1AntForDhcp(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- u8 BtState;
- struct bt_coexist_8723a *pBtCoex;
- struct btdm_8723a_1ant *pBtdm8723;
-
- pHalData = GET_HAL_DATA(padapter);
- pBtCoex = &pHalData->bt_coexist.halCoex8723;
- BtState = pBtCoex->c2hBtInfo;
- pBtdm8723 = &pBtCoex->btdm1Ant;
-
- RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for DHCP\n"));
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for DHCP, WiFi is %s\n",
- BTDM_IsWifiBusy(padapter)?"Busy":"IDLE"));
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for DHCP, %s\n",
- BtStateString[BtState]));
-
- BTDM_1AntWifiAssociateNotify(padapter, true);
-}
-
-static void BTDM_1AntWifiScanNotify(struct rtw_adapter *padapter, u8 scanType)
-{
- struct hal_data_8723a *pHalData;
- u8 BtState;
- struct bt_coexist_8723a *pBtCoex;
- struct btdm_8723a_1ant *pBtdm8723;
-
- pHalData = GET_HAL_DATA(padapter);
- BtState = pHalData->bt_coexist.halCoex8723.c2hBtInfo;
- pBtCoex = &pHalData->bt_coexist.halCoex8723;
- pBtdm8723 = &pBtCoex->btdm1Ant;
-
- RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for wifi scan =%d!!\n",
- scanType));
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for wifi scan, WiFi is %s\n",
- BTDM_IsWifiBusy(padapter)?"Busy":"IDLE"));
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for wifi scan, %s\n",
- BtStateString[BtState]));
-
- if (scanType) {
- rtl8723a_CheckAntenna_Selection(padapter);
- if (!rtl8723a_BT_enabled(padapter)) {
- btdm_1AntSetPSTDMA(padapter, false, 0, false, 9);
- } else if (BTDM_IsWifiConnectionExist(padapter) == false) {
- BTDM_1AntWifiAssociateNotify(padapter, true);
- } else {
- if ((BtState == BT_INFO_STATE_SCO_ONLY_BUSY) ||
- (BtState == BT_INFO_STATE_ACL_SCO_BUSY)) {
- if (pBtCoex->bC2hBtInquiryPage) {
- btdm_1AntSetPSTDMA(padapter, false, 0,
- true, 32);
- } else {
- padapter->pwrctrlpriv.btcoex_rfon =
- true;
- btdm_1AntSetPSTDMA(padapter, true, 0,
- true, 33);
- }
- } else if (true == pBtCoex->bC2hBtInquiryPage) {
- padapter->pwrctrlpriv.btcoex_rfon = true;
- btdm_1AntSetPSTDMA(padapter, true, 0, true, 30);
- } else if (BtState == BT_INFO_STATE_ACL_ONLY_BUSY) {
- padapter->pwrctrlpriv.btcoex_rfon = true;
- if (pBtCoex->c2hBtProfile == BT_INFO_HID)
- btdm_1AntSetPSTDMA(padapter, true, 0,
- true, 34);
- else
- btdm_1AntSetPSTDMA(padapter, true, 0,
- true, 4);
- } else {
- padapter->pwrctrlpriv.btcoex_rfon = true;
- btdm_1AntSetPSTDMA(padapter, true, 0, true, 5);
- }
- }
-
- btdm_NotifyFwScan(padapter, 1);
- } else {
- /* WiFi_Finish_Scan */
- btdm_NotifyFwScan(padapter, 0);
- btdm_1AntBtCoexistHandler(padapter);
- }
-}
-
-static void BTDM_1AntFwC2hBtInfo8723A(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct bt_30info *pBTInfo;
- struct bt_mgnt *pBtMgnt;
- struct bt_coexist_8723a *pBtCoex;
- u8 u1tmp, btState;
-
- pHalData = GET_HAL_DATA(padapter);
- pBTInfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTInfo->BtMgnt;
- pBtCoex = &pHalData->bt_coexist.halCoex8723;
-
- u1tmp = pBtCoex->c2hBtInfoOriginal;
- /* sco BUSY bit is not used on voice over PCM platform */
- btState = u1tmp & 0xF;
- pBtCoex->c2hBtProfile = u1tmp & 0xE0;
-
- /* default set bt to idle state. */
- pBtMgnt->ExtConfig.bBTBusy = false;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_IDLE;
-
- /* check BIT2 first ==> check if bt is under inquiry or page scan */
- if (btState & BIT(2))
- pBtCoex->bC2hBtInquiryPage = true;
- else
- pBtCoex->bC2hBtInquiryPage = false;
- btState &= ~BIT(2);
-
- if (!(btState & BIT(0)))
- pBtCoex->c2hBtInfo = BT_INFO_STATE_NO_CONNECTION;
- else {
- if (btState == 0x1)
- pBtCoex->c2hBtInfo = BT_INFO_STATE_CONNECT_IDLE;
- else if (btState == 0x9) {
- if (pBtCoex->bC2hBtInquiryPage == true)
- pBtCoex->c2hBtInfo =
- BT_INFO_STATE_ACL_INQ_OR_PAG;
- else
- pBtCoex->c2hBtInfo =
- BT_INFO_STATE_ACL_ONLY_BUSY;
- pBtMgnt->ExtConfig.bBTBusy = true;
- } else if (btState == 0x3) {
- pBtCoex->c2hBtInfo = BT_INFO_STATE_SCO_ONLY_BUSY;
- pBtMgnt->ExtConfig.bBTBusy = true;
- } else if (btState == 0xb) {
- pBtCoex->c2hBtInfo = BT_INFO_STATE_ACL_SCO_BUSY;
- pBtMgnt->ExtConfig.bBTBusy = true;
- } else
- pBtCoex->c2hBtInfo = BT_INFO_STATE_MAX;
- if (pBtMgnt->ExtConfig.bBTBusy)
- pHalData->bt_coexist.CurrentState &=
- ~BT_COEX_STATE_BT_IDLE;
- }
-
- if (BT_INFO_STATE_NO_CONNECTION == pBtCoex->c2hBtInfo ||
- BT_INFO_STATE_CONNECT_IDLE == pBtCoex->c2hBtInfo) {
- if (pBtCoex->bC2hBtInquiryPage)
- pBtCoex->c2hBtInfo = BT_INFO_STATE_INQ_OR_PAG;
- }
-
- RTPRINT(FBT, BT_TRACE, ("[BTC2H], %s(%d)\n",
- BtStateString[pBtCoex->c2hBtInfo], pBtCoex->c2hBtInfo));
-
- if (pBtCoex->c2hBtProfile != BT_INFO_HID)
- pBtCoex->c2hBtProfile &= ~BT_INFO_HID;
-}
-
-void BTDM_1AntBtCoexist8723A(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv;
- struct hal_data_8723a *pHalData;
- unsigned long delta_time;
-
- pmlmepriv = &padapter->mlmepriv;
- pHalData = GET_HAL_DATA(padapter);
-
- if (check_fwstate(pmlmepriv, WIFI_SITE_MONITOR)) {
- /* already done in BTDM_1AntForScan() */
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], wifi is under scan progress!!\n"));
- return;
- }
-
- if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], wifi is under link progress!!\n"));
- return;
- }
-
- /* under DHCP(Special packet) */
- delta_time = jiffies - padapter->pwrctrlpriv.DelayLPSLastTimeStamp;
- delta_time = jiffies_to_msecs(delta_time);
- if (delta_time < 500) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], wifi is under DHCP "
- "progress(%li ms)!!\n", delta_time));
- return;
- }
-
- BTDM_CheckWiFiState(padapter);
-
- btdm_1AntBtCoexistHandler(padapter);
-}
-
-/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87231Ant.c ===== */
-
-/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc87232Ant.c ===== */
-
-/* local function start with btdm_ */
-static u8 btdm_ActionAlgorithm(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
- u8 bScoExist = false, bBtLinkExist = false, bBtHsModeExist = false;
- u8 algorithm = BT_2ANT_COEX_ALGO_UNDEFINED;
-
- if (pBtMgnt->ExtConfig.NumberOfHandle)
- bBtLinkExist = true;
- if (pBtMgnt->ExtConfig.NumberOfSCO)
- bScoExist = true;
- if (BT_HsConnectionEstablished(padapter))
- bBtHsModeExist = true;
-
- /* here we get BT status first */
- /* 1) initialize */
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_IDLE;
-
- if ((bScoExist) || (bBtHsModeExist) ||
- (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID))) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO or HID or HS exists, set BT non-idle !!!\n"));
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
- } else {
- /* A2dp profile */
- if ((pBtMgnt->ExtConfig.NumberOfHandle == 1) &&
- (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP))) {
- if (BTDM_BtTxRxCounterL(padapter) < 100) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP, low priority tx+rx < 100, set BT connected-idle!!!\n"));
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP, low priority tx+rx >= 100, set BT non-idle!!!\n"));
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
- }
- }
- /* Pan profile */
- if ((pBtMgnt->ExtConfig.NumberOfHandle == 1) &&
- (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN))) {
- if (BTDM_BtTxRxCounterL(padapter) < 600) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN, low priority tx+rx < 600, set BT connected-idle!!!\n"));
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
- } else {
- if (pHalData->bt_coexist.halCoex8723.lowPriorityTx) {
- if ((pHalData->bt_coexist.halCoex8723.lowPriorityRx /
- pHalData->bt_coexist.halCoex8723.lowPriorityTx) > 9) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN, low priority rx/tx > 9, set BT connected-idle!!!\n"));
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
- }
- }
- }
- if (BT_2ANT_BT_STATUS_CONNECTED_IDLE != pBtdm8723->btStatus) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN, set BT non-idle!!!\n"));
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
- }
- }
- /* Pan+A2dp profile */
- if ((pBtMgnt->ExtConfig.NumberOfHandle == 2) &&
- (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) &&
- (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN))) {
- if (BTDM_BtTxRxCounterL(padapter) < 600) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN+A2DP, low priority tx+rx < 600, set BT connected-idle!!!\n"));
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
- } else {
- if (pHalData->bt_coexist.halCoex8723.lowPriorityTx) {
- if ((pHalData->bt_coexist.halCoex8723.lowPriorityRx /
- pHalData->bt_coexist.halCoex8723.lowPriorityTx) > 9) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN+A2DP, low priority rx/tx > 9, set BT connected-idle!!!\n"));
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
- }
- }
- }
- if (BT_2ANT_BT_STATUS_CONNECTED_IDLE != pBtdm8723->btStatus) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN+A2DP, set BT non-idle!!!\n"));
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
- }
- }
- }
- if (BT_2ANT_BT_STATUS_IDLE != pBtdm8723->btStatus)
- pBtMgnt->ExtConfig.bBTBusy = true;
- else
- pBtMgnt->ExtConfig.bBTBusy = false;
-
- if (!bBtLinkExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], No profile exists!!!\n"));
- return algorithm;
- }
-
- if (pBtMgnt->ExtConfig.NumberOfHandle == 1) {
- if (bScoExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO only\n"));
- algorithm = BT_2ANT_COEX_ALGO_SCO;
- } else {
- if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID)) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID only\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID;
- } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP only\n"));
- algorithm = BT_2ANT_COEX_ALGO_A2DP;
- } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN(HS) only\n"));
- algorithm = BT_2ANT_COEX_ALGO_PANHS;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN(EDR) only\n"));
- algorithm = BT_2ANT_COEX_ALGO_PANEDR;
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d \n",
- pBtMgnt->ExtConfig.NumberOfHandle));
- }
- }
- } else if (pBtMgnt->ExtConfig.NumberOfHandle == 2) {
- if (bScoExist) {
- if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID)) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID;
- } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP\n"));
- } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(HS)\n"));
- algorithm = BT_2ANT_COEX_ALGO_SCO;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(EDR)\n"));
- algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO exists but why NO matched ACL profile for NumberOfHandle =%d\n",
- pBtMgnt->ExtConfig.NumberOfHandle));
- }
- } else {
- if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
- BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
- } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
- BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(HS)\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(EDR)\n"));
- algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
- }
- } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
- BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(HS)\n"));
- algorithm = BT_2ANT_COEX_ALGO_A2DP;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n"));
- algorithm = BT_2ANT_COEX_ALGO_PANEDR_A2DP;
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d\n",
- pBtMgnt->ExtConfig.NumberOfHandle));
- }
- }
- } else if (pBtMgnt->ExtConfig.NumberOfHandle == 3) {
- if (bScoExist) {
- if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
- BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP\n"));
- } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
- BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID + PAN(HS)\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID + PAN(EDR)\n"));
- algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
- }
- } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
- BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP + PAN(HS)\n"));
- algorithm = BT_2ANT_COEX_ALGO_SCO;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP + PAN(EDR)\n"));
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO exists but why NO matched profile for NumberOfHandle =%d\n",
- pBtMgnt->ExtConfig.NumberOfHandle));
- }
- } else {
- if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
- BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
- BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANHS;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d\n",
- pBtMgnt->ExtConfig.NumberOfHandle));
- }
- }
- } else if (pBtMgnt->ExtConfig.NumberOfHandle >= 3) {
- if (bScoExist) {
- if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
- BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
- BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
- if (bBtHsModeExist)
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n"));
- else
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(EDR)\n"));
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO exists but why NO matched profile for NumberOfHandle =%d\n",
- pBtMgnt->ExtConfig.NumberOfHandle));
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d\n",
- pBtMgnt->ExtConfig.NumberOfHandle));
- }
- }
- return algorithm;
-}
-
-static u8 btdm_NeedToDecBtPwr(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 bRet = false;
-
- if (BT_Operation(padapter)) {
- if (pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB > 47) {
- RTPRINT(FBT, BT_TRACE, ("Need to decrease bt power for HS mode!!\n"));
- bRet = true;
- } else {
- RTPRINT(FBT, BT_TRACE, ("NO Need to decrease bt power for HS mode!!\n"));
- }
- } else {
- if (BTDM_IsWifiConnectionExist(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("Need to decrease bt power for Wifi is connected!!\n"));
- bRet = true;
- }
- }
- return bRet;
-}
-
-static void
-btdm_SetCoexTable(struct rtw_adapter *padapter, u32 val0x6c0,
- u32 val0x6c8, u8 val0x6cc)
-{
- RTPRINT(FBT, BT_TRACE, ("set coex table, set 0x6c0 = 0x%x\n", val0x6c0));
- rtl8723au_write32(padapter, 0x6c0, val0x6c0);
-
- RTPRINT(FBT, BT_TRACE, ("set coex table, set 0x6c8 = 0x%x\n", val0x6c8));
- rtl8723au_write32(padapter, 0x6c8, val0x6c8);
-
- RTPRINT(FBT, BT_TRACE, ("set coex table, set 0x6cc = 0x%x\n", val0x6cc));
- rtl8723au_write8(padapter, 0x6cc, val0x6cc);
-}
-
-static void
-btdm_SetSwFullTimeDacSwing(struct rtw_adapter *padapter, u8 bSwDacSwingOn,
- u32 swDacSwingLvl)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (bSwDacSwingOn) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], SwDacSwing = 0x%x\n", swDacSwingLvl));
- PHY_SetBBReg(padapter, 0x880, 0xff000000, swDacSwingLvl);
- pHalData->bt_coexist.bSWCoexistAllOff = false;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], SwDacSwing Off!\n"));
- PHY_SetBBReg(padapter, 0x880, 0xff000000, 0xc0);
- }
-}
-
-static void
-btdm_SetFwDacSwingLevel(struct rtw_adapter *padapter, u8 dacSwingLvl)
-{
- u8 H2C_Parameter[1] = {0};
-
- H2C_Parameter[0] = dacSwingLvl;
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Set Dac Swing Level = 0x%x\n", dacSwingLvl));
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], write 0x29 = 0x%x\n", H2C_Parameter[0]));
-
- FillH2CCmd(padapter, 0x29, 1, H2C_Parameter);
-}
-
-static void btdm_2AntDecBtPwr(struct rtw_adapter *padapter, u8 bDecBtPwr)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
-
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], Dec BT power = %s\n",
- ((bDecBtPwr) ? "ON" : "OFF")));
- pBtdm8723->bCurDecBtPwr = bDecBtPwr;
-
- if (pBtdm8723->bPreDecBtPwr == pBtdm8723->bCurDecBtPwr)
- return;
-
- BTDM_SetFwDecBtPwr(padapter, pBtdm8723->bCurDecBtPwr);
-
- pBtdm8723->bPreDecBtPwr = pBtdm8723->bCurDecBtPwr;
-}
-
-static void
-btdm_2AntFwDacSwingLvl(struct rtw_adapter *padapter, u8 fwDacSwingLvl)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], set FW Dac Swing level = %d\n", fwDacSwingLvl));
- pBtdm8723->curFwDacSwingLvl = fwDacSwingLvl;
-
- /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], preFwDacSwingLvl =%d, curFwDacSwingLvl =%d\n", */
- /*pBtdm8723->preFwDacSwingLvl, pBtdm8723->curFwDacSwingLvl)); */
-
- if (pBtdm8723->preFwDacSwingLvl == pBtdm8723->curFwDacSwingLvl)
- return;
-
- btdm_SetFwDacSwingLevel(padapter, pBtdm8723->curFwDacSwingLvl);
-
- pBtdm8723->preFwDacSwingLvl = pBtdm8723->curFwDacSwingLvl;
-}
-
-static void
-btdm_2AntRfShrink(struct rtw_adapter *padapter, u8 bRxRfShrinkOn)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
-
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], turn Rx RF Shrink = %s\n",
- ((bRxRfShrinkOn) ? "ON" : "OFF")));
- pBtdm8723->bCurRfRxLpfShrink = bRxRfShrinkOn;
-
- /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], bPreRfRxLpfShrink =%d, bCurRfRxLpfShrink =%d\n", */
- /*pBtdm8723->bPreRfRxLpfShrink, pBtdm8723->bCurRfRxLpfShrink)); */
-
- if (pBtdm8723->bPreRfRxLpfShrink == pBtdm8723->bCurRfRxLpfShrink)
- return;
-
- BTDM_SetSwRfRxLpfCorner(padapter, (u8)pBtdm8723->bCurRfRxLpfShrink);
-
- pBtdm8723->bPreRfRxLpfShrink = pBtdm8723->bCurRfRxLpfShrink;
-}
-
-static void
-btdm_2AntLowPenaltyRa(struct rtw_adapter *padapter, u8 bLowPenaltyRa)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
-
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], turn LowPenaltyRA = %s\n",
- ((bLowPenaltyRa) ? "ON" : "OFF")));
- pBtdm8723->bCurLowPenaltyRa = bLowPenaltyRa;
-
- /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], bPreLowPenaltyRa =%d, bCurLowPenaltyRa =%d\n", */
- /*pBtdm8723->bPreLowPenaltyRa, pBtdm8723->bCurLowPenaltyRa)); */
-
- if (pBtdm8723->bPreLowPenaltyRa == pBtdm8723->bCurLowPenaltyRa)
- return;
-
- BTDM_SetSwPenaltyTxRateAdaptive(padapter, (u8)pBtdm8723->bCurLowPenaltyRa);
-
- pBtdm8723->bPreLowPenaltyRa = pBtdm8723->bCurLowPenaltyRa;
-}
-
-static void
-btdm_2AntDacSwing(struct rtw_adapter *padapter,
- u8 bDacSwingOn, u32 dacSwingLvl)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
-
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], turn DacSwing =%s, dacSwingLvl = 0x%x\n",
- (bDacSwingOn ? "ON" : "OFF"), dacSwingLvl));
- pBtdm8723->bCurDacSwingOn = bDacSwingOn;
- pBtdm8723->curDacSwingLvl = dacSwingLvl;
-
- if ((pBtdm8723->bPreDacSwingOn == pBtdm8723->bCurDacSwingOn) &&
- (pBtdm8723->preDacSwingLvl == pBtdm8723->curDacSwingLvl))
- return;
-
- mdelay(30);
- btdm_SetSwFullTimeDacSwing(padapter, bDacSwingOn, dacSwingLvl);
-
- pBtdm8723->bPreDacSwingOn = pBtdm8723->bCurDacSwingOn;
- pBtdm8723->preDacSwingLvl = pBtdm8723->curDacSwingLvl;
-}
-
-static void btdm_2AntAdcBackOff(struct rtw_adapter *padapter, u8 bAdcBackOff)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
-
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], turn AdcBackOff = %s\n",
- ((bAdcBackOff) ? "ON" : "OFF")));
- pBtdm8723->bCurAdcBackOff = bAdcBackOff;
-
- if (pBtdm8723->bPreAdcBackOff == pBtdm8723->bCurAdcBackOff)
- return;
-
- BTDM_BBBackOffLevel(padapter, (u8)pBtdm8723->bCurAdcBackOff);
-
- pBtdm8723->bPreAdcBackOff = pBtdm8723->bCurAdcBackOff;
-}
-
-static void btdm_2AntAgcTable(struct rtw_adapter *padapter, u8 bAgcTableEn)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
-
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], %s Agc Table\n", ((bAgcTableEn) ? "Enable" : "Disable")));
- pBtdm8723->bCurAgcTableEn = bAgcTableEn;
-
- /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], bPreAgcTableEn =%d, bCurAgcTableEn =%d\n", */
- /*pBtdm8723->bPreAgcTableEn, pBtdm8723->bCurAgcTableEn)); */
-
- if (pBtdm8723->bPreAgcTableEn == pBtdm8723->bCurAgcTableEn)
- return;
-
- BTDM_AGCTable(padapter, (u8)bAgcTableEn);
-
- pBtdm8723->bPreAgcTableEn = pBtdm8723->bCurAgcTableEn;
-}
-
-static void
-btdm_2AntCoexTable(struct rtw_adapter *padapter,
- u32 val0x6c0, u32 val0x6c8, u8 val0x6cc)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], write Coex Table 0x6c0 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n",
- val0x6c0, val0x6c8, val0x6cc));
- pBtdm8723->curVal0x6c0 = val0x6c0;
- pBtdm8723->curVal0x6c8 = val0x6c8;
- pBtdm8723->curVal0x6cc = val0x6cc;
-
- /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], preVal0x6c0 = 0x%x, preVal0x6c8 = 0x%x, preVal0x6cc = 0x%x !!\n", */
- /*pBtdm8723->preVal0x6c0, pBtdm8723->preVal0x6c8, pBtdm8723->preVal0x6cc)); */
- /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], curVal0x6c0 = 0x%x, curVal0x6c8 = 0x%x, curVal0x6cc = 0x%x !!\n", */
- /*pBtdm8723->curVal0x6c0, pBtdm8723->curVal0x6c8, pBtdm8723->curVal0x6cc)); */
-
- if ((pBtdm8723->preVal0x6c0 == pBtdm8723->curVal0x6c0) &&
- (pBtdm8723->preVal0x6c8 == pBtdm8723->curVal0x6c8) &&
- (pBtdm8723->preVal0x6cc == pBtdm8723->curVal0x6cc))
- return;
-
- btdm_SetCoexTable(padapter, val0x6c0, val0x6c8, val0x6cc);
-
- pBtdm8723->preVal0x6c0 = pBtdm8723->curVal0x6c0;
- pBtdm8723->preVal0x6c8 = pBtdm8723->curVal0x6c8;
- pBtdm8723->preVal0x6cc = pBtdm8723->curVal0x6cc;
-}
-
-static void btdm_2AntIgnoreWlanAct(struct rtw_adapter *padapter, u8 bEnable)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
-
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], turn Ignore WlanAct %s\n", (bEnable ? "ON" : "OFF")));
- pBtdm8723->bCurIgnoreWlanAct = bEnable;
-
-
- if (pBtdm8723->bPreIgnoreWlanAct == pBtdm8723->bCurIgnoreWlanAct)
- return;
-
- btdm_SetFwIgnoreWlanAct(padapter, bEnable);
- pBtdm8723->bPreIgnoreWlanAct = pBtdm8723->bCurIgnoreWlanAct;
-}
-
-static void
-btdm_2AntSetFw3a(struct rtw_adapter *padapter, u8 byte1, u8 byte2,
- u8 byte3, u8 byte4, u8 byte5)
-{
- u8 H2C_Parameter[5] = {0};
-
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- /* byte1[1:0] != 0 means enable pstdma */
- /* for 2Ant bt coexist, if byte1 != 0 means enable pstdma */
- if (byte1)
- pHalData->bt_coexist.bFWCoexistAllOff = false;
- H2C_Parameter[0] = byte1;
- H2C_Parameter[1] = byte2;
- H2C_Parameter[2] = byte3;
- H2C_Parameter[3] = byte4;
- H2C_Parameter[4] = byte5;
-
- pHalData->bt_coexist.fw3aVal[0] = byte1;
- pHalData->bt_coexist.fw3aVal[1] = byte2;
- pHalData->bt_coexist.fw3aVal[2] = byte3;
- pHalData->bt_coexist.fw3aVal[3] = byte4;
- pHalData->bt_coexist.fw3aVal[4] = byte5;
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], FW write 0x3a(5bytes) = 0x%x%08x\n",
- H2C_Parameter[0],
- H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4]));
-
- FillH2CCmd(padapter, 0x3a, 5, H2C_Parameter);
- }
-
-static void btdm_2AntPsTdma(struct rtw_adapter *padapter, u8 bTurnOn, u8 type)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
- u32 btTxRxCnt = 0;
- u8 bTurnOnByCnt = false;
- u8 psTdmaTypeByCnt = 0;
-
- btTxRxCnt = BTDM_BtTxRxCounterH(padapter)+BTDM_BtTxRxCounterL(padapter);
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT TxRx Counters = %d\n", btTxRxCnt));
- if (btTxRxCnt > 3000) {
- bTurnOnByCnt = true;
- psTdmaTypeByCnt = 8;
-
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], For BTTxRxCounters, turn %s PS TDMA, type =%d\n",
- (bTurnOnByCnt ? "ON" : "OFF"), psTdmaTypeByCnt));
- pBtdm8723->bCurPsTdmaOn = bTurnOnByCnt;
- pBtdm8723->curPsTdma = psTdmaTypeByCnt;
- } else {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], turn %s PS TDMA, type =%d\n",
- (bTurnOn ? "ON" : "OFF"), type));
- pBtdm8723->bCurPsTdmaOn = bTurnOn;
- pBtdm8723->curPsTdma = type;
- }
-
- if ((pBtdm8723->bPrePsTdmaOn == pBtdm8723->bCurPsTdmaOn) &&
- (pBtdm8723->prePsTdma == pBtdm8723->curPsTdma))
- return;
-
- if (bTurnOn) {
- switch (type) {
- case 1:
- default:
- btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0xa1, 0x98);
- break;
- case 2:
- btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0xa1, 0x98);
- break;
- case 3:
- btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0xa1, 0x98);
- break;
- case 4:
- btdm_2AntSetFw3a(padapter, 0xa3, 0x5, 0x5, 0xa1, 0x80);
- break;
- case 5:
- btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0x20, 0x98);
- break;
- case 6:
- btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0x20, 0x98);
- break;
- case 7:
- btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0x20, 0x98);
- break;
- case 8:
- btdm_2AntSetFw3a(padapter, 0xa3, 0x5, 0x5, 0x20, 0x80);
- break;
- case 9:
- btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0xa1, 0x98);
- break;
- case 10:
- btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0xa1, 0x98);
- break;
- case 11:
- btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0xa1, 0x98);
- break;
- case 12:
- btdm_2AntSetFw3a(padapter, 0xe3, 0x5, 0x5, 0xa1, 0x98);
- break;
- case 13:
- btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0x20, 0x98);
- break;
- case 14:
- btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0x20, 0x98);
- break;
- case 15:
- btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0x20, 0x98);
- break;
- case 16:
- btdm_2AntSetFw3a(padapter, 0xe3, 0x5, 0x5, 0x20, 0x98);
- break;
- case 17:
- btdm_2AntSetFw3a(padapter, 0xa3, 0x2f, 0x2f, 0x20, 0x80);
- break;
- case 18:
- btdm_2AntSetFw3a(padapter, 0xe3, 0x5, 0x5, 0xa1, 0x98);
- break;
- case 19:
- btdm_2AntSetFw3a(padapter, 0xe3, 0x25, 0x25, 0xa1, 0x98);
- break;
- case 20:
- btdm_2AntSetFw3a(padapter, 0xe3, 0x25, 0x25, 0x20, 0x98);
- break;
- }
- } else {
- /* disable PS tdma */
- switch (type) {
- case 0:
- btdm_2AntSetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0);
- break;
- case 1:
- btdm_2AntSetFw3a(padapter, 0x0, 0x0, 0x0, 0x0, 0x0);
- break;
- default:
- btdm_2AntSetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0);
- break;
- }
- }
-
- /* update pre state */
- pBtdm8723->bPrePsTdmaOn = pBtdm8723->bCurPsTdmaOn;
- pBtdm8723->prePsTdma = pBtdm8723->curPsTdma;
-}
-
-static void btdm_2AntBtInquiryPage(struct rtw_adapter *padapter)
-{
- btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
- btdm_2AntIgnoreWlanAct(padapter, false);
- btdm_2AntPsTdma(padapter, true, 8);
-}
-
-static u8 btdm_HoldForBtInqPage(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u32 curTime = jiffies;
-
- if (pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage) {
- /* bt inquiry or page is started. */
- if (pHalData->bt_coexist.halCoex8723.btInqPageStartTime == 0) {
- pHalData->bt_coexist.halCoex8723.btInqPageStartTime = curTime;
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Inquiry/page is started at time : 0x%lx \n",
- pHalData->bt_coexist.halCoex8723.btInqPageStartTime));
- }
- }
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Inquiry/page started time : 0x%lx, curTime : 0x%x \n",
- pHalData->bt_coexist.halCoex8723.btInqPageStartTime, curTime));
-
- if (pHalData->bt_coexist.halCoex8723.btInqPageStartTime) {
- if (((curTime - pHalData->bt_coexist.halCoex8723.btInqPageStartTime)/1000000) >= 10) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Inquiry/page >= 10sec!!!"));
- pHalData->bt_coexist.halCoex8723.btInqPageStartTime = 0;
- }
- }
-
- if (pHalData->bt_coexist.halCoex8723.btInqPageStartTime) {
- btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
- btdm_2AntIgnoreWlanAct(padapter, false);
- btdm_2AntPsTdma(padapter, true, 8);
- return true;
- } else {
- return false;
- }
-}
-
-static u8 btdm_Is2Ant8723ACommonAction(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
- u8 bCommon = false;
-
- RTPRINT(FBT, BT_TRACE, ("%s :BTDM_IsWifiConnectionExist =%x check_fwstate =%x pmlmepriv->fw_state = 0x%x\n", __func__, BTDM_IsWifiConnectionExist(padapter), check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)), padapter->mlmepriv.fw_state));
-
- if ((!BTDM_IsWifiConnectionExist(padapter)) &&
- (!check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) &&
- (BT_2ANT_BT_STATUS_IDLE == pBtdm8723->btStatus)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi idle + Bt idle!!\n"));
-
- btdm_2AntLowPenaltyRa(padapter, false);
- btdm_2AntRfShrink(padapter, false);
- btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
-
- btdm_2AntIgnoreWlanAct(padapter, false);
- btdm_2AntPsTdma(padapter, false, 0);
- btdm_2AntFwDacSwingLvl(padapter, 0x20);
- btdm_2AntDecBtPwr(padapter, false);
-
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
-
- bCommon = true;
- } else if (((BTDM_IsWifiConnectionExist(padapter)) ||
- (check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)))) &&
- (BT_2ANT_BT_STATUS_IDLE == pBtdm8723->btStatus)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi non-idle + BT idle!!\n"));
-
- btdm_2AntLowPenaltyRa(padapter, true);
- btdm_2AntRfShrink(padapter, false);
- btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
-
- btdm_2AntIgnoreWlanAct(padapter, false);
- btdm_2AntPsTdma(padapter, false, 0);
- btdm_2AntFwDacSwingLvl(padapter, 0x20);
- btdm_2AntDecBtPwr(padapter, true);
-
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
-
- bCommon = true;
- } else if ((!BTDM_IsWifiConnectionExist(padapter)) &&
- (!check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) &&
- (BT_2ANT_BT_STATUS_CONNECTED_IDLE == pBtdm8723->btStatus)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi idle + Bt connected idle!!\n"));
-
- btdm_2AntLowPenaltyRa(padapter, true);
- btdm_2AntRfShrink(padapter, true);
- btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
-
- btdm_2AntIgnoreWlanAct(padapter, false);
- btdm_2AntPsTdma(padapter, false, 0);
- btdm_2AntFwDacSwingLvl(padapter, 0x20);
- btdm_2AntDecBtPwr(padapter, false);
-
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
-
- bCommon = true;
- } else if (((BTDM_IsWifiConnectionExist(padapter)) ||
- (check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)))) &&
- (BT_2ANT_BT_STATUS_CONNECTED_IDLE == pBtdm8723->btStatus)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi non-idle + Bt connected idle!!\n"));
-
- btdm_2AntLowPenaltyRa(padapter, true);
- btdm_2AntRfShrink(padapter, true);
- btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
-
- btdm_2AntIgnoreWlanAct(padapter, false);
- btdm_2AntPsTdma(padapter, false, 0);
- btdm_2AntFwDacSwingLvl(padapter, 0x20);
- btdm_2AntDecBtPwr(padapter, true);
-
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
-
- bCommon = true;
- } else if ((!BTDM_IsWifiConnectionExist(padapter)) &&
- (!check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) &&
- (BT_2ANT_BT_STATUS_NON_IDLE == pBtdm8723->btStatus)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi idle + BT non-idle!!\n"));
-
- btdm_2AntLowPenaltyRa(padapter, true);
- btdm_2AntRfShrink(padapter, true);
- btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
-
- btdm_2AntIgnoreWlanAct(padapter, false);
- btdm_2AntPsTdma(padapter, false, 0);
- btdm_2AntFwDacSwingLvl(padapter, 0x20);
- btdm_2AntDecBtPwr(padapter, false);
-
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
-
- bCommon = true;
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi non-idle + BT non-idle!!\n"));
- btdm_2AntLowPenaltyRa(padapter, true);
- btdm_2AntRfShrink(padapter, true);
- btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
- btdm_2AntIgnoreWlanAct(padapter, false);
- btdm_2AntFwDacSwingLvl(padapter, 0x20);
-
- bCommon = false;
- }
- return bCommon;
-}
-
-static void
-btdm_2AntTdmaDurationAdjust(struct rtw_adapter *padapter, u8 bScoHid,
- u8 bTxPause, u8 maxInterval)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
- static s32 up, dn, m, n, WaitCount;
- s32 result; /* 0: no change, +1: increase WiFi duration, -1: decrease WiFi duration */
- u8 retryCount = 0;
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], TdmaDurationAdjust()\n"));
-
- if (pBtdm8723->bResetTdmaAdjust) {
- pBtdm8723->bResetTdmaAdjust = false;
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n"));
- if (bScoHid) {
- if (bTxPause) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- }
- } else {
- if (bTxPause) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- }
- }
- up = 0;
- dn = 0;
- m = 1;
- n = 3;
- result = 0;
- WaitCount = 0;
- } else {
- /* accquire the BT TRx retry count from BT_Info byte2 */
- retryCount = pHalData->bt_coexist.halCoex8723.btRetryCnt;
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], retryCount = %d\n", retryCount));
- result = 0;
- WaitCount++;
-
- if (retryCount == 0) { /* no retry in the last 2-second duration */
- up++;
- dn--;
-
- if (dn <= 0)
- dn = 0;
-
- if (up >= n) { /* if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration */
- WaitCount = 0;
- n = 3;
- up = 0;
- dn = 0;
- result = 1;
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Increase wifi duration!!\n"));
- }
- } else if (retryCount <= 3) { /* <= 3 retry in the last 2-second duration */
- up--;
- dn++;
-
- if (up <= 0)
- up = 0;
-
- if (dn == 2) { /* if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration */
- if (WaitCount <= 2)
- m++; /* ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ */
- else
- m = 1;
-
- if (m >= 20) /* m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. */
- m = 20;
-
- n = 3*m;
- up = 0;
- dn = 0;
- WaitCount = 0;
- result = -1;
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n"));
- }
- } else { /* retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration */
- if (WaitCount == 1)
- m++; /* ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ */
- else
- m = 1;
-
- if (m >= 20) /* m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. */
- m = 20;
- n = 3*m;
- up = 0;
- dn = 0;
- WaitCount = 0;
- result = -1;
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n"));
- }
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], max Interval = %d\n", maxInterval));
- if (maxInterval == 1) {
- if (bTxPause) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 1\n"));
- if (pBtdm8723->curPsTdma == 1) {
- btdm_2AntPsTdma(padapter, true, 5);
- pBtdm8723->psTdmaDuAdjType = 5;
- } else if (pBtdm8723->curPsTdma == 2) {
- btdm_2AntPsTdma(padapter, true, 6);
- pBtdm8723->psTdmaDuAdjType = 6;
- } else if (pBtdm8723->curPsTdma == 3) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 4) {
- btdm_2AntPsTdma(padapter, true, 8);
- pBtdm8723->psTdmaDuAdjType = 8;
- }
- if (pBtdm8723->curPsTdma == 9) {
- btdm_2AntPsTdma(padapter, true, 13);
- pBtdm8723->psTdmaDuAdjType = 13;
- } else if (pBtdm8723->curPsTdma == 10) {
- btdm_2AntPsTdma(padapter, true, 14);
- pBtdm8723->psTdmaDuAdjType = 14;
- } else if (pBtdm8723->curPsTdma == 11) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else if (pBtdm8723->curPsTdma == 12) {
- btdm_2AntPsTdma(padapter, true, 16);
- pBtdm8723->psTdmaDuAdjType = 16;
- }
-
- if (result == -1) {
- if (pBtdm8723->curPsTdma == 5) {
- btdm_2AntPsTdma(padapter, true, 6);
- pBtdm8723->psTdmaDuAdjType = 6;
- } else if (pBtdm8723->curPsTdma == 6) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 7) {
- btdm_2AntPsTdma(padapter, true, 8);
- pBtdm8723->psTdmaDuAdjType = 8;
- } else if (pBtdm8723->curPsTdma == 13) {
- btdm_2AntPsTdma(padapter, true, 14);
- pBtdm8723->psTdmaDuAdjType = 14;
- } else if (pBtdm8723->curPsTdma == 14) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else if (pBtdm8723->curPsTdma == 15) {
- btdm_2AntPsTdma(padapter, true, 16);
- pBtdm8723->psTdmaDuAdjType = 16;
- }
- } else if (result == 1) {
- if (pBtdm8723->curPsTdma == 8) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 7) {
- btdm_2AntPsTdma(padapter, true, 6);
- pBtdm8723->psTdmaDuAdjType = 6;
- } else if (pBtdm8723->curPsTdma == 6) {
- btdm_2AntPsTdma(padapter, true, 5);
- pBtdm8723->psTdmaDuAdjType = 5;
- } else if (pBtdm8723->curPsTdma == 16) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else if (pBtdm8723->curPsTdma == 15) {
- btdm_2AntPsTdma(padapter, true, 14);
- pBtdm8723->psTdmaDuAdjType = 14;
- } else if (pBtdm8723->curPsTdma == 14) {
- btdm_2AntPsTdma(padapter, true, 13);
- pBtdm8723->psTdmaDuAdjType = 13;
- }
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 0\n"));
- if (pBtdm8723->curPsTdma == 5) {
- btdm_2AntPsTdma(padapter, true, 1);
- pBtdm8723->psTdmaDuAdjType = 1;
- } else if (pBtdm8723->curPsTdma == 6) {
- btdm_2AntPsTdma(padapter, true, 2);
- pBtdm8723->psTdmaDuAdjType = 2;
- } else if (pBtdm8723->curPsTdma == 7) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 8) {
- btdm_2AntPsTdma(padapter, true, 4);
- pBtdm8723->psTdmaDuAdjType = 4;
- }
- if (pBtdm8723->curPsTdma == 13) {
- btdm_2AntPsTdma(padapter, true, 9);
- pBtdm8723->psTdmaDuAdjType = 9;
- } else if (pBtdm8723->curPsTdma == 14) {
- btdm_2AntPsTdma(padapter, true, 10);
- pBtdm8723->psTdmaDuAdjType = 10;
- } else if (pBtdm8723->curPsTdma == 15) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- } else if (pBtdm8723->curPsTdma == 16) {
- btdm_2AntPsTdma(padapter, true, 12);
- pBtdm8723->psTdmaDuAdjType = 12;
- }
-
- if (result == -1) {
- if (pBtdm8723->curPsTdma == 1) {
- btdm_2AntPsTdma(padapter, true, 2);
- pBtdm8723->psTdmaDuAdjType = 2;
- } else if (pBtdm8723->curPsTdma == 2) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 3) {
- btdm_2AntPsTdma(padapter, true, 4);
- pBtdm8723->psTdmaDuAdjType = 4;
- } else if (pBtdm8723->curPsTdma == 9) {
- btdm_2AntPsTdma(padapter, true, 10);
- pBtdm8723->psTdmaDuAdjType = 10;
- } else if (pBtdm8723->curPsTdma == 10) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- } else if (pBtdm8723->curPsTdma == 11) {
- btdm_2AntPsTdma(padapter, true, 12);
- pBtdm8723->psTdmaDuAdjType = 12;
- }
- } else if (result == 1) {
- if (pBtdm8723->curPsTdma == 4) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 3) {
- btdm_2AntPsTdma(padapter, true, 2);
- pBtdm8723->psTdmaDuAdjType = 2;
- } else if (pBtdm8723->curPsTdma == 2) {
- btdm_2AntPsTdma(padapter, true, 1);
- pBtdm8723->psTdmaDuAdjType = 1;
- } else if (pBtdm8723->curPsTdma == 12) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- } else if (pBtdm8723->curPsTdma == 11) {
- btdm_2AntPsTdma(padapter, true, 10);
- pBtdm8723->psTdmaDuAdjType = 10;
- } else if (pBtdm8723->curPsTdma == 10) {
- btdm_2AntPsTdma(padapter, true, 9);
- pBtdm8723->psTdmaDuAdjType = 9;
- }
- }
- }
- } else if (maxInterval == 2) {
- if (bTxPause) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 1\n"));
- if (pBtdm8723->curPsTdma == 1) {
- btdm_2AntPsTdma(padapter, true, 6);
- pBtdm8723->psTdmaDuAdjType = 6;
- } else if (pBtdm8723->curPsTdma == 2) {
- btdm_2AntPsTdma(padapter, true, 6);
- pBtdm8723->psTdmaDuAdjType = 6;
- } else if (pBtdm8723->curPsTdma == 3) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 4) {
- btdm_2AntPsTdma(padapter, true, 8);
- pBtdm8723->psTdmaDuAdjType = 8;
- }
- if (pBtdm8723->curPsTdma == 9) {
- btdm_2AntPsTdma(padapter, true, 14);
- pBtdm8723->psTdmaDuAdjType = 14;
- } else if (pBtdm8723->curPsTdma == 10) {
- btdm_2AntPsTdma(padapter, true, 14);
- pBtdm8723->psTdmaDuAdjType = 14;
- } else if (pBtdm8723->curPsTdma == 11) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else if (pBtdm8723->curPsTdma == 12) {
- btdm_2AntPsTdma(padapter, true, 16);
- pBtdm8723->psTdmaDuAdjType = 16;
- }
- if (result == -1) {
- if (pBtdm8723->curPsTdma == 5) {
- btdm_2AntPsTdma(padapter, true, 6);
- pBtdm8723->psTdmaDuAdjType = 6;
- } else if (pBtdm8723->curPsTdma == 6) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 7) {
- btdm_2AntPsTdma(padapter, true, 8);
- pBtdm8723->psTdmaDuAdjType = 8;
- } else if (pBtdm8723->curPsTdma == 13) {
- btdm_2AntPsTdma(padapter, true, 14);
- pBtdm8723->psTdmaDuAdjType = 14;
- } else if (pBtdm8723->curPsTdma == 14) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else if (pBtdm8723->curPsTdma == 15) {
- btdm_2AntPsTdma(padapter, true, 16);
- pBtdm8723->psTdmaDuAdjType = 16;
- }
- } else if (result == 1) {
- if (pBtdm8723->curPsTdma == 8) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 7) {
- btdm_2AntPsTdma(padapter, true, 6);
- pBtdm8723->psTdmaDuAdjType = 6;
- } else if (pBtdm8723->curPsTdma == 6) {
- btdm_2AntPsTdma(padapter, true, 6);
- pBtdm8723->psTdmaDuAdjType = 6;
- } else if (pBtdm8723->curPsTdma == 16) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else if (pBtdm8723->curPsTdma == 15) {
- btdm_2AntPsTdma(padapter, true, 14);
- pBtdm8723->psTdmaDuAdjType = 14;
- } else if (pBtdm8723->curPsTdma == 14) {
- btdm_2AntPsTdma(padapter, true, 14);
- pBtdm8723->psTdmaDuAdjType = 14;
- }
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 0\n"));
- if (pBtdm8723->curPsTdma == 5) {
- btdm_2AntPsTdma(padapter, true, 2);
- pBtdm8723->psTdmaDuAdjType = 2;
- } else if (pBtdm8723->curPsTdma == 6) {
- btdm_2AntPsTdma(padapter, true, 2);
- pBtdm8723->psTdmaDuAdjType = 2;
- } else if (pBtdm8723->curPsTdma == 7) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 8) {
- btdm_2AntPsTdma(padapter, true, 4);
- pBtdm8723->psTdmaDuAdjType = 4;
- }
- if (pBtdm8723->curPsTdma == 13) {
- btdm_2AntPsTdma(padapter, true, 10);
- pBtdm8723->psTdmaDuAdjType = 10;
- } else if (pBtdm8723->curPsTdma == 14) {
- btdm_2AntPsTdma(padapter, true, 10);
- pBtdm8723->psTdmaDuAdjType = 10;
- } else if (pBtdm8723->curPsTdma == 15) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- } else if (pBtdm8723->curPsTdma == 16) {
- btdm_2AntPsTdma(padapter, true, 12);
- pBtdm8723->psTdmaDuAdjType = 12;
- }
- if (result == -1) {
- if (pBtdm8723->curPsTdma == 1) {
- btdm_2AntPsTdma(padapter, true, 2);
- pBtdm8723->psTdmaDuAdjType = 2;
- } else if (pBtdm8723->curPsTdma == 2) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 3) {
- btdm_2AntPsTdma(padapter, true, 4);
- pBtdm8723->psTdmaDuAdjType = 4;
- } else if (pBtdm8723->curPsTdma == 9) {
- btdm_2AntPsTdma(padapter, true, 10);
- pBtdm8723->psTdmaDuAdjType = 10;
- } else if (pBtdm8723->curPsTdma == 10) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- } else if (pBtdm8723->curPsTdma == 11) {
- btdm_2AntPsTdma(padapter, true, 12);
- pBtdm8723->psTdmaDuAdjType = 12;
- }
- } else if (result == 1) {
- if (pBtdm8723->curPsTdma == 4) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 3) {
- btdm_2AntPsTdma(padapter, true, 2);
- pBtdm8723->psTdmaDuAdjType = 2;
- } else if (pBtdm8723->curPsTdma == 2) {
- btdm_2AntPsTdma(padapter, true, 2);
- pBtdm8723->psTdmaDuAdjType = 2;
- } else if (pBtdm8723->curPsTdma == 12) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- } else if (pBtdm8723->curPsTdma == 11) {
- btdm_2AntPsTdma(padapter, true, 10);
- pBtdm8723->psTdmaDuAdjType = 10;
- } else if (pBtdm8723->curPsTdma == 10) {
- btdm_2AntPsTdma(padapter, true, 10);
- pBtdm8723->psTdmaDuAdjType = 10;
- }
- }
- }
- } else if (maxInterval == 3) {
- if (bTxPause) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 1\n"));
- if (pBtdm8723->curPsTdma == 1) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 2) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 3) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 4) {
- btdm_2AntPsTdma(padapter, true, 8);
- pBtdm8723->psTdmaDuAdjType = 8;
- }
- if (pBtdm8723->curPsTdma == 9) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else if (pBtdm8723->curPsTdma == 10) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else if (pBtdm8723->curPsTdma == 11) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else if (pBtdm8723->curPsTdma == 12) {
- btdm_2AntPsTdma(padapter, true, 16);
- pBtdm8723->psTdmaDuAdjType = 16;
- }
- if (result == -1) {
- if (pBtdm8723->curPsTdma == 5) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 6) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 7) {
- btdm_2AntPsTdma(padapter, true, 8);
- pBtdm8723->psTdmaDuAdjType = 8;
- } else if (pBtdm8723->curPsTdma == 13) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else if (pBtdm8723->curPsTdma == 14) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else if (pBtdm8723->curPsTdma == 15) {
- btdm_2AntPsTdma(padapter, true, 16);
- pBtdm8723->psTdmaDuAdjType = 16;
- }
- } else if (result == 1) {
- if (pBtdm8723->curPsTdma == 8) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 7) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 6) {
- btdm_2AntPsTdma(padapter, true, 7);
- pBtdm8723->psTdmaDuAdjType = 7;
- } else if (pBtdm8723->curPsTdma == 16) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else if (pBtdm8723->curPsTdma == 15) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- } else if (pBtdm8723->curPsTdma == 14) {
- btdm_2AntPsTdma(padapter, true, 15);
- pBtdm8723->psTdmaDuAdjType = 15;
- }
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 0\n"));
- if (pBtdm8723->curPsTdma == 5) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 6) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 7) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 8) {
- btdm_2AntPsTdma(padapter, true, 4);
- pBtdm8723->psTdmaDuAdjType = 4;
- }
- if (pBtdm8723->curPsTdma == 13) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- } else if (pBtdm8723->curPsTdma == 14) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- } else if (pBtdm8723->curPsTdma == 15) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- } else if (pBtdm8723->curPsTdma == 16) {
- btdm_2AntPsTdma(padapter, true, 12);
- pBtdm8723->psTdmaDuAdjType = 12;
- }
- if (result == -1) {
- if (pBtdm8723->curPsTdma == 1) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 2) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 3) {
- btdm_2AntPsTdma(padapter, true, 4);
- pBtdm8723->psTdmaDuAdjType = 4;
- } else if (pBtdm8723->curPsTdma == 9) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- } else if (pBtdm8723->curPsTdma == 10) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- } else if (pBtdm8723->curPsTdma == 11) {
- btdm_2AntPsTdma(padapter, true, 12);
- pBtdm8723->psTdmaDuAdjType = 12;
- }
- } else if (result == 1) {
- if (pBtdm8723->curPsTdma == 4) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 3) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 2) {
- btdm_2AntPsTdma(padapter, true, 3);
- pBtdm8723->psTdmaDuAdjType = 3;
- } else if (pBtdm8723->curPsTdma == 12) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- } else if (pBtdm8723->curPsTdma == 11) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- } else if (pBtdm8723->curPsTdma == 10) {
- btdm_2AntPsTdma(padapter, true, 11);
- pBtdm8723->psTdmaDuAdjType = 11;
- }
- }
- }
- }
- }
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], PsTdma type : recordPsTdma =%d\n", pBtdm8723->psTdmaDuAdjType));
- /* if current PsTdma not match with the recorded one (when scan, dhcp...), */
- /* then we have to adjust it back to the previous record one. */
- if (pBtdm8723->curPsTdma != pBtdm8723->psTdmaDuAdjType) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], PsTdma type dismatch!!!, curPsTdma =%d, recordPsTdma =%d\n",
- pBtdm8723->curPsTdma, pBtdm8723->psTdmaDuAdjType));
-
- if (!check_fwstate(&padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING))
- btdm_2AntPsTdma(padapter, true, pBtdm8723->psTdmaDuAdjType);
- else
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n"));
- }
-}
-
-/* default Action */
-/* SCO only or SCO+PAN(HS) */
-static void btdm_2Ant8723ASCOAction(struct rtw_adapter *padapter)
-{
- u8 btRssiState, btRssiState1;
-
- if (btdm_NeedToDecBtPwr(padapter))
- btdm_2AntDecBtPwr(padapter, true);
- else
- btdm_2AntDecBtPwr(padapter, false);
-
- if (BTDM_IsHT40(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("HT40\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
- /* fw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
- btdm_2AntPsTdma(padapter, true, 11);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
- btdm_2AntPsTdma(padapter, true, 15);
- }
-
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
- btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
-
- /* fw mechanism */
- if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
- (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
- btdm_2AntPsTdma(padapter, true, 11);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
- btdm_2AntPsTdma(padapter, true, 15);
- }
-
- /* sw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- btdm_2AntAgcTable(padapter, true);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- }
- }
-}
-
-static void btdm_2Ant8723AHIDAction(struct rtw_adapter *padapter)
-{
- u8 btRssiState, btRssiState1;
-
- if (btdm_NeedToDecBtPwr(padapter))
- btdm_2AntDecBtPwr(padapter, true);
- else
- btdm_2AntDecBtPwr(padapter, false);
-
- if (BTDM_IsHT40(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("HT40\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
- /* fw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
- btdm_2AntPsTdma(padapter, true, 9);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
- btdm_2AntPsTdma(padapter, true, 13);
- }
-
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
- btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
-
- /* fw mechanism */
- if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
- (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
- btdm_2AntPsTdma(padapter, true, 9);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
- btdm_2AntPsTdma(padapter, true, 13);
- }
-
- /* sw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- btdm_2AntAgcTable(padapter, true);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- }
- }
-}
-
-/* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
-static void btdm_2Ant8723AA2DPAction(struct rtw_adapter *padapter)
-{
- u8 btRssiState, btRssiState1;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
-
- if (btdm_NeedToDecBtPwr(padapter))
- btdm_2AntDecBtPwr(padapter, true);
- else
- btdm_2AntDecBtPwr(padapter, false);
-
- if (BTDM_IsHT40(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("HT40\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
-
- /* fw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
-
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, false, false, 3);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, false, false, 1);
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, false, true, 3);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, false, true, 1);
- }
- }
-
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
- btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
-
- /* fw mechanism */
- if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
- (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, false, false, 3);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, false, false, 1);
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, false, true, 3);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, false, true, 1);
- }
- }
-
- /* sw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- btdm_2AntAgcTable(padapter, true);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- }
- }
-}
-
-static void btdm_2Ant8723APANEDRAction(struct rtw_adapter *padapter)
-{
- u8 btRssiState, btRssiState1;
-
- if (btdm_NeedToDecBtPwr(padapter))
- btdm_2AntDecBtPwr(padapter, true);
- else
- btdm_2AntDecBtPwr(padapter, false);
-
- if (BTDM_IsHT40(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("HT40\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
-
- /* fw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
- btdm_2AntPsTdma(padapter, true, 2);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- btdm_2AntPsTdma(padapter, true, 6);
- }
-
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
- btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
-
- /* fw mechanism */
- if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
- (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
- btdm_2AntPsTdma(padapter, true, 2);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
- btdm_2AntPsTdma(padapter, true, 6);
- }
-
- /* sw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- btdm_2AntAgcTable(padapter, true);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- }
- }
-}
-
-/* PAN(HS) only */
-static void btdm_2Ant8723APANHSAction(struct rtw_adapter *padapter)
-{
- u8 btRssiState;
-
- if (BTDM_IsHT40(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("HT40\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 47, 0);
- /* fw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- btdm_2AntDecBtPwr(padapter, true);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- btdm_2AntDecBtPwr(padapter, false);
- }
- btdm_2AntPsTdma(padapter, false, 0);
-
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 47, 0);
-
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high\n"));
- /* fw mechanism */
- btdm_2AntDecBtPwr(padapter, true);
- btdm_2AntPsTdma(padapter, false, 0);
-
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, true);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low\n"));
- /* fw mechanism */
- btdm_2AntDecBtPwr(padapter, false);
- btdm_2AntPsTdma(padapter, false, 0);
-
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- }
- }
-}
-
-/* PAN(EDR)+A2DP */
-static void btdm_2Ant8723APANEDRA2DPAction(struct rtw_adapter *padapter)
-{
- u8 btRssiState, btRssiState1, btInfoExt;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
-
- if (btdm_NeedToDecBtPwr(padapter))
- btdm_2AntDecBtPwr(padapter, true);
- else
- btdm_2AntDecBtPwr(padapter, false);
-
- if (BTDM_IsHT40(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("HT40\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
-
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- /* fw mechanism */
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
-
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntPsTdma(padapter, true, 4);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntPsTdma(padapter, true, 2);
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- /* fw mechanism */
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntPsTdma(padapter, true, 8);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntPsTdma(padapter, true, 6);
- }
- }
-
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
- btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
-
- if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
- (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
- /* fw mechanism */
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntPsTdma(padapter, true, 4);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntPsTdma(padapter, true, 2);
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
- /* fw mechanism */
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntPsTdma(padapter, true, 8);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntPsTdma(padapter, true, 6);
- }
- }
-
- /* sw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- btdm_2AntAgcTable(padapter, true);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- }
- }
-}
-
-static void btdm_2Ant8723APANEDRHIDAction(struct rtw_adapter *padapter)
-{
- u8 btRssiState, btRssiState1;
-
- if (btdm_NeedToDecBtPwr(padapter))
- btdm_2AntDecBtPwr(padapter, true);
- else
- btdm_2AntDecBtPwr(padapter, false);
-
- if (BTDM_IsHT40(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("HT40\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
- /* fw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
- btdm_2AntPsTdma(padapter, true, 10);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- btdm_2AntPsTdma(padapter, true, 14);
- }
-
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
- btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
-
- /* fw mechanism */
- if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
- (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
- btdm_2AntPsTdma(padapter, true, 10);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
- btdm_2AntPsTdma(padapter, true, 14);
- }
-
- /* sw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- btdm_2AntAgcTable(padapter, true);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- }
- }
-}
-
-/* HID+A2DP+PAN(EDR) */
-static void btdm_2Ant8723AHIDA2DPPANEDRAction(struct rtw_adapter *padapter)
-{
- u8 btRssiState, btRssiState1, btInfoExt;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
-
- if (btdm_NeedToDecBtPwr(padapter))
- btdm_2AntDecBtPwr(padapter, true);
- else
- btdm_2AntDecBtPwr(padapter, false);
-
- if (BTDM_IsHT40(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("HT40\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
-
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntPsTdma(padapter, true, 12);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntPsTdma(padapter, true, 10);
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntPsTdma(padapter, true, 16);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntPsTdma(padapter, true, 14);
- }
- }
-
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
- btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 37, 0);
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 27, 0);
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
-
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntPsTdma(padapter, true, 12);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntPsTdma(padapter, true, 10);
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntPsTdma(padapter, true, 16);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntPsTdma(padapter, true, 14);
- }
- }
-
- /* sw mechanism */
- if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
- (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
- btdm_2AntAgcTable(padapter, true);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- }
- }
-}
-
-static void btdm_2Ant8723AHIDA2DPAction(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 btRssiState, btRssiState1, btInfoExt;
-
- btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
-
- if (btdm_NeedToDecBtPwr(padapter))
- btdm_2AntDecBtPwr(padapter, true);
- else
- btdm_2AntDecBtPwr(padapter, false);
-
- if (BTDM_IsHT40(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("HT40\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
-
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, true, false, 3);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, true, false, 1);
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, true, true, 3);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, true, true, 1);
- }
- }
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
- btRssiState1 = BTDM_CheckCoexRSSIState(padapter, 2, 27, 0);
-
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
-
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, true, false, 3);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, true, false, 1);
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
- RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, true, true, 3);
- } else {
- RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
- btdm_2AntTdmaDurationAdjust(padapter, true, true, 1);
- }
- }
- if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
- (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, true);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- }
- }
-}
-
-static void btdm_2Ant8723AA2dp(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 btRssiState, btRssiState1, btInfoExt;
-
- btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
-
- if (btdm_NeedToDecBtPwr(padapter))
- btdm_2AntDecBtPwr(padapter, true);
- else
- btdm_2AntDecBtPwr(padapter, false);
- /* coex table */
- btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
- btdm_2AntIgnoreWlanAct(padapter, false);
-
- if (BTDM_IsHT40(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("HT40\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
- /* fw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
- btdm_2AntTdmaDurationAdjust(padapter, false, false, 1);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
- btdm_2AntTdmaDurationAdjust(padapter, false, true, 1);
- }
-
- /* sw mechanism */
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
- btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 47, 0);
- btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
-
- /* fw mechanism */
- if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
- (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
- PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
- btdm_2AntTdmaDurationAdjust(padapter, false, false, 1);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
- btdm_2AntTdmaDurationAdjust(padapter, false, true, 1);
- }
-
- /* sw mechanism */
- if ((btRssiState == BT_RSSI_STATE_HIGH) ||
- (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
- btdm_2AntAgcTable(padapter, true);
- btdm_2AntAdcBackOff(padapter, true);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- } else {
- RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
- }
- }
-}
-
-/* extern function start with BTDM_ */
-static void BTDM_2AntParaInit(struct rtw_adapter *padapter)
-{
-
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], 2Ant Parameter Init!!\n"));
-
- /* Enable counter statistics */
- rtl8723au_write8(padapter, 0x76e, 0x4);
- rtl8723au_write8(padapter, 0x778, 0x3);
- rtl8723au_write8(padapter, 0x40, 0x20);
-
- /* force to reset coex mechanism */
- pBtdm8723->preVal0x6c0 = 0x0;
- btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
-
- pBtdm8723->bPrePsTdmaOn = true;
- btdm_2AntPsTdma(padapter, false, 0);
-
- pBtdm8723->preFwDacSwingLvl = 0x10;
- btdm_2AntFwDacSwingLvl(padapter, 0x20);
-
- pBtdm8723->bPreDecBtPwr = true;
- btdm_2AntDecBtPwr(padapter, false);
-
- pBtdm8723->bPreAgcTableEn = true;
- btdm_2AntAgcTable(padapter, false);
-
- pBtdm8723->bPreAdcBackOff = true;
- btdm_2AntAdcBackOff(padapter, false);
-
- pBtdm8723->bPreLowPenaltyRa = true;
- btdm_2AntLowPenaltyRa(padapter, false);
-
- pBtdm8723->bPreRfRxLpfShrink = true;
- btdm_2AntRfShrink(padapter, false);
-
- pBtdm8723->bPreDacSwingOn = true;
- btdm_2AntDacSwing(padapter, false, 0xc0);
-
- pBtdm8723->bPreIgnoreWlanAct = true;
- btdm_2AntIgnoreWlanAct(padapter, false);
-}
-
-static void BTDM_2AntHwCoexAllOff8723A(struct rtw_adapter *padapter)
-{
- btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
-}
-
-static void BTDM_2AntFwCoexAllOff8723A(struct rtw_adapter *padapter)
-{
- btdm_2AntIgnoreWlanAct(padapter, false);
- btdm_2AntPsTdma(padapter, false, 0);
- btdm_2AntFwDacSwingLvl(padapter, 0x20);
- btdm_2AntDecBtPwr(padapter, false);
-}
-
-static void BTDM_2AntSwCoexAllOff8723A(struct rtw_adapter *padapter)
-{
- btdm_2AntAgcTable(padapter, false);
- btdm_2AntAdcBackOff(padapter, false);
- btdm_2AntLowPenaltyRa(padapter, false);
- btdm_2AntRfShrink(padapter, false);
- btdm_2AntDacSwing(padapter, false, 0xc0);
-}
-
-static void BTDM_2AntFwC2hBtInfo8723A(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
- u8 btInfo = 0;
- u8 algorithm = BT_2ANT_COEX_ALGO_UNDEFINED;
- u8 bBtLinkExist = false, bBtHsModeExist = false;
-
- btInfo = pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal;
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_IDLE;
-
- /* check BIT2 first ==> check if bt is under inquiry or page scan */
- if (btInfo & BIT(2)) {
- if (!pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage) {
- pBtMgnt->ExtConfig.bHoldForBtOperation = true;
- pBtMgnt->ExtConfig.bHoldPeriodCnt = 1;
- btdm_2AntBtInquiryPage(padapter);
- } else {
- pBtMgnt->ExtConfig.bHoldPeriodCnt++;
- btdm_HoldForBtInqPage(padapter);
- }
- pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage = true;
-
- } else {
- pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage = false;
- pBtMgnt->ExtConfig.bHoldForBtOperation = false;
- pBtMgnt->ExtConfig.bHoldPeriodCnt = 0;
-
- }
- RTPRINT(FBT, BT_TRACE,
- ("[BTC2H], pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage =%x pBtMgnt->ExtConfig.bHoldPeriodCnt =%x pBtMgnt->ExtConfig.bHoldForBtOperation =%x\n",
- pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage,
- pBtMgnt->ExtConfig.bHoldPeriodCnt,
- pBtMgnt->ExtConfig.bHoldForBtOperation));
-
- RTPRINT(FBT, BT_TRACE,
- ("[BTC2H], btInfo =%x pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal =%x\n",
- btInfo, pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal));
- if (btInfo&BT_INFO_ACL) {
- RTPRINT(FBT, BT_TRACE, ("[BTC2H], BTInfo: bConnect = true btInfo =%x\n", btInfo));
- bBtLinkExist = true;
- if (((btInfo&(BT_INFO_FTP|BT_INFO_A2DP|BT_INFO_HID|BT_INFO_SCO_BUSY)) != 0) ||
- pHalData->bt_coexist.halCoex8723.btRetryCnt > 0) {
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
- } else {
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
- }
-
- if (btInfo&BT_INFO_SCO || btInfo&BT_INFO_SCO_BUSY) {
- if (btInfo&BT_INFO_FTP || btInfo&BT_INFO_A2DP || btInfo&BT_INFO_HID) {
- switch (btInfo&0xe0) {
- case BT_INFO_HID:
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID;
- break;
- case BT_INFO_A2DP:
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP\n"));
- break;
- case BT_INFO_FTP:
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(HS)\n"));
- algorithm = BT_2ANT_COEX_ALGO_SCO;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(EDR)\n"));
- algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
- }
- break;
- case (BT_INFO_HID | BT_INFO_A2DP):
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
- break;
- case (BT_INFO_HID | BT_INFO_FTP):
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(HS)\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(EDR)\n"));
- algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
- }
- break;
- case (BT_INFO_A2DP | BT_INFO_FTP):
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(HS)\n"));
- algorithm = BT_2ANT_COEX_ALGO_A2DP;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n"));
- algorithm = BT_2ANT_COEX_ALGO_PANEDR_A2DP;
- }
- break;
- case (BT_INFO_HID | BT_INFO_A2DP | BT_INFO_FTP):
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
- }
- break;
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO only\n"));
- algorithm = BT_2ANT_COEX_ALGO_SCO;
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], non SCO\n"));
- switch (btInfo&0xe0) {
- case BT_INFO_HID:
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID;
- break;
- case BT_INFO_A2DP:
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP\n"));
- algorithm = BT_2ANT_COEX_ALGO_A2DP;
- break;
- case BT_INFO_FTP:
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN(EDR)\n"));
- algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
- break;
- case (BT_INFO_HID | BT_INFO_A2DP):
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
- break;
- case (BT_INFO_HID|BT_INFO_FTP):
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(HS)\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(EDR)\n"));
- algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
- }
- break;
- case (BT_INFO_A2DP|BT_INFO_FTP):
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(HS)\n"));
- algorithm = BT_2ANT_COEX_ALGO_A2DP;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n"));
- algorithm = BT_2ANT_COEX_ALGO_PANEDR_A2DP;
- }
- break;
- case (BT_INFO_HID|BT_INFO_A2DP|BT_INFO_FTP):
- if (bBtHsModeExist) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n"));
- algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
- }
- break;
- }
-
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTC2H], BTInfo: bConnect = false\n"));
- pBtdm8723->btStatus = BT_2ANT_BT_STATUS_IDLE;
- }
-
- pBtdm8723->curAlgorithm = algorithm;
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Algorithm = %d \n", pBtdm8723->curAlgorithm));
-
-/* From */
- BTDM_CheckWiFiState(padapter);
- if (pBtMgnt->ExtConfig.bManualControl) {
- RTPRINT(FBT, BT_TRACE, ("Action Manual control, won't execute bt coexist mechanism!!\n"));
- return;
- }
-}
-
-void BTDM_2AntBtCoexist8723A(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
- u8 btInfoOriginal = 0;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
-
- if (BTDM_BtProfileSupport(padapter)) {
- if (pBtMgnt->ExtConfig.bHoldForBtOperation) {
- RTPRINT(FBT, BT_TRACE, ("Action for BT Operation adjust!!\n"));
- return;
- }
- if (pBtMgnt->ExtConfig.bHoldPeriodCnt) {
- RTPRINT(FBT, BT_TRACE, ("Hold BT inquiry/page scan setting (cnt = %d)!!\n",
- pBtMgnt->ExtConfig.bHoldPeriodCnt));
- if (pBtMgnt->ExtConfig.bHoldPeriodCnt >= 11) {
- pBtMgnt->ExtConfig.bHoldPeriodCnt = 0;
- /* next time the coexist parameters should be reset again. */
- } else {
- pBtMgnt->ExtConfig.bHoldPeriodCnt++;
- }
- return;
- }
-
- if (pBtDbg->dbgCtrl)
- RTPRINT(FBT, BT_TRACE, ("[Dbg control], "));
-
- pBtdm8723->curAlgorithm = btdm_ActionAlgorithm(padapter);
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Algorithm = %d \n", pBtdm8723->curAlgorithm));
-
- if (btdm_Is2Ant8723ACommonAction(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant common.\n"));
- pBtdm8723->bResetTdmaAdjust = true;
- } else {
- if (pBtdm8723->curAlgorithm != pBtdm8723->preAlgorithm) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], preAlgorithm =%d, curAlgorithm =%d\n",
- pBtdm8723->preAlgorithm, pBtdm8723->curAlgorithm));
- pBtdm8723->bResetTdmaAdjust = true;
- }
- switch (pBtdm8723->curAlgorithm) {
- case BT_2ANT_COEX_ALGO_SCO:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = SCO.\n"));
- btdm_2Ant8723ASCOAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_HID:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID.\n"));
- btdm_2Ant8723AHIDAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_A2DP:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = A2DP.\n"));
- btdm_2Ant8723AA2DPAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_PANEDR:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR).\n"));
- btdm_2Ant8723APANEDRAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_PANHS:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HS mode.\n"));
- btdm_2Ant8723APANHSAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_PANEDR_A2DP:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN+A2DP.\n"));
- btdm_2Ant8723APANEDRA2DPAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_PANEDR_HID:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR)+HID.\n"));
- btdm_2Ant8723APANEDRHIDAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP+PAN.\n"));
- btdm_2Ant8723AHIDA2DPPANEDRAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_HID_A2DP:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP.\n"));
- btdm_2Ant8723AHIDA2DPAction(padapter);
- break;
- default:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = 0.\n"));
- btdm_2Ant8723AA2DPAction(padapter);
- break;
- }
- pBtdm8723->preAlgorithm = pBtdm8723->curAlgorithm;
- }
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex] Get bt info by fw!!\n"));
- /* msg shows c2h rsp for bt_info is received or not. */
- if (pHalData->bt_coexist.halCoex8723.bC2hBtInfoReqSent)
- RTPRINT(FBT, BT_TRACE, ("[BTCoex] c2h for btInfo not rcvd yet!!\n"));
-
- btInfoOriginal = pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal;
-
- if (pBtMgnt->ExtConfig.bHoldForBtOperation) {
- RTPRINT(FBT, BT_TRACE, ("Action for BT Operation adjust!!\n"));
- return;
- }
- if (pBtMgnt->ExtConfig.bHoldPeriodCnt) {
- RTPRINT(FBT, BT_TRACE,
- ("Hold BT inquiry/page scan setting (cnt = %d)!!\n",
- pBtMgnt->ExtConfig.bHoldPeriodCnt));
- if (pBtMgnt->ExtConfig.bHoldPeriodCnt >= 11) {
- pBtMgnt->ExtConfig.bHoldPeriodCnt = 0;
- /* next time the coexist parameters should be reset again. */
- } else {
- pBtMgnt->ExtConfig.bHoldPeriodCnt++;
- }
- return;
- }
-
- if (pBtDbg->dbgCtrl)
- RTPRINT(FBT, BT_TRACE, ("[Dbg control], "));
- if (btdm_Is2Ant8723ACommonAction(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant common.\n"));
- pBtdm8723->bResetTdmaAdjust = true;
- } else {
- if (pBtdm8723->curAlgorithm != pBtdm8723->preAlgorithm) {
- RTPRINT(FBT, BT_TRACE,
- ("[BTCoex], preAlgorithm =%d, curAlgorithm =%d\n",
- pBtdm8723->preAlgorithm,
- pBtdm8723->curAlgorithm));
- pBtdm8723->bResetTdmaAdjust = true;
- }
- switch (pBtdm8723->curAlgorithm) {
- case BT_2ANT_COEX_ALGO_SCO:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = SCO.\n"));
- btdm_2Ant8723ASCOAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_HID:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID.\n"));
- btdm_2Ant8723AHIDAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_A2DP:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = A2DP.\n"));
- btdm_2Ant8723AA2dp(padapter);
- break;
- case BT_2ANT_COEX_ALGO_PANEDR:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR).\n"));
- btdm_2Ant8723APANEDRAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_PANHS:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HS mode.\n"));
- btdm_2Ant8723APANHSAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_PANEDR_A2DP:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN+A2DP.\n"));
- btdm_2Ant8723APANEDRA2DPAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_PANEDR_HID:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR)+HID.\n"));
- btdm_2Ant8723APANEDRHIDAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP+PAN.\n"));
- btdm_2Ant8723AHIDA2DPPANEDRAction(padapter);
- break;
- case BT_2ANT_COEX_ALGO_HID_A2DP:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP.\n"));
- btdm_2Ant8723AHIDA2DPAction(padapter);
- break;
- default:
- RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = 0.\n"));
- btdm_2Ant8723AA2DPAction(padapter);
- break;
- }
- pBtdm8723->preAlgorithm = pBtdm8723->curAlgorithm;
- }
- }
-}
-
-/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87232Ant.c ===== */
-
-/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc8723.c ===== */
-
-static u8 btCoexDbgBuf[BT_TMP_BUF_SIZE];
-
-static const char *const BtProfileString[] = {
- "NONE",
- "A2DP",
- "PAN",
- "HID",
- "SCO",
-};
-
-static const char *const BtSpecString[] = {
- "1.0b",
- "1.1",
- "1.2",
- "2.0+EDR",
- "2.1+EDR",
- "3.0+HS",
- "4.0",
-};
-
-static const char *const BtLinkRoleString[] = {
- "Master",
- "Slave",
-};
-
-static u8 btdm_BtWifiAntNum(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723;
-
- if (Ant_x2 == pHalData->bt_coexist.BT_Ant_Num) {
- if (Ant_x2 == pBtCoex->TotalAntNum)
- return Ant_x2;
- else
- return Ant_x1;
- } else {
- return Ant_x1;
- }
- return Ant_x2;
-}
-
-static void btdm_BtHwCountersMonitor(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u32 regHPTxRx, regLPTxRx, u4Tmp;
- u32 regHPTx = 0, regHPRx = 0, regLPTx = 0, regLPRx = 0;
-
- regHPTxRx = REG_HIGH_PRIORITY_TXRX;
- regLPTxRx = REG_LOW_PRIORITY_TXRX;
-
- u4Tmp = rtl8723au_read32(padapter, regHPTxRx);
- regHPTx = u4Tmp & bMaskLWord;
- regHPRx = (u4Tmp & bMaskHWord)>>16;
-
- u4Tmp = rtl8723au_read32(padapter, regLPTxRx);
- regLPTx = u4Tmp & bMaskLWord;
- regLPRx = (u4Tmp & bMaskHWord)>>16;
-
- pHalData->bt_coexist.halCoex8723.highPriorityTx = regHPTx;
- pHalData->bt_coexist.halCoex8723.highPriorityRx = regHPRx;
- pHalData->bt_coexist.halCoex8723.lowPriorityTx = regLPTx;
- pHalData->bt_coexist.halCoex8723.lowPriorityRx = regLPRx;
-
- RTPRINT(FBT, BT_TRACE, ("High Priority Tx/Rx = %d / %d\n", regHPTx, regHPRx));
- RTPRINT(FBT, BT_TRACE, ("Low Priority Tx/Rx = %d / %d\n", regLPTx, regLPRx));
-
- /* reset counter */
- rtl8723au_write8(padapter, 0x76e, 0xc);
-}
-
-/* This function check if 8723 bt is disabled */
-static void btdm_BtEnableDisableCheck8723A(struct rtw_adapter *padapter)
-{
- u8 btAlife = true;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
-#ifdef CHECK_BT_EXIST_FROM_REG
- u8 val8;
-
- /* ox68[28]= 1 => BT enable; otherwise disable */
- val8 = rtl8723au_read8(padapter, 0x6B);
- if (!(val8 & BIT(4)))
- btAlife = false;
-
- if (btAlife)
- pHalData->bt_coexist.bCurBtDisabled = false;
- else
- pHalData->bt_coexist.bCurBtDisabled = true;
-#else
- if (pHalData->bt_coexist.halCoex8723.highPriorityTx == 0 &&
- pHalData->bt_coexist.halCoex8723.highPriorityRx == 0 &&
- pHalData->bt_coexist.halCoex8723.lowPriorityTx == 0 &&
- pHalData->bt_coexist.halCoex8723.lowPriorityRx == 0)
- btAlife = false;
- if (pHalData->bt_coexist.halCoex8723.highPriorityTx == 0xeaea &&
- pHalData->bt_coexist.halCoex8723.highPriorityRx == 0xeaea &&
- pHalData->bt_coexist.halCoex8723.lowPriorityTx == 0xeaea &&
- pHalData->bt_coexist.halCoex8723.lowPriorityRx == 0xeaea)
- btAlife = false;
- if (pHalData->bt_coexist.halCoex8723.highPriorityTx == 0xffff &&
- pHalData->bt_coexist.halCoex8723.highPriorityRx == 0xffff &&
- pHalData->bt_coexist.halCoex8723.lowPriorityTx == 0xffff &&
- pHalData->bt_coexist.halCoex8723.lowPriorityRx == 0xffff)
- btAlife = false;
- if (btAlife) {
- pHalData->bt_coexist.btActiveZeroCnt = 0;
- pHalData->bt_coexist.bCurBtDisabled = false;
- RTPRINT(FBT, BT_TRACE, ("8723A BT is enabled !!\n"));
- } else {
- pHalData->bt_coexist.btActiveZeroCnt++;
- RTPRINT(FBT, BT_TRACE, ("8723A bt all counters = 0, %d times!!\n",
- pHalData->bt_coexist.btActiveZeroCnt));
- if (pHalData->bt_coexist.btActiveZeroCnt >= 2) {
- pHalData->bt_coexist.bCurBtDisabled = true;
- RTPRINT(FBT, BT_TRACE, ("8723A BT is disabled !!\n"));
- }
- }
-#endif
-
- if (!pHalData->bt_coexist.bCurBtDisabled) {
- if (BTDM_IsWifiConnectionExist(padapter))
- BTDM_SetFwChnlInfo(padapter, RT_MEDIA_CONNECT);
- else
- BTDM_SetFwChnlInfo(padapter, RT_MEDIA_DISCONNECT);
- }
-
- if (pHalData->bt_coexist.bPreBtDisabled !=
- pHalData->bt_coexist.bCurBtDisabled) {
- RTPRINT(FBT, BT_TRACE, ("8723A BT is from %s to %s!!\n",
- (pHalData->bt_coexist.bPreBtDisabled ? "disabled":"enabled"),
- (pHalData->bt_coexist.bCurBtDisabled ? "disabled":"enabled")));
- pHalData->bt_coexist.bPreBtDisabled = pHalData->bt_coexist.bCurBtDisabled;
- }
-}
-
-static void btdm_BTCoexist8723AHandler(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
-
- pHalData = GET_HAL_DATA(padapter);
-
- if (btdm_BtWifiAntNum(padapter) == Ant_x2) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], 2 Ant mechanism\n"));
- BTDM_2AntBtCoexist8723A(padapter);
- } else {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1 Ant mechanism\n"));
- BTDM_1AntBtCoexist8723A(padapter);
- }
-
- if (!BTDM_IsSameCoexistState(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Coexist State[bitMap] change from 0x%"i64fmt"x to 0x%"i64fmt"x\n",
- pHalData->bt_coexist.PreviousState,
- pHalData->bt_coexist.CurrentState));
- pHalData->bt_coexist.PreviousState = pHalData->bt_coexist.CurrentState;
-
- RTPRINT(FBT, BT_TRACE, ("["));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT30)
- RTPRINT(FBT, BT_TRACE, ("BT 3.0, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_HT20)
- RTPRINT(FBT, BT_TRACE, ("HT20, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_HT40)
- RTPRINT(FBT, BT_TRACE, ("HT40, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_LEGACY)
- RTPRINT(FBT, BT_TRACE, ("Legacy, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_RSSI_LOW)
- RTPRINT(FBT, BT_TRACE, ("Rssi_Low, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_RSSI_MEDIUM)
- RTPRINT(FBT, BT_TRACE, ("Rssi_Mid, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_RSSI_HIGH)
- RTPRINT(FBT, BT_TRACE, ("Rssi_High, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_IDLE)
- RTPRINT(FBT, BT_TRACE, ("Wifi_Idle, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_UPLINK)
- RTPRINT(FBT, BT_TRACE, ("Wifi_Uplink, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_DOWNLINK)
- RTPRINT(FBT, BT_TRACE, ("Wifi_Downlink, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT_IDLE)
- RTPRINT(FBT, BT_TRACE, ("BT_idle, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_HID)
- RTPRINT(FBT, BT_TRACE, ("PRO_HID, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_A2DP)
- RTPRINT(FBT, BT_TRACE, ("PRO_A2DP, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_PAN)
- RTPRINT(FBT, BT_TRACE, ("PRO_PAN, "));
- if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_SCO)
- RTPRINT(FBT, BT_TRACE, ("PRO_SCO, "));
- RTPRINT(FBT, BT_TRACE, ("]\n"));
- }
-}
-
-/* extern function start with BTDM_ */
-u32 BTDM_BtTxRxCounterH(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u32 counters;
-
- counters = pHalData->bt_coexist.halCoex8723.highPriorityTx+
- pHalData->bt_coexist.halCoex8723.highPriorityRx;
- return counters;
-}
-
-u32 BTDM_BtTxRxCounterL(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u32 counters;
-
- counters = pHalData->bt_coexist.halCoex8723.lowPriorityTx+
- pHalData->bt_coexist.halCoex8723.lowPriorityRx;
- return counters;
-}
-
-void BTDM_SetFwChnlInfo(struct rtw_adapter *padapter, enum rt_media_status mstatus)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- u8 H2C_Parameter[3] = {0};
- u8 chnl;
-
- /* opMode */
- if (RT_MEDIA_CONNECT == mstatus)
- H2C_Parameter[0] = 0x1; /* 0: disconnected, 1:connected */
-
- if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) {
- /* channel */
- chnl = pmlmeext->cur_channel;
- if (BTDM_IsHT40(padapter)) {
- if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
- chnl -= 2;
- else if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
- chnl += 2;
- }
- H2C_Parameter[1] = chnl;
- } else { /* check if HS link is exists */
- /* channel */
- if (BT_Operation(padapter))
- H2C_Parameter[1] = pBtMgnt->BTChannel;
- else
- H2C_Parameter[1] = pmlmeext->cur_channel;
- }
-
- if (BTDM_IsHT40(padapter))
- H2C_Parameter[2] = 0x30;
- else
- H2C_Parameter[2] = 0x20;
-
- FillH2CCmd(padapter, 0x19, 3, H2C_Parameter);
-}
-
-u8 BTDM_IsWifiConnectionExist(struct rtw_adapter *padapter)
-{
- u8 bRet = false;
-
- if (BTHCI_HsConnectionEstablished(padapter))
- bRet = true;
-
- if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == true)
- bRet = true;
-
- return bRet;
-}
-
-void BTDM_SetFw3a(
- struct rtw_adapter *padapter,
- u8 byte1,
- u8 byte2,
- u8 byte3,
- u8 byte4,
- u8 byte5
- )
-{
- u8 H2C_Parameter[5] = {0};
-
- if (rtl8723a_BT_using_antenna_1(padapter)) {
- if ((!check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) &&
- (get_fwstate(&padapter->mlmepriv) != WIFI_NULL_STATE)) {
- /* for softap mode */
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723;
- u8 BtState = pBtCoex->c2hBtInfo;
-
- if ((BtState != BT_INFO_STATE_NO_CONNECTION) &&
- (BtState != BT_INFO_STATE_CONNECT_IDLE)) {
- if (byte1 & BIT(4)) {
- byte1 &= ~BIT(4);
- byte1 |= BIT(5);
- }
-
- byte5 |= BIT(5);
- if (byte5 & BIT(6))
- byte5 &= ~BIT(6);
- }
- }
- }
-
- H2C_Parameter[0] = byte1;
- H2C_Parameter[1] = byte2;
- H2C_Parameter[2] = byte3;
- H2C_Parameter[3] = byte4;
- H2C_Parameter[4] = byte5;
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], FW write 0x3a(5bytes) = 0x%02x%08x\n",
- H2C_Parameter[0],
- H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4]));
-
- FillH2CCmd(padapter, 0x3a, 5, H2C_Parameter);
-}
-
-void BTDM_QueryBtInformation(struct rtw_adapter *padapter)
-{
- u8 H2C_Parameter[1] = {0};
- struct hal_data_8723a *pHalData;
- struct bt_coexist_8723a *pBtCoex;
-
- pHalData = GET_HAL_DATA(padapter);
- pBtCoex = &pHalData->bt_coexist.halCoex8723;
-
- if (!rtl8723a_BT_enabled(padapter)) {
- pBtCoex->c2hBtInfo = BT_INFO_STATE_DISABLED;
- pBtCoex->bC2hBtInfoReqSent = false;
- return;
- }
-
- if (pBtCoex->c2hBtInfo == BT_INFO_STATE_DISABLED)
- pBtCoex->c2hBtInfo = BT_INFO_STATE_NO_CONNECTION;
-
- if (pBtCoex->bC2hBtInfoReqSent == true)
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], didn't recv previous BtInfo report!\n"));
- else
- pBtCoex->bC2hBtInfoReqSent = true;
-
- H2C_Parameter[0] |= BIT(0); /* trigger */
-
-/*RTPRINT(FBT, BT_TRACE, ("[BTCoex], Query Bt information, write 0x38 = 0x%x\n", */
-/*H2C_Parameter[0])); */
-
- FillH2CCmd(padapter, 0x38, 1, H2C_Parameter);
-}
-
-void BTDM_SetSwRfRxLpfCorner(struct rtw_adapter *padapter, u8 type)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (BT_RF_RX_LPF_CORNER_SHRINK == type) {
- /* Shrink RF Rx LPF corner */
- RTPRINT(FBT, BT_TRACE, ("Shrink RF Rx LPF corner!!\n"));
- PHY_SetRFReg(padapter, PathA, 0x1e, bRFRegOffsetMask, 0xf0ff7);
- pHalData->bt_coexist.bSWCoexistAllOff = false;
- } else if (BT_RF_RX_LPF_CORNER_RESUME == type) {
- /* Resume RF Rx LPF corner */
- RTPRINT(FBT, BT_TRACE, ("Resume RF Rx LPF corner!!\n"));
- PHY_SetRFReg(padapter, PathA, 0x1e, bRFRegOffsetMask, pHalData->bt_coexist.BtRfRegOrigin1E);
- }
-}
-
-void
-BTDM_SetSwPenaltyTxRateAdaptive(
- struct rtw_adapter *padapter,
- u8 raType
- )
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 tmpU1;
-
- tmpU1 = rtl8723au_read8(padapter, 0x4fd);
- tmpU1 |= BIT(0);
- if (BT_TX_RATE_ADAPTIVE_LOW_PENALTY == raType) {
- tmpU1 &= ~BIT(2);
- pHalData->bt_coexist.bSWCoexistAllOff = false;
- } else if (BT_TX_RATE_ADAPTIVE_NORMAL == raType) {
- tmpU1 |= BIT(2);
- }
-
- rtl8723au_write8(padapter, 0x4fd, tmpU1);
-}
-
-void BTDM_SetFwDecBtPwr(struct rtw_adapter *padapter, u8 bDecBtPwr)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 H2C_Parameter[1] = {0};
-
- H2C_Parameter[0] = 0;
-
- if (bDecBtPwr) {
- H2C_Parameter[0] |= BIT(1);
- pHalData->bt_coexist.bFWCoexistAllOff = false;
- }
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], decrease Bt Power : %s, write 0x21 = 0x%x\n",
- (bDecBtPwr ? "Yes!!" : "No!!"), H2C_Parameter[0]));
-
- FillH2CCmd(padapter, 0x21, 1, H2C_Parameter);
-}
-
-u8 BTDM_BtProfileSupport(struct rtw_adapter *padapter)
-{
- u8 bRet = false;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (pBtMgnt->bSupportProfile &&
- !pHalData->bt_coexist.halCoex8723.bForceFwBtInfo)
- bRet = true;
-
- return bRet;
-}
-
-static void BTDM_AdjustForBtOperation8723A(struct rtw_adapter *padapter)
-{
- /* BTDM_2AntAdjustForBtOperation8723(padapter); */
-}
-
-static void BTDM_FwC2hBtRssi8723A(struct rtw_adapter *padapter, u8 *tmpBuf)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 percent, u1tmp;
-
- u1tmp = tmpBuf[0];
- percent = u1tmp*2+10;
-
- pHalData->bt_coexist.halCoex8723.btRssi = percent;
-/*RTPRINT(FBT, BT_TRACE, ("[BTC2H], BT RSSI =%d\n", percent)); */
-}
-
-void
-rtl8723a_fw_c2h_BT_info(struct rtw_adapter *padapter, u8 *tmpBuf, u8 length)
-{
- struct hal_data_8723a *pHalData;
- struct bt_30info *pBTInfo;
- struct bt_mgnt *pBtMgnt;
- struct bt_coexist_8723a *pBtCoex;
- u8 i;
-
- pHalData = GET_HAL_DATA(padapter);
- pBTInfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTInfo->BtMgnt;
- pBtCoex = &pHalData->bt_coexist.halCoex8723;
-
- pBtCoex->bC2hBtInfoReqSent = false;
-
- RTPRINT(FBT, BT_TRACE, ("[BTC2H], BT info[%d]=[", length));
-
- pBtCoex->btRetryCnt = 0;
- for (i = 0; i < length; i++) {
- switch (i) {
- case 0:
- pBtCoex->c2hBtInfoOriginal = tmpBuf[i];
- break;
- case 1:
- pBtCoex->btRetryCnt = tmpBuf[i];
- break;
- case 2:
- BTDM_FwC2hBtRssi8723A(padapter, &tmpBuf[i]);
- break;
- case 3:
- pBtCoex->btInfoExt = tmpBuf[i]&BIT(0);
- break;
- }
-
- if (i == length-1)
- RTPRINT(FBT, BT_TRACE, ("0x%02x]\n", tmpBuf[i]));
- else
- RTPRINT(FBT, BT_TRACE, ("0x%02x, ", tmpBuf[i]));
- }
- RTPRINT(FBT, BT_TRACE, ("[BTC2H], BT RSSI =%d\n", pBtCoex->btRssi));
- if (pBtCoex->btInfoExt)
- RTPRINT(FBT, BT_TRACE, ("[BTC2H], pBtCoex->btInfoExt =%x\n", pBtCoex->btInfoExt));
-
- if (btdm_BtWifiAntNum(padapter) == Ant_x1)
- BTDM_1AntFwC2hBtInfo8723A(padapter);
- else
- BTDM_2AntFwC2hBtInfo8723A(padapter);
-
- if (pBtMgnt->ExtConfig.bManualControl) {
- RTPRINT(FBT, BT_TRACE, ("%s: Action Manual control!!\n", __func__));
- return;
- }
-
- btdm_BTCoexist8723AHandler(padapter);
-}
-
-static void BTDM_Display8723ABtCoexInfo(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- u8 u1Tmp, u1Tmp1, u1Tmp2, i, btInfoExt, psTdmaCase = 0;
- u32 u4Tmp[4];
- u8 antNum = Ant_x2;
-
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============");
- DCMD_Printf(btCoexDbgBuf);
-
- if (!rtl8723a_BT_coexist(padapter)) {
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!");
- DCMD_Printf(btCoexDbgBuf);
- return;
- }
-
- antNum = btdm_BtWifiAntNum(padapter);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/%d ", "Ant mechanism PG/Now run :", \
- ((pHalData->bt_coexist.BT_Ant_Num == Ant_x2) ? 2 : 1), ((antNum == Ant_x2) ? 2 : 1));
- DCMD_Printf(btCoexDbgBuf);
-
- if (pBtMgnt->ExtConfig.bManualControl) {
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "[Action Manual control]!!");
- DCMD_Printf(btCoexDbgBuf);
- } else {
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \
- ((pBtMgnt->bSupportProfile) ? "Yes" : "No"), pBtMgnt->ExtConfig.HCIExtensionVer);
- DCMD_Printf(btCoexDbgBuf);
- }
-
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\n %-35s = / %d", "Dot11 channel / BT channel", \
- pBtMgnt->BTChannel);
- DCMD_Printf(btCoexDbgBuf);
-
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\n %-35s = %d / %d / %d", "Wifi/BT/HS rssi", \
- BTDM_GetRxSS(padapter),
- pHalData->bt_coexist.halCoex8723.btRssi,
- pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB);
- DCMD_Printf(btCoexDbgBuf);
-
- if (!pBtMgnt->ExtConfig.bManualControl) {
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\n %-35s = %s / %s ", "WIfi status",
- ((BTDM_Legacy(padapter)) ? "Legacy" : (((BTDM_IsHT40(padapter)) ? "HT40" : "HT20"))),
- ((!BTDM_IsWifiBusy(padapter)) ? "idle" : ((BTDM_IsWifiUplink(padapter)) ? "uplink" : "downlink")));
- DCMD_Printf(btCoexDbgBuf);
-
- if (pBtMgnt->bSupportProfile) {
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP",
- ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_SCO)) ? 1 : 0),
- ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID)) ? 1 : 0),
- ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) ? 1 : 0),
- ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) ? 1 : 0));
- DCMD_Printf(btCoexDbgBuf);
-
- for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) {
- if (pBtMgnt->ExtConfig.HCIExtensionVer >= 1) {
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s", "Bt link type/spec/role",
- BtProfileString[pBtMgnt->ExtConfig.linkInfo[i].BTProfile],
- BtSpecString[pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec],
- BtLinkRoleString[pBtMgnt->ExtConfig.linkInfo[i].linkRole]);
- DCMD_Printf(btCoexDbgBuf);
-
- btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "A2DP rate", \
- (btInfoExt & BIT(0)) ?
- "Basic rate" : "EDR rate");
- DCMD_Printf(btCoexDbgBuf);
- } else {
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s", "Bt link type/spec", \
- BtProfileString[pBtMgnt->ExtConfig.linkInfo[i].BTProfile],
- BtSpecString[pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec]);
- DCMD_Printf(btCoexDbgBuf);
- }
- }
- }
- }
-
- /* Sw mechanism */
- if (!pBtMgnt->ExtConfig.bManualControl) {
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw BT Coex mechanism]============");
- DCMD_Printf(btCoexDbgBuf);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "AGC Table", \
- pBtCoex->btdm2Ant.bCurAgcTableEn);
- DCMD_Printf(btCoexDbgBuf);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "ADC Backoff", \
- pBtCoex->btdm2Ant.bCurAdcBackOff);
- DCMD_Printf(btCoexDbgBuf);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "Low penalty RA", \
- pBtCoex->btdm2Ant.bCurLowPenaltyRa);
- DCMD_Printf(btCoexDbgBuf);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "RF Rx LPF Shrink", \
- pBtCoex->btdm2Ant.bCurRfRxLpfShrink);
- DCMD_Printf(btCoexDbgBuf);
- }
- u4Tmp[0] = PHY_QueryRFReg(padapter, PathA, 0x1e, 0xff0);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "RF-A, 0x1e[11:4]/original val", \
- u4Tmp[0], pHalData->bt_coexist.BtRfRegOrigin1E);
- DCMD_Printf(btCoexDbgBuf);
-
- /* Fw mechanism */
- if (!pBtMgnt->ExtConfig.bManualControl) {
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw BT Coex mechanism]============");
- DCMD_Printf(btCoexDbgBuf);
- }
- if (!pBtMgnt->ExtConfig.bManualControl) {
- if (btdm_BtWifiAntNum(padapter) == Ant_x1)
- psTdmaCase = pHalData->bt_coexist.halCoex8723.btdm1Ant.curPsTdma;
- else
- psTdmaCase = pHalData->bt_coexist.halCoex8723.btdm2Ant.curPsTdma;
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %*ph case-%d",
- "PS TDMA(0x3a)", 5, pHalData->bt_coexist.fw3aVal, psTdmaCase);
- DCMD_Printf(btCoexDbgBuf);
-
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "Decrease Bt Power", \
- pBtCoex->btdm2Ant.bCurDecBtPwr);
- DCMD_Printf(btCoexDbgBuf);
- }
- u1Tmp = rtl8723au_read8(padapter, 0x778);
- u1Tmp1 = rtl8723au_read8(padapter, 0x783);
- u1Tmp2 = rtl8723au_read8(padapter, 0x796);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x778/ 0x783/ 0x796", \
- u1Tmp, u1Tmp1, u1Tmp2);
- DCMD_Printf(btCoexDbgBuf);
-
- if (!pBtMgnt->ExtConfig.bManualControl) {
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x / 0x%x", "Sw DacSwing Ctrl/Val", \
- pBtCoex->btdm2Ant.bCurDacSwingOn, pBtCoex->btdm2Ant.curDacSwingLvl);
- DCMD_Printf(btCoexDbgBuf);
- }
- u4Tmp[0] = rtl8723au_read32(padapter, 0x880);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x880", \
- u4Tmp[0]);
- DCMD_Printf(btCoexDbgBuf);
-
- /* Hw mechanism */
- if (!pBtMgnt->ExtConfig.bManualControl) {
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw BT Coex mechanism]============");
- DCMD_Printf(btCoexDbgBuf);
- }
-
- u1Tmp = rtl8723au_read8(padapter, 0x40);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x40", \
- u1Tmp);
- DCMD_Printf(btCoexDbgBuf);
-
- u4Tmp[0] = rtl8723au_read32(padapter, 0x550);
- u1Tmp = rtl8723au_read8(padapter, 0x522);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x", "0x550(bcn contrl)/0x522", \
- u4Tmp[0], u1Tmp);
- DCMD_Printf(btCoexDbgBuf);
-
- u4Tmp[0] = rtl8723au_read32(padapter, 0x484);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x484(rate adaptive)", \
- u4Tmp[0]);
- DCMD_Printf(btCoexDbgBuf);
-
- u4Tmp[0] = rtl8723au_read32(padapter, 0x50);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \
- u4Tmp[0]);
- DCMD_Printf(btCoexDbgBuf);
-
- u4Tmp[0] = rtl8723au_read32(padapter, 0xda0);
- u4Tmp[1] = rtl8723au_read32(padapter, 0xda4);
- u4Tmp[2] = rtl8723au_read32(padapter, 0xda8);
- u4Tmp[3] = rtl8723au_read32(padapter, 0xdac);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0xda0/0xda4/0xda8/0xdac(FA cnt)", \
- u4Tmp[0], u4Tmp[1], u4Tmp[2], u4Tmp[3]);
- DCMD_Printf(btCoexDbgBuf);
-
- u4Tmp[0] = rtl8723au_read32(padapter, 0x6c0);
- u4Tmp[1] = rtl8723au_read32(padapter, 0x6c4);
- u4Tmp[2] = rtl8723au_read32(padapter, 0x6c8);
- u1Tmp = rtl8723au_read8(padapter, 0x6cc);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \
- u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp);
- DCMD_Printf(btCoexDbgBuf);
-
- /* u4Tmp = rtl8723au_read32(padapter, 0x770); */
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d", "0x770(Hi pri Rx[31:16]/Tx[15:0])", \
- pHalData->bt_coexist.halCoex8723.highPriorityRx,
- pHalData->bt_coexist.halCoex8723.highPriorityTx);
- DCMD_Printf(btCoexDbgBuf);
- /* u4Tmp = rtl8723au_read32(padapter, 0x774); */
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d", "0x774(Lo pri Rx[31:16]/Tx[15:0])", \
- pHalData->bt_coexist.halCoex8723.lowPriorityRx,
- pHalData->bt_coexist.halCoex8723.lowPriorityTx);
- DCMD_Printf(btCoexDbgBuf);
-
- /* Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang */
- u1Tmp = rtl8723au_read8(padapter, 0x41b);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x41b (hang chk == 0xf)", \
- u1Tmp);
- DCMD_Printf(btCoexDbgBuf);
- snprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "lastHMEBoxNum", \
- pHalData->LastHMEBoxNum);
- DCMD_Printf(btCoexDbgBuf);
-}
-
-static void
-BTDM_8723ASignalCompensation(struct rtw_adapter *padapter,
- u8 *rssi_wifi, u8 *rssi_bt)
-{
- if (btdm_BtWifiAntNum(padapter) == Ant_x1)
- BTDM_1AntSignalCompensation(padapter, rssi_wifi, rssi_bt);
-}
-
-static void BTDM_8723AInit(struct rtw_adapter *padapter)
-{
- if (btdm_BtWifiAntNum(padapter) == Ant_x2)
- BTDM_2AntParaInit(padapter);
- else
- BTDM_1AntParaInit(padapter);
-}
-
-static void BTDM_HWCoexAllOff8723A(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- if (pBtMgnt->ExtConfig.bManualControl)
- return;
-
- if (btdm_BtWifiAntNum(padapter) == Ant_x2)
- BTDM_2AntHwCoexAllOff8723A(padapter);
-}
-
-static void BTDM_FWCoexAllOff8723A(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- if (pBtMgnt->ExtConfig.bManualControl)
- return;
-
- if (btdm_BtWifiAntNum(padapter) == Ant_x2)
- BTDM_2AntFwCoexAllOff8723A(padapter);
-}
-
-static void BTDM_SWCoexAllOff8723A(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- if (pBtMgnt->ExtConfig.bManualControl)
- return;
-
- if (btdm_BtWifiAntNum(padapter) == Ant_x2)
- BTDM_2AntSwCoexAllOff8723A(padapter);
-}
-
-static void
-BTDM_Set8723ABtCoexCurrAntNum(struct rtw_adapter *padapter, u8 antNum)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723;
-
- if (antNum == 1)
- pBtCoex->TotalAntNum = Ant_x1;
- else if (antNum == 2)
- pBtCoex->TotalAntNum = Ant_x2;
-}
-
-void rtl8723a_BT_lps_leave(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- if (pBtMgnt->ExtConfig.bManualControl)
- return;
-
- if (btdm_BtWifiAntNum(padapter) == Ant_x1)
- BTDM_1AntLpsLeave(padapter);
-}
-
-static void BTDM_ForHalt8723A(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- if (pBtMgnt->ExtConfig.bManualControl)
- return;
-
- if (btdm_BtWifiAntNum(padapter) == Ant_x1)
- BTDM_1AntForHalt(padapter);
-}
-
-static void BTDM_WifiScanNotify8723A(struct rtw_adapter *padapter, u8 scanType)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- if (pBtMgnt->ExtConfig.bManualControl)
- return;
-
- if (btdm_BtWifiAntNum(padapter) == Ant_x1)
- BTDM_1AntWifiScanNotify(padapter, scanType);
-}
-
-static void
-BTDM_WifiAssociateNotify8723A(struct rtw_adapter *padapter, u8 action)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- if (pBtMgnt->ExtConfig.bManualControl)
- return;
-
- if (btdm_BtWifiAntNum(padapter) == Ant_x1)
- BTDM_1AntWifiAssociateNotify(padapter, action);
-}
-
-static void
-BTDM_MediaStatusNotify8723A(struct rtw_adapter *padapter,
- enum rt_media_status mstatus)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], MediaStatusNotify, %s\n",
- mstatus?"connect":"disconnect"));
-
- BTDM_SetFwChnlInfo(padapter, mstatus);
-
- if (pBtMgnt->ExtConfig.bManualControl)
- return;
-
- if (btdm_BtWifiAntNum(padapter) == Ant_x1)
- BTDM_1AntMediaStatusNotify(padapter, mstatus);
-}
-
-static void BTDM_ForDhcp8723A(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- if (pBtMgnt->ExtConfig.bManualControl)
- return;
-
- if (btdm_BtWifiAntNum(padapter) == Ant_x1)
- BTDM_1AntForDhcp(padapter);
-}
-
-bool rtl8723a_BT_using_antenna_1(struct rtw_adapter *padapter)
-{
- if (btdm_BtWifiAntNum(padapter) == Ant_x1)
- return true;
- else
- return false;
-}
-
-static void BTDM_BTCoexist8723A(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct bt_30info *pBTInfo;
- struct bt_mgnt *pBtMgnt;
- struct bt_coexist_8723a *pBtCoex;
-
- pHalData = GET_HAL_DATA(padapter);
- pBTInfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTInfo->BtMgnt;
- pBtCoex = &pHalData->bt_coexist.halCoex8723;
-
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], beacon RSSI = 0x%x(%d)\n",
- pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB,
- pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB));
-
- btdm_BtHwCountersMonitor(padapter);
- btdm_BtEnableDisableCheck8723A(padapter);
-
- if (pBtMgnt->ExtConfig.bManualControl) {
- RTPRINT(FBT, BT_TRACE, ("%s: Action Manual control!!\n", __func__));
- return;
- }
-
- if (pBtCoex->bC2hBtInfoReqSent) {
- if (!rtl8723a_BT_enabled(padapter)) {
- pBtCoex->c2hBtInfo = BT_INFO_STATE_DISABLED;
- } else {
- if (pBtCoex->c2hBtInfo == BT_INFO_STATE_DISABLED)
- pBtCoex->c2hBtInfo = BT_INFO_STATE_NO_CONNECTION;
- }
-
- btdm_BTCoexist8723AHandler(padapter);
- } else if (!rtl8723a_BT_enabled(padapter)) {
- pBtCoex->c2hBtInfo = BT_INFO_STATE_DISABLED;
- btdm_BTCoexist8723AHandler(padapter);
- }
-
- BTDM_QueryBtInformation(padapter);
-}
-
-/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc8723.c ===== */
-
-/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtcCsr1Ant.c ===== */
-
-/* local function start with btdm_ */
-/* extern function start with BTDM_ */
-
-static void BTDM_SetAntenna(struct rtw_adapter *padapter, u8 who)
-{
-}
-
-void
-BTDM_SingleAnt(
- struct rtw_adapter *padapter,
- u8 bSingleAntOn,
- u8 bInterruptOn,
- u8 bMultiNAVOn
- )
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 H2C_Parameter[3] = {0};
-
- if (pHalData->bt_coexist.BT_Ant_Num != Ant_x1)
- return;
-
- H2C_Parameter[2] = 0;
- H2C_Parameter[1] = 0;
- H2C_Parameter[0] = 0;
-
- if (bInterruptOn) {
- H2C_Parameter[2] |= 0x02; /* BIT1 */
- pHalData->bt_coexist.bFWCoexistAllOff = false;
- }
- pHalData->bt_coexist.bInterruptOn = bInterruptOn;
-
- if (bSingleAntOn) {
- H2C_Parameter[2] |= 0x10; /* BIT4 */
- pHalData->bt_coexist.bFWCoexistAllOff = false;
- }
- pHalData->bt_coexist.bSingleAntOn = bSingleAntOn;
-
- if (bMultiNAVOn) {
- H2C_Parameter[2] |= 0x20; /* BIT5 */
- pHalData->bt_coexist.bFWCoexistAllOff = false;
- }
- pHalData->bt_coexist.bMultiNAVOn = bMultiNAVOn;
-
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], SingleAntenna =[%s:%s:%s], write 0xe = 0x%x\n",
- bSingleAntOn?"ON":"OFF", bInterruptOn?"ON":"OFF", bMultiNAVOn?"ON":"OFF",
- H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2]));
-}
-
-void BTDM_CheckBTIdleChange1Ant(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- u8 stateChange = false;
- u32 BT_Polling, Ratio_Act, Ratio_STA;
- u32 BT_Active, BT_State;
- u32 regBTActive = 0, regBTState = 0, regBTPolling = 0;
-
- if (!rtl8723a_BT_coexist(padapter))
- return;
- if (pBtMgnt->ExtConfig.bManualControl)
- return;
- if (pHalData->bt_coexist.BT_CoexistType != BT_CSR_BC8)
- return;
- if (pHalData->bt_coexist.BT_Ant_Num != Ant_x1)
- return;
-
- /* The following we only consider CSR BC8 and fw version should be >= 62 */
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], FirmwareVersion = 0x%x(%d)\n",
- pHalData->FirmwareVersion, pHalData->FirmwareVersion));
- regBTActive = REG_BT_ACTIVE;
- regBTState = REG_BT_STATE;
- if (pHalData->FirmwareVersion >= FW_VER_BT_REG1)
- regBTPolling = REG_BT_POLLING1;
- else
- regBTPolling = REG_BT_POLLING;
-
- BT_Active = rtl8723au_read32(padapter, regBTActive);
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT_Active(0x%x) =%x\n", regBTActive, BT_Active));
- BT_Active = BT_Active & 0x00ffffff;
-
- BT_State = rtl8723au_read32(padapter, regBTState);
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT_State(0x%x) =%x\n", regBTState, BT_State));
- BT_State = BT_State & 0x00ffffff;
-
- BT_Polling = rtl8723au_read32(padapter, regBTPolling);
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT_Polling(0x%x) =%x\n", regBTPolling, BT_Polling));
-
- if (BT_Active == 0xffffffff && BT_State == 0xffffffff && BT_Polling == 0xffffffff)
- return;
- if (BT_Polling == 0)
- return;
-
- Ratio_Act = BT_Active*1000/BT_Polling;
- Ratio_STA = BT_State*1000/BT_Polling;
-
- pHalData->bt_coexist.Ratio_Tx = Ratio_Act;
- pHalData->bt_coexist.Ratio_PRI = Ratio_STA;
-
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], Ratio_Act =%d\n", Ratio_Act));
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], Ratio_STA =%d\n", Ratio_STA));
-
- if (Ratio_STA < 60 && Ratio_Act < 500) { /* BT PAN idle */
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_IDLE;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_DOWNLINK;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_UPLINK;
- } else {
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_IDLE;
-
- if (Ratio_STA) {
- /* Check if BT PAN (under BT 2.1) is uplink or downlink */
- if ((Ratio_Act/Ratio_STA) < 2) {
- /* BT PAN Uplink */
- pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic = true;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_UPLINK;
- pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic = false;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_DOWNLINK;
- } else {
- /* BT PAN downlink */
- pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic = false;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_UPLINK;
- pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic = true;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_DOWNLINK;
- }
- } else {
- /* BT PAN downlink */
- pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic = false;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_UPLINK;
- pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic = true;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_DOWNLINK;
- }
- }
-
- /* Check BT is idle or not */
- if (pBtMgnt->ExtConfig.NumberOfHandle == 0 &&
- pBtMgnt->ExtConfig.NumberOfSCO == 0) {
- pBtMgnt->ExtConfig.bBTBusy = false;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_IDLE;
- } else {
- if (Ratio_STA < 60) {
- pBtMgnt->ExtConfig.bBTBusy = false;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_IDLE;
- } else {
- pBtMgnt->ExtConfig.bBTBusy = true;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_IDLE;
- }
- }
-
- if (pBtMgnt->ExtConfig.NumberOfHandle == 0 &&
- pBtMgnt->ExtConfig.NumberOfSCO == 0) {
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_RSSI_LOW;
- pBtMgnt->ExtConfig.MIN_BT_RSSI = 0;
- BTDM_SetAntenna(padapter, BTDM_ANT_BT_IDLE);
- } else {
- if (pBtMgnt->ExtConfig.MIN_BT_RSSI <= -5) {
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_RSSI_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], core stack notify bt rssi Low\n"));
- } else {
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_RSSI_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], core stack notify bt rssi Normal\n"));
- }
- }
-
- if (pHalData->bt_coexist.bBTBusyTraffic != pBtMgnt->ExtConfig.bBTBusy) {
- /* BT idle or BT non-idle */
- pHalData->bt_coexist.bBTBusyTraffic = pBtMgnt->ExtConfig.bBTBusy;
- stateChange = true;
- }
-
- if (stateChange) {
- if (!pBtMgnt->ExtConfig.bBTBusy)
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT is idle or disable\n"));
- else
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT is non-idle\n"));
- }
- if (!pBtMgnt->ExtConfig.bBTBusy) {
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT is idle or disable\n"));
- if (check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING|WIFI_SITE_MONITOR) == true)
- BTDM_SetAntenna(padapter, BTDM_ANT_WIFI);
- }
-}
-
-/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr1Ant.c ===== */
-
-/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtcCsr2Ant.c ===== */
-
-/* local function start with btdm_ */
-
-/* Note: */
-/* In the following, FW should be done before SW mechanism. */
-/* BTDM_Balance(), BTDM_DiminishWiFi(), BT_NAV() should be done */
-/* before BTDM_AGCTable(), BTDM_BBBackOffLevel(), btdm_DacSwing(). */
-
-/* extern function start with BTDM_ */
-
-void
-BTDM_DiminishWiFi(
- struct rtw_adapter *padapter,
- u8 bDACOn,
- u8 bInterruptOn,
- u8 DACSwingLevel,
- u8 bNAVOn
- )
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 H2C_Parameter[3] = {0};
-
- if (pHalData->bt_coexist.BT_Ant_Num != Ant_x2)
- return;
-
- if ((pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT_RSSI_LOW) &&
- (DACSwingLevel == 0x20)) {
- RTPRINT(FBT, BT_TRACE, ("[BT]DiminishWiFi 0x20 original, but set 0x18 for Low RSSI!\n"));
- DACSwingLevel = 0x18;
- }
-
- H2C_Parameter[2] = 0;
- H2C_Parameter[1] = DACSwingLevel;
- H2C_Parameter[0] = 0;
- if (bDACOn) {
- H2C_Parameter[2] |= 0x01; /* BIT0 */
- if (bInterruptOn)
- H2C_Parameter[2] |= 0x02; /* BIT1 */
- pHalData->bt_coexist.bFWCoexistAllOff = false;
- }
- if (bNAVOn) {
- H2C_Parameter[2] |= 0x08; /* BIT3 */
- pHalData->bt_coexist.bFWCoexistAllOff = false;
- }
-
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], bDACOn = %s, bInterruptOn = %s, write 0xe = 0x%x\n",
- bDACOn?"ON":"OFF", bInterruptOn?"ON":"OFF",
- H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2]));
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], bNAVOn = %s\n",
- bNAVOn?"ON":"OFF"));
-}
-
-/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr2Ant.c ===== */
-
-/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtCoexist.c ===== */
-
-/* local function */
-static void btdm_ResetFWCoexState(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- pHalData->bt_coexist.CurrentState = 0;
- pHalData->bt_coexist.PreviousState = 0;
-}
-
-static void btdm_InitBtCoexistDM(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- /* 20100415 Joseph: Restore RF register 0x1E and 0x1F value for further usage. */
- pHalData->bt_coexist.BtRfRegOrigin1E = PHY_QueryRFReg(padapter, PathA, RF_RCK1, bRFRegOffsetMask);
- pHalData->bt_coexist.BtRfRegOrigin1F = PHY_QueryRFReg(padapter, PathA, RF_RCK2, 0xf0);
-
- pHalData->bt_coexist.CurrentState = 0;
- pHalData->bt_coexist.PreviousState = 0;
-
- BTDM_8723AInit(padapter);
- pHalData->bt_coexist.bInitlized = true;
-}
-
-/* */
-/* extern function */
-/* */
-void BTDM_CheckAntSelMode(struct rtw_adapter *padapter)
-{
-}
-
-void BTDM_FwC2hBtRssi(struct rtw_adapter *padapter, u8 *tmpBuf)
-{
- BTDM_FwC2hBtRssi8723A(padapter, tmpBuf);
-}
-
-void BTDM_DisplayBtCoexInfo(struct rtw_adapter *padapter)
-{
- BTDM_Display8723ABtCoexInfo(padapter);
-}
-
-void BTDM_RejectAPAggregatedPacket(struct rtw_adapter *padapter, u8 bReject)
-{
-}
-
-u8 BTDM_IsHT40(struct rtw_adapter *padapter)
-{
- u8 isht40 = true;
- enum ht_channel_width bw;
-
- bw = padapter->mlmeextpriv.cur_bwmode;
-
- if (bw == HT_CHANNEL_WIDTH_20)
- isht40 = false;
- else if (bw == HT_CHANNEL_WIDTH_40)
- isht40 = true;
-
- return isht40;
-}
-
-u8 BTDM_Legacy(struct rtw_adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext;
- u8 isLegacy = false;
-
- pmlmeext = &padapter->mlmeextpriv;
- if ((pmlmeext->cur_wireless_mode == WIRELESS_11B) ||
- (pmlmeext->cur_wireless_mode == WIRELESS_11G) ||
- (pmlmeext->cur_wireless_mode == WIRELESS_11BG))
- isLegacy = true;
-
- return isLegacy;
-}
-
-void BTDM_CheckWiFiState(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct mlme_priv *pmlmepriv;
- struct bt_30info *pBTInfo;
- struct bt_mgnt *pBtMgnt;
-
- pHalData = GET_HAL_DATA(padapter);
- pmlmepriv = &padapter->mlmepriv;
- pBTInfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTInfo->BtMgnt;
-
- if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_IDLE;
-
- if (pmlmepriv->LinkDetectInfo.bTxBusyTraffic)
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_UPLINK;
- else
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_UPLINK;
-
- if (pmlmepriv->LinkDetectInfo.bRxBusyTraffic)
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_DOWNLINK;
- else
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_DOWNLINK;
- } else {
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_IDLE;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_UPLINK;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_DOWNLINK;
- }
-
- if (BTDM_Legacy(padapter)) {
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_LEGACY;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT20;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT40;
- } else {
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_LEGACY;
- if (BTDM_IsHT40(padapter)) {
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_HT40;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT20;
- } else {
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_HT20;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT40;
- }
- }
-
- if (pBtMgnt->BtOperationOn)
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT30;
- else
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT30;
-}
-
-s32 BTDM_GetRxSS(struct rtw_adapter *padapter)
-{
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct mlme_priv *pmlmepriv;
- struct hal_data_8723a *pHalData;
- s32 UndecoratedSmoothedPWDB = 0;
-
- pmlmepriv = &padapter->mlmepriv;
- pHalData = GET_HAL_DATA(padapter);
-
- if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- UndecoratedSmoothedPWDB = GET_UNDECORATED_AVERAGE_RSSI(padapter);
- } else { /* associated entry pwdb */
- UndecoratedSmoothedPWDB = pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB;
- /* pHalData->BT_EntryMinUndecoratedSmoothedPWDB */
- }
- RTPRINT(FBT, BT_TRACE, ("BTDM_GetRxSS() = %d\n", UndecoratedSmoothedPWDB));
- return UndecoratedSmoothedPWDB;
-}
-
-static s32 BTDM_GetRxBeaconSS(struct rtw_adapter *padapter)
-{
-/*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
- struct mlme_priv *pmlmepriv;
- struct hal_data_8723a *pHalData;
- s32 pwdbBeacon = 0;
-
- pmlmepriv = &padapter->mlmepriv;
- pHalData = GET_HAL_DATA(padapter);
-
- if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- /* pwdbBeacon = pHalData->dmpriv.UndecoratedSmoothedBeacon; */
- pwdbBeacon = pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB;
- }
- RTPRINT(FBT, BT_TRACE, ("BTDM_GetRxBeaconSS() = %d\n", pwdbBeacon));
- return pwdbBeacon;
-}
-
-/* Get beacon rssi state */
-u8 BTDM_CheckCoexBcnRssiState(struct rtw_adapter *padapter, u8 levelNum,
- u8 RssiThresh, u8 RssiThresh1)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- s32 pwdbBeacon = 0;
- u8 bcnRssiState = 0;
-
- pwdbBeacon = BTDM_GetRxBeaconSS(padapter);
-
- if (levelNum == 2) {
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
-
- if ((pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_LOW) ||
- (pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_STAY_LOW)) {
- if (pwdbBeacon >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
- bcnRssiState = BT_RSSI_STATE_HIGH;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to High\n"));
- } else {
- bcnRssiState = BT_RSSI_STATE_STAY_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at Low\n"));
- }
- } else {
- if (pwdbBeacon < RssiThresh) {
- bcnRssiState = BT_RSSI_STATE_LOW;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Low\n"));
- } else {
- bcnRssiState = BT_RSSI_STATE_STAY_HIGH;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at High\n"));
- }
- }
- } else if (levelNum == 3) {
- if (RssiThresh > RssiThresh1) {
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON thresh error!!\n"));
- return pHalData->bt_coexist.preRssiStateBeacon;
- }
-
- if ((pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_LOW) ||
- (pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_STAY_LOW)) {
- if (pwdbBeacon >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
- bcnRssiState = BT_RSSI_STATE_MEDIUM;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Medium\n"));
- } else {
- bcnRssiState = BT_RSSI_STATE_STAY_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at Low\n"));
- }
- } else if ((pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_MEDIUM) ||
- (pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_STAY_MEDIUM)) {
- if (pwdbBeacon >= (RssiThresh1+BT_FW_COEX_THRESH_TOL)) {
- bcnRssiState = BT_RSSI_STATE_HIGH;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to High\n"));
- } else if (pwdbBeacon < RssiThresh) {
- bcnRssiState = BT_RSSI_STATE_LOW;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Low\n"));
- } else {
- bcnRssiState = BT_RSSI_STATE_STAY_MEDIUM;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at Medium\n"));
- }
- } else {
- if (pwdbBeacon < RssiThresh1) {
- bcnRssiState = BT_RSSI_STATE_MEDIUM;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Medium\n"));
- } else {
- bcnRssiState = BT_RSSI_STATE_STAY_HIGH;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at High\n"));
- }
- }
- }
-
- pHalData->bt_coexist.preRssiStateBeacon = bcnRssiState;
-
- return bcnRssiState;
-}
-
-u8 BTDM_CheckCoexRSSIState1(struct rtw_adapter *padapter, u8 levelNum,
- u8 RssiThresh, u8 RssiThresh1)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- s32 UndecoratedSmoothedPWDB = 0;
- u8 btRssiState = 0;
-
- UndecoratedSmoothedPWDB = BTDM_GetRxSS(padapter);
-
- if (levelNum == 2) {
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
-
- if ((pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_LOW) ||
- (pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_STAY_LOW)) {
- if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
- btRssiState = BT_RSSI_STATE_HIGH;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_HIGH;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to High\n"));
- } else {
- btRssiState = BT_RSSI_STATE_STAY_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at Low\n"));
- }
- } else {
- if (UndecoratedSmoothedPWDB < RssiThresh) {
- btRssiState = BT_RSSI_STATE_LOW;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_LOW;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Low\n"));
- } else {
- btRssiState = BT_RSSI_STATE_STAY_HIGH;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at High\n"));
- }
- }
- } else if (levelNum == 3) {
- if (RssiThresh > RssiThresh1) {
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 thresh error!!\n"));
- return pHalData->bt_coexist.preRssiState1;
- }
-
- if ((pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_LOW) ||
- (pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_STAY_LOW)) {
- if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
- btRssiState = BT_RSSI_STATE_MEDIUM;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Medium\n"));
- } else {
- btRssiState = BT_RSSI_STATE_STAY_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at Low\n"));
- }
- } else if ((pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_MEDIUM) ||
- (pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_STAY_MEDIUM)) {
- if (UndecoratedSmoothedPWDB >= (RssiThresh1+BT_FW_COEX_THRESH_TOL)) {
- btRssiState = BT_RSSI_STATE_HIGH;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_HIGH;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to High\n"));
- } else if (UndecoratedSmoothedPWDB < RssiThresh) {
- btRssiState = BT_RSSI_STATE_LOW;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_LOW;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Low\n"));
- } else {
- btRssiState = BT_RSSI_STATE_STAY_MEDIUM;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at Medium\n"));
- }
- } else {
- if (UndecoratedSmoothedPWDB < RssiThresh1) {
- btRssiState = BT_RSSI_STATE_MEDIUM;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Medium\n"));
- } else {
- btRssiState = BT_RSSI_STATE_STAY_HIGH;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at High\n"));
- }
- }
- }
-
- pHalData->bt_coexist.preRssiState1 = btRssiState;
-
- return btRssiState;
-}
-
-u8 BTDM_CheckCoexRSSIState(struct rtw_adapter *padapter, u8 levelNum,
- u8 RssiThresh, u8 RssiThresh1)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- s32 UndecoratedSmoothedPWDB = 0;
- u8 btRssiState = 0;
-
- UndecoratedSmoothedPWDB = BTDM_GetRxSS(padapter);
-
- if (levelNum == 2) {
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
-
- if ((pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_LOW) ||
- (pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_STAY_LOW)) {
- if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
- btRssiState = BT_RSSI_STATE_HIGH;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_HIGH;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to High\n"));
- } else {
- btRssiState = BT_RSSI_STATE_STAY_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at Low\n"));
- }
- } else {
- if (UndecoratedSmoothedPWDB < RssiThresh) {
- btRssiState = BT_RSSI_STATE_LOW;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_LOW;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Low\n"));
- } else {
- btRssiState = BT_RSSI_STATE_STAY_HIGH;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at High\n"));
- }
- }
- } else if (levelNum == 3) {
- if (RssiThresh > RssiThresh1) {
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI thresh error!!\n"));
- return pHalData->bt_coexist.preRssiState;
- }
-
- if ((pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_LOW) ||
- (pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_STAY_LOW)) {
- if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
- btRssiState = BT_RSSI_STATE_MEDIUM;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Medium\n"));
- } else {
- btRssiState = BT_RSSI_STATE_STAY_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at Low\n"));
- }
- } else if ((pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_MEDIUM) ||
- (pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_STAY_MEDIUM)) {
- if (UndecoratedSmoothedPWDB >= (RssiThresh1+BT_FW_COEX_THRESH_TOL)) {
- btRssiState = BT_RSSI_STATE_HIGH;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_HIGH;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to High\n"));
- } else if (UndecoratedSmoothedPWDB < RssiThresh) {
- btRssiState = BT_RSSI_STATE_LOW;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_LOW;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Low\n"));
- } else {
- btRssiState = BT_RSSI_STATE_STAY_MEDIUM;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at Medium\n"));
- }
- } else {
- if (UndecoratedSmoothedPWDB < RssiThresh1) {
- btRssiState = BT_RSSI_STATE_MEDIUM;
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
- pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Medium\n"));
- } else {
- btRssiState = BT_RSSI_STATE_STAY_HIGH;
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at High\n"));
- }
- }
- }
-
- pHalData->bt_coexist.preRssiState = btRssiState;
-
- return btRssiState;
-}
-
-bool rtl8723a_BT_disable_EDCA_turbo(struct rtw_adapter *padapter)
-{
- struct bt_mgnt *pBtMgnt;
- struct hal_data_8723a *pHalData;
- u8 bBtChangeEDCA = false;
- u32 EDCA_BT_BE = 0x5ea42b, cur_EDCA_reg;
- bool bRet = false;
-
- pHalData = GET_HAL_DATA(padapter);
- pBtMgnt = &pHalData->BtInfo.BtMgnt;
-
- if (!rtl8723a_BT_coexist(padapter)) {
- bRet = false;
- pHalData->bt_coexist.lastBtEdca = 0;
- return bRet;
- }
- if (!((pBtMgnt->bSupportProfile) ||
- (pHalData->bt_coexist.BT_CoexistType == BT_CSR_BC8))) {
- bRet = false;
- pHalData->bt_coexist.lastBtEdca = 0;
- return bRet;
- }
-
- if (rtl8723a_BT_using_antenna_1(padapter)) {
- bRet = false;
- pHalData->bt_coexist.lastBtEdca = 0;
- return bRet;
- }
-
- if (pHalData->bt_coexist.exec_cnt < 3)
- pHalData->bt_coexist.exec_cnt++;
- else
- pHalData->bt_coexist.bEDCAInitialized = true;
-
- /* When BT is non idle */
- if (!(pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT_IDLE)) {
- RTPRINT(FBT, BT_TRACE, ("BT state non idle, set bt EDCA\n"));
-
- /* aggr_num = 0x0909; */
- if (pHalData->odmpriv.DM_EDCA_Table.bCurrentTurboEDCA) {
- bBtChangeEDCA = true;
- pHalData->odmpriv.DM_EDCA_Table.bCurrentTurboEDCA = false;
- pHalData->dmpriv.prv_traffic_idx = 3;
- }
- cur_EDCA_reg = rtl8723au_read32(padapter, REG_EDCA_BE_PARAM);
-
- if (cur_EDCA_reg != EDCA_BT_BE)
- bBtChangeEDCA = true;
- if (bBtChangeEDCA || !pHalData->bt_coexist.bEDCAInitialized) {
- rtl8723au_write32(padapter, REG_EDCA_BE_PARAM,
- EDCA_BT_BE);
- pHalData->bt_coexist.lastBtEdca = EDCA_BT_BE;
- }
- bRet = true;
- } else {
- RTPRINT(FBT, BT_TRACE, ("BT state idle, set original EDCA\n"));
- pHalData->bt_coexist.lastBtEdca = 0;
- bRet = false;
- }
- return bRet;
-}
-
-void
-BTDM_Balance(
- struct rtw_adapter *padapter,
- u8 bBalanceOn,
- u8 ms0,
- u8 ms1
- )
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 H2C_Parameter[3] = {0};
-
- if (bBalanceOn) {
- H2C_Parameter[2] = 1;
- H2C_Parameter[1] = ms1;
- H2C_Parameter[0] = ms0;
- pHalData->bt_coexist.bFWCoexistAllOff = false;
- } else {
- H2C_Parameter[2] = 0;
- H2C_Parameter[1] = 0;
- H2C_Parameter[0] = 0;
- }
- pHalData->bt_coexist.bBalanceOn = bBalanceOn;
-
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], Balance =[%s:%dms:%dms], write 0xc = 0x%x\n",
- bBalanceOn?"ON":"OFF", ms0, ms1,
- H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2]));
-
- FillH2CCmd(padapter, 0xc, 3, H2C_Parameter);
-}
-
-void BTDM_AGCTable(struct rtw_adapter *padapter, u8 type)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- if (type == BT_AGCTABLE_OFF) {
- RTPRINT(FBT, BT_TRACE, ("[BT]AGCTable Off!\n"));
- rtl8723au_write32(padapter, 0xc78, 0x641c0001);
- rtl8723au_write32(padapter, 0xc78, 0x631d0001);
- rtl8723au_write32(padapter, 0xc78, 0x621e0001);
- rtl8723au_write32(padapter, 0xc78, 0x611f0001);
- rtl8723au_write32(padapter, 0xc78, 0x60200001);
-
- PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x32000);
- PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x71000);
- PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0xb0000);
- PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0xfc000);
- PHY_SetRFReg(padapter, PathA, RF_RX_G1, bRFRegOffsetMask, 0x30355);
-
- pHalData->bt_coexist.b8723aAgcTableOn = false;
- } else if (type == BT_AGCTABLE_ON) {
- RTPRINT(FBT, BT_TRACE, ("[BT]AGCTable On!\n"));
- rtl8723au_write32(padapter, 0xc78, 0x4e1c0001);
- rtl8723au_write32(padapter, 0xc78, 0x4d1d0001);
- rtl8723au_write32(padapter, 0xc78, 0x4c1e0001);
- rtl8723au_write32(padapter, 0xc78, 0x4b1f0001);
- rtl8723au_write32(padapter, 0xc78, 0x4a200001);
-
- PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0xdc000);
- PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x90000);
- PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x51000);
- PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x12000);
- PHY_SetRFReg(padapter, PathA, RF_RX_G1, bRFRegOffsetMask, 0x00355);
-
- pHalData->bt_coexist.b8723aAgcTableOn = true;
-
- pHalData->bt_coexist.bSWCoexistAllOff = false;
- }
-}
-
-void BTDM_BBBackOffLevel(struct rtw_adapter *padapter, u8 type)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (type == BT_BB_BACKOFF_OFF) {
- RTPRINT(FBT, BT_TRACE, ("[BT]BBBackOffLevel Off!\n"));
- rtl8723au_write32(padapter, 0xc04, 0x3a05611);
- } else if (type == BT_BB_BACKOFF_ON) {
- RTPRINT(FBT, BT_TRACE, ("[BT]BBBackOffLevel On!\n"));
- rtl8723au_write32(padapter, 0xc04, 0x3a07611);
- pHalData->bt_coexist.bSWCoexistAllOff = false;
- }
-}
-
-void BTDM_FWCoexAllOff(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- RTPRINT(FBT, BT_TRACE, ("BTDM_FWCoexAllOff()\n"));
- if (pHalData->bt_coexist.bFWCoexistAllOff)
- return;
- RTPRINT(FBT, BT_TRACE, ("BTDM_FWCoexAllOff(), real Do\n"));
-
- BTDM_FWCoexAllOff8723A(padapter);
-
- pHalData->bt_coexist.bFWCoexistAllOff = true;
-}
-
-void BTDM_SWCoexAllOff(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- RTPRINT(FBT, BT_TRACE, ("BTDM_SWCoexAllOff()\n"));
- if (pHalData->bt_coexist.bSWCoexistAllOff)
- return;
- RTPRINT(FBT, BT_TRACE, ("BTDM_SWCoexAllOff(), real Do\n"));
- BTDM_SWCoexAllOff8723A(padapter);
-
- pHalData->bt_coexist.bSWCoexistAllOff = true;
-}
-
-void BTDM_HWCoexAllOff(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- RTPRINT(FBT, BT_TRACE, ("BTDM_HWCoexAllOff()\n"));
- if (pHalData->bt_coexist.bHWCoexistAllOff)
- return;
- RTPRINT(FBT, BT_TRACE, ("BTDM_HWCoexAllOff(), real Do\n"));
-
- BTDM_HWCoexAllOff8723A(padapter);
-
- pHalData->bt_coexist.bHWCoexistAllOff = true;
-}
-
-void BTDM_CoexAllOff(struct rtw_adapter *padapter)
-{
- BTDM_FWCoexAllOff(padapter);
- BTDM_SWCoexAllOff(padapter);
- BTDM_HWCoexAllOff(padapter);
-}
-
-void rtl8723a_BT_disable_coexist(struct rtw_adapter *padapter)
-{
- struct pwrctrl_priv *ppwrctrl = &padapter->pwrctrlpriv;
-
- if (!rtl8723a_BT_coexist(padapter))
- return;
-
- /* 8723 1Ant doesn't need to turn off bt coexist mechanism. */
- if (rtl8723a_BT_using_antenna_1(padapter))
- return;
-
- /* Before enter IPS, turn off FW BT Co-exist mechanism */
- if (ppwrctrl->reg_rfoff == rf_on) {
- RTPRINT(FBT, BT_TRACE, ("[BT][DM], Before enter IPS, turn off all Coexist DM\n"));
- btdm_ResetFWCoexState(padapter);
- BTDM_CoexAllOff(padapter);
- BTDM_SetAntenna(padapter, BTDM_ANT_BT);
- }
-}
-
-void BTDM_SignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi, u8 *rssi_bt)
-{
- BTDM_8723ASignalCompensation(padapter, rssi_wifi, rssi_bt);
-}
-
-void rtl8723a_BT_do_coexist(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (!rtl8723a_BT_coexist(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT not exists!!\n"));
- return;
- }
-
- if (!pHalData->bt_coexist.bInitlized) {
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], btdm_InitBtCoexistDM()\n"));
- btdm_InitBtCoexistDM(padapter);
- }
-
- RTPRINT(FBT, BT_TRACE, ("\n\n[DM][BT], BTDM start!!\n"));
-
- BTDM_PWDBMonitor(padapter);
-
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], HW type is 8723\n"));
- BTDM_BTCoexist8723A(padapter);
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], BTDM end!!\n\n"));
-}
-
-void BTDM_UpdateCoexState(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (!BTDM_IsSameCoexistState(padapter)) {
- RTPRINT(FBT, BT_TRACE, ("[BTCoex], Coexist State[bitMap] change from 0x%"i64fmt"x to 0x%"i64fmt"x, changeBits = 0x%"i64fmt"x\n",
- pHalData->bt_coexist.PreviousState,
- pHalData->bt_coexist.CurrentState,
- (pHalData->bt_coexist.PreviousState^pHalData->bt_coexist.CurrentState)));
- pHalData->bt_coexist.PreviousState = pHalData->bt_coexist.CurrentState;
- }
-}
-
-u8 BTDM_IsSameCoexistState(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (pHalData->bt_coexist.PreviousState == pHalData->bt_coexist.CurrentState) {
- return true;
- } else {
- RTPRINT(FBT, BT_TRACE, ("[DM][BT], Coexist state changed!!\n"));
- return false;
- }
-}
-
-void BTDM_PWDBMonitor(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(GetDefaultAdapter(padapter));
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 H2C_Parameter[3] = {0};
- s32 tmpBTEntryMaxPWDB = 0, tmpBTEntryMinPWDB = 0xff;
- u8 i;
-
- if (pBtMgnt->BtOperationOn) {
- for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) {
- if (pBTInfo->BtAsocEntry[i].bUsed) {
- if (pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB < tmpBTEntryMinPWDB)
- tmpBTEntryMinPWDB = pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB;
- if (pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB > tmpBTEntryMaxPWDB)
- tmpBTEntryMaxPWDB = pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB;
- /* Report every BT connection (HS mode) RSSI to FW */
- H2C_Parameter[2] = (u8)(pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB & 0xFF);
- H2C_Parameter[0] = (MAX_FW_SUPPORT_MACID_NUM-1-i);
- RTPRINT(FDM, DM_BT30, ("RSSI report for BT[%d], H2C_Par = 0x%x\n", i, H2C_Parameter[0]));
- FillH2CCmd(padapter, RSSI_SETTING_EID, 3, H2C_Parameter);
- RTPRINT_ADDR(FDM, (DM_PWDB|DM_BT30), ("BT_Entry Mac :"),
- pBTInfo->BtAsocEntry[i].BTRemoteMACAddr)
- RTPRINT(FDM, (DM_PWDB|DM_BT30),
- ("BT rx pwdb[%d] = 0x%x(%d)\n", i,
- pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB,
- pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB));
- }
- }
- if (tmpBTEntryMaxPWDB != 0) { /* If associated entry is found */
- pHalData->dmpriv.BT_EntryMaxUndecoratedSmoothedPWDB = tmpBTEntryMaxPWDB;
- RTPRINT(FDM, (DM_PWDB|DM_BT30), ("BT_EntryMaxPWDB = 0x%x(%d)\n",
- tmpBTEntryMaxPWDB, tmpBTEntryMaxPWDB));
- } else {
- pHalData->dmpriv.BT_EntryMaxUndecoratedSmoothedPWDB = 0;
- }
- if (tmpBTEntryMinPWDB != 0xff) { /* If associated entry is found */
- pHalData->dmpriv.BT_EntryMinUndecoratedSmoothedPWDB = tmpBTEntryMinPWDB;
- RTPRINT(FDM, (DM_PWDB|DM_BT30), ("BT_EntryMinPWDB = 0x%x(%d)\n",
- tmpBTEntryMinPWDB, tmpBTEntryMinPWDB));
- } else {
- pHalData->dmpriv.BT_EntryMinUndecoratedSmoothedPWDB = 0;
- }
- }
-}
-
-u8 BTDM_IsBTBusy(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
-
- if (pBtMgnt->ExtConfig.bBTBusy)
- return true;
- else
- return false;
-}
-
-u8 BTDM_IsWifiBusy(struct rtw_adapter *padapter)
-{
-/*PMGNT_INFO pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */
- struct mlme_priv *pmlmepriv = &GetDefaultAdapter(padapter)->mlmepriv;
- struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
- struct bt_traffic *pBtTraffic = &pBTInfo->BtTraffic;
-
- if (pmlmepriv->LinkDetectInfo.bBusyTraffic ||
- pBtTraffic->Bt30TrafficStatistics.bTxBusyTraffic ||
- pBtTraffic->Bt30TrafficStatistics.bRxBusyTraffic)
- return true;
- else
- return false;
-}
-
-u8 BTDM_IsCoexistStateChanged(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (pHalData->bt_coexist.PreviousState == pHalData->bt_coexist.CurrentState)
- return false;
- else
- return true;
-}
-
-u8 BTDM_IsWifiUplink(struct rtw_adapter *padapter)
-{
-/*PMGNT_INFO pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */
- struct mlme_priv *pmlmepriv;
- struct bt_30info *pBTInfo;
- struct bt_traffic *pBtTraffic;
-
- pmlmepriv = &padapter->mlmepriv;
- pBTInfo = GET_BT_INFO(padapter);
- pBtTraffic = &pBTInfo->BtTraffic;
-
- if ((pmlmepriv->LinkDetectInfo.bTxBusyTraffic) ||
- (pBtTraffic->Bt30TrafficStatistics.bTxBusyTraffic))
- return true;
- else
- return false;
-}
-
-u8 BTDM_IsWifiDownlink(struct rtw_adapter *padapter)
-{
-/*PMGNT_INFO pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */
- struct mlme_priv *pmlmepriv;
- struct bt_30info *pBTInfo;
- struct bt_traffic *pBtTraffic;
-
- pmlmepriv = &padapter->mlmepriv;
- pBTInfo = GET_BT_INFO(padapter);
- pBtTraffic = &pBTInfo->BtTraffic;
-
- if ((pmlmepriv->LinkDetectInfo.bRxBusyTraffic) ||
- (pBtTraffic->Bt30TrafficStatistics.bRxBusyTraffic))
- return true;
- else
- return false;
-}
-
-u8 BTDM_IsBTHSMode(struct rtw_adapter *padapter)
-{
-/*PMGNT_INFO pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */
- struct hal_data_8723a *pHalData;
- struct bt_mgnt *pBtMgnt;
-
- pHalData = GET_HAL_DATA(padapter);
- pBtMgnt = &pHalData->BtInfo.BtMgnt;
-
- if (pBtMgnt->BtOperationOn)
- return true;
- else
- return false;
-}
-
-u8 BTDM_IsBTUplink(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic)
- return true;
- else
- return false;
-}
-
-u8 BTDM_IsBTDownlink(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic)
- return true;
- else
- return false;
-}
-
-void BTDM_AdjustForBtOperation(struct rtw_adapter *padapter)
-{
- RTPRINT(FBT, BT_TRACE, ("[BT][DM], BTDM_AdjustForBtOperation()\n"));
- BTDM_AdjustForBtOperation8723A(padapter);
-}
-
-void BTDM_SetBtCoexCurrAntNum(struct rtw_adapter *padapter, u8 antNum)
-{
- BTDM_Set8723ABtCoexCurrAntNum(padapter, antNum);
-}
-
-void BTDM_ForHalt(struct rtw_adapter *padapter)
-{
- if (!rtl8723a_BT_coexist(padapter))
- return;
-
- BTDM_ForHalt8723A(padapter);
- GET_HAL_DATA(padapter)->bt_coexist.bInitlized = false;
-}
-
-void BTDM_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType)
-{
- if (!rtl8723a_BT_coexist(padapter))
- return;
-
- BTDM_WifiScanNotify8723A(padapter, scanType);
-}
-
-void BTDM_WifiAssociateNotify(struct rtw_adapter *padapter, u8 action)
-{
- if (!rtl8723a_BT_coexist(padapter))
- return;
-
- BTDM_WifiAssociateNotify8723A(padapter, action);
-}
-
-void rtl8723a_BT_mediastatus_notify(struct rtw_adapter *padapter,
- enum rt_media_status mstatus)
-{
- if (!rtl8723a_BT_coexist(padapter))
- return;
-
- BTDM_MediaStatusNotify8723A(padapter, mstatus);
-}
-
-void rtl8723a_BT_specialpacket_notify(struct rtw_adapter *padapter)
-{
- if (!rtl8723a_BT_coexist(padapter))
- return;
-
- BTDM_ForDhcp8723A(padapter);
-}
-
-void BTDM_ResetActionProfileState(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- pHalData->bt_coexist.CurrentState &= ~\
- (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_A2DP|
- BT_COEX_STATE_PROFILE_PAN|BT_COEX_STATE_PROFILE_SCO);
-}
-
-u8 BTDM_IsActionSCO(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct bt_30info *pBTInfo;
- struct bt_mgnt *pBtMgnt;
- struct bt_dgb *pBtDbg;
- u8 bRet;
-
- pHalData = GET_HAL_DATA(padapter);
- pBTInfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTInfo->BtMgnt;
- pBtDbg = &pBTInfo->BtDbg;
- bRet = false;
-
- if (pBtDbg->dbgCtrl) {
- if (pBtDbg->dbgProfile == BT_DBG_PROFILE_SCO) {
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_SCO;
- bRet = true;
- }
- } else {
- if (pBtMgnt->ExtConfig.NumberOfSCO > 0) {
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_SCO;
- bRet = true;
- }
- }
- return bRet;
-}
-
-u8 BTDM_IsActionHID(struct rtw_adapter *padapter)
-{
- struct bt_30info *pBTInfo;
- struct hal_data_8723a *pHalData;
- struct bt_mgnt *pBtMgnt;
- struct bt_dgb *pBtDbg;
- u8 bRet;
-
- pHalData = GET_HAL_DATA(padapter);
- pBTInfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTInfo->BtMgnt;
- pBtDbg = &pBTInfo->BtDbg;
- bRet = false;
-
- if (pBtDbg->dbgCtrl) {
- if (pBtDbg->dbgProfile == BT_DBG_PROFILE_HID) {
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_HID;
- bRet = true;
- }
- } else {
- if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
- pBtMgnt->ExtConfig.NumberOfHandle == 1) {
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_HID;
- bRet = true;
- }
- }
- return bRet;
-}
-
-u8 BTDM_IsActionA2DP(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct bt_30info *pBTInfo;
- struct bt_mgnt *pBtMgnt;
- struct bt_dgb *pBtDbg;
- u8 bRet;
-
- pHalData = GET_HAL_DATA(padapter);
- pBTInfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTInfo->BtMgnt;
- pBtDbg = &pBTInfo->BtDbg;
- bRet = false;
-
- if (pBtDbg->dbgCtrl) {
- if (pBtDbg->dbgProfile == BT_DBG_PROFILE_A2DP) {
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_A2DP;
- bRet = true;
- }
- } else {
- if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP) &&
- pBtMgnt->ExtConfig.NumberOfHandle == 1) {
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_A2DP;
- bRet = true;
- }
- }
- return bRet;
-}
-
-u8 BTDM_IsActionPAN(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct bt_30info *pBTInfo;
- struct bt_mgnt *pBtMgnt;
- struct bt_dgb *pBtDbg;
- u8 bRet;
-
- pHalData = GET_HAL_DATA(padapter);
- pBTInfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTInfo->BtMgnt;
- pBtDbg = &pBTInfo->BtDbg;
- bRet = false;
-
- if (pBtDbg->dbgCtrl) {
- if (pBtDbg->dbgProfile == BT_DBG_PROFILE_PAN) {
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_PAN;
- bRet = true;
- }
- } else {
- if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
- pBtMgnt->ExtConfig.NumberOfHandle == 1) {
- pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_PAN;
- bRet = true;
- }
- }
- return bRet;
-}
-
-u8 BTDM_IsActionHIDA2DP(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct bt_30info *pBTInfo;
- struct bt_mgnt *pBtMgnt;
- struct bt_dgb *pBtDbg;
- u8 bRet;
-
- pHalData = GET_HAL_DATA(padapter);
- pBTInfo = GET_BT_INFO(padapter);
- pBtMgnt = &pBTInfo->BtMgnt;
- pBtDbg = &pBTInfo->BtDbg;
- bRet = false;
-
- if (pBtDbg->dbgCtrl) {
- if (pBtDbg->dbgProfile == BT_DBG_PROFILE_HID_A2DP) {
- pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_A2DP);
- bRet = true;
- }
- } else {
- if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
- BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
- pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_A2DP);
- bRet = true;
- }
- }
- return bRet;
-}
-
-u8 BTDM_IsActionHIDPAN(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct bt_30info *pBTInfo;
- struct bt_dgb *pBtDbg;
- u8 bRet;
-
- pHalData = GET_HAL_DATA(padapter);
- pBTInfo = GET_BT_INFO(padapter);
- pBtDbg = &pBTInfo->BtDbg;
- bRet = false;
-
- if (pBtDbg->dbgCtrl) {
- if (pBtDbg->dbgProfile == BT_DBG_PROFILE_HID_PAN) {
- pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_PAN);
- bRet = true;
- }
- } else {
- if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
- BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
- pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_PAN);
- bRet = true;
- }
- }
- return bRet;
-}
-
-u8 BTDM_IsActionPANA2DP(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct bt_30info *pBTInfo;
- struct bt_dgb *pBtDbg;
- u8 bRet;
-
- pHalData = GET_HAL_DATA(padapter);
- pBTInfo = GET_BT_INFO(padapter);
- pBtDbg = &pBTInfo->BtDbg;
- bRet = false;
-
- if (pBtDbg->dbgCtrl) {
- if (pBtDbg->dbgProfile == BT_DBG_PROFILE_PAN_A2DP) {
- pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_PAN|BT_COEX_STATE_PROFILE_A2DP);
- bRet = true;
- }
- } else {
- if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) && BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
- pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_PAN|BT_COEX_STATE_PROFILE_A2DP);
- bRet = true;
- }
- }
- return bRet;
-}
-
-bool rtl8723a_BT_enabled(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (pHalData->bt_coexist.bCurBtDisabled)
- return false;
- else
- return true;
-}
-
-/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtCoexist.c ===== */
-
-/* ===== Below this line is sync from SD7 driver HAL/HalBT.c ===== */
-
-/* */
-/*local function */
-/* */
-
-static void halbt_InitHwConfig8723A(struct rtw_adapter *padapter)
-{
-}
-
-/* */
-/*extern function */
-/* */
-u8 HALBT_GetPGAntNum(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- return pHalData->bt_coexist.BT_Ant_Num;
-}
-
-void HALBT_SetKey(struct rtw_adapter *padapter, u8 EntryNum)
-{
- struct bt_30info *pBTinfo;
- struct bt_asoc_entry *pBtAssocEntry;
- u16 usConfig = 0;
-
- pBTinfo = GET_BT_INFO(padapter);
- pBtAssocEntry = &pBTinfo->BtAsocEntry[EntryNum];
-
- pBtAssocEntry->HwCAMIndex = BT_HWCAM_STAR + EntryNum;
-
- usConfig = CAM_VALID | (CAM_AES << 2);
- rtl8723a_cam_write(padapter, pBtAssocEntry->HwCAMIndex, usConfig,
- pBtAssocEntry->BTRemoteMACAddr,
- pBtAssocEntry->PTK + TKIP_ENC_KEY_POS);
-}
-
-void HALBT_RemoveKey(struct rtw_adapter *padapter, u8 EntryNum)
-{
- struct bt_30info *pBTinfo;
- struct bt_asoc_entry *pBtAssocEntry;
-
- pBTinfo = GET_BT_INFO(padapter);
- pBtAssocEntry = &pBTinfo->BtAsocEntry[EntryNum];
-
- if (pBTinfo->BtAsocEntry[EntryNum].HwCAMIndex != 0) {
- /* ToDo : add New HALBT_RemoveKey function !! */
- if (pBtAssocEntry->HwCAMIndex >= BT_HWCAM_STAR &&
- pBtAssocEntry->HwCAMIndex < HALF_CAM_ENTRY)
- rtl8723a_cam_empty_entry(padapter,
- pBtAssocEntry->HwCAMIndex);
- pBTinfo->BtAsocEntry[EntryNum].HwCAMIndex = 0;
- }
-}
-
-void rtl8723a_BT_init_hal_vars(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
-
- pHalData = GET_HAL_DATA(padapter);
-
- pHalData->bt_coexist.BluetoothCoexist = pHalData->EEPROMBluetoothCoexist;
- pHalData->bt_coexist.BT_Ant_Num = pHalData->EEPROMBluetoothAntNum;
- pHalData->bt_coexist.BT_CoexistType = pHalData->EEPROMBluetoothType;
- pHalData->bt_coexist.BT_Ant_isolation = pHalData->EEPROMBluetoothAntIsolation;
- pHalData->bt_coexist.bt_radiosharedtype = pHalData->EEPROMBluetoothRadioShared;
-
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "BT Coexistance = 0x%x\n", rtl8723a_BT_coexist(padapter));
-
- if (rtl8723a_BT_coexist(padapter)) {
- if (pHalData->bt_coexist.BT_Ant_Num == Ant_x2) {
- BTDM_SetBtCoexCurrAntNum(padapter, 2);
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "BlueTooth BT_Ant_Num = Antx2\n");
- } else if (pHalData->bt_coexist.BT_Ant_Num == Ant_x1) {
- BTDM_SetBtCoexCurrAntNum(padapter, 1);
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "BlueTooth BT_Ant_Num = Antx1\n");
- }
- pHalData->bt_coexist.bBTBusyTraffic = false;
- pHalData->bt_coexist.bBTTrafficModeSet = false;
- pHalData->bt_coexist.bBTNonTrafficModeSet = false;
- pHalData->bt_coexist.CurrentState = 0;
- pHalData->bt_coexist.PreviousState = 0;
-
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "bt_radiosharedType = 0x%x\n",
- pHalData->bt_coexist.bt_radiosharedtype);
- }
-}
-
-bool rtl8723a_BT_coexist(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (pHalData->bt_coexist.BluetoothCoexist)
- return true;
- else
- return false;
-}
-
-u8 HALBT_BTChipType(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- return pHalData->bt_coexist.BT_CoexistType;
-}
-
-void rtl8723a_BT_init_hwconfig(struct rtw_adapter *padapter)
-{
- halbt_InitHwConfig8723A(padapter);
- rtl8723a_BT_do_coexist(padapter);
-}
-
-void HALBT_SetRtsCtsNoLenLimit(struct rtw_adapter *padapter)
-{
-}
-
-/* ===== End of sync from SD7 driver HAL/HalBT.c ===== */
-
-void rtl8723a_dual_antenna_detection(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct dm_odm_t *pDM_Odm;
- struct sw_ant_sw *pDM_SWAT_Table;
- u8 i;
-
- pHalData = GET_HAL_DATA(padapter);
- pDM_Odm = &pHalData->odmpriv;
- pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table;
-
- /* */
- /* <Roger_Notes> RTL8723A Single and Dual antenna dynamic detection
- mechanism when RF power state is on. */
- /* We should take power tracking, IQK, LCK, RCK RF read/write
- operation into consideration. */
- /* 2011.12.15. */
- /* */
- if (!pHalData->bAntennaDetected) {
- u8 btAntNum = BT_GetPGAntNum(padapter);
-
- /* Set default antenna B status */
- if (btAntNum == Ant_x2)
- pDM_SWAT_Table->ANTB_ON = true;
- else if (btAntNum == Ant_x1)
- pDM_SWAT_Table->ANTB_ON = false;
- else
- pDM_SWAT_Table->ANTB_ON = true;
-
- if (pHalData->CustomerID != RT_CID_TOSHIBA) {
- for (i = 0; i < MAX_ANTENNA_DETECTION_CNT; i++) {
- if (ODM_SingleDualAntennaDetection
- (&pHalData->odmpriv, ANTTESTALL) == true)
- break;
- }
-
- /* Set default antenna number for BT coexistence */
- if (btAntNum == Ant_x2)
- BT_SetBtCoexCurrAntNum(padapter,
- pDM_SWAT_Table->
- ANTB_ON ? 2 : 1);
- }
- pHalData->bAntennaDetected = true;
- }
-}
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c
deleted file mode 100644
index 2230f4c539ec..000000000000
--- a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c
+++ /dev/null
@@ -1,755 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTL8723A_CMD_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <recv_osdep.h>
-#include <mlme_osdep.h>
-#include <rtl8723a_hal.h>
-#include <usb_ops_linux.h>
-
-#define RTL92C_MAX_H2C_BOX_NUMS 4
-#define RTL92C_MAX_CMD_LEN 5
-#define MESSAGE_BOX_SIZE 4
-#define EX_MESSAGE_BOX_SIZE 2
-
-static u8 _is_fw_read_cmd_down(struct rtw_adapter *padapter, u8 msgbox_num)
-{
- u8 read_down = false;
- int retry_cnts = 100;
- u8 valid;
-
- do {
- valid = rtl8723au_read8(padapter, REG_HMETFR) & BIT(msgbox_num);
- if (0 == valid)
- read_down = true;
- } while ((!read_down) && (retry_cnts--));
-
- return read_down;
-}
-
-/*****************************************
-* H2C Msg format :
-*| 31 - 8 |7 | 6 - 0 |
-*| h2c_msg |Ext_bit |CMD_ID |
-*
-******************************************/
-int FillH2CCmd(struct rtw_adapter *padapter, u8 ElementID, u32 CmdLen,
- u8 *pCmdBuffer)
-{
- u8 bcmd_down = false;
- s32 retry_cnts = 100;
- u8 h2c_box_num;
- u32 msgbox_addr;
- u32 msgbox_ex_addr;
- struct hal_data_8723a *pHalData;
- u32 h2c_cmd = 0;
- u16 h2c_cmd_ex = 0;
- int ret = _FAIL;
-
- padapter = GET_PRIMARY_ADAPTER(padapter);
- pHalData = GET_HAL_DATA(padapter);
-
- mutex_lock(&adapter_to_dvobj(padapter)->h2c_fwcmd_mutex);
-
- if (!pCmdBuffer)
- goto exit;
- if (CmdLen > RTL92C_MAX_CMD_LEN)
- goto exit;
- if (padapter->bSurpriseRemoved == true)
- goto exit;
-
- /* pay attention to if race condition happened in H2C cmd setting. */
- do {
- h2c_box_num = pHalData->LastHMEBoxNum;
-
- if (!_is_fw_read_cmd_down(padapter, h2c_box_num)) {
- DBG_8723A(" fw read cmd failed...\n");
- goto exit;
- }
-
- if (CmdLen <= 3) {
- memcpy((u8 *)(&h2c_cmd)+1, pCmdBuffer, CmdLen);
- } else {
- memcpy((u8 *)(&h2c_cmd_ex), pCmdBuffer, EX_MESSAGE_BOX_SIZE);
- memcpy((u8 *)(&h2c_cmd)+1, pCmdBuffer+2, (CmdLen-EX_MESSAGE_BOX_SIZE));
- *(u8 *)(&h2c_cmd) |= BIT(7);
- }
-
- *(u8 *)(&h2c_cmd) |= ElementID;
-
- if (h2c_cmd & BIT(7)) {
- msgbox_ex_addr = REG_HMEBOX_EXT_0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE);
- h2c_cmd_ex = le16_to_cpu(h2c_cmd_ex);
- rtl8723au_write16(padapter, msgbox_ex_addr, h2c_cmd_ex);
- }
- msgbox_addr = REG_HMEBOX_0 + (h2c_box_num * MESSAGE_BOX_SIZE);
- h2c_cmd = le32_to_cpu(h2c_cmd);
- rtl8723au_write32(padapter, msgbox_addr, h2c_cmd);
-
- bcmd_down = true;
-
- pHalData->LastHMEBoxNum = (h2c_box_num+1) % RTL92C_MAX_H2C_BOX_NUMS;
-
- } while ((!bcmd_down) && (retry_cnts--));
-
- ret = _SUCCESS;
-
-exit:
- mutex_unlock(&adapter_to_dvobj(padapter)->h2c_fwcmd_mutex);
- return ret;
-}
-
-int rtl8723a_set_rssi_cmd(struct rtw_adapter *padapter, u32 param)
-{
- __le32 cmd = cpu_to_le32(param);
-
- FillH2CCmd(padapter, RSSI_SETTING_EID, 3, (void *)&cmd);
-
- return _SUCCESS;
-}
-
-int rtl8723a_set_raid_cmd(struct rtw_adapter *padapter, u32 mask, u8 arg)
-{
- u8 buf[5];
-
- memset(buf, 0, 5);
- put_unaligned_le32(mask, buf);
- buf[4] = arg;
-
- FillH2CCmd(padapter, MACID_CONFIG_EID, 5, buf);
-
- return _SUCCESS;
-}
-
-/* bitmap[0:27] = tx_rate_bitmap */
-/* bitmap[28:31]= Rate Adaptive id */
-/* arg[0:4] = macid */
-/* arg[5] = Short GI */
-void rtl8723a_add_rateatid(struct rtw_adapter *pAdapter, u32 bitmap, u8 arg, u8 rssi_level)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
- u8 macid = arg & 0x1f;
- u32 raid = bitmap & 0xf0000000;
-
- bitmap &= 0x0fffffff;
- if (rssi_level != DM_RATR_STA_INIT)
- bitmap = ODM_Get_Rate_Bitmap23a(pHalData, macid, bitmap,
- rssi_level);
-
- bitmap |= raid;
-
- rtl8723a_set_raid_cmd(pAdapter, bitmap, arg);
-}
-
-void rtl8723a_set_FwPwrMode_cmd(struct rtw_adapter *padapter, u8 Mode)
-{
- struct setpwrmode_parm H2CSetPwrMode;
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- DBG_8723A("%s: Mode =%d SmartPS =%d UAPSD =%d BcnMode = 0x%02x\n", __func__,
- Mode, pwrpriv->smart_ps, padapter->registrypriv.uapsd_enable, pwrpriv->bcn_ant_mode);
-
- /* Forece leave RF low power mode for 1T1R to
- prevent conficting setting in Fw power */
- /* saving sequence. 2010.06.07. Added by tynli.
- Suggested by SD3 yschang. */
- if (Mode != PS_MODE_ACTIVE && pHalData->rf_type != RF_2T2R)
- ODM_RF_Saving23a(&pHalData->odmpriv, true);
-
- H2CSetPwrMode.Mode = Mode;
- H2CSetPwrMode.SmartPS = pwrpriv->smart_ps;
- H2CSetPwrMode.AwakeInterval = 1;
- H2CSetPwrMode.bAllQueueUAPSD = padapter->registrypriv.uapsd_enable;
- H2CSetPwrMode.BcnAntMode = pwrpriv->bcn_ant_mode;
-
- FillH2CCmd(padapter, SET_PWRMODE_EID, sizeof(H2CSetPwrMode), (u8 *)&H2CSetPwrMode);
-
-}
-
-static void
-ConstructBeacon(struct rtw_adapter *padapter, u8 *pframe, u32 *pLength)
-{
- struct ieee80211_mgmt *mgmt;
- u32 rate_len, pktlen;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
- u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
- /* DBG_8723A("%s\n", __func__); */
-
- mgmt = (struct ieee80211_mgmt *)pframe;
-
- mgmt->frame_control =
- cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
-
- ether_addr_copy(mgmt->da, bc_addr);
- ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
- ether_addr_copy(mgmt->bssid, get_my_bssid23a(cur_network));
-
- /* A Beacon frame shouldn't have fragment bits set */
- mgmt->seq_ctrl = 0;
-
- /* timestamp will be inserted by hardware */
-
- put_unaligned_le16(cur_network->beacon_interval,
- &mgmt->u.beacon.beacon_int);
-
- put_unaligned_le16(cur_network->capability,
- &mgmt->u.beacon.capab_info);
-
- pframe = mgmt->u.beacon.variable;
- pktlen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
-
- if ((pmlmeinfo->state&0x03) == MSR_AP) {
- /* DBG_8723A("ie len =%d\n", cur_network->IELength); */
- pktlen += cur_network->IELength;
- memcpy(pframe, cur_network->IEs, pktlen);
-
- goto _ConstructBeacon;
- }
-
- /* below for ad-hoc mode */
-
- /* SSID */
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
- cur_network->Ssid.ssid_len,
- cur_network->Ssid.ssid, &pktlen);
-
- /* supported rates... */
- rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
- pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, ((rate_len > 8) ?
- 8 : rate_len), cur_network->SupportedRates, &pktlen);
-
- /* DS parameter set */
- pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)
- &cur_network->DSConfig, &pktlen);
-
- if ((pmlmeinfo->state&0x03) == MSR_ADHOC) {
- u32 ATIMWindow;
- /* IBSS Parameter Set... */
- /* ATIMWindow = cur->ATIMWindow; */
- ATIMWindow = 0;
- pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
- (unsigned char *)&ATIMWindow, &pktlen);
- }
-
- /* todo: ERP IE */
-
- /* EXTERNDED SUPPORTED RATE */
- if (rate_len > 8)
- pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
- (rate_len - 8),
- (cur_network->SupportedRates + 8),
- &pktlen);
-
- /* todo:HT for adhoc */
-
-_ConstructBeacon:
-
- if ((pktlen + TXDESC_SIZE) > 512) {
- DBG_8723A("beacon frame too large\n");
- return;
- }
-
- *pLength = pktlen;
-
- /* DBG_8723A("%s bcn_sz =%d\n", __func__, pktlen); */
-
-}
-
-static void ConstructPSPoll(struct rtw_adapter *padapter,
- u8 *pframe, u32 *pLength)
-{
- struct ieee80211_hdr *pwlanhdr;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- pwlanhdr = (struct ieee80211_hdr *)pframe;
-
- /* Frame control. */
- pwlanhdr->frame_control =
- cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
- pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
-
- /* AID. */
- pwlanhdr->duration_id = cpu_to_le16(pmlmeinfo->aid | 0xc000);
-
- /* BSSID. */
- memcpy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN);
-
- /* TA. */
- memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-
- *pLength = 16;
-}
-
-static void
-ConstructNullFunctionData(struct rtw_adapter *padapter, u8 *pframe,
- u32 *pLength, u8 *StaAddr, u8 bQoS, u8 AC,
- u8 bEosp, u8 bForcePowerSave)
-{
- struct ieee80211_hdr *pwlanhdr;
- u32 pktlen;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_network *cur_network = &pmlmepriv->cur_network;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- pwlanhdr = (struct ieee80211_hdr *)pframe;
-
- pwlanhdr->frame_control = 0;
- pwlanhdr->seq_ctrl = 0;
-
- if (bForcePowerSave)
- pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
-
- switch (cur_network->network.ifmode) {
- case NL80211_IFTYPE_P2P_CLIENT:
- case NL80211_IFTYPE_STATION:
- pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_TODS);
- memcpy(pwlanhdr->addr1,
- get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv),
- ETH_ALEN);
- memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
- break;
- case NL80211_IFTYPE_P2P_GO:
- case NL80211_IFTYPE_AP:
- pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
- memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2,
- get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN);
- memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv),
- ETH_ALEN);
- break;
- case NL80211_IFTYPE_ADHOC:
- default:
- memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
- memcpy(pwlanhdr->addr3,
- get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN);
- break;
- }
-
- if (bQoS == true) {
- struct ieee80211_qos_hdr *qoshdr;
- qoshdr = (struct ieee80211_qos_hdr *)pframe;
-
- qoshdr->frame_control |=
- cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_QOS_NULLFUNC);
-
- qoshdr->qos_ctrl = cpu_to_le16(AC & IEEE80211_QOS_CTL_TID_MASK);
- if (bEosp)
- qoshdr->qos_ctrl |= cpu_to_le16(IEEE80211_QOS_CTL_EOSP);
-
- pktlen = sizeof(struct ieee80211_qos_hdr);
- } else {
- pwlanhdr->frame_control |=
- cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_NULLFUNC);
-
- pktlen = sizeof(struct ieee80211_hdr_3addr);
- }
-
- *pLength = pktlen;
-}
-
-static void ConstructProbeRsp(struct rtw_adapter *padapter, u8 *pframe,
- u32 *pLength, u8 *StaAddr, bool bHideSSID)
-{
- struct ieee80211_mgmt *mgmt;
- u8 *mac, *bssid;
- u32 pktlen;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
-
- /* DBG_8723A("%s\n", __func__); */
-
- mgmt = (struct ieee80211_mgmt *)pframe;
-
- mac = myid(&padapter->eeprompriv);
- bssid = cur_network->MacAddress;
-
- mgmt->frame_control =
- cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
-
- mgmt->seq_ctrl = 0;
-
- memcpy(mgmt->da, StaAddr, ETH_ALEN);
- memcpy(mgmt->sa, mac, ETH_ALEN);
- memcpy(mgmt->bssid, bssid, ETH_ALEN);
-
- put_unaligned_le64(cur_network->tsf,
- &mgmt->u.probe_resp.timestamp);
- put_unaligned_le16(cur_network->beacon_interval,
- &mgmt->u.probe_resp.beacon_int);
- put_unaligned_le16(cur_network->capability,
- &mgmt->u.probe_resp.capab_info);
-
- pktlen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
-
- if (cur_network->IELength > MAX_IE_SZ)
- return;
-
- memcpy(mgmt->u.probe_resp.variable, cur_network->IEs,
- cur_network->IELength);
- pktlen += (cur_network->IELength);
-
- *pLength = pktlen;
-}
-
-/* */
-/* Description: Fill the reserved packets that FW will use to RSVD page. */
-/* Now we just send 4 types packet to rsvd page. */
-/* (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp. */
-/* Input: */
-/* bDLFinished - false: At the first time we will send all the packets as a large packet to Hw, */
-/* so we need to set the packet length to total lengh. */
-/* true: At the second time, we should send the first packet (default:beacon) */
-/* to Hw again and set the lengh in descriptor to the real beacon lengh. */
-/* 2009.10.15 by tynli. */
-static void SetFwRsvdPagePkt(struct rtw_adapter *padapter, bool bDLFinished)
-{
- struct hal_data_8723a *pHalData;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct xmit_priv *pxmitpriv;
- struct mlme_ext_priv *pmlmeext;
- struct mlme_ext_info *pmlmeinfo;
- u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength;
- u32 NullDataLength, QosNullLength, BTQosNullLength;
- u8 *ReservedPagePacket;
- u8 PageNum, PageNeed, TxDescLen;
- u16 BufIndex;
- u32 TotalPacketLen;
- struct rsvdpage_loc RsvdPageLoc;
-
- DBG_8723A("%s\n", __func__);
-
- ReservedPagePacket = kzalloc(1000, GFP_KERNEL);
- if (ReservedPagePacket == NULL) {
- DBG_8723A("%s: alloc ReservedPagePacket fail!\n", __func__);
- return;
- }
-
- pHalData = GET_HAL_DATA(padapter);
- pxmitpriv = &padapter->xmitpriv;
- pmlmeext = &padapter->mlmeextpriv;
- pmlmeinfo = &pmlmeext->mlmext_info;
-
- TxDescLen = TXDESC_SIZE;
- PageNum = 0;
-
- /* 3 (1) beacon */
- BufIndex = TXDESC_OFFSET;
- ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength);
-
- /* When we count the first page size, we need to reserve description size for the RSVD */
- /* packet, it will be filled in front of the packet in TXPKTBUF. */
- PageNeed = (u8)PageNum_128(TxDescLen + BeaconLength);
- /* To reserved 2 pages for beacon buffer. 2010.06.24. */
- if (PageNeed == 1)
- PageNeed += 1;
- PageNum += PageNeed;
- pHalData->FwRsvdPageStartOffset = PageNum;
-
- BufIndex += PageNeed*128;
-
- /* 3 (2) ps-poll */
- RsvdPageLoc.LocPsPoll = PageNum;
- ConstructPSPoll(padapter, &ReservedPagePacket[BufIndex], &PSPollLength);
- rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], PSPollLength, true, false);
-
- PageNeed = (u8)PageNum_128(TxDescLen + PSPollLength);
- PageNum += PageNeed;
-
- BufIndex += PageNeed*128;
-
- /* 3 (3) null data */
- RsvdPageLoc.LocNullData = PageNum;
- ConstructNullFunctionData(padapter, &ReservedPagePacket[BufIndex],
- &NullDataLength,
- get_my_bssid23a(&pmlmeinfo->network),
- false, 0, 0, false);
- rtl8723a_fill_fake_txdesc(padapter,
- &ReservedPagePacket[BufIndex-TxDescLen],
- NullDataLength, false, false);
-
- PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength);
- PageNum += PageNeed;
-
- BufIndex += PageNeed*128;
-
- /* 3 (4) probe response */
- RsvdPageLoc.LocProbeRsp = PageNum;
- ConstructProbeRsp(
- padapter,
- &ReservedPagePacket[BufIndex],
- &ProbeRspLength,
- get_my_bssid23a(&pmlmeinfo->network),
- false);
- rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, false, false);
-
- PageNeed = (u8)PageNum_128(TxDescLen + ProbeRspLength);
- PageNum += PageNeed;
-
- BufIndex += PageNeed*128;
-
- /* 3 (5) Qos null data */
- RsvdPageLoc.LocQosNull = PageNum;
- ConstructNullFunctionData(
- padapter,
- &ReservedPagePacket[BufIndex],
- &QosNullLength,
- get_my_bssid23a(&pmlmeinfo->network),
- true, 0, 0, false);
- rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], QosNullLength, false, false);
-
- PageNeed = (u8)PageNum_128(TxDescLen + QosNullLength);
- PageNum += PageNeed;
-
- BufIndex += PageNeed*128;
-
- /* 3 (6) BT Qos null data */
- RsvdPageLoc.LocBTQosNull = PageNum;
- ConstructNullFunctionData(
- padapter,
- &ReservedPagePacket[BufIndex],
- &BTQosNullLength,
- get_my_bssid23a(&pmlmeinfo->network),
- true, 0, 0, false);
- rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, false, true);
-
- TotalPacketLen = BufIndex + BTQosNullLength;
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (pmgntframe == NULL)
- goto exit;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
- pattrib->qsel = 0x10;
- pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TXDESC_OFFSET;
- memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen);
-
- rtl8723au_mgnt_xmit(padapter, pmgntframe);
-
- DBG_8723A("%s: Set RSVD page location to Fw\n", __func__);
- FillH2CCmd(padapter, RSVD_PAGE_EID, sizeof(RsvdPageLoc), (u8 *)&RsvdPageLoc);
-
-exit:
- kfree(ReservedPagePacket);
-}
-
-void rtl8723a_set_FwJoinBssReport_cmd(struct rtw_adapter *padapter, u8 mstatus)
-{
- struct joinbssrpt_parm JoinBssRptParm;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- DBG_8723A("%s mstatus(%x)\n", __func__, mstatus);
-
- if (mstatus == 1) {
- bool bRecover = false;
- u8 v8;
-
- /* We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C. */
- /* Suggested by filen. Added by tynli. */
- rtl8723au_write16(padapter, REG_BCN_PSR_RPT,
- 0xC000|pmlmeinfo->aid);
- /* Do not set TSF again here or vWiFi beacon DMA INT will not work. */
- /* correct_TSF23a(padapter, pmlmeext); */
- /* Hw sequende enable by dedault. 2010.06.23. by tynli. */
- /* rtl8723au_write16(padapter, REG_NQOS_SEQ, ((pmlmeext->mgnt_seq+100)&0xFFF)); */
- /* rtl8723au_write8(padapter, REG_HWSEQ_CTRL, 0xFF); */
-
- /* set REG_CR bit 8 */
- v8 = rtl8723au_read8(padapter, REG_CR+1);
- v8 |= BIT(0); /* ENSWBCN */
- rtl8723au_write8(padapter, REG_CR+1, v8);
-
- /* Disable Hw protection for a time which revserd for Hw sending beacon. */
- /* Fix download reserved page packet fail that access collision with the protection time. */
- /* 2010.05.11. Added by tynli. */
-/* SetBcnCtrlReg23a(padapter, 0, BIT(3)); */
-/* SetBcnCtrlReg23a(padapter, BIT(4), 0); */
- SetBcnCtrlReg23a(padapter, BIT(4), BIT(3));
-
- /* Set FWHW_TXQ_CTRL 0x422[6]= 0 to tell Hw the packet is not a real beacon frame. */
- if (pHalData->RegFwHwTxQCtrl & BIT(6))
- bRecover = true;
-
- /* To tell Hw the packet is not a real beacon frame. */
- /* U1bTmp = rtl8723au_read8(padapter, REG_FWHW_TXQ_CTRL+2); */
- rtl8723au_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
- pHalData->RegFwHwTxQCtrl & ~BIT(6));
- pHalData->RegFwHwTxQCtrl &= ~BIT(6);
- SetFwRsvdPagePkt(padapter, 0);
-
- /* 2010.05.11. Added by tynli. */
- SetBcnCtrlReg23a(padapter, BIT(3), BIT(4));
-
- /* To make sure that if there exists an adapter which would like to send beacon. */
- /* If exists, the origianl value of 0x422[6] will be 1, we should check this to */
- /* prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */
- /* the beacon cannot be sent by HW. */
- /* 2010.06.23. Added by tynli. */
- if (bRecover) {
- rtl8723au_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
- pHalData->RegFwHwTxQCtrl | BIT(6));
- pHalData->RegFwHwTxQCtrl |= BIT(6);
- }
-
- /* Clear CR[8] or beacon packet will not be send to TxBuf anymore. */
- v8 = rtl8723au_read8(padapter, REG_CR+1);
- v8 &= ~BIT(0); /* ~ENSWBCN */
- rtl8723au_write8(padapter, REG_CR+1, v8);
- }
-
- JoinBssRptParm.OpMode = mstatus;
-
- FillH2CCmd(padapter, JOINBSS_RPT_EID, sizeof(JoinBssRptParm), (u8 *)&JoinBssRptParm);
-
-}
-
-#ifdef CONFIG_8723AU_BT_COEXIST
-static void SetFwRsvdPagePkt_BTCoex(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct xmit_priv *pxmitpriv;
- struct mlme_ext_priv *pmlmeext;
- struct mlme_ext_info *pmlmeinfo;
- u8 fakemac[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x00};
- u32 NullDataLength, BTQosNullLength;
- u8 *ReservedPagePacket;
- u8 PageNum, PageNeed, TxDescLen;
- u16 BufIndex;
- u32 TotalPacketLen;
- struct rsvdpage_loc RsvdPageLoc;
-
- DBG_8723A("+%s\n", __func__);
-
- ReservedPagePacket = kzalloc(1024, GFP_KERNEL);
- if (ReservedPagePacket == NULL) {
- DBG_8723A("%s: alloc ReservedPagePacket fail!\n", __func__);
- return;
- }
-
- pHalData = GET_HAL_DATA(padapter);
- pxmitpriv = &padapter->xmitpriv;
- pmlmeext = &padapter->mlmeextpriv;
- pmlmeinfo = &pmlmeext->mlmext_info;
-
- TxDescLen = TXDESC_SIZE;
- PageNum = 0;
-
- /* 3 (1) beacon */
- BufIndex = TXDESC_OFFSET;
- /* skip Beacon Packet */
- PageNeed = 3;
-
- PageNum += PageNeed;
- pHalData->FwRsvdPageStartOffset = PageNum;
-
- BufIndex += PageNeed*128;
-
- /* 3 (3) null data */
- RsvdPageLoc.LocNullData = PageNum;
- ConstructNullFunctionData(
- padapter,
- &ReservedPagePacket[BufIndex],
- &NullDataLength,
- fakemac,
- false, 0, 0, false);
- rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], NullDataLength, false, false);
-
- PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength);
- PageNum += PageNeed;
-
- BufIndex += PageNeed*128;
-
- /* 3 (6) BT Qos null data */
- RsvdPageLoc.LocBTQosNull = PageNum;
- ConstructNullFunctionData(
- padapter,
- &ReservedPagePacket[BufIndex],
- &BTQosNullLength,
- fakemac,
- true, 0, 0, false);
- rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, false, true);
-
- TotalPacketLen = BufIndex + BTQosNullLength;
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (pmgntframe == NULL)
- goto exit;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
- pattrib->qsel = 0x10;
- pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TXDESC_OFFSET;
- memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen);
-
- rtl8723au_mgnt_xmit(padapter, pmgntframe);
-
- DBG_8723A("%s: Set RSVD page location to Fw\n", __func__);
- FillH2CCmd(padapter, RSVD_PAGE_EID, sizeof(RsvdPageLoc), (u8 *)&RsvdPageLoc);
-
-exit:
- kfree(ReservedPagePacket);
-}
-
-void rtl8723a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- u8 bRecover = false;
-
- DBG_8723A("+%s\n", __func__);
-
- pHalData = GET_HAL_DATA(padapter);
-
- /* Set FWHW_TXQ_CTRL 0x422[6]= 0 to tell Hw the packet is not a real beacon frame. */
- if (pHalData->RegFwHwTxQCtrl & BIT(6))
- bRecover = true;
-
- /* To tell Hw the packet is not a real beacon frame. */
- pHalData->RegFwHwTxQCtrl &= ~BIT(6);
- rtl8723au_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
- pHalData->RegFwHwTxQCtrl);
- SetFwRsvdPagePkt_BTCoex(padapter);
-
- /* To make sure that if there exists an adapter which would like to send beacon. */
- /* If exists, the origianl value of 0x422[6] will be 1, we should check this to */
- /* prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */
- /* the beacon cannot be sent by HW. */
- /* 2010.06.23. Added by tynli. */
- if (bRecover) {
- pHalData->RegFwHwTxQCtrl |= BIT(6);
- rtl8723au_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
- pHalData->RegFwHwTxQCtrl);
- }
-}
-#endif
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c
deleted file mode 100644
index 1e831f2d1caf..000000000000
--- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-/* */
-/* Description: */
-/* */
-/* This file is for 92CE/92CU dynamic mechanism only */
-/* */
-/* */
-/* */
-#define _RTL8723A_DM_C_
-
-/* */
-/* include files */
-/* */
-#include <osdep_service.h>
-#include <drv_types.h>
-
-#include <rtl8723a_hal.h>
-#include <usb_ops_linux.h>
-
-/* */
-/* Global var */
-/* */
-
-static void dm_CheckPbcGPIO(struct rtw_adapter *padapter)
-{
- u8 tmp1byte;
- u8 bPbcPressed = false;
-
- if (!padapter->registrypriv.hw_wps_pbc)
- return;
-
- tmp1byte = rtl8723au_read8(padapter, GPIO_IO_SEL);
- tmp1byte |= (HAL_8192C_HW_GPIO_WPS_BIT);
- /* enable GPIO[2] as output mode */
- rtl8723au_write8(padapter, GPIO_IO_SEL, tmp1byte);
-
- tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
- /* reset the floating voltage level */
- rtl8723au_write8(padapter, GPIO_IN, tmp1byte);
-
- tmp1byte = rtl8723au_read8(padapter, GPIO_IO_SEL);
- tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
- /* enable GPIO[2] as input mode */
- rtl8723au_write8(padapter, GPIO_IO_SEL, tmp1byte);
-
- tmp1byte = rtl8723au_read8(padapter, GPIO_IN);
-
- if (tmp1byte == 0xff)
- return;
-
- if (tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT)
- bPbcPressed = true;
-
- if (bPbcPressed) {
- /* Here we only set bPbcPressed to true */
- /* After trigger PBC, the variable will be set to false */
- DBG_8723A("CheckPbcGPIO - PBC is pressed\n");
-
- if (padapter->pid[0] == 0) {
- /* 0 is the default value and it means the application
- * monitors the HW PBC doesn't privde its pid to driver.
- */
- return;
- }
-
- kill_pid(find_vpid(padapter->pid[0]), SIGUSR1, 1);
- }
-}
-
-/* Initialize GPIO setting registers */
-/* functions */
-
-void rtl8723a_init_dm_priv(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
- struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
- u8 cut_ver, fab_ver;
-
- memset(pdmpriv, 0, sizeof(struct dm_priv));
- memset(pDM_Odm, 0, sizeof(*pDM_Odm));
-
- pDM_Odm->Adapter = Adapter;
-
- ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_IC_TYPE, ODM_RTL8723A);
-
- if (IS_8723A_A_CUT(pHalData->VersionID)) {
- fab_ver = ODM_UMC;
- cut_ver = ODM_CUT_A;
- } else if (IS_8723A_B_CUT(pHalData->VersionID)) {
- fab_ver = ODM_UMC;
- cut_ver = ODM_CUT_B;
- } else {
- fab_ver = ODM_TSMC;
- cut_ver = ODM_CUT_A;
- }
- ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_FAB_VER, fab_ver);
- ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_CUT_VER, cut_ver);
- ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(pHalData->VersionID));
-
- ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_BOARD_TYPE, pHalData->BoardType);
-
- if (pHalData->BoardType == BOARD_USB_High_PA) {
- ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_EXT_LNA, true);
- ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_EXT_PA, true);
- }
- ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_BWIFI_TEST, Adapter->registrypriv.wifi_spec);
-}
-
-static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
- int i;
- pdmpriv->InitODMFlag = 0;
- /* Pointer reference */
- rtl8723a_odm_support_ability_set(Adapter, DYNAMIC_ALL_FUNC_ENABLE);
-
- for (i = 0; i < NUM_STA; i++)
- ODM_CmnInfoPtrArrayHook23a(pDM_Odm, ODM_CMNINFO_STA_STATUS, i, NULL);
-}
-
-void rtl8723a_InitHalDm(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
- struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
- u8 i;
-
- Update_ODM_ComInfo_8723a(Adapter);
- ODM23a_DMInit(pDM_Odm);
- /* Save REG_INIDATA_RATE_SEL value for TXDESC. */
- for (i = 0; i < 32; i++)
- pdmpriv->INIDATA_RATE[i] = rtl8723au_read8(Adapter, REG_INIDATA_RATE_SEL+i) & 0x3f;
-}
-
-void
-rtl8723a_HalDmWatchDog(
- struct rtw_adapter *Adapter
- )
-{
- bool bFwCurrentInPSMode = false;
- bool bFwPSAwake = true;
- u8 bLinked = false;
- u8 hw_init_completed = false;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
-
- hw_init_completed = Adapter->hw_init_completed;
-
- if (hw_init_completed == false)
- goto skip_dm;
-
- bFwCurrentInPSMode = Adapter->pwrctrlpriv.bFwCurrentInPSMode;
- bFwPSAwake = rtl8723a_get_fwlps_rf_on(Adapter);
-
- if (!bFwCurrentInPSMode && bFwPSAwake) {
- /* Read REG_INIDATA_RATE_SEL value for TXDESC. */
- if (check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE)) {
- pdmpriv->INIDATA_RATE[0] = rtl8723au_read8(Adapter, REG_INIDATA_RATE_SEL) & 0x3f;
- } else {
- u8 i;
- for (i = 1 ; i < (Adapter->stapriv.asoc_sta_count + 1); i++)
- pdmpriv->INIDATA_RATE[i] = rtl8723au_read8(Adapter, (REG_INIDATA_RATE_SEL+i)) & 0x3f;
- }
- }
-
- /* ODM */
- if (rtw_linked_check(Adapter))
- bLinked = true;
-
- ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_LINK, bLinked);
- ODM_DMWatchdog23a(Adapter);
-
-skip_dm:
-
- /* Check GPIO to determine current RF on/off and Pbc status. */
- /* Check Hardware Radio ON/OFF or not */
- dm_CheckPbcGPIO(Adapter);
-}
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c
deleted file mode 100644
index 1ea0af499ce9..000000000000
--- a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c
+++ /dev/null
@@ -1,2076 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _HAL_INIT_C_
-
-#include <linux/firmware.h>
-#include <drv_types.h>
-#include <rtw_efuse.h>
-
-#include <rtl8723a_hal.h>
-#include <usb_ops_linux.h>
-
-static void _FWDownloadEnable(struct rtw_adapter *padapter, bool enable)
-{
- u8 tmp;
-
- if (enable) {
- /* 8051 enable */
- tmp = rtl8723au_read8(padapter, REG_SYS_FUNC_EN + 1);
- rtl8723au_write8(padapter, REG_SYS_FUNC_EN + 1, tmp | 0x04);
-
- /* MCU firmware download enable. */
- tmp = rtl8723au_read8(padapter, REG_MCUFWDL);
- rtl8723au_write8(padapter, REG_MCUFWDL, tmp | 0x01);
-
- /* 8051 reset */
- tmp = rtl8723au_read8(padapter, REG_MCUFWDL + 2);
- rtl8723au_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
- } else {
- /* MCU firmware download disable. */
- tmp = rtl8723au_read8(padapter, REG_MCUFWDL);
- rtl8723au_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
-
- /* Reserved for fw extension. */
- rtl8723au_write8(padapter, REG_MCUFWDL + 1, 0x00);
- }
-}
-
-static int
-_PageWrite(struct rtw_adapter *padapter, u32 page, void *buffer, u32 size)
-{
- u8 value8;
- u8 u8Page = (u8) (page & 0x07);
-
- if (size > MAX_PAGE_SIZE)
- return _FAIL;
-
- value8 = (rtl8723au_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
- rtl8723au_write8(padapter, REG_MCUFWDL + 2, value8);
-
- return rtl8723au_writeN(padapter, FW_8723A_START_ADDRESS, size, buffer);
-}
-
-static int _WriteFW(struct rtw_adapter *padapter, void *buffer, u32 size)
-{
- /* Since we need dynamic decide method of dwonload fw, so we
- call this function to get chip version. */
- /* We can remove _ReadChipVersion from ReadpadapterInfo8192C later. */
- int ret = _SUCCESS;
- u32 pageNums, remainSize;
- u32 page, offset;
- u8 *bufferPtr = (u8 *) buffer;
-
- pageNums = size / MAX_PAGE_SIZE;
- /* RT_ASSERT((pageNums <= 4),
- ("Page numbers should not greater then 4 \n")); */
- remainSize = size % MAX_PAGE_SIZE;
-
- for (page = 0; page < pageNums; page++) {
- offset = page * MAX_PAGE_SIZE;
- ret = _PageWrite(padapter, page, bufferPtr + offset,
- MAX_PAGE_SIZE);
-
- if (ret == _FAIL)
- goto exit;
- }
- if (remainSize) {
- offset = pageNums * MAX_PAGE_SIZE;
- page = pageNums;
- ret = _PageWrite(padapter, page, bufferPtr + offset,
- remainSize);
-
- if (ret == _FAIL)
- goto exit;
- }
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "_WriteFW Done- for Normal chip.\n");
-
-exit:
- return ret;
-}
-
-static int _FWFreeToGo(struct rtw_adapter *padapter)
-{
- u32 counter = 0;
- u32 value32;
-
- /* polling CheckSum report */
- do {
- value32 = rtl8723au_read32(padapter, REG_MCUFWDL);
- if (value32 & FWDL_ChkSum_rpt)
- break;
- } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
-
- if (counter >= POLLING_READY_TIMEOUT_COUNT) {
- RT_TRACE(_module_hal_init_c_, _drv_err_,
- "%s: chksum report fail! REG_MCUFWDL:0x%08x\n",
- __func__, value32);
- return _FAIL;
- }
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__,
- value32);
-
- value32 = rtl8723au_read32(padapter, REG_MCUFWDL);
- value32 |= MCUFWDL_RDY;
- value32 &= ~WINTINI_RDY;
- rtl8723au_write32(padapter, REG_MCUFWDL, value32);
-
- /* polling for FW ready */
- counter = 0;
- do {
- value32 = rtl8723au_read32(padapter, REG_MCUFWDL);
- if (value32 & WINTINI_RDY) {
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n",
- __func__, value32);
- return _SUCCESS;
- }
- udelay(5);
- } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
-
- RT_TRACE(_module_hal_init_c_, _drv_err_,
- "%s: Polling FW ready fail!! REG_MCUFWDL:0x%08x\n",
- __func__, value32);
- return _FAIL;
-}
-
-#define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
-
-void rtl8723a_FirmwareSelfReset(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 u1bTmp;
- u8 Delay = 100;
-
- if (!(IS_FW_81xxC(padapter) &&
- ((pHalData->FirmwareVersion < 0x21) ||
- (pHalData->FirmwareVersion == 0x21 &&
- pHalData->FirmwareSubVersion < 0x01)))) {
- /* after 88C Fw v33.1 */
- /* 0x1cf = 0x20. Inform 8051 to reset. 2009.12.25. tynli_test */
- rtl8723au_write8(padapter, REG_HMETFR + 3, 0x20);
-
- u1bTmp = rtl8723au_read8(padapter, REG_SYS_FUNC_EN + 1);
- while (u1bTmp & BIT(2)) {
- Delay--;
- if (Delay == 0)
- break;
- udelay(50);
- u1bTmp = rtl8723au_read8(padapter, REG_SYS_FUNC_EN + 1);
- }
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "-%s: 8051 reset success (%d)\n", __func__,
- Delay);
-
- if ((Delay == 0)) {
- /* force firmware reset */
- u1bTmp = rtl8723au_read8(padapter, REG_SYS_FUNC_EN + 1);
- rtl8723au_write8(padapter, REG_SYS_FUNC_EN + 1,
- u1bTmp & ~BIT(2));
- }
- }
-}
-
-/* */
-/* Description: */
-/* Download 8192C firmware code. */
-/* */
-/* */
-int rtl8723a_FirmwareDownload(struct rtw_adapter *padapter)
-{
- int rtStatus = _SUCCESS;
- u8 writeFW_retry = 0;
- unsigned long fwdl_start_time;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
- struct device *device = dvobj_to_dev(dvobj);
- struct rt_8723a_firmware_hdr *pFwHdr = NULL;
- const struct firmware *fw;
- char *fw_name;
- u8 *firmware_buf = NULL;
- u8 *buf;
- int fw_size;
- static int log_version;
-
- RT_TRACE(_module_hal_init_c_, _drv_info_, "+%s\n", __func__);
-
- if (IS_8723A_A_CUT(pHalData->VersionID)) {
- fw_name = "rtlwifi/rtl8723aufw_A.bin";
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "rtl8723a_FirmwareDownload: R8723FwImageArray_UMC for RTL8723A A CUT\n");
- } else if (IS_8723A_B_CUT(pHalData->VersionID)) {
- /* WLAN Fw. */
- if (padapter->registrypriv.wifi_spec == 1) {
- fw_name = "rtlwifi/rtl8723aufw_B_NoBT.bin";
- DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithoutBT for "
- "RTL8723A B CUT\n");
- } else {
- if (rtl8723a_BT_coexist(padapter)) {
- fw_name = "rtlwifi/rtl8723aufw_B.bin";
- DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithBT "
- "for RTL8723A B CUT\n");
- } else {
- fw_name = "rtlwifi/rtl8723aufw_B_NoBT.bin";
- DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithout "
- "BT for RTL8723A B CUT\n");
- }
- }
- } else {
- /* <Roger_TODO> We should download proper RAM Code here
- to match the ROM code. */
- RT_TRACE(_module_hal_init_c_, _drv_err_,
- "%s: unknown version!\n", __func__);
- rtStatus = _FAIL;
- goto Exit;
- }
-
- pr_info("rtl8723au: Loading firmware %s\n", fw_name);
- if (request_firmware(&fw, fw_name, device)) {
- pr_err("rtl8723au: request_firmware load failed\n");
- rtStatus = _FAIL;
- goto Exit;
- }
- if (!fw) {
- pr_err("rtl8723au: Firmware %s not available\n", fw_name);
- rtStatus = _FAIL;
- goto Exit;
- }
- firmware_buf = kmemdup(fw->data, fw->size, GFP_KERNEL);
- fw_size = fw->size;
- release_firmware(fw);
- if (!firmware_buf) {
- rtStatus = _FAIL;
- goto Exit;
- }
- buf = firmware_buf;
-
- /* To Check Fw header. Added by tynli. 2009.12.04. */
- pFwHdr = (struct rt_8723a_firmware_hdr *)firmware_buf;
-
- pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version);
- pHalData->FirmwareSubVersion = pFwHdr->Subversion;
- pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
-
- DBG_8723A("%s: fw_ver =%d fw_subver =%d sig = 0x%x\n",
- __func__, pHalData->FirmwareVersion,
- pHalData->FirmwareSubVersion, pHalData->FirmwareSignature);
-
- if (!log_version++)
- pr_info("%sFirmware Version %d, SubVersion %d, Signature "
- "0x%x\n", DRIVER_PREFIX, pHalData->FirmwareVersion,
- pHalData->FirmwareSubVersion,
- pHalData->FirmwareSignature);
-
- if (IS_FW_HEADER_EXIST(pFwHdr)) {
- /* Shift 32 bytes for FW header */
- buf = buf + 32;
- fw_size = fw_size - 32;
- }
-
- /* Suggested by Filen. If 8051 is running in RAM code, driver should
- inform Fw to reset by itself, */
- /* or it will cause download Fw fail. 2010.02.01. by tynli. */
- if (rtl8723au_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) {
- /* 8051 RAM code */
- rtl8723a_FirmwareSelfReset(padapter);
- rtl8723au_write8(padapter, REG_MCUFWDL, 0x00);
- }
-
- _FWDownloadEnable(padapter, true);
- fwdl_start_time = jiffies;
- while (1) {
- /* reset the FWDL chksum */
- rtl8723au_write8(padapter, REG_MCUFWDL,
- rtl8723au_read8(padapter, REG_MCUFWDL) |
- FWDL_ChkSum_rpt);
-
- rtStatus = _WriteFW(padapter, buf, fw_size);
-
- if (rtStatus == _SUCCESS ||
- (jiffies_to_msecs(jiffies - fwdl_start_time) > 500 &&
- writeFW_retry++ >= 3))
- break;
-
- DBG_8723A("%s writeFW_retry:%u, time after fwdl_start_time:"
- "%ums\n", __func__, writeFW_retry,
- jiffies_to_msecs(jiffies - fwdl_start_time));
- }
- _FWDownloadEnable(padapter, false);
- if (_SUCCESS != rtStatus) {
- DBG_8723A("DL Firmware failed!\n");
- goto Exit;
- }
-
- rtStatus = _FWFreeToGo(padapter);
- if (_SUCCESS != rtStatus) {
- RT_TRACE(_module_hal_init_c_, _drv_err_,
- "DL Firmware failed!\n");
- goto Exit;
- }
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "Firmware is ready to run!\n");
-
-Exit:
- kfree(firmware_buf);
- return rtStatus;
-}
-
-void rtl8723a_InitializeFirmwareVars(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- /* Init Fw LPS related. */
- padapter->pwrctrlpriv.bFwCurrentInPSMode = false;
-
- /* Init H2C counter. by tynli. 2009.12.09. */
- pHalData->LastHMEBoxNum = 0;
-}
-
-/* */
-/* Efuse related code */
-/* */
-static u8
-hal_EfuseSwitchToBank(struct rtw_adapter *padapter, u8 bank)
-{
- u8 bRet = false;
- u32 value32 = 0;
-
- DBG_8723A("%s: Efuse switch bank to %d\n", __func__, bank);
- value32 = rtl8723au_read32(padapter, EFUSE_TEST);
- bRet = true;
- switch (bank) {
- case 0:
- value32 = (value32 & ~EFUSE_SEL_MASK) |
- EFUSE_SEL(EFUSE_WIFI_SEL_0);
- break;
- case 1:
- value32 = (value32 & ~EFUSE_SEL_MASK) |
- EFUSE_SEL(EFUSE_BT_SEL_0);
- break;
- case 2:
- value32 = (value32 & ~EFUSE_SEL_MASK) |
- EFUSE_SEL(EFUSE_BT_SEL_1);
- break;
- case 3:
- value32 = (value32 & ~EFUSE_SEL_MASK) |
- EFUSE_SEL(EFUSE_BT_SEL_2);
- break;
- default:
- value32 = (value32 & ~EFUSE_SEL_MASK) |
- EFUSE_SEL(EFUSE_WIFI_SEL_0);
- bRet = false;
- break;
- }
- rtl8723au_write32(padapter, EFUSE_TEST, value32);
-
- return bRet;
-}
-
-static void
-hal_ReadEFuse_WiFi(struct rtw_adapter *padapter,
- u16 _offset, u16 _size_byte, u8 *pbuf)
-{
- u8 *efuseTbl = NULL;
- u16 eFuse_Addr = 0;
- u8 offset, wden;
- u8 efuseHeader, efuseExtHdr, efuseData;
- u16 i, total, used;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- /* Do NOT excess total size of EFuse table.
- Added by Roger, 2008.11.10. */
- if ((_offset + _size_byte) > EFUSE_MAP_LEN_8723A) {
- DBG_8723A("%s: Invalid offset(%#x) with read bytes(%#x)!!\n",
- __func__, _offset, _size_byte);
- return;
- }
-
- efuseTbl = kmalloc(EFUSE_MAP_LEN_8723A, GFP_KERNEL);
- if (!efuseTbl)
- return;
- /* 0xff will be efuse default value instead of 0x00. */
- memset(efuseTbl, 0xFF, EFUSE_MAP_LEN_8723A);
-
- /* switch bank back to bank 0 for later BT and wifi use. */
- hal_EfuseSwitchToBank(padapter, 0);
-
- while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
- ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseHeader);
- if (efuseHeader == 0xFF) {
- DBG_8723A("%s: data end at address =%#x\n", __func__,
- eFuse_Addr);
- break;
- }
-
- /* Check PG header for section num. */
- if (EXT_HEADER(efuseHeader)) { /* extended header */
- offset = GET_HDR_OFFSET_2_0(efuseHeader);
-
- ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseExtHdr);
- if (ALL_WORDS_DISABLED(efuseExtHdr))
- continue;
-
- offset |= ((efuseExtHdr & 0xF0) >> 1);
- wden = efuseExtHdr & 0x0F;
- } else {
- offset = (efuseHeader >> 4) & 0x0f;
- wden = efuseHeader & 0x0f;
- }
-
- if (offset < EFUSE_MAX_SECTION_8723A) {
- u16 addr;
- /* Get word enable value from PG header */
-
- addr = offset * PGPKT_DATA_SIZE;
- for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
- /* Check word enable condition in the section */
- if (!(wden & (0x01 << i))) {
- ReadEFuseByte23a(padapter, eFuse_Addr++,
- &efuseData);
- efuseTbl[addr] = efuseData;
-
- ReadEFuseByte23a(padapter, eFuse_Addr++,
- &efuseData);
- efuseTbl[addr + 1] = efuseData;
- }
- addr += 2;
- }
- } else {
- DBG_8723A(KERN_ERR "%s: offset(%d) is illegal!!\n",
- __func__, offset);
- eFuse_Addr += Efuse_CalculateWordCnts23a(wden) * 2;
- }
- }
-
- /* Copy from Efuse map to output pointer memory!!! */
- for (i = 0; i < _size_byte; i++)
- pbuf[i] = efuseTbl[_offset + i];
-
- /* Calculate Efuse utilization */
- EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
- TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total);
- used = eFuse_Addr - 1;
- pHalData->EfuseUsedBytes = used;
-
- kfree(efuseTbl);
-}
-
-static void
-hal_ReadEFuse_BT(struct rtw_adapter *padapter,
- u16 _offset, u16 _size_byte, u8 *pbuf)
-{
- u8 *efuseTbl;
- u8 bank;
- u16 eFuse_Addr;
- u8 efuseHeader, efuseExtHdr, efuseData;
- u8 offset, wden;
- u16 i, total, used;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- /* Do NOT excess total size of EFuse table.
- Added by Roger, 2008.11.10. */
- if ((_offset + _size_byte) > EFUSE_BT_MAP_LEN) {
- DBG_8723A("%s: Invalid offset(%#x) with read bytes(%#x)!!\n",
- __func__, _offset, _size_byte);
- return;
- }
-
- efuseTbl = kmalloc(EFUSE_BT_MAP_LEN, GFP_KERNEL);
- if (!efuseTbl)
- return;
- /* 0xff will be efuse default value instead of 0x00. */
- memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
-
- EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
- TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total);
-
- for (bank = 1; bank < EFUSE_MAX_BANK; bank++) {
- if (hal_EfuseSwitchToBank(padapter, bank) == false) {
- DBG_8723A("%s: hal_EfuseSwitchToBank Fail!!\n",
- __func__);
- goto exit;
- }
-
- eFuse_Addr = 0;
-
- while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
- ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseHeader);
- if (efuseHeader == 0xFF)
- break;
-
- /* Check PG header for section num. */
- if (EXT_HEADER(efuseHeader)) { /* extended header */
- offset = GET_HDR_OFFSET_2_0(efuseHeader);
-
- ReadEFuseByte23a(padapter, eFuse_Addr++,
- &efuseExtHdr);
- if (ALL_WORDS_DISABLED(efuseExtHdr))
- continue;
-
- offset |= ((efuseExtHdr & 0xF0) >> 1);
- wden = efuseExtHdr & 0x0F;
- } else {
- offset = (efuseHeader >> 4) & 0x0f;
- wden = efuseHeader & 0x0f;
- }
-
- if (offset < EFUSE_BT_MAX_SECTION) {
- u16 addr;
-
- /* Get word enable value from PG header */
-
- addr = offset * PGPKT_DATA_SIZE;
- for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
- /* Check word enable condition in
- the section */
- if (!(wden & (0x01 << i))) {
- ReadEFuseByte23a(padapter,
- eFuse_Addr++,
- &efuseData);
- efuseTbl[addr] = efuseData;
-
- ReadEFuseByte23a(padapter,
- eFuse_Addr++,
- &efuseData);
- efuseTbl[addr + 1] = efuseData;
- }
- addr += 2;
- }
- } else {
- DBG_8723A(KERN_ERR
- "%s: offset(%d) is illegal!!\n",
- __func__, offset);
- eFuse_Addr += Efuse_CalculateWordCnts23a(wden) * 2;
- }
- }
-
- if ((eFuse_Addr - 1) < total) {
- DBG_8723A("%s: bank(%d) data end at %#x\n",
- __func__, bank, eFuse_Addr - 1);
- break;
- }
- }
-
- /* switch bank back to bank 0 for later BT and wifi use. */
- hal_EfuseSwitchToBank(padapter, 0);
-
- /* Copy from Efuse map to output pointer memory!!! */
- for (i = 0; i < _size_byte; i++)
- pbuf[i] = efuseTbl[_offset + i];
-
- /* */
- /* Calculate Efuse utilization. */
- /* */
- EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
- TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total);
- used = (EFUSE_BT_REAL_BANK_CONTENT_LEN * (bank - 1)) + eFuse_Addr - 1;
- pHalData->BTEfuseUsedBytes = used;
-
-exit:
- kfree(efuseTbl);
-}
-
-void
-rtl8723a_readefuse(struct rtw_adapter *padapter,
- u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf)
-{
- if (efuseType == EFUSE_WIFI)
- hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf);
- else
- hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf);
-}
-
-u16 rtl8723a_EfuseGetCurrentSize_WiFi(struct rtw_adapter *padapter)
-{
- u16 efuse_addr = 0;
- u8 hoffset = 0, hworden = 0;
- u8 efuse_data, word_cnts = 0;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- efuse_addr = pHalData->EfuseUsedBytes;
-
- DBG_8723A("%s: start_efuse_addr = 0x%X\n", __func__, efuse_addr);
-
- /* switch bank back to bank 0 for later BT and wifi use. */
- hal_EfuseSwitchToBank(padapter, 0);
-
- while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
- if (efuse_OneByteRead23a(padapter, efuse_addr, &efuse_data) ==
- _FAIL) {
- DBG_8723A(KERN_ERR "%s: efuse_OneByteRead23a Fail! "
- "addr = 0x%X !!\n", __func__, efuse_addr);
- break;
- }
-
- if (efuse_data == 0xFF)
- break;
-
- if (EXT_HEADER(efuse_data)) {
- hoffset = GET_HDR_OFFSET_2_0(efuse_data);
- efuse_addr++;
- efuse_OneByteRead23a(padapter, efuse_addr, &efuse_data);
- if (ALL_WORDS_DISABLED(efuse_data))
- continue;
-
- hoffset |= ((efuse_data & 0xF0) >> 1);
- hworden = efuse_data & 0x0F;
- } else {
- hoffset = (efuse_data >> 4) & 0x0F;
- hworden = efuse_data & 0x0F;
- }
-
- word_cnts = Efuse_CalculateWordCnts23a(hworden);
- efuse_addr += (word_cnts * 2) + 1;
- }
-
- pHalData->EfuseUsedBytes = efuse_addr;
-
- DBG_8723A("%s: CurrentSize =%d\n", __func__, efuse_addr);
-
- return efuse_addr;
-}
-
-u16 rtl8723a_EfuseGetCurrentSize_BT(struct rtw_adapter *padapter)
-{
- u16 btusedbytes;
- u16 efuse_addr;
- u8 bank, startBank;
- u8 hoffset = 0, hworden = 0;
- u8 efuse_data, word_cnts = 0;
- u16 retU2 = 0;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- btusedbytes = pHalData->BTEfuseUsedBytes;
-
- efuse_addr = (u16) ((btusedbytes % EFUSE_BT_REAL_BANK_CONTENT_LEN));
- startBank = (u8) (1 + (btusedbytes / EFUSE_BT_REAL_BANK_CONTENT_LEN));
-
- DBG_8723A("%s: start from bank =%d addr = 0x%X\n", __func__, startBank,
- efuse_addr);
-
- EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
- TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2);
-
- for (bank = startBank; bank < EFUSE_MAX_BANK; bank++) {
- if (hal_EfuseSwitchToBank(padapter, bank) == false) {
- DBG_8723A(KERN_ERR "%s: switch bank(%d) Fail!!\n",
- __func__, bank);
- bank = EFUSE_MAX_BANK;
- break;
- }
-
- /* only when bank is switched we have to reset
- the efuse_addr. */
- if (bank != startBank)
- efuse_addr = 0;
-
- while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
- if (efuse_OneByteRead23a(padapter, efuse_addr,
- &efuse_data) == _FAIL) {
- DBG_8723A(KERN_ERR "%s: efuse_OneByteRead23a Fail!"
- " addr = 0x%X !!\n",
- __func__, efuse_addr);
- bank = EFUSE_MAX_BANK;
- break;
- }
-
- if (efuse_data == 0xFF)
- break;
-
- if (EXT_HEADER(efuse_data)) {
- hoffset = GET_HDR_OFFSET_2_0(efuse_data);
- efuse_addr++;
- efuse_OneByteRead23a(padapter, efuse_addr,
- &efuse_data);
- if (ALL_WORDS_DISABLED(efuse_data)) {
- efuse_addr++;
- continue;
- }
-
- hoffset |= ((efuse_data & 0xF0) >> 1);
- hworden = efuse_data & 0x0F;
- } else {
- hoffset = (efuse_data >> 4) & 0x0F;
- hworden = efuse_data & 0x0F;
- }
- word_cnts = Efuse_CalculateWordCnts23a(hworden);
- /* read next header */
- efuse_addr += (word_cnts * 2) + 1;
- }
-
- /* Check if we need to check next bank efuse */
- if (efuse_addr < retU2)
- break; /* don't need to check next bank. */
- }
-
- retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
- pHalData->BTEfuseUsedBytes = retU2;
-
- DBG_8723A("%s: CurrentSize =%d\n", __func__, retU2);
- return retU2;
-}
-
-void rtl8723a_read_chip_version(struct rtw_adapter *padapter)
-{
- u32 value32;
- struct hal_version ChipVersion;
- struct hal_data_8723a *pHalData;
-
- pHalData = GET_HAL_DATA(padapter);
-
- value32 = rtl8723au_read32(padapter, REG_SYS_CFG);
- ChipVersion.ICType = CHIP_8723A;
- ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
- pHalData->rf_type = RF_1T1R;
- ChipVersion.VendorType =
- ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
- ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /* IC version (CUT) */
-
- /* For regulator mode. by tynli. 2011.01.14 */
- pHalData->RegulatorMode = ((value32 & SPS_SEL) ?
- RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
-
- value32 = rtl8723au_read32(padapter, REG_GPIO_OUTSTS);
- /* ROM code version. */
- ChipVersion.ROMVer = (value32 & RF_RL_ID) >> 20;
-
- /* For multi-function consideration. Added by Roger, 2010.10.06. */
- pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
- value32 = rtl8723au_read32(padapter, REG_MULTI_FUNC_CTRL);
- pHalData->MultiFunc |=
- ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
- pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
- pHalData->MultiFunc |=
- ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
- pHalData->PolarityCtl =
- ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT :
- RT_POLARITY_LOW_ACT);
- pHalData->VersionID = ChipVersion;
-
- MSG_8723A("RF_Type is %x!!\n", pHalData->rf_type);
-}
-
-/* */
-/* */
-/* 20100209 Joseph: */
-/* This function is used only for 92C to set REG_BCN_CTRL(0x550) register. */
-/* We just reserve the value of the register in variable
- pHalData->RegBcnCtrlVal and then operate */
-/* the value of the register via atomic operation. */
-/* This prevents from race condition when setting this register. */
-/* The value of pHalData->RegBcnCtrlVal is initialized in
- HwConfigureRTL8192CE() function. */
-/* */
-void SetBcnCtrlReg23a(struct rtw_adapter *padapter, u8 SetBits, u8 ClearBits)
-{
- u8 val8;
-
- val8 = rtl8723au_read8(padapter, REG_BCN_CTRL);
- val8 |= SetBits;
- val8 &= ~ClearBits;
-
- rtl8723au_write8(padapter, REG_BCN_CTRL, val8);
-}
-
-void rtl8723a_InitBeaconParameters(struct rtw_adapter *padapter)
-{
- rtl8723au_write16(padapter, REG_BCN_CTRL, 0x1010);
-
- /* TODO: Remove these magic number */
- rtl8723au_write16(padapter, REG_TBTT_PROHIBIT, 0x6404); /* ms */
- /* Firmware will control REG_DRVERLYINT when power saving is enable, */
- /* so don't set this register on STA mode. */
- if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == false)
- rtl8723au_write8(padapter, REG_DRVERLYINT,
- DRIVER_EARLY_INT_TIME);
- /* 2ms */
- rtl8723au_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME);
-
- /* Suggested by designer timchen. Change beacon AIFS to the
- largest number beacause test chip does not contension before
- sending beacon. by tynli. 2009.11.03 */
- rtl8723au_write16(padapter, REG_BCNTCFG, 0x660F);
-}
-
-static void ResumeTxBeacon(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- /* 2010.03.01. Marked by tynli. No need to call workitem beacause
- we record the value */
- /* which should be read from register to a global variable. */
-
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_, "+ResumeTxBeacon\n");
-
- pHalData->RegFwHwTxQCtrl |= BIT(6);
- rtl8723au_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
- pHalData->RegFwHwTxQCtrl);
- rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 1, 0xff);
- pHalData->RegReg542 |= BIT(0);
- rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
-}
-
-static void StopTxBeacon(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- /* 2010.03.01. Marked by tynli. No need to call workitem beacause
- we record the value */
- /* which should be read from register to a global variable. */
-
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_, "+StopTxBeacon\n");
-
- pHalData->RegFwHwTxQCtrl &= ~BIT(6);
- rtl8723au_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
- pHalData->RegFwHwTxQCtrl);
- rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 1, 0x64);
- pHalData->RegReg542 &= ~BIT(0);
- rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
-}
-
-static void _BeaconFunctionEnable(struct rtw_adapter *padapter, u8 Enable,
- u8 Linked)
-{
- SetBcnCtrlReg23a(padapter, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB,
- 0);
- rtl8723au_write8(padapter, REG_RD_CTRL + 1, 0x6F);
-}
-
-void rtl8723a_SetBeaconRelatedRegisters(struct rtw_adapter *padapter)
-{
- u32 value32;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- /* reset TSF, enable update TSF, correcting TSF On Beacon */
-
- /* REG_BCN_INTERVAL */
- /* REG_BCNDMATIM */
- /* REG_ATIMWND */
- /* REG_TBTT_PROHIBIT */
- /* REG_DRVERLYINT */
- /* REG_BCN_MAX_ERR */
- /* REG_BCNTCFG (0x510) */
- /* REG_DUAL_TSF_RST */
- /* REG_BCN_CTRL (0x550) */
-
- /* */
- /* ATIM window */
- /* */
- rtl8723au_write16(padapter, REG_ATIMWND, 2);
-
- /* */
- /* Beacon interval (in unit of TU). */
- /* */
- rtl8723au_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
-
- rtl8723a_InitBeaconParameters(padapter);
-
- rtl8723au_write8(padapter, REG_SLOT, 0x09);
-
- /* */
- /* Reset TSF Timer to zero, added by Roger. 2008.06.24 */
- /* */
- value32 = rtl8723au_read32(padapter, REG_TCR);
- value32 &= ~TSFRST;
- rtl8723au_write32(padapter, REG_TCR, value32);
-
- value32 |= TSFRST;
- rtl8723au_write32(padapter, REG_TCR, value32);
-
- /* NOTE: Fix test chip's bug (about contention windows's randomness) */
- if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE |
- WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE) == true) {
- rtl8723au_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
- rtl8723au_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
- }
-
- _BeaconFunctionEnable(padapter, true, true);
-
- ResumeTxBeacon(padapter);
- SetBcnCtrlReg23a(padapter, DIS_BCNQ_SUB, 0);
-}
-
-void rtl8723a_SetHalODMVar(struct rtw_adapter *Adapter,
- enum hal_odm_variable eVariable,
- void *pValue1, bool bSet)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct dm_odm_t *podmpriv = &pHalData->odmpriv;
- switch (eVariable) {
- case HAL_ODM_STA_INFO:
- {
- struct sta_info *psta = (struct sta_info *)pValue1;
-
- if (bSet) {
- DBG_8723A("Set STA_(%d) info\n", psta->mac_id);
- ODM_CmnInfoPtrArrayHook23a(podmpriv,
- ODM_CMNINFO_STA_STATUS,
- psta->mac_id, psta);
- } else {
- DBG_8723A("Clean STA_(%d) info\n", psta->mac_id);
- ODM_CmnInfoPtrArrayHook23a(podmpriv,
- ODM_CMNINFO_STA_STATUS,
- psta->mac_id, NULL);
- }
- }
- break;
- case HAL_ODM_P2P_STATE:
- ODM_CmnInfoUpdate23a(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet);
- break;
- case HAL_ODM_WIFI_DISPLAY_STATE:
- ODM_CmnInfoUpdate23a(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet);
- break;
- default:
- break;
- }
-}
-
-void rtl8723a_notch_filter(struct rtw_adapter *adapter, bool enable)
-{
- if (enable) {
- DBG_8723A("Enable notch filter\n");
- rtl8723au_write8(adapter, rOFDM0_RxDSP + 1,
- rtl8723au_read8(adapter, rOFDM0_RxDSP + 1) |
- BIT(1));
- } else {
- DBG_8723A("Disable notch filter\n");
- rtl8723au_write8(adapter, rOFDM0_RxDSP + 1,
- rtl8723au_read8(adapter, rOFDM0_RxDSP + 1) &
- ~BIT(1));
- }
-}
-
-bool c2h_id_filter_ccx_8723a(u8 id)
-{
- bool ret = false;
- if (id == C2H_CCX_TX_RPT)
- ret = true;
-
- return ret;
-}
-
-int c2h_handler_8723a(struct rtw_adapter *padapter, struct c2h_evt_hdr *c2h_evt)
-{
- int ret = _SUCCESS;
- u8 i = 0;
-
- if (c2h_evt == NULL) {
- DBG_8723A("%s c2h_evt is NULL\n", __func__);
- ret = _FAIL;
- goto exit;
- }
-
- switch (c2h_evt->id) {
- case C2H_DBG:
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "C2HCommandHandler: %s\n", c2h_evt->payload);
- break;
-
- case C2H_CCX_TX_RPT:
- handle_txrpt_ccx_8723a(padapter, c2h_evt->payload);
- break;
- case C2H_EXT_RA_RPT:
- break;
- case C2H_HW_INFO_EXCH:
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "[BT], C2H_HW_INFO_EXCH\n");
- for (i = 0; i < c2h_evt->plen; i++) {
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "[BT], tmpBuf[%d]= 0x%x\n", i,
- c2h_evt->payload[i]);
- }
- break;
-
- case C2H_C2H_H2C_TEST:
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "[BT], C2H_H2C_TEST\n");
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "[BT], tmpBuf[0]/[1]/[2]/[3]/[4]= 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x\n",
- c2h_evt->payload[0],
- c2h_evt->payload[1], c2h_evt->payload[2],
- c2h_evt->payload[3], c2h_evt->payload[4]);
- break;
-
- case C2H_BT_INFO:
- DBG_8723A("%s , Got C2H_BT_INFO \n", __func__);
- rtl8723a_fw_c2h_BT_info(padapter,
- c2h_evt->payload, c2h_evt->plen);
- break;
-
- default:
- ret = _FAIL;
- break;
- }
-
-exit:
- return ret;
-}
-
-void handle_txrpt_ccx_8723a(struct rtw_adapter *adapter, void *buf)
-{
- struct txrpt_ccx_8723a *txrpt_ccx = buf;
- struct submit_ctx *pack_tx_ops = &adapter->xmitpriv.ack_tx_ops;
-
- if (txrpt_ccx->int_ccx && adapter->xmitpriv.ack_tx) {
- if (txrpt_ccx->pkt_ok)
- rtw23a_sctx_done_err(&pack_tx_ops,
- RTW_SCTX_DONE_SUCCESS);
- else
- rtw23a_sctx_done_err(&pack_tx_ops,
- RTW_SCTX_DONE_CCX_PKT_FAIL);
- }
-}
-
-void rtl8723a_InitAntenna_Selection(struct rtw_adapter *padapter)
-{
- u8 val;
-
- val = rtl8723au_read8(padapter, REG_LEDCFG2);
- /* Let 8051 take control antenna setting */
- val |= BIT(7); /* DPDT_SEL_EN, 0x4C[23] */
- rtl8723au_write8(padapter, REG_LEDCFG2, val);
-}
-
-void rtl8723a_CheckAntenna_Selection(struct rtw_adapter *padapter)
-{
- u8 val;
-
- val = rtl8723au_read8(padapter, REG_LEDCFG2);
- /* Let 8051 take control antenna setting */
- if (!(val & BIT(7))) {
- val |= BIT(7); /* DPDT_SEL_EN, 0x4C[23] */
- rtl8723au_write8(padapter, REG_LEDCFG2, val);
- }
-}
-
-void rtl8723a_DeinitAntenna_Selection(struct rtw_adapter *padapter)
-{
- u8 val;
-
- val = rtl8723au_read8(padapter, REG_LEDCFG2);
- /* Let 8051 take control antenna setting */
- val &= ~BIT(7); /* DPDT_SEL_EN, clear 0x4C[23] */
- rtl8723au_write8(padapter, REG_LEDCFG2, val);
-}
-
-void rtl8723a_init_default_value(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData;
- struct dm_priv *pdmpriv;
- u8 i;
-
- pHalData = GET_HAL_DATA(padapter);
- pdmpriv = &pHalData->dmpriv;
-
- /* init default value */
- pHalData->bIQKInitialized = false;
- if (!padapter->pwrctrlpriv.bkeepfwalive)
- pHalData->LastHMEBoxNum = 0;
-
- pHalData->bIQKInitialized = false;
-
- /* init dm default value */
- pdmpriv->TM_Trigger = 0; /* for IQK */
-/* pdmpriv->binitialized = false; */
-/* pdmpriv->prv_traffic_idx = 3; */
-/* pdmpriv->initialize = 0; */
-
- pdmpriv->ThermalValue_HP_index = 0;
- for (i = 0; i < HP_THERMAL_NUM; i++)
- pdmpriv->ThermalValue_HP[i] = 0;
-
- /* init Efuse variables */
- pHalData->EfuseUsedBytes = 0;
- pHalData->BTEfuseUsedBytes = 0;
-}
-
-u8 GetEEPROMSize8723A(struct rtw_adapter *padapter)
-{
- u8 size = 0;
- u32 cr;
-
- cr = rtl8723au_read16(padapter, REG_9346CR);
- /* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */
- size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
-
- MSG_8723A("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46");
-
- return size;
-}
-
-/* */
-/* */
-/* LLT R/W/Init function */
-/* */
-/* */
-static int _LLTWrite(struct rtw_adapter *padapter, u32 address, u32 data)
-{
- int status = _SUCCESS;
- s32 count = 0;
- u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
- _LLT_OP(_LLT_WRITE_ACCESS);
- u16 LLTReg = REG_LLT_INIT;
-
- rtl8723au_write32(padapter, LLTReg, value);
-
- /* polling */
- do {
- value = rtl8723au_read32(padapter, LLTReg);
- if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
- break;
-
- if (count > POLLING_LLT_THRESHOLD) {
- RT_TRACE(_module_hal_init_c_, _drv_err_,
- "Failed to polling write LLT done at address %d!\n",
- address);
- status = _FAIL;
- break;
- }
- } while (count++);
-
- return status;
-}
-
-int InitLLTTable23a(struct rtw_adapter *padapter, u32 boundary)
-{
- int status = _SUCCESS;
- u32 i;
- u32 txpktbuf_bndy = boundary;
- u32 Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;
-
- for (i = 0; i < (txpktbuf_bndy - 1); i++) {
- status = _LLTWrite(padapter, i, i + 1);
- if (status != _SUCCESS)
- return status;
- }
-
- /* end of list */
- status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
- if (status != _SUCCESS)
- return status;
-
- /* Make the other pages as ring buffer */
- /* This ring buffer is used as beacon buffer if we config this
- MAC as two MAC transfer. */
- /* Otherwise used as local loopback buffer. */
- for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
- status = _LLTWrite(padapter, i, (i + 1));
- if (_SUCCESS != status)
- return status;
- }
-
- /* Let last entry point to the start entry of ring buffer */
- status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
-
- return status;
-}
-
-static void _DisableGPIO(struct rtw_adapter *padapter)
-{
-/***************************************
-j. GPIO_PIN_CTRL 0x44[31:0]= 0x000
-k.Value = GPIO_PIN_CTRL[7:0]
-l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); write external PIN level
-m. GPIO_MUXCFG 0x42 [15:0] = 0x0780
-n. LEDCFG 0x4C[15:0] = 0x8080
-***************************************/
- u32 value32;
- u32 u4bTmp;
-
- /* 1. Disable GPIO[7:0] */
- rtl8723au_write16(padapter, REG_GPIO_PIN_CTRL + 2, 0x0000);
- value32 = rtl8723au_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF;
- u4bTmp = value32 & 0x000000FF;
- value32 |= ((u4bTmp << 8) | 0x00FF0000);
- rtl8723au_write32(padapter, REG_GPIO_PIN_CTRL, value32);
-
- /* */
- /* <Roger_Notes> For RTL8723u multi-function configuration which
- was autoload from Efuse offset 0x0a and 0x0b, */
- /* WLAN HW GPIO[9], GPS HW GPIO[10] and BT HW GPIO[11]. */
- /* Added by Roger, 2010.10.07. */
- /* */
- /* 2. Disable GPIO[8] and GPIO[12] */
-
- /* Configure all pins as input mode. */
- rtl8723au_write16(padapter, REG_GPIO_IO_SEL_2, 0x0000);
- value32 = rtl8723au_read32(padapter, REG_GPIO_PIN_CTRL_2) & 0xFFFF001F;
- u4bTmp = value32 & 0x0000001F;
- /* Set pin 8, 10, 11 and pin 12 to output mode. */
- value32 |= ((u4bTmp << 8) | 0x001D0000);
- rtl8723au_write32(padapter, REG_GPIO_PIN_CTRL_2, value32);
-
- /* 3. Disable LED0 & 1 */
- rtl8723au_write16(padapter, REG_LEDCFG0, 0x8080);
-} /* end of _DisableGPIO() */
-
-static void _DisableRFAFEAndResetBB8192C(struct rtw_adapter *padapter)
-{
-/**************************************
-a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue
-b. RF path 0 offset 0x00 = 0x00 disable RF
-c. APSD_CTRL 0x600[7:0] = 0x40
-d. SYS_FUNC_EN 0x02[7:0] = 0x16 reset BB state machine
-e. SYS_FUNC_EN 0x02[7:0] = 0x14 reset BB state machine
-***************************************/
- u8 value8;
-
- rtl8723au_write8(padapter, REG_TXPAUSE, 0xFF);
-
- PHY_SetRFReg(padapter, RF_PATH_A, 0x0, bMaskByte0, 0x0);
-
- value8 = APSDOFF;
- rtl8723au_write8(padapter, REG_APSD_CTRL, value8); /* 0x40 */
-
- /* Set BB reset at first */
- value8 = FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn;
- rtl8723au_write8(padapter, REG_SYS_FUNC_EN, value8); /* 0x16 */
-
- /* Set global reset. */
- value8 &= ~FEN_BB_GLB_RSTn;
- rtl8723au_write8(padapter, REG_SYS_FUNC_EN, value8); /* 0x14 */
-
- /* 2010/08/12 MH We need to set BB/GLBAL reset to save power
- for SS mode. */
-}
-
-static void _ResetDigitalProcedure1_92C(struct rtw_adapter *padapter,
- bool bWithoutHWSM)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (IS_FW_81xxC(padapter) && (pHalData->FirmwareVersion <= 0x20)) {
- /*****************************
- f. MCUFWDL 0x80[7:0]= 0 reset MCU ready status
- g. SYS_FUNC_EN 0x02[10]= 0 reset MCU register, (8051 reset)
- h. SYS_FUNC_EN 0x02[15-12]= 5 reset MAC register, DCORE
- i. SYS_FUNC_EN 0x02[10]= 1 enable MCU register,
- (8051 enable)
- ******************************/
- u16 valu16;
- rtl8723au_write8(padapter, REG_MCUFWDL, 0);
-
- valu16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN);
- /* reset MCU , 8051 */
- rtl8723au_write16(padapter, REG_SYS_FUNC_EN,
- valu16 & ~FEN_CPUEN);
-
- valu16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN) & 0x0FFF;
- /* reset MAC */
- rtl8723au_write16(padapter, REG_SYS_FUNC_EN,
- valu16 | FEN_HWPDN | FEN_ELDR);
-
- valu16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN);
- /* enable MCU , 8051 */
- rtl8723au_write16(padapter, REG_SYS_FUNC_EN,
- valu16 | FEN_CPUEN);
- } else {
- u8 retry_cnts = 0;
- u8 val8;
-
- val8 = rtl8723au_read8(padapter, REG_MCUFWDL);
-
- /* 2010/08/12 MH For USB SS, we can not stop 8051 when we
- are trying to enter IPS/HW&SW radio off. For
- S3/S4/S5/Disable, we can stop 8051 because */
- /* we will init FW when power on again. */
- /* If we want to SS mode, we can not reset 8051. */
- if ((val8 & BIT(1)) && padapter->bFWReady) {
- /* IF fw in RAM code, do reset */
- /* 2010/08/25 MH According to RD alfred's
- suggestion, we need to disable other */
- /* HRCV INT to influence 8051 reset. */
- rtl8723au_write8(padapter, REG_FWIMR, 0x20);
- /* 2011/02/15 MH According to Alex's
- suggestion, close mask to prevent
- incorrect FW write operation. */
- rtl8723au_write8(padapter, REG_FTIMR, 0x00);
- rtl8723au_write8(padapter, REG_FSIMR, 0x00);
-
- /* 8051 reset by self */
- rtl8723au_write8(padapter, REG_HMETFR + 3, 0x20);
-
- while ((retry_cnts++ < 100) &&
- (rtl8723au_read16(padapter, REG_SYS_FUNC_EN) &
- FEN_CPUEN)) {
- udelay(50); /* us */
- }
-
- if (retry_cnts >= 100) {
- /* Reset MAC and Enable 8051 */
- rtl8723au_write8(padapter,
- REG_SYS_FUNC_EN + 1, 0x50);
- mdelay(10);
- }
- }
- /* Reset MAC and Enable 8051 */
- rtl8723au_write8(padapter, REG_SYS_FUNC_EN + 1, 0x54);
- rtl8723au_write8(padapter, REG_MCUFWDL, 0);
- }
-
- if (bWithoutHWSM) {
- /*****************************
- Without HW auto state machine
- g. SYS_CLKR 0x08[15:0] = 0x30A3 disable MAC clock
- h. AFE_PLL_CTRL 0x28[7:0] = 0x80 disable AFE PLL
- i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F gated AFE DIG_CLOCK
- j. SYS_ISO_CTRL 0x00[7:0] = 0xF9 isolated digital to PON
- ******************************/
- /* modify to 0x70A3 by Scott. */
- rtl8723au_write16(padapter, REG_SYS_CLKR, 0x70A3);
- rtl8723au_write8(padapter, REG_AFE_PLL_CTRL, 0x80);
- rtl8723au_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F);
- rtl8723au_write8(padapter, REG_SYS_ISO_CTRL, 0xF9);
- } else {
- /* Disable all RF/BB power */
- rtl8723au_write8(padapter, REG_RF_CTRL, 0x00);
- }
-}
-
-static void _ResetDigitalProcedure2(struct rtw_adapter *padapter)
-{
-/*****************************
-k. SYS_FUNC_EN 0x03[7:0] = 0x44 disable ELDR runction
-l. SYS_CLKR 0x08[15:0] = 0x3083 disable ELDR clock
-m. SYS_ISO_CTRL 0x01[7:0] = 0x83 isolated ELDR to PON
-******************************/
- /* modify to 0x70a3 by Scott. */
- rtl8723au_write16(padapter, REG_SYS_CLKR, 0x70a3);
- /* modify to 0x82 by Scott. */
- rtl8723au_write8(padapter, REG_SYS_ISO_CTRL + 1, 0x82);
-}
-
-static void _DisableAnalog(struct rtw_adapter *padapter, bool bWithoutHWSM)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u16 value16;
- u8 value8;
-
- if (bWithoutHWSM) {
- /*****************************
- n. LDOA15_CTRL 0x20[7:0] = 0x04 disable A15 power
- o. LDOV12D_CTRL 0x21[7:0] = 0x54 disable digital core power
- r. When driver call disable, the ASIC will turn off remaining
- clock automatically
- ******************************/
-
- rtl8723au_write8(padapter, REG_LDOA15_CTRL, 0x04);
- /* rtl8723au_write8(padapter, REG_LDOV12D_CTRL, 0x54); */
-
- value8 = rtl8723au_read8(padapter, REG_LDOV12D_CTRL);
- value8 &= ~LDV12_EN;
- rtl8723au_write8(padapter, REG_LDOV12D_CTRL, value8);
- }
-
- /*****************************
- h. SPS0_CTRL 0x11[7:0] = 0x23 enter PFM mode
- i. APS_FSMCO 0x04[15:0] = 0x4802 set USB suspend
- ******************************/
- value8 = 0x23;
- if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
- value8 |= BIT(3);
-
- rtl8723au_write8(padapter, REG_SPS0_CTRL, value8);
-
- if (bWithoutHWSM) {
- /* value16 |= (APDM_HOST | FSM_HSUS |/PFM_ALDN); */
- /* 2010/08/31 According to Filen description, we need to
- use HW to shut down 8051 automatically. */
- /* Because suspend operation need the asistance of 8051
- to wait for 3ms. */
- value16 = APDM_HOST | AFSM_HSUS | PFM_ALDN;
- } else {
- value16 = APDM_HOST | AFSM_HSUS | PFM_ALDN;
- }
-
- rtl8723au_write16(padapter, REG_APS_FSMCO, value16); /* 0x4802 */
-
- rtl8723au_write8(padapter, REG_RSV_CTRL, 0x0e);
-}
-
-/* HW Auto state machine */
-int CardDisableHWSM(struct rtw_adapter *padapter, u8 resetMCU)
-{
- if (padapter->bSurpriseRemoved)
- return _SUCCESS;
-
- /* RF Off Sequence ==== */
- _DisableRFAFEAndResetBB8192C(padapter);
-
- /* ==== Reset digital sequence ====== */
- _ResetDigitalProcedure1_92C(padapter, false);
-
- /* ==== Pull GPIO PIN to balance level and LED control ====== */
- _DisableGPIO(padapter);
-
- /* ==== Disable analog sequence === */
- _DisableAnalog(padapter, false);
-
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "======> Card disable finished.\n");
-
- return _SUCCESS;
-}
-
-/* without HW Auto state machine */
-int CardDisableWithoutHWSM(struct rtw_adapter *padapter)
-{
- if (padapter->bSurpriseRemoved)
- return _SUCCESS;
-
- /* RF Off Sequence ==== */
- _DisableRFAFEAndResetBB8192C(padapter);
-
- /* ==== Reset digital sequence ====== */
- _ResetDigitalProcedure1_92C(padapter, true);
-
- /* ==== Pull GPIO PIN to balance level and LED control ====== */
- _DisableGPIO(padapter);
-
- /* ==== Reset digital sequence ====== */
- _ResetDigitalProcedure2(padapter);
-
- /* ==== Disable analog sequence === */
- _DisableAnalog(padapter, true);
-
- return _SUCCESS;
-}
-
-void Hal_InitPGData(struct rtw_adapter *padapter, u8 *PROMContent)
-{
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
-
- if (!pEEPROM->bautoload_fail_flag) { /* autoload OK. */
- if (!pEEPROM->EepromOrEfuse) {
- /* Read EFUSE real map to shadow. */
- EFUSE_ShadowMapUpdate23a(padapter, EFUSE_WIFI);
- memcpy(PROMContent, pEEPROM->efuse_eeprom_data,
- HWSET_MAX_SIZE);
- }
- } else {
- RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,
- "AutoLoad Fail reported from CR9346!!\n");
- /* update to default value 0xFF */
- if (!pEEPROM->EepromOrEfuse)
- EFUSE_ShadowMapUpdate23a(padapter, EFUSE_WIFI);
- memcpy(PROMContent, pEEPROM->efuse_eeprom_data,
- HWSET_MAX_SIZE);
- }
-}
-
-void Hal_EfuseParseIDCode(struct rtw_adapter *padapter, u8 *hwinfo)
-{
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
-/* struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); */
- u16 EEPROMId;
-
- /* Checl 0x8129 again for making sure autoload status!! */
- EEPROMId = le16_to_cpu(*((__le16 *) hwinfo));
- if (EEPROMId != RTL_EEPROM_ID) {
- DBG_8723A("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
- pEEPROM->bautoload_fail_flag = true;
- } else {
- pEEPROM->bautoload_fail_flag = false;
- }
-
- RT_TRACE(_module_hal_init_c_, _drv_info_,
- "EEPROM ID = 0x%04x\n", EEPROMId);
-}
-
-static void
-Hal_ReadPowerValueFromPROM_8723A(struct txpowerinfo *pwrInfo,
- u8 *PROMContent, bool AutoLoadFail)
-{
- u32 rfPath, eeAddr, group, rfPathMax = 1;
-
- memset(pwrInfo, 0, sizeof(*pwrInfo));
-
- if (AutoLoadFail) {
- for (group = 0; group < MAX_CHNL_GROUP; group++) {
- for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
- pwrInfo->CCKIndex[rfPath][group] =
- EEPROM_Default_TxPowerLevel;
- pwrInfo->HT40_1SIndex[rfPath][group] =
- EEPROM_Default_TxPowerLevel;
- pwrInfo->HT40_2SIndexDiff[rfPath][group] =
- EEPROM_Default_HT40_2SDiff;
- pwrInfo->HT20IndexDiff[rfPath][group] =
- EEPROM_Default_HT20_Diff;
- pwrInfo->OFDMIndexDiff[rfPath][group] =
- EEPROM_Default_LegacyHTTxPowerDiff;
- pwrInfo->HT40MaxOffset[rfPath][group] =
- EEPROM_Default_HT40_PwrMaxOffset;
- pwrInfo->HT20MaxOffset[rfPath][group] =
- EEPROM_Default_HT20_PwrMaxOffset;
- }
- }
- pwrInfo->TSSI_A[0] = EEPROM_Default_TSSI;
- return;
- }
-
- for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
- for (group = 0; group < MAX_CHNL_GROUP; group++) {
- eeAddr =
- EEPROM_CCK_TX_PWR_INX_8723A + (rfPath * 3) + group;
-
- pwrInfo->CCKIndex[rfPath][group] = PROMContent[eeAddr];
- if (pwrInfo->CCKIndex[rfPath][group] > 63)
- pwrInfo->CCKIndex[rfPath][group] =
- EEPROM_Default_TxPowerLevel;
-
- eeAddr = EEPROM_HT40_1S_TX_PWR_INX_8723A +
- (rfPath * 3) + group;
- pwrInfo->HT40_1SIndex[rfPath][group] =
- PROMContent[eeAddr];
- if (pwrInfo->HT40_1SIndex[rfPath][group] > 63)
- pwrInfo->HT40_1SIndex[rfPath][group] =
- EEPROM_Default_TxPowerLevel;
- }
- }
-
- for (group = 0; group < MAX_CHNL_GROUP; group++) {
- for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
- pwrInfo->HT40_2SIndexDiff[rfPath][group] = 0;
- pwrInfo->HT20IndexDiff[rfPath][group] =
- (PROMContent
- [EEPROM_HT20_TX_PWR_INX_DIFF_8723A +
- group] >> (rfPath * 4)) & 0xF;
- /* 4bit sign number to 8 bit sign number */
- if (pwrInfo->HT20IndexDiff[rfPath][group] & BIT(3))
- pwrInfo->HT20IndexDiff[rfPath][group] |= 0xF0;
-
- pwrInfo->OFDMIndexDiff[rfPath][group] =
- (PROMContent[EEPROM_OFDM_TX_PWR_INX_DIFF_8723A +
- group] >> (rfPath * 4)) & 0xF;
-
- pwrInfo->HT40MaxOffset[rfPath][group] =
- (PROMContent[EEPROM_HT40_MAX_PWR_OFFSET_8723A +
- group] >> (rfPath * 4)) & 0xF;
-
- pwrInfo->HT20MaxOffset[rfPath][group] =
- (PROMContent[EEPROM_HT20_MAX_PWR_OFFSET_8723A +
- group] >> (rfPath * 4)) & 0xF;
- }
- }
-
- pwrInfo->TSSI_A[0] = PROMContent[EEPROM_TSSI_A_8723A];
-}
-
-static u8 Hal_GetChnlGroup(u8 chnl)
-{
- u8 group = 0;
-
- if (chnl < 3) /* Cjanel 1-3 */
- group = 0;
- else if (chnl < 9) /* Channel 4-9 */
- group = 1;
- else /* Channel 10-14 */
- group = 2;
-
- return group;
-}
-
-void
-Hal_EfuseParsetxpowerinfo_8723A(struct rtw_adapter *padapter,
- u8 *PROMContent, bool AutoLoadFail)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct txpowerinfo pwrInfo;
- u8 rfPath, ch, group, rfPathMax = 1;
- u8 pwr, diff;
-
- Hal_ReadPowerValueFromPROM_8723A(&pwrInfo, PROMContent, AutoLoadFail);
- for (rfPath = 0; rfPath < rfPathMax; rfPath++) {
- for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
- group = Hal_GetChnlGroup(ch);
-
- pHalData->TxPwrLevelCck[rfPath][ch] =
- pwrInfo.CCKIndex[rfPath][group];
- pHalData->TxPwrLevelHT40_1S[rfPath][ch] =
- pwrInfo.HT40_1SIndex[rfPath][group];
-
- pHalData->TxPwrHt20Diff[rfPath][ch] =
- pwrInfo.HT20IndexDiff[rfPath][group];
- pHalData->TxPwrLegacyHtDiff[rfPath][ch] =
- pwrInfo.OFDMIndexDiff[rfPath][group];
- pHalData->PwrGroupHT20[rfPath][ch] =
- pwrInfo.HT20MaxOffset[rfPath][group];
- pHalData->PwrGroupHT40[rfPath][ch] =
- pwrInfo.HT40MaxOffset[rfPath][group];
-
- pwr = pwrInfo.HT40_1SIndex[rfPath][group];
- diff = pwrInfo.HT40_2SIndexDiff[rfPath][group];
-
- pHalData->TxPwrLevelHT40_2S[rfPath][ch] =
- (pwr > diff) ? (pwr - diff) : 0;
- }
- }
- for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) {
- for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "RF(%u)-Ch(%u) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n",
- rfPath, ch,
- pHalData->TxPwrLevelCck[rfPath][ch],
- pHalData->TxPwrLevelHT40_1S[rfPath][ch],
- pHalData->TxPwrLevelHT40_2S[rfPath][ch]);
-
- }
- }
- for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "RF-A Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch,
- pHalData->TxPwrHt20Diff[RF_PATH_A][ch],
- pHalData->TxPwrHt20Diff[RF_PATH_A][ch]);
- }
- for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++)
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "RF-A Legacy to Ht40 Diff[%u] = 0x%x\n", ch,
- pHalData->TxPwrLegacyHtDiff[RF_PATH_A][ch]);
- for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "RF-B Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch,
- pHalData->TxPwrHt20Diff[RF_PATH_B][ch],
- pHalData->TxPwrHt20Diff[RF_PATH_B][ch]);
- }
- for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++)
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "RF-B Legacy to HT40 Diff[%u] = 0x%x\n", ch,
- pHalData->TxPwrLegacyHtDiff[RF_PATH_B][ch]);
- if (!AutoLoadFail) {
- struct registry_priv *registry_par = &padapter->registrypriv;
- if (registry_par->regulatory_tid == 0xff) {
- if (PROMContent[RF_OPTION1_8723A] == 0xff)
- pHalData->EEPROMRegulatory = 0;
- else
- pHalData->EEPROMRegulatory =
- PROMContent[RF_OPTION1_8723A] & 0x7;
- } else {
- pHalData->EEPROMRegulatory =
- registry_par->regulatory_tid;
- }
- } else {
- pHalData->EEPROMRegulatory = 0;
- }
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory);
-
- if (!AutoLoadFail)
- pHalData->bTXPowerDataReadFromEEPORM = true;
-}
-
-void
-Hal_EfuseParseBTCoexistInfo_8723A(struct rtw_adapter *padapter,
- u8 *hwinfo, bool AutoLoadFail)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- u8 tempval;
- u32 tmpu4;
-
- if (!AutoLoadFail) {
- tmpu4 = rtl8723au_read32(padapter, REG_MULTI_FUNC_CTRL);
- if (tmpu4 & BT_FUNC_EN)
- pHalData->EEPROMBluetoothCoexist = 1;
- else
- pHalData->EEPROMBluetoothCoexist = 0;
- pHalData->EEPROMBluetoothType = BT_RTL8723A;
-
- /* The following need to be checked with newer version of */
- /* eeprom spec */
- tempval = hwinfo[RF_OPTION4_8723A];
- pHalData->EEPROMBluetoothAntNum = (tempval & 0x1);
- pHalData->EEPROMBluetoothAntIsolation = (tempval & 0x10) >> 4;
- pHalData->EEPROMBluetoothRadioShared = (tempval & 0x20) >> 5;
- } else {
- pHalData->EEPROMBluetoothCoexist = 0;
- pHalData->EEPROMBluetoothType = BT_RTL8723A;
- pHalData->EEPROMBluetoothAntNum = Ant_x2;
- pHalData->EEPROMBluetoothAntIsolation = 0;
- pHalData->EEPROMBluetoothRadioShared = BT_Radio_Shared;
- }
-
- rtl8723a_BT_init_hal_vars(padapter);
-}
-
-void
-Hal_EfuseParseEEPROMVer(struct rtw_adapter *padapter,
- u8 *hwinfo, bool AutoLoadFail)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (!AutoLoadFail)
- pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8723A];
- else
- pHalData->EEPROMVersion = 1;
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "Hal_EfuseParseEEPROMVer(), EEVer = %d\n",
- pHalData->EEPROMVersion);
-}
-
-void
-rtl8723a_EfuseParseChnlPlan(struct rtw_adapter *padapter,
- u8 *hwinfo, bool AutoLoadFail)
-{
- padapter->mlmepriv.ChannelPlan =
- hal_com_get_channel_plan23a(padapter, hwinfo ?
- hwinfo[EEPROM_ChannelPlan_8723A]:0xFF,
- padapter->registrypriv.channel_plan,
- RT_CHANNEL_DOMAIN_WORLD_WIDE_13,
- AutoLoadFail);
-
- DBG_8723A("mlmepriv.ChannelPlan = 0x%02x\n",
- padapter->mlmepriv.ChannelPlan);
-}
-
-void
-Hal_EfuseParseCustomerID(struct rtw_adapter *padapter,
- u8 *hwinfo, bool AutoLoadFail)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- if (!AutoLoadFail) {
- pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8723A];
- pHalData->EEPROMSubCustomerID =
- hwinfo[EEPROM_SubCustomID_8723A];
- } else {
- pHalData->EEPROMCustomerID = 0;
- pHalData->EEPROMSubCustomerID = 0;
- }
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID);
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "EEPROM SubCustomer ID: 0x%02x\n",
- pHalData->EEPROMSubCustomerID);
-}
-
-void
-Hal_EfuseParseAntennaDiversity(struct rtw_adapter *padapter,
- u8 *hwinfo, bool AutoLoadFail)
-{
-}
-
-void
-Hal_EfuseParseRateIndicationOption(struct rtw_adapter *padapter,
- u8 *hwinfo, bool AutoLoadFail)
-{
-}
-
-void
-Hal_EfuseParseXtal_8723A(struct rtw_adapter *pAdapter,
- u8 *hwinfo, u8 AutoLoadFail)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
-
- if (!AutoLoadFail) {
- pHalData->CrystalCap = hwinfo[EEPROM_XTAL_K_8723A];
- if (pHalData->CrystalCap == 0xFF)
- pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A;
- } else {
- pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A;
- }
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "%s: CrystalCap = 0x%2x\n", __func__,
- pHalData->CrystalCap);
-}
-
-void
-Hal_EfuseParseThermalMeter_8723A(struct rtw_adapter *padapter,
- u8 *PROMContent, bool AutoloadFail)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- /* */
- /* ThermalMeter from EEPROM */
- /* */
- if (!AutoloadFail)
- pHalData->EEPROMThermalMeter =
- PROMContent[EEPROM_THERMAL_METER_8723A];
- else
- pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
-
- if ((pHalData->EEPROMThermalMeter == 0xff) || AutoloadFail) {
- pHalData->bAPKThermalMeterIgnore = true;
- pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
- }
-
- DBG_8723A("%s: ThermalMeter = 0x%x\n", __func__,
- pHalData->EEPROMThermalMeter);
-}
-
-static void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc)
-{
- __le16 *usPtr = (__le16 *)ptxdesc;
- u32 count = 16; /* (32 bytes / 2 bytes per XOR) => 16 times */
- u32 index;
- u16 checksum = 0;
-
- /* Clear first */
- ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
-
- for (index = 0; index < count; index++)
- checksum ^= le16_to_cpu(usPtr[index]);
-
- ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
-}
-
-/*
- * Description: In normal chip, we should send some packet to Hw which
- * will be used by Fw in FW LPS mode. The function is to fill the Tx
- * descriptor of this packets, then
- */
-/* Fw can tell Hw to send these packet derectly. */
-/* Added by tynli. 2009.10.15. */
-/* */
-void rtl8723a_fill_fake_txdesc(struct rtw_adapter *padapter, u8 *pDesc,
- u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull)
-{
- struct tx_desc *ptxdesc;
-
- /* Clear all status */
- ptxdesc = (struct tx_desc *)pDesc;
- memset(pDesc, 0, TXDESC_SIZE);
-
- /* offset 0 */
- /* own, bFirstSeg, bLastSeg; */
- ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
-
- /* 32 bytes for TX Desc */
- ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) <<
- OFFSET_SHT) & 0x00ff0000);
-
- /* Buffer size + command header */
- ptxdesc->txdw0 |= cpu_to_le32(BufferLen & 0x0000ffff);
-
- /* offset 4 */
- /* Fixed queue of Mgnt queue */
- ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT << QSEL_SHT) & 0x00001f00);
-
- /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed
- to error vlaue by Hw. */
- if (IsPsPoll) {
- ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR);
- } else {
- /* Hw set sequence number */
- ptxdesc->txdw4 |= cpu_to_le32(BIT(7));
- /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */
- ptxdesc->txdw3 |= cpu_to_le32((8 << 28));
- }
-
- if (true == IsBTQosNull)
- ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); /* BT NULL */
-
- /* offset 16 */
- ptxdesc->txdw4 |= cpu_to_le32(BIT(8)); /* driver uses rate */
-
- /* USB interface drop packet if the checksum of descriptor isn't
- correct. */
- /* Using this checksum can let hardware recovery from packet bulk
- out error (e.g. Cancel URC, Bulk out error.). */
- rtl8723a_cal_txdesc_chksum(ptxdesc);
-}
-
-void hw_var_set_opmode(struct rtw_adapter *padapter, u8 mode)
-{
- u8 val8;
-
- if (mode == MSR_INFRA || mode == MSR_NOLINK) {
- StopTxBeacon(padapter);
-
- /* disable atim wnd */
- val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM;
- SetBcnCtrlReg23a(padapter, val8, ~val8);
- } else if (mode == MSR_ADHOC) {
- ResumeTxBeacon(padapter);
-
- val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB;
- SetBcnCtrlReg23a(padapter, val8, ~val8);
- } else if (mode == MSR_AP) {
- /* add NULL Data and BT NULL Data Packets to FW RSVD Page */
- rtl8723a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(padapter);
-
- ResumeTxBeacon(padapter);
-
- val8 = DIS_TSF_UDT | DIS_BCNQ_SUB;
- SetBcnCtrlReg23a(padapter, val8, ~val8);
-
- /* Set RCR */
- /* rtl8723au_write32(padapter, REG_RCR, 0x70002a8e);
- CBSSID_DATA must set to 0 */
- /* CBSSID_DATA must set to 0 */
- rtl8723au_write32(padapter, REG_RCR, 0x7000228e);
- /* enable to rx data frame */
- rtl8723au_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
- /* enable to rx ps-poll */
- rtl8723au_write16(padapter, REG_RXFLTMAP1, 0x0400);
-
- /* Beacon Control related register for first time */
- /* 2ms */
- rtl8723au_write8(padapter, REG_BCNDMATIM, 0x02);
- /* 5ms */
- rtl8723au_write8(padapter, REG_DRVERLYINT, 0x05);
- /* 10ms for port0 */
- rtl8723au_write8(padapter, REG_ATIMWND, 0x0a);
- rtl8723au_write16(padapter, REG_BCNTCFG, 0x00);
- rtl8723au_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
- /* +32767 (~32ms) */
- rtl8723au_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);
-
- /* reset TSF */
- rtl8723au_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
-
- /* enable BCN Function */
- /* don't enable update TSF (due to TSF update when
- beacon/probe rsp are received) */
- val8 = DIS_TSF_UDT | EN_BCN_FUNCTION |
- EN_TXBCN_RPT | DIS_BCNQ_SUB;
- SetBcnCtrlReg23a(padapter, val8, ~val8);
- }
-
- val8 = rtl8723au_read8(padapter, MSR);
- val8 = (val8 & 0xC) | mode;
- rtl8723au_write8(padapter, MSR, val8);
-}
-
-void hw_var_set_macaddr(struct rtw_adapter *padapter, u8 *val)
-{
- u8 idx = 0;
- u32 reg_macid;
-
- reg_macid = REG_MACID;
-
- for (idx = 0; idx < 6; idx++)
- rtl8723au_write8(padapter, (reg_macid + idx), val[idx]);
-}
-
-void hw_var_set_bssid(struct rtw_adapter *padapter, u8 *val)
-{
- u8 idx = 0;
- u32 reg_bssid;
-
- reg_bssid = REG_BSSID;
-
- for (idx = 0; idx < 6; idx++)
- rtl8723au_write8(padapter, (reg_bssid + idx), val[idx]);
-}
-
-void hw_var_set_correct_tsf(struct rtw_adapter *padapter)
-{
- u64 tsf;
- u32 reg_tsftr;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- /* tsf = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue %
- (pmlmeinfo->bcn_interval*1024)) - 1024; us */
- tsf = pmlmeext->TSFValue -
- do_div(pmlmeext->TSFValue,
- (pmlmeinfo->bcn_interval * 1024)) - 1024; /* us */
-
- if (((pmlmeinfo->state & 0x03) == MSR_ADHOC) ||
- ((pmlmeinfo->state & 0x03) == MSR_AP)) {
- /* pHalData->RegTxPause |= STOP_BCNQ;BIT(6) */
- /* rtl8723au_write8(padapter, REG_TXPAUSE,
- (rtl8723au_read8(Adapter, REG_TXPAUSE)|BIT(6))); */
- StopTxBeacon(padapter);
- }
-
- reg_tsftr = REG_TSFTR;
-
- /* disable related TSF function */
- SetBcnCtrlReg23a(padapter, 0, EN_BCN_FUNCTION);
-
- rtl8723au_write32(padapter, reg_tsftr, tsf);
- rtl8723au_write32(padapter, reg_tsftr + 4, tsf >> 32);
-
- /* enable related TSF function */
- SetBcnCtrlReg23a(padapter, EN_BCN_FUNCTION, 0);
-
- if (((pmlmeinfo->state & 0x03) == MSR_ADHOC) ||
- ((pmlmeinfo->state & 0x03) == MSR_AP))
- ResumeTxBeacon(padapter);
-}
-
-void hw_var_set_mlme_disconnect(struct rtw_adapter *padapter)
-{
- /* reject all data frames */
- rtl8723au_write16(padapter, REG_RXFLTMAP2, 0);
-
- /* reset TSF */
- rtl8723au_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
-
- /* disable update TSF */
- SetBcnCtrlReg23a(padapter, DIS_TSF_UDT, 0);
-}
-
-void hw_var_set_mlme_join(struct rtw_adapter *padapter, u8 type)
-{
- u8 RetryLimit = 0x30;
-
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- if (type == 0) { /* prepare to join */
- u32 v32;
-
- /* enable to rx data frame.Accept all data frame */
- /* rtl8723au_write32(padapter, REG_RCR,
- rtl8723au_read32(padapter, REG_RCR)|RCR_ADF); */
- rtl8723au_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
-
- v32 = rtl8723au_read32(padapter, REG_RCR);
- v32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
- rtl8723au_write32(padapter, REG_RCR, v32);
-
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
- RetryLimit =
- (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
- else /* Ad-hoc Mode */
- RetryLimit = 0x7;
- } else if (type == 1) { /* joinbss_event callback when join res < 0 */
- /* config RCR to receive different BSSID & not to
- receive data frame during linking */
- rtl8723au_write16(padapter, REG_RXFLTMAP2, 0);
- } else if (type == 2) { /* sta add event callback */
- /* enable update TSF */
- SetBcnCtrlReg23a(padapter, 0, DIS_TSF_UDT);
-
- if (check_fwstate(pmlmepriv,
- WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
- /* fixed beacon issue for 8191su........... */
- rtl8723au_write8(padapter, 0x542, 0x02);
- RetryLimit = 0x7;
- }
- }
-
- rtl8723au_write16(padapter, REG_RL,
- RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit <<
- RETRY_LIMIT_LONG_SHIFT);
-
- switch (type) {
- case 0:
- /* prepare to join */
- rtl8723a_BT_wifiassociate_notify(padapter, true);
- break;
- case 1:
- /* joinbss_event callback when join res < 0 */
- rtl8723a_BT_wifiassociate_notify(padapter, false);
- break;
- case 2:
- /* sta add event callback */
-/* BT_WifiMediaStatusNotify(padapter, RT_MEDIA_CONNECT); */
- break;
- }
-}
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c
deleted file mode 100644
index 06a6c3eeeb33..000000000000
--- a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c
+++ /dev/null
@@ -1,961 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTL8723A_PHYCFG_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-#include <rtl8723a_hal.h>
-#include <usb_ops_linux.h>
-
-/*---------------------------Define Local Constant---------------------------*/
-/* Channel switch:The size of command tables for switch channel*/
-#define MAX_PRECMD_CNT 16
-#define MAX_RFDEPENDCMD_CNT 16
-#define MAX_POSTCMD_CNT 16
-
-#define MAX_DOZE_WAITING_TIMES_9x 64
-
-/*---------------------------Define Local Constant---------------------------*/
-
-/*------------------------Define global variable-----------------------------*/
-
-/*------------------------Define local variable------------------------------*/
-
-/*--------------------Define export function prototype-----------------------*/
-/* Please refer to header file */
-/*--------------------Define export function prototype-----------------------*/
-
-/*----------------------------Function Body----------------------------------*/
-/* */
-/* 1. BB register R/W API */
-/* */
-
-/**
-* Function: phy_CalculateBitShift
-*
-* OverView: Get shifted position of the BitMask
-*
-* Input:
-* u32 BitMask,
-*
-* Output: none
-* Return: u32 Return the shift bit bit position of the mask
-*/
-static u32 phy_CalculateBitShift(u32 BitMask)
-{
- u32 i;
-
- for (i = 0; i <= 31; i++) {
- if (((BitMask>>i) & 0x1) == 1)
- break;
- }
-
- return i;
-}
-
-/**
-* Function: PHY_QueryBBReg
-*
-* OverView: Read "sepcific bits" from BB register
-*
-* Input:
-* struct rtw_adapter * Adapter,
-* u32 RegAddr, Target address to be readback
-* u32 BitMask Target bit position in the
-* target address to be readback
-* Output:
-* None
-* Return:
-* u32 Data The readback register value
-* Note:
-* This function is equal to "GetRegSetting" in PHY programming guide
-*/
-u32
-PHY_QueryBBReg(struct rtw_adapter *Adapter, u32 RegAddr, u32 BitMask)
-{
- u32 ReturnValue = 0, OriginalValue, BitShift;
-
- OriginalValue = rtl8723au_read32(Adapter, RegAddr);
- BitShift = phy_CalculateBitShift(BitMask);
- ReturnValue = (OriginalValue & BitMask) >> BitShift;
- return ReturnValue;
-}
-
-/**
-* Function: PHY_SetBBReg
-*
-* OverView: Write "Specific bits" to BB register (page 8~)
-*
-* Input:
-* struct rtw_adapter * Adapter,
-* u32 RegAddr, Target address to be modified
-* u32 BitMask Target bit position in the
-* target address to be modified
-* u32 Data The new register value in the
-* target bit position of the
-* target address
-*
-* Output:
-* None
-* Return:
-* None
-* Note:
-* This function is equal to "PutRegSetting" in PHY programming guide
-*/
-
-void
-PHY_SetBBReg(struct rtw_adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
-{
- u32 OriginalValue, BitShift;
-
- if (BitMask != bMaskDWord) {/* if not "double word" write */
- OriginalValue = rtl8723au_read32(Adapter, RegAddr);
- BitShift = phy_CalculateBitShift(BitMask);
- Data = (OriginalValue & (~BitMask)) | (Data << BitShift);
- }
-
- rtl8723au_write32(Adapter, RegAddr, Data);
-
- /* RTPRINT(FPHY, PHY_BBW, ("BBW MASK = 0x%lx Addr[0x%lx]= 0x%lx\n", BitMask, RegAddr, Data)); */
-}
-
-/* */
-/* 2. RF register R/W API */
-/* */
-
-/**
-* Function: phy_RFSerialRead
-*
-* OverView: Read regster from RF chips
-*
-* Input:
-* struct rtw_adapter * Adapter,
-* enum RF_RADIO_PATH eRFPath, Radio path of A/B/C/D
-* u32 Offset, The target address to be read
-*
-* Output: None
-* Return: u32 reback value
-* Note: Threre are three types of serial operations:
-* 1. Software serial write
-* 2. Hardware LSSI-Low Speed Serial Interface
-* 3. Hardware HSSI-High speed
-* serial write. Driver need to implement (1) and (2).
-* This function is equal to the combination of RF_ReadReg() and
-* RFLSSIRead()
-*/
-static u32
-phy_RFSerialRead(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
- u32 Offset)
-{
- u32 retValue = 0;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct bb_reg_define *pPhyReg = &pHalData->PHYRegDef[eRFPath];
- u32 NewOffset;
- u32 tmplong, tmplong2;
- u8 RfPiEnable = 0;
- /* */
- /* Make sure RF register offset is correct */
- /* */
- Offset &= 0x3f;
-
- /* */
- /* Switch page for 8256 RF IC */
- /* */
- NewOffset = Offset;
-
- /* 2009/06/17 MH We can not execute IO for power save or
- other accident mode. */
- /* if (RT_CANNOT_IO(Adapter)) */
- /* */
- /* RTPRINT(FPHY, PHY_RFR, ("phy_RFSerialRead return all one\n")); */
- /* return 0xFFFFFFFF; */
- /* */
-
- /* For 92S LSSI Read RFLSSIRead */
- /* For RF A/B write 0x824/82c(does not work in the future) */
- /* We must use 0x824 for RF A and B to execute read trigger */
- tmplong = rtl8723au_read32(Adapter, rFPGA0_XA_HSSIParameter2);
- if (eRFPath == RF_PATH_A)
- tmplong2 = tmplong;
- else
- tmplong2 = rtl8723au_read32(Adapter, pPhyReg->rfHSSIPara2);
-
- tmplong2 = (tmplong2 & ~bLSSIReadAddress) |
- (NewOffset << 23) | bLSSIReadEdge; /* T65 RF */
-
- rtl8723au_write32(Adapter, rFPGA0_XA_HSSIParameter2,
- tmplong & (~bLSSIReadEdge));
- udelay(10);/* PlatformStallExecution(10); */
-
- rtl8723au_write32(Adapter, pPhyReg->rfHSSIPara2, tmplong2);
- udelay(100);/* PlatformStallExecution(100); */
-
- rtl8723au_write32(Adapter, rFPGA0_XA_HSSIParameter2,
- tmplong | bLSSIReadEdge);
- udelay(10);/* PlatformStallExecution(10); */
-
- if (eRFPath == RF_PATH_A)
- RfPiEnable = (u8)PHY_QueryBBReg(Adapter,
- rFPGA0_XA_HSSIParameter1,
- BIT(8));
- else if (eRFPath == RF_PATH_B)
- RfPiEnable = (u8)PHY_QueryBBReg(Adapter,
- rFPGA0_XB_HSSIParameter1,
- BIT(8));
-
- if (RfPiEnable) {
- /* Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */
- retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi,
- bLSSIReadBackData);
- /* DBG_8723A("Readback from RF-PI : 0x%x\n", retValue); */
- } else {
- /* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */
- retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack,
- bLSSIReadBackData);
- /* DBG_8723A("Readback from RF-SI : 0x%x\n", retValue); */
- }
- /* DBG_8723A("RFR-%d Addr[0x%x]= 0x%x\n", eRFPath, pPhyReg->rfLSSIReadBack, retValue); */
-
- return retValue;
-}
-
-/**
-* Function: phy_RFSerialWrite
-*
-* OverView: Write data to RF register (page 8~)
-*
-* Input:
-* struct rtw_adapter * Adapter,
-* enum RF_RADIO_PATH eRFPath, Radio path of A/B/C/D
-* u32 Offset, The target address to be read
-* u32 Data The new register Data in the target
-* bit position of the target to be read
-*
-* Output:
-* None
-* Return:
-* None
-* Note:
-* Threre are three types of serial operations:
-* 1. Software serial write
-* 2. Hardware LSSI-Low Speed Serial Interface
-* 3. Hardware HSSI-High speed
-* serial write. Driver need to implement (1) and (2).
-* This function is equal to the combination of RF_ReadReg() and
-* RFLSSIRead()
-*
-* Note: For RF8256 only
-* The total count of RTL8256(Zebra4) register is around 36 bit it only employs
-* 4-bit RF address. RTL8256 uses "register mode control bit"
-* (Reg00[12], Reg00[10]) to access register address bigger than 0xf.
-* See "Appendix-4 in PHY Configuration programming guide" for more details.
-* Thus, we define a sub-finction for RTL8526 register address conversion
-* ===========================================================
-* Register Mode: RegCTL[1] RegCTL[0] Note
-* (Reg00[12]) (Reg00[10])
-* ===========================================================
-* Reg_Mode0 0 x Reg 0 ~15(0x0 ~ 0xf)
-* ------------------------------------------------------------------
-* Reg_Mode1 1 0 Reg 16 ~30(0x1 ~ 0xf)
-* ------------------------------------------------------------------
-* Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf)
-* ------------------------------------------------------------------
-*
-* 2008/09/02 MH Add 92S RF definition
-*/
-static void
-phy_RFSerialWrite(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
- u32 Offset, u32 Data)
-{
- u32 DataAndAddr = 0;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct bb_reg_define *pPhyReg = &pHalData->PHYRegDef[eRFPath];
- u32 NewOffset;
-
- /* 2009/06/17 MH We can not execute IO for power save or
- other accident mode. */
- /* if (RT_CANNOT_IO(Adapter)) */
- /* */
- /* RTPRINT(FPHY, PHY_RFW, ("phy_RFSerialWrite stop\n")); */
- /* return; */
- /* */
-
- Offset &= 0x3f;
-
- /* */
- /* Shadow Update */
- /* */
- /* PHY_RFShadowWrite(Adapter, eRFPath, Offset, Data); */
-
- /* */
- /* Switch page for 8256 RF IC */
- /* */
- NewOffset = Offset;
-
- /* */
- /* Put write addr in [5:0] and write data in [31:16] */
- /* */
- /* DataAndAddr = (Data<<16) | (NewOffset&0x3f); */
- /* T65 RF */
- DataAndAddr = ((NewOffset<<20) | (Data&0x000fffff)) & 0x0fffffff;
-
- /* */
- /* Write Operation */
- /* */
- rtl8723au_write32(Adapter, pPhyReg->rf3wireOffset, DataAndAddr);
-}
-
-/**
-* Function: PHY_QueryRFReg
-*
-* OverView: Query "Specific bits" to RF register (page 8~)
-*
-* Input:
-* struct rtw_adapter * Adapter,
-* enum RF_RADIO_PATH eRFPath, Radio path of A/B/C/D
-* u32 RegAddr, The target address to be read
-* u32BitMask The target bit position in the target
-* address to be read
-*
-* Output:
-* None
-* Return:
-* u32 Readback value
-* Note:
-* This function is equal to "GetRFRegSetting" in PHY programming guide
-*/
-u32
-PHY_QueryRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
- u32 RegAddr, u32 BitMask)
-{
- u32 Original_Value, Readback_Value, BitShift;
- /* struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); */
- /* u8 RFWaitCounter = 0; */
- /* _irqL irqL; */
-
- Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr);
-
- BitShift = phy_CalculateBitShift(BitMask);
- Readback_Value = (Original_Value & BitMask) >> BitShift;
-
- return Readback_Value;
-}
-
-/**
-* Function: PHY_SetRFReg
-*
-* OverView: Write "Specific bits" to RF register (page 8~)
-*
-* Input:
-* struct rtw_adapter * Adapter,
-* enum RF_RADIO_PATH eRFPath, Radio path of A/B/C/D
-* u32 RegAddr, The target address to be modified
-* u32 BitMask The target bit position in the target
-* address to be modified
-* u32 Data The new register Data in the target
-* bit position of the target address
-*
-* Output:
-* None
-* Return:
-* None
-* Note: This function is equal to "PutRFRegSetting" in PHY programming guide
-*/
-void
-PHY_SetRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath,
- u32 RegAddr, u32 BitMask, u32 Data)
-{
- /* struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); */
- /* u8 RFWaitCounter = 0; */
- u32 Original_Value, BitShift;
-
- /* RF data is 12 bits only */
- if (BitMask != bRFRegOffsetMask) {
- Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr);
- BitShift = phy_CalculateBitShift(BitMask);
- Data = (Original_Value & (~BitMask)) | (Data << BitShift);
- }
-
- phy_RFSerialWrite(Adapter, eRFPath, RegAddr, Data);
-}
-
-/* 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */
-
-/*-----------------------------------------------------------------------------
- * Function: PHY_MACConfig8723A
- *
- * Overview: Condig MAC by header file or parameter file.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 08/12/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-int PHY_MACConfig8723A(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
-
- /* */
- /* Config MAC */
- /* */
- ODM_ReadAndConfig_MAC_REG_8723A(&pHalData->odmpriv);
-
- /* 2010.07.13 AMPDU aggregation number 9 */
- rtl8723au_write8(Adapter, REG_MAX_AGGR_NUM, 0x0A);
- if (pHalData->rf_type == RF_2T2R &&
- BOARD_USB_DONGLE == pHalData->BoardType)
- rtl8723au_write8(Adapter, 0x40, 0x04);
-
- return _SUCCESS;
-}
-
-/**
-* Function: phy_InitBBRFRegisterDefinition
-*
-* OverView: Initialize Register definition offset for Radio Path A/B/C/D
-*
-* Input:
-* struct rtw_adapter * Adapter,
-*
-* Output: None
-* Return: None
-* Note:
-* The initialization value is constant and it should never be changes
-*/
-static void
-phy_InitBBRFRegisterDefinition(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
-
- /* RF Interface Sowrtware Control */
- /* 16 LSBs if read 32-bit from 0x870 */
- pHalData->PHYRegDef[RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW;
- /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */
- pHalData->PHYRegDef[RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW;
-
- /* RF Interface Readback Value */
- /* 16 LSBs if read 32-bit from 0x8E0 */
- pHalData->PHYRegDef[RF_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB;
- /* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */
- pHalData->PHYRegDef[RF_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;
-
- /* RF Interface Output (and Enable) */
- /* 16 LSBs if read 32-bit from 0x860 */
- pHalData->PHYRegDef[RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE;
- /* 16 LSBs if read 32-bit from 0x864 */
- pHalData->PHYRegDef[RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE;
-
- /* RF Interface (Output and) Enable */
- /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
- pHalData->PHYRegDef[RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE;
- /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */
- pHalData->PHYRegDef[RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE;
-
- /* Addr of LSSI. Wirte RF register by driver */
- pHalData->PHYRegDef[RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter;
- pHalData->PHYRegDef[RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
-
- /* RF parameter */
- /* BB Band Select */
- pHalData->PHYRegDef[RF_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter;
- pHalData->PHYRegDef[RF_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter;
-
- /* Tx AGC Gain Stage (same for all path. Should we remove this?) */
- pHalData->PHYRegDef[RF_PATH_A].rfTxGainStage = rFPGA0_TxGainStage;
- pHalData->PHYRegDef[RF_PATH_B].rfTxGainStage = rFPGA0_TxGainStage;
-
- /* Tranceiver A~D HSSI Parameter-1 */
- /* wire control parameter1 */
- pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1;
- /* wire control parameter1 */
- pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1;
-
- /* Tranceiver A~D HSSI Parameter-2 */
- /* wire control parameter2 */
- pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;
- /* wire control parameter2 */
- pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2;
-
- /* RF switch Control */
- pHalData->PHYRegDef[RF_PATH_A].rfSwitchControl =
- rFPGA0_XAB_SwitchControl; /* TR/Ant switch control */
- pHalData->PHYRegDef[RF_PATH_B].rfSwitchControl =
- rFPGA0_XAB_SwitchControl;
-
- /* AGC control 1 */
- pHalData->PHYRegDef[RF_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1;
- pHalData->PHYRegDef[RF_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1;
-
- /* AGC control 2 */
- pHalData->PHYRegDef[RF_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2;
- pHalData->PHYRegDef[RF_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2;
-
- /* RX AFE control 1 */
- pHalData->PHYRegDef[RF_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance;
- pHalData->PHYRegDef[RF_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance;
-
- /* RX AFE control 1 */
- pHalData->PHYRegDef[RF_PATH_A].rfRxAFE = rOFDM0_XARxAFE;
- pHalData->PHYRegDef[RF_PATH_B].rfRxAFE = rOFDM0_XBRxAFE;
-
- /* Tx AFE control 1 */
- pHalData->PHYRegDef[RF_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance;
- pHalData->PHYRegDef[RF_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance;
-
- /* Tx AFE control 2 */
- pHalData->PHYRegDef[RF_PATH_A].rfTxAFE = rOFDM0_XATxAFE;
- pHalData->PHYRegDef[RF_PATH_B].rfTxAFE = rOFDM0_XBTxAFE;
-
- /* Tranceiver LSSI Readback SI mode */
- pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
- pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
-
- /* Tranceiver LSSI Readback PI mode */
- pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi =
- TransceiverA_HSPI_Readback;
- pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBackPi =
- TransceiverB_HSPI_Readback;
-}
-
-/* The following is for High Power PA */
-static void
-storePwrIndexDiffRateOffset(struct rtw_adapter *Adapter, u32 RegAddr,
- u32 BitMask, u32 Data)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
-
- if (RegAddr == rTxAGC_A_Rate18_06) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0] = Data;
- }
- if (RegAddr == rTxAGC_A_Rate54_24) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1] = Data;
- }
- if (RegAddr == rTxAGC_A_CCK1_Mcs32) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6] = Data;
- }
- if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0xffffff00) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7] = Data;
- }
- if (RegAddr == rTxAGC_A_Mcs03_Mcs00) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2] = Data;
- }
- if (RegAddr == rTxAGC_A_Mcs07_Mcs04) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3] = Data;
- }
- if (RegAddr == rTxAGC_A_Mcs11_Mcs08) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4] = Data;
- }
- if (RegAddr == rTxAGC_A_Mcs15_Mcs12) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5] = Data;
- }
- if (RegAddr == rTxAGC_B_Rate18_06) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8] = Data;
- }
- if (RegAddr == rTxAGC_B_Rate54_24) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9] = Data;
- }
- if (RegAddr == rTxAGC_B_CCK1_55_Mcs32) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14] = Data;
- }
- if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0x000000ff) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15] = Data;
- }
- if (RegAddr == rTxAGC_B_Mcs03_Mcs00) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10] = Data;
- }
- if (RegAddr == rTxAGC_B_Mcs07_Mcs04) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11] = Data;
- }
- if (RegAddr == rTxAGC_B_Mcs11_Mcs08) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12] = Data;
- }
- if (RegAddr == rTxAGC_B_Mcs15_Mcs12) {
- pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13] = Data;
- pHalData->pwrGroupCnt++;
- }
-}
-
-/*-----------------------------------------------------------------------------
- * Function: phy_ConfigBBWithPgHeaderFile
- *
- * Overview: Config PHY_REG_PG array
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/06/2008 MHC Add later!!!!!!.. Please modify for new files!!!!
- * 11/10/2008 tynli Modify to mew files.
- *---------------------------------------------------------------------------*/
-static int
-phy_ConfigBBWithPgHeaderFile(struct rtw_adapter *Adapter)
-{
- int i;
- u32 *Rtl819XPHY_REGArray_Table_PG;
- u16 PHY_REGArrayPGLen;
-
- PHY_REGArrayPGLen = Rtl8723_PHY_REG_Array_PGLength;
- Rtl819XPHY_REGArray_Table_PG = (u32 *)Rtl8723_PHY_REG_Array_PG;
-
- for (i = 0; i < PHY_REGArrayPGLen; i = i + 3) {
- storePwrIndexDiffRateOffset(Adapter,
- Rtl819XPHY_REGArray_Table_PG[i],
- Rtl819XPHY_REGArray_Table_PG[i+1],
- Rtl819XPHY_REGArray_Table_PG[i+2]);
- }
-
- return _SUCCESS;
-}
-
-static void
-phy_BB8192C_Config_1T(struct rtw_adapter *Adapter)
-{
- /* for path - B */
- PHY_SetBBReg(Adapter, rFPGA0_TxInfo, 0x3, 0x2);
- PHY_SetBBReg(Adapter, rFPGA1_TxInfo, 0x300033, 0x200022);
-
- /* 20100519 Joseph: Add for 1T2R config. Suggested by Kevin,
- Jenyu and Yunan. */
- PHY_SetBBReg(Adapter, rCCK0_AFESetting, bMaskByte3, 0x45);
- PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x23);
- /* B path first AGC */
- PHY_SetBBReg(Adapter, rOFDM0_AGCParameter1, 0x30, 0x1);
-
- PHY_SetBBReg(Adapter, 0xe74, 0x0c000000, 0x2);
- PHY_SetBBReg(Adapter, 0xe78, 0x0c000000, 0x2);
- PHY_SetBBReg(Adapter, 0xe7c, 0x0c000000, 0x2);
- PHY_SetBBReg(Adapter, 0xe80, 0x0c000000, 0x2);
- PHY_SetBBReg(Adapter, 0xe88, 0x0c000000, 0x2);
-}
-
-static int
-phy_BB8723a_Config_ParaFile(struct rtw_adapter *Adapter)
-{
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter);
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- int rtStatus = _SUCCESS;
-
- /* */
- /* 1. Read PHY_REG.TXT BB INIT!! */
- /* We will separate as 88C / 92C according to chip version */
- /* */
- ODM_ReadAndConfig_PHY_REG_1T_8723A(&pHalData->odmpriv);
-
- /* */
- /* 20100318 Joseph: Config 2T2R to 1T2R if necessary. */
- /* */
- if (pHalData->rf_type == RF_1T2R) {
- phy_BB8192C_Config_1T(Adapter);
- DBG_8723A("phy_BB8723a_Config_ParaFile():Config to 1T!!\n");
- }
-
- /* */
- /* 2. If EEPROM or EFUSE autoload OK, We must config by
- PHY_REG_PG.txt */
- /* */
- if (pEEPROM->bautoload_fail_flag == false) {
- pHalData->pwrGroupCnt = 0;
-
- rtStatus = phy_ConfigBBWithPgHeaderFile(Adapter);
- }
-
- if (rtStatus != _SUCCESS)
- goto phy_BB8190_Config_ParaFile_Fail;
-
- /* */
- /* 3. BB AGC table Initialization */
- /* */
- ODM_ReadAndConfig_AGC_TAB_1T_8723A(&pHalData->odmpriv);
-
-phy_BB8190_Config_ParaFile_Fail:
-
- return rtStatus;
-}
-
-int
-PHY_BBConfig8723A(struct rtw_adapter *Adapter)
-{
- int rtStatus = _SUCCESS;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- u8 TmpU1B = 0;
- u8 CrystalCap;
-
- phy_InitBBRFRegisterDefinition(Adapter);
-
- /* Suggested by Scott. tynli_test. 2010.12.30. */
- /* 1. 0x28[1] = 1 */
- TmpU1B = rtl8723au_read8(Adapter, REG_AFE_PLL_CTRL);
- udelay(2);
- rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL, TmpU1B | BIT(1));
- udelay(2);
-
- /* 2. 0x29[7:0] = 0xFF */
- rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL+1, 0xff);
- udelay(2);
-
- /* 3. 0x02[1:0] = 2b'11 */
- TmpU1B = rtl8723au_read8(Adapter, REG_SYS_FUNC_EN);
- rtl8723au_write8(Adapter, REG_SYS_FUNC_EN,
- (TmpU1B | FEN_BB_GLB_RSTn | FEN_BBRSTB));
-
- /* 4. 0x25[6] = 0 */
- TmpU1B = rtl8723au_read8(Adapter, REG_AFE_XTAL_CTRL + 1);
- rtl8723au_write8(Adapter, REG_AFE_XTAL_CTRL+1, TmpU1B & ~BIT(6));
-
- /* 5. 0x24[20] = 0 Advised by SD3 Alex Wang. 2011.02.09. */
- TmpU1B = rtl8723au_read8(Adapter, REG_AFE_XTAL_CTRL+2);
- rtl8723au_write8(Adapter, REG_AFE_XTAL_CTRL+2, TmpU1B & ~BIT(4));
-
- /* 6. 0x1f[7:0] = 0x07 */
- rtl8723au_write8(Adapter, REG_RF_CTRL, 0x07);
-
- /* */
- /* Config BB and AGC */
- /* */
- rtStatus = phy_BB8723a_Config_ParaFile(Adapter);
-
-/* only for B-cut */
- if (pHalData->EEPROMVersion >= 0x01) {
- CrystalCap = pHalData->CrystalCap & 0x3F;
- PHY_SetBBReg(Adapter, REG_MAC_PHY_CTRL, 0xFFF000,
- (CrystalCap | (CrystalCap << 6)));
- }
-
- rtl8723au_write32(Adapter, REG_LDOA15_CTRL, 0x01572505);
- return rtStatus;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: SetTxPowerLevel8723A()
- *
- * Overview: This function is export to "HalCommon" moudule
- * We must consider RF path later!!!!!!!
- *
- * Input: struct rtw_adapter * Adapter
- * u8 channel
- *
- * Output: NONE
- *
- * Return: NONE
- *
- *---------------------------------------------------------------------------*/
-void PHY_SetTxPowerLevel8723A(struct rtw_adapter *Adapter, u8 channel)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- u8 cckpwr[2], ofdmpwr[2]; /* [0]:RF-A, [1]:RF-B */
- int i = channel - 1;
-
- if (pHalData->bTXPowerDataReadFromEEPORM == false)
- return;
-
- /* 1. CCK */
- cckpwr[RF_PATH_A] = pHalData->TxPwrLevelCck[RF_PATH_A][i];
- cckpwr[RF_PATH_B] = pHalData->TxPwrLevelCck[RF_PATH_B][i];
-
- /* 2. OFDM for 1S or 2S */
- if (GET_RF_TYPE(Adapter) == RF_1T2R ||
- GET_RF_TYPE(Adapter) == RF_1T1R) {
- /* Read HT 40 OFDM TX power */
- ofdmpwr[RF_PATH_A] = pHalData->TxPwrLevelHT40_1S[RF_PATH_A][i];
- ofdmpwr[RF_PATH_B] = pHalData->TxPwrLevelHT40_1S[RF_PATH_B][i];
- } else if (GET_RF_TYPE(Adapter) == RF_2T2R) {
- /* Read HT 40 OFDM TX power */
- ofdmpwr[RF_PATH_A] = pHalData->TxPwrLevelHT40_2S[RF_PATH_A][i];
- ofdmpwr[RF_PATH_B] = pHalData->TxPwrLevelHT40_2S[RF_PATH_B][i];
- }
-
- rtl823a_phy_rf6052setccktxpower(Adapter, &cckpwr[0]);
- rtl8723a_PHY_RF6052SetOFDMTxPower(Adapter, &ofdmpwr[0], channel);
-}
-
-/*-----------------------------------------------------------------------------
- * Function: PHY_SetBWMode23aCallback8192C()
- *
- * Overview: Timer callback function for SetSetBWMode23a
- *
- * Input: PRT_TIMER pTimer
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Note:
- * (1) We do not take j mode into consideration now
- * (2) Will two workitem of "switch channel" and
- * "switch channel bandwidth" run concurrently?
- *---------------------------------------------------------------------------*/
-static void
-_PHY_SetBWMode23a92C(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- u8 regBwOpMode;
- u8 regRRSR_RSC;
-
- if (Adapter->bDriverStopped)
- return;
-
- /* 3 */
- /* 3<1>Set MAC register */
- /* 3 */
-
- regBwOpMode = rtl8723au_read8(Adapter, REG_BWOPMODE);
- regRRSR_RSC = rtl8723au_read8(Adapter, REG_RRSR+2);
-
- switch (pHalData->CurrentChannelBW) {
- case HT_CHANNEL_WIDTH_20:
- regBwOpMode |= BW_OPMODE_20MHZ;
- rtl8723au_write8(Adapter, REG_BWOPMODE, regBwOpMode);
- break;
- case HT_CHANNEL_WIDTH_40:
- regBwOpMode &= ~BW_OPMODE_20MHZ;
- rtl8723au_write8(Adapter, REG_BWOPMODE, regBwOpMode);
- regRRSR_RSC = (regRRSR_RSC & 0x90) |
- (pHalData->nCur40MhzPrimeSC << 5);
- rtl8723au_write8(Adapter, REG_RRSR+2, regRRSR_RSC);
- break;
-
- default:
- break;
- }
-
- /* 3 */
- /* 3<2>Set PHY related register */
- /* 3 */
- switch (pHalData->CurrentChannelBW) {
- /* 20 MHz channel*/
- case HT_CHANNEL_WIDTH_20:
- PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0);
- PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0);
- PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT(10), 1);
-
- break;
-
- /* 40 MHz channel*/
- case HT_CHANNEL_WIDTH_40:
- PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1);
- PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1);
-
- /* Set Control channel to upper or lower. These settings
- are required only for 40MHz */
- PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand,
- (pHalData->nCur40MhzPrimeSC >> 1));
- PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00,
- pHalData->nCur40MhzPrimeSC);
- PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT(10), 0);
-
- PHY_SetBBReg(Adapter, 0x818, BIT(26) | BIT(27),
- (pHalData->nCur40MhzPrimeSC ==
- HAL_PRIME_CHNL_OFFSET_LOWER) ? 2:1);
- break;
-
- default:
- break;
- }
- /* Skip over setting of J-mode in BB register here. Default value
- is "None J mode". Emily 20070315 */
-
- /* Added it for 20/40 mhz switch time evaluation by guangan 070531 */
- /* NowL = PlatformEFIORead4Byte(Adapter, TSFR); */
- /* NowH = PlatformEFIORead4Byte(Adapter, TSFR+4); */
- /* EndTime = ((u64)NowH << 32) + NowL; */
-
- rtl8723a_phy_rf6052set_bw(Adapter, pHalData->CurrentChannelBW);
-}
-
- /*-----------------------------------------------------------------------------
- * Function: SetBWMode23a8190Pci()
- *
- * Overview: This function is export to "HalCommon" moudule
- *
- * Input: struct rtw_adapter * Adapter
- * enum ht_channel_width Bandwidth 20M or 40M
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Note: We do not take j mode into consideration now
- *---------------------------------------------------------------------------*/
-void
-PHY_SetBWMode23a8723A(struct rtw_adapter *Adapter,
- enum ht_channel_width Bandwidth, unsigned char Offset)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- enum ht_channel_width tmpBW = pHalData->CurrentChannelBW;
-
- pHalData->CurrentChannelBW = Bandwidth;
-
- pHalData->nCur40MhzPrimeSC = Offset;
-
- if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved))
- _PHY_SetBWMode23a92C(Adapter);
- else
- pHalData->CurrentChannelBW = tmpBW;
-}
-
-static void _PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
-{
- enum RF_RADIO_PATH eRFPath;
- u32 param1, param2;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
-
- /* s1. pre common command - CmdID_SetTxPowerLevel */
- PHY_SetTxPowerLevel8723A(Adapter, channel);
-
- /* s2. RF dependent command - CmdID_RF_WriteReg,
- param1 = RF_CHNLBW, param2 = channel */
- param1 = RF_CHNLBW;
- param2 = channel;
- for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) {
- pHalData->RfRegChnlVal[eRFPath] =
- (pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2;
- PHY_SetRFReg(Adapter, eRFPath, param1,
- bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]);
- }
-
- /* s3. post common command - CmdID_End, None */
-}
-
-void PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- u8 tmpchannel = pHalData->CurrentChannel;
- bool result = true;
-
- if (channel == 0)
- channel = 1;
-
- pHalData->CurrentChannel = channel;
-
- if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) {
- _PHY_SwChnl8723A(Adapter, channel);
-
- if (!result)
- pHalData->CurrentChannel = tmpchannel;
- } else {
- pHalData->CurrentChannel = tmpchannel;
- }
-}
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c b/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c
deleted file mode 100644
index 24c0ff3d82bc..000000000000
--- a/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c
+++ /dev/null
@@ -1,503 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-/******************************************************************************
- *
- *
- * Module: rtl8192c_rf6052.c (Source C File)
- *
- * Note: Provide RF 6052 series relative API.
- *
- * Function:
- *
- * Export:
- *
- * Abbrev:
- *
- * History:
- * Data Who Remark
- *
- * 09/25/2008 MHC Create initial version.
- * 11/05/2008 MHC Add API for tw power setting.
- *
- *
-******************************************************************************/
-
-#define _RTL8723A_RF6052_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-#include <rtl8723a_hal.h>
-#include <usb_ops_linux.h>
-
-/*-----------------------------------------------------------------------------
- * Function: PHY_RF6052SetBandwidth()
- *
- * Overview: This function is called by SetBWMode23aCallback8190Pci() only
- *
- * Input: struct rtw_adapter * Adapter
- * WIRELESS_BANDWIDTH_E Bandwidth 20M or 40M
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Note: For RF type 0222D
- *---------------------------------------------------------------------------*/
-void rtl8723a_phy_rf6052set_bw(struct rtw_adapter *Adapter,
- enum ht_channel_width Bandwidth) /* 20M or 40M */
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
-
- switch (Bandwidth) {
- case HT_CHANNEL_WIDTH_20:
- pHalData->RfRegChnlVal[0] =
- (pHalData->RfRegChnlVal[0] & 0xfffff3ff) | 0x0400;
- PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask,
- pHalData->RfRegChnlVal[0]);
- break;
- case HT_CHANNEL_WIDTH_40:
- pHalData->RfRegChnlVal[0] =
- (pHalData->RfRegChnlVal[0] & 0xfffff3ff);
- PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask,
- pHalData->RfRegChnlVal[0]);
- break;
- default:
- break;
- }
-}
-
-/*-----------------------------------------------------------------------------
- * Function: PHY_RF6052SetCckTxPower
- *
- * Overview:
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/05/2008 MHC Simulate 8192series..
- *
- *---------------------------------------------------------------------------*/
-
-void rtl823a_phy_rf6052setccktxpower(struct rtw_adapter *Adapter,
- u8 *pPowerlevel)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
- struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
- u32 TxAGC[2] = {0, 0}, tmpval = 0;
- u8 idx1, idx2;
- u8 *ptr;
-
- if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
- TxAGC[RF_PATH_A] = 0x3f3f3f3f;
- TxAGC[RF_PATH_B] = 0x3f3f3f3f;
-
- for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
- TxAGC[idx1] = pPowerlevel[idx1] |
- (pPowerlevel[idx1] << 8) |
- (pPowerlevel[idx1] << 16) |
- (pPowerlevel[idx1] << 24);
- /*
- * 2010/10/18 MH For external PA module. We need
- * to limit power index to be less than 0x20.
- */
- if (TxAGC[idx1] > 0x20 && pHalData->ExternalPA)
- TxAGC[idx1] = 0x20;
- }
- } else {
-/* 20100427 Joseph: Driver dynamic Tx power shall not affect Tx
- * power. It shall be determined by power training mechanism. */
-/* Currently, we cannot fully disable driver dynamic tx power
- * mechanism because it is referenced by BT coexist mechanism. */
-/* In the future, two mechanism shall be separated from each other
- * and maintained independently. Thanks for Lanhsin's reminder. */
- if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) {
- TxAGC[RF_PATH_A] = 0x10101010;
- TxAGC[RF_PATH_B] = 0x10101010;
- } else if (pdmpriv->DynamicTxHighPowerLvl ==
- TxHighPwrLevel_Level2) {
- TxAGC[RF_PATH_A] = 0x00000000;
- TxAGC[RF_PATH_B] = 0x00000000;
- } else {
- for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
- TxAGC[idx1] = pPowerlevel[idx1] |
- (pPowerlevel[idx1] << 8) |
- (pPowerlevel[idx1] << 16) |
- (pPowerlevel[idx1] << 24);
- }
-
- if (pHalData->EEPROMRegulatory == 0) {
- tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][6]) +
- (pHalData->MCSTxPowerLevelOriginalOffset[0][7]<<8);
- TxAGC[RF_PATH_A] += tmpval;
-
- tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][14]) +
- (pHalData->MCSTxPowerLevelOriginalOffset[0][15]<<24);
- TxAGC[RF_PATH_B] += tmpval;
- }
- }
- }
-
- for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
- ptr = (u8 *)(&TxAGC[idx1]);
- for (idx2 = 0; idx2 < 4; idx2++) {
- if (*ptr > RF6052_MAX_TX_PWR)
- *ptr = RF6052_MAX_TX_PWR;
- ptr++;
- }
- }
-
- /* rf-A cck tx power */
- tmpval = TxAGC[RF_PATH_A] & 0xff;
- PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, tmpval);
- tmpval = TxAGC[RF_PATH_A] >> 8;
- PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
-
- /* rf-B cck tx power */
- tmpval = TxAGC[RF_PATH_B] >> 24;
- PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, tmpval);
- tmpval = TxAGC[RF_PATH_B] & 0x00ffffff;
- PHY_SetBBReg(Adapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval);
-} /* PHY_RF6052SetCckTxPower */
-
-/* powerbase0 for OFDM rates */
-/* powerbase1 for HT MCS rates */
-static void getPowerBase(struct rtw_adapter *Adapter, u8 *pPowerLevel,
- u8 Channel, u32 *OfdmBase, u32 *MCSBase)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- u32 ofdm, mcs;
- u8 Legacy_pwrdiff = 0;
- s8 HT20_pwrdiff = 0;
- u8 i, powerlevel[2];
-
- for (i = 0; i < 2; i++) {
- powerlevel[i] = pPowerLevel[i];
- Legacy_pwrdiff = pHalData->TxPwrLegacyHtDiff[i][Channel-1];
- ofdm = powerlevel[i] + Legacy_pwrdiff;
-
- ofdm = ofdm << 24 | ofdm << 16 | ofdm << 8 | ofdm;
- *(OfdmBase + i) = ofdm;
- }
-
- for (i = 0; i < 2; i++) {
- /* Check HT20 to HT40 diff */
- if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20) {
- HT20_pwrdiff = pHalData->TxPwrHt20Diff[i][Channel-1];
- powerlevel[i] += HT20_pwrdiff;
- }
- mcs = powerlevel[i];
- mcs = mcs << 24 | mcs << 16 | mcs << 8 | mcs;
- *(MCSBase + i) = mcs;
- }
-}
-
-static void
-getTxPowerWriteValByRegulatory(struct rtw_adapter *Adapter, u8 Channel,
- u8 index, u32 *powerBase0, u32 *powerBase1,
- u32 *pOutWriteVal)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
- u8 i, chnlGroup = 0, pwr_diff_limit[4];
- u32 writeVal, customer_limit, rf;
-
- /* Index 0 & 1 = legacy OFDM, 2-5 = HT_MCS rate */
- for (rf = 0; rf < 2; rf++) {
- switch (pHalData->EEPROMRegulatory) {
- case 0: /* Realtek better performance */
- /* increase power diff defined by Realtek for
- * large power */
- chnlGroup = 0;
- writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] +
- ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
- break;
- case 1: /* Realtek regulatory */
- /* increase power diff defined by Realtek for
- * regulatory */
- if (pHalData->pwrGroupCnt == 1)
- chnlGroup = 0;
- if (pHalData->pwrGroupCnt >= 3) {
- if (Channel <= 3)
- chnlGroup = 0;
- else if (Channel >= 4 && Channel <= 9)
- chnlGroup = 1;
- else if (Channel > 9)
- chnlGroup = 2;
-
- if (pHalData->CurrentChannelBW ==
- HT_CHANNEL_WIDTH_20)
- chnlGroup++;
- else
- chnlGroup += 4;
- }
- writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] +
- ((index < 2) ? powerBase0[rf] :
- powerBase1[rf]);
- break;
- case 2: /* Better regulatory */
- /* don't increase any power diff */
- writeVal = (index < 2) ? powerBase0[rf] :
- powerBase1[rf];
- break;
- case 3: /* Customer defined power diff. */
- chnlGroup = 0;
-
- for (i = 0; i < 4; i++) {
- pwr_diff_limit[i] = (u8)((pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index +
- (rf ? 8 : 0)]&(0x7f << (i*8))) >> (i*8));
- if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_40) {
- if (pwr_diff_limit[i] > pHalData->PwrGroupHT40[rf][Channel-1])
- pwr_diff_limit[i] = pHalData->PwrGroupHT40[rf][Channel-1];
- } else {
- if (pwr_diff_limit[i] > pHalData->PwrGroupHT20[rf][Channel-1])
- pwr_diff_limit[i] = pHalData->PwrGroupHT20[rf][Channel-1];
- }
- }
- customer_limit = (pwr_diff_limit[3]<<24) | (pwr_diff_limit[2]<<16) |
- (pwr_diff_limit[1]<<8) | (pwr_diff_limit[0]);
- writeVal = customer_limit + ((index<2)?powerBase0[rf]:powerBase1[rf]);
- break;
- default:
- chnlGroup = 0;
- writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] +
- ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
- break;
- }
-
-/* 20100427 Joseph: Driver dynamic Tx power shall not affect Tx power.
- It shall be determined by power training mechanism. */
-/* Currently, we cannot fully disable driver dynamic tx power mechanism
- because it is referenced by BT coexist mechanism. */
-/* In the future, two mechanism shall be separated from each other and
- maintained independently. Thanks for Lanhsin's reminder. */
-
- if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1)
- writeVal = 0x14141414;
- else if (pdmpriv->DynamicTxHighPowerLvl ==
- TxHighPwrLevel_Level2)
- writeVal = 0x00000000;
-
- /* 20100628 Joseph: High power mode for BT-Coexist mechanism. */
- /* This mechanism is only applied when
- Driver-Highpower-Mechanism is OFF. */
- if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT1)
- writeVal = writeVal - 0x06060606;
- else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT2)
- writeVal = writeVal;
- *(pOutWriteVal + rf) = writeVal;
- }
-}
-
-static void writeOFDMPowerReg(struct rtw_adapter *Adapter, u8 index,
- u32 *pValue)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- u16 RegOffset_A[6] = {
- rTxAGC_A_Rate18_06, rTxAGC_A_Rate54_24,
- rTxAGC_A_Mcs03_Mcs00, rTxAGC_A_Mcs07_Mcs04,
- rTxAGC_A_Mcs11_Mcs08, rTxAGC_A_Mcs15_Mcs12
- };
- u16 RegOffset_B[6] = {
- rTxAGC_B_Rate18_06, rTxAGC_B_Rate54_24,
- rTxAGC_B_Mcs03_Mcs00, rTxAGC_B_Mcs07_Mcs04,
- rTxAGC_B_Mcs11_Mcs08, rTxAGC_B_Mcs15_Mcs12
- };
- u8 i, rf, pwr_val[4];
- u32 writeVal;
- u16 RegOffset;
-
- for (rf = 0; rf < 2; rf++) {
- writeVal = pValue[rf];
- for (i = 0; i < 4; i++) {
- pwr_val[i] = (u8)((writeVal &
- (0x7f << (i * 8))) >> (i * 8));
- if (pwr_val[i] > RF6052_MAX_TX_PWR)
- pwr_val[i] = RF6052_MAX_TX_PWR;
- }
- writeVal = pwr_val[3] << 24 | pwr_val[2] << 16 |
- pwr_val[1] << 8 | pwr_val[0];
-
- if (rf == 0)
- RegOffset = RegOffset_A[index];
- else
- RegOffset = RegOffset_B[index];
-
- rtl8723au_write32(Adapter, RegOffset, writeVal);
-
- /* 201005115 Joseph: Set Tx Power diff for Tx power
- training mechanism. */
- if (((pHalData->rf_type == RF_2T2R) &&
- (RegOffset == rTxAGC_A_Mcs15_Mcs12 ||
- RegOffset == rTxAGC_B_Mcs15_Mcs12)) ||
- ((pHalData->rf_type != RF_2T2R) &&
- (RegOffset == rTxAGC_A_Mcs07_Mcs04 ||
- RegOffset == rTxAGC_B_Mcs07_Mcs04))) {
- writeVal = pwr_val[3];
- if (RegOffset == rTxAGC_A_Mcs15_Mcs12 ||
- RegOffset == rTxAGC_A_Mcs07_Mcs04)
- RegOffset = 0xc90;
- if (RegOffset == rTxAGC_B_Mcs15_Mcs12 ||
- RegOffset == rTxAGC_B_Mcs07_Mcs04)
- RegOffset = 0xc98;
- for (i = 0; i < 3; i++) {
- if (i != 2)
- writeVal = (writeVal > 8) ?
- (writeVal - 8) : 0;
- else
- writeVal = (writeVal > 6) ?
- (writeVal - 6) : 0;
- rtl8723au_write8(Adapter, RegOffset + i,
- (u8)writeVal);
- }
- }
- }
-}
-/*-----------------------------------------------------------------------------
- * Function: PHY_RF6052SetOFDMTxPower
- *
- * Overview: For legacy and HY OFDM, we must read EEPROM TX power index for
- * different channel and read original value in TX power
- * register area from 0xe00. We increase offset and
- * original value to be correct tx pwr.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Remark
- * 11/05/2008 MHC Simulate 8192 series method.
- * 01/06/2009 MHC 1. Prevent Path B tx power overflow or
- * underflow dure to A/B pwr difference or
- * legacy/HT pwr diff.
- * 2. We concern with path B legacy/HT OFDM difference.
- * 01/22/2009 MHC Support new EPRO format from SD3.
- *
- *---------------------------------------------------------------------------*/
-void rtl8723a_PHY_RF6052SetOFDMTxPower(struct rtw_adapter *Adapter,
- u8 *pPowerLevel, u8 Channel)
-{
- u32 writeVal[2], powerBase0[2], powerBase1[2];
- u8 index = 0;
-
- getPowerBase(Adapter, pPowerLevel, Channel,
- &powerBase0[0], &powerBase1[0]);
-
- for (index = 0; index < 6; index++) {
- getTxPowerWriteValByRegulatory(Adapter, Channel, index,
- &powerBase0[0], &powerBase1[0], &writeVal[0]);
-
- writeOFDMPowerReg(Adapter, index, &writeVal[0]);
- }
-}
-
-static int phy_RF6052_Config_ParaFile(struct rtw_adapter *Adapter)
-{
- u32 u4RegValue = 0;
- u8 eRFPath;
- struct bb_reg_define *pPhyReg;
- int rtStatus = _SUCCESS;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
-
- /* 3----------------------------------------------------------------- */
- /* 3 <2> Initialize RF */
- /* 3----------------------------------------------------------------- */
- for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) {
-
- pPhyReg = &pHalData->PHYRegDef[eRFPath];
-
- /*----Store original RFENV control type----*/
- switch (eRFPath) {
- case RF_PATH_A:
- u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs,
- bRFSI_RFENV);
- break;
- case RF_PATH_B:
- u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs,
- bRFSI_RFENV << 16);
- break;
- }
-
- /*----Set RF_ENV enable----*/
- PHY_SetBBReg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1);
- udelay(1);/* PlatformStallExecution(1); */
-
- /*----Set RF_ENV output high----*/
- PHY_SetBBReg(Adapter, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
- udelay(1);/* PlatformStallExecution(1); */
-
- /* Set bit number of Address and Data for RF register */
- PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength,
- 0x0); /* Set 1 to 4 bits for 8255 */
- udelay(1);/* PlatformStallExecution(1); */
-
- PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength,
- 0x0); /* Set 0 to 12 bits for 8255 */
- udelay(1);/* PlatformStallExecution(1); */
-
- /*----Initialize RF fom connfiguration file----*/
- switch (eRFPath) {
- case RF_PATH_A:
- ODM_ReadAndConfig_RadioA_1T_8723A(&pHalData->odmpriv);
- break;
- case RF_PATH_B:
- break;
- }
-
- /*----Restore RFENV control type----*/
- switch (eRFPath) {
- case RF_PATH_A:
- PHY_SetBBReg(Adapter, pPhyReg->rfintfs,
- bRFSI_RFENV, u4RegValue);
- break;
- case RF_PATH_B:
- PHY_SetBBReg(Adapter, pPhyReg->rfintfs,
- bRFSI_RFENV << 16, u4RegValue);
- break;
- }
-
- if (rtStatus != _SUCCESS) {
- goto phy_RF6052_Config_ParaFile_Fail;
- }
- }
-phy_RF6052_Config_ParaFile_Fail:
- return rtStatus;
-}
-
-int PHY_RF6052_Config8723A(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
-
- /* Initialize general global value */
- /* TODO: Extend RF_PATH_C and RF_PATH_D in the future */
- if (pHalData->rf_type == RF_1T1R)
- pHalData->NumTotalRFPath = 1;
- else
- pHalData->NumTotalRFPath = 2;
-
- /* Config BB and RF */
- return phy_RF6052_Config_ParaFile(Adapter);
-}
-
-/* End of HalRf6052.c */
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_rxdesc.c b/drivers/staging/rtl8723au/hal/rtl8723a_rxdesc.c
deleted file mode 100644
index 81b5efe649fa..000000000000
--- a/drivers/staging/rtl8723au/hal/rtl8723a_rxdesc.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTL8723A_REDESC_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <rtl8723a_hal.h>
-
-static void process_rssi(struct rtw_adapter *padapter,
- struct recv_frame *prframe)
-{
- struct rx_pkt_attrib *pattrib = &prframe->attrib;
- struct signal_stat *signal_stat = &padapter->recvpriv.signal_strength_data;
-
- if (signal_stat->update_req) {
- signal_stat->total_num = 0;
- signal_stat->total_val = 0;
- signal_stat->update_req = 0;
- }
-
- signal_stat->total_num++;
- signal_stat->total_val += pattrib->phy_info.SignalStrength;
- signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
-}
-
-static void process_link_qual(struct rtw_adapter *padapter,
- struct recv_frame *prframe)
-{
- struct rx_pkt_attrib *pattrib;
- struct signal_stat *signal_stat;
-
- if (prframe == NULL || padapter == NULL)
- return;
-
- pattrib = &prframe->attrib;
- signal_stat = &padapter->recvpriv.signal_qual_data;
-
- if (signal_stat->update_req) {
- signal_stat->total_num = 0;
- signal_stat->total_val = 0;
- signal_stat->update_req = 0;
- }
-
- signal_stat->total_num++;
- signal_stat->total_val += pattrib->phy_info.SignalQuality;
- signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
-}
-
-/* void rtl8723a_process_phy_info(struct rtw_adapter *padapter, union recv_frame *prframe) */
-void rtl8723a_process_phy_info(struct rtw_adapter *padapter, void *prframe)
-{
- struct recv_frame *precvframe = prframe;
- /* Check RSSI */
- process_rssi(padapter, precvframe);
- /* Check EVM */
- process_link_qual(padapter, precvframe);
-}
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_sreset.c b/drivers/staging/rtl8723au/hal/rtl8723a_sreset.c
deleted file mode 100644
index 3c46294b8788..000000000000
--- a/drivers/staging/rtl8723au/hal/rtl8723a_sreset.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTL8723A_SRESET_C_
-
-#include <rtl8723a_sreset.h>
-#include <rtl8723a_hal.h>
-#include <usb_ops_linux.h>
-
-void rtl8723a_sreset_xmit_status_check(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
- unsigned long current_time;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- unsigned int diff_time;
- u32 txdma_status;
-
- txdma_status = rtl8723au_read32(padapter, REG_TXDMA_STATUS);
- if (txdma_status != 0) {
- DBG_8723A("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status);
- rtw_sreset_reset(padapter);
- }
-
- current_time = jiffies;
-
- if (0 == pxmitpriv->free_xmitbuf_cnt || 0 == pxmitpriv->free_xmit_extbuf_cnt) {
-
- diff_time = jiffies_to_msecs(jiffies - psrtpriv->last_tx_time);
-
- if (diff_time > 2000) {
- if (psrtpriv->last_tx_complete_time == 0) {
- psrtpriv->last_tx_complete_time = current_time;
- } else {
- diff_time = jiffies_to_msecs(jiffies - psrtpriv->last_tx_complete_time);
- if (diff_time > 4000) {
- DBG_8723A("%s tx hang\n", __func__);
- rtw_sreset_reset(padapter);
- }
- }
- }
- }
-}
diff --git a/drivers/staging/rtl8723au/hal/rtl8723au_recv.c b/drivers/staging/rtl8723au/hal/rtl8723au_recv.c
deleted file mode 100644
index 0fec84bcb5d9..000000000000
--- a/drivers/staging/rtl8723au/hal/rtl8723au_recv.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTL8192CU_RECV_C_
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <recv_osdep.h>
-#include <mlme_osdep.h>
-#include <linux/ip.h>
-#include <linux/if_ether.h>
-#include <usb_ops.h>
-#include <wifi.h>
-#include <rtl8723a_hal.h>
-
-int rtl8723au_init_recv_priv(struct rtw_adapter *padapter)
-{
- struct recv_priv *precvpriv = &padapter->recvpriv;
- int i, size, res = _SUCCESS;
- struct recv_buf *precvbuf;
- unsigned long tmpaddr;
- unsigned long alignment;
- struct sk_buff *pskb;
-
- tasklet_init(&precvpriv->recv_tasklet,
- (void(*)(unsigned long))rtl8723au_recv_tasklet,
- (unsigned long)padapter);
-
- precvpriv->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!precvpriv->int_in_urb)
- DBG_8723A("alloc_urb for interrupt in endpoint fail !!!!\n");
- precvpriv->int_in_buf = kzalloc(USB_INTR_CONTENT_LENGTH, GFP_KERNEL);
- if (!precvpriv->int_in_buf)
- DBG_8723A("alloc_mem for interrupt in endpoint fail !!!!\n");
-
- size = NR_RECVBUFF * sizeof(struct recv_buf);
- precvpriv->precv_buf = kzalloc(size, GFP_KERNEL);
- if (!precvpriv->precv_buf) {
- res = _FAIL;
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "alloc recv_buf fail!\n");
- goto exit;
- }
-
- precvbuf = (struct recv_buf *)precvpriv->precv_buf;
-
- for (i = 0; i < NR_RECVBUFF; i++) {
- INIT_LIST_HEAD(&precvbuf->list);
-
- precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL);
- if (!precvbuf->purb)
- break;
-
- precvbuf->adapter = padapter;
-
- precvbuf++;
- }
-
- skb_queue_head_init(&precvpriv->rx_skb_queue);
- skb_queue_head_init(&precvpriv->free_recv_skb_queue);
-
- for (i = 0; i < NR_PREALLOC_RECV_SKB; i++) {
- size = MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ;
- pskb = __netdev_alloc_skb(padapter->pnetdev, size, GFP_KERNEL);
-
- if (pskb) {
- pskb->dev = padapter->pnetdev;
-
- tmpaddr = (unsigned long)pskb->data;
- alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
- skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment));
-
- skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
- }
-
- pskb = NULL;
- }
-
-exit:
- return res;
-}
-
-void rtl8723au_free_recv_priv(struct rtw_adapter *padapter)
-{
- int i;
- struct recv_buf *precvbuf;
- struct recv_priv *precvpriv = &padapter->recvpriv;
-
- precvbuf = (struct recv_buf *)precvpriv->precv_buf;
-
- for (i = 0; i < NR_RECVBUFF; i++) {
- usb_free_urb(precvbuf->purb);
-
- if (precvbuf->pskb)
- dev_kfree_skb_any(precvbuf->pskb);
-
- precvbuf++;
- }
-
- kfree(precvpriv->precv_buf);
-
- usb_free_urb(precvpriv->int_in_urb);
- kfree(precvpriv->int_in_buf);
-
- if (skb_queue_len(&precvpriv->rx_skb_queue))
- DBG_8723A(KERN_WARNING "rx_skb_queue not empty\n");
-
- skb_queue_purge(&precvpriv->rx_skb_queue);
-
- if (skb_queue_len(&precvpriv->free_recv_skb_queue)) {
- DBG_8723A(KERN_WARNING "free_recv_skb_queue not empty, %d\n",
- skb_queue_len(&precvpriv->free_recv_skb_queue));
- }
-
- skb_queue_purge(&precvpriv->free_recv_skb_queue);
-}
-
-struct recv_stat_cpu {
- u32 rxdw0;
- u32 rxdw1;
- u32 rxdw2;
- u32 rxdw3;
- u32 rxdw4;
- u32 rxdw5;
-};
-
-void update_recvframe_attrib(struct recv_frame *precvframe,
- struct recv_stat *prxstat)
-{
- struct rx_pkt_attrib *pattrib;
- struct recv_stat_cpu report;
- struct rxreport_8723a *prxreport;
-
- report.rxdw0 = le32_to_cpu(prxstat->rxdw0);
- report.rxdw1 = le32_to_cpu(prxstat->rxdw1);
- report.rxdw2 = le32_to_cpu(prxstat->rxdw2);
- report.rxdw3 = le32_to_cpu(prxstat->rxdw3);
- report.rxdw4 = le32_to_cpu(prxstat->rxdw4);
- report.rxdw5 = le32_to_cpu(prxstat->rxdw5);
-
- prxreport = (struct rxreport_8723a *)&report;
-
- pattrib = &precvframe->attrib;
- memset(pattrib, 0, sizeof(struct rx_pkt_attrib));
-
- /* update rx report to recv_frame attribute */
- pattrib->pkt_len = (u16)prxreport->pktlen;
- pattrib->drvinfo_sz = (u8)(prxreport->drvinfosize << 3);
- pattrib->physt = (u8)prxreport->physt;
-
- pattrib->crc_err = (u8)prxreport->crc32;
- pattrib->icv_err = (u8)prxreport->icverr;
-
- pattrib->bdecrypted = (u8)(prxreport->swdec ? 0 : 1);
- pattrib->encrypt = (u8)prxreport->security;
-
- pattrib->qos = (u8)prxreport->qos;
- pattrib->priority = (u8)prxreport->tid;
-
- pattrib->amsdu = (u8)prxreport->amsdu;
-
- pattrib->seq_num = (u16)prxreport->seq;
- pattrib->frag_num = (u8)prxreport->frag;
- pattrib->mfrag = (u8)prxreport->mf;
- pattrib->mdata = (u8)prxreport->md;
-
- pattrib->mcs_rate = (u8)prxreport->rxmcs;
- pattrib->rxht = (u8)prxreport->rxht;
-}
-
-void update_recvframe_phyinfo(struct recv_frame *precvframe,
- struct phy_stat *pphy_status)
-{
- struct rtw_adapter *padapter = precvframe->adapter;
- struct rx_pkt_attrib *pattrib = &precvframe->attrib;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct phy_info *pPHYInfo = &pattrib->phy_info;
- struct odm_packet_info pkt_info;
- u8 *sa = NULL, *da;
- struct sta_priv *pstapriv;
- struct sta_info *psta;
- struct sk_buff *skb = precvframe->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- bool matchbssid = false;
- u8 *bssid;
-
- matchbssid = !ieee80211_is_ctl(hdr->frame_control) &&
- !pattrib->icv_err && !pattrib->crc_err;
-
- if (matchbssid) {
- switch (hdr->frame_control &
- cpu_to_le16(IEEE80211_FCTL_TODS |
- IEEE80211_FCTL_FROMDS)) {
- case cpu_to_le16(IEEE80211_FCTL_TODS):
- bssid = hdr->addr1;
- break;
- case cpu_to_le16(IEEE80211_FCTL_FROMDS):
- bssid = hdr->addr2;
- break;
- case cpu_to_le16(0):
- bssid = hdr->addr3;
- break;
- default:
- bssid = NULL;
- matchbssid = false;
- }
-
- if (bssid)
- matchbssid = ether_addr_equal(
- get_bssid(&padapter->mlmepriv), bssid);
- }
-
- pkt_info.bPacketMatchBSSID = matchbssid;
-
- da = ieee80211_get_DA(hdr);
- pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID &&
- (!memcmp(da, myid(&padapter->eeprompriv), ETH_ALEN));
-
- pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID &&
- ieee80211_is_beacon(hdr->frame_control);
-
- pkt_info.StationID = 0xFF;
- if (pkt_info.bPacketBeacon) {
- if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == true)
- sa = padapter->mlmepriv.cur_network.network.MacAddress;
- /* to do Ad-hoc */
- } else {
- sa = ieee80211_get_SA(hdr);
- }
-
- pstapriv = &padapter->stapriv;
- psta = rtw_get_stainfo23a(pstapriv, sa);
- if (psta) {
- pkt_info.StationID = psta->mac_id;
- /* printk("%s ==> StationID(%d)\n", __func__, pkt_info.StationID); */
- }
- pkt_info.Rate = pattrib->mcs_rate;
-
- ODM_PhyStatusQuery23a(&pHalData->odmpriv, pPHYInfo,
- (u8 *)pphy_status, &pkt_info);
- precvframe->psta = NULL;
- if (pkt_info.bPacketMatchBSSID &&
- (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true)) {
- if (psta) {
- precvframe->psta = psta;
- rtl8723a_process_phy_info(padapter, precvframe);
- }
- } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) {
- if (check_fwstate(&padapter->mlmepriv,
- WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) ==
- true) {
- if (psta)
- precvframe->psta = psta;
- }
- rtl8723a_process_phy_info(padapter, precvframe);
- }
-}
diff --git a/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c b/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c
deleted file mode 100644
index 14746dd8db78..000000000000
--- a/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RTL8192C_XMIT_C_
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <wifi.h>
-#include <osdep_intf.h>
-#include <usb_ops.h>
-/* include <rtl8192c_hal.h> */
-#include <rtl8723a_hal.h>
-
-static int urb_zero_packet_chk(struct rtw_adapter *padapter, int sz)
-{
- int blnSetTxDescOffset;
- struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
-
- if (pdvobj->ishighspeed) {
- if (((sz + TXDESC_SIZE) % 512) == 0)
- blnSetTxDescOffset = 1;
- else
- blnSetTxDescOffset = 0;
- } else {
- if (((sz + TXDESC_SIZE) % 64) == 0)
- blnSetTxDescOffset = 1;
- else
- blnSetTxDescOffset = 0;
- }
- return blnSetTxDescOffset;
-}
-
-static void rtl8192cu_cal_txdesc_chksum(struct tx_desc *ptxdesc)
-{
- __le16 *usPtr = (__le16 *)ptxdesc;
- u32 count = 16; /* (32 bytes / 2 bytes per XOR) => 16 times */
- u32 index;
- u16 checksum = 0;
-
- /* Clear first */
- ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
-
- for (index = 0 ; index < count ; index++)
- checksum = checksum ^ le16_to_cpu(*(usPtr + index));
-
- ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff&checksum);
-}
-
-static void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc)
-{
- if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
- switch (pattrib->encrypt) {
- /* SEC_TYPE */
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- /* ptxdesc->txdw1 |= cpu_to_le32((0x02<<22)&0x00c00000); */
- ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- ptxdesc->txdw1 |= cpu_to_le32((0x03<<22)&0x00c00000);
- break;
- case 0:
- default:
- break;
- }
- }
-}
-
-static void fill_txdesc_vcs(struct pkt_attrib *pattrib, __le32 *pdw)
-{
- /* DBG_8723A("cvs_mode =%d\n", pattrib->vcs_mode); */
-
- switch (pattrib->vcs_mode) {
- case RTS_CTS:
- *pdw |= cpu_to_le32(BIT(12));
- break;
- case CTS_TO_SELF:
- *pdw |= cpu_to_le32(BIT(11));
- break;
- case NONE_VCS:
- default:
- break;
- }
-
- if (pattrib->vcs_mode) {
- *pdw |= cpu_to_le32(BIT(13));
-
- /* Set RTS BW */
- if (pattrib->ht_en) {
- *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(27)) : 0;
-
- if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
- *pdw |= cpu_to_le32((0x01<<28)&0x30000000);
- else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
- *pdw |= cpu_to_le32((0x02<<28)&0x30000000);
- else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
- *pdw |= 0;
- else
- *pdw |= cpu_to_le32((0x03<<28)&0x30000000);
- }
- }
-}
-
-static void fill_txdesc_phy(struct pkt_attrib *pattrib, __le32 *pdw)
-{
- if (pattrib->ht_en) {
- *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(25)) : 0;
-
- if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
- *pdw |= cpu_to_le32((0x01<<20)&0x003f0000);
- else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
- *pdw |= cpu_to_le32((0x02<<20)&0x003f0000);
- else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
- *pdw |= 0;
- else
- *pdw |= cpu_to_le32((0x03<<20)&0x003f0000);
- }
-}
-
-static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz)
-{
- int pull = 0;
- uint qsel;
- struct rtw_adapter *padapter = pxmitframe->padapter;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
- struct tx_desc *ptxdesc = (struct tx_desc *)pmem;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- int bmcst = is_multicast_ether_addr(pattrib->ra);
-
- if (urb_zero_packet_chk(padapter, sz) == 0) {
- ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ);
- pull = 1;
- pxmitframe->pkt_offset--;
- }
-
- memset(ptxdesc, 0, sizeof(struct tx_desc));
-
- if (pxmitframe->frame_tag == DATA_FRAMETAG) {
- /* offset 4 */
- ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f);
-
- qsel = (uint)(pattrib->qsel & 0x0000001f);
- ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
-
- ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<<16) & 0x000f0000);
-
- fill_txdesc_sectype(pattrib, ptxdesc);
-
- if (pattrib->ampdu_en)
- ptxdesc->txdw1 |= cpu_to_le32(BIT(5));/* AGG EN */
- else
- ptxdesc->txdw1 |= cpu_to_le32(BIT(6));/* AGG BK */
-
- /* offset 8 */
-
- /* offset 12 */
- ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
-
- /* offset 16 , offset 20 */
- if (pattrib->qos_en)
- ptxdesc->txdw4 |= cpu_to_le32(BIT(6));/* QoS */
-
- if ((pattrib->ether_type != 0x888e) &&
- (pattrib->ether_type != 0x0806) &&
- (pattrib->dhcp_pkt != 1)) {
- /* Non EAP & ARP & DHCP type data packet */
-
- fill_txdesc_vcs(pattrib, &ptxdesc->txdw4);
- fill_txdesc_phy(pattrib, &ptxdesc->txdw4);
-
- ptxdesc->txdw4 |= cpu_to_le32(0x00000008);/* RTS Rate = 24M */
- ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);/* */
-
- /* use REG_INIDATA_RATE_SEL value */
- ptxdesc->txdw5 |= cpu_to_le32(pdmpriv->INIDATA_RATE[pattrib->mac_id]);
- } else {
- /* EAP data packet and ARP packet. */
- /* Use the 1M data rate to send the EAP/ARP packet. */
- /* This will maybe make the handshake smooth. */
-
- ptxdesc->txdw1 |= cpu_to_le32(BIT(6));/* AGG BK */
-
- ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */
-
- if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
- ptxdesc->txdw4 |= cpu_to_le32(BIT(24));/* DATA_SHORT */
-
- ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate23a(pmlmeext->tx_rate));
- }
- } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) {
- /* offset 4 */
- ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f);
-
- qsel = (uint)(pattrib->qsel&0x0000001f);
- ptxdesc->txdw1 |= cpu_to_le32((qsel<<QSEL_SHT)&0x00001f00);
-
- ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<<16) & 0x000f0000);
-
- /* offset 8 */
- /* CCX-TXRPT ack for xmit mgmt frames. */
- if (pxmitframe->ack_report)
- ptxdesc->txdw2 |= cpu_to_le32(BIT(19));
-
- /* offset 12 */
- ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
-
- /* offset 16 */
- ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */
-
- /* offset 20 */
- ptxdesc->txdw5 |= cpu_to_le32(BIT(17));/* retry limit enable */
- ptxdesc->txdw5 |= cpu_to_le32(0x00180000);/* retry limit = 6 */
-
- ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate23a(pmlmeext->tx_rate));
- } else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) {
- DBG_8723A("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
- } else {
- DBG_8723A("pxmitframe->frame_tag = %d\n",
- pxmitframe->frame_tag);
-
- /* offset 4 */
- ptxdesc->txdw1 |= cpu_to_le32((4)&0x1f);/* CAM_ID(MAC_ID) */
-
- ptxdesc->txdw1 |= cpu_to_le32((6<<16) & 0x000f0000);/* raid */
-
- /* offset 8 */
-
- /* offset 12 */
- ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
-
- /* offset 16 */
- ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */
-
- /* offset 20 */
- ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate23a(pmlmeext->tx_rate));
- }
-
- /* (1) The sequence number of each non-Qos frame / broadcast / multicast / */
- /* mgnt frame should be controlled by Hw because Fw will also send null data */
- /* which we cannot control when Fw LPS enable. */
- /* --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */
- /* (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */
- /* (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. */
- if (!pattrib->qos_en) {
- /* Hw set sequence number */
- ptxdesc->txdw4 |= cpu_to_le32(BIT(7));
- /* set bit3 to 1. */
- ptxdesc->txdw3 |= cpu_to_le32((8 << 28));
- }
-
- /* offset 0 */
- ptxdesc->txdw0 |= cpu_to_le32(sz&0x0000ffff);
- ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
- ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);/* 32 bytes for TX Desc */
-
- if (bmcst)
- ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
-
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "offset0-txdesc = 0x%x\n", ptxdesc->txdw0);
-
- /* offset 4 */
- /* pkt_offset, unit:8 bytes padding */
- if (pxmitframe->pkt_offset > 0)
- ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000);
-
- rtl8192cu_cal_txdesc_chksum(ptxdesc);
- return pull;
-}
-
-static int rtw_dump_xframe(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe)
-{
- int ret = _SUCCESS;
- int inner_ret = _SUCCESS;
- int t, sz, w_sz, pull = 0;
- u8 *mem_addr;
- u32 ff_hwaddr;
- struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- if (pxmitframe->frame_tag == DATA_FRAMETAG &&
- pxmitframe->attrib.ether_type != ETH_P_ARP &&
- pxmitframe->attrib.ether_type != ETH_P_PAE &&
- pxmitframe->attrib.dhcp_pkt != 1)
- rtw_issue_addbareq_cmd23a(padapter, pxmitframe);
-
- mem_addr = pxmitframe->buf_addr;
-
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, "rtw_dump_xframe()\n");
-
- for (t = 0; t < pattrib->nr_frags; t++) {
- if (inner_ret != _SUCCESS && ret == _SUCCESS)
- ret = _FAIL;
-
- if (t != (pattrib->nr_frags - 1)) {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
- "pattrib->nr_frags =%d\n", pattrib->nr_frags);
-
- sz = pxmitpriv->frag_len;
- sz = sz - 4 - pattrib->icv_len;
- } else {
- /* no frag */
- sz = pattrib->last_txcmdsz;
- }
-
- pull = update_txdesc(pxmitframe, mem_addr, sz);
-
- if (pull) {
- mem_addr += PACKET_OFFSET_SZ; /* pull txdesc head */
-
- pxmitframe->buf_addr = mem_addr;
-
- w_sz = sz + TXDESC_SIZE;
- } else {
- w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
- }
-
- ff_hwaddr = rtw_get_ff_hwaddr23a(pxmitframe);
- inner_ret = rtl8723au_write_port(padapter, ff_hwaddr,
- w_sz, pxmitbuf);
- rtw_count_tx_stats23a(padapter, pxmitframe, sz);
-
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "rtw_write_port, w_sz =%d\n", w_sz);
-
- mem_addr += w_sz;
-
- mem_addr = PTR_ALIGN(mem_addr, 4);
- }
-
- rtw_free_xmitframe23a(pxmitpriv, pxmitframe);
-
- if (ret != _SUCCESS)
- rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
-
- return ret;
-}
-
-bool rtl8723au_xmitframe_complete(struct rtw_adapter *padapter,
- struct xmit_priv *pxmitpriv,
- struct xmit_buf *pxmitbuf)
-{
- struct hw_xmit *phwxmits;
- struct xmit_frame *pxmitframe;
- int hwentry;
- int res = _SUCCESS, xcnt = 0;
-
- phwxmits = pxmitpriv->hwxmits;
- hwentry = pxmitpriv->hwxmit_entry;
-
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, "xmitframe_complete()\n");
-
- if (pxmitbuf == NULL) {
- pxmitbuf = rtw_alloc_xmitbuf23a(pxmitpriv);
- if (!pxmitbuf)
- return false;
- }
- pxmitframe = rtw_dequeue_xframe23a(pxmitpriv, phwxmits, hwentry);
-
- if (pxmitframe) {
- pxmitframe->pxmitbuf = pxmitbuf;
-
- pxmitframe->buf_addr = pxmitbuf->pbuf;
-
- pxmitbuf->priv_data = pxmitframe;
-
- if (pxmitframe->frame_tag == DATA_FRAMETAG) {
- if (pxmitframe->attrib.priority <= 15)/* TID0~15 */
- res = rtw_xmitframe_coalesce23a(padapter, pxmitframe->pkt, pxmitframe);
-
- rtw_os_xmit_complete23a(padapter, pxmitframe);/* always return ndis_packet after rtw_xmitframe_coalesce23a */
- }
-
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
- "xmitframe_complete(): rtw_dump_xframe\n");
-
- if (res == _SUCCESS) {
- rtw_dump_xframe(padapter, pxmitframe);
- } else {
- rtw_free_xmitbuf23a(pxmitpriv, pxmitbuf);
- rtw_free_xmitframe23a(pxmitpriv, pxmitframe);
- }
- xcnt++;
- } else {
- rtw_free_xmitbuf23a(pxmitpriv, pxmitbuf);
- return false;
- }
- return true;
-}
-
-static int xmitframe_direct(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe)
-{
- int res;
-
- res = rtw_xmitframe_coalesce23a(padapter, pxmitframe->pkt, pxmitframe);
- if (res == _SUCCESS)
- rtw_dump_xframe(padapter, pxmitframe);
- return res;
-}
-
-/*
- * Return
- * true dump packet directly
- * false enqueue packet
- */
-bool rtl8723au_hal_xmit(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe)
-{
- int res;
- struct xmit_buf *pxmitbuf = NULL;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- pattrib->qsel = pattrib->priority;
- spin_lock_bh(&pxmitpriv->lock);
-
-#ifdef CONFIG_8723AU_AP_MODE
- if (xmitframe_enqueue_for_sleeping_sta23a(padapter, pxmitframe)) {
- struct sta_info *psta;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- spin_unlock_bh(&pxmitpriv->lock);
-
- if (pattrib->psta)
- psta = pattrib->psta;
- else
- psta = rtw_get_stainfo23a(pstapriv, pattrib->ra);
-
- if (psta) {
- if (psta->sleepq_len > (NR_XMITFRAME>>3))
- wakeup_sta_to_xmit23a(padapter, psta);
- }
-
- return false;
- }
-#endif
-
- if (rtw_txframes_sta_ac_pending23a(padapter, pattrib) > 0)
- goto enqueue;
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true)
- goto enqueue;
-
- pxmitbuf = rtw_alloc_xmitbuf23a(pxmitpriv);
- if (pxmitbuf == NULL)
- goto enqueue;
-
- spin_unlock_bh(&pxmitpriv->lock);
-
- pxmitframe->pxmitbuf = pxmitbuf;
- pxmitframe->buf_addr = pxmitbuf->pbuf;
- pxmitbuf->priv_data = pxmitframe;
-
- if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
- rtw_free_xmitbuf23a(pxmitpriv, pxmitbuf);
- rtw_free_xmitframe23a(pxmitpriv, pxmitframe);
- }
- return true;
-
-enqueue:
- res = rtw_xmitframe_enqueue23a(padapter, pxmitframe);
- spin_unlock_bh(&pxmitpriv->lock);
-
- if (res != _SUCCESS) {
- RT_TRACE(_module_xmit_osdep_c_, _drv_err_,
- "pre_xmitframe: enqueue xmitframe fail\n");
- rtw_free_xmitframe23a(pxmitpriv, pxmitframe);
-
- /* Trick, make the statistics correct */
- pxmitpriv->tx_pkts--;
- pxmitpriv->tx_drop++;
- return true;
- }
- return false;
-}
-
-int rtl8723au_mgnt_xmit(struct rtw_adapter *padapter,
- struct xmit_frame *pmgntframe)
-{
- return rtw_dump_xframe(padapter, pmgntframe);
-}
-
-int rtl8723au_hal_xmitframe_enqueue(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe)
-{
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- int err;
-
- err = rtw_xmitframe_enqueue23a(padapter, pxmitframe);
- if (err != _SUCCESS) {
- rtw_free_xmitframe23a(pxmitpriv, pxmitframe);
-
- /* Trick, make the statistics correct */
- pxmitpriv->tx_pkts--;
- pxmitpriv->tx_drop++;
- } else {
- tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
- }
- return err;
-}
diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c
deleted file mode 100644
index fa47aebf8b98..000000000000
--- a/drivers/staging/rtl8723au/hal/usb_halinit.c
+++ /dev/null
@@ -1,1269 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _HCI_HAL_INIT_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <rtw_efuse.h>
-
-#include <HalPwrSeqCmd.h>
-#include <Hal8723PwrSeq.h>
-#include <rtl8723a_hal.h>
-#include <linux/ieee80211.h>
-
-#include <usb_ops.h>
-
-static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter,
- enum rt_rf_power_state eRFPowerState);
-
-static void
-_ConfigChipOutEP(struct rtw_adapter *pAdapter, u8 NumOutPipe)
-{
- u8 value8;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
-
- pHalData->OutEpQueueSel = 0;
- pHalData->OutEpNumber = 0;
-
- /* Normal and High queue */
- value8 = rtl8723au_read8(pAdapter, (REG_NORMAL_SIE_EP + 1));
-
- if (value8 & USB_NORMAL_SIE_EP_MASK) {
- pHalData->OutEpQueueSel |= TX_SELE_HQ;
- pHalData->OutEpNumber++;
- }
-
- if ((value8 >> USB_NORMAL_SIE_EP_SHIFT) & USB_NORMAL_SIE_EP_MASK) {
- pHalData->OutEpQueueSel |= TX_SELE_NQ;
- pHalData->OutEpNumber++;
- }
-
- /* Low queue */
- value8 = rtl8723au_read8(pAdapter, (REG_NORMAL_SIE_EP + 2));
- if (value8 & USB_NORMAL_SIE_EP_MASK) {
- pHalData->OutEpQueueSel |= TX_SELE_LQ;
- pHalData->OutEpNumber++;
- }
-
- /* TODO: Error recovery for this case */
- /* RT_ASSERT((NumOutPipe == pHalData->OutEpNumber),
- ("Out EP number isn't match! %d(Descriptor) != %d (SIE reg)\n",
- (u32)NumOutPipe, (u32)pHalData->OutEpNumber)); */
-}
-
-bool rtl8723au_chip_configure(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
- u8 NumInPipe = pdvobjpriv->RtNumInPipes;
- u8 NumOutPipe = pdvobjpriv->RtNumOutPipes;
-
- _ConfigChipOutEP(padapter, NumOutPipe);
-
- /* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */
- if (pHalData->OutEpNumber == 1) {
- if (NumInPipe != 1)
- return false;
- }
-
- return Hal_MappingOutPipe23a(padapter, NumOutPipe);
-}
-
-static int _InitPowerOn(struct rtw_adapter *padapter)
-{
- u16 value16;
- u8 value8;
-
- /* RSV_CTRL 0x1C[7:0] = 0x00
- unlock ISO/CLK/Power control register */
- rtl8723au_write8(padapter, REG_RSV_CTRL, 0x0);
-
- /* HW Power on sequence */
- if (!HalPwrSeqCmdParsing23a(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
- PWR_INTF_USB_MSK, rtl8723AU_card_enable_flow))
- return _FAIL;
-
- /* 0x04[19] = 1, suggest by Jackie 2011.05.09, reset 8051 */
- value8 = rtl8723au_read8(padapter, REG_APS_FSMCO+2);
- rtl8723au_write8(padapter, REG_APS_FSMCO + 2, value8 | BIT(3));
-
- /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
- /* Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy.
- Added by tynli. 2011.08.31. */
- value16 = rtl8723au_read16(padapter, REG_CR);
- value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN |
- PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN |
- ENSEC | CALTMR_EN);
- rtl8723au_write16(padapter, REG_CR, value16);
-
- /* for Efuse PG, suggest by Jackie 2011.11.23 */
- PHY_SetBBReg(padapter, REG_EFUSE_CTRL, BIT(28)|BIT(29)|BIT(30), 0x06);
-
- return _SUCCESS;
-}
-
-/* Shall USB interface init this? */
-static void _InitInterrupt(struct rtw_adapter *Adapter)
-{
- u32 value32;
-
- /* HISR - turn all on */
- value32 = 0xFFFFFFFF;
- rtl8723au_write32(Adapter, REG_HISR, value32);
-
- /* HIMR - turn all on */
- rtl8723au_write32(Adapter, REG_HIMR, value32);
-}
-
-static void _InitQueueReservedPage(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct registry_priv *pregistrypriv = &Adapter->registrypriv;
- u32 numHQ = 0;
- u32 numLQ = 0;
- u32 numNQ = 0;
- u32 numPubQ;
- u32 value32;
- u8 value8;
- bool bWiFiConfig = pregistrypriv->wifi_spec;
-
- /* RT_ASSERT((outEPNum>= 2), ("for WMM , number of out-ep "
- "must more than or equal to 2!\n")); */
-
- numPubQ = bWiFiConfig ? WMM_NORMAL_PAGE_NUM_PUBQ : NORMAL_PAGE_NUM_PUBQ;
-
- if (pHalData->OutEpQueueSel & TX_SELE_HQ) {
- numHQ = bWiFiConfig ?
- WMM_NORMAL_PAGE_NUM_HPQ : NORMAL_PAGE_NUM_HPQ;
- }
-
- if (pHalData->OutEpQueueSel & TX_SELE_LQ) {
- numLQ = bWiFiConfig ?
- WMM_NORMAL_PAGE_NUM_LPQ : NORMAL_PAGE_NUM_LPQ;
- }
- /* NOTE: This step shall be proceed before
- writting REG_RQPN. */
- if (pHalData->OutEpQueueSel & TX_SELE_NQ) {
- numNQ = bWiFiConfig ?
- WMM_NORMAL_PAGE_NUM_NPQ : NORMAL_PAGE_NUM_NPQ;
- }
- value8 = (u8)_NPQ(numNQ);
- rtl8723au_write8(Adapter, REG_RQPN_NPQ, value8);
-
- /* TX DMA */
- value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN;
- rtl8723au_write32(Adapter, REG_RQPN, value32);
-}
-
-static void _InitTxBufferBoundary(struct rtw_adapter *Adapter)
-{
- struct registry_priv *pregistrypriv = &Adapter->registrypriv;
-
- u8 txpktbuf_bndy;
-
- if (!pregistrypriv->wifi_spec)
- txpktbuf_bndy = TX_PAGE_BOUNDARY;
- else /* for WMM */
- txpktbuf_bndy = WMM_NORMAL_TX_PAGE_BOUNDARY;
-
- rtl8723au_write8(Adapter, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
- rtl8723au_write8(Adapter, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
- rtl8723au_write8(Adapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy);
- rtl8723au_write8(Adapter, REG_TRXFF_BNDY, txpktbuf_bndy);
- rtl8723au_write8(Adapter, REG_TDECTRL+1, txpktbuf_bndy);
-}
-
-static void _InitPageBoundary(struct rtw_adapter *Adapter)
-{
- /* RX Page Boundary */
- /* srand(static_cast<unsigned int>(time(NULL))); */
- u16 rxff_bndy = 0x27FF;/* rand() % 1) ? 0x27FF : 0x23FF; */
-
- rtl8723au_write16(Adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
-
- /* TODO: ?? shall we set tx boundary? */
-}
-
-static void
-_InitNormalChipRegPriority(struct rtw_adapter *Adapter, u16 beQ, u16 bkQ,
- u16 viQ, u16 voQ, u16 mgtQ, u16 hiQ)
-{
- u16 value16 = rtl8723au_read16(Adapter, REG_TRXDMA_CTRL) & 0x7;
-
- value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) |
- _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) |
- _TXDMA_MGQ_MAP(mgtQ) | _TXDMA_HIQ_MAP(hiQ);
-
- rtl8723au_write16(Adapter, REG_TRXDMA_CTRL, value16);
-}
-
-static void _InitNormalChipOneOutEpPriority(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- u16 value = 0;
-
- switch (pHalData->OutEpQueueSel) {
- case TX_SELE_HQ:
- value = QUEUE_HIGH;
- break;
- case TX_SELE_LQ:
- value = QUEUE_LOW;
- break;
- case TX_SELE_NQ:
- value = QUEUE_NORMAL;
- break;
- default:
- /* RT_ASSERT(false, ("Shall not reach here!\n")); */
- break;
- }
-
- _InitNormalChipRegPriority(Adapter, value, value, value,
- value, value, value);
-}
-
-static void _InitNormalChipTwoOutEpPriority(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct registry_priv *pregistrypriv = &Adapter->registrypriv;
- u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
- u16 valueHi = 0;
- u16 valueLow = 0;
-
- switch (pHalData->OutEpQueueSel) {
- case (TX_SELE_HQ | TX_SELE_LQ):
- valueHi = QUEUE_HIGH;
- valueLow = QUEUE_LOW;
- break;
- case (TX_SELE_NQ | TX_SELE_LQ):
- valueHi = QUEUE_NORMAL;
- valueLow = QUEUE_LOW;
- break;
- case (TX_SELE_HQ | TX_SELE_NQ):
- valueHi = QUEUE_HIGH;
- valueLow = QUEUE_NORMAL;
- break;
- default:
- /* RT_ASSERT(false, ("Shall not reach here!\n")); */
- break;
- }
-
- if (!pregistrypriv->wifi_spec) {
- beQ = valueLow;
- bkQ = valueLow;
- viQ = valueHi;
- voQ = valueHi;
- mgtQ = valueHi;
- hiQ = valueHi;
- } else {/* for WMM , CONFIG_OUT_EP_WIFI_MODE */
- beQ = valueLow;
- bkQ = valueHi;
- viQ = valueHi;
- voQ = valueLow;
- mgtQ = valueHi;
- hiQ = valueHi;
- }
-
- _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
-}
-
-static void _InitNormalChipThreeOutEpPriority(struct rtw_adapter *Adapter)
-{
- struct registry_priv *pregistrypriv = &Adapter->registrypriv;
- u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
-
- if (!pregistrypriv->wifi_spec) {/* typical setting */
- beQ = QUEUE_LOW;
- bkQ = QUEUE_LOW;
- viQ = QUEUE_NORMAL;
- voQ = QUEUE_HIGH;
- mgtQ = QUEUE_HIGH;
- hiQ = QUEUE_HIGH;
- } else {/* for WMM */
- beQ = QUEUE_LOW;
- bkQ = QUEUE_NORMAL;
- viQ = QUEUE_NORMAL;
- voQ = QUEUE_HIGH;
- mgtQ = QUEUE_HIGH;
- hiQ = QUEUE_HIGH;
- }
- _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
-}
-
-static void _InitQueuePriority(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
-
- switch (pHalData->OutEpNumber) {
- case 1:
- _InitNormalChipOneOutEpPriority(Adapter);
- break;
- case 2:
- _InitNormalChipTwoOutEpPriority(Adapter);
- break;
- case 3:
- _InitNormalChipThreeOutEpPriority(Adapter);
- break;
- default:
- /* RT_ASSERT(false, ("Shall not reach here!\n")); */
- break;
- }
-}
-
-static void _InitTransferPageSize(struct rtw_adapter *Adapter)
-{
- /* Tx page size is always 128. */
-
- u8 value8;
- value8 = _PSRX(PBP_128) | _PSTX(PBP_128);
- rtl8723au_write8(Adapter, REG_PBP, value8);
-}
-
-static void _InitDriverInfoSize(struct rtw_adapter *Adapter, u8 drvInfoSize)
-{
- rtl8723au_write8(Adapter, REG_RX_DRVINFO_SZ, drvInfoSize);
-}
-
-static void _InitWMACSetting(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
-
- /* don't turn on AAP, it will allow all packets to driver */
- pHalData->ReceiveConfig = RCR_APM | RCR_AM | RCR_AB | RCR_CBSSID_DATA |
- RCR_CBSSID_BCN | RCR_APP_ICV | RCR_AMF |
- RCR_HTC_LOC_CTRL | RCR_APP_MIC |
- RCR_APP_PHYSTS;
-
- /* some REG_RCR will be modified later by
- phy_ConfigMACWithHeaderFile() */
- rtl8723au_write32(Adapter, REG_RCR, pHalData->ReceiveConfig);
-
- /* Accept all multicast address */
- rtl8723au_write32(Adapter, REG_MAR, 0xFFFFFFFF);
- rtl8723au_write32(Adapter, REG_MAR + 4, 0xFFFFFFFF);
-
- /* Accept all data frames */
- /* value16 = 0xFFFF; */
- /* rtl8723au_write16(Adapter, REG_RXFLTMAP2, value16); */
-
- /* 2010.09.08 hpfan */
- /* Since ADF is removed from RCR, ps-poll will not be indicate
- to driver, */
- /* RxFilterMap should mask ps-poll to guarantee AP mode can
- rx ps-poll. */
- /* value16 = 0x400; */
- /* rtl8723au_write16(Adapter, REG_RXFLTMAP1, value16); */
-
- /* Accept all management frames */
- /* value16 = 0xFFFF; */
- /* rtl8723au_write16(Adapter, REG_RXFLTMAP0, value16); */
-
- /* enable RX_SHIFT bits */
- /* rtl8723au_write8(Adapter, REG_TRXDMA_CTRL, rtl8723au_read8(Adapter,
- REG_TRXDMA_CTRL)|BIT(1)); */
-}
-
-static void _InitAdaptiveCtrl(struct rtw_adapter *Adapter)
-{
- u16 value16;
- u32 value32;
-
- /* Response Rate Set */
- value32 = rtl8723au_read32(Adapter, REG_RRSR);
- value32 &= ~RATE_BITMAP_ALL;
- value32 |= RATE_RRSR_CCK_ONLY_1M;
- rtl8723au_write32(Adapter, REG_RRSR, value32);
-
- /* CF-END Threshold */
- /* m_spIoBase->rtl8723au_write8(REG_CFEND_TH, 0x1); */
-
- /* SIFS (used in NAV) */
- value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
- rtl8723au_write16(Adapter, REG_SPEC_SIFS, value16);
-
- /* Retry Limit */
- value16 = _LRL(0x30) | _SRL(0x30);
- rtl8723au_write16(Adapter, REG_RL, value16);
-}
-
-static void _InitRateFallback(struct rtw_adapter *Adapter)
-{
- /* Set Data Auto Rate Fallback Retry Count register. */
- rtl8723au_write32(Adapter, REG_DARFRC, 0x00000000);
- rtl8723au_write32(Adapter, REG_DARFRC+4, 0x10080404);
- rtl8723au_write32(Adapter, REG_RARFRC, 0x04030201);
- rtl8723au_write32(Adapter, REG_RARFRC+4, 0x08070605);
-}
-
-static void _InitEDCA(struct rtw_adapter *Adapter)
-{
- /* Set Spec SIFS (used in NAV) */
- rtl8723au_write16(Adapter, REG_SPEC_SIFS, 0x100a);
- rtl8723au_write16(Adapter, REG_MAC_SPEC_SIFS, 0x100a);
-
- /* Set SIFS for CCK */
- rtl8723au_write16(Adapter, REG_SIFS_CTX, 0x100a);
-
- /* Set SIFS for OFDM */
- rtl8723au_write16(Adapter, REG_SIFS_TRX, 0x100a);
-
- /* TXOP */
- rtl8723au_write32(Adapter, REG_EDCA_BE_PARAM, 0x005EA42B);
- rtl8723au_write32(Adapter, REG_EDCA_BK_PARAM, 0x0000A44F);
- rtl8723au_write32(Adapter, REG_EDCA_VI_PARAM, 0x005EA324);
- rtl8723au_write32(Adapter, REG_EDCA_VO_PARAM, 0x002FA226);
-}
-
-static void _InitRDGSetting(struct rtw_adapter *Adapter)
-{
- rtl8723au_write8(Adapter, REG_RD_CTRL, 0xFF);
- rtl8723au_write16(Adapter, REG_RD_NAV_NXT, 0x200);
- rtl8723au_write8(Adapter, REG_RD_RESP_PKT_TH, 0x05);
-}
-
-static void _InitRetryFunction(struct rtw_adapter *Adapter)
-{
- u8 value8;
-
- value8 = rtl8723au_read8(Adapter, REG_FWHW_TXQ_CTRL);
- value8 |= EN_AMPDU_RTY_NEW;
- rtl8723au_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
-
- /* Set ACK timeout */
- rtl8723au_write8(Adapter, REG_ACKTO, 0x40);
-}
-
-static void _InitRFType(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
-
- pHalData->rf_type = RF_1T1R;
-}
-
-/* Set CCK and OFDM Block "ON" */
-static void _BBTurnOnBlock(struct rtw_adapter *Adapter)
-{
- PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bCCKEn, 0x1);
- PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bOFDMEn, 0x1);
-}
-
-#define MgntActSet_RF_State(...)
-static void _RfPowerSave(struct rtw_adapter *padapter)
-{
-}
-
-enum {
- Antenna_Lfet = 1,
- Antenna_Right = 2,
-};
-
-enum rt_rf_power_state RfOnOffDetect23a(struct rtw_adapter *pAdapter)
-{
- /* struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); */
- u8 val8;
- enum rt_rf_power_state rfpowerstate = rf_off;
-
- rtl8723au_write8(pAdapter, REG_MAC_PINMUX_CFG,
- rtl8723au_read8(pAdapter,
- REG_MAC_PINMUX_CFG) & ~BIT(3));
- val8 = rtl8723au_read8(pAdapter, REG_GPIO_IO_SEL);
- DBG_8723A("GPIO_IN =%02x\n", val8);
- rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off;
-
- return rfpowerstate;
-}
-
-int rtl8723au_hal_init(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
- struct registry_priv *pregistrypriv = &Adapter->registrypriv;
- u8 val8 = 0;
- u32 boundary;
- int status = _SUCCESS;
- bool mac_on;
-
- unsigned long init_start_time = jiffies;
-
- Adapter->hw_init_completed = false;
-
- if (Adapter->pwrctrlpriv.bkeepfwalive) {
- phy_SsPwrSwitch92CU(Adapter, rf_on);
-
- if (pHalData->bIQKInitialized) {
- rtl8723a_phy_iq_calibrate(Adapter, true);
- } else {
- rtl8723a_phy_iq_calibrate(Adapter, false);
- pHalData->bIQKInitialized = true;
- }
- rtl8723a_odm_check_tx_power_tracking(Adapter);
- rtl8723a_phy_lc_calibrate(Adapter);
-
- goto exit;
- }
-
- /* Check if MAC has already power on. by tynli. 2011.05.27. */
- val8 = rtl8723au_read8(Adapter, REG_CR);
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "%s: REG_CR 0x100 = 0x%02x\n", __func__, val8);
- /* Fix 92DU-VC S3 hang with the reason is that secondary mac is not
- initialized. */
- /* 0x100 value of first mac is 0xEA while 0x100 value of secondary
- is 0x00 */
- if (val8 == 0xEA) {
- mac_on = false;
- } else {
- mac_on = true;
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "%s: MAC has already power on\n", __func__);
- }
-
- status = _InitPowerOn(Adapter);
- if (status == _FAIL) {
- RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
- "Failed to init power on!\n");
- goto exit;
- }
-
- if (!pregistrypriv->wifi_spec) {
- boundary = TX_PAGE_BOUNDARY;
- } else {
- /* for WMM */
- boundary = WMM_NORMAL_TX_PAGE_BOUNDARY;
- }
-
- if (!mac_on) {
- status = InitLLTTable23a(Adapter, boundary);
- if (status == _FAIL) {
- RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
- "Failed to init LLT table\n");
- goto exit;
- }
- }
-
- if (pHalData->bRDGEnable)
- _InitRDGSetting(Adapter);
-
- status = rtl8723a_FirmwareDownload(Adapter);
- if (status != _SUCCESS) {
- Adapter->bFWReady = false;
- DBG_8723A("fw download fail!\n");
- goto exit;
- } else {
- Adapter->bFWReady = true;
- DBG_8723A("fw download ok!\n");
- }
-
- rtl8723a_InitializeFirmwareVars(Adapter);
-
- if (pwrctrlpriv->reg_rfoff == true) {
- pwrctrlpriv->rf_pwrstate = rf_off;
- }
-
- /* 2010/08/09 MH We need to check if we need to turnon or off RF after detecting */
- /* HW GPIO pin. Before PHY_RFConfig8192C. */
- /* HalDetectPwrDownMode(Adapter); */
- /* 2010/08/26 MH If Efuse does not support sective suspend then disable the function. */
- /* HalDetectSelectiveSuspendMode(Adapter); */
-
- /* Set RF type for BB/RF configuration */
- _InitRFType(Adapter);/* _ReadRFType() */
-
- /* Save target channel */
- /* <Roger_Notes> Current Channel will be updated again later. */
- pHalData->CurrentChannel = 6;/* default set to 6 */
-
- status = PHY_MACConfig8723A(Adapter);
- if (status == _FAIL) {
- DBG_8723A("PHY_MACConfig8723A fault !!\n");
- goto exit;
- }
-
- /* */
- /* d. Initialize BB related configurations. */
- /* */
- status = PHY_BBConfig8723A(Adapter);
- if (status == _FAIL) {
- DBG_8723A("PHY_BBConfig8723A fault !!\n");
- goto exit;
- }
-
- /* Add for tx power by rate fine tune. We need to call the function after BB config. */
- /* Because the tx power by rate table is inited in BB config. */
-
- status = PHY_RF6052_Config8723A(Adapter);
- if (status == _FAIL) {
- DBG_8723A("PHY_RF6052_Config8723A failed!!\n");
- goto exit;
- }
-
- /* reducing 80M spur */
- rtl8723au_write32(Adapter, REG_AFE_XTAL_CTRL, 0x0381808d);
- rtl8723au_write32(Adapter, REG_AFE_PLL_CTRL, 0xf0ffff83);
- rtl8723au_write32(Adapter, REG_AFE_PLL_CTRL, 0xf0ffff82);
- rtl8723au_write32(Adapter, REG_AFE_PLL_CTRL, 0xf0ffff83);
-
- /* RFSW Control */
- /* 0x804[14]= 0 */
- rtl8723au_write32(Adapter, rFPGA0_TxInfo, 0x00000003);
- /* 0x870[6:5]= b'11 */
- rtl8723au_write32(Adapter, rFPGA0_XAB_RFInterfaceSW, 0x07000760);
- /* 0x860[6:5]= b'00 */
- rtl8723au_write32(Adapter, rFPGA0_XA_RFInterfaceOE, 0x66F60210);
-
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "%s: 0x870 = value 0x%x\n", __func__,
- rtl8723au_read32(Adapter, 0x870));
-
- /* */
- /* Joseph Note: Keep RfRegChnlVal for later use. */
- /* */
- pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, RF_PATH_A,
- RF_CHNLBW, bRFRegOffsetMask);
- pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, RF_PATH_B,
- RF_CHNLBW, bRFRegOffsetMask);
-
- if (!mac_on) {
- _InitQueueReservedPage(Adapter);
- _InitTxBufferBoundary(Adapter);
- }
- _InitQueuePriority(Adapter);
- _InitPageBoundary(Adapter);
- _InitTransferPageSize(Adapter);
-
- /* Get Rx PHY status in order to report RSSI and others. */
- _InitDriverInfoSize(Adapter, DRVINFO_SZ);
-
- _InitInterrupt(Adapter);
- hw_var_set_macaddr(Adapter, Adapter->eeprompriv.mac_addr);
- rtl8723a_set_media_status(Adapter, MSR_INFRA);
- _InitWMACSetting(Adapter);
- _InitAdaptiveCtrl(Adapter);
- _InitEDCA(Adapter);
- _InitRateFallback(Adapter);
- _InitRetryFunction(Adapter);
- rtl8723a_InitBeaconParameters(Adapter);
-
- _BBTurnOnBlock(Adapter);
- /* NicIFSetMacAddress(padapter, padapter->PermanentAddress); */
-
- rtl8723a_cam_invalidate_all(Adapter);
-
- /* 2010/12/17 MH We need to set TX power according to EFUSE content at first. */
- PHY_SetTxPowerLevel8723A(Adapter, pHalData->CurrentChannel);
-
- rtl8723a_InitAntenna_Selection(Adapter);
-
- /* HW SEQ CTRL */
- /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */
- rtl8723au_write8(Adapter, REG_HWSEQ_CTRL, 0xFF);
-
- /* */
- /* Disable BAR, suggested by Scott */
- /* 2010.04.09 add by hpfan */
- /* */
- rtl8723au_write32(Adapter, REG_BAR_MODE_CTRL, 0x0201ffff);
-
- if (pregistrypriv->wifi_spec)
- rtl8723au_write16(Adapter, REG_FAST_EDCA_CTRL, 0);
-
- /* Move by Neo for USB SS from above setp */
- _RfPowerSave(Adapter);
-
- /* 2010/08/26 MH Merge from 8192CE. */
- /* sherry masked that it has been done in _RfPowerSave */
- /* 20110927 */
- /* recovery for 8192cu and 9723Au 20111017 */
- if (pwrctrlpriv->rf_pwrstate == rf_on) {
- if (pHalData->bIQKInitialized) {
- rtl8723a_phy_iq_calibrate(Adapter, true);
- } else {
- rtl8723a_phy_iq_calibrate(Adapter, false);
- pHalData->bIQKInitialized = true;
- }
-
- rtl8723a_odm_check_tx_power_tracking(Adapter);
-
- rtl8723a_phy_lc_calibrate(Adapter);
-
- rtl8723a_dual_antenna_detection(Adapter);
- }
-
- /* fixed USB interface interference issue */
- rtl8723au_write8(Adapter, 0xfe40, 0xe0);
- rtl8723au_write8(Adapter, 0xfe41, 0x8d);
- rtl8723au_write8(Adapter, 0xfe42, 0x80);
- rtl8723au_write32(Adapter, 0x20c, 0xfd0320);
- /* Solve too many protocol error on USB bus */
- if (!IS_81xxC_VENDOR_UMC_A_CUT(pHalData->VersionID)) {
- /* 0xE6 = 0x94 */
- rtl8723au_write8(Adapter, 0xFE40, 0xE6);
- rtl8723au_write8(Adapter, 0xFE41, 0x94);
- rtl8723au_write8(Adapter, 0xFE42, 0x80);
-
- /* 0xE0 = 0x19 */
- rtl8723au_write8(Adapter, 0xFE40, 0xE0);
- rtl8723au_write8(Adapter, 0xFE41, 0x19);
- rtl8723au_write8(Adapter, 0xFE42, 0x80);
-
- /* 0xE5 = 0x91 */
- rtl8723au_write8(Adapter, 0xFE40, 0xE5);
- rtl8723au_write8(Adapter, 0xFE41, 0x91);
- rtl8723au_write8(Adapter, 0xFE42, 0x80);
-
- /* 0xE2 = 0x81 */
- rtl8723au_write8(Adapter, 0xFE40, 0xE2);
- rtl8723au_write8(Adapter, 0xFE41, 0x81);
- rtl8723au_write8(Adapter, 0xFE42, 0x80);
-
- }
-
-/* _InitPABias(Adapter); */
-
- /* Init BT hw config. */
- rtl8723a_BT_init_hwconfig(Adapter);
-
- rtl8723a_InitHalDm(Adapter);
-
- val8 = DIV_ROUND_UP(WiFiNavUpperUs, HAL_8723A_NAV_UPPER_UNIT);
- rtl8723au_write8(Adapter, REG_NAV_UPPER, val8);
-
- /* 2011/03/09 MH debug only, UMC-B cut pass 2500 S5 test, but we need to fin root cause. */
- if (((rtl8723au_read32(Adapter, rFPGA0_RFMOD) & 0xFF000000) !=
- 0x83000000)) {
- PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(24), 1);
- RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
- "%s: IQK fail recover\n", __func__);
- }
-
- /* ack for xmit mgmt frames. */
- rtl8723au_write32(Adapter, REG_FWHW_TXQ_CTRL,
- rtl8723au_read32(Adapter, REG_FWHW_TXQ_CTRL)|BIT(12));
-
-exit:
- if (status == _SUCCESS) {
- Adapter->hw_init_completed = true;
-
- if (Adapter->registrypriv.notch_filter == 1)
- rtl8723a_notch_filter(Adapter, 1);
- }
-
- DBG_8723A("%s in %dms\n", __func__,
- jiffies_to_msecs(jiffies - init_start_time));
- return status;
-}
-
-static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter,
- enum rt_rf_power_state eRFPowerState)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- u8 sps0;
-
- sps0 = rtl8723au_read8(Adapter, REG_SPS0_CTRL);
-
- switch (eRFPowerState) {
- case rf_on:
- /* 1. Enable MAC Clock. Can not be enabled now. */
- /* WriteXBYTE(REG_SYS_CLKR+1,
- ReadXBYTE(REG_SYS_CLKR+1) | BIT(3)); */
-
- /* 2. Force PWM, Enable SPS18_LDO_Marco_Block */
- rtl8723au_write8(Adapter, REG_SPS0_CTRL,
- sps0 | BIT(0) | BIT(3));
-
- /* 3. restore BB, AFE control register. */
- /* RF */
- if (pHalData->rf_type == RF_2T2R)
- PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
- 0x380038, 1);
- else
- PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
- 0x38, 1);
- PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 1);
- PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 0);
-
- /* AFE */
- if (pHalData->rf_type == RF_2T2R)
- rtl8723au_write32(Adapter, rRx_Wait_CCA, 0x63DB25A0);
- else if (pHalData->rf_type == RF_1T1R)
- rtl8723au_write32(Adapter, rRx_Wait_CCA, 0x631B25A0);
-
- /* 4. issue 3-wire command that RF set to Rx idle
- mode. This is used to re-write the RX idle mode. */
- /* We can only prvide a usual value instead and then
- HW will modify the value by itself. */
- PHY_SetRFReg(Adapter, RF_PATH_A, RF_AC,
- bRFRegOffsetMask, 0x32D95);
- if (pHalData->rf_type == RF_2T2R) {
- PHY_SetRFReg(Adapter, RF_PATH_B, RF_AC,
- bRFRegOffsetMask, 0x32D95);
- }
- break;
- case rf_sleep:
- case rf_off:
- if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
- sps0 &= ~BIT(0);
- else
- sps0 &= ~(BIT(0) | BIT(3));
-
- RT_TRACE(_module_hal_init_c_, _drv_err_, "SS LVL1\n");
- /* Disable RF and BB only for SelectSuspend. */
-
- /* 1. Set BB/RF to shutdown. */
- /* (1) Reg878[5:3]= 0 RF rx_code for
- preamble power saving */
- /* (2)Reg878[21:19]= 0 Turn off RF-B */
- /* (3) RegC04[7:4]= 0 Turn off all paths
- for packet detection */
- /* (4) Reg800[1] = 1 enable preamble power saving */
- Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] =
- rtl8723au_read32(Adapter, rFPGA0_XAB_RFParameter);
- Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] =
- rtl8723au_read32(Adapter, rOFDM0_TRxPathEnable);
- Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] =
- rtl8723au_read32(Adapter, rFPGA0_RFMOD);
- if (pHalData->rf_type == RF_2T2R)
- PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
- 0x380038, 0);
- else if (pHalData->rf_type == RF_1T1R)
- PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, 0x38, 0);
- PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0);
- PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 1);
-
- /* 2 .AFE control register to power down. bit[30:22] */
- Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] =
- rtl8723au_read32(Adapter, rRx_Wait_CCA);
- if (pHalData->rf_type == RF_2T2R)
- rtl8723au_write32(Adapter, rRx_Wait_CCA, 0x00DB25A0);
- else if (pHalData->rf_type == RF_1T1R)
- rtl8723au_write32(Adapter, rRx_Wait_CCA, 0x001B25A0);
-
- /* 3. issue 3-wire command that RF set to power down.*/
- PHY_SetRFReg(Adapter, RF_PATH_A, RF_AC, bRFRegOffsetMask, 0);
- if (pHalData->rf_type == RF_2T2R)
- PHY_SetRFReg(Adapter, RF_PATH_B, RF_AC,
- bRFRegOffsetMask, 0);
-
- /* 4. Force PFM , disable SPS18_LDO_Marco_Block */
- rtl8723au_write8(Adapter, REG_SPS0_CTRL, sps0);
- break;
- default:
- break;
- }
-}
-
-static void CardDisableRTL8723U(struct rtw_adapter *Adapter)
-{
- u8 u1bTmp;
-
- DBG_8723A("CardDisableRTL8723U\n");
- /* USB-MF Card Disable Flow */
- /* 1. Run LPS WL RFOFF flow */
- HalPwrSeqCmdParsing23a(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
- PWR_INTF_USB_MSK, rtl8723AU_enter_lps_flow);
-
- /* 2. 0x1F[7:0] = 0 turn off RF */
- rtl8723au_write8(Adapter, REG_RF_CTRL, 0x00);
-
- /* ==== Reset digital sequence ====== */
- if ((rtl8723au_read8(Adapter, REG_MCUFWDL) & BIT(7)) &&
- Adapter->bFWReady) /* 8051 RAM code */
- rtl8723a_FirmwareSelfReset(Adapter);
-
- /* Reset MCU. Suggested by Filen. 2011.01.26. by tynli. */
- u1bTmp = rtl8723au_read8(Adapter, REG_SYS_FUNC_EN+1);
- rtl8723au_write8(Adapter, REG_SYS_FUNC_EN+1, u1bTmp & ~BIT(2));
-
- /* g. MCUFWDL 0x80[1:0]= 0 reset MCU ready status */
- rtl8723au_write8(Adapter, REG_MCUFWDL, 0x00);
-
- /* ==== Reset digital sequence end ====== */
- /* Card disable power action flow */
- HalPwrSeqCmdParsing23a(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
- PWR_INTF_USB_MSK,
- rtl8723AU_card_disable_flow);
-
- /* Reset MCU IO Wrapper, added by Roger, 2011.08.30. */
- u1bTmp = rtl8723au_read8(Adapter, REG_RSV_CTRL + 1);
- rtl8723au_write8(Adapter, REG_RSV_CTRL+1, u1bTmp & ~BIT(0));
- u1bTmp = rtl8723au_read8(Adapter, REG_RSV_CTRL + 1);
- rtl8723au_write8(Adapter, REG_RSV_CTRL+1, u1bTmp | BIT(0));
-
- /* 7. RSV_CTRL 0x1C[7:0] = 0x0E lock ISO/CLK/Power control register */
- rtl8723au_write8(Adapter, REG_RSV_CTRL, 0x0e);
-}
-
-int rtl8723au_hal_deinit(struct rtw_adapter *padapter)
-{
- DBG_8723A("==> %s\n", __func__);
-
-#ifdef CONFIG_8723AU_BT_COEXIST
- BT_HaltProcess(padapter);
-#endif
- /* 2011/02/18 To Fix RU LNA power leakage problem. We need to
- execute below below in Adapter init and halt sequence.
- According to EEchou's opinion, we can enable the ability for all */
- /* IC. Accord to johnny's opinion, only RU need the support. */
- CardDisableRTL8723U(padapter);
-
- padapter->hw_init_completed = false;
-
- return _SUCCESS;
-}
-
-int rtl8723au_inirp_init(struct rtw_adapter *Adapter)
-{
- u8 i;
- struct recv_buf *precvbuf;
- int status;
- struct recv_priv *precvpriv = &Adapter->recvpriv;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
-
- status = _SUCCESS;
-
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_, "===> usb_inirp_init\n");
-
- /* issue Rx irp to receive data */
- precvbuf = (struct recv_buf *)precvpriv->precv_buf;
- for (i = 0; i < NR_RECVBUFF; i++) {
- if (rtl8723au_read_port(Adapter, 0, precvbuf) == _FAIL) {
- RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
- "usb_rx_init: usb_read_port error\n");
- status = _FAIL;
- goto exit;
- }
- precvbuf++;
- }
- if (rtl8723au_read_interrupt(Adapter) == _FAIL) {
- RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
- "%s: usb_read_interrupt error\n", __func__);
- status = _FAIL;
- }
- pHalData->IntrMask[0] = rtl8723au_read32(Adapter, REG_USB_HIMR);
- MSG_8723A("pHalData->IntrMask = 0x%04x\n", pHalData->IntrMask[0]);
- pHalData->IntrMask[0] |= UHIMR_C2HCMD|UHIMR_CPWM;
- rtl8723au_write32(Adapter, REG_USB_HIMR, pHalData->IntrMask[0]);
-exit:
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "<=== usb_inirp_init\n");
- return status;
-}
-
-int rtl8723au_inirp_deinit(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
-
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "===> usb_rx_deinit\n");
- rtl8723au_read_port_cancel(Adapter);
- pHalData->IntrMask[0] = rtl8723au_read32(Adapter, REG_USB_HIMR);
- MSG_8723A("%s pHalData->IntrMask = 0x%04x\n", __func__,
- pHalData->IntrMask[0]);
- pHalData->IntrMask[0] = 0x0;
- rtl8723au_write32(Adapter, REG_USB_HIMR, pHalData->IntrMask[0]);
- RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
- "<=== usb_rx_deinit\n");
- return _SUCCESS;
-}
-
-static void _ReadBoardType(struct rtw_adapter *Adapter, u8 *PROMContent,
- bool AutoloadFail)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- u8 boardType = BOARD_USB_DONGLE;
-
- if (AutoloadFail) {
- if (IS_8723_SERIES(pHalData->VersionID))
- pHalData->rf_type = RF_1T1R;
- else
- pHalData->rf_type = RF_2T2R;
- pHalData->BoardType = boardType;
- return;
- }
-
- boardType = PROMContent[EEPROM_NORMAL_BoardType];
- boardType &= BOARD_TYPE_NORMAL_MASK;/* bit[7:5] */
- boardType >>= 5;
-
- pHalData->BoardType = boardType;
- MSG_8723A("_ReadBoardType(%x)\n", pHalData->BoardType);
-
- if (boardType == BOARD_USB_High_PA)
- pHalData->ExternalPA = 1;
-}
-
-static void Hal_EfuseParseMACAddr_8723AU(struct rtw_adapter *padapter,
- u8 *hwinfo, bool AutoLoadFail)
-{
- u16 i;
- u8 sMacAddr[ETH_ALEN] = {0x00, 0xE0, 0x4C, 0x87, 0x23, 0x00};
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
-
- if (AutoLoadFail) {
- for (i = 0; i < 6; i++)
- pEEPROM->mac_addr[i] = sMacAddr[i];
- } else {
- /* Read Permanent MAC address */
- memcpy(pEEPROM->mac_addr, &hwinfo[EEPROM_MAC_ADDR_8723AU],
- ETH_ALEN);
- }
-
- RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,
- "Hal_EfuseParseMACAddr_8723AU: Permanent Address =%pM\n",
- pEEPROM->mac_addr);
-}
-
-static void readAdapterInfo(struct rtw_adapter *padapter)
-{
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
- /* struct hal_data_8723a * pHalData = GET_HAL_DATA(padapter); */
- u8 hwinfo[HWSET_MAX_SIZE];
-
- Hal_InitPGData(padapter, hwinfo);
- Hal_EfuseParseIDCode(padapter, hwinfo);
- Hal_EfuseParseEEPROMVer(padapter, hwinfo,
- pEEPROM->bautoload_fail_flag);
- Hal_EfuseParseMACAddr_8723AU(padapter, hwinfo,
- pEEPROM->bautoload_fail_flag);
- Hal_EfuseParsetxpowerinfo_8723A(padapter, hwinfo,
- pEEPROM->bautoload_fail_flag);
- _ReadBoardType(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
- Hal_EfuseParseBTCoexistInfo_8723A(padapter, hwinfo,
- pEEPROM->bautoload_fail_flag);
-
- rtl8723a_EfuseParseChnlPlan(padapter, hwinfo,
- pEEPROM->bautoload_fail_flag);
- Hal_EfuseParseThermalMeter_8723A(padapter, hwinfo,
- pEEPROM->bautoload_fail_flag);
-/* _ReadRFSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); */
-/* _ReadPSSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); */
- Hal_EfuseParseAntennaDiversity(padapter, hwinfo,
- pEEPROM->bautoload_fail_flag);
-
- Hal_EfuseParseEEPROMVer(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
- Hal_EfuseParseCustomerID(padapter, hwinfo,
- pEEPROM->bautoload_fail_flag);
- Hal_EfuseParseRateIndicationOption(padapter, hwinfo,
- pEEPROM->bautoload_fail_flag);
- Hal_EfuseParseXtal_8723A(padapter, hwinfo,
- pEEPROM->bautoload_fail_flag);
-
- /* hal_CustomizedBehavior_8723U(Adapter); */
-
-/* Adapter->bDongle = (PROMContent[EEPROM_EASY_REPLACEMENT] == 1)? 0: 1; */
- DBG_8723A("%s(): REPLACEMENT = %x\n", __func__, padapter->bDongle);
-}
-
-static void _ReadPROMContent(struct rtw_adapter *Adapter)
-{
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter);
- u8 eeValue;
-
- eeValue = rtl8723au_read8(Adapter, REG_9346CR);
- /* To check system boot selection. */
- pEEPROM->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false;
- pEEPROM->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true;
-
- DBG_8723A("Boot from %s, Autoload %s !\n",
- (pEEPROM->EepromOrEfuse ? "EEPROM" : "EFUSE"),
- (pEEPROM->bautoload_fail_flag ? "Fail" : "OK"));
-
- readAdapterInfo(Adapter);
-}
-
-/* */
-/* Description: */
-/* We should set Efuse cell selection to WiFi cell in default. */
-/* */
-/* Assumption: */
-/* PASSIVE_LEVEL */
-/* */
-/* Added by Roger, 2010.11.23. */
-/* */
-static void hal_EfuseCellSel(struct rtw_adapter *Adapter)
-{
- u32 value32;
-
- value32 = rtl8723au_read32(Adapter, EFUSE_TEST);
- value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
- rtl8723au_write32(Adapter, EFUSE_TEST, value32);
-}
-
-void rtl8723a_read_adapter_info(struct rtw_adapter *Adapter)
-{
- unsigned long start = jiffies;
-
- /* Read EEPROM size before call any EEPROM function */
- Adapter->EepromAddressSize = GetEEPROMSize8723A(Adapter);
-
- MSG_8723A("====> _ReadAdapterInfo8723AU\n");
-
- hal_EfuseCellSel(Adapter);
-
- _ReadPROMContent(Adapter);
-
- MSG_8723A("<==== _ReadAdapterInfo8723AU in %d ms\n",
- jiffies_to_msecs(jiffies - start));
-}
-
-/* */
-/* Description: */
-/* Query setting of specified variable. */
-/* */
-int GetHalDefVar8192CUsb(struct rtw_adapter *Adapter,
- enum hal_def_variable eVariable, void *pValue)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- int bResult = _SUCCESS;
-
- switch (eVariable) {
- case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB:
- *((int *)pValue) = pHalData->dmpriv.UndecoratedSmoothedPWDB;
- break;
- case HAL_DEF_IS_SUPPORT_ANT_DIV:
- break;
- case HAL_DEF_CURRENT_ANTENNA:
- break;
- case HAL_DEF_DRVINFO_SZ:
- *((u32 *)pValue) = DRVINFO_SZ;
- break;
- case HAL_DEF_MAX_RECVBUF_SZ:
- *((u32 *)pValue) = MAX_RECVBUF_SZ;
- break;
- case HAL_DEF_RX_PACKET_OFFSET:
- *((u32 *)pValue) = RXDESC_SIZE + DRVINFO_SZ;
- break;
- case HAL_DEF_DBG_DUMP_RXPKT:
- *((u8 *)pValue) = pHalData->bDumpRxPkt;
- break;
- case HAL_DEF_DBG_DM_FUNC:
- *((u32 *)pValue) = pHalData->odmpriv.SupportAbility;
- break;
- case HW_VAR_MAX_RX_AMPDU_FACTOR:
- *((u32 *)pValue) = IEEE80211_HT_MAX_AMPDU_64K;
- break;
- case HW_DEF_ODM_DBG_FLAG:
- {
- struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
- printk("pDM_Odm->DebugComponents = 0x%llx\n",
- pDM_Odm->DebugComponents);
- }
- break;
- default:
- bResult = _FAIL;
- break;
- }
-
- return bResult;
-}
-
-void rtl8723a_update_ramask(struct rtw_adapter *padapter,
- u32 mac_id, u8 rssi_level)
-{
- struct sta_info *psta;
- struct FW_Sta_Info *fw_sta;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
- u8 init_rate, networkType, raid, arg;
- u32 mask, rate_bitmap;
- u8 shortGIrate = false;
- int supportRateNum;
-
- if (mac_id >= NUM_STA) /* CAM_SIZE */
- return;
-
- psta = pmlmeinfo->FW_sta_info[mac_id].psta;
- if (psta == NULL)
- return;
-
- switch (mac_id) {
- case 0:/* for infra mode */
- supportRateNum =
- rtw_get_rateset_len23a(cur_network->SupportedRates);
- networkType = judge_network_type23a(padapter,
- cur_network->SupportedRates,
- supportRateNum) & 0xf;
- /* pmlmeext->cur_wireless_mode = networkType; */
- raid = networktype_to_raid23a(networkType);
-
- mask = update_supported_rate23a(cur_network->SupportedRates,
- supportRateNum);
- mask |= (pmlmeinfo->HT_enable) ?
- update_MSC_rate23a(&pmlmeinfo->ht_cap) : 0;
-
- if (support_short_GI23a(padapter, &pmlmeinfo->ht_cap))
- shortGIrate = true;
- break;
-
- case 1:/* for broadcast/multicast */
- fw_sta = &pmlmeinfo->FW_sta_info[mac_id];
- supportRateNum = rtw_get_rateset_len23a(fw_sta->SupportedRates);
- if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
- networkType = WIRELESS_11B;
- else
- networkType = WIRELESS_11G;
- raid = networktype_to_raid23a(networkType);
-
- mask = update_basic_rate23a(cur_network->SupportedRates,
- supportRateNum);
- break;
-
- default: /* for each sta in IBSS */
- fw_sta = &pmlmeinfo->FW_sta_info[mac_id];
- supportRateNum = rtw_get_rateset_len23a(fw_sta->SupportedRates);
- networkType = judge_network_type23a(padapter,
- fw_sta->SupportedRates,
- supportRateNum) & 0xf;
- /* pmlmeext->cur_wireless_mode = networkType; */
- raid = networktype_to_raid23a(networkType);
-
- mask = update_supported_rate23a(cur_network->SupportedRates,
- supportRateNum);
-
- /* todo: support HT in IBSS */
- break;
- }
-
- /* mask &= 0x0fffffff; */
- rate_bitmap = ODM_Get_Rate_Bitmap23a(pHalData, mac_id, mask,
- rssi_level);
- DBG_8723A("%s => mac_id:%d, networkType:0x%02x, "
- "mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n",
- __func__, mac_id, networkType, mask, rssi_level, rate_bitmap);
-
- mask &= rate_bitmap;
- mask |= ((raid << 28) & 0xf0000000);
-
- init_rate = get_highest_rate_idx23a(mask) & 0x3f;
-
- arg = mac_id & 0x1f;/* MACID */
- arg |= BIT(7);
-
- if (shortGIrate == true)
- arg |= BIT(5);
-
- DBG_8723A("update raid entry, mask = 0x%x, arg = 0x%x\n", mask, arg);
-
- rtl8723a_set_raid_cmd(padapter, mask, arg);
-
- /* set ra_id */
- psta->raid = raid;
- psta->init_rate = init_rate;
-
- /* set correct initial date rate for each mac_id */
- pdmpriv->INIDATA_RATE[mac_id] = init_rate;
-}
diff --git a/drivers/staging/rtl8723au/hal/usb_ops_linux.c b/drivers/staging/rtl8723au/hal/usb_ops_linux.c
deleted file mode 100644
index 5c81ff48252e..000000000000
--- a/drivers/staging/rtl8723au/hal/usb_ops_linux.c
+++ /dev/null
@@ -1,690 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _HCI_OPS_OS_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <osdep_intf.h>
-#include <usb_ops.h>
-#include <recv_osdep.h>
-#include <rtl8723a_hal.h>
-#include <rtl8723a_recv.h>
-
-u8 rtl8723au_read8(struct rtw_adapter *padapter, u16 addr)
-{
- struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
- struct usb_device *udev = pdvobjpriv->pusbdev;
- int len;
- u8 data;
-
- mutex_lock(&pdvobjpriv->usb_vendor_req_mutex);
- len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- REALTEK_USB_VENQT_CMD_REQ, REALTEK_USB_VENQT_READ,
- addr, 0, &pdvobjpriv->usb_buf.val8, sizeof(data),
- RTW_USB_CONTROL_MSG_TIMEOUT);
-
- data = pdvobjpriv->usb_buf.val8;
- mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex);
-
- return data;
-}
-
-u16 rtl8723au_read16(struct rtw_adapter *padapter, u16 addr)
-{
- struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
- struct usb_device *udev = pdvobjpriv->pusbdev;
- int len;
- u16 data;
-
- mutex_lock(&pdvobjpriv->usb_vendor_req_mutex);
- len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- REALTEK_USB_VENQT_CMD_REQ, REALTEK_USB_VENQT_READ,
- addr, 0, &pdvobjpriv->usb_buf.val16, sizeof(data),
- RTW_USB_CONTROL_MSG_TIMEOUT);
-
- data = le16_to_cpu(pdvobjpriv->usb_buf.val16);
- mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex);
-
- return data;
-}
-
-u32 rtl8723au_read32(struct rtw_adapter *padapter, u16 addr)
-{
- struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
- struct usb_device *udev = pdvobjpriv->pusbdev;
- int len;
- u32 data;
-
- mutex_lock(&pdvobjpriv->usb_vendor_req_mutex);
- len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- REALTEK_USB_VENQT_CMD_REQ, REALTEK_USB_VENQT_READ,
- addr, 0, &pdvobjpriv->usb_buf.val32, sizeof(data),
- RTW_USB_CONTROL_MSG_TIMEOUT);
-
- data = le32_to_cpu(pdvobjpriv->usb_buf.val32);
- mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex);
-
- return data;
-}
-
-int rtl8723au_write8(struct rtw_adapter *padapter, u16 addr, u8 val)
-{
- struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
- struct usb_device *udev = pdvobjpriv->pusbdev;
- int ret;
-
- mutex_lock(&pdvobjpriv->usb_vendor_req_mutex);
- pdvobjpriv->usb_buf.val8 = val;
-
- ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- REALTEK_USB_VENQT_CMD_REQ,
- REALTEK_USB_VENQT_WRITE,
- addr, 0, &pdvobjpriv->usb_buf.val8, sizeof(val),
- RTW_USB_CONTROL_MSG_TIMEOUT);
-
- if (ret != sizeof(val))
- ret = _FAIL;
- else
- ret = _SUCCESS;
-
- mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex);
- return ret;
-}
-
-int rtl8723au_write16(struct rtw_adapter *padapter, u16 addr, u16 val)
-{
- struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
- struct usb_device *udev = pdvobjpriv->pusbdev;
- int ret;
-
- mutex_lock(&pdvobjpriv->usb_vendor_req_mutex);
- pdvobjpriv->usb_buf.val16 = cpu_to_le16(val);
-
- ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- REALTEK_USB_VENQT_CMD_REQ,
- REALTEK_USB_VENQT_WRITE,
- addr, 0, &pdvobjpriv->usb_buf.val16, sizeof(val),
- RTW_USB_CONTROL_MSG_TIMEOUT);
-
- if (ret != sizeof(val))
- ret = _FAIL;
- else
- ret = _SUCCESS;
-
- mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex);
- return ret;
-}
-
-int rtl8723au_write32(struct rtw_adapter *padapter, u16 addr, u32 val)
-{
- struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
- struct usb_device *udev = pdvobjpriv->pusbdev;
- int ret;
-
- mutex_lock(&pdvobjpriv->usb_vendor_req_mutex);
- pdvobjpriv->usb_buf.val32 = cpu_to_le32(val);
-
- ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- REALTEK_USB_VENQT_CMD_REQ,
- REALTEK_USB_VENQT_WRITE,
- addr, 0, &pdvobjpriv->usb_buf.val32, sizeof(val),
- RTW_USB_CONTROL_MSG_TIMEOUT);
-
- if (ret != sizeof(val))
- ret = _FAIL;
- else
- ret = _SUCCESS;
-
- mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex);
- return ret;
-}
-
-int rtl8723au_writeN(struct rtw_adapter *padapter, u16 addr, u16 len, u8 *buf)
-{
- struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
- struct usb_device *udev = pdvobjpriv->pusbdev;
- int ret;
-
- ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- REALTEK_USB_VENQT_CMD_REQ,
- REALTEK_USB_VENQT_WRITE,
- addr, 0, buf, len, RTW_USB_CONTROL_MSG_TIMEOUT);
-
- if (ret != len)
- return _FAIL;
- return _SUCCESS;
-}
-
-/*
- * Description:
- * Recognize the interrupt content by reading the interrupt
- * register or content and masking interrupt mask (IMR)
- * if it is our NIC's interrupt. After recognizing, we may clear
- * the all interrupts (ISR).
- * Arguments:
- * [in] Adapter -
- * The adapter context.
- * [in] pContent -
- * Under PCI interface, this field is ignord.
- * Under USB interface, the content is the interrupt
- * content pointer.
- * Under SDIO interface, this is the interrupt type which
- * is Local interrupt or system interrupt.
- * [in] ContentLen -
- * The length in byte of pContent.
- * Return:
- * If any interrupt matches the mask (IMR), return true, and
- * return false otherwise.
- */
-static bool
-InterruptRecognized8723AU(struct rtw_adapter *Adapter, void *pContent,
- u32 ContentLen)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- u8 *buffer = (u8 *)pContent;
- struct reportpwrstate_parm report;
-
- memcpy(&pHalData->IntArray[0], &buffer[USB_INTR_CONTENT_HISR_OFFSET],
- 4);
- pHalData->IntArray[0] &= pHalData->IntrMask[0];
-
- /* For HISR extension. Added by tynli. 2009.10.07. */
- memcpy(&pHalData->IntArray[1],
- &buffer[USB_INTR_CONTENT_HISRE_OFFSET], 4);
- pHalData->IntArray[1] &= pHalData->IntrMask[1];
-
- /* We sholud remove this function later because DDK suggest
- * not to executing too many operations in MPISR */
-
- memcpy(&report.state, &buffer[USB_INTR_CPWM_OFFSET], 1);
-
- return (pHalData->IntArray[0] & pHalData->IntrMask[0]) != 0 ||
- (pHalData->IntArray[1] & pHalData->IntrMask[1]) != 0;
-}
-
-static void usb_read_interrupt_complete(struct urb *purb)
-{
- int err;
- struct rtw_adapter *padapter = (struct rtw_adapter *)purb->context;
-
- if (padapter->bSurpriseRemoved || padapter->bDriverStopped ||
- padapter->bReadPortCancel) {
- DBG_8723A("%s() RX Warning! bDriverStopped(%d) OR "
- "bSurpriseRemoved(%d) bReadPortCancel(%d)\n",
- __func__, padapter->bDriverStopped,
- padapter->bSurpriseRemoved,
- padapter->bReadPortCancel);
- return;
- }
-
- if (purb->status == 0) {
- struct c2h_evt_hdr *c2h_evt;
-
- c2h_evt = (struct c2h_evt_hdr *)purb->transfer_buffer;
-
- if (purb->actual_length > USB_INTR_CONTENT_LENGTH) {
- DBG_8723A("usb_read_interrupt_complete: purb->actual_"
- "length > USB_INTR_CONTENT_LENGTH\n");
- goto urb_submit;
- }
-
- InterruptRecognized8723AU(padapter, purb->transfer_buffer,
- purb->actual_length);
-
- if (c2h_evt_exist(c2h_evt)) {
- if (c2h_id_filter_ccx_8723a(c2h_evt->id)) {
- /* Handle CCX report here */
- handle_txrpt_ccx_8723a(padapter, (void *)
- c2h_evt->payload);
- schedule_work(&padapter->evtpriv.irq_wk);
- } else {
- struct evt_work *c2w;
- int res;
-
- c2w = kmalloc(sizeof(struct evt_work),
- GFP_ATOMIC);
-
- if (!c2w)
- goto urb_submit;
-
- c2w->adapter = padapter;
- INIT_WORK(&c2w->work, rtw_evt_work);
- memcpy(c2w->u.buf, purb->transfer_buffer, 16);
-
- res = queue_work(padapter->evtpriv.wq,
- &c2w->work);
-
- if (!res) {
- printk(KERN_ERR "%s: Call to "
- "queue_work() failed\n",
- __func__);
- kfree(c2w);
- goto urb_submit;
- }
- }
- }
-
-urb_submit:
- err = usb_submit_urb(purb, GFP_ATOMIC);
- if (err && (err != -EPERM)) {
- DBG_8723A("cannot submit interrupt in-token(err = "
- "0x%08x), urb_status = %d\n",
- err, purb->status);
- }
- } else {
- DBG_8723A("###=> usb_read_interrupt_complete => urb "
- "status(%d)\n", purb->status);
-
- switch (purb->status) {
- case -EINVAL:
- case -EPIPE:
- case -ENODEV:
- case -ESHUTDOWN:
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_read_port_complete:bSurpriseRemoved =true\n");
- /* Fall Through here */
- case -ENOENT:
- padapter->bDriverStopped = true;
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_read_port_complete:bDriverStopped =true\n");
- break;
- case -EPROTO:
- break;
- case -EINPROGRESS:
- DBG_8723A("ERROR: URB IS IN PROGRESS!\n");
- break;
- default:
- break;
- }
- }
-}
-
-int rtl8723au_read_interrupt(struct rtw_adapter *adapter)
-{
- int err;
- unsigned int pipe;
- int ret = _SUCCESS;
- struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter);
- struct recv_priv *precvpriv = &adapter->recvpriv;
- struct usb_device *pusbd = pdvobj->pusbdev;
-
- /* translate DMA FIFO addr to pipehandle */
- pipe = usb_rcvintpipe(pusbd, pdvobj->RtInPipe[1]);
-
- usb_fill_int_urb(precvpriv->int_in_urb, pusbd, pipe,
- precvpriv->int_in_buf, USB_INTR_CONTENT_LENGTH,
- usb_read_interrupt_complete, adapter, 1);
-
- err = usb_submit_urb(precvpriv->int_in_urb, GFP_ATOMIC);
- if (err && (err != -EPERM)) {
- DBG_8723A("cannot submit interrupt in-token(err = 0x%08x),"
- "urb_status = %d\n", err,
- precvpriv->int_in_urb->status);
- ret = _FAIL;
- }
-
- return ret;
-}
-
-static int recvbuf2recvframe(struct rtw_adapter *padapter, struct sk_buff *pskb)
-{
- u8 *pbuf;
- u8 shift_sz = 0;
- u16 pkt_cnt;
- u32 pkt_offset, skb_len, alloc_sz;
- int transfer_len;
- struct recv_stat *prxstat;
- struct phy_stat *pphy_info;
- struct sk_buff *pkt_copy;
- struct recv_frame *precvframe;
- struct rx_pkt_attrib *pattrib;
- struct recv_priv *precvpriv = &padapter->recvpriv;
- struct rtw_queue *pfree_recv_queue = &precvpriv->free_recv_queue;
-
- transfer_len = (int)pskb->len;
- pbuf = pskb->data;
-
- prxstat = (struct recv_stat *)pbuf;
- pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;
-
- do {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "recvbuf2recvframe: rxdesc = offsset 0:0x%08x, 4:0x%08x, 8:0x%08x, C:0x%08x\n",
- prxstat->rxdw0, prxstat->rxdw1,
- prxstat->rxdw2, prxstat->rxdw4);
-
- prxstat = (struct recv_stat *)pbuf;
-
- precvframe = rtw_alloc_recvframe23a(pfree_recv_queue);
- if (!precvframe) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "recvbuf2recvframe: precvframe == NULL\n");
- DBG_8723A("%s()-%d: rtw_alloc_recvframe23a() failed! RX "
- "Drop!\n", __func__, __LINE__);
- goto _exit_recvbuf2recvframe;
- }
-
- INIT_LIST_HEAD(&precvframe->list);
-
- update_recvframe_attrib(precvframe, prxstat);
-
- pattrib = &precvframe->attrib;
-
- if (pattrib->crc_err) {
- DBG_8723A("%s()-%d: RX Warning! rx CRC ERROR !!\n",
- __func__, __LINE__);
- rtw_free_recvframe23a(precvframe);
- goto _exit_recvbuf2recvframe;
- }
-
- pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz +
- pattrib->shift_sz + pattrib->pkt_len;
-
- if (pattrib->pkt_len <= 0 || pkt_offset > transfer_len) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- "recvbuf2recvframe: pkt_len<= 0\n");
- DBG_8723A("%s()-%d: RX Warning!\n",
- __func__, __LINE__);
- rtw_free_recvframe23a(precvframe);
- goto _exit_recvbuf2recvframe;
- }
-
- /* Modified by Albert 20101213 */
- /* For 8 bytes IP header alignment. */
- /* Qos data, wireless lan header length is 26 */
- if (pattrib->qos)
- shift_sz = 6;
- else
- shift_sz = 0;
-
- skb_len = pattrib->pkt_len;
-
- /* for first fragment packet, driver need allocate
- * 1536+drvinfo_sz+RXDESC_SIZE to defrag packet.
- * modify alloc_sz for recvive crc error packet
- * by thomas 2011-06-02 */
- if (pattrib->mfrag == 1 && pattrib->frag_num == 0) {
- /* alloc_sz = 1664; 1664 is 128 alignment. */
- if (skb_len <= 1650)
- alloc_sz = 1664;
- else
- alloc_sz = skb_len + 14;
- } else {
- alloc_sz = skb_len;
- /* 6 is for IP header 8 bytes alignment in QoS packet case. */
- /* 8 is for skb->data 4 bytes alignment. */
- alloc_sz += 14;
- }
-
- pkt_copy = netdev_alloc_skb(padapter->pnetdev, alloc_sz);
- if (pkt_copy) {
- pkt_copy->dev = padapter->pnetdev;
- precvframe->pkt = pkt_copy;
- /* force pkt_copy->data at 8-byte alignment address */
- skb_reserve(pkt_copy, 8 -
- ((unsigned long)(pkt_copy->data) & 7));
- /*force ip_hdr at 8-byte alignment address
- according to shift_sz. */
- skb_reserve(pkt_copy, shift_sz);
- memcpy(pkt_copy->data, pbuf + pattrib->shift_sz +
- pattrib->drvinfo_sz + RXDESC_SIZE, skb_len);
- skb_put(pkt_copy, skb_len);
- } else {
- if (pattrib->mfrag == 1 && pattrib->frag_num == 0) {
- DBG_8723A("recvbuf2recvframe: alloc_skb fail, "
- "drop frag frame \n");
- rtw_free_recvframe23a(precvframe);
- goto _exit_recvbuf2recvframe;
- }
-
- precvframe->pkt = skb_clone(pskb, GFP_ATOMIC);
- if (!precvframe->pkt) {
- DBG_8723A("recvbuf2recvframe: skb_clone "
- "fail\n");
- rtw_free_recvframe23a(precvframe);
- goto _exit_recvbuf2recvframe;
- }
- }
-
- if (pattrib->physt) {
- pphy_info = (struct phy_stat *)(pbuf + RXDESC_OFFSET);
- update_recvframe_phyinfo(precvframe, pphy_info);
- }
-
- if (rtw_recv_entry23a(precvframe) != _SUCCESS)
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- "recvbuf2recvframe: rtw_recv_entry23a(precvframe) != _SUCCESS\n");
-
- pkt_cnt--;
- transfer_len -= pkt_offset;
- pbuf += pkt_offset;
- precvframe = NULL;
- pkt_copy = NULL;
-
- if (transfer_len > 0 && pkt_cnt == 0)
- pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff;
-
- } while (transfer_len > 0 && pkt_cnt > 0);
-
-_exit_recvbuf2recvframe:
-
- return _SUCCESS;
-}
-
-void rtl8723au_recv_tasklet(void *priv)
-{
- struct sk_buff *pskb;
- struct rtw_adapter *padapter = (struct rtw_adapter *)priv;
- struct recv_priv *precvpriv = &padapter->recvpriv;
-
- while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) {
- if (padapter->bDriverStopped || padapter->bSurpriseRemoved) {
- DBG_8723A("recv_tasklet => bDriverStopped or "
- "bSurpriseRemoved \n");
- dev_kfree_skb_any(pskb);
- break;
- }
-
- recvbuf2recvframe(padapter, pskb);
- skb_reset_tail_pointer(pskb);
-
- pskb->len = 0;
-
- skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
- }
-}
-
-static void usb_read_port_complete(struct urb *purb)
-{
- struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
- struct rtw_adapter *padapter = (struct rtw_adapter *)precvbuf->adapter;
- struct recv_priv *precvpriv = &padapter->recvpriv;
-
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_read_port_complete!!!\n");
-
- precvpriv->rx_pending_cnt--;
-
- if (padapter->bSurpriseRemoved || padapter->bDriverStopped ||
- padapter->bReadPortCancel) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
- padapter->bDriverStopped, padapter->bSurpriseRemoved);
-
- DBG_8723A("%s()-%d: RX Warning! bDriverStopped(%d) OR "
- "bSurpriseRemoved(%d) bReadPortCancel(%d)\n",
- __func__, __LINE__, padapter->bDriverStopped,
- padapter->bSurpriseRemoved, padapter->bReadPortCancel);
- return;
- }
-
- if (purb->status == 0) {
- if (purb->actual_length > MAX_RECVBUF_SZ ||
- purb->actual_length < RXDESC_SIZE) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_read_port_complete: (purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)\n");
- rtl8723au_read_port(padapter, 0, precvbuf);
- DBG_8723A("%s()-%d: RX Warning!\n",
- __func__, __LINE__);
- } else {
- rtw_reset_continual_urb_error(
- adapter_to_dvobj(padapter));
-
- skb_put(precvbuf->pskb, purb->actual_length);
- skb_queue_tail(&precvpriv->rx_skb_queue,
- precvbuf->pskb);
-
- if (skb_queue_len(&precvpriv->rx_skb_queue) <= 1)
- tasklet_schedule(&precvpriv->recv_tasklet);
-
- precvbuf->pskb = NULL;
- rtl8723au_read_port(padapter, 0, precvbuf);
- }
- } else {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_read_port_complete : purb->status(%d) != 0\n",
- purb->status);
- skb_put(precvbuf->pskb, purb->actual_length);
- precvbuf->pskb = NULL;
-
- DBG_8723A("###=> usb_read_port_complete => urb status(%d)\n",
- purb->status);
-
- if (rtw_inc_and_chk_continual_urb_error(
- adapter_to_dvobj(padapter))) {
- padapter->bSurpriseRemoved = true;
- }
-
- switch (purb->status) {
- case -EINVAL:
- case -EPIPE:
- case -ENODEV:
- case -ESHUTDOWN:
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_read_port_complete:bSurpriseRemoved = true\n");
- /* Intentional fall through here */
- case -ENOENT:
- padapter->bDriverStopped = true;
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_read_port_complete:bDriverStopped = true\n");
- break;
- case -EPROTO:
- case -EOVERFLOW:
- rtl8723au_read_port(padapter, 0, precvbuf);
- break;
- case -EINPROGRESS:
- DBG_8723A("ERROR: URB IS IN PROGRESS!\n");
- break;
- default:
- break;
- }
- }
-}
-
-int rtl8723au_read_port(struct rtw_adapter *adapter, u32 cnt,
- struct recv_buf *precvbuf)
-{
- struct urb *purb;
- struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter);
- struct recv_priv *precvpriv = &adapter->recvpriv;
- struct usb_device *pusbd = pdvobj->pusbdev;
- int err;
- unsigned int pipe;
- unsigned long tmpaddr;
- unsigned long alignment;
- int ret = _SUCCESS;
-
- if (adapter->bDriverStopped || adapter->bSurpriseRemoved) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_read_port:(padapter->bDriverStopped ||padapter->bSurpriseRemoved)!!!\n");
- return _FAIL;
- }
-
- if (!precvbuf) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_read_port:precvbuf == NULL\n");
- return _FAIL;
- }
-
- if (!precvbuf->pskb)
- precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
-
- /* re-assign for linux based on skb */
- if (!precvbuf->pskb) {
- precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
- if (precvbuf->pskb == NULL) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "init_recvbuf(): alloc_skb fail!\n");
- return _FAIL;
- }
-
- tmpaddr = (unsigned long)precvbuf->pskb->data;
- alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
- skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
- }
-
- precvpriv->rx_pending_cnt++;
-
- purb = precvbuf->purb;
-
- /* translate DMA FIFO addr to pipehandle */
- pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[0]);
-
- usb_fill_bulk_urb(purb, pusbd, pipe, precvbuf->pskb->data,
- MAX_RECVBUF_SZ, usb_read_port_complete,
- precvbuf);/* context is precvbuf */
-
- err = usb_submit_urb(purb, GFP_ATOMIC);
- if ((err) && (err != -EPERM)) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "cannot submit rx in-token(err = 0x%.8x), URB_STATUS = 0x%.8x\n",
- err, purb->status);
- DBG_8723A("cannot submit rx in-token(err = 0x%08x), urb_status "
- "= %d\n", err, purb->status);
- ret = _FAIL;
- }
- return ret;
-}
-
-void rtl8723au_xmit_tasklet(void *priv)
-{
- int ret;
- struct rtw_adapter *padapter = (struct rtw_adapter *)priv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- if (check_fwstate(&padapter->mlmepriv, _FW_UNDER_SURVEY))
- return;
-
- while (1) {
- if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
- padapter->bWritePortCancel) {
- DBG_8723A("xmit_tasklet => bDriverStopped or "
- "bSurpriseRemoved or bWritePortCancel\n");
- break;
- }
-
- ret = rtl8723au_xmitframe_complete(padapter, pxmitpriv, NULL);
-
- if (!ret)
- break;
- }
-}
-
-void rtl8723au_set_hw_type(struct rtw_adapter *padapter)
-{
- padapter->chip_type = RTL8723A;
- padapter->HardwareType = HARDWARE_TYPE_RTL8723AU;
- DBG_8723A("CHIP TYPE: RTL8723A\n");
-}
diff --git a/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h b/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h
deleted file mode 100644
index bcf36579f43a..000000000000
--- a/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- *
- ******************************************************************************/
-#ifndef __INC_HAL8723PHYCFG_H__
-#define __INC_HAL8723PHYCFG_H__
-
-/*------------------------------Define structure----------------------------*/
-enum RF_RADIO_PATH {
- RF_PATH_A = 0, /* Radio Path A */
- RF_PATH_B = 1, /* Radio Path B */
- RF_PATH_MAX /* Max RF number 90 support */
-};
-
-#define CHANNEL_MAX_NUMBER 14 /* 14 is the max channel number */
-
-enum WIRELESS_MODE {
- WIRELESS_MODE_UNKNOWN = 0x00,
- WIRELESS_MODE_A = BIT(2),
- WIRELESS_MODE_B = BIT(0),
- WIRELESS_MODE_G = BIT(1),
- WIRELESS_MODE_AUTO = BIT(5),
- WIRELESS_MODE_N_24G = BIT(3),
- WIRELESS_MODE_N_5G = BIT(4),
- WIRELESS_MODE_AC = BIT(6)
-};
-
-struct bb_reg_define {
- u32 rfintfs; /* set software control: */
- /* 0x870~0x877[8 bytes] */
- u32 rfintfi; /* readback data: */
- /* 0x8e0~0x8e7[8 bytes] */
- u32 rfintfo; /* output data: */
- /* 0x860~0x86f [16 bytes] */
- u32 rfintfe; /* output enable: */
- /* 0x860~0x86f [16 bytes] */
- u32 rf3wireOffset; /* LSSI data: */
- /* 0x840~0x84f [16 bytes] */
- u32 rfLSSI_Select; /* BB Band Select: */
- /* 0x878~0x87f [8 bytes] */
- u32 rfTxGainStage; /* Tx gain stage: */
- /* 0x80c~0x80f [4 bytes] */
- u32 rfHSSIPara1; /* wire parameter control1 : */
- /* 0x820~0x823, 0x828~0x82b, 0x830~0x833, 0x838~0x83b [16 bytes] */
- u32 rfHSSIPara2; /* wire parameter control2 : */
- /* 0x824~0x827, 0x82c~0x82f, 0x834~0x837, 0x83c~0x83f [16 bytes] */
- u32 rfSwitchControl; /* Tx Rx antenna control : */
- /* 0x858~0x85f [16 bytes] */
- u32 rfAGCControl1; /* AGC parameter control1 : */
- /* 0xc50~0xc53, 0xc58~0xc5b, 0xc60~0xc63, 0xc68~0xc6b [16 bytes] */
- u32 rfAGCControl2; /* AGC parameter control2 : */
- /* 0xc54~0xc57, 0xc5c~0xc5f, 0xc64~0xc67, 0xc6c~0xc6f [16 bytes] */
- u32 rfRxIQImbalance; /* OFDM Rx IQ imbalance matrix : */
- /* 0xc14~0xc17, 0xc1c~0xc1f, 0xc24~0xc27, 0xc2c~0xc2f [16 bytes] */
- u32 rfRxAFE; /* Rx IQ DC ofset and Rx digital filter, Rx DC notch filter : */
- /* 0xc10~0xc13, 0xc18~0xc1b, 0xc20~0xc23, 0xc28~0xc2b [16 bytes] */
- u32 rfTxIQImbalance; /* OFDM Tx IQ imbalance matrix */
- /* 0xc80~0xc83, 0xc88~0xc8b, 0xc90~0xc93, 0xc98~0xc9b [16 bytes] */
- u32 rfTxAFE; /* Tx IQ DC Offset and Tx DFIR type */
- /* 0xc84~0xc87, 0xc8c~0xc8f, 0xc94~0xc97, 0xc9c~0xc9f [16 bytes] */
- u32 rfLSSIReadBack; /* LSSI RF readback data SI mode */
- /* 0x8a0~0x8af [16 bytes] */
- u32 rfLSSIReadBackPi; /* LSSI RF readback data PI mode 0x8b8-8bc for Path A and B */
-};
-
-struct r_antenna_sel_ofdm {
- u32 r_tx_antenna:4;
- u32 r_ant_l:4;
- u32 r_ant_non_ht:4;
- u32 r_ant_ht1:4;
- u32 r_ant_ht2:4;
- u32 r_ant_ht_s1:4;
- u32 r_ant_non_ht_s1:4;
- u32 OFDM_TXSC:2;
- u32 Reserved:2;
-};
-
-struct r_antenna_sel_cck {
- u8 r_cckrx_enable_2:2;
- u8 r_cckrx_enable:2;
- u8 r_ccktx_enable:4;
-};
-
-/*------------------------------Define structure----------------------------*/
-
-
-/*------------------------Export global variable----------------------------*/
-/*------------------------Export global variable----------------------------*/
-
-
-/*------------------------Export Macro Definition---------------------------*/
-/*------------------------Export Macro Definition---------------------------*/
-
-
-/*--------------------------Exported Function prototype---------------------*/
-/* */
-/* BB and RF register read/write */
-/* */
-u32 PHY_QueryBBReg(struct rtw_adapter *Adapter, u32 RegAddr,
- u32 BitMask);
-void PHY_SetBBReg(struct rtw_adapter *Adapter, u32 RegAddr,
- u32 BitMask, u32 Data);
-u32 PHY_QueryRFReg(struct rtw_adapter *Adapter,
- enum RF_RADIO_PATH eRFPath, u32 RegAddr,
- u32 BitMask);
-void PHY_SetRFReg(struct rtw_adapter *Adapter,
- enum RF_RADIO_PATH eRFPath, u32 RegAddr,
- u32 BitMask, u32 Data);
-
-/* */
-/* BB TX Power R/W */
-/* */
-void PHY_SetTxPowerLevel8723A(struct rtw_adapter *Adapter, u8 channel);
-
-/* */
-/* Switch bandwidth for 8723A */
-/* */
-void PHY_SetBWMode23a8723A(struct rtw_adapter *pAdapter,
- enum ht_channel_width ChnlWidth,
- unsigned char Offset);
-
-/* */
-/* channel switch related funciton */
-/* */
-void PHY_SwChnl8723A(struct rtw_adapter *pAdapter, u8 channel);
- /* Call after initialization */
-void ChkFwCmdIoDone(struct rtw_adapter *Adapter);
-
-/* */
-/* Modify the value of the hw register when beacon interval be changed. */
-/* */
-void
-rtl8192c_PHY_SetBeaconHwReg(struct rtw_adapter *Adapter, u16 BeaconInterval);
-
-
-void PHY_SwitchEphyParameter(struct rtw_adapter *Adapter);
-
-void PHY_EnableHostClkReq(struct rtw_adapter *Adapter);
-
-bool
-SetAntennaConfig92C(struct rtw_adapter *Adapter, u8 DefaultAnt);
-
-/*--------------------------Exported Function prototype---------------------*/
-
-#define PHY_SetMacReg PHY_SetBBReg
-
-/* MAC/BB/RF HAL config */
-int PHY_BBConfig8723A(struct rtw_adapter *Adapter);
-s32 PHY_MACConfig8723A(struct rtw_adapter *padapter);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/Hal8723APhyReg.h b/drivers/staging/rtl8723au/include/Hal8723APhyReg.h
deleted file mode 100644
index 759928f78d6d..000000000000
--- a/drivers/staging/rtl8723au/include/Hal8723APhyReg.h
+++ /dev/null
@@ -1,1078 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- *
- ******************************************************************************/
-#ifndef __INC_HAL8723APHYREG_H__
-#define __INC_HAL8723APHYREG_H__
-
-/* 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF */
-/* 1. Page1(0x100) */
-#define rPMAC_Reset 0x100
-#define rPMAC_TxStart 0x104
-#define rPMAC_TxLegacySIG 0x108
-#define rPMAC_TxHTSIG1 0x10c
-#define rPMAC_TxHTSIG2 0x110
-#define rPMAC_PHYDebug 0x114
-#define rPMAC_TxPacketNum 0x118
-#define rPMAC_TxIdle 0x11c
-#define rPMAC_TxMACHeader0 0x120
-#define rPMAC_TxMACHeader1 0x124
-#define rPMAC_TxMACHeader2 0x128
-#define rPMAC_TxMACHeader3 0x12c
-#define rPMAC_TxMACHeader4 0x130
-#define rPMAC_TxMACHeader5 0x134
-#define rPMAC_TxDataType 0x138
-#define rPMAC_TxRandomSeed 0x13c
-#define rPMAC_CCKPLCPPreamble 0x140
-#define rPMAC_CCKPLCPHeader 0x144
-#define rPMAC_CCKCRC16 0x148
-#define rPMAC_OFDMRxCRC32OK 0x170
-#define rPMAC_OFDMRxCRC32Er 0x174
-#define rPMAC_OFDMRxParityEr 0x178
-#define rPMAC_OFDMRxCRC8Er 0x17c
-#define rPMAC_CCKCRxRC16Er 0x180
-#define rPMAC_CCKCRxRC32Er 0x184
-#define rPMAC_CCKCRxRC32OK 0x188
-#define rPMAC_TxStatus 0x18c
-
-/* 2. Page2(0x200) */
-/* The following two definition are only used for USB interface. */
-#define RF_BB_CMD_ADDR 0x02c0 /* RF/BB read/write command address. */
-#define RF_BB_CMD_DATA 0x02c4 /* RF/BB read/write command data. */
-
-/* 3. Page8(0x800) */
-#define rFPGA0_RFMOD 0x800 /* RF mode & CCK TxSC RF BW Setting?? */
-
-#define rFPGA0_TxInfo 0x804 /* Status report?? */
-#define rFPGA0_PSDFunction 0x808
-
-#define rFPGA0_TxGainStage 0x80c /* Set TX PWR init gain? */
-
-#define rFPGA0_RFTiming1 0x810 /* Useless now */
-#define rFPGA0_RFTiming2 0x814
-
-#define rFPGA0_XA_HSSIParameter1 0x820 /* RF 3 wire register */
-#define rFPGA0_XA_HSSIParameter2 0x824
-#define rFPGA0_XB_HSSIParameter1 0x828
-#define rFPGA0_XB_HSSIParameter2 0x82c
-#define rTxAGC_B_Rate18_06 0x830
-#define rTxAGC_B_Rate54_24 0x834
-#define rTxAGC_B_CCK1_55_Mcs32 0x838
-#define rTxAGC_B_Mcs03_Mcs00 0x83c
-
-#define rTxAGC_B_Mcs07_Mcs04 0x848
-#define rTxAGC_B_Mcs11_Mcs08 0x84c
-
-#define rFPGA0_XA_LSSIParameter 0x840
-#define rFPGA0_XB_LSSIParameter 0x844
-
-#define rFPGA0_RFWakeUpParameter 0x850 /* Useless now */
-#define rFPGA0_RFSleepUpParameter 0x854
-
-#define rFPGA0_XAB_SwitchControl 0x858 /* RF Channel switch */
-#define rFPGA0_XCD_SwitchControl 0x85c
-
-#define rFPGA0_XA_RFInterfaceOE 0x860 /* RF Channel switch */
-#define rFPGA0_XB_RFInterfaceOE 0x864
-
-#define rTxAGC_B_Mcs15_Mcs12 0x868
-#define rTxAGC_B_CCK11_A_CCK2_11 0x86c
-
-#define rFPGA0_XAB_RFInterfaceSW 0x870 /* RF Interface Software Control */
-#define rFPGA0_XCD_RFInterfaceSW 0x874
-
-#define rFPGA0_XAB_RFParameter 0x878 /* RF Parameter */
-#define rFPGA0_XCD_RFParameter 0x87c
-
-#define rFPGA0_AnalogParameter1 0x880 /* Crystal cap setting RF-R/W protection for parameter4?? */
-#define rFPGA0_AnalogParameter2 0x884
-#define rFPGA0_AnalogParameter3 0x888 /* Useless now */
-#define rFPGA0_AnalogParameter4 0x88c
-
-#define rFPGA0_XA_LSSIReadBack 0x8a0 /* Tranceiver LSSI Readback */
-#define rFPGA0_XB_LSSIReadBack 0x8a4
-#define rFPGA0_XC_LSSIReadBack 0x8a8
-#define rFPGA0_XD_LSSIReadBack 0x8ac
-
-#define rFPGA0_PSDReport 0x8b4 /* Useless now */
-#define TransceiverA_HSPI_Readback 0x8b8 /* Transceiver A HSPI Readback */
-#define TransceiverB_HSPI_Readback 0x8bc /* Transceiver B HSPI Readback */
-#define rFPGA0_XAB_RFInterfaceRB 0x8e0 /* Useless now RF Interface Readback Value */
-#define rFPGA0_XCD_RFInterfaceRB 0x8e4 /* Useless now */
-
-/* 4. Page9(0x900) */
-#define rFPGA1_RFMOD 0x900 /* RF mode & OFDM TxSC RF BW Setting?? */
-
-#define rFPGA1_TxBlock 0x904 /* Useless now */
-#define rFPGA1_DebugSelect 0x908 /* Useless now */
-#define rFPGA1_TxInfo 0x90c /* Useless now Status report?? */
-
-/* 5. PageA(0xA00) */
-/* Set Control channel to upper or lower. These settings are required only for 40MHz */
-#define rCCK0_System 0xa00
-
-#define rCCK0_AFESetting 0xa04 /* Disable init gain now Select RX path by RSSI */
-#define rCCK0_CCA 0xa08 /* Disable init gain now Init gain */
-
-#define rCCK0_RxAGC1 0xa0c /* AGC default value, saturation level Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series */
-#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */
-
-#define rCCK0_RxHP 0xa14
-
-#define rCCK0_DSPParameter1 0xa18 /* Timing recovery & Channel estimation threshold */
-#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */
-
-#define rCCK0_TxFilter1 0xa20
-#define rCCK0_TxFilter2 0xa24
-#define rCCK0_DebugPort 0xa28 /* debug port and Tx filter3 */
-#define rCCK0_FalseAlarmReport 0xa2c /* 0xa2d useless now 0xa30-a4f channel report */
-#define rCCK0_TRSSIReport 0xa50
-#define rCCK0_RxReport 0xa54 /* 0xa57 */
-#define rCCK0_FACounterLower 0xa5c /* 0xa5b */
-#define rCCK0_FACounterUpper 0xa58 /* 0xa5c */
-/* PageB(0xB00) */
-#define rPdp_AntA 0xb00
-#define rPdp_AntA_4 0xb04
-#define rConfig_Pmpd_AntA 0xb28
-#define rConfig_AntA 0xb68
-#define rConfig_AntB 0xb6c
-#define rPdp_AntB 0xb70
-#define rPdp_AntB_4 0xb74
-#define rConfig_Pmpd_AntB 0xb98
-#define rAPK 0xbd8
-
-/* 6. PageC(0xC00) */
-#define rOFDM0_LSTF 0xc00
-
-#define rOFDM0_TRxPathEnable 0xc04
-#define rOFDM0_TRMuxPar 0xc08
-#define rOFDM0_TRSWIsolation 0xc0c
-
-#define rOFDM0_XARxAFE 0xc10 /* RxIQ DC offset, Rx digital filter, DC notch filter */
-#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imblance matrix */
-#define rOFDM0_XBRxAFE 0xc18
-#define rOFDM0_XBRxIQImbalance 0xc1c
-#define rOFDM0_XCRxAFE 0xc20
-#define rOFDM0_XCRxIQImbalance 0xc24
-#define rOFDM0_XDRxAFE 0xc28
-#define rOFDM0_XDRxIQImbalance 0xc2c
-
-#define rOFDM0_RxDetector1 0xc30 /* PD,BW & SBD DM tune init gain */
-#define rOFDM0_RxDetector2 0xc34 /* SBD & Fame Sync. */
-#define rOFDM0_RxDetector3 0xc38 /* Frame Sync. */
-#define rOFDM0_RxDetector4 0xc3c /* PD, SBD, Frame Sync & Short-GI */
-
-#define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */
-#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */
-#define rOFDM0_CCADropThreshold 0xc48 /* CCA Drop threshold */
-#define rOFDM0_ECCAThreshold 0xc4c /* energy CCA */
-
-#define rOFDM0_XAAGCCore1 0xc50 /* DIG */
-#define rOFDM0_XAAGCCore2 0xc54
-#define rOFDM0_XBAGCCore1 0xc58
-#define rOFDM0_XBAGCCore2 0xc5c
-#define rOFDM0_XCAGCCore1 0xc60
-#define rOFDM0_XCAGCCore2 0xc64
-#define rOFDM0_XDAGCCore1 0xc68
-#define rOFDM0_XDAGCCore2 0xc6c
-
-#define rOFDM0_AGCParameter1 0xc70
-#define rOFDM0_AGCParameter2 0xc74
-#define rOFDM0_AGCRSSITable 0xc78
-#define rOFDM0_HTSTFAGC 0xc7c
-
-#define rOFDM0_XATxIQImbalance 0xc80 /* TX PWR TRACK and DIG */
-#define rOFDM0_XATxAFE 0xc84
-#define rOFDM0_XBTxIQImbalance 0xc88
-#define rOFDM0_XBTxAFE 0xc8c
-#define rOFDM0_XCTxIQImbalance 0xc90
-#define rOFDM0_XCTxAFE 0xc94
-#define rOFDM0_XDTxIQImbalance 0xc98
-#define rOFDM0_XDTxAFE 0xc9c
-
-#define rOFDM0_RxIQExtAnta 0xca0
-#define rOFDM0_TxCoeff1 0xca4
-#define rOFDM0_TxCoeff2 0xca8
-#define rOFDM0_TxCoeff3 0xcac
-#define rOFDM0_TxCoeff4 0xcb0
-#define rOFDM0_TxCoeff5 0xcb4
-#define rOFDM0_TxCoeff6 0xcb8
-#define rOFDM0_RxHPParameter 0xce0
-#define rOFDM0_TxPseudoNoiseWgt 0xce4
-#define rOFDM0_FrameSync 0xcf0
-#define rOFDM0_DFSReport 0xcf4
-
-/* 7. PageD(0xD00) */
-#define rOFDM1_LSTF 0xd00
-#define rOFDM1_TRxPathEnable 0xd04
-
-#define rOFDM1_CFO 0xd08 /* No setting now */
-#define rOFDM1_CSI1 0xd10
-#define rOFDM1_SBD 0xd14
-#define rOFDM1_CSI2 0xd18
-#define rOFDM1_CFOTracking 0xd2c
-#define rOFDM1_TRxMesaure1 0xd34
-#define rOFDM1_IntfDet 0xd3c
-#define rOFDM1_PseudoNoiseStateAB 0xd50
-#define rOFDM1_PseudoNoiseStateCD 0xd54
-#define rOFDM1_RxPseudoNoiseWgt 0xd58
-
-#define rOFDM_PHYCounter1 0xda0 /* cca, parity fail */
-#define rOFDM_PHYCounter2 0xda4 /* rate illegal, crc8 fail */
-#define rOFDM_PHYCounter3 0xda8 /* MCS not support */
-
-#define rOFDM_ShortCFOAB 0xdac /* No setting now */
-#define rOFDM_ShortCFOCD 0xdb0
-#define rOFDM_LongCFOAB 0xdb4
-#define rOFDM_LongCFOCD 0xdb8
-#define rOFDM_TailCFOAB 0xdbc
-#define rOFDM_TailCFOCD 0xdc0
-#define rOFDM_PWMeasure1 0xdc4
-#define rOFDM_PWMeasure2 0xdc8
-#define rOFDM_BWReport 0xdcc
-#define rOFDM_AGCReport 0xdd0
-#define rOFDM_RxSNR 0xdd4
-#define rOFDM_RxEVMCSI 0xdd8
-#define rOFDM_SIGReport 0xddc
-
-
-/* 8. PageE(0xE00) */
-#define rTxAGC_A_Rate18_06 0xe00
-#define rTxAGC_A_Rate54_24 0xe04
-#define rTxAGC_A_CCK1_Mcs32 0xe08
-#define rTxAGC_A_Mcs03_Mcs00 0xe10
-#define rTxAGC_A_Mcs07_Mcs04 0xe14
-#define rTxAGC_A_Mcs11_Mcs08 0xe18
-#define rTxAGC_A_Mcs15_Mcs12 0xe1c
-
-#define rFPGA0_IQK 0xe28
-#define rTx_IQK_Tone_A 0xe30
-#define rRx_IQK_Tone_A 0xe34
-#define rTx_IQK_PI_A 0xe38
-#define rRx_IQK_PI_A 0xe3c
-
-#define rTx_IQK 0xe40
-#define rRx_IQK 0xe44
-#define rIQK_AGC_Pts 0xe48
-#define rIQK_AGC_Rsp 0xe4c
-#define rTx_IQK_Tone_B 0xe50
-#define rRx_IQK_Tone_B 0xe54
-#define rTx_IQK_PI_B 0xe58
-#define rRx_IQK_PI_B 0xe5c
-#define rIQK_AGC_Cont 0xe60
-
-#define rBlue_Tooth 0xe6c
-#define rRx_Wait_CCA 0xe70
-#define rTx_CCK_RFON 0xe74
-#define rTx_CCK_BBON 0xe78
-#define rTx_OFDM_RFON 0xe7c
-#define rTx_OFDM_BBON 0xe80
-#define rTx_To_Rx 0xe84
-#define rTx_To_Tx 0xe88
-#define rRx_CCK 0xe8c
-
-#define rTx_Power_Before_IQK_A 0xe94
-#define rTx_Power_After_IQK_A 0xe9c
-
-#define rRx_Power_Before_IQK_A 0xea0
-#define rRx_Power_Before_IQK_A_2 0xea4
-#define rRx_Power_After_IQK_A 0xea8
-#define rRx_Power_After_IQK_A_2 0xeac
-
-#define rTx_Power_Before_IQK_B 0xeb4
-#define rTx_Power_After_IQK_B 0xebc
-
-#define rRx_Power_Before_IQK_B 0xec0
-#define rRx_Power_Before_IQK_B_2 0xec4
-#define rRx_Power_After_IQK_B 0xec8
-#define rRx_Power_After_IQK_B_2 0xecc
-
-#define rRx_OFDM 0xed0
-#define rRx_Wait_RIFS 0xed4
-#define rRx_TO_Rx 0xed8
-#define rStandby 0xedc
-#define rSleep 0xee0
-#define rPMPD_ANAEN 0xeec
-
-/* 7. RF Register 0x00-0x2E (RF 8256) */
-/* RF-0222D 0x00-3F */
-/* Zebra1 */
-#define rZebra1_HSSIEnable 0x0 /* Useless now */
-#define rZebra1_TRxEnable1 0x1
-#define rZebra1_TRxEnable2 0x2
-#define rZebra1_AGC 0x4
-#define rZebra1_ChargePump 0x5
-#define rZebra1_Channel 0x7 /* RF channel switch */
-
-#define rZebra1_TxGain 0x8 /* Useless now */
-#define rZebra1_TxLPF 0x9
-#define rZebra1_RxLPF 0xb
-#define rZebra1_RxHPFCorner 0xc
-
-/* Zebra4 */
-#define rGlobalCtrl 0 /* Useless now */
-#define rRTL8256_TxLPF 19
-#define rRTL8256_RxLPF 11
-
-/* RTL8258 */
-#define rRTL8258_TxLPF 0x11 /* Useless now */
-#define rRTL8258_RxLPF 0x13
-#define rRTL8258_RSSILPF 0xa
-
-/* RL6052 Register definition */
-#define RF_AC 0x00
-#define RF_IQADJ_G1 0x01
-#define RF_IQADJ_G2 0x02
-#define RF_BS_PA_APSET_G1_G4 0x03
-#define RF_BS_PA_APSET_G5_G8 0x04
-#define RF_POW_TRSW 0x05
-#define RF_GAIN_RX 0x06
-#define RF_GAIN_TX 0x07
-#define RF_TXM_IDAC 0x08
-#define RF_IPA_G 0x09
-#define RF_TXBIAS_G 0x0A
-#define RF_TXPA_AG 0x0B
-#define RF_IPA_A 0x0C
-#define RF_TXBIAS_A 0x0D
-#define RF_BS_PA_APSET_G9_G11 0x0E
-#define RF_BS_IQGEN 0x0F
-#define RF_MODE1 0x10
-#define RF_MODE2 0x11
-#define RF_RX_AGC_HP 0x12
-#define RF_TX_AGC 0x13
-#define RF_BIAS 0x14
-#define RF_IPA 0x15
-#define RF_TXBIAS 0x16
-#define RF_POW_ABILITY 0x17
-#define RF_MODE_AG 0x18
-#define rRfChannel 0x18 /* RF channel and BW switch */
-#define RF_CHNLBW 0x18 /* RF channel and BW switch */
-#define RF_TOP 0x19
-#define RF_RX_G1 0x1A
-#define RF_RX_G2 0x1B
-#define RF_RX_BB2 0x1C
-#define RF_RX_BB1 0x1D
-#define RF_RCK1 0x1E
-#define RF_RCK2 0x1F
-#define RF_TX_G1 0x20
-#define RF_TX_G2 0x21
-#define RF_TX_G3 0x22
-#define RF_TX_BB1 0x23
-#define RF_T_METER 0x24
-#define RF_SYN_G1 0x25 /* RF TX Power control */
-#define RF_SYN_G2 0x26 /* RF TX Power control */
-#define RF_SYN_G3 0x27 /* RF TX Power control */
-#define RF_SYN_G4 0x28 /* RF TX Power control */
-#define RF_SYN_G5 0x29 /* RF TX Power control */
-#define RF_SYN_G6 0x2A /* RF TX Power control */
-#define RF_SYN_G7 0x2B /* RF TX Power control */
-#define RF_SYN_G8 0x2C /* RF TX Power control */
-
-#define RF_RCK_OS 0x30 /* RF TX PA control */
-
-#define RF_TXPA_G1 0x31 /* RF TX PA control */
-#define RF_TXPA_G2 0x32 /* RF TX PA control */
-#define RF_TXPA_G3 0x33 /* RF TX PA control */
-
-/* Bit Mask */
-/* 1. Page1(0x100) */
-#define bBBResetB 0x100 /* Useless now? */
-#define bGlobalResetB 0x200
-#define bOFDMTxStart 0x4
-#define bCCKTxStart 0x8
-#define bCRC32Debug 0x100
-#define bPMACLoopback 0x10
-#define bTxLSIG 0xffffff
-#define bOFDMTxRate 0xf
-#define bOFDMTxReserved 0x10
-#define bOFDMTxLength 0x1ffe0
-#define bOFDMTxParity 0x20000
-#define bTxHTSIG1 0xffffff
-#define bTxHTMCSRate 0x7f
-#define bTxHTBW 0x80
-#define bTxHTLength 0xffff00
-#define bTxHTSIG2 0xffffff
-#define bTxHTSmoothing 0x1
-#define bTxHTSounding 0x2
-#define bTxHTReserved 0x4
-#define bTxHTAggreation 0x8
-#define bTxHTSTBC 0x30
-#define bTxHTAdvanceCoding 0x40
-#define bTxHTShortGI 0x80
-#define bTxHTNumberHT_LTF 0x300
-#define bTxHTCRC8 0x3fc00
-#define bCounterReset 0x10000
-#define bNumOfOFDMTx 0xffff
-#define bNumOfCCKTx 0xffff0000
-#define bTxIdleInterval 0xffff
-#define bOFDMService 0xffff0000
-#define bTxMACHeader 0xffffffff
-#define bTxDataInit 0xff
-#define bTxHTMode 0x100
-#define bTxDataType 0x30000
-#define bTxRandomSeed 0xffffffff
-#define bCCKTxPreamble 0x1
-#define bCCKTxSFD 0xffff0000
-#define bCCKTxSIG 0xff
-#define bCCKTxService 0xff00
-#define bCCKLengthExt 0x8000
-#define bCCKTxLength 0xffff0000
-#define bCCKTxCRC16 0xffff
-#define bCCKTxStatus 0x1
-#define bOFDMTxStatus 0x2
-
-#define IS_BB_REG_OFFSET_92S(_Offset) \
- ((_Offset >= 0x800) && (_Offset <= 0xfff))
-
-/* 2. Page8(0x800) */
-#define bRFMOD 0x1 /* Reg 0x800 rFPGA0_RFMOD */
-#define bJapanMode 0x2
-#define bCCKTxSC 0x30
-#define bCCKEn 0x1000000
-#define bOFDMEn 0x2000000
-
-#define bOFDMRxADCPhase 0x10000 /* Useless now */
-#define bOFDMTxDACPhase 0x40000
-#define bXATxAGC 0x3f
-
-#define bAntennaSelect 0x0300
-
-#define bXBTxAGC 0xf00 /* Reg 80c rFPGA0_TxGainStage */
-#define bXCTxAGC 0xf000
-#define bXDTxAGC 0xf0000
-
-#define bPAStart 0xf0000000 /* Useless now */
-#define bTRStart 0x00f00000
-#define bRFStart 0x0000f000
-#define bBBStart 0x000000f0
-#define bBBCCKStart 0x0000000f
-#define bPAEnd 0xf /* Reg0x814 */
-#define bTREnd 0x0f000000
-#define bRFEnd 0x000f0000
-#define bCCAMask 0x000000f0 /* T2R */
-#define bR2RCCAMask 0x00000f00
-#define bHSSI_R2TDelay 0xf8000000
-#define bHSSI_T2RDelay 0xf80000
-#define bContTxHSSI 0x400 /* chane gain at continue Tx */
-#define bIGFromCCK 0x200
-#define bAGCAddress 0x3f
-#define bRxHPTx 0x7000
-#define bRxHPT2R 0x38000
-#define bRxHPCCKIni 0xc0000
-#define bAGCTxCode 0xc00000
-#define bAGCRxCode 0x300000
-
-#define b3WireDataLength 0x800 /* Reg 0x820~84f rFPGA0_XA_HSSIParameter1 */
-#define b3WireAddressLength 0x400
-
-#define b3WireRFPowerDown 0x1 /* Useless now */
-/* define bHWSISelect 0x8 */
-#define b5GPAPEPolarity 0x40000000
-#define b2GPAPEPolarity 0x80000000
-#define bRFSW_TxDefaultAnt 0x3
-#define bRFSW_TxOptionAnt 0x30
-#define bRFSW_RxDefaultAnt 0x300
-#define bRFSW_RxOptionAnt 0x3000
-#define bRFSI_3WireData 0x1
-#define bRFSI_3WireClock 0x2
-#define bRFSI_3WireLoad 0x4
-#define bRFSI_3WireRW 0x8
-#define bRFSI_3Wire 0xf
-
-#define bRFSI_RFENV 0x10 /* Reg 0x870 rFPGA0_XAB_RFInterfaceSW */
-
-#define bRFSI_TRSW 0x20 /* Useless now */
-#define bRFSI_TRSWB 0x40
-#define bRFSI_ANTSW 0x100
-#define bRFSI_ANTSWB 0x200
-#define bRFSI_PAPE 0x400
-#define bRFSI_PAPE5G 0x800
-#define bBandSelect 0x1
-#define bHTSIG2_GI 0x80
-#define bHTSIG2_Smoothing 0x01
-#define bHTSIG2_Sounding 0x02
-#define bHTSIG2_Aggreaton 0x08
-#define bHTSIG2_STBC 0x30
-#define bHTSIG2_AdvCoding 0x40
-#define bHTSIG2_NumOfHTLTF 0x300
-#define bHTSIG2_CRC8 0x3fc
-#define bHTSIG1_MCS 0x7f
-#define bHTSIG1_BandWidth 0x80
-#define bHTSIG1_HTLength 0xffff
-#define bLSIG_Rate 0xf
-#define bLSIG_Reserved 0x10
-#define bLSIG_Length 0x1fffe
-#define bLSIG_Parity 0x20
-#define bCCKRxPhase 0x4
-
-#define bLSSIReadAddress 0x7f800000 /* T65 RF */
-
-#define bLSSIReadEdge 0x80000000 /* LSSI "Read" edge signal */
-
-#define bLSSIReadBackData 0xfffff /* T65 RF */
-
-#define bLSSIReadOKFlag 0x1000 /* Useless now */
-#define bCCKSampleRate 0x8 /* 0: 44MHz, 1:88MHz */
-#define bRegulator0Standby 0x1
-#define bRegulatorPLLStandby 0x2
-#define bRegulator1Standby 0x4
-#define bPLLPowerUp 0x8
-#define bDPLLPowerUp 0x10
-#define bDA10PowerUp 0x20
-#define bAD7PowerUp 0x200
-#define bDA6PowerUp 0x2000
-#define bXtalPowerUp 0x4000
-#define b40MDClkPowerUP 0x8000
-#define bDA6DebugMode 0x20000
-#define bDA6Swing 0x380000
-
-#define bADClkPhase 0x4000000 /* Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ */
-
-#define b80MClkDelay 0x18000000 /* Useless */
-#define bAFEWatchDogEnable 0x20000000
-
-#define bXtalCap01 0xc0000000 /* Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap */
-#define bXtalCap23 0x3
-#define bXtalCap92x 0x0f000000
-#define bXtalCap 0x0f000000
-
-#define bIntDifClkEnable 0x400 /* Useless */
-#define bExtSigClkEnable 0x800
-#define bBandgapMbiasPowerUp 0x10000
-#define bAD11SHGain 0xc0000
-#define bAD11InputRange 0x700000
-#define bAD11OPCurrent 0x3800000
-#define bIPathLoopback 0x4000000
-#define bQPathLoopback 0x8000000
-#define bAFELoopback 0x10000000
-#define bDA10Swing 0x7e0
-#define bDA10Reverse 0x800
-#define bDAClkSource 0x1000
-#define bAD7InputRange 0x6000
-#define bAD7Gain 0x38000
-#define bAD7OutputCMMode 0x40000
-#define bAD7InputCMMode 0x380000
-#define bAD7Current 0xc00000
-#define bRegulatorAdjust 0x7000000
-#define bAD11PowerUpAtTx 0x1
-#define bDA10PSAtTx 0x10
-#define bAD11PowerUpAtRx 0x100
-#define bDA10PSAtRx 0x1000
-#define bCCKRxAGCFormat 0x200
-#define bPSDFFTSamplepPoint 0xc000
-#define bPSDAverageNum 0x3000
-#define bIQPathControl 0xc00
-#define bPSDFreq 0x3ff
-#define bPSDAntennaPath 0x30
-#define bPSDIQSwitch 0x40
-#define bPSDRxTrigger 0x400000
-#define bPSDTxTrigger 0x80000000
-#define bPSDSineToneScale 0x7f000000
-#define bPSDReport 0xffff
-
-/* 3. Page9(0x900) */
-#define bOFDMTxSC 0x30000000 /* Useless */
-#define bCCKTxOn 0x1
-#define bOFDMTxOn 0x2
-#define bDebugPage 0xfff /* reset debug page and also HWord, LWord */
-#define bDebugItem 0xff /* reset debug page and LWord */
-#define bAntL 0x10
-#define bAntNonHT 0x100
-#define bAntHT1 0x1000
-#define bAntHT2 0x10000
-#define bAntHT1S1 0x100000
-#define bAntNonHTS1 0x1000000
-
-/* 4. PageA(0xA00) */
-#define bCCKBBMode 0x3 /* Useless */
-#define bCCKTxPowerSaving 0x80
-#define bCCKRxPowerSaving 0x40
-
-#define bCCKSideBand 0x10 /* Reg 0xa00 rCCK0_System 20/40 switch */
-
-#define bCCKScramble 0x8 /* Useless */
-#define bCCKAntDiversity 0x8000
-#define bCCKCarrierRecovery 0x4000
-#define bCCKTxRate 0x3000
-#define bCCKDCCancel 0x0800
-#define bCCKISICancel 0x0400
-#define bCCKMatchFilter 0x0200
-#define bCCKEqualizer 0x0100
-#define bCCKPreambleDetect 0x800000
-#define bCCKFastFalseCCA 0x400000
-#define bCCKChEstStart 0x300000
-#define bCCKCCACount 0x080000
-#define bCCKcs_lim 0x070000
-#define bCCKBistMode 0x80000000
-#define bCCKCCAMask 0x40000000
-#define bCCKTxDACPhase 0x4
-#define bCCKRxADCPhase 0x20000000 /* r_rx_clk */
-#define bCCKr_cp_mode0 0x0100
-#define bCCKTxDCOffset 0xf0
-#define bCCKRxDCOffset 0xf
-#define bCCKCCAMode 0xc000
-#define bCCKFalseCS_lim 0x3f00
-#define bCCKCS_ratio 0xc00000
-#define bCCKCorgBit_sel 0x300000
-#define bCCKPD_lim 0x0f0000
-#define bCCKNewCCA 0x80000000
-#define bCCKRxHPofIG 0x8000
-#define bCCKRxIG 0x7f00
-#define bCCKLNAPolarity 0x800000
-#define bCCKRx1stGain 0x7f0000
-#define bCCKRFExtend 0x20000000 /* CCK Rx Iinital gain polarity */
-#define bCCKRxAGCSatLevel 0x1f000000
-#define bCCKRxAGCSatCount 0xe0
-#define bCCKRxRFSettle 0x1f /* AGCsamp_dly */
-#define bCCKFixedRxAGC 0x8000
-/* define bCCKRxAGCFormat 0x4000 remove to HSSI register 0x824 */
-#define bCCKAntennaPolarity 0x2000
-#define bCCKTxFilterType 0x0c00
-#define bCCKRxAGCReportType 0x0300
-#define bCCKRxDAGCEn 0x80000000
-#define bCCKRxDAGCPeriod 0x20000000
-#define bCCKRxDAGCSatLevel 0x1f000000
-#define bCCKTimingRecovery 0x800000
-#define bCCKTxC0 0x3f0000
-#define bCCKTxC1 0x3f000000
-#define bCCKTxC2 0x3f
-#define bCCKTxC3 0x3f00
-#define bCCKTxC4 0x3f0000
-#define bCCKTxC5 0x3f000000
-#define bCCKTxC6 0x3f
-#define bCCKTxC7 0x3f00
-#define bCCKDebugPort 0xff0000
-#define bCCKDACDebug 0x0f000000
-#define bCCKFalseAlarmEnable 0x8000
-#define bCCKFalseAlarmRead 0x4000
-#define bCCKTRSSI 0x7f
-#define bCCKRxAGCReport 0xfe
-#define bCCKRxReport_AntSel 0x80000000
-#define bCCKRxReport_MFOff 0x40000000
-#define bCCKRxRxReport_SQLoss 0x20000000
-#define bCCKRxReport_Pktloss 0x10000000
-#define bCCKRxReport_Lockedbit 0x08000000
-#define bCCKRxReport_RateError 0x04000000
-#define bCCKRxReport_RxRate 0x03000000
-#define bCCKRxFACounterLower 0xff
-#define bCCKRxFACounterUpper 0xff000000
-#define bCCKRxHPAGCStart 0xe000
-#define bCCKRxHPAGCFinal 0x1c00
-#define bCCKRxFalseAlarmEnable 0x8000
-#define bCCKFACounterFreeze 0x4000
-#define bCCKTxPathSel 0x10000000
-#define bCCKDefaultRxPath 0xc000000
-#define bCCKOptionRxPath 0x3000000
-
-/* 5. PageC(0xC00) */
-#define bNumOfSTF 0x3 /* Useless */
-#define bShift_L 0xc0
-#define bGI_TH 0xc
-#define bRxPathA 0x1
-#define bRxPathB 0x2
-#define bRxPathC 0x4
-#define bRxPathD 0x8
-#define bTxPathA 0x1
-#define bTxPathB 0x2
-#define bTxPathC 0x4
-#define bTxPathD 0x8
-#define bTRSSIFreq 0x200
-#define bADCBackoff 0x3000
-#define bDFIRBackoff 0xc000
-#define bTRSSILatchPhase 0x10000
-#define bRxIDCOffset 0xff
-#define bRxQDCOffset 0xff00
-#define bRxDFIRMode 0x1800000
-#define bRxDCNFType 0xe000000
-#define bRXIQImb_A 0x3ff
-#define bRXIQImb_B 0xfc00
-#define bRXIQImb_C 0x3f0000
-#define bRXIQImb_D 0xffc00000
-#define bDC_dc_Notch 0x60000
-#define bRxNBINotch 0x1f000000
-#define bPD_TH 0xf
-#define bPD_TH_Opt2 0xc000
-#define bPWED_TH 0x700
-#define bIfMF_Win_L 0x800
-#define bPD_Option 0x1000
-#define bMF_Win_L 0xe000
-#define bBW_Search_L 0x30000
-#define bwin_enh_L 0xc0000
-#define bBW_TH 0x700000
-#define bED_TH2 0x3800000
-#define bBW_option 0x4000000
-#define bRatio_TH 0x18000000
-#define bWindow_L 0xe0000000
-#define bSBD_Option 0x1
-#define bFrame_TH 0x1c
-#define bFS_Option 0x60
-#define bDC_Slope_check 0x80
-#define bFGuard_Counter_DC_L 0xe00
-#define bFrame_Weight_Short 0x7000
-#define bSub_Tune 0xe00000
-#define bFrame_DC_Length 0xe000000
-#define bSBD_start_offset 0x30000000
-#define bFrame_TH_2 0x7
-#define bFrame_GI2_TH 0x38
-#define bGI2_Sync_en 0x40
-#define bSarch_Short_Early 0x300
-#define bSarch_Short_Late 0xc00
-#define bSarch_GI2_Late 0x70000
-#define bCFOAntSum 0x1
-#define bCFOAcc 0x2
-#define bCFOStartOffset 0xc
-#define bCFOLookBack 0x70
-#define bCFOSumWeight 0x80
-#define bDAGCEnable 0x10000
-#define bTXIQImb_A 0x3ff
-#define bTXIQImb_B 0xfc00
-#define bTXIQImb_C 0x3f0000
-#define bTXIQImb_D 0xffc00000
-#define bTxIDCOffset 0xff
-#define bTxQDCOffset 0xff00
-#define bTxDFIRMode 0x10000
-#define bTxPesudoNoiseOn 0x4000000
-#define bTxPesudoNoise_A 0xff
-#define bTxPesudoNoise_B 0xff00
-#define bTxPesudoNoise_C 0xff0000
-#define bTxPesudoNoise_D 0xff000000
-#define bCCADropOption 0x20000
-#define bCCADropThres 0xfff00000
-#define bEDCCA_H 0xf
-#define bEDCCA_L 0xf0
-#define bLambda_ED 0x300
-#define bRxInitialGain 0x7f
-#define bRxAntDivEn 0x80
-#define bRxAGCAddressForLNA 0x7f00
-#define bRxHighPowerFlow 0x8000
-#define bRxAGCFreezeThres 0xc0000
-#define bRxFreezeStep_AGC1 0x300000
-#define bRxFreezeStep_AGC2 0xc00000
-#define bRxFreezeStep_AGC3 0x3000000
-#define bRxFreezeStep_AGC0 0xc000000
-#define bRxRssi_Cmp_En 0x10000000
-#define bRxQuickAGCEn 0x20000000
-#define bRxAGCFreezeThresMode 0x40000000
-#define bRxOverFlowCheckType 0x80000000
-#define bRxAGCShift 0x7f
-#define bTRSW_Tri_Only 0x80
-#define bPowerThres 0x300
-#define bRxAGCEn 0x1
-#define bRxAGCTogetherEn 0x2
-#define bRxAGCMin 0x4
-#define bRxHP_Ini 0x7
-#define bRxHP_TRLNA 0x70
-#define bRxHP_RSSI 0x700
-#define bRxHP_BBP1 0x7000
-#define bRxHP_BBP2 0x70000
-#define bRxHP_BBP3 0x700000
-#define bRSSI_H 0x7f0000 /* the threshold for high power */
-#define bRSSI_Gen 0x7f000000 /* the threshold for ant diversity */
-#define bRxSettle_TRSW 0x7
-#define bRxSettle_LNA 0x38
-#define bRxSettle_RSSI 0x1c0
-#define bRxSettle_BBP 0xe00
-#define bRxSettle_RxHP 0x7000
-#define bRxSettle_AntSW_RSSI 0x38000
-#define bRxSettle_AntSW 0xc0000
-#define bRxProcessTime_DAGC 0x300000
-#define bRxSettle_HSSI 0x400000
-#define bRxProcessTime_BBPPW 0x800000
-#define bRxAntennaPowerShift 0x3000000
-#define bRSSITableSelect 0xc000000
-#define bRxHP_Final 0x7000000
-#define bRxHTSettle_BBP 0x7
-#define bRxHTSettle_HSSI 0x8
-#define bRxHTSettle_RxHP 0x70
-#define bRxHTSettle_BBPPW 0x80
-#define bRxHTSettle_Idle 0x300
-#define bRxHTSettle_Reserved 0x1c00
-#define bRxHTRxHPEn 0x8000
-#define bRxHTAGCFreezeThres 0x30000
-#define bRxHTAGCTogetherEn 0x40000
-#define bRxHTAGCMin 0x80000
-#define bRxHTAGCEn 0x100000
-#define bRxHTDAGCEn 0x200000
-#define bRxHTRxHP_BBP 0x1c00000
-#define bRxHTRxHP_Final 0xe0000000
-#define bRxPWRatioTH 0x3
-#define bRxPWRatioEn 0x4
-#define bRxMFHold 0x3800
-#define bRxPD_Delay_TH1 0x38
-#define bRxPD_Delay_TH2 0x1c0
-#define bRxPD_DC_COUNT_MAX 0x600
-/* define bRxMF_Hold 0x3800 */
-#define bRxPD_Delay_TH 0x8000
-#define bRxProcess_Delay 0xf0000
-#define bRxSearchrange_GI2_Early 0x700000
-#define bRxFrame_Guard_Counter_L 0x3800000
-#define bRxSGI_Guard_L 0xc000000
-#define bRxSGI_Search_L 0x30000000
-#define bRxSGI_TH 0xc0000000
-#define bDFSCnt0 0xff
-#define bDFSCnt1 0xff00
-#define bDFSFlag 0xf0000
-#define bMFWeightSum 0x300000
-#define bMinIdxTH 0x7f000000
-#define bDAFormat 0x40000
-#define bTxChEmuEnable 0x01000000
-#define bTRSWIsolation_A 0x7f
-#define bTRSWIsolation_B 0x7f00
-#define bTRSWIsolation_C 0x7f0000
-#define bTRSWIsolation_D 0x7f000000
-#define bExtLNAGain 0x7c00
-
-/* 6. PageE(0xE00) */
-#define bSTBCEn 0x4 /* Useless */
-#define bAntennaMapping 0x10
-#define bNss 0x20
-#define bCFOAntSumD 0x200
-#define bPHYCounterReset 0x8000000
-#define bCFOReportGet 0x4000000
-#define bOFDMContinueTx 0x10000000
-#define bOFDMSingleCarrier 0x20000000
-#define bOFDMSingleTone 0x40000000
-/* define bRxPath1 0x01 */
-/* define bRxPath2 0x02 */
-/* define bRxPath3 0x04 */
-/* define bRxPath4 0x08 */
-/* define bTxPath1 0x10 */
-/* define bTxPath2 0x20 */
-#define bHTDetect 0x100
-#define bCFOEn 0x10000
-#define bCFOValue 0xfff00000
-#define bSigTone_Re 0x3f
-#define bSigTone_Im 0x7f00
-#define bCounter_CCA 0xffff
-#define bCounter_ParityFail 0xffff0000
-#define bCounter_RateIllegal 0xffff
-#define bCounter_CRC8Fail 0xffff0000
-#define bCounter_MCSNoSupport 0xffff
-#define bCounter_FastSync 0xffff
-#define bShortCFO 0xfff
-#define bShortCFOTLength 12 /* total */
-#define bShortCFOFLength 11 /* fraction */
-#define bLongCFO 0x7ff
-#define bLongCFOTLength 11
-#define bLongCFOFLength 11
-#define bTailCFO 0x1fff
-#define bTailCFOTLength 13
-#define bTailCFOFLength 12
-#define bmax_en_pwdB 0xffff
-#define bCC_power_dB 0xffff0000
-#define bnoise_pwdB 0xffff
-#define bPowerMeasTLength 10
-#define bPowerMeasFLength 3
-#define bRx_HT_BW 0x1
-#define bRxSC 0x6
-#define bRx_HT 0x8
-#define bNB_intf_det_on 0x1
-#define bIntf_win_len_cfg 0x30
-#define bNB_Intf_TH_cfg 0x1c0
-#define bRFGain 0x3f
-#define bTableSel 0x40
-#define bTRSW 0x80
-#define bRxSNR_A 0xff
-#define bRxSNR_B 0xff00
-#define bRxSNR_C 0xff0000
-#define bRxSNR_D 0xff000000
-#define bSNREVMTLength 8
-#define bSNREVMFLength 1
-#define bCSI1st 0xff
-#define bCSI2nd 0xff00
-#define bRxEVM1st 0xff0000
-#define bRxEVM2nd 0xff000000
-#define bSIGEVM 0xff
-#define bPWDB 0xff00
-#define bSGIEN 0x10000
-
-#define bSFactorQAM1 0xf /* Useless */
-#define bSFactorQAM2 0xf0
-#define bSFactorQAM3 0xf00
-#define bSFactorQAM4 0xf000
-#define bSFactorQAM5 0xf0000
-#define bSFactorQAM6 0xf0000
-#define bSFactorQAM7 0xf00000
-#define bSFactorQAM8 0xf000000
-#define bSFactorQAM9 0xf0000000
-#define bCSIScheme 0x100000
-
-#define bNoiseLvlTopSet 0x3 /* Useless */
-#define bChSmooth 0x4
-#define bChSmoothCfg1 0x38
-#define bChSmoothCfg2 0x1c0
-#define bChSmoothCfg3 0xe00
-#define bChSmoothCfg4 0x7000
-#define bMRCMode 0x800000
-#define bTHEVMCfg 0x7000000
-
-#define bLoopFitType 0x1 /* Useless */
-#define bUpdCFO 0x40
-#define bUpdCFOOffData 0x80
-#define bAdvUpdCFO 0x100
-#define bAdvTimeCtrl 0x800
-#define bUpdClko 0x1000
-#define bFC 0x6000
-#define bTrackingMode 0x8000
-#define bPhCmpEnable 0x10000
-#define bUpdClkoLTF 0x20000
-#define bComChCFO 0x40000
-#define bCSIEstiMode 0x80000
-#define bAdvUpdEqz 0x100000
-#define bUChCfg 0x7000000
-#define bUpdEqz 0x8000000
-
-/* Rx Pseduo noise */
-#define bRxPesudoNoiseOn 0x20000000 /* Useless */
-#define bRxPesudoNoise_A 0xff
-#define bRxPesudoNoise_B 0xff00
-#define bRxPesudoNoise_C 0xff0000
-#define bRxPesudoNoise_D 0xff000000
-#define bPesudoNoiseState_A 0xffff
-#define bPesudoNoiseState_B 0xffff0000
-#define bPesudoNoiseState_C 0xffff
-#define bPesudoNoiseState_D 0xffff0000
-
-/* 7. RF Register */
-/* Zebra1 */
-#define bZebra1_HSSIEnable 0x8 /* Useless */
-#define bZebra1_TRxControl 0xc00
-#define bZebra1_TRxGainSetting 0x07f
-#define bZebra1_RxCorner 0xc00
-#define bZebra1_TxChargePump 0x38
-#define bZebra1_RxChargePump 0x7
-#define bZebra1_ChannelNum 0xf80
-#define bZebra1_TxLPFBW 0x400
-#define bZebra1_RxLPFBW 0x600
-
-/* Zebra4 */
-#define bRTL8256RegModeCtrl1 0x100 /* Useless */
-#define bRTL8256RegModeCtrl0 0x40
-#define bRTL8256_TxLPFBW 0x18
-#define bRTL8256_RxLPFBW 0x600
-
-/* RTL8258 */
-#define bRTL8258_TxLPFBW 0xc /* Useless */
-#define bRTL8258_RxLPFBW 0xc00
-#define bRTL8258_RSSILPFBW 0xc0
-
-
-/* Other Definition */
-
-/* byte endable for sb_write */
-#define bByte0 0x1 /* Useless */
-#define bByte1 0x2
-#define bByte2 0x4
-#define bByte3 0x8
-#define bWord0 0x3
-#define bWord1 0xc
-#define bDWord 0xf
-
-/* for PutRegsetting & GetRegSetting BitMask */
-#define bMaskByte0 0xff /* Reg 0xc50 rOFDM0_XAAGCCore~0xC6f */
-#define bMaskByte1 0xff00
-#define bMaskByte2 0xff0000
-#define bMaskByte3 0xff000000
-#define bMaskHWord 0xffff0000
-#define bMaskLWord 0x0000ffff
-#define bMaskDWord 0xffffffff
-#define bMask12Bits 0xfff
-#define bMaskH4Bits 0xf0000000
-#define bMaskOFDM_D 0xffc00000
-#define bMaskCCK 0x3f3f3f3f
-
-/* for PutRFRegsetting & GetRFRegSetting BitMask */
-#define bRFRegOffsetMask 0xfffff
-
-#define bDisable 0x0
-
-#define LeftAntenna 0x0 /* Useless */
-#define RightAntenna 0x1
-
-#define tCheckTxStatus 500 /* 500ms Useless */
-#define tUpdateRxCounter 100 /* 100ms */
-
-#define rateCCK 0 /* Useless */
-#define rateOFDM 1
-#define rateHT 2
-
-/* define Register-End */
-#define bPMAC_End 0x1ff /* Useless */
-#define bFPGAPHY0_End 0x8ff
-#define bFPGAPHY1_End 0x9ff
-#define bCCKPHY0_End 0xaff
-#define bOFDMPHY0_End 0xcff
-#define bOFDMPHY1_End 0xdff
-
-/* define max debug item in each debug page */
-/* define bMaxItem_FPGA_PHY0 0x9 */
-/* define bMaxItem_FPGA_PHY1 0x3 */
-/* define bMaxItem_PHY_11B 0x16 */
-/* define bMaxItem_OFDM_PHY0 0x29 */
-/* define bMaxItem_OFDM_PHY1 0x0 */
-
-#define bPMACControl 0x0 /* Useless */
-#define bWMACControl 0x1
-#define bWNICControl 0x2
-
-#define PathA 0x0 /* Useless */
-#define PathB 0x1
-#define PathC 0x2
-#define PathD 0x3
-
-/* PageB(0xB00) */
-#define rPdp_AntA 0xb00
-#define rPdp_AntA_4 0xb04
-#define rPdp_AntA_8 0xb08
-#define rPdp_AntA_C 0xb0c
-#define rPdp_AntA_18 0xb18
-#define rPdp_AntA_1C 0xb1c
-#define rPdp_AntA_20 0xb20
-#define rPdp_AntA_24 0xb24
-
-#define rConfig_Pmpd_AntA 0xb28
-#define rConfig_ram64x16 0xb2c
-
-#define rBndA 0xb30
-#define rHssiPar 0xb34
-
-#define rConfig_AntA 0xb68
-#define rConfig_AntB 0xb6c
-
-#define rPdp_AntB 0xb70
-#define rPdp_AntB_4 0xb74
-#define rPdp_AntB_8 0xb78
-#define rPdp_AntB_C 0xb7c
-#define rPdp_AntB_10 0xb80
-#define rPdp_AntB_14 0xb84
-#define rPdp_AntB_18 0xb88
-#define rPdp_AntB_1C 0xb8c
-#define rPdp_AntB_20 0xb90
-#define rPdp_AntB_24 0xb94
-
-#define rConfig_Pmpd_AntB 0xb98
-
-#define rBndB 0xba0
-
-#define rAPK 0xbd8
-#define rPm_Rx0_AntA 0xbdc
-#define rPm_Rx1_AntA 0xbe0
-#define rPm_Rx2_AntA 0xbe4
-#define rPm_Rx3_AntA 0xbe8
-#define rPm_Rx0_AntB 0xbec
-#define rPm_Rx1_AntB 0xbf0
-#define rPm_Rx2_AntB 0xbf4
-#define rPm_Rx3_AntB 0xbf8
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/Hal8723PwrSeq.h b/drivers/staging/rtl8723au/include/Hal8723PwrSeq.h
deleted file mode 100644
index 3771d6bb5774..000000000000
--- a/drivers/staging/rtl8723au/include/Hal8723PwrSeq.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef __HAL8723PWRSEQ_H__
-#define __HAL8723PWRSEQ_H__
-/*
- Check document WM-20110607-Paul-RTL8723A_Power_Architecture-R02.vsd
- There are 6 HW Power States:
- 0: POFF--Power Off
- 1: PDN--Power Down
- 2: CARDEMU--Card Emulation
- 3: ACT--Active Mode
- 4: LPS--Low Power State
- 5: SUS--Suspend
-
- The transision from different states are defined below
- TRANS_CARDEMU_TO_ACT
- TRANS_ACT_TO_CARDEMU
- TRANS_CARDEMU_TO_SUS
- TRANS_SUS_TO_CARDEMU
- TRANS_CARDEMU_TO_PDN
- TRANS_ACT_TO_LPS
- TRANS_LPS_TO_ACT
-
- TRANS_END
-*/
-#include "HalPwrSeqCmd.h"
-#include "rtl8723a_spec.h"
-
-#define RTL8723A_TRANS_CARDEMU_TO_ACT_STEPS 15
-#define RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS 15
-#define RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS 15
-#define RTL8723A_TRANS_SUS_TO_CARDEMU_STEPS 15
-#define RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS 15
-#define RTL8723A_TRANS_PDN_TO_CARDEMU_STEPS 15
-#define RTL8723A_TRANS_ACT_TO_LPS_STEPS 15
-#define RTL8723A_TRANS_LPS_TO_ACT_STEPS 15
-#define RTL8723A_TRANS_END_STEPS 1
-
-
-/* format
- * { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, comments here
- */
-#define RTL8723A_TRANS_CARDEMU_TO_ACT \
- {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/ \
- {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*0x67[0] = 0 to disable BT_GPS_SEL pins*/ \
- {0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS},/*Delay 1ms*/ \
- {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), 0}, /*0x00[5] = 1b'0 release analog Ips to digital , 1:isolation*/ \
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), 0},/* disable SW LPS 0x04[10]= 0*/ \
- {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)},/* wait till 0x04[17] = 1 power ready*/ \
- {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)},/* release WLON reset 0x04[16]= 1*/ \
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},/* disable HWPDN 0x04[15]= 0*/ \
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)), 0},/* disable WL suspend*/ \
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)},/* polling until return 0*/ \
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0},/**/ \
- {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 1},/*0x4C[23] = 0x4E[7] = 1, switch DPDT_SEL_P output from WL BB */\
-
-#define RTL8723A_TRANS_ACT_TO_CARDEMU \
- {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},/*0x1F[7:0] = 0 turn off RF*/ \
- {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},/*0x4C[23] = 0x4E[7] = 0, switch DPDT_SEL_P output from register 0x65[2] */\
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \
- {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)}, /*0x00[5] = 1b'1 analog Ips to digital , 1:isolation*/ \
- {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, /*0x20[0] = 1b'0 disable LDOA12 MACRO block*/ \
-
-
-#define RTL8723A_TRANS_CARDEMU_TO_SUS \
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/
-
-#define RTL8723A_TRANS_SUS_TO_CARDEMU \
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, /*clear suspend enable and power down enable*/ \
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/
-
-#define RTL8723A_TRANS_CARDEMU_TO_CARDDIS \
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \
- {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*0x48[16] = 1 to enable GPIO9 as EXT WAKEUP*/
-
-#define RTL8723A_TRANS_CARDDIS_TO_CARDEMU \
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, /*clear suspend enable and power down enable*/ \
- {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/ \
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/
-
-#define RTL8723A_TRANS_CARDEMU_TO_PDN \
- {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/ \
- {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},/* 0x04[16] = 0*/\
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)},/* 0x04[15] = 1*/
-
-#define RTL8723A_TRANS_PDN_TO_CARDEMU \
- {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},/* 0x04[15] = 0*/
-
-#define RTL8723A_TRANS_ACT_TO_LPS \
- {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/ \
- {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \
- {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \
- {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \
- {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \
- {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},/*CCK and OFDM are disabled, and clock are gated*/ \
- {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \
- {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},/*Whole BB is reset*/ \
- {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/ \
- {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},/*check if removed later*/ \
- {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)},/*Respond TxOK to scheduler*/
-
-#define RTL8723A_TRANS_LPS_TO_ACT \
- {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\
- {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\
- {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*. 0x08[4] = 0 switch TSF to 40M*/\
- {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, /*Polling 0x109[7]= 0 TSF in 40M*/\
- {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0}, /*. 0x29[7:6] = 2b'00 enable BB clock*/\
- {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, /*. 0x101[1] = 1*/\
- {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\
- {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1)|BIT(0), BIT(1)|BIT(0)}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\
- {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/
-
-#define RTL8723A_TRANS_END \
- {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, 0, PWR_CMD_END, 0, 0},
-
-
-extern struct wlan_pwr_cfg rtl8723AU_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STEPS+RTL8723A_TRANS_END_STEPS];
-extern struct wlan_pwr_cfg rtl8723AU_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_END_STEPS];
-extern struct wlan_pwr_cfg rtl8723AU_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723A_TRANS_END_STEPS];
-extern struct wlan_pwr_cfg rtl8723AU_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723A_TRANS_END_STEPS];
-extern struct wlan_pwr_cfg rtl8723AU_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8723A_TRANS_END_STEPS];
-extern struct wlan_pwr_cfg rtl8723AU_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8723A_TRANS_END_STEPS];
-extern struct wlan_pwr_cfg rtl8723AU_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723A_TRANS_END_STEPS];
-extern struct wlan_pwr_cfg rtl8723AU_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STEPS+RTL8723A_TRANS_END_STEPS];
-extern struct wlan_pwr_cfg rtl8723AU_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STEPS+RTL8723A_TRANS_END_STEPS];
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/Hal8723UHWImg_CE.h b/drivers/staging/rtl8723au/include/Hal8723UHWImg_CE.h
deleted file mode 100644
index c834b3a738d7..000000000000
--- a/drivers/staging/rtl8723au/include/Hal8723UHWImg_CE.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __INC_HAL8723U_FW_IMG_H
-#define __INC_HAL8723U_FW_IMG_H
-
-/*Created on 2013/01/14, 15:51*/
-
-/* FW v16 enable usb interrupt */
-#define Rtl8723UImgArrayLength 22172
-extern u8 Rtl8723UFwImgArray[Rtl8723UImgArrayLength];
-#define Rtl8723UBTImgArrayLength 1
-extern u8 Rtl8723UFwBTImgArray[Rtl8723UBTImgArrayLength];
-
-#define Rtl8723UUMCBCutImgArrayWithBTLength 24118
-#define Rtl8723UUMCBCutImgArrayWithoutBTLength 19200
-
-extern u8 Rtl8723UFwUMCBCutImgArrayWithBT[Rtl8723UUMCBCutImgArrayWithBTLength];
-extern u8 Rtl8723UFwUMCBCutImgArrayWithoutBT[Rtl8723UUMCBCutImgArrayWithoutBTLength];
-
-#define Rtl8723SUMCBCutMPImgArrayLength 24174
-extern const u8 Rtl8723SFwUMCBCutMPImgArray[Rtl8723SUMCBCutMPImgArrayLength];
-
-#define Rtl8723EBTImgArrayLength 15276
-extern u8 Rtl8723EFwBTImgArray[Rtl8723EBTImgArrayLength];
-
-#define Rtl8723UPHY_REG_Array_PGLength 336
-extern u32 Rtl8723UPHY_REG_Array_PG[Rtl8723UPHY_REG_Array_PGLength];
-#define Rtl8723UMACPHY_Array_PGLength 1
-extern u32 Rtl8723UMACPHY_Array_PG[Rtl8723UMACPHY_Array_PGLength];
-
-#endif /* ifndef __INC_HAL8723U_FW_IMG_H */
diff --git a/drivers/staging/rtl8723au/include/HalDMOutSrc8723A.h b/drivers/staging/rtl8723au/include/HalDMOutSrc8723A.h
deleted file mode 100644
index d7651f7a665b..000000000000
--- a/drivers/staging/rtl8723au/include/HalDMOutSrc8723A.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- *
- ******************************************************************************/
-#ifndef __RTL8723A_ODM_H__
-#define __RTL8723A_ODM_H__
-/* */
-
-#define RSSI_CCK 0
-#define RSSI_OFDM 1
-#define RSSI_DEFAULT 2
-
-#define IQK_MAC_REG_NUM 4
-#define IQK_ADDA_REG_NUM 16
-#define IQK_BB_REG_NUM 9
-#define HP_THERMAL_NUM 8
-
-
-/* */
-/* structure and define */
-/* */
-
-
-
-
-/*------------------------Export global variable----------------------------*/
-/*------------------------Export global variable----------------------------*/
-/*------------------------Export Marco Definition---------------------------*/
-/* define DM_MultiSTA_InitGainChangeNotify(Event) {DM_DigTable.CurMultiSTAConnectState = Event;} */
-
-
-/* */
-/* function prototype */
-/* */
-
-/* */
-/* IQ calibrate */
-/* */
-void rtl8723a_phy_iq_calibrate(struct rtw_adapter *pAdapter, bool bReCovery);
-
-/* */
-/* LC calibrate */
-/* */
-void rtl8723a_phy_lc_calibrate(struct rtw_adapter *pAdapter);
-
-/* */
-/* AP calibrate */
-/* */
-void rtl8723a_phy_ap_calibrate(struct rtw_adapter *pAdapter, char delta);
-
-void rtl8723a_odm_check_tx_power_tracking(struct rtw_adapter *Adapter);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/HalHWImg8723A_BB.h b/drivers/staging/rtl8723au/include/HalHWImg8723A_BB.h
deleted file mode 100644
index 127609404652..000000000000
--- a/drivers/staging/rtl8723au/include/HalHWImg8723A_BB.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/******************************************************************************
-*
-* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of version 2 of the GNU General Public License 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.
-*
-*
-******************************************************************************/
-
-#ifndef __INC_BB_8723A_HW_IMG_H
-#define __INC_BB_8723A_HW_IMG_H
-
-/******************************************************************************
-* AGC_TAB_1T.TXT
-******************************************************************************/
-
-void ODM_ReadAndConfig_AGC_TAB_1T_8723A(struct dm_odm_t *pDM_Odm);
-
-/******************************************************************************
-* PHY_REG_1T.TXT
-******************************************************************************/
-
-void ODM_ReadAndConfig_PHY_REG_1T_8723A(struct dm_odm_t *pDM_Odm);
-
-/******************************************************************************
-* PHY_REG_MP.TXT
-******************************************************************************/
-
-void ODM_ReadAndConfig_PHY_REG_MP_8723A(struct dm_odm_t *pDM_Odm);
-
-#endif /* end of HWIMG_SUPPORT */
diff --git a/drivers/staging/rtl8723au/include/HalHWImg8723A_FW.h b/drivers/staging/rtl8723au/include/HalHWImg8723A_FW.h
deleted file mode 100644
index 7ee363b99b49..000000000000
--- a/drivers/staging/rtl8723au/include/HalHWImg8723A_FW.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/******************************************************************************
-*
-* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of version 2 of the GNU General Public License 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.
-*
-*
-******************************************************************************/
-
-#ifndef __INC_FW_8723A_HW_IMG_H
-#define __INC_FW_8723A_HW_IMG_H
-
-
-/******************************************************************************
-* rtl8723fw_B.TXT
-******************************************************************************/
-
-void ODM_ReadFirmware_8723A_rtl8723fw_B(struct dm_odm_t *pDM_Odm,
- u8 *pFirmware, u32 *pFirmwareSize);
-
-#endif /* end of HWIMG_SUPPORT */
diff --git a/drivers/staging/rtl8723au/include/HalHWImg8723A_MAC.h b/drivers/staging/rtl8723au/include/HalHWImg8723A_MAC.h
deleted file mode 100644
index 201be1f87292..000000000000
--- a/drivers/staging/rtl8723au/include/HalHWImg8723A_MAC.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/******************************************************************************
-*
-* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of version 2 of the GNU General Public License 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.
-*
-*
-******************************************************************************/
-
-#ifndef __INC_MAC_8723A_HW_IMG_H
-#define __INC_MAC_8723A_HW_IMG_H
-
-/******************************************************************************
-* MAC_REG.TXT
-******************************************************************************/
-
-void ODM_ReadAndConfig_MAC_REG_8723A(struct dm_odm_t *pDM_Odm);
-
-#endif /* end of HWIMG_SUPPORT */
diff --git a/drivers/staging/rtl8723au/include/HalHWImg8723A_RF.h b/drivers/staging/rtl8723au/include/HalHWImg8723A_RF.h
deleted file mode 100644
index c9af1c375339..000000000000
--- a/drivers/staging/rtl8723au/include/HalHWImg8723A_RF.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/******************************************************************************
-*
-* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of version 2 of the GNU General Public License 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.
-*
-******************************************************************************/
-
-#ifndef __INC_RF_8723A_HW_IMG_H
-#define __INC_RF_8723A_HW_IMG_H
-
-/******************************************************************************
-* RadioA_1T.TXT
-******************************************************************************/
-
-void ODM_ReadAndConfig_RadioA_1T_8723A(struct dm_odm_t *pDM_Odm);
-
-#endif /* end of HWIMG_SUPPORT */
diff --git a/drivers/staging/rtl8723au/include/HalPwrSeqCmd.h b/drivers/staging/rtl8723au/include/HalPwrSeqCmd.h
deleted file mode 100644
index 12e03a36f2d3..000000000000
--- a/drivers/staging/rtl8723au/include/HalPwrSeqCmd.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- *
- ******************************************************************************/
-#ifndef __HALPWRSEQCMD_H__
-#define __HALPWRSEQCMD_H__
-
-#include <drv_types.h>
-
-/*---------------------------------------------*/
-/*---------------------------------------------*/
-#define PWR_CMD_READ 0x00
- /* offset: the read register offset */
- /* msk: the mask of the read value */
- /* value: N/A, left by 0 */
- /* note: dirver shall implement this function by read & msk */
-
-#define PWR_CMD_WRITE 0x01
- /* offset: the read register offset */
- /* msk: the mask of the write bits */
- /* value: write value */
- /* note: driver shall implement this cmd by read & msk after write */
-
-#define PWR_CMD_POLLING 0x02
- /* offset: the read register offset */
- /* msk: the mask of the polled value */
- /* value: the value to be polled, masked by the msd field. */
- /* note: driver shall implement this cmd by */
- /* do{ */
- /* if( (Read(offset) & msk) == (value & msk) ) */
- /* break; */
- /* } while(not timeout); */
-
-#define PWR_CMD_DELAY 0x03
- /* offset: the value to delay */
- /* msk: N/A */
- /* value: the unit of delay, 0: us, 1: ms */
-
-#define PWR_CMD_END 0x04
- /* offset: N/A */
- /* msk: N/A */
- /* value: N/A */
-
-/*---------------------------------------------*/
-/* 3 The value of base: 4 bits */
-/*---------------------------------------------*/
- /* define the base address of each block */
-#define PWR_BASEADDR_MAC 0x00
-#define PWR_BASEADDR_USB 0x01
-#define PWR_BASEADDR_PCIE 0x02
-#define PWR_BASEADDR_SDIO 0x03
-
-/*---------------------------------------------*/
-/* 3 The value of interface_msk: 4 bits */
-/*---------------------------------------------*/
-#define PWR_INTF_SDIO_MSK BIT(0)
-#define PWR_INTF_USB_MSK BIT(1)
-#define PWR_INTF_PCI_MSK BIT(2)
-#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3))
-
-/*---------------------------------------------*/
-/* 3 The value of fab_msk: 4 bits */
-/*---------------------------------------------*/
-#define PWR_FAB_TSMC_MSK BIT(0)
-#define PWR_FAB_UMC_MSK BIT(1)
-#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3))
-
-/*---------------------------------------------*/
-/* 3 The value of cut_msk: 8 bits */
-/*---------------------------------------------*/
-#define PWR_CUT_TESTCHIP_MSK BIT(0)
-#define PWR_CUT_A_MSK BIT(1)
-#define PWR_CUT_B_MSK BIT(2)
-#define PWR_CUT_C_MSK BIT(3)
-#define PWR_CUT_D_MSK BIT(4)
-#define PWR_CUT_E_MSK BIT(5)
-#define PWR_CUT_F_MSK BIT(6)
-#define PWR_CUT_G_MSK BIT(7)
-#define PWR_CUT_ALL_MSK 0xFF
-
-
-enum pwrseq_delay_unit {
- PWRSEQ_DELAY_US,
- PWRSEQ_DELAY_MS,
-};
-
-struct wlan_pwr_cfg {
- u16 offset;
- u8 cut_msk;
- u8 fab_msk:4;
- u8 interface_msk:4;
- u8 base:4;
- u8 cmd:4;
- u8 msk;
- u8 value;
-};
-
-
-#define GET_PWR_CFG_OFFSET(__PWR_CMD) __PWR_CMD.offset
-#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) __PWR_CMD.cut_msk
-#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) __PWR_CMD.fab_msk
-#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) __PWR_CMD.interface_msk
-#define GET_PWR_CFG_BASE(__PWR_CMD) __PWR_CMD.base
-#define GET_PWR_CFG_CMD(__PWR_CMD) __PWR_CMD.cmd
-#define GET_PWR_CFG_MASK(__PWR_CMD) __PWR_CMD.msk
-#define GET_PWR_CFG_VALUE(__PWR_CMD) __PWR_CMD.value
-
-
-/* */
-/* Prototype of protected function. */
-/* */
-u8 HalPwrSeqCmdParsing23a(
- struct rtw_adapter *padapter,
- u8 CutVersion,
- u8 FabVersion,
- u8 InterfaceType,
- struct wlan_pwr_cfg PwrCfgCmd[]);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/HalVerDef.h b/drivers/staging/rtl8723au/include/HalVerDef.h
deleted file mode 100644
index 2a0e4ea7afad..000000000000
--- a/drivers/staging/rtl8723au/include/HalVerDef.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __HAL_VERSION_DEF_H__
-#define __HAL_VERSION_DEF_H__
-
-enum hal_ic_type {
- CHIP_8192S = 0,
- CHIP_8188C = 1,
- CHIP_8192C = 2,
- CHIP_8192D = 3,
- CHIP_8723A = 4,
- CHIP_8188E = 5,
- CHIP_8881A = 6,
- CHIP_8812A = 7,
- CHIP_8821A = 8,
- CHIP_8723B = 9,
- CHIP_8192E = 10,
-};
-
-enum hal_chip_type {
- TEST_CHIP = 0,
- NORMAL_CHIP = 1,
- FPGA = 2,
-};
-
-enum hal_cut_version {
- A_CUT_VERSION = 0,
- B_CUT_VERSION = 1,
- C_CUT_VERSION = 2,
- D_CUT_VERSION = 3,
- E_CUT_VERSION = 4,
- F_CUT_VERSION = 5,
- G_CUT_VERSION = 6,
-};
-
-/* HAL_Manufacturer */
-enum hal_vendor {
- CHIP_VENDOR_TSMC = 0,
- CHIP_VENDOR_UMC = 1,
-};
-
-struct hal_version {
- enum hal_ic_type ICType;
- enum hal_chip_type ChipType;
- enum hal_cut_version CUTVersion;
- enum hal_vendor VendorType;
- u8 ROMVer;
-};
-
-/* Get element */
-#define GET_CVID_IC_TYPE(version) ((version).ICType)
-#define GET_CVID_CHIP_TYPE(version) ((version).ChipType)
-#define GET_CVID_MANUFACTUER(version) ((version).VendorType)
-#define GET_CVID_CUT_VERSION(version) ((version).CUTVersion)
-#define GET_CVID_ROM_VERSION(version) (((version).ROMVer) & ROM_VERSION_MASK)
-
-/* Common Macro. -- */
-
-#define IS_81XXC(version) \
- (((GET_CVID_IC_TYPE(version) == CHIP_8192C) || \
- (GET_CVID_IC_TYPE(version) == CHIP_8188C)) ? true : false)
-#define IS_8723_SERIES(version) \
- ((GET_CVID_IC_TYPE(version) == CHIP_8723A) ? true : false)
-
-#define IS_TEST_CHIP(version) \
- ((GET_CVID_CHIP_TYPE(version) == TEST_CHIP) ? true : false)
-#define IS_NORMAL_CHIP(version) \
- ((GET_CVID_CHIP_TYPE(version) == NORMAL_CHIP) ? true : false)
-
-#define IS_A_CUT(version) \
- ((GET_CVID_CUT_VERSION(version) == A_CUT_VERSION) ? true : false)
-#define IS_B_CUT(version) \
- ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? true : false)
-#define IS_C_CUT(version) \
- ((GET_CVID_CUT_VERSION(version) == C_CUT_VERSION) ? true : false)
-#define IS_D_CUT(version) \
- ((GET_CVID_CUT_VERSION(version) == D_CUT_VERSION) ? true : false)
-#define IS_E_CUT(version) \
- ((GET_CVID_CUT_VERSION(version) == E_CUT_VERSION) ? true : false)
-
-#define IS_CHIP_VENDOR_TSMC(version) \
- ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_TSMC) ? true : false)
-#define IS_CHIP_VENDOR_UMC(version) \
- ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_UMC) ? true : false)
-
-/* Chip version Macro. -- */
-
-#define IS_81xxC_VENDOR_UMC_A_CUT(version) \
- (IS_81XXC(version)?(IS_CHIP_VENDOR_UMC(version) ? \
- (IS_A_CUT(version) ? true : false) : false) : false)
-#define IS_81xxC_VENDOR_UMC_B_CUT(version) \
- (IS_81XXC(version) ? (IS_CHIP_VENDOR_UMC(version) ? \
- (IS_B_CUT(version) ? true : false) : false): false)
-#define IS_81xxC_VENDOR_UMC_C_CUT(version) \
- (IS_81XXC(version)?(IS_CHIP_VENDOR_UMC(version) ? \
- (IS_C_CUT(version) ? true : false) : false) : false)
-#define IS_8723A_A_CUT(version) \
- ((IS_8723_SERIES(version)) ? (IS_A_CUT(version) ? true : false) : false)
-#define IS_8723A_B_CUT(version) \
- ((IS_8723_SERIES(version)) ? (IS_B_CUT(version) ? true : false) : false)
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/drv_types.h b/drivers/staging/rtl8723au/include/drv_types.h
deleted file mode 100644
index e83463aeb9b1..000000000000
--- a/drivers/staging/rtl8723au/include/drv_types.h
+++ /dev/null
@@ -1,274 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-/*-----------------------------------------------------------------------------
-
- For type defines and data structure defines
-
-------------------------------------------------------------------------------*/
-
-
-#ifndef __DRV_TYPES_H__
-#define __DRV_TYPES_H__
-
-#include <osdep_service.h>
-#include <wlan_bssdef.h>
-
-
-enum _NIC_VERSION {
- RTL8711_NIC,
- RTL8712_NIC,
- RTL8713_NIC,
- RTL8716_NIC
-
-};
-
-
-#include <rtw_ht.h>
-
-#include <rtw_cmd.h>
-#include <rtw_xmit.h>
-#include <rtw_recv.h>
-#include <hal_intf.h>
-#include <hal_com.h>
-#include <rtw_security.h>
-#include <rtw_pwrctrl.h>
-#include <rtw_io.h>
-#include <rtw_eeprom.h>
-#include <sta_info.h>
-#include <rtw_mlme.h>
-#include <rtw_debug.h>
-#include <rtw_rf.h>
-#include <rtw_event.h>
-#include <rtw_mlme_ext.h>
-#include <rtw_ap.h>
-
-#include "ioctl_cfg80211.h"
-
-struct registry_priv {
- u8 chip_version;
- u8 rfintfs;
- struct cfg80211_ssid ssid;
- u8 channel;/* ad-hoc support requirement */
- u8 wireless_mode;/* A, B, G, auto */
- u8 scan_mode;/* active, passive */
- u8 preamble;/* long, short, auto */
- u8 vrtl_carrier_sense;/* Enable, Disable, Auto */
- u8 vcs_type;/* RTS/CTS, CTS-to-self */
- u16 rts_thresh;
- u16 frag_thresh;
- u8 adhoc_tx_pwr;
- u8 soft_ap;
- u8 power_mgnt;
- u8 ips_mode;
- u8 smart_ps;
- u8 long_retry_lmt;
- u8 short_retry_lmt;
- u16 busy_thresh;
- u8 ack_policy;
- u8 software_encrypt;
- u8 software_decrypt;
- u8 acm_method;
- /* UAPSD */
- u8 wmm_enable;
- u8 uapsd_enable;
-
- struct wlan_bssid_ex dev_network;
-
- u8 ht_enable;
- u8 cbw40_enable;
- u8 ampdu_enable;/* for tx */
- u8 rx_stbc;
- u8 ampdu_amsdu;/* A-MPDU Supports A-MSDU is permitted */
- u8 lowrate_two_xmit;
-
- u8 rf_config;
- u8 low_power;
-
- u8 wifi_spec;/* !turbo_mode */
-
- u8 channel_plan;
-#ifdef CONFIG_8723AU_BT_COEXIST
- u8 btcoex;
- u8 bt_iso;
- u8 bt_sco;
- u8 bt_ampdu;
-#endif
- bool bAcceptAddbaReq;
-
- u8 antdiv_cfg;
- u8 antdiv_type;
-
- u8 hwpdn_mode;/* 0:disable,1:enable,2:decide by EFUSE config */
- u8 hwpwrp_detect;/* 0:disable,1:enable */
-
- u8 hw_wps_pbc;/* 0:disable,1:enable */
-
- u8 max_roaming_times; /* max number driver will try to roaming */
-
- u8 enable80211d;
-
- u8 ifname[16];
- u8 if2name[16];
-
- u8 notch_filter;
-
- u8 regulatory_tid;
-};
-
-
-#define MAX_CONTINUAL_URB_ERR 4
-
-#define GET_PRIMARY_ADAPTER(padapter) \
- (((struct rtw_adapter *)padapter)->dvobj->if1)
-
-enum _IFACE_ID {
- IFACE_ID0, /* maping to PRIMARY_ADAPTER */
- IFACE_ID1, /* maping to SECONDARY_ADAPTER */
- IFACE_ID2,
- IFACE_ID3,
- IFACE_ID_MAX,
-};
-
-struct dvobj_priv {
- struct rtw_adapter *if1; /* PRIMARY_ADAPTER */
- struct rtw_adapter *if2; /* SECONDARY_ADAPTER */
-
- /* for local/global synchronization */
- struct mutex hw_init_mutex;
- struct mutex h2c_fwcmd_mutex;
- struct mutex setch_mutex;
- struct mutex setbw_mutex;
-
- unsigned char oper_channel; /* saved chan info when set chan bw */
- unsigned char oper_bwmode;
- unsigned char oper_ch_offset;/* PRIME_CHNL_OFFSET */
-
- struct rtw_adapter *padapters[IFACE_ID_MAX];
- u8 iface_nums; /* total number of ifaces used runtime */
-
- /* For 92D, DMDP have 2 interface. */
- u8 InterfaceNumber;
- u8 NumInterfaces;
-
- /* In /Out Pipe information */
- int RtInPipe[2];
- int RtOutPipe[3];
- u8 Queue2Pipe[HW_QUEUE_ENTRY];/* for out pipe mapping */
-
-/*-------- below is for USB INTERFACE --------*/
-
- u8 nr_endpoint;
- u8 ishighspeed;
- u8 RtNumInPipes;
- u8 RtNumOutPipes;
- int ep_num[5]; /* endpoint number */
-
- struct mutex usb_vendor_req_mutex;
-
- union {
- __le32 val32;
- __le16 val16;
- u8 val8;
- } usb_buf;
-
- struct usb_interface *pusbintf;
- struct usb_device *pusbdev;
- atomic_t continual_urb_error;
-
-/*-------- below is for PCIE INTERFACE --------*/
-
-};
-
-static inline struct device *dvobj_to_dev(struct dvobj_priv *dvobj)
-{
- /* todo: get interface type from dvobj and the return the dev accordingly */
- return &dvobj->pusbintf->dev;
-}
-
-enum _IFACE_TYPE {
- IFACE_PORT0, /* mapping to port0 for C/D series chips */
- IFACE_PORT1, /* mapping to port1 for C/D series chip */
- MAX_IFACE_PORT,
-};
-
-enum _ADAPTER_TYPE {
- PRIMARY_ADAPTER,
- SECONDARY_ADAPTER,
- MAX_ADAPTER,
-};
-
-struct rtw_adapter {
- int pid[3];/* process id from UI, 0:wps, 1:hostapd, 2:dhcpcd */
- int bDongle;/* build-in module or external dongle */
- u16 chip_type;
- u16 HardwareType;
-
- struct dvobj_priv *dvobj;
- struct mlme_priv mlmepriv;
- struct mlme_ext_priv mlmeextpriv;
- struct cmd_priv cmdpriv;
- struct evt_priv evtpriv;
- struct xmit_priv xmitpriv;
- struct recv_priv recvpriv;
- struct sta_priv stapriv;
- struct security_priv securitypriv;
- struct registry_priv registrypriv;
- struct pwrctrl_priv pwrctrlpriv;
- struct eeprom_priv eeprompriv;
-
- u32 setband;
-
- void *HalData;
-
- s32 bDriverStopped;
- s32 bSurpriseRemoved;
- s32 bCardDisableWOHSM;
-
- u32 IsrContent;
- u32 ImrContent;
-
- u8 EepromAddressSize;
- u8 hw_init_completed;
- u8 bDriverIsGoingToUnload;
- u8 init_adpt_in_progress;
- u8 bHaltInProgress;
-
- struct net_device *pnetdev;
-
- /* used by rtw_rereg_nd_name related function */
- int bup;
- struct net_device_stats stats;
-
- struct wireless_dev *rtw_wdev;
- int net_closed;
-
- u8 bFWReady;
- u8 bReadPortCancel;
- u8 bWritePortCancel;
-
- /* extend to support multi interface */
- /* IFACE_ID0 is equals to PRIMARY_ADAPTER */
- /* IFACE_ID1 is equals to SECONDARY_ADAPTER */
- u8 iface_id;
-};
-
-#define adapter_to_dvobj(adapter) (adapter->dvobj)
-
-static inline u8 *myid(struct eeprom_priv *peepriv)
-{
- return peepriv->mac_addr;
-}
-
-#endif /* __DRV_TYPES_H__ */
diff --git a/drivers/staging/rtl8723au/include/hal_com.h b/drivers/staging/rtl8723au/include/hal_com.h
deleted file mode 100644
index 9c50320b2100..000000000000
--- a/drivers/staging/rtl8723au/include/hal_com.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __HAL_COMMON_H__
-#define __HAL_COMMON_H__
-
-/* */
-/* Rate Definition */
-/* */
-/* CCK */
-#define RATR_1M 0x00000001
-#define RATR_2M 0x00000002
-#define RATR_55M 0x00000004
-#define RATR_11M 0x00000008
-/* OFDM */
-#define RATR_6M 0x00000010
-#define RATR_9M 0x00000020
-#define RATR_12M 0x00000040
-#define RATR_18M 0x00000080
-#define RATR_24M 0x00000100
-#define RATR_36M 0x00000200
-#define RATR_48M 0x00000400
-#define RATR_54M 0x00000800
-/* MCS 1 Spatial Stream */
-#define RATR_MCS0 0x00001000
-#define RATR_MCS1 0x00002000
-#define RATR_MCS2 0x00004000
-#define RATR_MCS3 0x00008000
-#define RATR_MCS4 0x00010000
-#define RATR_MCS5 0x00020000
-#define RATR_MCS6 0x00040000
-#define RATR_MCS7 0x00080000
-/* MCS 2 Spatial Stream */
-#define RATR_MCS8 0x00100000
-#define RATR_MCS9 0x00200000
-#define RATR_MCS10 0x00400000
-#define RATR_MCS11 0x00800000
-#define RATR_MCS12 0x01000000
-#define RATR_MCS13 0x02000000
-#define RATR_MCS14 0x04000000
-#define RATR_MCS15 0x08000000
-
-/* CCK */
-#define RATE_1M BIT(0)
-#define RATE_2M BIT(1)
-#define RATE_5_5M BIT(2)
-#define RATE_11M BIT(3)
-/* OFDM */
-#define RATE_6M BIT(4)
-#define RATE_9M BIT(5)
-#define RATE_12M BIT(6)
-#define RATE_18M BIT(7)
-#define RATE_24M BIT(8)
-#define RATE_36M BIT(9)
-#define RATE_48M BIT(10)
-#define RATE_54M BIT(11)
-
-/*------------------------------ Tx Desc definition Macro ------------------------*/
-/* pragma mark -- Tx Desc related definition. -- */
-/* */
-/* */
-/* Rate */
-/* */
-/* CCK Rates, TxHT = 0 */
-#define DESC_RATE1M 0x00
-#define DESC_RATE2M 0x01
-#define DESC_RATE5_5M 0x02
-#define DESC_RATE11M 0x03
-
-/* OFDM Rates, TxHT = 0 */
-#define DESC_RATE6M 0x04
-#define DESC_RATE9M 0x05
-#define DESC_RATE12M 0x06
-#define DESC_RATE18M 0x07
-#define DESC_RATE24M 0x08
-#define DESC_RATE36M 0x09
-#define DESC_RATE48M 0x0a
-#define DESC_RATE54M 0x0b
-
-/* MCS Rates, TxHT = 1 */
-#define DESC_RATEMCS0 0x0c
-#define DESC_RATEMCS1 0x0d
-#define DESC_RATEMCS2 0x0e
-#define DESC_RATEMCS3 0x0f
-#define DESC_RATEMCS4 0x10
-#define DESC_RATEMCS5 0x11
-#define DESC_RATEMCS6 0x12
-#define DESC_RATEMCS7 0x13
-#define DESC_RATEMCS8 0x14
-#define DESC_RATEMCS9 0x15
-#define DESC_RATEMCS10 0x16
-#define DESC_RATEMCS11 0x17
-#define DESC_RATEMCS12 0x18
-#define DESC_RATEMCS13 0x19
-#define DESC_RATEMCS14 0x1a
-#define DESC_RATEMCS15 0x1b
-#define DESC_RATEMCS15_SG 0x1c
-#define DESC_RATEMCS32 0x20
-
-#define REG_P2P_CTWIN 0x0572 /* 1 Byte long (in unit of TU) */
-#define REG_NOA_DESC_SEL 0x05CF
-#define REG_NOA_DESC_DURATION 0x05E0
-#define REG_NOA_DESC_INTERVAL 0x05E4
-#define REG_NOA_DESC_START 0x05E8
-#define REG_NOA_DESC_COUNT 0x05EC
-
-#include "HalVerDef.h"
-
-
-u8 /* return the final channel plan decision */
-hal_com_get_channel_plan23a(
- struct rtw_adapter *padapter,
- u8 hw_channel_plan, /* channel plan from HW (efuse/eeprom) */
- u8 sw_channel_plan, /* channel plan from SW (registry/module param) */
- u8 def_channel_plan, /* channel plan used when the former two is invalid */
- bool AutoLoadFail
- );
-
-u8 MRateToHwRate23a(u8 rate);
-
-void HalSetBrateCfg23a(struct rtw_adapter *padapter, u8 *mBratesOS);
-
-bool
-Hal_MappingOutPipe23a(struct rtw_adapter *pAdapter, u8 NumOutPipe);
-
-void c2h_evt_clear23a(struct rtw_adapter *adapter);
-s32 c2h_evt_read23a(struct rtw_adapter *adapter, u8 *buf);
-
-void rtl8723a_set_ampdu_min_space(struct rtw_adapter *padapter, u8 MinSpacingToSet);
-void rtl8723a_set_ampdu_factor(struct rtw_adapter *padapter, u8 FactorToSet);
-void rtl8723a_set_acm_ctrl(struct rtw_adapter *padapter, u8 ctrl);
-void rtl8723a_set_media_status(struct rtw_adapter *padapter, u8 status);
-void rtl8723a_set_media_status1(struct rtw_adapter *padapter, u8 status);
-void rtl8723a_set_bcn_func(struct rtw_adapter *padapter, u8 val);
-void rtl8723a_check_bssid(struct rtw_adapter *padapter, u8 val);
-void rtl8723a_mlme_sitesurvey(struct rtw_adapter *padapter, u8 flag);
-void rtl8723a_on_rcr_am(struct rtw_adapter *padapter);
-void rtl8723a_off_rcr_am(struct rtw_adapter *padapter);
-void rtl8723a_set_slot_time(struct rtw_adapter *padapter, u8 slottime);
-void rtl8723a_ack_preamble(struct rtw_adapter *padapter, u8 bShortPreamble);
-void rtl8723a_set_sec_cfg(struct rtw_adapter *padapter, u8 sec);
-void rtl8723a_cam_empty_entry(struct rtw_adapter *padapter, u8 ucIndex);
-void rtl8723a_cam_invalidate_all(struct rtw_adapter *padapter);
-void rtl8723a_cam_write(struct rtw_adapter *padapter,
- u8 entry, u16 ctrl, const u8 *mac, const u8 *key);
-void rtl8723a_fifo_cleanup(struct rtw_adapter *padapter);
-void rtl8723a_set_apfm_on_mac(struct rtw_adapter *padapter, u8 val);
-void rtl8723a_bcn_valid(struct rtw_adapter *padapter);
-bool rtl8723a_get_bcn_valid(struct rtw_adapter *padapter);
-void rtl8723a_set_beacon_interval(struct rtw_adapter *padapter, u16 interval);
-void rtl8723a_set_resp_sifs(struct rtw_adapter *padapter,
- u8 r2t1, u8 r2t2, u8 t2t1, u8 t2t2);
-void rtl8723a_set_ac_param_vo(struct rtw_adapter *padapter, u32 vo);
-void rtl8723a_set_ac_param_vi(struct rtw_adapter *padapter, u32 vi);
-void rtl8723a_set_ac_param_be(struct rtw_adapter *padapter, u32 be);
-void rtl8723a_set_ac_param_bk(struct rtw_adapter *padapter, u32 bk);
-void rtl8723a_set_rxdma_agg_pg_th(struct rtw_adapter *padapter, u8 val);
-void rtl8723a_set_initial_gain(struct rtw_adapter *padapter, u32 rx_gain);
-
-void rtl8723a_odm_support_ability_write(struct rtw_adapter *padapter, u32 val);
-void rtl8723a_odm_support_ability_backup(struct rtw_adapter *padapter);
-void rtl8723a_odm_support_ability_restore(struct rtw_adapter *padapter);
-void rtl8723a_odm_support_ability_set(struct rtw_adapter *padapter, u32 val);
-void rtl8723a_odm_support_ability_clr(struct rtw_adapter *padapter, u32 val);
-
-void rtl8723a_set_rpwm(struct rtw_adapter *padapter, u8 val);
-u8 rtl8723a_get_rf_type(struct rtw_adapter *padapter);
-bool rtl8723a_get_fwlps_rf_on(struct rtw_adapter *padapter);
-bool rtl8723a_chk_hi_queue_empty(struct rtw_adapter *padapter);
-
-#endif /* __HAL_COMMON_H__ */
diff --git a/drivers/staging/rtl8723au/include/hal_intf.h b/drivers/staging/rtl8723au/include/hal_intf.h
deleted file mode 100644
index b924d47fcfbc..000000000000
--- a/drivers/staging/rtl8723au/include/hal_intf.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __HAL_INTF_H__
-#define __HAL_INTF_H__
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-enum _CHIP_TYPE {
- NULL_CHIP_TYPE,
- RTL8712_8188S_8191S_8192S,
- RTL8188C_8192C,
- RTL8192D,
- RTL8723A,
- RTL8188E,
- MAX_CHIP_TYPE
-};
-
-enum hal_def_variable {
- HAL_DEF_UNDERCORATEDSMOOTHEDPWDB,
- HAL_DEF_IS_SUPPORT_ANT_DIV,
- HAL_DEF_CURRENT_ANTENNA,
- HAL_DEF_DRVINFO_SZ,
- HAL_DEF_MAX_RECVBUF_SZ,
- HAL_DEF_RX_PACKET_OFFSET,
- HAL_DEF_DBG_DUMP_RXPKT,/* for dbg */
- HAL_DEF_DBG_DM_FUNC,/* for dbg */
- HAL_DEF_RA_DECISION_RATE,
- HAL_DEF_RA_SGI,
- HAL_DEF_PT_PWR_STATUS,
- HW_VAR_MAX_RX_AMPDU_FACTOR,
- HW_DEF_RA_INFO_DUMP,
- HAL_DEF_DBG_DUMP_TXPKT,
- HW_DEF_FA_CNT_DUMP,
- HW_DEF_ODM_DBG_FLAG,
-};
-
-enum hal_odm_variable {
- HAL_ODM_STA_INFO,
- HAL_ODM_P2P_STATE,
- HAL_ODM_WIFI_DISPLAY_STATE,
-};
-
-enum rt_eeprom_type {
- EEPROM_93C46,
- EEPROM_93C56,
- EEPROM_BOOT_EFUSE,
-};
-
-
-
-#define RF_CHANGE_BY_INIT 0
-#define RF_CHANGE_BY_IPS BIT(28)
-#define RF_CHANGE_BY_PS BIT(29)
-#define RF_CHANGE_BY_HW BIT(30)
-#define RF_CHANGE_BY_SW BIT(31)
-
-enum hardware_type {
- HARDWARE_TYPE_RTL8180,
- HARDWARE_TYPE_RTL8185,
- HARDWARE_TYPE_RTL8187,
- HARDWARE_TYPE_RTL8188,
- HARDWARE_TYPE_RTL8190P,
- HARDWARE_TYPE_RTL8192E,
- HARDWARE_TYPE_RTL819xU,
- HARDWARE_TYPE_RTL8192SE,
- HARDWARE_TYPE_RTL8192SU,
- HARDWARE_TYPE_RTL8192CE,
- HARDWARE_TYPE_RTL8192CU,
- HARDWARE_TYPE_RTL8192DE,
- HARDWARE_TYPE_RTL8192DU,
- HARDWARE_TYPE_RTL8723AE,
- HARDWARE_TYPE_RTL8723AU,
- HARDWARE_TYPE_RTL8723AS,
- HARDWARE_TYPE_RTL8188EE,
- HARDWARE_TYPE_RTL8188EU,
- HARDWARE_TYPE_RTL8188ES,
- HARDWARE_TYPE_MAX,
-};
-
-#define GET_EEPROM_EFUSE_PRIV(adapter) (&adapter->eeprompriv)
-
-void rtw_hal_def_value_init23a(struct rtw_adapter *padapter);
-int pm_netdev_open23a(struct net_device *pnetdev, u8 bnormal);
-
-int rtl8723au_hal_init(struct rtw_adapter *padapter);
-int rtl8723au_hal_deinit(struct rtw_adapter *padapter);
-void rtw_hal_stop(struct rtw_adapter *padapter);
-
-void rtw_hal_update_ra_mask23a(struct sta_info *psta, u8 rssi_level);
-void rtw_hal_clone_data(struct rtw_adapter *dst_padapter, struct rtw_adapter *src_padapter);
-
-void hw_var_set_correct_tsf(struct rtw_adapter *padapter);
-void hw_var_set_mlme_disconnect(struct rtw_adapter *padapter);
-void hw_var_set_opmode(struct rtw_adapter *padapter, u8 mode);
-void hw_var_set_macaddr(struct rtw_adapter *padapter, u8 *val);
-void hw_var_set_bssid(struct rtw_adapter *padapter, u8 *val);
-void hw_var_set_mlme_join(struct rtw_adapter *padapter, u8 type);
-
-int GetHalDefVar8192CUsb(struct rtw_adapter *Adapter,
- enum hal_def_variable eVariable, void *pValue);
-
-#endif /* __HAL_INTF_H__ */
diff --git a/drivers/staging/rtl8723au/include/ieee80211.h b/drivers/staging/rtl8723au/include/ieee80211.h
deleted file mode 100644
index 634102e1bda6..000000000000
--- a/drivers/staging/rtl8723au/include/ieee80211.h
+++ /dev/null
@@ -1,341 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __IEEE80211_H
-#define __IEEE80211_H
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include "linux/ieee80211.h"
-#include "wifi.h"
-
-#include <linux/wireless.h>
-
-#if (WIRELESS_EXT < 22)
-#error "Obsolete pre 2007 wireless extensions are not supported"
-#endif
-
-
-#ifdef CONFIG_8723AU_AP_MODE
-
-/* STA flags */
-#define WLAN_STA_AUTH BIT(0)
-#define WLAN_STA_ASSOC BIT(1)
-#define WLAN_STA_PS BIT(2)
-#define WLAN_STA_TIM BIT(3)
-#define WLAN_STA_PERM BIT(4)
-#define WLAN_STA_AUTHORIZED BIT(5)
-#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */
-#define WLAN_STA_SHORT_PREAMBLE BIT(7)
-#define WLAN_STA_PREAUTH BIT(8)
-#define WLAN_STA_WME BIT(9)
-#define WLAN_STA_MFP BIT(10)
-#define WLAN_STA_HT BIT(11)
-#define WLAN_STA_WPS BIT(12)
-#define WLAN_STA_MAYBE_WPS BIT(13)
-#define WLAN_STA_NONERP BIT(31)
-
-#endif
-
-#define WPA_CIPHER_NONE BIT(0)
-#define WPA_CIPHER_WEP40 BIT(1)
-#define WPA_CIPHER_WEP104 BIT(2)
-#define WPA_CIPHER_TKIP BIT(3)
-#define WPA_CIPHER_CCMP BIT(4)
-
-
-
-#define WPA_SELECTOR_LEN 4
-extern u8 RTW_WPA_OUI23A_TYPE[] ;
-extern u16 RTW_WPA_VERSION23A ;
-extern u8 WPA_AUTH_KEY_MGMT_NONE23A[];
-extern u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X23A[];
-extern u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X23A[];
-extern u8 WPA_CIPHER_SUITE_NONE23A[];
-extern u8 WPA_CIPHER_SUITE_WEP4023A[];
-extern u8 WPA_CIPHER_SUITE_TKIP23A[];
-extern u8 WPA_CIPHER_SUITE_WRAP23A[];
-extern u8 WPA_CIPHER_SUITE_CCMP23A[];
-extern u8 WPA_CIPHER_SUITE_WEP10423A[];
-
-
-#define RSN_HEADER_LEN 4
-#define RSN_SELECTOR_LEN 4
-
-extern u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X23A[];
-extern u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X23A[];
-extern u8 RSN_CIPHER_SUITE_NONE23A[];
-extern u8 RSN_CIPHER_SUITE_WEP4023A[];
-extern u8 RSN_CIPHER_SUITE_TKIP23A[];
-extern u8 RSN_CIPHER_SUITE_WRAP23A[];
-extern u8 RSN_CIPHER_SUITE_CCMP23A[];
-extern u8 RSN_CIPHER_SUITE_WEP10423A[];
-
-enum ratr_table_mode {
- RATR_INX_WIRELESS_NGB = 0, /* BGN 40 Mhz 2SS 1SS */
- RATR_INX_WIRELESS_NG = 1, /* GN or N */
- RATR_INX_WIRELESS_NB = 2, /* BGN 20 Mhz 2SS 1SS or BN */
- RATR_INX_WIRELESS_N = 3,
- RATR_INX_WIRELESS_GB = 4,
- RATR_INX_WIRELESS_G = 5,
- RATR_INX_WIRELESS_B = 6,
- RATR_INX_WIRELESS_MC = 7,
- RATR_INX_WIRELESS_AC_N = 8,
-};
-
-enum NETWORK_TYPE
-{
- WIRELESS_INVALID = 0,
- /* Sub-Element */
- /* tx: cck only , rx: cck only, hw: cck */
- WIRELESS_11B = BIT(0),
- /* tx: ofdm only, rx: ofdm & cck, hw: cck & ofdm */
- WIRELESS_11G = BIT(1),
- /* tx: ofdm only, rx: ofdm only, hw: ofdm only */
- WIRELESS_11A = BIT(2),
- /* tx: MCS only, rx: MCS & cck, hw: MCS & cck */
- WIRELESS_11_24N = BIT(3),
- /* tx: MCS only, rx: MCS & ofdm, hw: ofdm only */
- WIRELESS_11_5N = BIT(4),
- /* WIRELESS_AUTO = BIT(5), */
- WIRELESS_AC = BIT(6),
-
- /* Combination */
- /* tx: cck & ofdm, rx: cck & ofdm & MCS, hw: cck & ofdm */
- WIRELESS_11BG = WIRELESS_11B|WIRELESS_11G,
- /* tx: ofdm & MCS, rx: ofdm & cck & MCS, hw: cck & ofdm */
- WIRELESS_11G_24N = WIRELESS_11G | WIRELESS_11_24N,
- /* tx: ofdm & MCS, rx: ofdm & MCS, hw: ofdm only */
- WIRELESS_11A_5N = WIRELESS_11A | WIRELESS_11_5N,
- /* tx: ofdm & cck & MCS, rx: ofdm & cck & MCS, hw: ofdm & cck */
- WIRELESS_11BG_24N = WIRELESS_11B | WIRELESS_11G | WIRELESS_11_24N,
- /* tx: ofdm & MCS, rx: ofdm & MCS, hw: ofdm only */
- WIRELESS_11AGN = WIRELESS_11A | WIRELESS_11G | WIRELESS_11_24N |
- WIRELESS_11_5N,
- WIRELESS_11ABGN = WIRELESS_11A | WIRELESS_11B | WIRELESS_11G |
- WIRELESS_11_24N | WIRELESS_11_5N,
-};
-
-#define SUPPORTED_24G_NETTYPE_MSK (WIRELESS_11B | WIRELESS_11G | WIRELESS_11_24N)
-#define SUPPORTED_5G_NETTYPE_MSK (WIRELESS_11A | WIRELESS_11_5N)
-
-#define IsSupported24G(NetType) (NetType & SUPPORTED_24G_NETTYPE_MSK ? true : false)
-#define IsSupported5G(NetType) (NetType & SUPPORTED_5G_NETTYPE_MSK ? true : false)
-
-#define IsEnableHWCCK(NetType) IsSupported24G(NetType)
-#define IsEnableHWOFDM(NetType) (NetType & (WIRELESS_11G|WIRELESS_11_24N|SUPPORTED_5G_NETTYPE_MSK) ? true : false)
-
-#define IsSupportedRxCCK(NetType) IsEnableHWCCK(NetType)
-#define IsSupportedRxOFDM(NetType) IsEnableHWOFDM(NetType)
-#define IsSupportedRxMCS(NetType) IsEnableHWOFDM(NetType)
-
-#define IsSupportedTxCCK(NetType) (NetType & (WIRELESS_11B) ? true : false)
-#define IsSupportedTxOFDM(NetType) (NetType & (WIRELESS_11G|WIRELESS_11A) ? true : false)
-#define IsSupportedTxMCS(NetType) (NetType & (WIRELESS_11_24N|WIRELESS_11_5N) ? true : false)
-
-
-#define MIN_FRAG_THRESHOLD 256U
-#define MAX_FRAG_THRESHOLD 2346U
-
-/* QoS,QOS */
-#define NORMAL_ACK 0
-#define NO_ACK 1
-#define NON_EXPLICIT_ACK 2
-#define BLOCK_ACK 3
-
-/* IEEE 802.11 defines */
-
-#define P80211_OUI_LEN 3
-
-struct ieee80211_snap_hdr {
- u8 dsap; /* always 0xAA */
- u8 ssap; /* always 0xAA */
- u8 ctrl; /* always 0x03 */
- u8 oui[P80211_OUI_LEN]; /* organizational universal id */
-} __attribute__ ((packed));
-
-
-#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
-
-#define WLAN_REASON_JOIN_WRONG_CHANNEL 65534
-#define WLAN_REASON_EXPIRATION_CHK 65535
-
-#define IEEE80211_CCK_RATE_LEN 4
-#define IEEE80211_NUM_OFDM_RATESLEN 8
-
-
-#define IEEE80211_CCK_RATE_1MB 0x02
-#define IEEE80211_CCK_RATE_2MB 0x04
-#define IEEE80211_CCK_RATE_5MB 0x0B
-#define IEEE80211_CCK_RATE_11MB 0x16
-#define IEEE80211_OFDM_RATE_LEN 8
-#define IEEE80211_OFDM_RATE_6MB 0x0C
-#define IEEE80211_OFDM_RATE_9MB 0x12
-#define IEEE80211_OFDM_RATE_12MB 0x18
-#define IEEE80211_OFDM_RATE_18MB 0x24
-#define IEEE80211_OFDM_RATE_24MB 0x30
-#define IEEE80211_OFDM_RATE_36MB 0x48
-#define IEEE80211_OFDM_RATE_48MB 0x60
-#define IEEE80211_OFDM_RATE_54MB 0x6C
-#define IEEE80211_BASIC_RATE_MASK 0x80
-
-#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
-#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
-#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
-#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
-#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
-#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
-#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
-#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
-#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
-#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
-#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
-#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
-
-#define IEEE80211_CCK_RATES_MASK 0x0000000F
-#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
- IEEE80211_CCK_RATE_2MB_MASK)
-#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
- IEEE80211_CCK_RATE_5MB_MASK | \
- IEEE80211_CCK_RATE_11MB_MASK)
-
-#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
-#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
- IEEE80211_OFDM_RATE_12MB_MASK | \
- IEEE80211_OFDM_RATE_24MB_MASK)
-#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
- IEEE80211_OFDM_RATE_9MB_MASK | \
- IEEE80211_OFDM_RATE_18MB_MASK | \
- IEEE80211_OFDM_RATE_36MB_MASK | \
- IEEE80211_OFDM_RATE_48MB_MASK | \
- IEEE80211_OFDM_RATE_54MB_MASK)
-#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
- IEEE80211_CCK_DEFAULT_RATES_MASK)
-
-#define IEEE80211_NUM_OFDM_RATES 8
-#define IEEE80211_NUM_CCK_RATES 4
-#define IEEE80211_OFDM_SHIFT_MASK_A 4
-
-#define WEP_KEYS 4
-
-
-/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
- * only use 8, and then use extended rates for the remaining supported
- * rates. Other APs, however, stick all of their supported rates on the
- * main rates information element... */
-#define MAX_RATES_LENGTH 12
-#define MAX_RATES_EX_LENGTH 16
-#define MAX_CHANNEL_NUMBER 161
-#define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
-
-#define MAX_WPA_IE_LEN 256
-#define MAX_WPS_IE_LEN 256
-#define MAX_P2P_IE_LEN 256
-#define MAX_WFD_IE_LEN 128
-
-/*
-join_res:
--1: authentication fail
--2: association fail
-> 0: TID
-*/
-
-#define MAXTID 16
-
-#define WME_OUI_TYPE 2
-#define WME_OUI_SUBTYPE_INFORMATION_ELEMENT 0
-#define WME_OUI_SUBTYPE_PARAMETER_ELEMENT 1
-#define WME_OUI_SUBTYPE_TSPEC_ELEMENT 2
-#define WME_VERSION 1
-
-
-#define OUI_BROADCOM 0x00904c /* Broadcom (Epigram) */
-
-#define VENDOR_HT_CAPAB_OUI_TYPE 0x33 /* 00-90-4c:0x33 */
-
-/* Represent channel details, subset of ieee80211_channel */
-struct rtw_ieee80211_channel {
- /* enum nl80211_band band; */
- /* u16 center_freq; */
- u16 hw_value;
- u32 flags;
- /* int max_antenna_gain; */
- /* int max_power; */
- /* int max_reg_power; */
- /* bool beacon_found; */
- /* u32 orig_flags; */
- /* int orig_mag; */
- /* int orig_mpwr; */
-};
-
-#define CHAN_FMT \
- /*"band:%d, "*/ \
- /*"center_freq:%u, "*/ \
- "hw_value:%u, " \
- "flags:0x%08x" \
- /*"max_antenna_gain:%d\n"*/ \
- /*"max_power:%d\n"*/ \
- /*"max_reg_power:%d\n"*/ \
- /*"beacon_found:%u\n"*/ \
- /*"orig_flags:0x%08x\n"*/ \
- /*"orig_mag:%d\n"*/ \
- /*"orig_mpwr:%d\n"*/
-
-#define CHAN_ARG(channel) \
- /*(channel)->band*/ \
- /*, (channel)->center_freq*/ \
- (channel)->hw_value \
- , (channel)->flags \
- /*, (channel)->max_antenna_gain*/ \
- /*, (channel)->max_power*/ \
- /*, (channel)->max_reg_power*/ \
- /*, (channel)->beacon_found*/ \
- /*, (channel)->orig_flags*/ \
- /*, (channel)->orig_mag*/ \
- /*, (channel)->orig_mpwr*/ \
-
-u8 *rtw_set_ie23a(u8 *pbuf, int index, uint len, const u8 *source, uint *frlen);
-
-u8 hal_ch_offset_to_secondary_ch_offset23a(u8 ch_offset);
-u8 *rtw_set_ie23a_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode, u8 new_ch, u8 ch_switch_cnt);
-u8 *rtw_set_ie23a_secondary_ch_offset(u8 *buf, u32 *buf_len, u8 secondary_ch_offset);
-
-u8 *rtw_get_ie23a(u8*pbuf, int index, int *len, int limit);
-u8 *rtw_get_ie23a_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len, u8 *ie, uint *ielen);
-int rtw_ies_remove_ie23a(u8 *ies, uint *ies_len, uint offset, u8 eid, u8 *oui, u8 oui_len);
-
-void rtw_set_supported_rate23a(u8 *SupportedRates, uint mode);
-
-int rtw_parse_wpa_ie23a(const u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x);
-int rtw_parse_wpa2_ie23a(const u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x);
-
-const u8 *rtw_get_wps_attr23a(const u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_attr, u32 *len_attr);
-const u8 *rtw_get_wps_attr_content23a(const u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_content);
-
-uint rtw_get_rateset_len23a(u8 *rateset);
-
-struct registry_priv;
-int rtw_generate_ie23a(struct registry_priv *pregistrypriv);
-
-
-int rtw_get_bit_value_from_ieee_value23a(u8 val);
-
-int rtw_check_network_type23a(unsigned char *rate, int ratelen, int channel);
-
-void rtw_get_bcn_info23a(struct wlan_network *pnetwork);
-
-u16 rtw_mcs_rate23a(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40,
- struct ieee80211_mcs_info *mcs);
-
-#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8723au/include/ioctl_cfg80211.h b/drivers/staging/rtl8723au/include/ioctl_cfg80211.h
deleted file mode 100644
index 3a4ead54f948..000000000000
--- a/drivers/staging/rtl8723au/include/ioctl_cfg80211.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __IOCTL_CFG80211_H__
-#define __IOCTL_CFG80211_H__
-
-struct rtw_wdev_priv {
- struct wireless_dev *rtw_wdev;
-
- struct rtw_adapter *padapter;
-
- struct cfg80211_scan_request *scan_request;
- spinlock_t scan_req_lock;
-
- struct net_device *pmon_ndev;/* for monitor interface */
- char ifname_mon[IFNAMSIZ + 1]; /* name for monitor interface */
-
- u8 p2p_enabled;
-
- bool power_mgmt;
-};
-
-#define wdev_to_priv(w) ((struct rtw_wdev_priv *)(wdev_priv(w)))
-
-#define wiphy_to_adapter(x) \
- (struct rtw_adapter *)(((struct rtw_wdev_priv *) \
- wiphy_priv(x))->padapter)
-
-#define wiphy_to_wdev(x) \
- (struct wireless_dev *)(((struct rtw_wdev_priv *) \
- wiphy_priv(x))->rtw_wdev)
-
-int rtw_wdev_alloc(struct rtw_adapter *padapter, struct device *dev);
-void rtw_wdev_free(struct wireless_dev *wdev);
-void rtw_wdev_unregister(struct wireless_dev *wdev);
-
-void rtw_cfg80211_init_wiphy(struct rtw_adapter *padapter);
-
-void rtw_cfg80211_surveydone_event_callback(struct rtw_adapter *padapter);
-
-void rtw_cfg80211_indicate_connect(struct rtw_adapter *padapter);
-void rtw_cfg80211_indicate_disconnect(struct rtw_adapter *padapter);
-void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv,
- bool aborted);
-
-#ifdef CONFIG_8723AU_AP_MODE
-void rtw_cfg80211_indicate_sta_assoc(struct rtw_adapter *padapter,
- u8 *pmgmt_frame, uint frame_len);
-void rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter,
- unsigned char *da, unsigned short reason);
-#endif /* CONFIG_8723AU_AP_MODE */
-
-bool rtw_cfg80211_pwr_mgmt(struct rtw_adapter *adapter);
-
-#endif /* __IOCTL_CFG80211_H__ */
diff --git a/drivers/staging/rtl8723au/include/mlme_osdep.h b/drivers/staging/rtl8723au/include/mlme_osdep.h
deleted file mode 100644
index 4bb5525b7a68..000000000000
--- a/drivers/staging/rtl8723au/include/mlme_osdep.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __MLME_OSDEP_H_
-#define __MLME_OSDEP_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-void rtw_os_indicate_disconnect23a(struct rtw_adapter *adapter);
-void rtw_reset_securitypriv23a(struct rtw_adapter *adapter);
-
-#endif /* _MLME_OSDEP_H_ */
diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h
deleted file mode 100644
index 24f2f28c473f..000000000000
--- a/drivers/staging/rtl8723au/include/odm.h
+++ /dev/null
@@ -1,860 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-
-#ifndef __HALDMOUTSRC_H__
-#define __HALDMOUTSRC_H__
-
-/* */
-/* Definition */
-/* */
-/* */
-/* 2011/09/22 MH Define all team supprt ability. */
-/* */
-
-/* */
-/* 2011/09/22 MH Define for all teams. Please Define the constan in your precomp header. */
-/* */
-/* define DM_ODM_SUPPORT_AP 0 */
-/* define DM_ODM_SUPPORT_ADSL 0 */
-/* define DM_ODM_SUPPORT_CE 0 */
-/* define DM_ODM_SUPPORT_MP 1 */
-
-#define TP_MODE 0
-#define RSSI_MODE 1
-#define TRAFFIC_LOW 0
-#define TRAFFIC_HIGH 1
-
-
-/* */
-/* 3 Tx Power Tracking */
-/* 3============================================================ */
-#define DPK_DELTA_MAPPING_NUM 13
-#define index_mapping_HP_NUM 15
-
-
-/* */
-/* 3 PSD Handler */
-/* 3============================================================ */
-
-#define AFH_PSD 1 /* 0:normal PSD scan, 1: only do 20 pts PSD */
-#define MODE_40M 0 /* 0:20M, 1:40M */
-#define PSD_TH2 3
-#define PSD_CHMIN 20 /* Minimum channel number for BT AFH */
-#define SIR_STEP_SIZE 3
-#define Smooth_Size_1 5
-#define Smooth_TH_1 3
-#define Smooth_Size_2 10
-#define Smooth_TH_2 4
-#define Smooth_Size_3 20
-#define Smooth_TH_3 4
-#define Smooth_Step_Size 5
-#define Adaptive_SIR 1
-#define PSD_RESCAN 4
-#define PSD_SCAN_INTERVAL 700 /* ms */
-
-/* 8723A High Power IGI Setting */
-#define DM_DIG_HIGH_PWR_IGI_LOWER_BOUND 0x22
-#define DM_DIG_Gmode_HIGH_PWR_IGI_LOWER_BOUND 0x28
-#define DM_DIG_HIGH_PWR_THRESHOLD 0x3a
-
-/* LPS define */
-#define DM_DIG_FA_TH0_LPS 4 /* 4 in lps */
-#define DM_DIG_FA_TH1_LPS 15 /* 15 lps */
-#define DM_DIG_FA_TH2_LPS 30 /* 30 lps */
-#define RSSI_OFFSET_DIG 0x05;
-
-/* ANT Test */
-#define ANTTESTALL 0x00 /* Ant A or B will be Testing */
-#define ANTTESTA 0x01 /* Ant A will be Testing */
-#define ANTTESTB 0x02 /* Ant B will be testing */
-
-
-/* */
-/* structure and define */
-/* */
-
-struct dig_t {
- u8 Dig_Enable_Flag;
- u8 Dig_Ext_Port_Stage;
-
- int RssiLowThresh;
- int RssiHighThresh;
-
- u32 FALowThresh;
- u32 FAHighThresh;
-
- u8 CurSTAConnectState;
- u8 PreSTAConnectState;
- u8 CurMultiSTAConnectState;
-
- u8 PreIGValue;
- u8 CurIGValue;
- u8 BackupIGValue;
-
- s8 BackoffVal;
- s8 BackoffVal_range_max;
- s8 BackoffVal_range_min;
- u8 rx_gain_range_max;
- u8 rx_gain_range_min;
- u8 Rssi_val_min;
-
- u8 PreCCK_CCAThres;
- u8 CurCCK_CCAThres;
- u8 PreCCKPDState;
- u8 CurCCKPDState;
-
- u8 LargeFAHit;
- u8 ForbiddenIGI;
- u32 Recover_cnt;
-
- u8 DIG_Dynamic_MIN_0;
- u8 DIG_Dynamic_MIN_1;
- bool bMediaConnect_0;
- bool bMediaConnect_1;
-
- u32 RSSI_max;
-};
-
-struct dynamic_pwr_sav {
- u8 PreCCAState;
- u8 CurCCAState;
-
- u8 PreRFState;
- u8 CurRFState;
-
- int Rssi_val_min;
-
- u8 initialize;
- u32 Reg874, RegC70, Reg85C, RegA74;
-};
-
-struct false_alarm_stats {
- u32 Cnt_Parity_Fail;
- u32 Cnt_Rate_Illegal;
- u32 Cnt_Crc8_fail;
- u32 Cnt_Mcs_fail;
- u32 Cnt_Ofdm_fail;
- u32 Cnt_Cck_fail;
- u32 Cnt_all;
- u32 Cnt_Fast_Fsync;
- u32 Cnt_SB_Search_fail;
- u32 Cnt_OFDM_CCA;
- u32 Cnt_CCK_CCA;
- u32 Cnt_CCA_all;
- u32 Cnt_BW_USC; /* Gary */
- u32 Cnt_BW_LSC; /* Gary */
-};
-
-#define ASSOCIATE_ENTRY_NUM 32 /* Max size of AsocEntry[]. */
-#define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM
-
-/* This indicates two different the steps. */
-/* In SWAW_STEP_PEAK, driver needs to switch antenna and listen to the signal on the air. */
-/* In SWAW_STEP_DETERMINE, driver just compares the signal captured in SWAW_STEP_PEAK */
-/* with original RSSI to determine if it is necessary to switch antenna. */
-#define SWAW_STEP_PEAK 0
-#define SWAW_STEP_DETERMINE 1
-
-#define TP_MODE 0
-#define RSSI_MODE 1
-#define TRAFFIC_LOW 0
-#define TRAFFIC_HIGH 1
-
-struct sw_ant_sw {
- u8 try_flag;
- s32 PreRSSI;
- u8 CurAntenna;
- u8 PreAntenna;
- u8 RSSI_Trying;
- u8 TestMode;
- u8 bTriggerAntennaSwitch;
- u8 SelectAntennaMap;
- u8 RSSI_target;
-
- /* Before link Antenna Switch check */
- u8 SWAS_NoLink_State;
- u32 SWAS_NoLink_BK_Reg860;
- bool ANTA_ON; /* To indicate Ant A is or not */
- bool ANTB_ON; /* To indicate Ant B is on or not */
-
- s32 RSSI_sum_A;
- s32 RSSI_sum_B;
- s32 RSSI_cnt_A;
- s32 RSSI_cnt_B;
-
- u64 lastTxOkCnt;
- u64 lastRxOkCnt;
- u64 TXByteCnt_A;
- u64 TXByteCnt_B;
- u64 RXByteCnt_A;
- u64 RXByteCnt_B;
- u8 TrafficLoad;
-};
-
-struct edca_turbo {
- bool bCurrentTurboEDCA;
- u32 prv_traffic_idx; /* edca turbo */
-};
-
-struct odm_rate_adapt {
- u8 Type; /* DM_Type_ByFW/DM_Type_ByDriver */
- u8 HighRSSIThresh; /* if RSSI > HighRSSIThresh => RATRState is DM_RATR_STA_HIGH */
- u8 LowRSSIThresh; /* if RSSI <= LowRSSIThresh => RATRState is DM_RATR_STA_LOW */
- u8 RATRState; /* Current RSSI level, DM_RATR_STA_HIGH/DM_RATR_STA_MIDDLE/DM_RATR_STA_LOW */
- u32 LastRATR; /* RATR Register Content */
-};
-
-#define IQK_MAC_REG_NUM 4
-#define IQK_ADDA_REG_NUM 16
-#define IQK_BB_REG_NUM_MAX 10
-#define IQK_BB_REG_NUM 9
-#define HP_THERMAL_NUM 8
-
-#define AVG_THERMAL_NUM 8
-#define IQK_Matrix_REG_NUM 8
-#define IQK_Matrix_Settings_NUM 1+24+21
-
-#define DM_Type_ByFW 0
-#define DM_Type_ByDriver 1
-
-/* Declare for common info */
-
-struct odm_phy_dbg_info {
- /* ODM Write,debug info */
- s8 RxSNRdB[RF_PATH_MAX];
- u64 NumQryPhyStatus;
- u64 NumQryPhyStatusCCK;
- u64 NumQryPhyStatusOFDM;
- /* Others */
- s32 RxEVM[RF_PATH_MAX];
-
-};
-
-struct odm_packet_info {
- u8 Rate;
- u8 StationID;
- bool bPacketMatchBSSID;
- bool bPacketToSelf;
- bool bPacketBeacon;
-};
-
-
-enum {
- /* BB Team */
- ODM_DIG = 0x00000001,
- ODM_HIGH_POWER = 0x00000002,
- ODM_CCK_CCA_TH = 0x00000004,
- ODM_FA_STATISTICS = 0x00000008,
- ODM_RAMASK = 0x00000010,
- ODM_RSSI_MONITOR = 0x00000020,
- ODM_SW_ANTDIV = 0x00000040,
- ODM_HW_ANTDIV = 0x00000080,
- ODM_BB_PWRSV = 0x00000100,
- ODM_2TPATHDIV = 0x00000200,
- ODM_1TPATHDIV = 0x00000400,
- ODM_PSD2AFH = 0x00000800
-};
-
-/* */
-/* 2011/10/20 MH Define Common info enum for all team. */
-/* */
-
-enum odm_cmninfo {
- /* Fixed value: */
- /* */
-
- ODM_CMNINFO_MP_TEST_CHIP = 2,
- ODM_CMNINFO_IC_TYPE, /* enum odm_ic_type_def */
- ODM_CMNINFO_CUT_VER, /* enum odm_cut_version */
- ODM_CMNINFO_FAB_VER, /* enum odm_fab_version */
- ODM_CMNINFO_BOARD_TYPE, /* enum odm_board_type */
- ODM_CMNINFO_EXT_LNA, /* true */
- ODM_CMNINFO_EXT_PA,
- ODM_CMNINFO_EXT_TRSW,
- ODM_CMNINFO_BINHCT_TEST,
- ODM_CMNINFO_BWIFI_TEST,
- ODM_CMNINFO_SMART_CONCURRENT,
-
-
- /* */
- /* Dynamic value: */
- /* */
- ODM_CMNINFO_MP_MODE,
-
- ODM_CMNINFO_WIFI_DIRECT,
- ODM_CMNINFO_WIFI_DISPLAY,
- ODM_CMNINFO_LINK,
- ODM_CMNINFO_RSSI_MIN,
- ODM_CMNINFO_DBG_COMP, /* u64 */
- ODM_CMNINFO_DBG_LEVEL, /* u32 */
- ODM_CMNINFO_RA_THRESHOLD_HIGH, /* u8 */
- ODM_CMNINFO_RA_THRESHOLD_LOW, /* u8 */
- ODM_CMNINFO_RF_ANTENNA_TYPE, /* u8 */
- ODM_CMNINFO_BT_DISABLED,
- ODM_CMNINFO_BT_OPERATION,
- ODM_CMNINFO_BT_DIG,
- ODM_CMNINFO_BT_BUSY, /* Check Bt is using or not */
- ODM_CMNINFO_BT_DISABLE_EDCA,
-
- /* */
- /* Dynamic ptr array hook itms. */
- /* */
- ODM_CMNINFO_STA_STATUS,
- ODM_CMNINFO_PHY_STATUS,
- ODM_CMNINFO_MAC_STATUS,
-
- ODM_CMNINFO_MAX,
-};
-
-/* Define ODM support ability. ODM_CMNINFO_ABILITY */
-enum {
- /* BB ODM section BIT 0-15 */
- ODM_BB_ANT_DIV = BIT(6),
-};
-
-/* ODM_CMNINFO_INTERFACE */
-enum odm_interface_def {
- ODM_ITRF_PCIE = 0x1,
- ODM_ITRF_USB = 0x2,
- ODM_ITRF_SDIO = 0x4,
- ODM_ITRF_ALL = 0x7,
-};
-
-/* ODM_CMNINFO_IC_TYPE */
-enum odm_ic_type_def {
- ODM_RTL8192S = BIT(0),
- ODM_RTL8192C = BIT(1),
- ODM_RTL8192D = BIT(2),
- ODM_RTL8723A = BIT(3),
- ODM_RTL8188E = BIT(4),
- ODM_RTL8812 = BIT(5),
- ODM_RTL8821 = BIT(6),
-};
-
-/* ODM_CMNINFO_CUT_VER */
-enum odm_cut_version {
- ODM_CUT_A = 1,
- ODM_CUT_B = 2,
- ODM_CUT_C = 3,
- ODM_CUT_D = 4,
- ODM_CUT_E = 5,
- ODM_CUT_F = 6,
- ODM_CUT_TEST = 7,
-};
-
-/* ODM_CMNINFO_FAB_VER */
-enum odm_fab_version {
- ODM_TSMC = 0,
- ODM_UMC = 1,
-};
-
-/* For example 1T2R (A+AB = BIT0|BIT4|BIT5) */
-enum rf_path_def {
- ODM_RF_TX_A = BIT(0),
- ODM_RF_TX_B = BIT(1),
- ODM_RF_TX_C = BIT(2),
- ODM_RF_TX_D = BIT(3),
- ODM_RF_RX_A = BIT(4),
- ODM_RF_RX_B = BIT(5),
- ODM_RF_RX_C = BIT(6),
- ODM_RF_RX_D = BIT(7),
-};
-
-/* ODM Dynamic common info value definition */
-
-enum odm_mac_phy_mode {
- ODM_SMSP = 0,
- ODM_DMSP = 1,
- ODM_DMDP = 2,
-};
-
-
-enum odm_bt_coexist {
- ODM_BT_BUSY = 1,
- ODM_BT_ON = 2,
- ODM_BT_OFF = 3,
- ODM_BT_NONE = 4,
-};
-
-/* ODM_CMNINFO_OP_MODE */
-enum odm_operation_mode {
- ODM_NO_LINK = BIT(0),
- ODM_LINK = BIT(1),
- ODM_SCAN = BIT(2),
- ODM_POWERSAVE = BIT(3),
- ODM_AP_MODE = BIT(4),
- ODM_CLIENT_MODE = BIT(5),
- ODM_AD_HOC = BIT(6),
- ODM_WIFI_DIRECT = BIT(7),
- ODM_WIFI_DISPLAY = BIT(8),
-};
-
-/* ODM_CMNINFO_WM_MODE */
-enum odm_wireless_mode {
- ODM_WM_UNKNOW = 0x0,
- ODM_WM_B = BIT(0),
- ODM_WM_G = BIT(1),
- ODM_WM_A = BIT(2),
- ODM_WM_N24G = BIT(3),
- ODM_WM_N5G = BIT(4),
- ODM_WM_AUTO = BIT(5),
- ODM_WM_AC = BIT(6),
-};
-
-/* ODM_CMNINFO_BAND */
-enum odm_band_type {
- ODM_BAND_2_4G = BIT(0),
- ODM_BAND_5G = BIT(1),
-
-};
-
-/* ODM_CMNINFO_SEC_CHNL_OFFSET */
-enum odm_sec_chnl_offset {
- ODM_DONT_CARE = 0,
- ODM_BELOW = 1,
- ODM_ABOVE = 2
-};
-
-/* ODM_CMNINFO_CHNL */
-
-/* ODM_CMNINFO_BOARD_TYPE */
-enum odm_board_type {
- ODM_BOARD_NORMAL = 0,
- ODM_BOARD_HIGHPWR = 1,
- ODM_BOARD_MINICARD = 2,
- ODM_BOARD_SLIM = 3,
- ODM_BOARD_COMBO = 4,
-
-};
-
-/* ODM_CMNINFO_ONE_PATH_CCA */
-enum odm_cca_path {
- ODM_CCA_2R = 0,
- ODM_CCA_1R_A = 1,
- ODM_CCA_1R_B = 2,
-};
-
-struct iqk_matrix_regs_set {
- bool bIQKDone;
- s32 Value[1][IQK_Matrix_REG_NUM];
-};
-
-struct odm_rf_cal_t {
- /* for tx power tracking */
-
- u32 RegA24; /* for TempCCK */
- s32 RegE94;
- s32 RegE9C;
- s32 RegEB4;
- s32 RegEBC;
-
- /* u8 bTXPowerTracking; */
- u8 TXPowercount;
- bool bTXPowerTrackingInit;
- bool bTXPowerTracking;
- u8 TxPowerTrackControl; /* for mp mode, turn off txpwrtracking as default */
- u8 TM_Trigger;
- u8 InternalPA5G[2]; /* pathA / pathB */
-
- u8 ThermalMeter[2]; /* ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 */
- u8 ThermalValue;
- u8 ThermalValue_LCK;
- u8 ThermalValue_IQK;
- u8 ThermalValue_DPK;
- u8 ThermalValue_AVG[AVG_THERMAL_NUM];
- u8 ThermalValue_AVG_index;
- u8 ThermalValue_RxGain;
- u8 ThermalValue_Crystal;
- u8 ThermalValue_DPKstore;
- u8 ThermalValue_DPKtrack;
- bool TxPowerTrackingInProgress;
- bool bDPKenable;
-
- bool bReloadtxpowerindex;
- u8 bRfPiEnable;
- u32 TXPowerTrackingCallbackCnt; /* cosa add for debug */
-
- u8 bCCKinCH14;
- u8 CCK_index;
- u8 OFDM_index[2];
- bool bDoneTxpower;
-
- u8 ThermalValue_HP[HP_THERMAL_NUM];
- u8 ThermalValue_HP_index;
- struct iqk_matrix_regs_set IQKMatrixRegSetting[IQK_Matrix_Settings_NUM];
-
- u8 Delta_IQK;
- u8 Delta_LCK;
-
- /* for IQK */
- u32 RegC04;
- u32 Reg874;
- u32 RegC08;
- u32 RegB68;
- u32 RegB6C;
- u32 Reg870;
- u32 Reg860;
- u32 Reg864;
-
- bool bIQKInitialized;
- bool bLCKInProgress;
- bool bAntennaDetected;
- u32 ADDA_backup[IQK_ADDA_REG_NUM];
- u32 IQK_MAC_backup[IQK_MAC_REG_NUM];
- u32 IQK_BB_backup_recover[9];
- u32 IQK_BB_backup[IQK_BB_REG_NUM];
-
- /* for APK */
- u32 APKoutput[2][2]; /* path A/B; output1_1a/output1_2a */
- u8 bAPKdone;
- u8 bAPKThermalMeterIgnore;
- u8 bDPdone;
- u8 bDPPathAOK;
- u8 bDPPathBOK;
-};
-
-enum ant_dif_type {
- NO_ANTDIV = 0xFF,
- CG_TRX_HW_ANTDIV = 0x01,
- CGCS_RX_HW_ANTDIV = 0x02,
- FIXED_HW_ANTDIV = 0x03,
- CG_TRX_SMART_ANTDIV = 0x04,
- CGCS_RX_SW_ANTDIV = 0x05,
-};
-
-/* 2011/09/22 MH Copy from SD4 defined structure. We use to support PHY DM integration. */
-struct dm_odm_t {
- /* */
- /* Add for different team use temporarily */
- /* */
- struct rtw_adapter *Adapter; /* For CE/NIC team */
-
- u64 DebugComponents;
- u32 DebugLevel;
-
-/* ODM HANDLE, DRIVER NEEDS NOT TO HOOK------ */
- bool bCckHighPower;
- u8 RFPathRxEnable; /* ODM_CMNINFO_RFPATH_ENABLE */
-/* ODM HANDLE, DRIVER NEEDS NOT TO HOOK------ */
-
-/* 1 COMMON INFORMATION */
-
- /* Init Value */
-/* HOOK BEFORE REG INIT----------- */
- /* ODM Support Ability DIG/RATR/TX_PWR_TRACK/ ¡K¡K = 1/2/3/¡K */
- u32 SupportAbility;
- /* ODM composite or independent. Bit oriented/ 92C+92D+ .... or any other type = 1/2/3/... */
- u32 SupportICType;
- /* Cut Version TestChip/A-cut/B-cut... = 0/1/2/3/... */
- u8 CutVersion;
- /* Fab Version TSMC/UMC = 0/1 */
- u8 FabVersion;
- /* Board Type Normal/HighPower/MiniCard/SLIM/Combo/... = 0/1/2/3/4/... */
- u8 BoardType;
- /* with external LNA NO/Yes = 0/1 */
- u8 ExtLNA;
- /* with external PA NO/Yes = 0/1 */
- u8 ExtPA;
- /* with external TRSW NO/Yes = 0/1 */
- u8 ExtTRSW;
- bool bInHctTest;
- bool bWIFITest;
-
- bool bDualMacSmartConcurrent;
- u32 BK_SupportAbility;
-/* HOOK BEFORE REG INIT----------- */
-
- /* */
- /* Dynamic Value */
- /* */
-/* POINTER REFERENCE----------- */
-
- u8 u8_temp;
- bool bool_temp;
- struct rtw_adapter *PADAPTER_temp;
-
-/* POINTER REFERENCE----------- */
- /* */
-/* CALL BY VALUE------------- */
- bool bWIFI_Direct;
- bool bWIFI_Display;
- bool bLinked;
- u8 RSSI_Min;
- u8 InterfaceIndex; /* Add for 92D dual MAC: 0--Mac0 1--Mac1 */
- bool bIsMPChip;
- bool bOneEntryOnly;
- /* Common info for BTDM */
- bool bBtDisabled; /* BT is disabled */
- bool bBtHsOperation; /* BT HS mode is under progress */
- u8 btHsDigVal; /* use BT rssi to decide the DIG value */
- bool bBtDisableEdcaTurbo; /* Under some condition, don't enable the EDCA Turbo */
- bool bBtBusy; /* BT is busy. */
-/* CALL BY VALUE------------- */
-
- /* 2 Define STA info. */
- /* _ODM_STA_INFO */
- /* 2012/01/12 MH For MP, we need to reduce one array pointer for default port.?? */
- struct sta_info * pODM_StaInfo[ODM_ASSOCIATE_ENTRY_NUM];
-
- /* Latest packet phy info (ODM write) */
- struct odm_phy_dbg_info PhyDbgInfo;
- /* PHY_INFO_88E PhyInfo; */
-
- /* Latest packet phy info (ODM write) */
- /* MAC_INFO_88E MacInfo; */
-
- /* Different Team independt structure?? */
-
- /* */
- /* TX_RTP_CMN TX_retrpo; */
- /* TX_RTP_88E TX_retrpo; */
- /* TX_RTP_8195 TX_retrpo; */
-
- /* */
- /* ODM Structure */
- /* */
- struct dig_t DM_DigTable;
- struct dynamic_pwr_sav DM_PSTable;
- struct false_alarm_stats FalseAlmCnt;
- struct false_alarm_stats FlaseAlmCntBuddyAdapter;
- struct sw_ant_sw DM_SWAT_Table;
-
- struct edca_turbo DM_EDCA_Table;
- u32 WMMEDCA_BE;
- /* Copy from SD4 structure */
- /* */
- /* ================================================== */
- /* */
-
- /* PSD */
- u8 RSSI_BT; /* come from BT */
- struct odm_rate_adapt RateAdaptive;
-
-
- struct odm_rf_cal_t RFCalibrateInfo;
-}; /* DM_Dynamic_Mechanism_Structure */
-
-enum odm_rf_content {
- odm_radioa_txt = 0x1000,
- odm_radiob_txt = 0x1001,
- odm_radioc_txt = 0x1002,
- odm_radiod_txt = 0x1003
-};
-
-/* Status code */
-enum rt_status {
- RT_STATUS_SUCCESS,
- RT_STATUS_FAILURE,
- RT_STATUS_PENDING,
- RT_STATUS_RESOURCE,
- RT_STATUS_INVALID_CONTEXT,
- RT_STATUS_INVALID_PARAMETER,
- RT_STATUS_NOT_SUPPORT,
- RT_STATUS_OS_API_FAILED,
-};
-
-/* include "odm_function.h" */
-
-/* 3=========================================================== */
-/* 3 DIG */
-/* 3=========================================================== */
-
-enum dm_dig_op {
- DIG_TYPE_THRESH_HIGH = 0,
- DIG_TYPE_THRESH_LOW = 1,
- DIG_TYPE_BACKOFF = 2,
- DIG_TYPE_RX_GAIN_MIN = 3,
- DIG_TYPE_RX_GAIN_MAX = 4,
- DIG_TYPE_ENABLE = 5,
- DIG_TYPE_DISABLE = 6,
- DIG_OP_TYPE_MAX
-};
-
-#define DM_DIG_THRESH_HIGH 40
-#define DM_DIG_THRESH_LOW 35
-
-#define DM_SCAN_RSSI_TH 0x14 /* scan return issue for LC */
-
-
-#define DM_FALSEALARM_THRESH_LOW 400
-#define DM_FALSEALARM_THRESH_HIGH 1000
-
-#define DM_DIG_MAX_NIC 0x4e
-#define DM_DIG_MIN_NIC 0x1e
-
-#define DM_DIG_MAX_AP 0x32
-#define DM_DIG_MIN_AP 0x20
-
-#define DM_DIG_MAX_NIC_HP 0x46
-#define DM_DIG_MIN_NIC_HP 0x2e
-
-#define DM_DIG_MAX_AP_HP 0x42
-#define DM_DIG_MIN_AP_HP 0x30
-
-/* vivi 92c&92d has different definition, 20110504 */
-/* this is for 92c */
-#define DM_DIG_FA_TH0 0x200
-#define DM_DIG_FA_TH1 0x300
-#define DM_DIG_FA_TH2 0x400
-/* this is for 92d */
-#define DM_DIG_FA_TH0_92D 0x100
-#define DM_DIG_FA_TH1_92D 0x400
-#define DM_DIG_FA_TH2_92D 0x600
-
-#define DM_DIG_BACKOFF_MAX 12
-#define DM_DIG_BACKOFF_MIN -4
-#define DM_DIG_BACKOFF_DEFAULT 10
-
-/* 3=========================================================== */
-/* 3 AGC RX High Power Mode */
-/* 3=========================================================== */
-#define LNA_Low_Gain_1 0x64
-#define LNA_Low_Gain_2 0x5A
-#define LNA_Low_Gain_3 0x58
-
-#define FA_RXHP_TH1 5000
-#define FA_RXHP_TH2 1500
-#define FA_RXHP_TH3 800
-#define FA_RXHP_TH4 600
-#define FA_RXHP_TH5 500
-
-/* 3=========================================================== */
-/* 3 EDCA */
-/* 3=========================================================== */
-
-/* 3=========================================================== */
-/* 3 Dynamic Tx Power */
-/* 3=========================================================== */
-/* Dynamic Tx Power Control Threshold */
-#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
-#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
-#define TX_POWER_NEAR_FIELD_THRESH_AP 0x3F
-
-#define TxHighPwrLevel_Normal 0
-#define TxHighPwrLevel_Level1 1
-#define TxHighPwrLevel_Level2 2
-#define TxHighPwrLevel_BT1 3
-#define TxHighPwrLevel_BT2 4
-#define TxHighPwrLevel_15 5
-#define TxHighPwrLevel_35 6
-#define TxHighPwrLevel_50 7
-#define TxHighPwrLevel_70 8
-#define TxHighPwrLevel_100 9
-
-/* 3=========================================================== */
-/* 3 Rate Adaptive */
-/* 3=========================================================== */
-#define DM_RATR_STA_INIT 0
-#define DM_RATR_STA_HIGH 1
-#define DM_RATR_STA_MIDDLE 2
-#define DM_RATR_STA_LOW 3
-
-/* 3=========================================================== */
-/* 3 BB Power Save */
-/* 3=========================================================== */
-
-
-enum dm_1r_cca {
- CCA_1R =0,
- CCA_2R = 1,
- CCA_MAX = 2,
-};
-
-enum dm_rf_def {
- RF_Save =0,
- RF_Normal = 1,
- RF_MAX = 2,
-};
-
-/* 3=========================================================== */
-/* 3 Antenna Diversity */
-/* 3=========================================================== */
-enum dm_swas {
- Antenna_A = 1,
- Antenna_B = 2,
- Antenna_MAX = 3,
-};
-
-/* Maximal number of antenna detection mechanism needs to perform, added by Roger, 2011.12.28. */
-#define MAX_ANTENNA_DETECTION_CNT 10
-
-/* */
-/* Extern Global Variables. */
-/* */
-#define OFDM_TABLE_SIZE_92C 37
-#define OFDM_TABLE_SIZE_92D 43
-#define CCK_TABLE_SIZE 33
-
-extern u32 OFDMSwingTable23A[OFDM_TABLE_SIZE_92D];
-extern u8 CCKSwingTable_Ch1_Ch1323A[CCK_TABLE_SIZE][8];
-extern u8 CCKSwingTable_Ch1423A [CCK_TABLE_SIZE][8];
-
-
-
-/* 20100514 Joseph: Add definition for antenna switching test after link. */
-/* This indicates two different the steps. */
-/* In SWAW_STEP_PEAK, driver needs to switch antenna and listen to the signal on the air. */
-/* In SWAW_STEP_DETERMINE, driver just compares the signal captured in SWAW_STEP_PEAK */
-/* with original RSSI to determine if it is necessary to switch antenna. */
-#define SWAW_STEP_PEAK 0
-#define SWAW_STEP_DETERMINE 1
-
-struct hal_data_8723a;
-
-void ODM_Write_DIG23a(struct dm_odm_t *pDM_Odm, u8 CurrentIGI);
-void ODM_Write_CCK_CCA_Thres23a(struct dm_odm_t *pDM_Odm, u8 CurCCK_CCAThres);
-
-void ODM_SetAntenna(struct dm_odm_t *pDM_Odm, u8 Antenna);
-
-
-#define dm_RF_Saving ODM_RF_Saving23a
-void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal);
-
-#define dm_CheckTXPowerTracking ODM_TXPowerTrackingCheck23a
-void ODM_TXPowerTrackingCheck23a(struct dm_odm_t *pDM_Odm);
-
-bool ODM_RAStateCheck23a(struct dm_odm_t *pDM_Odm, s32 RSSI, bool bForceUpdate,
- u8 *pRATRState);
-
-
-u32 ConvertTo_dB23a(u32 Value);
-
-u32 GetPSDData(struct dm_odm_t *pDM_Odm, unsigned int point, u8 initial_gain_psd);
-
-void odm_DIG23abyRSSI_LPS(struct dm_odm_t *pDM_Odm);
-
-u32 ODM_Get_Rate_Bitmap23a(struct hal_data_8723a *pHalData, u32 macid, u32 ra_mask, u8 rssi_level);
-
-
-void ODM23a_DMInit(struct dm_odm_t *pDM_Odm);
-
-void ODM_DMWatchdog23a(struct rtw_adapter *adapter);
-
-void ODM_CmnInfoInit23a(struct dm_odm_t *pDM_Odm, enum odm_cmninfo CmnInfo, u32 Value);
-
-void ODM_CmnInfoPtrArrayHook23a(struct dm_odm_t *pDM_Odm, enum odm_cmninfo CmnInfo, u16 Index, void *pValue);
-
-void ODM_CmnInfoUpdate23a(struct dm_odm_t *pDM_Odm, u32 CmnInfo, u64 Value);
-
-void ODM_ResetIQKResult(struct dm_odm_t *pDM_Odm);
-
-void ODM_AntselStatistics_88C(struct dm_odm_t *pDM_Odm, u8 MacId, u32 PWDBAll, bool isCCKrate);
-
-void ODM_SingleDualAntennaDefaultSetting(struct dm_odm_t *pDM_Odm);
-
-bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/odm_HWConfig.h b/drivers/staging/rtl8723au/include/odm_HWConfig.h
deleted file mode 100644
index c748d5fb47fa..000000000000
--- a/drivers/staging/rtl8723au/include/odm_HWConfig.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-
-#ifndef __HALHWOUTSRC_H__
-#define __HALHWOUTSRC_H__
-
-#include <Hal8723APhyCfg.h>
-
-/* */
-/* Definition */
-/* */
-/* */
-/* */
-/* CCK Rates, TxHT = 0 */
-#define DESC92C_RATE1M 0x00
-#define DESC92C_RATE2M 0x01
-#define DESC92C_RATE5_5M 0x02
-#define DESC92C_RATE11M 0x03
-
-/* OFDM Rates, TxHT = 0 */
-#define DESC92C_RATE6M 0x04
-#define DESC92C_RATE9M 0x05
-#define DESC92C_RATE12M 0x06
-#define DESC92C_RATE18M 0x07
-#define DESC92C_RATE24M 0x08
-#define DESC92C_RATE36M 0x09
-#define DESC92C_RATE48M 0x0a
-#define DESC92C_RATE54M 0x0b
-
-/* MCS Rates, TxHT = 1 */
-#define DESC92C_RATEMCS0 0x0c
-#define DESC92C_RATEMCS1 0x0d
-#define DESC92C_RATEMCS2 0x0e
-#define DESC92C_RATEMCS3 0x0f
-#define DESC92C_RATEMCS4 0x10
-#define DESC92C_RATEMCS5 0x11
-#define DESC92C_RATEMCS6 0x12
-#define DESC92C_RATEMCS7 0x13
-#define DESC92C_RATEMCS8 0x14
-#define DESC92C_RATEMCS9 0x15
-#define DESC92C_RATEMCS10 0x16
-#define DESC92C_RATEMCS11 0x17
-#define DESC92C_RATEMCS12 0x18
-#define DESC92C_RATEMCS13 0x19
-#define DESC92C_RATEMCS14 0x1a
-#define DESC92C_RATEMCS15 0x1b
-#define DESC92C_RATEMCS15_SG 0x1c
-#define DESC92C_RATEMCS32 0x20
-
-
-/* */
-/* structure and define */
-/* */
-
-struct phy_rx_agc_info {
- #ifdef __LITTLE_ENDIAN
- u8 gain:7, trsw:1;
- #else
- u8 trsw:1, gain:7;
- #endif
-};
-
-struct phy_status_rpt {
- struct phy_rx_agc_info path_agc[RF_PATH_MAX];
- u8 ch_corr[RF_PATH_MAX];
- u8 cck_sig_qual_ofdm_pwdb_all;
- u8 cck_agc_rpt_ofdm_cfosho_a;
- u8 cck_rpt_b_ofdm_cfosho_b;
- u8 rsvd_1;/* ch_corr_msb; */
- u8 noise_power_db_msb;
- u8 path_cfotail[RF_PATH_MAX];
- u8 pcts_mask[RF_PATH_MAX];
- s8 stream_rxevm[RF_PATH_MAX];
- u8 path_rxsnr[RF_PATH_MAX];
- u8 noise_power_db_lsb;
- u8 rsvd_2[3];
- u8 stream_csi[RF_PATH_MAX];
- u8 stream_target_csi[RF_PATH_MAX];
- s8 sig_evm;
- u8 rsvd_3;
-
-#ifdef __LITTLE_ENDIAN
- u8 antsel_rx_keep_2:1; /* ex_intf_flg:1; */
- u8 sgi_en:1;
- u8 rxsc:2;
- u8 idle_long:1;
- u8 r_ant_train_en:1;
- u8 ant_sel_b:1;
- u8 ant_sel:1;
-#else /* _BIG_ENDIAN_ */
- u8 ant_sel:1;
- u8 ant_sel_b:1;
- u8 r_ant_train_en:1;
- u8 idle_long:1;
- u8 rxsc:2;
- u8 sgi_en:1;
- u8 antsel_rx_keep_2:1; /* ex_intf_flg:1; */
-#endif
-};
-
-
-struct phy_status_rpt_8195 {
- struct phy_rx_agc_info path_agc[2];
- u8 ch_num[2];
- u8 cck_sig_qual_ofdm_pwdb_all;
- u8 cck_agc_rpt_ofdm_cfosho_a;
- u8 cck_bb_pwr_ofdm_cfosho_b;
- u8 cck_rx_path; /* CCK_RX_PATH [3:0] (with regA07[3:0] definition) */
- u8 rsvd_1;
- u8 path_cfotail[2];
- u8 pcts_mask[2];
- s8 stream_rxevm[2];
- u8 path_rxsnr[2];
- u8 rsvd_2[2];
- u8 stream_snr[2];
- u8 stream_csi[2];
- u8 rsvd_3[2];
- s8 sig_evm;
- u8 rsvd_4;
-#ifdef __LITTLE_ENDIAN
- u8 antidx_anta:3;
- u8 antidx_antb:3;
- u8 rsvd_5:2;
-#else /* _BIG_ENDIAN_ */
- u8 rsvd_5:2;
- u8 antidx_antb:3;
- u8 antidx_anta:3;
-#endif
-};
-
-
-void
-ODM_PhyStatusQuery23a(
- struct dm_odm_t *pDM_Odm,
- struct phy_info *pPhyInfo,
- u8 * pPhyStatus,
- struct odm_packet_info *pPktinfo
- );
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h b/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h
deleted file mode 100644
index f2a54d829ed5..000000000000
--- a/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __INC_ODM_REGCONFIG_H_8723A
-#define __INC_ODM_REGCONFIG_H_8723A
-
-void odm_ConfigRFReg_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, u32 Data,
- enum RF_RADIO_PATH RF_PATH, u32 RegAddr);
-
-void odm_ConfigMAC_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, u8 Data);
-
-void odm_ConfigBB_AGC_8723A(struct dm_odm_t *pDM_Odm, u32 addr, u32 data);
-
-void odm_ConfigBB_PHY_8723A(struct dm_odm_t *pDM_Odm, u32 addr, u32 data);
-
-#endif /* end of SUPPORT */
diff --git a/drivers/staging/rtl8723au/include/odm_RegDefine11N.h b/drivers/staging/rtl8723au/include/odm_RegDefine11N.h
deleted file mode 100644
index 27782154f502..000000000000
--- a/drivers/staging/rtl8723au/include/odm_RegDefine11N.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-#ifndef __ODM_REGDEFINE11N_H__
-#define __ODM_REGDEFINE11N_H__
-
-
-/* 2 RF REG LIST */
-#define ODM_REG_RF_MODE_11N 0x00
-#define ODM_REG_RF_0B_11N 0x0B
-#define ODM_REG_CHNBW_11N 0x18
-#define ODM_REG_T_METER_11N 0x24
-#define ODM_REG_RF_25_11N 0x25
-#define ODM_REG_RF_26_11N 0x26
-#define ODM_REG_RF_27_11N 0x27
-#define ODM_REG_RF_2B_11N 0x2B
-#define ODM_REG_RF_2C_11N 0x2C
-#define ODM_REG_RXRF_A3_11N 0x3C
-#define ODM_REG_T_METER_92D_11N 0x42
-#define ODM_REG_T_METER_88E_11N 0x42
-
-
-
-/* 2 BB REG LIST */
-/* PAGE 8 */
-#define ODM_REG_BB_CTRL_11N 0x800
-#define ODM_REG_RF_PIN_11N 0x804
-#define ODM_REG_PSD_CTRL_11N 0x808
-#define ODM_REG_TX_ANT_CTRL_11N 0x80C
-#define ODM_REG_BB_PWR_SAV5_11N 0x818
-#define ODM_REG_CCK_RPT_FORMAT_11N 0x824
-#define ODM_REG_RX_DEFUALT_A_11N 0x858
-#define ODM_REG_RX_DEFUALT_B_11N 0x85A
-#define ODM_REG_BB_PWR_SAV3_11N 0x85C
-#define ODM_REG_ANTSEL_CTRL_11N 0x860
-#define ODM_REG_RX_ANT_CTRL_11N 0x864
-#define ODM_REG_PIN_CTRL_11N 0x870
-#define ODM_REG_BB_PWR_SAV1_11N 0x874
-#define ODM_REG_ANTSEL_PATH_11N 0x878
-#define ODM_REG_BB_3WIRE_11N 0x88C
-#define ODM_REG_SC_CNT_11N 0x8C4
-#define ODM_REG_PSD_DATA_11N 0x8B4
-/* PAGE 9 */
-#define ODM_REG_ANT_MAPPING1_11N 0x914
-#define ODM_REG_ANT_MAPPING2_11N 0x918
-/* PAGE A */
-#define ODM_REG_CCK_ANTDIV_PARA1_11N 0xA00
-#define ODM_REG_CCK_CCA_11N 0xA0A
-#define ODM_REG_CCK_ANTDIV_PARA2_11N 0xA0C
-#define ODM_REG_CCK_ANTDIV_PARA3_11N 0xA10
-#define ODM_REG_CCK_ANTDIV_PARA4_11N 0xA14
-#define ODM_REG_CCK_FILTER_PARA1_11N 0xA22
-#define ODM_REG_CCK_FILTER_PARA2_11N 0xA23
-#define ODM_REG_CCK_FILTER_PARA3_11N 0xA24
-#define ODM_REG_CCK_FILTER_PARA4_11N 0xA25
-#define ODM_REG_CCK_FILTER_PARA5_11N 0xA26
-#define ODM_REG_CCK_FILTER_PARA6_11N 0xA27
-#define ODM_REG_CCK_FILTER_PARA7_11N 0xA28
-#define ODM_REG_CCK_FILTER_PARA8_11N 0xA29
-#define ODM_REG_CCK_FA_RST_11N 0xA2C
-#define ODM_REG_CCK_FA_MSB_11N 0xA58
-#define ODM_REG_CCK_FA_LSB_11N 0xA5C
-#define ODM_REG_CCK_CCA_CNT_11N 0xA60
-#define ODM_REG_BB_PWR_SAV4_11N 0xA74
-/* PAGE B */
-#define ODM_REG_LNA_SWITCH_11N 0xB2C
-#define ODM_REG_PATH_SWITCH_11N 0xB30
-#define ODM_REG_RSSI_CTRL_11N 0xB38
-#define ODM_REG_CONFIG_ANTA_11N 0xB68
-#define ODM_REG_RSSI_BT_11N 0xB9C
-/* PAGE C */
-#define ODM_REG_OFDM_FA_HOLDC_11N 0xC00
-#define ODM_REG_RX_PATH_11N 0xC04
-#define ODM_REG_TRMUX_11N 0xC08
-#define ODM_REG_OFDM_FA_RSTC_11N 0xC0C
-#define ODM_REG_RXIQI_MATRIX_11N 0xC14
-#define ODM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C
-#define ODM_REG_IGI_A_11N 0xC50
-#define ODM_REG_ANTDIV_PARA2_11N 0xC54
-#define ODM_REG_IGI_B_11N 0xC58
-#define ODM_REG_ANTDIV_PARA3_11N 0xC5C
-#define ODM_REG_BB_PWR_SAV2_11N 0xC70
-#define ODM_REG_RX_OFF_11N 0xC7C
-#define ODM_REG_TXIQK_MATRIXA_11N 0xC80
-#define ODM_REG_TXIQK_MATRIXB_11N 0xC88
-#define ODM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94
-#define ODM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C
-#define ODM_REG_RXIQK_MATRIX_LSB_11N 0xCA0
-#define ODM_REG_ANTDIV_PARA1_11N 0xCA4
-#define ODM_REG_OFDM_FA_TYPE1_11N 0xCF0
-/* PAGE D */
-#define ODM_REG_OFDM_FA_RSTD_11N 0xD00
-#define ODM_REG_OFDM_FA_TYPE2_11N 0xDA0
-#define ODM_REG_OFDM_FA_TYPE3_11N 0xDA4
-#define ODM_REG_OFDM_FA_TYPE4_11N 0xDA8
-/* PAGE E */
-#define ODM_REG_TXAGC_A_6_18_11N 0xE00
-#define ODM_REG_TXAGC_A_24_54_11N 0xE04
-#define ODM_REG_TXAGC_A_1_MCS32_11N 0xE08
-#define ODM_REG_TXAGC_A_MCS0_3_11N 0xE10
-#define ODM_REG_TXAGC_A_MCS4_7_11N 0xE14
-#define ODM_REG_TXAGC_A_MCS8_11_11N 0xE18
-#define ODM_REG_TXAGC_A_MCS12_15_11N 0xE1C
-#define ODM_REG_FPGA0_IQK_11N 0xE28
-#define ODM_REG_TXIQK_TONE_A_11N 0xE30
-#define ODM_REG_RXIQK_TONE_A_11N 0xE34
-#define ODM_REG_TXIQK_PI_A_11N 0xE38
-#define ODM_REG_RXIQK_PI_A_11N 0xE3C
-#define ODM_REG_TXIQK_11N 0xE40
-#define ODM_REG_RXIQK_11N 0xE44
-#define ODM_REG_IQK_AGC_PTS_11N 0xE48
-#define ODM_REG_IQK_AGC_RSP_11N 0xE4C
-#define ODM_REG_BLUETOOTH_11N 0xE6C
-#define ODM_REG_RX_WAIT_CCA_11N 0xE70
-#define ODM_REG_TX_CCK_RFON_11N 0xE74
-#define ODM_REG_TX_CCK_BBON_11N 0xE78
-#define ODM_REG_OFDM_RFON_11N 0xE7C
-#define ODM_REG_OFDM_BBON_11N 0xE80
-#define ODM_REG_TX2RX_11N 0xE84
-#define ODM_REG_TX2TX_11N 0xE88
-#define ODM_REG_RX_CCK_11N 0xE8C
-#define ODM_REG_RX_OFDM_11N 0xED0
-#define ODM_REG_RX_WAIT_RIFS_11N 0xED4
-#define ODM_REG_RX2RX_11N 0xED8
-#define ODM_REG_STANDBY_11N 0xEDC
-#define ODM_REG_SLEEP_11N 0xEE0
-#define ODM_REG_PMPD_ANAEN_11N 0xEEC
-
-
-
-
-
-
-
-/* 2 MAC REG LIST */
-#define ODM_REG_BB_RST_11N 0x02
-#define ODM_REG_ANTSEL_PIN_11N 0x4C
-#define ODM_REG_EARLY_MODE_11N 0x4D0
-#define ODM_REG_RSSI_MONITOR_11N 0x4FE
-#define ODM_REG_EDCA_VO_11N 0x500
-#define ODM_REG_EDCA_VI_11N 0x504
-#define ODM_REG_EDCA_BE_11N 0x508
-#define ODM_REG_EDCA_BK_11N 0x50C
-#define ODM_REG_TXPAUSE_11N 0x522
-#define ODM_REG_RESP_TX_11N 0x6D8
-#define ODM_REG_ANT_TRAIN_PARA1_11N 0x7b0
-#define ODM_REG_ANT_TRAIN_PARA2_11N 0x7b4
-
-
-/* DIG Related */
-#define ODM_BIT_IGI_11N 0x0000007F
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/odm_debug.h b/drivers/staging/rtl8723au/include/odm_debug.h
deleted file mode 100644
index c4b375a6f409..000000000000
--- a/drivers/staging/rtl8723au/include/odm_debug.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-
-#ifndef __ODM_DBG_H__
-#define __ODM_DBG_H__
-
-
-/* */
-/* Define the debug levels */
-/* */
-/* 1. DBG_TRACE and DBG_LOUD are used for normal cases. */
-/* So that, they can help SW engineer to develop or trace states changed */
-/* and also help HW enginner to trace every operation to and from HW, */
-/* e.g IO, Tx, Rx. */
-/* */
-/* 2. DBG_WARNNING and DBG_SERIOUS are used for unusual or error cases, */
-/* which help us to debug SW or HW. */
-/* */
-/* */
-/* */
-/* Never used in a call to ODM_RT_TRACE()! */
-/* */
-#define ODM_DBG_OFF 1
-
-/* */
-/* Fatal bug. */
-/* For example, Tx/Rx/IO locked up, OS hangs, memory access violation, */
-/* resource allocation failed, unexpected HW behavior, HW BUG and so on. */
-/* */
-#define ODM_DBG_SERIOUS 2
-
-/* */
-/* Abnormal, rare, or unexpeted cases. */
-/* For example, IRP/Packet/OID canceled, device suprisely unremoved and so on. */
-/* */
-#define ODM_DBG_WARNING 3
-
-/* */
-/* Normal case with useful information about current SW or HW state. */
-/* For example, Tx/Rx descriptor to fill, Tx/Rx descriptor completed status, */
-/* SW protocol state change, dynamic mechanism state change and so on. */
-/* */
-#define ODM_DBG_LOUD 4
-
-/* */
-/* Normal case with detail execution flow or information. */
-/* */
-#define ODM_DBG_TRACE 5
-
-/* */
-/* Define the tracing components */
-/* */
-/* */
-/* BB Functions */
-#define ODM_COMP_DIG BIT(0)
-#define ODM_COMP_RA_MASK BIT(1)
-#define ODM_COMP_DYNAMIC_TXPWR BIT(2)
-#define ODM_COMP_FA_CNT BIT(3)
-#define ODM_COMP_RSSI_MONITOR BIT(4)
-#define ODM_COMP_CCK_PD BIT(5)
-#define ODM_COMP_ANT_DIV BIT(6)
-#define ODM_COMP_PWR_SAVE BIT(7)
-#define ODM_COMP_PWR_TRAIN BIT(8)
-#define ODM_COMP_RATE_ADAPTIVE BIT(9)
-#define ODM_COMP_PATH_DIV BIT(10)
-#define ODM_COMP_PSD BIT(11)
-#define ODM_COMP_DYNAMIC_PRICCA BIT(12)
-#define ODM_COMP_RXHP BIT(13)
-/* MAC Functions */
-#define ODM_COMP_EDCA_TURBO BIT(16)
-#define ODM_COMP_EARLY_MODE BIT(17)
-/* RF Functions */
-#define ODM_COMP_TX_PWR_TRACK BIT(24)
-#define ODM_COMP_RX_GAIN_TRACK BIT(25)
-#define ODM_COMP_CALIBRATION BIT(26)
-/* Common Functions */
-#define ODM_COMP_COMMON BIT(30)
-#define ODM_COMP_INIT BIT(31)
-
-/*------------------------Export Macro Definition---------------------------*/
- #define RT_PRINTK(fmt, args...) printk("%s(): " fmt, __func__, ## args);
-
-#ifndef ASSERT
- #define ASSERT(expr)
-#endif
-
-#define ODM_RT_TRACE(pDM_Odm, comp, level, fmt) \
- if(((comp) & pDM_Odm->DebugComponents) && (level <= pDM_Odm->DebugLevel)) \
- { \
- printk("[ODM-8723A] "); \
- RT_PRINTK fmt; \
- }
-
-#define ODM_RT_ASSERT(pDM_Odm, expr, fmt) \
- if(!(expr)) { \
- printk("Assertion failed! %s at ......\n", #expr); \
- printk(" ......%s,%s,line=%d\n", __FILE__, __func__, __LINE__);\
- RT_PRINTK fmt; \
- ASSERT(false); \
- }
-
-void ODM_InitDebugSetting23a(struct dm_odm_t *pDM_Odm);
-
-#endif /* __ODM_DBG_H__ */
diff --git a/drivers/staging/rtl8723au/include/odm_interface.h b/drivers/staging/rtl8723au/include/odm_interface.h
deleted file mode 100644
index 1d3bf03b59ea..000000000000
--- a/drivers/staging/rtl8723au/include/odm_interface.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-
-#ifndef __ODM_INTERFACE_H__
-#define __ODM_INTERFACE_H__
-
-
-/* _cat: implemented by Token-Pasting Operator. */
-
-/*===================================
-
-#define ODM_REG_DIG_11N 0xC50
-#define ODM_REG_DIG_11AC 0xDDD
-
-ODM_REG(DIG,_pDM_Odm)
-=====================================*/
-
-#define _reg_11N(_name) ODM_REG_##_name##_11N
-#define _reg_11AC(_name) ODM_REG_##_name##_11AC
-#define _bit_11N(_name) ODM_BIT_##_name##_11N
-#define _bit_11AC(_name) ODM_BIT_##_name##_11AC
-
-#define _cat(_name, _func) \
- ( \
- _func##_11N(_name) \
- )
-
-/* _name: name of register or bit. */
-/* Example: "ODM_REG(R_A_AGC_CORE1, pDM_Odm)" */
-/* gets "ODM_R_A_AGC_CORE1" or "ODM_R_A_AGC_CORE1_8192C", depends on SupportICType. */
-#define ODM_REG(_name, _pDM_Odm) _cat(_name, _reg)
-#define ODM_BIT(_name, _pDM_Odm) _cat(_name, _bit)
-
-/* */
-/* 2012/02/17 MH For non-MP compile pass only. Linux does not support workitem. */
-/* Suggest HW team to use thread instead of workitem. Windows also support the feature. */
-/* */
-typedef void (*RT_WORKITEM_CALL_BACK)(struct work_struct *pContext);
-
-/* */
-/* =========== EXtern Function Prototype */
-/* */
-
-void ODM_SetRFReg(struct dm_odm_t *pDM_Odm, enum RF_RADIO_PATH eRFPath,
- u32 RegAddr, u32 BitMask, u32 Data);
-u32 ODM_GetRFReg(struct dm_odm_t *pDM_Odm, enum RF_RADIO_PATH eRFPath,
- u32 RegAddr, u32 BitMask);
-
-#endif /* __ODM_INTERFACE_H__ */
diff --git a/drivers/staging/rtl8723au/include/odm_precomp.h b/drivers/staging/rtl8723au/include/odm_precomp.h
deleted file mode 100644
index fb793c8ba7f8..000000000000
--- a/drivers/staging/rtl8723au/include/odm_precomp.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-#ifndef __ODM_PRECOMP_H__
-#define __ODM_PRECOMP_H__
-
-/* 2 Config Flags and Structs - defined by each ODM Type */
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <hal_intf.h>
-
-
-/* 2 Hardware Parameter Files */
-#include "Hal8723UHWImg_CE.h"
-
-
-/* 2 OutSrc Header Files */
-
-#include "odm.h"
-#include "odm_HWConfig.h"
-#include "odm_debug.h"
-#include "odm_RegDefine11N.h"
-
-#include "HalDMOutSrc8723A.h" /* for IQK,LCK,Power-tracking */
-#include "rtl8723a_hal.h"
-
-#include "odm_interface.h"
-#include "odm_reg.h"
-
-#include "HalHWImg8723A_MAC.h"
-#include "HalHWImg8723A_RF.h"
-#include "HalHWImg8723A_BB.h"
-#include "HalHWImg8723A_FW.h"
-#include "odm_RegConfig8723A.h"
-
-#endif /* __ODM_PRECOMP_H__ */
diff --git a/drivers/staging/rtl8723au/include/odm_reg.h b/drivers/staging/rtl8723au/include/odm_reg.h
deleted file mode 100644
index c18433120fe8..000000000000
--- a/drivers/staging/rtl8723au/include/odm_reg.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-/* */
-/* File Name: odm_reg.h */
-/* */
-/* Description: */
-/* */
-/* This file is for general register definition. */
-/* */
-/* */
-/* */
-#ifndef __HAL_ODM_REG_H__
-#define __HAL_ODM_REG_H__
-
-/* */
-/* Register Definition */
-/* */
-
-/* MAC REG */
-#define ODM_BB_RESET 0x002
-#define ODM_DUMMY 0x4fe
-#define ODM_EDCA_VO_PARAM 0x500
-#define ODM_EDCA_VI_PARAM 0x504
-#define ODM_EDCA_BE_PARAM 0x508
-#define ODM_EDCA_BK_PARAM 0x50C
-#define ODM_TXPAUSE 0x522
-
-/* BB REG */
-#define ODM_FPGA_PHY0_PAGE8 0x800
-#define ODM_PSD_SETTING 0x808
-#define ODM_AFE_SETTING 0x818
-#define ODM_TXAGC_B_6_18 0x830
-#define ODM_TXAGC_B_24_54 0x834
-#define ODM_TXAGC_B_MCS32_5 0x838
-#define ODM_TXAGC_B_MCS0_MCS3 0x83c
-#define ODM_TXAGC_B_MCS4_MCS7 0x848
-#define ODM_TXAGC_B_MCS8_MCS11 0x84c
-#define ODM_ANALOG_REGISTER 0x85c
-#define ODM_RF_INTERFACE_OUTPUT 0x860
-#define ODM_TXAGC_B_MCS12_MCS15 0x868
-#define ODM_TXAGC_B_11_A_2_11 0x86c
-#define ODM_AD_DA_LSB_MASK 0x874
-#define ODM_ENABLE_3_WIRE 0x88c
-#define ODM_PSD_REPORT 0x8b4
-#define ODM_R_ANT_SELECT 0x90c
-#define ODM_CCK_ANT_SELECT 0xa07
-#define ODM_CCK_PD_THRESH 0xa0a
-#define ODM_CCK_RF_REG1 0xa11
-#define ODM_CCK_MATCH_FILTER 0xa20
-#define ODM_CCK_RAKE_MAC 0xa2e
-#define ODM_CCK_CNT_RESET 0xa2d
-#define ODM_CCK_TX_DIVERSITY 0xa2f
-#define ODM_CCK_FA_CNT_MSB 0xa5b
-#define ODM_CCK_FA_CNT_LSB 0xa5c
-#define ODM_CCK_NEW_FUNCTION 0xa75
-#define ODM_OFDM_PHY0_PAGE_C 0xc00
-#define ODM_OFDM_RX_ANT 0xc04
-#define ODM_R_A_RXIQI 0xc14
-#define ODM_R_A_AGC_CORE1 0xc50
-#define ODM_R_A_AGC_CORE2 0xc54
-#define ODM_R_B_AGC_CORE1 0xc58
-#define ODM_R_AGC_PAR 0xc70
-#define ODM_R_HTSTF_AGC_PAR 0xc7c
-#define ODM_TX_PWR_TRAINING_A 0xc90
-#define ODM_TX_PWR_TRAINING_B 0xc98
-#define ODM_OFDM_FA_CNT1 0xcf0
-#define ODM_OFDM_PHY0_PAGE_D 0xd00
-#define ODM_OFDM_FA_CNT2 0xda0
-#define ODM_OFDM_FA_CNT3 0xda4
-#define ODM_OFDM_FA_CNT4 0xda8
-#define ODM_TXAGC_A_6_18 0xe00
-#define ODM_TXAGC_A_24_54 0xe04
-#define ODM_TXAGC_A_1_MCS32 0xe08
-#define ODM_TXAGC_A_MCS0_MCS3 0xe10
-#define ODM_TXAGC_A_MCS4_MCS7 0xe14
-#define ODM_TXAGC_A_MCS8_MCS11 0xe18
-#define ODM_TXAGC_A_MCS12_MCS15 0xe1c
-
-/* RF REG */
-#define ODM_GAIN_SETTING 0x00
-#define ODM_CHANNEL 0x18
-
-/* Ant Detect Reg */
-#define ODM_DPDT 0x300
-
-/* PSD Init */
-#define ODM_PSDREG 0x808
-
-/* 92D Path Div */
-#define PATHDIV_REG 0xB30
-#define PATHDIV_TRI 0xBA0
-
-/* */
-/* Bitmap Definition */
-/* */
-
-#define BIT_FA_RESET BIT(0)
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/osdep_intf.h b/drivers/staging/rtl8723au/include/osdep_intf.h
deleted file mode 100644
index a157eb2e78df..000000000000
--- a/drivers/staging/rtl8723au/include/osdep_intf.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-#ifndef __OSDEP_INTF_H_
-#define __OSDEP_INTF_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-int rtw_init_drv_sw23a(struct rtw_adapter *padapter);
-int rtw_free_drv_sw23a(struct rtw_adapter *padapter);
-int rtw_reset_drv_sw23a(struct rtw_adapter *padapter);
-
-void rtw_cancel_all_timer23a(struct rtw_adapter *padapter);
-
-int rtw_init_netdev23a_name23a(struct net_device *pnetdev, const char *ifname);
-struct net_device *rtw_init_netdev23a(struct rtw_adapter *padapter);
-
-u16 rtw_recv_select_queue23a(struct sk_buff *skb);
-
-void rtw_ips_dev_unload23a(struct rtw_adapter *padapter);
-
-int rtw_ips_pwr_up23a(struct rtw_adapter *padapter);
-void rtw_ips_pwr_down23a(struct rtw_adapter *padapter);
-
-int rtw_drv_register_netdev(struct rtw_adapter *padapter);
-void rtw_ndev_destructor(struct net_device *ndev);
-
-int rtl8723au_inirp_init(struct rtw_adapter *Adapter);
-int rtl8723au_inirp_deinit(struct rtw_adapter *Adapter);
-void rtl8723a_usb_intf_stop(struct rtw_adapter *padapter);
-
-#endif /* _OSDEP_INTF_H_ */
diff --git a/drivers/staging/rtl8723au/include/osdep_service.h b/drivers/staging/rtl8723au/include/osdep_service.h
deleted file mode 100644
index 98250b12e9f2..000000000000
--- a/drivers/staging/rtl8723au/include/osdep_service.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __OSDEP_SERVICE_H_
-#define __OSDEP_SERVICE_H_
-
-#define _FAIL 0
-#define _SUCCESS 1
-#define RTW_RX_HANDLED 2
-
-#include <linux/spinlock.h>
-#include <linux/compiler.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kref.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <linux/uaccess.h>
-#include <asm/byteorder.h>
-#include <linux/atomic.h>
-#include <linux/io.h>
-#include <linux/semaphore.h>
-#include <linux/sem.h>
-#include <linux/sched.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-#include <linux/if_arp.h>
-#include <linux/rtnetlink.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h> /* for struct tasklet_struct */
-#include <linux/ip.h>
-
-#include <net/ieee80211_radiotap.h>
-#include <net/cfg80211.h>
-
-struct rtw_queue {
- struct list_head queue;
- spinlock_t lock;
-};
-
-static inline struct list_head *get_list_head(struct rtw_queue *queue)
-{
- return &queue->queue;
-}
-
-static inline int rtw_netif_queue_stopped(struct net_device *pnetdev)
-{
- return (netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 0)) &&
- netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 1)) &&
- netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 2)) &&
- netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 3)));
-}
-
-static inline u32 CHKBIT(u32 x)
-{
- WARN_ON(x >= 32);
- if (x >= 32)
- return 0;
- return BIT(x);
-}
-
-extern unsigned char MCS_rate_2R23A[16];
-
-extern unsigned char MCS_rate_2R23A[16];
-extern unsigned char MCS_rate_1R23A[16];
-
-void _rtw_init_queue23a(struct rtw_queue *pqueue);
-
-/* Macros for handling unaligned memory accesses */
-
-#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \
- ((u32) (a)[2]))
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/recv_osdep.h b/drivers/staging/rtl8723au/include/recv_osdep.h
deleted file mode 100644
index c2d3f1bd5948..000000000000
--- a/drivers/staging/rtl8723au/include/recv_osdep.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RECV_OSDEP_H_
-#define __RECV_OSDEP_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-int _rtw_init_recv_priv23a(struct recv_priv *precvpriv, struct rtw_adapter *padapter);
-void _rtw_free_recv_priv23a (struct recv_priv *precvpriv);
-
-int rtw_recv_entry23a(struct recv_frame *precv_frame);
-int rtw_recv_indicatepkt23a(struct rtw_adapter *adapter, struct recv_frame *precv_frame);
-
-void rtw_handle_tkip_mic_err23a(struct rtw_adapter *padapter, u8 bgroup);
-
-int rtw_init_recv_priv(struct recv_priv *precvpriv, struct rtw_adapter *padapter);
-void rtw_free_recv_priv (struct recv_priv *precvpriv);
-
-int rtw_os_recv_resource_init(struct recv_priv *precvpriv, struct rtw_adapter *padapter);
-
-void rtw_init_recv_timer23a(struct recv_reorder_ctrl *preorder_ctrl);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h b/drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h
deleted file mode 100644
index 7add5dfe015f..000000000000
--- a/drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h
+++ /dev/null
@@ -1,1627 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTL8723A_BT_COEXIST_H__
-#define __RTL8723A_BT_COEXIST_H__
-
-#include <drv_types.h>
-#include "odm_precomp.h"
-
-
-/* HEADER/PlatformDef.h */
-enum rt_media_status {
- RT_MEDIA_DISCONNECT = 0,
- RT_MEDIA_CONNECT = 1
-};
-
-/* ===== Below this line is sync from SD7 driver COMMON/BT.h ===== */
-
-#define BT_TMP_BUF_SIZE 100
-
-void BT_SignalCompensation(struct rtw_adapter *padapter,
- u8 *rssi_wifi, u8 *rssi_bt);
-void BT_HaltProcess(struct rtw_adapter *padapter);
-void BT_LpsLeave(struct rtw_adapter *padapter);
-
-
-#define BT_HsConnectionEstablished(Adapter) false
-/* ===== End of sync from SD7 driver COMMON/BT.h ===== */
-
-/* HEADER/SecurityType.h */
-#define TKIP_ENC_KEY_POS 32 /* KEK_LEN+KEK_LEN) */
-#define MAXRSNIELEN 256
-
-/* COMMON/Protocol802_11.h */
-/* */
-/* 802.11 Management frame Status Code field */
-/* */
-struct octet_string {
- u8 *Octet;
- u16 Length;
-};
-
-
-/* AES_CCMP specific */
-enum {
- AESCCMP_BLK_SIZE = 16, /* # octets in an AES block */
- AESCCMP_MAX_PACKET = 4*512, /* largest packet size */
- AESCCMP_N_RESERVED = 0, /* reserved nonce octet value */
- AESCCMP_A_DATA = 0x40, /* the Adata bit in the flags */
- AESCCMP_M_SHIFT = 3, /* how much to shift the 3-bit M field */
- AESCCMP_L_SHIFT = 0, /* how much to shift the 3-bit L field */
- AESCCMP_L_SIZE = 2, /* size of the l(m) length field (in octets) */
- AESCCMP_OFFSET_SC = 22,
- AESCCMP_OFFSET_DURATION = 4,
- AESCCMP_OFFSET_A2 = 10,
- AESCCMP_OFFSET_A4 = 24,
- AESCCMP_QC_TID_MASK = 0x0f,
- AESCCMP_BLK_SIZE_TOTAL = 16*16, /* Added by Annie for CKIP AES MIC BSOD, 2006-08-17. */
- /* 16*8 < 4*60 Resove to 16*16 */
-};
-
-/* Key Length */
-#define PMK_LEN 32
-#define PTK_LEN_TKIP 64
-#define GTK_LEN 32
-#define KEY_NONCE_LEN 32
-
-
-/* COMMON/Dot11d.h */
-struct chnl_txpower_triple {
- u8 FirstChnl;
- u8 NumChnls;
- s8 MaxTxPowerInDbm;
-};
-
-
-/* ===== Below this line is sync from SD7 driver COMMON/bt_hci.h ===== */
-/* The following is for BT 3.0 + HS HCI COMMAND ERRORS CODES */
-
-#define Max80211PALPDUSize 1492
-#define Max80211AMPASSOCLen 672
-#define MinGUserPrio 4
-#define MaxGUserPrio 7
-#define BEUserPrio0 0
-#define BEUserPrio1 3
-#define Max80211BeaconPeriod 2000
-#define ShortRangeModePowerMax 4
-
-#define BT_Default_Chnl 10
-#define ACLDataHeaderLen 4
-
-#define BTTotalDataBlockNum 0x100
-#define BTLocalBufNum 0x200
-#define BTMaxDataBlockLen 0x800
-#define BTTOTALBANDWIDTH 0x7530
-#define BTMAXBANDGUBANDWIDTH 0x4e20
-#define TmpLocalBufSize 0x100
-#define BTSynDataPacketLength 0xff
-/* */
-
-#define BTMaxAuthCount 5
-#define BTMaxAsocCount 5
-
-#define MAX_LOGICAL_LINK_NUM 2 /* temporarily define */
-#define MAX_BT_ASOC_ENTRY_NUM 2 /* temporarily define */
-
-#define INVALID_PL_HANDLE 0xff
-#define INVALID_ENTRY_NUM 0xff
-/* */
-
-#define CAM_BT_START_INDEX (HALF_CAM_ENTRY - 4) /* MAX_BT_ASOC_ENTRY_NUM : 4 !!! */
-#define BT_HWCAM_STAR CAM_BT_START_INDEX /* We used HALF_CAM_ENTRY ~ HALF_CAM_ENTRY -MAX_BT_ASOC_ENTRY_NUM */
-
-enum hci_status {
- HCI_STATUS_SUCCESS = 0x00, /* Success */
- HCI_STATUS_UNKNOW_HCI_CMD = 0x01, /* Unknown HCI Command */
- HCI_STATUS_UNKNOW_CONNECT_ID = 0X02, /* Unknown Connection Identifier */
- HCI_STATUS_HW_FAIL = 0X03, /* Hardware Failure */
- HCI_STATUS_PAGE_TIMEOUT = 0X04, /* Page Timeout */
- HCI_STATUS_AUTH_FAIL = 0X05, /* Authentication Failure */
- HCI_STATUS_PIN_OR_KEY_MISSING = 0X06, /* PIN or Key Missing */
- HCI_STATUS_MEM_CAP_EXCEED = 0X07, /* Memory Capacity Exceeded */
- HCI_STATUS_CONNECT_TIMEOUT = 0X08, /* Connection Timeout */
- HCI_STATUS_CONNECT_LIMIT = 0X09, /* Connection Limit Exceeded */
- HCI_STATUS_SYN_CONNECT_LIMIT = 0X0a, /* Synchronous Connection Limit To A Device Exceeded */
- HCI_STATUS_ACL_CONNECT_EXISTS = 0X0b, /* ACL Connection Already Exists */
- HCI_STATUS_CMD_DISALLOW = 0X0c, /* Command Disallowed */
- HCI_STATUS_CONNECT_RJT_LIMIT_RESOURCE = 0X0d, /* Connection Rejected due to Limited Resources */
- HCI_STATUS_CONNECT_RJT_SEC_REASON = 0X0e, /* Connection Rejected Due To Security Reasons */
- HCI_STATUS_CONNECT_RJT_UNACCEPT_BD_ADDR = 0X0f, /* Connection Rejected due to Unacceptable BD_ADDR */
- HCI_STATUS_CONNECT_ACCEPT_TIMEOUT = 0X10, /* Connection Accept Timeout Exceeded */
- HCI_STATUS_UNSUPPORT_FEATURE_PARA_VALUE = 0X11, /* Unsupported Feature or Parameter Value */
- HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE = 0X12, /* Invalid HCI Command Parameters */
- HCI_STATUS_REMOTE_USER_TERMINATE_CONNECT = 0X13, /* Remote User Terminated Connection */
- HCI_STATUS_REMOTE_DEV_TERMINATE_LOW_RESOURCE = 0X14, /* Remote Device Terminated Connection due to Low Resources */
- HCI_STATUS_REMOTE_DEV_TERMINATE_CONNECT_POWER_OFF = 0X15, /* Remote Device Terminated Connection due to Power Off */
- HCI_STATUS_CONNECT_TERMINATE_LOCAL_HOST = 0X16, /* Connection Terminated By Local Host */
- HCI_STATUS_REPEATE_ATTEMPT = 0X17, /* Repeated Attempts */
- HCI_STATUS_PAIR_NOT_ALLOW = 0X18, /* Pairing Not Allowed */
- HCI_STATUS_UNKNOW_LMP_PDU = 0X19, /* Unknown LMP PDU */
- HCI_STATUS_UNSUPPORT_REMOTE_LMP_FEATURE = 0X1a, /* Unsupported Remote Feature / Unsupported LMP Feature */
- HCI_STATUS_SOC_OFFSET_REJECT = 0X1b, /* SCO Offset Rejected */
- HCI_STATUS_SOC_INTERVAL_REJECT = 0X1c, /* SCO Interval Rejected */
- HCI_STATUS_SOC_AIR_MODE_REJECT = 0X1d,/* SCO Air Mode Rejected */
- HCI_STATUS_INVALID_LMP_PARA = 0X1e, /* Invalid LMP Parameters */
- HCI_STATUS_UNSPECIFIC_ERROR = 0X1f, /* Unspecified Error */
- HCI_STATUS_UNSUPPORT_LMP_PARA_VALUE = 0X20, /* Unsupported LMP Parameter Value */
- HCI_STATUS_ROLE_CHANGE_NOT_ALLOW = 0X21, /* Role Change Not Allowed */
- HCI_STATUS_LMP_RESPONSE_TIMEOUT = 0X22, /* LMP Response Timeout */
- HCI_STATUS_LMP_ERROR_TRANSACTION_COLLISION = 0X23, /* LMP Error Transaction Collision */
- HCI_STATUS_LMP_PDU_NOT_ALLOW = 0X24, /* LMP PDU Not Allowed */
- HCI_STATUS_ENCRYPTION_MODE_NOT_ALLOW = 0X25, /* Encryption Mode Not Acceptable */
- HCI_STATUS_LINK_KEY_CAN_NOT_CHANGE = 0X26, /* Link Key Can Not be Changed */
- HCI_STATUS_REQUEST_QOS_NOT_SUPPORT = 0X27, /* Requested QoS Not Supported */
- HCI_STATUS_INSTANT_PASSED = 0X28, /* Instant Passed */
- HCI_STATUS_PAIRING_UNIT_KEY_NOT_SUPPORT = 0X29, /* Pairing With Unit Key Not Supported */
- HCI_STATUS_DIFFERENT_TRANSACTION_COLLISION = 0X2a, /* Different Transaction Collision */
- HCI_STATUS_RESERVE_1 = 0X2b, /* Reserved */
- HCI_STATUS_QOS_UNACCEPT_PARA = 0X2c, /* QoS Unacceptable Parameter */
- HCI_STATUS_QOS_REJECT = 0X2d, /* QoS Rejected */
- HCI_STATUS_CHNL_CLASSIFICATION_NOT_SUPPORT = 0X2e, /* Channel Classification Not Supported */
- HCI_STATUS_INSUFFICIENT_SECURITY = 0X2f, /* Insufficient Security */
- HCI_STATUS_PARA_OUT_OF_RANGE = 0x30, /* Parameter Out Of Mandatory Range */
- HCI_STATUS_RESERVE_2 = 0X31, /* Reserved */
- HCI_STATUS_ROLE_SWITCH_PENDING = 0X32, /* Role Switch Pending */
- HCI_STATUS_RESERVE_3 = 0X33, /* Reserved */
- HCI_STATUS_RESERVE_SOLT_VIOLATION = 0X34, /* Reserved Slot Violation */
- HCI_STATUS_ROLE_SWITCH_FAIL = 0X35, /* Role Switch Failed */
- HCI_STATUS_EXTEND_INQUIRY_RSP_TOO_LARGE = 0X36, /* Extended Inquiry Response Too Large */
- HCI_STATUS_SEC_SIMPLE_PAIRING_NOT_SUPPORT = 0X37, /* Secure Simple Pairing Not Supported By Host. */
- HCI_STATUS_HOST_BUSY_PAIRING = 0X38, /* Host Busy - Pairing */
- HCI_STATUS_CONNECT_REJ_NOT_SUIT_CHNL_FOUND = 0X39, /* Connection Rejected due to No Suitable Channel Found */
- HCI_STATUS_CONTROLLER_BUSY = 0X3a /* CONTROLLER BUSY */
-};
-
-/* */
-/* The following is for BT 3.0 + HS HCI COMMAND */
-/* */
-
-/* bit 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
-/* | OCF | OGF | */
-/* */
-
-/* OGF 0x01 */
-#define LINK_CONTROL_COMMANDS 0x01
-enum link_control_commands {
- HCI_INQUIRY = 0x0001,
- HCI_INQUIRY_CANCEL = 0x0002,
- HCI_PERIODIC_INQUIRY_MODE = 0x0003,
- HCI_EXIT_PERIODIC_INQUIRY_MODE = 0x0004,
- HCI_CREATE_CONNECTION = 0x0005,
- HCI_DISCONNECT = 0x0006,
- HCI_CREATE_CONNECTION_CANCEL = 0x0008,
- HCI_ACCEPT_CONNECTIONREQUEST = 0x0009,
- HCI_REJECT_CONNECTION_REQUEST = 0x000a,
- HCI_LINK_KEY_REQUEST_REPLY = 0x000b,
- HCI_LINK_KEY_REQUEST_NEGATIVE_REPLY = 0x000c,
- HCI_PIN_CODE_REQUEST_REPLY = 0x000d,
- HCI_PIN_CODE_REQUEST_NEGATIVE_REPLY = 0x000e,
- HCI_CHANGE_CONNECTION_PACKET_TYPE = 0x000f,
- HCI_AUTHENTICATION_REQUESTED = 0x0011,
- HCI_SET_CONNECTION_ENCRYPTION = 0x0013,
- HCI_CHANGE_CONNECTION_LINK_KEY = 0x0015,
- HCI_MASTER_LINK_KEY = 0x0017,
- HCI_REMOTE_NAME_REQUEST = 0x0019,
- HCI_REMOTE_NAME_REQUEST_CANCEL = 0x001a,
- HCI_READ_REMOTE_SUPPORTED_FEATURES = 0x001b,
- HCI_READ_REMOTE_EXTENDED_FEATURES = 0x001c,
- HCI_READ_REMOTE_VERSION_INFORMATION = 0x001d,
- HCI_READ_CLOCK_OFFSET = 0x001f,
- HCI_READ_LMP_HANDLE = 0x0020,
- HCI_SETUP_SYNCHRONOUS_CONNECTION = 0x0028,
- HCI_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST = 0x0029,
- HCI_REJECT_SYNCHRONOUS_CONNECTION_REQUEST = 0x002a,
- HCI_IO_CAPABILITY_REQUEST_REPLY = 0x002b,
- HCI_USER_CONFIRMATION_REQUEST_REPLY = 0x002c,
- HCI_USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY = 0x002d,
- HCI_USER_PASSKEY_REQUEST_REPLY = 0x002e,
- HCI_USER_PASSKEY_REQUESTNEGATIVE_REPLY = 0x002f,
- HCI_REMOTE_OOB_DATA_REQUEST_REPLY = 0x0030,
- HCI_REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY = 0x0033,
- HCI_IO_CAPABILITY_REQUEST_NEGATIVE_REPLY = 0x0034,
- HCI_CREATE_PHYSICAL_LINK = 0x0035,
- HCI_ACCEPT_PHYSICAL_LINK = 0x0036,
- HCI_DISCONNECT_PHYSICAL_LINK = 0x0037,
- HCI_CREATE_LOGICAL_LINK = 0x0038,
- HCI_ACCEPT_LOGICAL_LINK = 0x0039,
- HCI_DISCONNECT_LOGICAL_LINK = 0x003a,
- HCI_LOGICAL_LINK_CANCEL = 0x003b,
- HCI_FLOW_SPEC_MODIFY = 0x003c
-};
-
-/* OGF 0x02 */
-#define HOLD_MODE_COMMAND 0x02
-enum hold_mode_command {
- HCI_HOLD_MODE = 0x0001,
- HCI_SNIFF_MODE = 0x0002,
- HCI_EXIT_SNIFF_MODE = 0x0003,
- HCI_PARK_STATE = 0x0005,
- HCI_EXIT_PARK_STATE = 0x0006,
- HCI_QOS_SETUP = 0x0007,
- HCI_ROLE_DISCOVERY = 0x0009,
- HCI_SWITCH_ROLE = 0x000b,
- HCI_READ_LINK_POLICY_SETTINGS = 0x000c,
- HCI_WRITE_LINK_POLICY_SETTINGS = 0x000d,
- HCI_READ_DEFAULT_LINK_POLICY_SETTINGS = 0x000e,
- HCI_WRITE_DEFAULT_LINK_POLICY_SETTINGS = 0x000f,
- HCI_FLOW_SPECIFICATION = 0x0010,
- HCI_SNIFF_SUBRATING = 0x0011
-};
-
-/* OGF 0x03 */
-#define OGF_SET_EVENT_MASK_COMMAND 0x03
-enum set_event_mask_command {
- HCI_SET_EVENT_MASK = 0x0001,
- HCI_RESET = 0x0003,
- HCI_SET_EVENT_FILTER = 0x0005,
- HCI_FLUSH = 0x0008,
- HCI_READ_PIN_TYPE = 0x0009,
- HCI_WRITE_PIN_TYPE = 0x000a,
- HCI_CREATE_NEW_UNIT_KEY = 0x000b,
- HCI_READ_STORED_LINK_KEY = 0x000d,
- HCI_WRITE_STORED_LINK_KEY = 0x0011,
- HCI_DELETE_STORED_LINK_KEY = 0x0012,
- HCI_WRITE_LOCAL_NAME = 0x0013,
- HCI_READ_LOCAL_NAME = 0x0014,
- HCI_READ_CONNECTION_ACCEPT_TIMEOUT = 0x0015,
- HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT = 0x0016,
- HCI_READ_PAGE_TIMEOUT = 0x0017,
- HCI_WRITE_PAGE_TIMEOUT = 0x0018,
- HCI_READ_SCAN_ENABLE = 0x0019,
- HCI_WRITE_SCAN_ENABLE = 0x001a,
- HCI_READ_PAGE_SCAN_ACTIVITY = 0x001b,
- HCI_WRITE_PAGE_SCAN_ACTIVITY = 0x001c,
- HCI_READ_INQUIRY_SCAN_ACTIVITY = 0x001d,
- HCI_WRITE_INQUIRY_SCAN_ACTIVITY = 0x001e,
- HCI_READ_AUTHENTICATION_ENABLE = 0x001f,
- HCI_WRITE_AUTHENTICATION_ENABLE = 0x0020,
- HCI_READ_CLASS_OF_DEVICE = 0x0023,
- HCI_WRITE_CLASS_OF_DEVICE = 0x0024,
- HCI_READ_VOICE_SETTING = 0x0025,
- HCI_WRITE_VOICE_SETTING = 0x0026,
- HCI_READ_AUTOMATIC_FLUSH_TIMEOUT = 0x0027,
- HCI_WRITE_AUTOMATIC_FLUSH_TIMEOUT = 0x0028,
- HCI_READ_NUM_BROADCAST_RETRANSMISSIONS = 0x0029,
- HCI_WRITE_NUM_BROADCAST_RETRANSMISSIONS = 0x002a,
- HCI_READ_HOLD_MODE_ACTIVITY = 0x002b,
- HCI_WRITE_HOLD_MODE_ACTIVITY = 0x002c,
- HCI_READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 0x002e,
- HCI_WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 0x002f,
- HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL = 0x0031,
- HCI_HOST_BUFFER_SIZE = 0x0033,
- HCI_HOST_NUMBER_OF_COMPLETED_PACKETS = 0x0035,
- HCI_READ_LINK_SUPERVISION_TIMEOUT = 0x0036,
- HCI_WRITE_LINK_SUPERVISION_TIMEOUT = 0x0037,
- HCI_READ_NUMBER_OF_SUPPORTED_IAC = 0x0038,
- HCI_READ_CURRENT_IAC_LAP = 0x0039,
- HCI_WRITE_CURRENT_IAC_LAP = 0x003a,
- HCI_READ_PAGE_SCAN_MODE = 0x003d,
- HCI_WRITE_PAGE_SCAN_MODE = 0x003e,
- HCI_SET_AFH_HOST_CHANNEL_CLASSIFICATION = 0x003f,
- HCI_READ_INQUIRY_SCAN_TYPE = 0x0042,
- HCI_WRITE_INQUIRY_SCAN_TYPE = 0x0043,
- HCI_READ_INQUIRY_MODE = 0x0044,
- HCI_WRITE_INQUIRY_MODE = 0x0045,
- HCI_READ_PAGE_SCAN_TYPE = 0x0046,
- HCI_WRITE_PAGE_SCAN_TYPE = 0x0047,
- HCI_READ_AFH_CHANNEL_ASSESSMENT_MODE = 0x0048,
- HCI_WRITE_AFH_CHANNEL_ASSESSMENT_MODE = 0x0049,
- HCI_READ_EXTENDED_INQUIRY_RESPONSE = 0x0051,
- HCI_WRITE_EXTENDED_INQUIRY_RESPONSE = 0x0052,
- HCI_REFRESH_ENCRYPTION_KEY = 0x0053,
- HCI_READ_SIMPLE_PAIRING_MODE = 0x0055,
- HCI_WRITE_SIMPLE_PAIRING_MODE = 0x0056,
- HCI_READ_LOCAL_OOB_DATA = 0x0057,
- HCI_READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL = 0x0058,
- HCI_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL = 0x0059,
- HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING = 0x005a,
- HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING = 0x005b,
- HCI_ENHANCED_FLUSH = 0x005f,
- HCI_SEND_KEYPRESS_NOTIFICATION = 0x0060,
- HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT = 0x0061,
- HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT = 0x0062,
- HCI_SET_EVENT_MASK_PAGE_2 = 0x0063,
- HCI_READ_LOCATION_DATA = 0x0064,
- HCI_WRITE_LOCATION_DATA = 0x0065,
- HCI_READ_FLOW_CONTROL_MODE = 0x0066,
- HCI_WRITE_FLOW_CONTROL_MODE = 0x0067,
- HCI_READ_ENHANCE_TRANSMIT_POWER_LEVEL = 0x0068,
- HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT = 0x0069,
- HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT = 0x006a,
- HCI_SHORT_RANGE_MODE = 0x006b
-};
-
-/* OGF 0x04 */
-#define OGF_INFORMATIONAL_PARAMETERS 0x04
-enum informational_params {
- HCI_READ_LOCAL_VERSION_INFORMATION = 0x0001,
- HCI_READ_LOCAL_SUPPORTED_COMMANDS = 0x0002,
- HCI_READ_LOCAL_SUPPORTED_FEATURES = 0x0003,
- HCI_READ_LOCAL_EXTENDED_FEATURES = 0x0004,
- HCI_READ_BUFFER_SIZE = 0x0005,
- HCI_READ_BD_ADDR = 0x0009,
- HCI_READ_DATA_BLOCK_SIZE = 0x000a
-};
-
-/* OGF 0x05 */
-#define OGF_STATUS_PARAMETERS 0x05
-enum status_params {
- HCI_READ_FAILED_CONTACT_COUNTER = 0x0001,
- HCI_RESET_FAILED_CONTACT_COUNTER = 0x0002,
- HCI_READ_LINK_QUALITY = 0x0003,
- HCI_READ_RSSI = 0x0005,
- HCI_READ_AFH_CHANNEL_MAP = 0x0006,
- HCI_READ_CLOCK = 0x0007,
- HCI_READ_ENCRYPTION_KEY_SIZE = 0x0008,
- HCI_READ_LOCAL_AMP_INFO = 0x0009,
- HCI_READ_LOCAL_AMP_ASSOC = 0x000a,
- HCI_WRITE_REMOTE_AMP_ASSOC = 0x000b
-};
-
-/* OGF 0x06 */
-#define OGF_TESTING_COMMANDS 0x06
-enum testing_commands {
- HCI_READ_LOOPBACK_MODE = 0x0001,
- HCI_WRITE_LOOPBACK_MODE = 0x0002,
- HCI_ENABLE_DEVICE_UNDER_TEST_MODE = 0x0003,
- HCI_WRITE_SIMPLE_PAIRING_DEBUG_MODE = 0x0004,
- HCI_ENABLE_AMP_RECEIVER_REPORTS = 0x0007,
- HCI_AMP_TEST_END = 0x0008,
- HCI_AMP_TEST_COMMAND = 0x0009
-};
-
-/* OGF 0x3f */
-#define OGF_EXTENSION 0X3f
-enum hci_extension_commands {
- HCI_SET_ACL_LINK_DATA_FLOW_MODE = 0x0010,
- HCI_SET_ACL_LINK_STATUS = 0x0020,
- HCI_SET_SCO_LINK_STATUS = 0x0030,
- HCI_SET_RSSI_VALUE = 0x0040,
- HCI_SET_CURRENT_BLUETOOTH_STATUS = 0x0041,
-
- /* The following is for RTK8723 */
- HCI_EXTENSION_VERSION_NOTIFY = 0x0100,
- HCI_LINK_STATUS_NOTIFY = 0x0101,
- HCI_BT_OPERATION_NOTIFY = 0x0102,
- HCI_ENABLE_WIFI_SCAN_NOTIFY = 0x0103,
-
-
- /* The following is for IVT */
- HCI_WIFI_CURRENT_CHANNEL = 0x0300,
- HCI_WIFI_CURRENT_BANDWIDTH = 0x0301,
- HCI_WIFI_CONNECTION_STATUS = 0x0302,
-};
-
-enum bt_spec {
- BT_SPEC_1_0_b = 0x00,
- BT_SPEC_1_1 = 0x01,
- BT_SPEC_1_2 = 0x02,
- BT_SPEC_2_0_EDR = 0x03,
- BT_SPEC_2_1_EDR = 0x04,
- BT_SPEC_3_0_HS = 0x05,
- BT_SPEC_4_0 = 0x06
-};
-
-/* The following is for BT 3.0 + HS EVENTS */
-enum hci_event {
- HCI_EVENT_INQUIRY_COMPLETE = 0x01,
- HCI_EVENT_INQUIRY_RESULT = 0x02,
- HCI_EVENT_CONNECTION_COMPLETE = 0x03,
- HCI_EVENT_CONNECTION_REQUEST = 0x04,
- HCI_EVENT_DISCONNECTION_COMPLETE = 0x05,
- HCI_EVENT_AUTHENTICATION_COMPLETE = 0x06,
- HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE = 0x07,
- HCI_EVENT_ENCRYPTION_CHANGE = 0x08,
- HCI_EVENT_CHANGE_LINK_KEY_COMPLETE = 0x09,
- HCI_EVENT_MASTER_LINK_KEY_COMPLETE = 0x0a,
- HCI_EVENT_READ_REMOTE_SUPPORT_FEATURES_COMPLETE = 0x0b,
- HCI_EVENT_READ_REMOTE_VER_INFO_COMPLETE = 0x0c,
- HCI_EVENT_QOS_SETUP_COMPLETE = 0x0d,
- HCI_EVENT_COMMAND_COMPLETE = 0x0e,
- HCI_EVENT_COMMAND_STATUS = 0x0f,
- HCI_EVENT_HARDWARE_ERROR = 0x10,
- HCI_EVENT_FLUSH_OCCRUED = 0x11,
- HCI_EVENT_ROLE_CHANGE = 0x12,
- HCI_EVENT_NUMBER_OF_COMPLETE_PACKETS = 0x13,
- HCI_EVENT_MODE_CHANGE = 0x14,
- HCI_EVENT_RETURN_LINK_KEYS = 0x15,
- HCI_EVENT_PIN_CODE_REQUEST = 0x16,
- HCI_EVENT_LINK_KEY_REQUEST = 0x17,
- HCI_EVENT_LINK_KEY_NOTIFICATION = 0x18,
- HCI_EVENT_LOOPBACK_COMMAND = 0x19,
- HCI_EVENT_DATA_BUFFER_OVERFLOW = 0x1a,
- HCI_EVENT_MAX_SLOTS_CHANGE = 0x1b,
- HCI_EVENT_READ_CLOCK_OFFSET_COMPLETE = 0x1c,
- HCI_EVENT_CONNECT_PACKET_TYPE_CHANGE = 0x1d,
- HCI_EVENT_QOS_VIOLATION = 0x1e,
- HCI_EVENT_PAGE_SCAN_REPETITION_MODE_CHANGE = 0x20,
- HCI_EVENT_FLOW_SEPC_COMPLETE = 0x21,
- HCI_EVENT_INQUIRY_RESULT_WITH_RSSI = 0x22,
- HCI_EVENT_READ_REMOTE_EXT_FEATURES_COMPLETE = 0x23,
- HCI_EVENT_SYNC_CONNECT_COMPLETE = 0x2c,
- HCI_EVENT_SYNC_CONNECT_CHANGE = 0x2d,
- HCI_EVENT_SNIFFER_SUBRATING = 0x2e,
- HCI_EVENT_EXTENTED_INQUIRY_RESULT = 0x2f,
- HCI_EVENT_ENCRYPTION_KEY_REFLASH_COMPLETE = 0x30,
- HCI_EVENT_IO_CAPIBILITY_COMPLETE = 0x31,
- HCI_EVENT_IO_CAPIBILITY_RESPONSE = 0x32,
- HCI_EVENT_USER_CONFIRMTION_REQUEST = 0x33,
- HCI_EVENT_USER_PASSKEY_REQUEST = 0x34,
- HCI_EVENT_REMOTE_OOB_DATA_REQUEST = 0x35,
- HCI_EVENT_SIMPLE_PAIRING_COMPLETE = 0x36,
- HCI_EVENT_LINK_SUPERVISION_TIMEOUT_CHANGE = 0x38,
- HCI_EVENT_ENHANCED_FLUSH_COMPLETE = 0x39,
- HCI_EVENT_USER_PASSKEY_NOTIFICATION = 0x3b,
- HCI_EVENT_KEYPRESS_NOTIFICATION = 0x3c,
- HCI_EVENT_REMOTE_HOST_SUPPORT_FEATURES_NOTIFICATION = 0x3d,
- HCI_EVENT_PHY_LINK_COMPLETE = 0x40,
- HCI_EVENT_CHANNEL_SELECT = 0x41,
- HCI_EVENT_DISCONNECT_PHY_LINK_COMPLETE = 0x42,
- HCI_EVENT_PHY_LINK_LOSS_EARLY_WARNING = 0x43,
- HCI_EVENT_PHY_LINK_RECOVER = 0x44,
- HCI_EVENT_LOGICAL_LINK_COMPLETE = 0x45,
- HCI_EVENT_DISCONNECT_LOGICAL_LINK_COMPLETE = 0x46,
- HCI_EVENT_FLOW_SPEC_MODIFY_COMPLETE = 0x47,
- HCI_EVENT_NUM_OF_COMPLETE_DATA_BLOCKS = 0x48,
- HCI_EVENT_AMP_START_TEST = 0x49,
- HCI_EVENT_AMP_TEST_END = 0x4a,
- HCI_EVENT_AMP_RECEIVER_REPORT = 0x4b,
- HCI_EVENT_SHORT_RANGE_MODE_CHANGE_COMPLETE = 0x4c,
- HCI_EVENT_AMP_STATUS_CHANGE = 0x4d,
- HCI_EVENT_EXTENSION_RTK = 0xfe,
- HCI_EVENT_EXTENSION_MOTO = 0xff,
-};
-
-enum hci_extension_event_moto {
- HCI_EVENT_GET_BT_RSSI = 0x01,
-};
-
-enum hci_extension_event {
- HCI_EVENT_EXT_WIFI_SCAN_NOTIFY = 0x01,
-};
-
-enum hci_event_mask_page_2 {
- EMP2_HCI_EVENT_PHY_LINK_COMPLETE = 0x0000000000000001,
- EMP2_HCI_EVENT_CHANNEL_SELECT = 0x0000000000000002,
- EMP2_HCI_EVENT_DISCONNECT_PHY_LINK_COMPLETE = 0x0000000000000004,
- EMP2_HCI_EVENT_PHY_LINK_LOSS_EARLY_WARNING = 0x0000000000000008,
- EMP2_HCI_EVENT_PHY_LINK_RECOVER = 0x0000000000000010,
- EMP2_HCI_EVENT_LOGICAL_LINK_COMPLETE = 0x0000000000000020,
- EMP2_HCI_EVENT_DISCONNECT_LOGICAL_LINK_COMPLETE = 0x0000000000000040,
- EMP2_HCI_EVENT_FLOW_SPEC_MODIFY_COMPLETE = 0x0000000000000080,
- EMP2_HCI_EVENT_NUM_OF_COMPLETE_DATA_BLOCKS = 0x0000000000000100,
- EMP2_HCI_EVENT_AMP_START_TEST = 0x0000000000000200,
- EMP2_HCI_EVENT_AMP_TEST_END = 0x0000000000000400,
- EMP2_HCI_EVENT_AMP_RECEIVER_REPORT = 0x0000000000000800,
- EMP2_HCI_EVENT_SHORT_RANGE_MODE_CHANGE_COMPLETE = 0x0000000000001000,
- EMP2_HCI_EVENT_AMP_STATUS_CHANGE = 0x0000000000002000,
-};
-
-enum hci_state_machine {
- HCI_STATE_STARTING = 0x01,
- HCI_STATE_CONNECTING = 0x02,
- HCI_STATE_AUTHENTICATING = 0x04,
- HCI_STATE_CONNECTED = 0x08,
- HCI_STATE_DISCONNECTING = 0x10,
- HCI_STATE_DISCONNECTED = 0x20
-};
-
-enum amp_assoc_structure_type {
- AMP_MAC_ADDR = 0x01,
- AMP_PREFERRED_CHANNEL_LIST = 0x02,
- AMP_CONNECTED_CHANNEL = 0x03,
- AMP_80211_PAL_CAP_LIST = 0x04,
- AMP_80211_PAL_VISION = 0x05,
- AMP_RESERVED_FOR_TESTING = 0x33
-};
-
-enum amp_btap_type {
- AMP_BTAP_NONE,
- AMP_BTAP_CREATOR,
- AMP_BTAP_JOINER
-};
-
-enum hci_state_with_cmd {
- STATE_CMD_CREATE_PHY_LINK,
- STATE_CMD_ACCEPT_PHY_LINK,
- STATE_CMD_DISCONNECT_PHY_LINK,
- STATE_CMD_CONNECT_ACCEPT_TIMEOUT,
- STATE_CMD_MAC_START_COMPLETE,
- STATE_CMD_MAC_START_FAILED,
- STATE_CMD_MAC_CONNECT_COMPLETE,
- STATE_CMD_MAC_CONNECT_FAILED,
- STATE_CMD_MAC_DISCONNECT_INDICATE,
- STATE_CMD_MAC_CONNECT_CANCEL_INDICATE,
- STATE_CMD_4WAY_FAILED,
- STATE_CMD_4WAY_SUCCESSED,
- STATE_CMD_ENTER_STATE,
- STATE_CMD_NO_SUCH_CMD,
-};
-
-enum hci_service_type {
- SERVICE_NO_TRAFFIC,
- SERVICE_BEST_EFFORT,
- SERVICE_GUARANTEE
-};
-
-enum hci_traffic_mode {
- TRAFFIC_MODE_BEST_EFFORT = 0x00,
- TRAFFIC_MODE_GUARANTEED_LATENCY = 0x01,
- TRAFFIC_MODE_GUARANTEED_BANDWIDTH = 0x02,
- TRAFFIC_MODE_GUARANTEED_LATENCY_AND_BANDWIDTH = 0x03
-};
-
-#define HCIOPCODE(_OCF, _OGF) (_OGF<<10|_OCF)
-#define HCIOPCODELOW(_OCF, _OGF) (u8)(HCIOPCODE(_OCF, _OGF)&0x00ff)
-#define HCIOPCODEHIGHT(_OCF, _OGF) (u8)(HCIOPCODE(_OCF, _OGF)>>8)
-
-#define TWOBYTE_HIGHTBYTE(_DATA) (u8)(_DATA>>8)
-#define TWOBYTE_LOWBYTE(_DATA) (u8)(_DATA)
-
-enum amp_status {
- AMP_STATUS_AVA_PHY_PWR_DWN = 0x0,
- AMP_STATUS_BT_USE_ONLY = 0x1,
- AMP_STATUS_NO_CAPACITY_FOR_BT = 0x2,
- AMP_STATUS_LOW_CAPACITY_FOR_BT = 0x3,
- AMP_STATUS_MEDIUM_CAPACITY_FOR_BT = 0x4,
- AMP_STATUS_HIGH_CAPACITY_FOR_BT = 0x5,
- AMP_STATUS_FULL_CAPACITY_FOR_BT = 0x6
-};
-
-enum bt_wpa_msg_type {
- Type_BT_4way1st = 0,
- Type_BT_4way2nd = 1,
- Type_BT_4way3rd = 2,
- Type_BT_4way4th = 3,
- Type_BT_unknow = 4
-};
-
-enum bt_connect_type {
- BT_CONNECT_AUTH_REQ = 0x00,
- BT_CONNECT_AUTH_RSP = 0x01,
- BT_CONNECT_ASOC_REQ = 0x02,
- BT_CONNECT_ASOC_RSP = 0x03,
- BT_DISCONNECT = 0x04
-};
-
-enum bt_ll_service_type {
- BT_LL_BE = 0x01,
- BT_LL_GU = 0x02
-};
-
-enum bt_ll_flowspec {
- BT_TX_BE_FS, /* TX best effort flowspec */
- BT_RX_BE_FS, /* RX best effort flowspec */
- BT_TX_GU_FS, /* TX guaranteed latency flowspec */
- BT_RX_GU_FS, /* RX guaranteed latency flowspec */
- BT_TX_BE_AGG_FS, /* TX aggregated best effort flowspec */
- BT_RX_BE_AGG_FS, /* RX aggregated best effort flowspec */
- BT_TX_GU_BW_FS, /* TX guaranteed bandwidth flowspec */
- BT_RX_GU_BW_FS, /* RX guaranteed bandwidth flowspec */
- BT_TX_GU_LARGE_FS, /* TX guaranteed latency flowspec, for testing only */
- BT_RX_GU_LARGE_FS, /* RX guaranteed latency flowspec, for testing only */
-};
-
-enum bt_traffic_mode {
- BT_MOTOR_EXT_BE = 0x00, /* Best Effort. Default. for HCRP, PAN, SDP, RFCOMM-based profiles like FTP, OPP, SPP, DUN, etc. */
- BT_MOTOR_EXT_GUL = 0x01, /* Guaranteed Latency. This type of traffic is used e.g. for HID and AVRCP. */
- BT_MOTOR_EXT_GUB = 0X02, /* Guaranteed Bandwidth. */
- BT_MOTOR_EXT_GULB = 0X03 /* Guaranteed Latency and Bandwidth. for A2DP and VDP. */
-};
-
-enum bt_traffic_mode_profile {
- BT_PROFILE_NONE,
- BT_PROFILE_A2DP,
- BT_PROFILE_PAN,
- BT_PROFILE_HID,
- BT_PROFILE_SCO
-};
-
-enum bt_link_role {
- BT_LINK_MASTER = 0,
- BT_LINK_SLAVE = 1
-};
-
-enum bt_state_wpa_auth {
- STATE_WPA_AUTH_UNINITIALIZED,
- STATE_WPA_AUTH_WAIT_PACKET_1, /* Join */
- STATE_WPA_AUTH_WAIT_PACKET_2, /* Creat */
- STATE_WPA_AUTH_WAIT_PACKET_3,
- STATE_WPA_AUTH_WAIT_PACKET_4,
- STATE_WPA_AUTH_SUCCESSED
-};
-
-#define BT_WPA_AUTH_TIMEOUT_PERIOD 1000
-#define BTMaxWPAAuthReTransmitCoun 5
-
-#define MAX_AMP_ASSOC_FRAG_LEN 248
-#define TOTAL_ALLOCIATE_ASSOC_LEN 1000
-
-struct hci_flow_spec {
- u8 Identifier;
- u8 ServiceType;
- u16 MaximumSDUSize;
- u32 SDUInterArrivalTime;
- u32 AccessLatency;
- u32 FlushTimeout;
-};
-
-struct hci_log_link_cmd_data {
- u8 BtPhyLinkhandle;
- u16 BtLogLinkhandle;
- u8 BtTxFlowSpecID;
- struct hci_flow_spec Tx_Flow_Spec;
- struct hci_flow_spec Rx_Flow_Spec;
- u32 TxPacketCount;
- u32 BestEffortFlushTimeout;
-
- u8 bLLCompleteEventIsSet;
-
- u8 bLLCancelCMDIsSetandComplete;
-};
-
-struct hci_phy_link_cmd_data {
- /* Physical_Link_Handle */
- u8 BtPhyLinkhandle;
-
- u16 LinkSuperversionTimeout;
-
- /* u16 SuperTimeOutCnt; */
-
- /* Dedicated_AMP_Key_Length */
- u8 BtAMPKeyLen;
- /* Dedicated_AMP_Key_Type */
- u8 BtAMPKeyType;
- /* Dedicated_AMP_Key */
- u8 BtAMPKey[PMK_LEN];
-};
-
-struct amp_assoc_structure {
- /* TYPE ID */
- u8 TypeID;
- /* Length */
- u16 Length;
- /* Value */
- u8 Data[1];
-};
-
-struct amp_pref_chnl_regulatory {
- u8 reXId;
- u8 regulatoryClass;
- u8 coverageClass;
-};
-
-struct amp_assoc_cmd_data {
- /* Physical_Link_Handle */
- u8 BtPhyLinkhandle;
- /* Length_So_Far */
- u16 LenSoFar;
-
- u16 MaxRemoteASSOCLen;
- /* AMP_ASSOC_Remaining_Length */
- u16 AMPAssocRemLen;
- /* AMP_ASSOC_fragment */
- void *AMPAssocfragment;
-};
-
-struct hci_link_info {
- u16 ConnectHandle;
- u8 IncomingTrafficMode;
- u8 OutgoingTrafficMode;
- u8 BTProfile;
- u8 BTCoreSpec;
- s8 BT_RSSI;
- u8 TrafficProfile;
- u8 linkRole;
-};
-
-struct hci_ext_config {
- struct hci_link_info linkInfo[MAX_BT_ASOC_ENTRY_NUM];
- u8 btOperationCode;
- u16 CurrentConnectHandle;
- u8 CurrentIncomingTrafficMode;
- u8 CurrentOutgoingTrafficMode;
- s8 MIN_BT_RSSI;
- u8 NumberOfHandle;
- u8 NumberOfSCO;
- u8 CurrentBTStatus;
- u16 HCIExtensionVer;
-
- /* Bt coexist related */
- u8 btProfileCase;
- u8 btProfileAction;
- u8 bManualControl;
- u8 bBTBusy;
- u8 bBTA2DPBusy;
- u8 bEnableWifiScanNotify;
-
- u8 bHoldForBtOperation;
- u32 bHoldPeriodCnt;
-};
-
-struct hci_acl_packet_data {
- u16 ACLDataPacketLen;
- u8 SyncDataPacketLen;
- u16 TotalNumACLDataPackets;
- u16 TotalSyncNumDataPackets;
-};
-
-struct hci_phy_link_bss_info {
- u16 bdCap; /* capability information */
-};
-
-struct packet_irp_hcicmd_data {
- u16 OCF:10;
- u16 OGF:6;
- u8 Length;
- u8 Data[20];
-};
-
-struct bt_asoc_entry {
- u8 bUsed;
- u8 mAssoc;
- u8 b4waySuccess;
- u8 Bssid[6];
- struct hci_phy_link_cmd_data PhyLinkCmdData;
-
- struct hci_log_link_cmd_data LogLinkCmdData[MAX_LOGICAL_LINK_NUM];
-
- struct hci_acl_packet_data ACLPacketsData;
-
- struct amp_assoc_cmd_data AmpAsocCmdData;
- struct octet_string BTSsid;
- u8 BTSsidBuf[33];
-
- enum hci_status PhyLinkDisconnectReason;
-
- u8 bSendSupervisionPacket;
- /* u8 CurrentSuervisionPacketSendNum; */
- /* u8 LastSuervisionPacketSendNum; */
- u32 NoRxPktCnt;
- /* Is Creator or Joiner */
- enum amp_btap_type AMPRole;
-
- /* BT current state */
- u8 BtCurrentState;
- /* BT next state */
- u8 BtNextState;
-
- u8 bNeedPhysLinkCompleteEvent;
-
- enum hci_status PhysLinkCompleteStatus;
-
- u8 BTRemoteMACAddr[6];
-
- u32 BTCapability;
-
- u8 SyncDataPacketLen;
-
- u16 TotalSyncNumDataPackets;
- u16 TotalNumACLDataPackets;
-
- u8 ShortRangeMode;
-
- u8 PTK[PTK_LEN_TKIP];
- u8 GTK[GTK_LEN];
- u8 ANonce[KEY_NONCE_LEN];
- u8 SNonce[KEY_NONCE_LEN];
- u64 KeyReplayCounter;
- u8 WPAAuthReplayCount;
- u8 AESKeyBuf[AESCCMP_BLK_SIZE_TOTAL];
- u8 PMK[PMK_LEN];
- enum bt_state_wpa_auth BTWPAAuthState;
- s32 UndecoratedSmoothedPWDB;
-
- /* Add for HW security !! */
- u8 HwCAMIndex; /* Cam index */
- u8 bPeerQosSta;
-
- u32 rxSuvpPktCnt;
-};
-
-struct bt_traffic_statistics {
- u8 bTxBusyTraffic;
- u8 bRxBusyTraffic;
- u8 bIdle;
- u32 TxPktCntInPeriod;
- u32 RxPktCntInPeriod;
- u64 TxPktLenInPeriod;
- u64 RxPktLenInPeriod;
-};
-
-struct bt_mgnt {
- u8 bBTConnectInProgress;
- u8 bLogLinkInProgress;
- u8 bPhyLinkInProgress;
- u8 bPhyLinkInProgressStartLL;
- u8 BtCurrentPhyLinkhandle;
- u16 BtCurrentLogLinkhandle;
- u8 CurrentConnectEntryNum;
- u8 DisconnectEntryNum;
- u8 CurrentBTConnectionCnt;
- enum bt_connect_type BTCurrentConnectType;
- enum bt_connect_type BTReceiveConnectPkt;
- u8 BTAuthCount;
- u8 BTAsocCount;
- u8 bStartSendSupervisionPkt;
- u8 BtOperationOn;
- u8 BTNeedAMPStatusChg;
- u8 JoinerNeedSendAuth;
- struct hci_phy_link_bss_info bssDesc;
- struct hci_ext_config ExtConfig;
- u8 bNeedNotifyAMPNoCap;
- u8 bCreateSpportQos;
- u8 bSupportProfile;
- u8 BTChannel;
- u8 CheckChnlIsSuit;
- u8 bBtScan;
- u8 btLogoTest;
-};
-
-struct bt_hci_dgb_info {
- u32 hciCmdCnt;
- u32 hciCmdCntUnknown;
- u32 hciCmdCntCreatePhyLink;
- u32 hciCmdCntAcceptPhyLink;
- u32 hciCmdCntDisconnectPhyLink;
- u32 hciCmdPhyLinkStatus;
- u32 hciCmdCntCreateLogLink;
- u32 hciCmdCntAcceptLogLink;
- u32 hciCmdCntDisconnectLogLink;
- u32 hciCmdCntReadLocalAmpAssoc;
- u32 hciCmdCntWriteRemoteAmpAssoc;
- u32 hciCmdCntSetAclLinkStatus;
- u32 hciCmdCntSetScoLinkStatus;
- u32 hciCmdCntExtensionVersionNotify;
- u32 hciCmdCntLinkStatusNotify;
-};
-
-struct bt_irp_dgb_info {
- u32 irpMJCreate;
- /* Io Control */
- u32 irpIoControl;
- u32 irpIoCtrlHciCmd;
- u32 irpIoCtrlHciEvent;
- u32 irpIoCtrlHciTxData;
- u32 irpIoCtrlHciRxData;
- u32 irpIoCtrlUnknown;
-
- u32 irpIoCtrlHciTxData1s;
-};
-
-struct bt_packet_dgb_info {
- u32 btPktTxProbReq;
- u32 btPktRxProbReq;
- u32 btPktRxProbReqFail;
- u32 btPktTxProbRsp;
- u32 btPktRxProbRsp;
- u32 btPktTxAuth;
- u32 btPktRxAuth;
- u32 btPktRxAuthButDrop;
- u32 btPktTxAssocReq;
- u32 btPktRxAssocReq;
- u32 btPktRxAssocReqButDrop;
- u32 btPktTxAssocRsp;
- u32 btPktRxAssocRsp;
- u32 btPktTxDisassoc;
- u32 btPktRxDisassoc;
- u32 btPktRxDeauth;
- u32 btPktTx4way1st;
- u32 btPktRx4way1st;
- u32 btPktTx4way2nd;
- u32 btPktRx4way2nd;
- u32 btPktTx4way3rd;
- u32 btPktRx4way3rd;
- u32 btPktTx4way4th;
- u32 btPktRx4way4th;
- u32 btPktTxLinkSuperReq;
- u32 btPktRxLinkSuperReq;
- u32 btPktTxLinkSuperRsp;
- u32 btPktRxLinkSuperRsp;
- u32 btPktTxData;
- u32 btPktRxData;
-};
-
-struct bt_dgb {
- u8 dbgCtrl;
- u32 dbgProfile;
- struct bt_hci_dgb_info dbgHciInfo;
- struct bt_irp_dgb_info dbgIrpInfo;
- struct bt_packet_dgb_info dbgBtPkt;
-};
-
-struct bt_hci_info {
- /* 802.11 Pal version specifier */
- u8 BTPalVersion;
- u16 BTPalCompanyID;
- u16 BTPalsubversion;
-
- /* Connected channel list */
- u16 BTConnectChnlListLen;
- u8 BTConnectChnllist[64];
-
- /* Fail contact counter */
- u16 FailContactCount;
-
- /* Event mask */
- u64 BTEventMask;
- u64 BTEventMaskPage2;
-
- /* timeout var */
- u16 ConnAcceptTimeout;
- u16 LogicalAcceptTimeout;
- u16 PageTimeout;
-
- u8 LocationDomainAware;
- u16 LocationDomain;
- u8 LocationDomainOptions;
- u8 LocationOptions;
-
- u8 FlowControlMode;
-
- /* Preferred channel list */
- u16 BtPreChnlListLen;
- u8 BTPreChnllist[64];
-
- u16 enFlush_LLH; /* enhanced flush handle */
- u16 FLTO_LLH; /* enhanced flush handle */
-
- /* */
- /* Test command only. */
- u8 bInTestMode;
- u8 bTestIsEnd;
- u8 bTestNeedReport;
- u8 TestScenario;
- u8 TestReportInterval;
- u8 TestCtrType;
- u32 TestEventType;
- u16 TestNumOfFrame;
- u16 TestNumOfErrFrame;
- u16 TestNumOfBits;
- u16 TestNumOfErrBits;
- /* */
-};
-
-struct bt_traffic {
- /* Add for check replay data */
- u8 LastRxUniFragNum;
- u16 LastRxUniSeqNum;
-
- /* s32 EntryMaxUndecoratedSmoothedPWDB; */
- /* s32 EntryMinUndecoratedSmoothedPWDB; */
-
- struct bt_traffic_statistics Bt30TrafficStatistics;
-};
-
-#define RT_WORK_ITEM struct work_struct
-
-struct bt_security {
- /* WPA auth state
- * May need to remove to BTSecInfo ...
- * enum bt_state_wpa_auth BTWPAAuthState;
- */
- struct octet_string RSNIE;
- u8 RSNIEBuf[MAXRSNIELEN];
- u8 bRegNoEncrypt;
- u8 bUsedHwEncrypt;
-};
-
-struct bt_30info {
- struct rtw_adapter *padapter;
- struct bt_asoc_entry BtAsocEntry[MAX_BT_ASOC_ENTRY_NUM];
- struct bt_mgnt BtMgnt;
- struct bt_dgb BtDbg;
- struct bt_hci_info BtHciInfo;
- struct bt_traffic BtTraffic;
- struct bt_security BtSec;
- RT_WORK_ITEM HCICmdWorkItem;
- struct timer_list BTHCICmdTimer;
- RT_WORK_ITEM BTPsDisableWorkItem;
- RT_WORK_ITEM BTConnectWorkItem;
- struct timer_list BTHCIDiscardAclDataTimer;
- struct timer_list BTHCIJoinTimeoutTimer;
- struct timer_list BTTestSendPacketTimer;
- struct timer_list BTDisconnectPhyLinkTimer;
- struct timer_list BTBeaconTimer;
- u8 BTBeaconTmrOn;
-
- struct timer_list BTPsDisableTimer;
-
- void * pBtChnlList;
-};
-
-struct packet_irp_acl_data {
- u16 Handle:12;
- u16 PB_Flag:2;
- u16 BC_Flag:2;
- u16 Length;
- u8 Data[1];
-};
-
-struct packet_irp_hcievent_data {
- u8 EventCode;
- u8 Length;
- u8 Data[20];
-};
-
-struct common_triple {
- u8 byte_1st;
- u8 byte_2nd;
- u8 byte_3rd;
-};
-
-#define COUNTRY_STR_LEN 3 /* country string len = 3 */
-
-#define LOCAL_PMK 0
-
-enum hci_wifi_connect_status {
- HCI_WIFI_NOT_CONNECTED = 0x0,
- HCI_WIFI_CONNECTED = 0x1,
- HCI_WIFI_CONNECT_IN_PROGRESS = 0x2,
-};
-
-enum hci_ext_bp_operation {
- HCI_BT_OP_NONE = 0x0,
- HCI_BT_OP_INQUIRY_START = 0x1,
- HCI_BT_OP_INQUIRY_FINISH = 0x2,
- HCI_BT_OP_PAGING_START = 0x3,
- HCI_BT_OP_PAGING_SUCCESS = 0x4,
- HCI_BT_OP_PAGING_UNSUCCESS = 0x5,
- HCI_BT_OP_PAIRING_START = 0x6,
- HCI_BT_OP_PAIRING_FINISH = 0x7,
- HCI_BT_OP_BT_DEV_ENABLE = 0x8,
- HCI_BT_OP_BT_DEV_DISABLE = 0x9,
- HCI_BT_OP_MAX
-};
-
-#define BTHCI_SM_WITH_INFO(_Adapter, _StateToEnter, _StateCmd, _EntryNum) \
-{ \
- RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state change] caused by ""%s"", line =%d\n", __func__, __LINE__)); \
- BTHCI_StateMachine(_Adapter, _StateToEnter, _StateCmd, _EntryNum);\
-}
-
-void BTHCI_EventParse(struct rtw_adapter *padapter, void *pEvntData,
- u32 dataLen);
-#define BT_EventParse BTHCI_EventParse
-u8 BTHCI_HsConnectionEstablished(struct rtw_adapter *padapter);
-void BTHCI_UpdateBTProfileRTKToMoto(struct rtw_adapter *padapter);
-void BTHCI_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType);
-void BTHCI_StateMachine(struct rtw_adapter *padapter, u8 StateToEnter,
- enum hci_state_with_cmd StateCmd, u8 EntryNum);
-void BTHCI_DisconnectPeer(struct rtw_adapter *padapter, u8 EntryNum);
-void BTHCI_EventNumOfCompletedDataBlocks(struct rtw_adapter *padapter);
-void BTHCI_EventAMPStatusChange(struct rtw_adapter *padapter, u8 AMP_Status);
-void BTHCI_DisconnectAll(struct rtw_adapter *padapter);
-enum hci_status BTHCI_HandleHCICMD(struct rtw_adapter *padapter,
- struct packet_irp_hcicmd_data *pHciCmd);
-
-/* ===== End of sync from SD7 driver COMMON/bt_hci.h ===== */
-
-/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc87231Ant.h ===== */
-#define GET_BT_INFO(padapter) (&GET_HAL_DATA(padapter)->BtInfo)
-
-#define BTC_FOR_SCAN_START 1
-#define BTC_FOR_SCAN_FINISH 0
-
-#define BT_TXRX_CNT_THRES_1 1200
-#define BT_TXRX_CNT_THRES_2 1400
-#define BT_TXRX_CNT_THRES_3 3000
-#define BT_TXRX_CNT_LEVEL_0 0 /* < 1200 */
-#define BT_TXRX_CNT_LEVEL_1 1 /* >= 1200 && < 1400 */
-#define BT_TXRX_CNT_LEVEL_2 2 /* >= 1400 */
-#define BT_TXRX_CNT_LEVEL_3 3 /* >= 3000 */
-
-enum bt_state_1ant {
- BT_INFO_STATE_DISABLED = 0,
- BT_INFO_STATE_NO_CONNECTION = 1,
- BT_INFO_STATE_CONNECT_IDLE = 2,
- BT_INFO_STATE_INQ_OR_PAG = 3,
- BT_INFO_STATE_ACL_ONLY_BUSY = 4,
- BT_INFO_STATE_SCO_ONLY_BUSY = 5,
- BT_INFO_STATE_ACL_SCO_BUSY = 6,
- BT_INFO_STATE_ACL_INQ_OR_PAG = 7,
- BT_INFO_STATE_MAX = 8
-};
-
-struct btdm_8723a_1ant {
- u8 prePsTdma;
- u8 curPsTdma;
- u8 psTdmaDuAdjType;
- u8 bPrePsTdmaOn;
- u8 bCurPsTdmaOn;
- u8 preWifiPara;
- u8 curWifiPara;
- u8 preCoexWifiCon;
- u8 curCoexWifiCon;
- u8 wifiRssiThresh;
-
- u32 psTdmaMonitorCnt;
- u32 psTdmaGlobalCnt;
-
- /* DurationAdjust For SCO */
- u32 psTdmaMonitorCntForSCO;
- u8 psTdmaDuAdjTypeForSCO;
- u8 RSSI_WiFi_Last;
- u8 RSSI_BT_Last;
-
- u8 bWiFiHalt;
- u8 bRAChanged;
-};
-
-void BTDM_1AntSignalCompensation(struct rtw_adapter *padapter,
- u8 *rssi_wifi, u8 *rssi_bt);
-void BTDM_1AntForDhcp(struct rtw_adapter *padapter);
-void BTDM_1AntBtCoexist8723A(struct rtw_adapter *padapter);
-
-/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87231Ant.h ===== */
-
-/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc87232Ant.h ===== */
-enum bt_2ant_bt_status {
- BT_2ANT_BT_STATUS_IDLE = 0x0,
- BT_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
- BT_2ANT_BT_STATUS_NON_IDLE = 0x2,
- BT_2ANT_BT_STATUS_MAX
-};
-
-enum bt_2ant_coex_algo {
- BT_2ANT_COEX_ALGO_UNDEFINED = 0x0,
- BT_2ANT_COEX_ALGO_SCO = 0x1,
- BT_2ANT_COEX_ALGO_HID = 0x2,
- BT_2ANT_COEX_ALGO_A2DP = 0x3,
- BT_2ANT_COEX_ALGO_PANEDR = 0x4,
- BT_2ANT_COEX_ALGO_PANHS = 0x5,
- BT_2ANT_COEX_ALGO_PANEDR_A2DP = 0x6,
- BT_2ANT_COEX_ALGO_PANEDR_HID = 0x7,
- BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x8,
- BT_2ANT_COEX_ALGO_HID_A2DP = 0x9,
- BT_2ANT_COEX_ALGO_HID_A2DP_PANHS = 0xA,
- BT_2ANT_COEX_ALGO_MAX = 0xB,
-};
-
-struct btdm_8723a_2ant {
- u8 bPreDecBtPwr;
- u8 bCurDecBtPwr;
-
- u8 preWlanActHi;
- u8 curWlanActHi;
- u8 preWlanActLo;
- u8 curWlanActLo;
-
- u8 preFwDacSwingLvl;
- u8 curFwDacSwingLvl;
-
- u8 bPreRfRxLpfShrink;
- u8 bCurRfRxLpfShrink;
-
- u8 bPreLowPenaltyRa;
- u8 bCurLowPenaltyRa;
-
- u8 preBtRetryIndex;
- u8 curBtRetryIndex;
-
- u8 bPreDacSwingOn;
- u32 preDacSwingLvl;
- u8 bCurDacSwingOn;
- u32 curDacSwingLvl;
-
- u8 bPreAdcBackOff;
- u8 bCurAdcBackOff;
-
- u8 bPreAgcTableEn;
- u8 bCurAgcTableEn;
-
- u32 preVal0x6c0;
- u32 curVal0x6c0;
- u32 preVal0x6c8;
- u32 curVal0x6c8;
- u8 preVal0x6cc;
- u8 curVal0x6cc;
-
- u8 bCurIgnoreWlanAct;
- u8 bPreIgnoreWlanAct;
-
- u8 prePsTdma;
- u8 curPsTdma;
- u8 psTdmaDuAdjType;
- u8 bPrePsTdmaOn;
- u8 bCurPsTdmaOn;
-
- u8 preAlgorithm;
- u8 curAlgorithm;
- u8 bResetTdmaAdjust;
-
- u8 btStatus;
-};
-
-void BTDM_2AntBtCoexist8723A(struct rtw_adapter *padapter);
-/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87232Ant.h ===== */
-
-/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc8723.h ===== */
-
-#define BT_Q_PKT_OFF 0
-#define BT_Q_PKT_ON 1
-
-#define BT_TX_PWR_OFF 0
-#define BT_TX_PWR_ON 1
-
-/* TDMA mode definition */
-#define TDMA_2ANT 0
-#define TDMA_1ANT 1
-#define TDMA_NAV_OFF 0
-#define TDMA_NAV_ON 1
-#define TDMA_DAC_SWING_OFF 0
-#define TDMA_DAC_SWING_ON 1
-
-#define BT_RSSI_LEVEL_H 0
-#define BT_RSSI_LEVEL_M 1
-#define BT_RSSI_LEVEL_L 2
-
-/* PTA mode related definition */
-#define BT_PTA_MODE_OFF 0
-#define BT_PTA_MODE_ON 1
-
-/* Penalty Tx Rate Adaptive */
-#define BT_TX_RATE_ADAPTIVE_NORMAL 0
-#define BT_TX_RATE_ADAPTIVE_LOW_PENALTY 1
-
-/* RF Corner */
-#define BT_RF_RX_LPF_CORNER_RESUME 0
-#define BT_RF_RX_LPF_CORNER_SHRINK 1
-
-#define BT_INFO_ACL BIT(0)
-#define BT_INFO_SCO BIT(1)
-#define BT_INFO_INQ_PAG BIT(2)
-#define BT_INFO_ACL_BUSY BIT(3)
-#define BT_INFO_SCO_BUSY BIT(4)
-#define BT_INFO_HID BIT(5)
-#define BT_INFO_A2DP BIT(6)
-#define BT_INFO_FTP BIT(7)
-
-
-
-struct bt_coexist_8723a {
- u32 highPriorityTx;
- u32 highPriorityRx;
- u32 lowPriorityTx;
- u32 lowPriorityRx;
- u8 btRssi;
- u8 TotalAntNum;
- u8 bC2hBtInfoSupport;
- u8 c2hBtInfo;
- u8 c2hBtInfoOriginal;
- u8 prec2hBtInfo; /* for 1Ant */
- u8 bC2hBtInquiryPage;
- unsigned long btInqPageStartTime; /* for 2Ant */
- u8 c2hBtProfile; /* for 1Ant */
- u8 btRetryCnt;
- u8 btInfoExt;
- u8 bC2hBtInfoReqSent;
- u8 bForceFwBtInfo;
- u8 bForceA2dpSink;
- struct btdm_8723a_2ant btdm2Ant;
- struct btdm_8723a_1ant btdm1Ant;
-};
-
-void BTDM_SetFwChnlInfo(struct rtw_adapter *padapter,
- enum rt_media_status mstatus);
-u8 BTDM_IsWifiConnectionExist(struct rtw_adapter *padapter);
-void BTDM_SetFw3a(struct rtw_adapter *padapter, u8 byte1, u8 byte2, u8 byte3,
- u8 byte4, u8 byte5);
-void BTDM_QueryBtInformation(struct rtw_adapter *padapter);
-void BTDM_SetSwRfRxLpfCorner(struct rtw_adapter *padapter, u8 type);
-void BTDM_SetSwPenaltyTxRateAdaptive(struct rtw_adapter *padapter, u8 raType);
-void BTDM_SetFwDecBtPwr(struct rtw_adapter *padapter, u8 bDecBtPwr);
-u8 BTDM_BtProfileSupport(struct rtw_adapter *padapter);
-void BTDM_LpsLeave(struct rtw_adapter *padapter);
-
-/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc8723.h ===== */
-
-/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtcCsr1Ant.h ===== */
-
-enum BT_A2DP_INDEX{
- BT_A2DP_INDEX0 = 0, /* 32, 12; the most critical for BT */
- BT_A2DP_INDEX1, /* 12, 24 */
- BT_A2DP_INDEX2, /* 0, 0 */
- BT_A2DP_INDEX_MAX
-};
-
-#define BT_A2DP_STATE_NOT_ENTERED 0
-#define BT_A2DP_STATE_DETECTING 1
-#define BT_A2DP_STATE_DETECTED 2
-
-#define BTDM_ANT_BT_IDLE 0
-#define BTDM_ANT_WIFI 1
-#define BTDM_ANT_BT 2
-
-
-void BTDM_SingleAnt(struct rtw_adapter *padapter, u8 bSingleAntOn,
- u8 bInterruptOn, u8 bMultiNAVOn);
-void BTDM_CheckBTIdleChange1Ant(struct rtw_adapter *padapter);
-
-/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr1Ant.h ===== */
-
-/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtcCsr2Ant.h ===== */
-
-/* */
-/* For old core stack before v251 */
-/* */
-#define BT_RSSI_STATE_NORMAL_POWER BIT(0)
-#define BT_RSSI_STATE_AMDPU_OFF BIT(1)
-#define BT_RSSI_STATE_SPECIAL_LOW BIT(2)
-#define BT_RSSI_STATE_BG_EDCA_LOW BIT(3)
-#define BT_RSSI_STATE_TXPOWER_LOW BIT(4)
-
-#define BT_DACSWING_OFF 0
-#define BT_DACSWING_M4 1
-#define BT_DACSWING_M7 2
-#define BT_DACSWING_M10 3
-
-void BTDM_DiminishWiFi(struct rtw_adapter *Adapter, u8 bDACOn, u8 bInterruptOn,
- u8 DACSwingLevel, u8 bNAVOn);
-
-/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr2Ant.h ===== */
-
-/* HEADER/TypeDef.h */
-#define MAX_FW_SUPPORT_MACID_NUM 64
-
-/* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtCoexist.h ===== */
-
-#define FW_VER_BT_REG 62
-#define FW_VER_BT_REG1 74
-#define REG_BT_ACTIVE 0x444
-#define REG_BT_STATE 0x448
-#define REG_BT_POLLING1 0x44c
-#define REG_BT_POLLING 0x700
-
-#define REG_BT_ACTIVE_OLD 0x488
-#define REG_BT_STATE_OLD 0x48c
-#define REG_BT_POLLING_OLD 0x490
-
-/* The reg define is for 8723 */
-#define REG_HIGH_PRIORITY_TXRX 0x770
-#define REG_LOW_PRIORITY_TXRX 0x774
-
-#define BT_FW_COEX_THRESH_TOL 6
-#define BT_FW_COEX_THRESH_20 20
-#define BT_FW_COEX_THRESH_23 23
-#define BT_FW_COEX_THRESH_25 25
-#define BT_FW_COEX_THRESH_30 30
-#define BT_FW_COEX_THRESH_35 35
-#define BT_FW_COEX_THRESH_40 40
-#define BT_FW_COEX_THRESH_45 45
-#define BT_FW_COEX_THRESH_47 47
-#define BT_FW_COEX_THRESH_50 50
-#define BT_FW_COEX_THRESH_55 55
-#define BT_FW_COEX_THRESH_65 65
-
-#define BT_COEX_STATE_BT30 BIT(0)
-#define BT_COEX_STATE_WIFI_HT20 BIT(1)
-#define BT_COEX_STATE_WIFI_HT40 BIT(2)
-#define BT_COEX_STATE_WIFI_LEGACY BIT(3)
-
-#define BT_COEX_STATE_WIFI_RSSI_LOW BIT(4)
-#define BT_COEX_STATE_WIFI_RSSI_MEDIUM BIT(5)
-#define BT_COEX_STATE_WIFI_RSSI_HIGH BIT(6)
-#define BT_COEX_STATE_DEC_BT_POWER BIT(7)
-
-#define BT_COEX_STATE_WIFI_IDLE BIT(8)
-#define BT_COEX_STATE_WIFI_UPLINK BIT(9)
-#define BT_COEX_STATE_WIFI_DOWNLINK BIT(10)
-
-#define BT_COEX_STATE_BT_INQ_PAGE BIT(11)
-#define BT_COEX_STATE_BT_IDLE BIT(12)
-#define BT_COEX_STATE_BT_UPLINK BIT(13)
-#define BT_COEX_STATE_BT_DOWNLINK BIT(14)
-/* */
-/* Todo: Remove these definitions */
-#define BT_COEX_STATE_BT_PAN_IDLE BIT(15)
-#define BT_COEX_STATE_BT_PAN_UPLINK BIT(16)
-#define BT_COEX_STATE_BT_PAN_DOWNLINK BIT(17)
-#define BT_COEX_STATE_BT_A2DP_IDLE BIT(18)
-/* */
-#define BT_COEX_STATE_BT_RSSI_LOW BIT(19)
-
-#define BT_COEX_STATE_PROFILE_HID BIT(20)
-#define BT_COEX_STATE_PROFILE_A2DP BIT(21)
-#define BT_COEX_STATE_PROFILE_PAN BIT(22)
-#define BT_COEX_STATE_PROFILE_SCO BIT(23)
-
-#define BT_COEX_STATE_WIFI_RSSI_1_LOW BIT(24)
-#define BT_COEX_STATE_WIFI_RSSI_1_MEDIUM BIT(25)
-#define BT_COEX_STATE_WIFI_RSSI_1_HIGH BIT(26)
-
-#define BT_COEX_STATE_WIFI_RSSI_BEACON_LOW BIT(27)
-#define BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM BIT(28)
-#define BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH BIT(29)
-
-
-#define BT_COEX_STATE_BTINFO_COMMON BIT(30)
-#define BT_COEX_STATE_BTINFO_B_HID_SCOESCO BIT(31)
-#define BT_COEX_STATE_BTINFO_B_FTP_A2DP BIT(32)
-
-#define BT_COEX_STATE_BT_CNT_LEVEL_0 BIT(33)
-#define BT_COEX_STATE_BT_CNT_LEVEL_1 BIT(34)
-#define BT_COEX_STATE_BT_CNT_LEVEL_2 BIT(35)
-#define BT_COEX_STATE_BT_CNT_LEVEL_3 BIT(36)
-
-#define BT_RSSI_STATE_HIGH 0
-#define BT_RSSI_STATE_MEDIUM 1
-#define BT_RSSI_STATE_LOW 2
-#define BT_RSSI_STATE_STAY_HIGH 3
-#define BT_RSSI_STATE_STAY_MEDIUM 4
-#define BT_RSSI_STATE_STAY_LOW 5
-
-#define BT_AGCTABLE_OFF 0
-#define BT_AGCTABLE_ON 1
-
-#define BT_BB_BACKOFF_OFF 0
-#define BT_BB_BACKOFF_ON 1
-
-#define BT_FW_NAV_OFF 0
-#define BT_FW_NAV_ON 1
-
-#define BT_COEX_MECH_NONE 0
-#define BT_COEX_MECH_SCO 1
-#define BT_COEX_MECH_HID 2
-#define BT_COEX_MECH_A2DP 3
-#define BT_COEX_MECH_PAN 4
-#define BT_COEX_MECH_HID_A2DP 5
-#define BT_COEX_MECH_HID_PAN 6
-#define BT_COEX_MECH_PAN_A2DP 7
-#define BT_COEX_MECH_HID_SCO_ESCO 8
-#define BT_COEX_MECH_FTP_A2DP 9
-#define BT_COEX_MECH_COMMON 10
-#define BT_COEX_MECH_MAX 11
-/* BT Dbg Ctrl */
-#define BT_DBG_PROFILE_NONE 0
-#define BT_DBG_PROFILE_SCO 1
-#define BT_DBG_PROFILE_HID 2
-#define BT_DBG_PROFILE_A2DP 3
-#define BT_DBG_PROFILE_PAN 4
-#define BT_DBG_PROFILE_HID_A2DP 5
-#define BT_DBG_PROFILE_HID_PAN 6
-#define BT_DBG_PROFILE_PAN_A2DP 7
-#define BT_DBG_PROFILE_MAX 9
-
-struct bt_coexist_str {
- u8 BluetoothCoexist;
- u8 BT_Ant_Num;
- u8 BT_CoexistType;
- u8 BT_Ant_isolation; /* 0:good, 1:bad */
- u8 bt_radiosharedtype;
- u32 Ratio_Tx;
- u32 Ratio_PRI;
- u8 bInitlized;
- u32 BtRfRegOrigin1E;
- u32 BtRfRegOrigin1F;
- u8 bBTBusyTraffic;
- u8 bBTTrafficModeSet;
- u8 bBTNonTrafficModeSet;
- struct bt_traffic_statistics BT21TrafficStatistics;
- u64 CurrentState;
- u64 PreviousState;
- u8 preRssiState;
- u8 preRssiState1;
- u8 preRssiStateBeacon;
- u8 bFWCoexistAllOff;
- u8 bSWCoexistAllOff;
- u8 bHWCoexistAllOff;
- u8 bBalanceOn;
- u8 bSingleAntOn;
- u8 bInterruptOn;
- u8 bMultiNAVOn;
- u8 PreWLANActH;
- u8 PreWLANActL;
- u8 WLANActH;
- u8 WLANActL;
- u8 A2DPState;
- u8 AntennaState;
- u32 lastBtEdca;
- u16 last_aggr_num;
- u8 bEDCAInitialized;
- u8 exec_cnt;
- u8 b8723aAgcTableOn;
- u8 b92DAgcTableOn;
- struct bt_coexist_8723a halCoex8723;
- u8 btActiveZeroCnt;
- u8 bCurBtDisabled;
- u8 bPreBtDisabled;
- u8 bNeedToRoamForBtDisableEnable;
- u8 fw3aVal[5];
-};
-
-void BTDM_CheckAntSelMode(struct rtw_adapter *padapter);
-void BTDM_FwC2hBtRssi(struct rtw_adapter *padapter, u8 *tmpBuf);
-#define BT_FwC2hBtRssi BTDM_FwC2hBtRssi
-void BTDM_DisplayBtCoexInfo(struct rtw_adapter *padapter);
-#define BT_DisplayBtCoexInfo BTDM_DisplayBtCoexInfo
-void BTDM_RejectAPAggregatedPacket(struct rtw_adapter *padapter, u8 bReject);
-u8 BTDM_IsHT40(struct rtw_adapter *padapter);
-u8 BTDM_Legacy(struct rtw_adapter *padapter);
-void BTDM_CheckWiFiState(struct rtw_adapter *padapter);
-s32 BTDM_GetRxSS(struct rtw_adapter *padapter);
-u8 BTDM_CheckCoexBcnRssiState(struct rtw_adapter *padapter, u8 levelNum,
- u8 RssiThresh, u8 RssiThresh1);
-u8 BTDM_CheckCoexRSSIState1(struct rtw_adapter *padapter, u8 levelNum,
- u8 RssiThresh, u8 RssiThresh1);
-u8 BTDM_CheckCoexRSSIState(struct rtw_adapter *padapter, u8 levelNum,
- u8 RssiThresh, u8 RssiThresh1);
-void BTDM_Balance(struct rtw_adapter *padapter, u8 bBalanceOn, u8 ms0, u8 ms1);
-void BTDM_AGCTable(struct rtw_adapter *padapter, u8 type);
-void BTDM_BBBackOffLevel(struct rtw_adapter *padapter, u8 type);
-void BTDM_FWCoexAllOff(struct rtw_adapter *padapter);
-void BTDM_SWCoexAllOff(struct rtw_adapter *padapter);
-void BTDM_HWCoexAllOff(struct rtw_adapter *padapter);
-void BTDM_CoexAllOff(struct rtw_adapter *padapter);
-void BTDM_TurnOffBtCoexistBeforeEnterIPS(struct rtw_adapter *padapter);
-void BTDM_SignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi,
- u8 *rssi_bt);
-void BTDM_UpdateCoexState(struct rtw_adapter *padapter);
-u8 BTDM_IsSameCoexistState(struct rtw_adapter *padapter);
-void BTDM_PWDBMonitor(struct rtw_adapter *padapter);
-u8 BTDM_IsBTBusy(struct rtw_adapter *padapter);
-#define BT_IsBtBusy BTDM_IsBTBusy
-u8 BTDM_IsWifiBusy(struct rtw_adapter *padapter);
-u8 BTDM_IsCoexistStateChanged(struct rtw_adapter *padapter);
-u8 BTDM_IsWifiUplink(struct rtw_adapter *padapter);
-u8 BTDM_IsWifiDownlink(struct rtw_adapter *padapter);
-u8 BTDM_IsBTHSMode(struct rtw_adapter *padapter);
-u8 BTDM_IsBTUplink(struct rtw_adapter *padapter);
-u8 BTDM_IsBTDownlink(struct rtw_adapter *padapter);
-void BTDM_AdjustForBtOperation(struct rtw_adapter *padapter);
-void BTDM_ForHalt(struct rtw_adapter *padapter);
-void BTDM_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType);
-void BTDM_WifiAssociateNotify(struct rtw_adapter *padapter, u8 action);
-void BTDM_MediaStatusNotify(struct rtw_adapter *padapter,
- enum rt_media_status mstatus);
-void BTDM_ForDhcp(struct rtw_adapter *padapter);
-void BTDM_ResetActionProfileState(struct rtw_adapter *padapter);
-void BTDM_SetBtCoexCurrAntNum(struct rtw_adapter *padapter, u8 antNum);
-#define BT_SetBtCoexCurrAntNum BTDM_SetBtCoexCurrAntNum
-u8 BTDM_IsActionSCO(struct rtw_adapter *padapter);
-u8 BTDM_IsActionHID(struct rtw_adapter *padapter);
-u8 BTDM_IsActionA2DP(struct rtw_adapter *padapter);
-u8 BTDM_IsActionPAN(struct rtw_adapter *padapter);
-u8 BTDM_IsActionHIDA2DP(struct rtw_adapter *padapter);
-u8 BTDM_IsActionHIDPAN(struct rtw_adapter *padapter);
-u8 BTDM_IsActionPANA2DP(struct rtw_adapter *padapter);
-u32 BTDM_BtTxRxCounterH(struct rtw_adapter *padapter);
-u32 BTDM_BtTxRxCounterL(struct rtw_adapter *padapter);
-
-/* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtCoexist.h ===== */
-
-/* ===== Below this line is sync from SD7 driver HAL/HalBT.h ===== */
-
-#define RTS_CTS_NO_LEN_LIMIT 0
-
-u8 HALBT_GetPGAntNum(struct rtw_adapter *padapter);
-#define BT_GetPGAntNum HALBT_GetPGAntNum
-void HALBT_SetKey(struct rtw_adapter *padapter, u8 EntryNum);
-void HALBT_RemoveKey(struct rtw_adapter *padapter, u8 EntryNum);
-u8 HALBT_IsBTExist(struct rtw_adapter *padapter);
-#define BT_IsBtExist HALBT_IsBTExist
-u8 HALBT_BTChipType(struct rtw_adapter *padapter);
-void HALBT_SetRtsCtsNoLenLimit(struct rtw_adapter *padapter);
-
-/* ===== End of sync from SD7 driver HAL/HalBT.c ===== */
-
-#define _bt_dbg_off_ 0
-#define _bt_dbg_on_ 1
-
-extern u32 BTCoexDbgLevel;
-
-
-
-#endif /* __RTL8723A_BT_COEXIST_H__ */
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_bt_intf.h b/drivers/staging/rtl8723au/include/rtl8723a_bt_intf.h
deleted file mode 100644
index 4733559970e5..000000000000
--- a/drivers/staging/rtl8723au/include/rtl8723a_bt_intf.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- * Copyright(c) 2014, Jes Sorensen <Jes.Sorensen@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTL8723A_BT_INTF_H__
-#define __RTL8723A_BT_INTF_H__
-
-#include <drv_types.h>
-
-#ifdef CONFIG_8723AU_BT_COEXIST
-enum rt_media_status;
-bool rtl8723a_BT_using_antenna_1(struct rtw_adapter *padapter);
-bool rtl8723a_BT_enabled(struct rtw_adapter *padapter);
-bool rtl8723a_BT_coexist(struct rtw_adapter *padapter);
-void rtl8723a_BT_do_coexist(struct rtw_adapter *padapter);
-void rtl8723a_BT_wifiscan_notify(struct rtw_adapter *padapter, u8 scanType);
-void rtl8723a_BT_mediastatus_notify(struct rtw_adapter *padapter,
- enum rt_media_status mstatus);
-void rtl8723a_BT_specialpacket_notify(struct rtw_adapter *padapter);
-void rtl8723a_BT_lps_leave(struct rtw_adapter *padapter);
-void rtl8723a_BT_disable_coexist(struct rtw_adapter *padapter);
-bool rtl8723a_BT_disable_EDCA_turbo(struct rtw_adapter *padapter);
-void rtl8723a_dual_antenna_detection(struct rtw_adapter *padapter);
-void rtl8723a_BT_init_hwconfig(struct rtw_adapter *padapter);
-void rtl8723a_BT_wifiassociate_notify(struct rtw_adapter *padapter, u8 action);
-void rtl8723a_BT_init_hal_vars(struct rtw_adapter *padapter);
-void rtl8723a_fw_c2h_BT_info(struct rtw_adapter *padapter, u8 *tmpBuf, u8 length);
-#else
-static inline bool rtl8723a_BT_using_antenna_1(struct rtw_adapter *padapter)
-{
- return false;
-}
-static inline bool rtl8723a_BT_enabled(struct rtw_adapter *padapter)
-{
- return false;
-}
-static inline bool rtl8723a_BT_coexist(struct rtw_adapter *padapter)
-{
- return false;
-}
-#define rtl8723a_BT_do_coexist(padapter) do {} while(0)
-#define rtl8723a_BT_wifiscan_notify(padapter, scanType) do {} while(0)
-#define rtl8723a_BT_mediastatus_notify(padapter, mstatus) do {} while(0)
-#define rtl8723a_BT_specialpacket_notify(padapter) do {} while(0)
-#define rtl8723a_BT_lps_leave(padapter) do {} while(0)
-#define rtl8723a_BT_disable_coexist(padapter) do {} while(0)
-static inline bool rtl8723a_BT_disable_EDCA_turbo(struct rtw_adapter *padapter)
-{
- return false;
-}
-#define rtl8723a_dual_antenna_detection(padapter) do {} while(0)
-#define rtl8723a_BT_init_hwconfig(padapter) do {} while(0)
-#define rtl8723a_BT_wifiassociate_notify(padapter, action) do {} while(0)
-#define rtl8723a_BT_init_hal_vars(padapter) do {} while(0)
-#define rtl8723a_fw_c2h_BT_info(padapter, tmpBuf, length) do {} while(0)
-#endif
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_cmd.h b/drivers/staging/rtl8723au/include/rtl8723a_cmd.h
deleted file mode 100644
index f95535a915ab..000000000000
--- a/drivers/staging/rtl8723au/include/rtl8723a_cmd.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTL8723A_CMD_H__
-#define __RTL8723A_CMD_H__
-
-
-#define H2C_BT_FW_PATCH_LEN 3
-#define H2C_BT_PWR_FORCE_LEN 3
-
-enum cmd_msg_element_id
-{
- NONE_CMDMSG_EID,
- AP_OFFLOAD_EID = 0,
- SET_PWRMODE_EID = 1,
- JOINBSS_RPT_EID = 2,
- RSVD_PAGE_EID = 3,
- RSSI_4_EID = 4,
- RSSI_SETTING_EID = 5,
- MACID_CONFIG_EID = 6,
- MACID_PS_MODE_EID = 7,
- P2P_PS_OFFLOAD_EID = 8,
- SELECTIVE_SUSPEND_ROF_CMD = 9,
- BT_QUEUE_PKT_EID = 17,
- BT_ANT_TDMA_EID = 20,
- BT_2ANT_HID_EID = 21,
- P2P_PS_CTW_CMD_EID = 32,
- FORCE_BT_TX_PWR_EID = 33,
- SET_TDMA_WLAN_ACT_TIME_EID = 34,
- SET_BT_TX_RETRY_INDEX_EID = 35,
- HID_PROFILE_ENABLE_EID = 36,
- BT_IGNORE_WLAN_ACT_EID = 37,
- BT_PTA_MANAGER_UPDATE_ENABLE_EID = 38,
- DAC_SWING_VALUE_EID = 41,
- TRADITIONAL_TDMA_EN_EID = 51,
- H2C_BT_FW_PATCH = 54,
- B_TYPE_TDMA_EID = 58,
- SCAN_EN_EID = 59,
- LOWPWR_LPS_EID = 71,
- H2C_RESET_TSF = 75,
- MAX_CMDMSG_EID
-};
-
-struct cmd_msg_parm {
- u8 eid; /* element id */
- u8 sz; /* sz */
- u8 buf[6];
-};
-
-struct setpwrmode_parm {
- u8 Mode;
- u8 SmartPS;
- u8 AwakeInterval; /* unit: beacon interval */
- u8 bAllQueueUAPSD;
-
-#define SETPM_LOWRXBCN BIT(0)
-#define SETPM_AUTOANTSWITCH BIT(1)
-#define SETPM_PSALLOWBTHIGHPRI BIT(2)
- u8 BcnAntMode;
-} __packed;
-
-struct H2C_SS_RFOFF_PARAM{
- u8 ROFOn; /* 1: on, 0:off */
- u16 gpio_period; /* unit: 1024 us */
-}__attribute__ ((packed));
-
-
-struct joinbssrpt_parm {
- u8 OpMode; /* enum rt_media_status */
-};
-
-struct rsvdpage_loc {
- u8 LocProbeRsp;
- u8 LocPsPoll;
- u8 LocNullData;
- u8 LocQosNull;
- u8 LocBTQosNull;
-};
-
-struct P2P_PS_Offload_t {
- u8 Offload_En:1;
- u8 role:1; /* 1: Owner, 0: Client */
- u8 CTWindow_En:1;
- u8 NoA0_En:1;
- u8 NoA1_En:1;
- u8 AllStaSleep:1; /* Only valid in Owner */
- u8 discovery:1;
- u8 rsvd:1;
-};
-
-struct P2P_PS_CTWPeriod_t {
- u8 CTWPeriod; /* TU */
-};
-
-#define B_TDMA_EN BIT(0)
-#define B_TDMA_FIXANTINBT BIT(1)
-#define B_TDMA_TXPSPOLL BIT(2)
-#define B_TDMA_VAL870 BIT(3)
-#define B_TDMA_AUTOWAKEUP BIT(4)
-#define B_TDMA_NOPS BIT(5)
-#define B_TDMA_WLANHIGHPRI BIT(6)
-
-struct b_type_tdma_parm {
- u8 option;
-
- u8 TBTTOnPeriod;
- u8 MedPeriod;
- u8 rsvd30;
-} __packed;
-
-struct scan_en_parm {
- u8 En;
-} __packed;
-
-/* BT_PWR */
-#define SET_H2CCMD_BT_PWR_IDX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT(__pH2CCmd, 0, 8, __Value)
-
-/* BT_FW_PATCH */
-#define SET_H2CCMD_BT_FW_PATCH_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_4BYTE(__pH2CCmd, 0, 8, __Value) /* SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) */
-#define SET_H2CCMD_BT_FW_PATCH_SIZE(__pH2CCmd, __Value) SET_BITS_TO_LE_4BYTE(__pH2CCmd, 8, 16, __Value) /* SET_BITS_TO_LE_2BYTE((__pH2CCmd)+1, 0, 16, __Value) */
-
-struct lowpwr_lps_parm{
- u8 bcn_count:4;
- u8 tb_bcn_threshold:3;
- u8 enable:1;
- u8 bcn_interval;
- u8 drop_threshold;
- u8 max_early_period;
- u8 max_bcn_timeout_period;
-} __packed;
-
-
-/* host message to firmware cmd */
-void rtl8723a_set_FwPwrMode_cmd(struct rtw_adapter *padapter, u8 Mode);
-void rtl8723a_set_FwJoinBssReport_cmd(struct rtw_adapter *padapter, u8 mstatus);
-#ifdef CONFIG_8723AU_BT_COEXIST
-void rtl8723a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(struct rtw_adapter *padapter);
-#else
-#define rtl8723a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(padapter) do {} while(0)
-#endif
-int rtl8723a_set_rssi_cmd(struct rtw_adapter *padapter, u32 param);
-int rtl8723a_set_raid_cmd(struct rtw_adapter *padapter, u32 mask, u8 arg);
-void rtl8723a_add_rateatid(struct rtw_adapter *padapter, u32 bitmap, u8 arg, u8 rssi_level);
-
-int FillH2CCmd(struct rtw_adapter *padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_dm.h b/drivers/staging/rtl8723au/include/rtl8723a_dm.h
deleted file mode 100644
index bf236e8e47a2..000000000000
--- a/drivers/staging/rtl8723au/include/rtl8723a_dm.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTL8723A_DM_H__
-#define __RTL8723A_DM_H__
-/* */
-/* Description: */
-/* */
-/* This file is for 8723A dynamic mechanism only */
-/* */
-/* */
-/* */
-#define DYNAMIC_FUNC_BT BIT(0)
-
-enum{
- UP_LINK,
- DOWN_LINK,
-};
-/* */
-/* structure and define */
-/* */
-
-/* duplicate code,will move to ODM ######### */
-#define IQK_MAC_REG_NUM 4
-#define IQK_ADDA_REG_NUM 16
-#define IQK_BB_REG_NUM 9
-#define HP_THERMAL_NUM 8
-/* duplicate code,will move to ODM ######### */
-struct dm_priv {
- u32 InitODMFlag;
-
- /* Upper and Lower Signal threshold for Rate Adaptive*/
- int UndecoratedSmoothedPWDB;
- int UndecoratedSmoothedCCK;
- int EntryMinUndecoratedSmoothedPWDB;
- int EntryMaxUndecoratedSmoothedPWDB;
- int MinUndecoratedPWDBForDM;
- int LastMinUndecoratedPWDBForDM;
-
- s32 UndecoratedSmoothedBeacon;
- #ifdef CONFIG_8723AU_BT_COEXIST
- s32 BT_EntryMinUndecoratedSmoothedPWDB;
- s32 BT_EntryMaxUndecoratedSmoothedPWDB;
- #endif
-
- /* for High Power */
- u8 DynamicTxHighPowerLvl;/* Add by Jacken Tx Power Control for Near/Far Range 2008/03/06 */
-
- /* for tx power tracking */
- u8 bTXPowerTracking;
- u8 TXPowercount;
- u8 bTXPowerTrackingInit;
- u8 TxPowerTrackControl; /* for mp mode, turn off txpwrtracking as default */
- u8 TM_Trigger;
-
- u8 ThermalMeter[2]; /* ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 */
- u8 ThermalValue;
- u8 ThermalValue_LCK;
- u8 ThermalValue_IQK;
- u8 ThermalValue_DPK;
-
- u8 bRfPiEnable;
-
- /* for APK */
- u32 APKoutput[2][2]; /* path A/B; output1_1a/output1_2a */
- u8 bAPKdone;
- u8 bAPKThermalMeterIgnore;
- u8 bDPdone;
- u8 bDPPathAOK;
- u8 bDPPathBOK;
-
- /* for IQK */
- u32 RegC04;
- u32 Reg874;
- u32 RegC08;
- u32 RegB68;
- u32 RegB6C;
- u32 Reg870;
- u32 Reg860;
- u32 Reg864;
- u32 ADDA_backup[IQK_ADDA_REG_NUM];
- u32 IQK_MAC_backup[IQK_MAC_REG_NUM];
- u32 IQK_BB_backup_recover[9];
- u32 IQK_BB_backup[IQK_BB_REG_NUM];
- u8 PowerIndex_backup[6];
-
- u8 bCCKinCH14;
-
- u8 CCK_index;
- u8 OFDM_index[2];
-
- u8 bDoneTxpower;
- u8 CCK_index_HP;
- u8 OFDM_index_HP[2];
- u8 ThermalValue_HP[HP_THERMAL_NUM];
- u8 ThermalValue_HP_index;
-
- /* for TxPwrTracking */
- s32 RegE94;
- s32 RegE9C;
- s32 RegEB4;
- s32 RegEBC;
-
- u32 TXPowerTrackingCallbackCnt; /* cosa add for debug */
-
- u32 prv_traffic_idx; /* edca turbo */
-
- s32 OFDM_Pkt_Cnt;
- u8 RSSI_Select;
-/* u8 DIG_Dynamic_MIN ; */
-/* duplicate code,will move to ODM ######### */
- /* Add for Reading Initial Data Rate SEL Register 0x484 during watchdog. Using for fill tx desc. 2011.3.21 by Thomas */
- u8 INIDATA_RATE[32];
-};
-
-
-/* */
-/* function prototype */
-/* */
-
-void rtl8723a_init_dm_priv(struct rtw_adapter *padapter);
-
-void rtl8723a_InitHalDm(struct rtw_adapter *padapter);
-void rtl8723a_HalDmWatchDog(struct rtw_adapter *padapter);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_hal.h b/drivers/staging/rtl8723au/include/rtl8723a_hal.h
deleted file mode 100644
index 77a0fd485b51..000000000000
--- a/drivers/staging/rtl8723au/include/rtl8723a_hal.h
+++ /dev/null
@@ -1,538 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTL8723A_HAL_H__
-#define __RTL8723A_HAL_H__
-
-#include "rtl8723a_spec.h"
-#include "rtl8723a_pg.h"
-#include "Hal8723APhyReg.h"
-#include "Hal8723APhyCfg.h"
-#include "rtl8723a_rf.h"
-#include "rtl8723a_bt_intf.h"
-#ifdef CONFIG_8723AU_BT_COEXIST
-#include "rtl8723a_bt-coexist.h"
-#endif
-#include "rtl8723a_dm.h"
-#include "rtl8723a_recv.h"
-#include "rtl8723a_xmit.h"
-#include "rtl8723a_cmd.h"
-#include "rtl8723a_sreset.h"
-#include "rtw_efuse.h"
-#include "rtw_eeprom.h"
-
-#include "odm_precomp.h"
-#include "odm.h"
-
-
-/* 2TODO: We should define 8192S firmware related macro settings here!! */
-#define RTL819X_DEFAULT_RF_TYPE RF_1T2R
-#define RTL819X_TOTAL_RF_PATH 2
-
-/* */
-/* RTL8723S From header */
-/* */
-
-/* Fw Array */
-#define Rtl8723_FwImageArray Rtl8723UFwImgArray
-#define Rtl8723_FwUMCBCutImageArrayWithBT Rtl8723UFwUMCBCutImgArrayWithBT
-#define Rtl8723_FwUMCBCutImageArrayWithoutBT Rtl8723UFwUMCBCutImgArrayWithoutBT
-
-#define Rtl8723_ImgArrayLength Rtl8723UImgArrayLength
-#define Rtl8723_UMCBCutImgArrayWithBTLength Rtl8723UUMCBCutImgArrayWithBTLength
-#define Rtl8723_UMCBCutImgArrayWithoutBTLength Rtl8723UUMCBCutImgArrayWithoutBTLength
-
-#define Rtl8723_PHY_REG_Array_PG Rtl8723UPHY_REG_Array_PG
-#define Rtl8723_PHY_REG_Array_PGLength Rtl8723UPHY_REG_Array_PGLength
-
-#define Rtl8723_FwUMCBCutMPImageArray Rtl8723SFwUMCBCutMPImgAr
-#define Rtl8723_UMCBCutMPImgArrayLength Rtl8723SUMCBCutMPImgArrayLength
-
-#define DRVINFO_SZ 4 /* unit is 8bytes */
-#define PageNum_128(_Len) (u32)(((_Len)>>7) + ((_Len)&0x7F ? 1:0))
-
-#define FW_8723A_SIZE 0x8000
-#define FW_8723A_START_ADDRESS 0x1000
-#define FW_8723A_END_ADDRESS 0x1FFF /* 0x5FFF */
-
-#define MAX_PAGE_SIZE 4096 /* @ page : 4k bytes */
-
-#define IS_FW_HEADER_EXIST(_pFwHdr) ((le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x92C0 ||\
- (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x88C0 ||\
- (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x2300)
-
-/* */
-/* This structure must be cared byte-ordering */
-/* */
-/* Added by tynli. 2009.12.04. */
-struct rt_8723a_firmware_hdr {
- /* 8-byte alinment required */
-
- /* LONG WORD 0 ---- */
- __le16 Signature; /*
- * 92C0: test chip; 92C, 88C0: test chip;
- * 88C1: MP A-cut; 92C1: MP A-cut
- */
- u8 Category; /* AP/NIC and USB/PCI */
- u8 Function; /* Reserved for different FW function indcation, for further use when driver needs to download different FW in different conditions */
- __le16 Version; /* FW Version */
- u8 Subversion; /* FW Subversion, default 0x00 */
- u8 Rsvd1;
-
-
- /* LONG WORD 1 ---- */
- u8 Month; /* Release time Month field */
- u8 Date; /* Release time Date field */
- u8 Hour; /* Release time Hour field */
- u8 Minute; /* Release time Minute field */
- __le16 RamCodeSize; /* The size of RAM code */
- __le16 Rsvd2;
-
- /* LONG WORD 2 ---- */
- __le32 SvnIdx; /* The SVN entry index */
- __le32 Rsvd3;
-
- /* LONG WORD 3 ---- */
- __le32 Rsvd4;
- __le32 Rsvd5;
-};
-
-#define DRIVER_EARLY_INT_TIME 0x05
-#define BCN_DMA_ATIME_INT_TIME 0x02
-
-
-/* BK, BE, VI, VO, HCCA, MANAGEMENT, COMMAND, HIGH, BEACON. */
-#define MAX_TX_QUEUE 9
-
-#define TX_SELE_HQ BIT(0) /* High Queue */
-#define TX_SELE_LQ BIT(1) /* Low Queue */
-#define TX_SELE_NQ BIT(2) /* Normal Queue */
-
-/* Note: We will divide number of page equally for each queue other than public queue! */
-#define TX_TOTAL_PAGE_NUMBER 0xF8
-#define TX_PAGE_BOUNDARY (TX_TOTAL_PAGE_NUMBER + 1)
-
-/* For Normal Chip Setting */
-/* (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER */
-#define NORMAL_PAGE_NUM_PUBQ 0xE7
-#define NORMAL_PAGE_NUM_HPQ 0x0C
-#define NORMAL_PAGE_NUM_LPQ 0x02
-#define NORMAL_PAGE_NUM_NPQ 0x02
-
-/* For Test Chip Setting */
-/* (HPQ + LPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER */
-#define TEST_PAGE_NUM_PUBQ 0x7E
-
-/* For Test Chip Setting */
-#define WMM_TEST_TX_TOTAL_PAGE_NUMBER 0xF5
-#define WMM_TEST_TX_PAGE_BOUNDARY (WMM_TEST_TX_TOTAL_PAGE_NUMBER + 1) /* F6 */
-
-#define WMM_TEST_PAGE_NUM_PUBQ 0xA3
-#define WMM_TEST_PAGE_NUM_HPQ 0x29
-#define WMM_TEST_PAGE_NUM_LPQ 0x29
-
-/* Note: For Normal Chip Setting, modify later */
-#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER 0xF5
-#define WMM_NORMAL_TX_PAGE_BOUNDARY (WMM_TEST_TX_TOTAL_PAGE_NUMBER + 1) /* F6 */
-
-#define WMM_NORMAL_PAGE_NUM_PUBQ 0xB0
-#define WMM_NORMAL_PAGE_NUM_HPQ 0x29
-#define WMM_NORMAL_PAGE_NUM_LPQ 0x1C
-#define WMM_NORMAL_PAGE_NUM_NPQ 0x1C
-
-
-/* */
-/* Chip specific */
-/* */
-#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3)
-#define CHIP_BONDING_92C_1T2R 0x1
-#define CHIP_BONDING_88C_USB_MCARD 0x2
-#define CHIP_BONDING_88C_USB_HP 0x1
-
-#include "HalVerDef.h"
-#include "hal_com.h"
-
-/* */
-/* Channel Plan */
-/* */
-enum ChannelPlan
-{
- CHPL_FCC = 0,
- CHPL_IC = 1,
- CHPL_ETSI = 2,
- CHPL_SPAIN = 3,
- CHPL_FRANCE = 4,
- CHPL_MKK = 5,
- CHPL_MKK1 = 6,
- CHPL_ISRAEL = 7,
- CHPL_TELEC = 8,
- CHPL_GLOBAL = 9,
- CHPL_WORLD = 10,
-};
-
-#define EFUSE_REAL_CONTENT_LEN 512
-#define EFUSE_MAP_LEN 128
-#define EFUSE_MAX_SECTION 16
-#define EFUSE_IC_ID_OFFSET 506 /* For some inferiority IC purpose. added by Roger, 2009.09.02. */
-#define AVAILABLE_EFUSE_ADDR(addr) (addr < EFUSE_REAL_CONTENT_LEN)
-/* */
-/* <Roger_Notes> */
-/* To prevent out of boundary programming case, */
-/* leave 1byte and program full section */
-/* 9bytes + 1byt + 5bytes and pre 1byte. */
-/* For worst case: */
-/* | 1byte|----8bytes----|1byte|--5bytes--| */
-/* | | Reserved(14bytes) | */
-/* */
-
-/* PG data exclude header, dummy 6 bytes from CP test and reserved 1byte. */
-#define EFUSE_OOB_PROTECT_BYTES 15
-
-#define EFUSE_REAL_CONTENT_LEN_8723A 512
-#define EFUSE_MAP_LEN_8723A 256
-#define EFUSE_MAX_SECTION_8723A 32
-
-/* */
-/* EFUSE for BT definition */
-/* */
-#define EFUSE_BT_REAL_BANK_CONTENT_LEN 512
-#define EFUSE_BT_REAL_CONTENT_LEN 1536 /* 512*3 */
-#define EFUSE_BT_MAP_LEN 1024 /* 1k bytes */
-#define EFUSE_BT_MAX_SECTION 128 /* 1024/8 */
-
-#define EFUSE_PROTECT_BYTES_BANK 16
-
-/* */
-/* <Roger_Notes> For RTL8723 WiFi/BT/GPS multi-function configuration. 2010.10.06. */
-/* */
-enum RT_MULTI_FUNC {
- RT_MULTI_FUNC_NONE = 0x00,
- RT_MULTI_FUNC_WIFI = 0x01,
- RT_MULTI_FUNC_BT = 0x02,
- RT_MULTI_FUNC_GPS = 0x04,
-};
-
-/* */
-/* <Roger_Notes> For RTL8723 WiFi PDn/GPIO polarity control configuration. 2010.10.08. */
-/* */
-enum RT_POLARITY_CTL {
- RT_POLARITY_LOW_ACT = 0,
- RT_POLARITY_HIGH_ACT = 1,
-};
-
-/* For RTL8723 regulator mode. by tynli. 2011.01.14. */
-enum RT_REGULATOR_MODE {
- RT_SWITCHING_REGULATOR = 0,
- RT_LDO_REGULATOR = 1,
-};
-
-/* Description: Determine the types of C2H events that are the same in driver and Fw. */
-/* Fisrt constructed by tynli. 2009.10.09. */
-enum {
- C2H_DBG = 0,
- C2H_TSF = 1,
- C2H_AP_RPT_RSP = 2,
- C2H_CCX_TX_RPT = 3, /* The FW notify the report of the specific tx packet. */
- C2H_BT_RSSI = 4,
- C2H_BT_OP_MODE = 5,
- C2H_EXT_RA_RPT = 6,
- C2H_HW_INFO_EXCH = 10,
- C2H_C2H_H2C_TEST = 11,
- C2H_BT_INFO = 12,
- C2H_BT_MP_INFO = 15,
- MAX_C2HEVENT
-};
-
-struct hal_data_8723a {
- struct hal_version VersionID;
- enum rt_customer_id CustomerID;
-
- u16 FirmwareVersion;
- u16 FirmwareVersionRev;
- u16 FirmwareSubVersion;
- u16 FirmwareSignature;
-
- /* current WIFI_PHY values */
- u32 ReceiveConfig;
- enum WIRELESS_MODE CurrentWirelessMode;
- enum ht_channel_width CurrentChannelBW;
- u8 CurrentChannel;
- u8 nCur40MhzPrimeSC;/* Control channel sub-carrier */
-
- u16 BasicRateSet;
-
- /* rf_ctrl */
- u8 rf_type;
- u8 NumTotalRFPath;
-
- u8 BoardType;
- u8 CrystalCap;
- /* */
- /* EEPROM setting. */
- /* */
- u8 EEPROMVersion;
- u8 EEPROMCustomerID;
- u8 EEPROMSubCustomerID;
- u8 EEPROMRegulatory;
- u8 EEPROMThermalMeter;
- u8 EEPROMBluetoothCoexist;
- u8 EEPROMBluetoothType;
- u8 EEPROMBluetoothAntNum;
- u8 EEPROMBluetoothAntIsolation;
- u8 EEPROMBluetoothRadioShared;
-
- u8 bTXPowerDataReadFromEEPORM;
- u8 bAPKThermalMeterIgnore;
-
- u8 bIQKInitialized;
- u8 bAntennaDetected;
-
- u8 TxPwrLevelCck[RF_PATH_MAX][CHANNEL_MAX_NUMBER];
- u8 TxPwrLevelHT40_1S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; /* For HT 40MHZ pwr */
- u8 TxPwrLevelHT40_2S[RF_PATH_MAX][CHANNEL_MAX_NUMBER]; /* For HT 40MHZ pwr */
- u8 TxPwrHt20Diff[RF_PATH_MAX][CHANNEL_MAX_NUMBER];/* HT 20<->40 Pwr diff */
- u8 TxPwrLegacyHtDiff[RF_PATH_MAX][CHANNEL_MAX_NUMBER];/* For HT<->legacy pwr diff */
- /* For power group */
- u8 PwrGroupHT20[RF_PATH_MAX][CHANNEL_MAX_NUMBER];
- u8 PwrGroupHT40[RF_PATH_MAX][CHANNEL_MAX_NUMBER];
-
- u8 LegacyHTTxPowerDiff;/* Legacy to HT rate power diff */
-
- /* Read/write are allow for following hardware information variables */
- u8 framesync;
- u32 framesyncC34;
- u8 framesyncMonitor;
- u8 pwrGroupCnt;
- u32 MCSTxPowerLevelOriginalOffset[7][16];
- u32 CCKTxPowerLevelOriginalOffset;
-
- u32 AntennaTxPath; /* Antenna path Tx */
- u32 AntennaRxPath; /* Antenna path Rx */
- u8 ExternalPA;
-
- u8 bLedOpenDrain; /* Support Open-drain arrangement for controlling the LED. Added by Roger, 2009.10.16. */
-
- u8 b1x1RecvCombine; /* for 1T1R receive combining */
-
- /* For EDCA Turbo mode */
-
- u32 AcParam_BE; /* Original parameter for BE, use for EDCA turbo. */
-
- /* vivi, for tx power tracking, 20080407 */
- /* u16 TSSI_13dBm; */
- /* u32 Pwr_Track; */
- /* The current Tx Power Level */
- u8 CurrentCckTxPwrIdx;
- u8 CurrentOfdm24GTxPwrIdx;
-
- struct bb_reg_define PHYRegDef[4]; /* Radio A/B/C/D */
-
- bool bRFPathRxEnable[4]; /* We support 4 RF path now. */
-
- u32 RfRegChnlVal[2];
-
- u8 bCckHighPower;
-
- /* RDG enable */
- bool bRDGEnable;
-
- /* for host message to fw */
- u8 LastHMEBoxNum;
-
- u8 RegTxPause;
- /* Beacon function related global variable. */
- u8 RegFwHwTxQCtrl;
- u8 RegReg542;
-
- struct dm_priv dmpriv;
- struct dm_odm_t odmpriv;
- struct sreset_priv srestpriv;
-
-#ifdef CONFIG_8723AU_BT_COEXIST
- u8 bBTMode;
- /* BT only. */
- struct bt_30info BtInfo;
- /* For bluetooth co-existance */
- struct bt_coexist_str bt_coexist;
-#endif
-
- u8 bDumpRxPkt;/* for debug */
- u8 FwRsvdPageStartOffset; /* 2010.06.23. Added by tynli. Reserve page start offset except beacon in TxQ. */
-
- /* 2010/08/09 MH Add CU power down mode. */
- u8 pwrdown;
-
- u8 OutEpQueueSel;
- u8 OutEpNumber;
-
- /* */
- /* Add For EEPROM Efuse switch and Efuse Shadow map Setting */
- /* */
- u8 EepromOrEfuse;
- u16 EfuseUsedBytes;
- u16 BTEfuseUsedBytes;
-
- /* Interrupt relatd register information. */
- u32 SysIntrStatus;
- u32 SysIntrMask;
-
- /* */
- /* 2011/02/23 MH Add for 8723 mylti function definition. The define should be moved to an */
- /* independent file in the future. */
- /* */
- /* 8723-----------------------------------------*/
- enum RT_MULTI_FUNC MultiFunc; /* For multi-function consideration. */
- enum RT_POLARITY_CTL PolarityCtl; /* For Wifi PDn Polarity control. */
- enum RT_REGULATOR_MODE RegulatorMode; /* switching regulator or LDO */
- /* 8723-----------------------------------------
- * 2011/02/23 MH Add for 8723 mylti function definition. The define should be moved to an */
- /* independent file in the future. */
-
- /* Interrupt related register information. */
- u32 IntArray[2];
- u32 IntrMask[2];
-};
-
-#define GET_HAL_DATA(__pAdapter) ((struct hal_data_8723a *)((__pAdapter)->HalData))
-#define GET_RF_TYPE(priv) (GET_HAL_DATA(priv)->rf_type)
-
-#define INCLUDE_MULTI_FUNC_BT(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_BT)
-#define INCLUDE_MULTI_FUNC_GPS(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS)
-
-struct rxreport_8723a {
- u32 pktlen:14;
- u32 crc32:1;
- u32 icverr:1;
- u32 drvinfosize:4;
- u32 security:3;
- u32 qos:1;
- u32 shift:2;
- u32 physt:1;
- u32 swdec:1;
- u32 ls:1;
- u32 fs:1;
- u32 eor:1;
- u32 own:1;
-
- u32 macid:5;
- u32 tid:4;
- u32 hwrsvd:4;
- u32 amsdu:1;
- u32 paggr:1;
- u32 faggr:1;
- u32 a1fit:4;
- u32 a2fit:4;
- u32 pam:1;
- u32 pwr:1;
- u32 md:1;
- u32 mf:1;
- u32 type:2;
- u32 mc:1;
- u32 bc:1;
-
- u32 seq:12;
- u32 frag:4;
- u32 nextpktlen:14;
- u32 nextind:1;
- u32 rsvd0831:1;
-
- u32 rxmcs:6;
- u32 rxht:1;
- u32 gf:1;
- u32 splcp:1;
- u32 bw:1;
- u32 htc:1;
- u32 eosp:1;
- u32 bssidfit:2;
- u32 rsvd1214:16;
- u32 unicastwake:1;
- u32 magicwake:1;
-
- u32 pattern0match:1;
- u32 pattern1match:1;
- u32 pattern2match:1;
- u32 pattern3match:1;
- u32 pattern4match:1;
- u32 pattern5match:1;
- u32 pattern6match:1;
- u32 pattern7match:1;
- u32 pattern8match:1;
- u32 pattern9match:1;
- u32 patternamatch:1;
- u32 patternbmatch:1;
- u32 patterncmatch:1;
- u32 rsvd1613:19;
-
- u32 tsfl;
-
- u32 bassn:12;
- u32 bavld:1;
- u32 rsvd2413:19;
-};
-
-/* rtl8723a_hal_init.c */
-s32 rtl8723a_FirmwareDownload(struct rtw_adapter *padapter);
-void rtl8723a_FirmwareSelfReset(struct rtw_adapter *padapter);
-void rtl8723a_InitializeFirmwareVars(struct rtw_adapter *padapter);
-
-void rtl8723a_InitAntenna_Selection(struct rtw_adapter *padapter);
-void rtl8723a_DeinitAntenna_Selection(struct rtw_adapter *padapter);
-void rtl8723a_CheckAntenna_Selection(struct rtw_adapter *padapter);
-void rtl8723a_init_default_value(struct rtw_adapter *padapter);
-
-s32 InitLLTTable23a(struct rtw_adapter *padapter, u32 boundary);
-
-s32 CardDisableHWSM(struct rtw_adapter *padapter, u8 resetMCU);
-s32 CardDisableWithoutHWSM(struct rtw_adapter *padapter);
-
-/* EFuse */
-u8 GetEEPROMSize8723A(struct rtw_adapter *padapter);
-void Hal_InitPGData(struct rtw_adapter *padapter, u8 *PROMContent);
-void Hal_EfuseParseIDCode(struct rtw_adapter *padapter, u8 *hwinfo);
-void Hal_EfuseParsetxpowerinfo_8723A(struct rtw_adapter *padapter, u8 *PROMContent, bool AutoLoadFail);
-void Hal_EfuseParseBTCoexistInfo_8723A(struct rtw_adapter *padapter, u8 *hwinfo, bool AutoLoadFail);
-void Hal_EfuseParseEEPROMVer(struct rtw_adapter *padapter, u8 *hwinfo, bool AutoLoadFail);
-void rtl8723a_EfuseParseChnlPlan(struct rtw_adapter *padapter, u8 *hwinfo, bool AutoLoadFail);
-void Hal_EfuseParseCustomerID(struct rtw_adapter *padapter, u8 *hwinfo, bool AutoLoadFail);
-void Hal_EfuseParseAntennaDiversity(struct rtw_adapter *padapter, u8 *hwinfo, bool AutoLoadFail);
-void Hal_EfuseParseRateIndicationOption(struct rtw_adapter *padapter, u8 *hwinfo, bool AutoLoadFail);
-void Hal_EfuseParseXtal_8723A(struct rtw_adapter *pAdapter, u8 *hwinfo, u8 AutoLoadFail);
-void Hal_EfuseParseThermalMeter_8723A(struct rtw_adapter *padapter, u8 *hwinfo, bool AutoLoadFail);
-
-/* register */
-void SetBcnCtrlReg23a(struct rtw_adapter *padapter, u8 SetBits, u8 ClearBits);
-void rtl8723a_InitBeaconParameters(struct rtw_adapter *padapter);
-
-void rtl8723a_start_thread(struct rtw_adapter *padapter);
-void rtl8723a_stop_thread(struct rtw_adapter *padapter);
-
-bool c2h_id_filter_ccx_8723a(u8 id);
-int c2h_handler_8723a(struct rtw_adapter *padapter, struct c2h_evt_hdr *c2h_evt);
-
-void rtl8723a_read_adapter_info(struct rtw_adapter *Adapter);
-void rtl8723a_read_chip_version(struct rtw_adapter *padapter);
-void rtl8723a_notch_filter(struct rtw_adapter *adapter, bool enable);
-void rtl8723a_SetBeaconRelatedRegisters(struct rtw_adapter *padapter);
-void rtl8723a_SetHalODMVar(struct rtw_adapter *Adapter,
- enum hal_odm_variable eVariable,
- void *pValue1, bool bSet);
-void
-rtl8723a_readefuse(struct rtw_adapter *padapter,
- u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf);
-u16 rtl8723a_EfuseGetCurrentSize_WiFi(struct rtw_adapter *padapter);
-u16 rtl8723a_EfuseGetCurrentSize_BT(struct rtw_adapter *padapter);
-void rtl8723a_update_ramask(struct rtw_adapter *padapter,
- u32 mac_id, u8 rssi_level);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_pg.h b/drivers/staging/rtl8723au/include/rtl8723a_pg.h
deleted file mode 100644
index 5c2ec448e568..000000000000
--- a/drivers/staging/rtl8723au/include/rtl8723a_pg.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTL8723A_PG_H__
-#define __RTL8723A_PG_H__
-
-/* EEPROM/Efuse PG Offset for 8723E/8723U/8723S */
-#define EEPROM_CCK_TX_PWR_INX_8723A 0x10
-#define EEPROM_HT40_1S_TX_PWR_INX_8723A 0x16
-#define EEPROM_HT20_TX_PWR_INX_DIFF_8723A 0x1C
-#define EEPROM_OFDM_TX_PWR_INX_DIFF_8723A 0x1F
-#define EEPROM_HT40_MAX_PWR_OFFSET_8723A 0x22
-#define EEPROM_HT20_MAX_PWR_OFFSET_8723A 0x25
-
-#define EEPROM_ChannelPlan_8723A 0x28
-#define EEPROM_TSSI_A_8723A 0x29
-#define EEPROM_THERMAL_METER_8723A 0x2A
-#define RF_OPTION1_8723A 0x2B
-#define RF_OPTION2_8723A 0x2C
-#define RF_OPTION3_8723A 0x2D
-#define RF_OPTION4_8723A 0x2E
-#define EEPROM_VERSION_8723A 0x30
-#define EEPROM_CustomID_8723A 0x31
-#define EEPROM_SubCustomID_8723A 0x32
-#define EEPROM_XTAL_K_8723A 0x33
-#define EEPROM_Chipset_8723A 0x34
-
-/* RTL8723AE */
-#define EEPROM_VID_8723AE 0x49
-#define EEPROM_DID_8723AE 0x4B
-#define EEPROM_SVID_8723AE 0x4D
-#define EEPROM_SMID_8723AE 0x4F
-#define EEPROM_MAC_ADDR_8723AE 0x67
-
-/* RTL8723AU */
-#define EEPROM_MAC_ADDR_8723AU 0xC6
-#define EEPROM_VID_8723AU 0xB7
-#define EEPROM_PID_8723AU 0xB9
-
-/* RTL8723AS */
-#define EEPROM_MAC_ADDR_8723AS 0xAA
-
-/* EEPROM/Efuse Value Type */
-#define EETYPE_TX_PWR 0x0
-
-/* EEPROM/Efuse Default Value */
-#define EEPROM_Default_CrystalCap_8723A 0x20
-
-
-/* EEPROM/EFUSE data structure definition. */
-#define MAX_CHNL_GROUP 3+9
-
-struct txpowerinfo {
- u8 CCKIndex[RF_PATH_MAX][MAX_CHNL_GROUP];
- u8 HT40_1SIndex[RF_PATH_MAX][MAX_CHNL_GROUP];
- u8 HT40_2SIndexDiff[RF_PATH_MAX][MAX_CHNL_GROUP];
- u8 HT20IndexDiff[RF_PATH_MAX][MAX_CHNL_GROUP];
- u8 OFDMIndexDiff[RF_PATH_MAX][MAX_CHNL_GROUP];
- u8 HT40MaxOffset[RF_PATH_MAX][MAX_CHNL_GROUP];
- u8 HT20MaxOffset[RF_PATH_MAX][MAX_CHNL_GROUP];
- u8 TSSI_A[3];
- u8 TSSI_B[3];
- u8 TSSI_A_5G[3]; /* 5GL/5GM/5GH */
- u8 TSSI_B_5G[3];
-};
-
-enum bt_ant_num {
- Ant_x2 = 0,
- Ant_x1 = 1
-};
-
-enum bt_cotype {
- BT_2Wire = 0,
- BT_ISSC_3Wire = 1,
- BT_Accel = 2,
- BT_CSR_BC4 = 3,
- BT_CSR_BC8 = 4,
- BT_RTL8756 = 5,
- BT_RTL8723A = 6
-};
-
-enum bt_radioshared {
- BT_Radio_Shared = 0,
- BT_Radio_Individual = 1,
-};
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_recv.h b/drivers/staging/rtl8723au/include/rtl8723a_recv.h
deleted file mode 100644
index 875d37b3b94c..000000000000
--- a/drivers/staging/rtl8723au/include/rtl8723a_recv.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTL8723A_RECV_H__
-#define __RTL8723A_RECV_H__
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-#define NR_RECVBUFF 4
-
-#define NR_PREALLOC_RECV_SKB 8
-
-#define RECV_BLK_SZ 512
-#define RECV_BLK_CNT 16
-#define RECV_BLK_TH RECV_BLK_CNT
-
-#define MAX_RECVBUF_SZ 15360 /* 15k < 16k */
-
-#define PHY_RSSI_SLID_WIN_MAX 100
-#define PHY_LINKQUALITY_SLID_WIN_MAX 20
-
-
-struct phy_stat {
- unsigned int phydw0;
- unsigned int phydw1;
- unsigned int phydw2;
- unsigned int phydw3;
- unsigned int phydw4;
- unsigned int phydw5;
- unsigned int phydw6;
- unsigned int phydw7;
-};
-
-/* Rx smooth factor */
-#define Rx_Smooth_Factor 20
-
-struct interrupt_msg_format {
- unsigned int C2H_MSG0;
- unsigned int C2H_MSG1;
- unsigned int C2H_MSG2;
- unsigned int C2H_MSG3;
- unsigned int HISR; /* from HISR Reg0x124, read to clear */
- unsigned int HISRE;/* from HISRE Reg0x12c, read to clear */
- unsigned int MSG_EX;
-};
-
-int rtl8723au_init_recv_priv(struct rtw_adapter *padapter);
-void rtl8723au_free_recv_priv(struct rtw_adapter *padapter);
-void rtl8723a_process_phy_info(struct rtw_adapter *padapter, void *prframe);
-void update_recvframe_attrib(struct recv_frame *precvframe, struct recv_stat *prxstat);
-void update_recvframe_phyinfo(struct recv_frame *precvframe, struct phy_stat *pphy_info);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_rf.h b/drivers/staging/rtl8723au/include/rtl8723a_rf.h
deleted file mode 100644
index 0432799f53cf..000000000000
--- a/drivers/staging/rtl8723au/include/rtl8723a_rf.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTL8723A_RF_H__
-#define __RTL8723A_RF_H__
-
-/*--------------------------Define Parameters-------------------------------*/
-
-/* */
-/* For RF 6052 Series */
-/* */
-#define RF6052_MAX_TX_PWR 0x3F
-#define RF6052_MAX_REG 0x3F
-#define RF6052_MAX_PATH 2
-/*--------------------------Define Parameters-------------------------------*/
-
-
-/*------------------------------Define structure----------------------------*/
-
-/*------------------------------Define structure----------------------------*/
-
-
-/*------------------------Export global variable----------------------------*/
-/*------------------------Export global variable----------------------------*/
-
-/*------------------------Export Marco Definition---------------------------*/
-
-/*------------------------Export Marco Definition---------------------------*/
-
-
-/*--------------------------Exported Function prototype---------------------*/
-
-/* */
-/* RF RL6052 Series API */
-/* */
-void rtl8723a_phy_rf6052set_bw(struct rtw_adapter *Adapter,
- enum ht_channel_width Bandwidth);
-void rtl823a_phy_rf6052setccktxpower(struct rtw_adapter *Adapter,
- u8 *pPowerlevel);
-void rtl8723a_PHY_RF6052SetOFDMTxPower(struct rtw_adapter *Adapter,
- u8 *pPowerLevel, u8 Channel);
-
-/*--------------------------Exported Function prototype---------------------*/
-
-int PHY_RF6052_Config8723A(struct rtw_adapter *Adapter);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_spec.h b/drivers/staging/rtl8723au/include/rtl8723a_spec.h
deleted file mode 100644
index 2f186890dbb5..000000000000
--- a/drivers/staging/rtl8723au/include/rtl8723a_spec.h
+++ /dev/null
@@ -1,2148 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- *******************************************************************************/
-#ifndef __RTL8723A_SPEC_H__
-#define __RTL8723A_SPEC_H__
-
-/* */
-/* */
-/* 0x0000h ~ 0x00FFh System Configuration */
-/* */
-/* */
-#define REG_SYS_ISO_CTRL 0x0000
-#define REG_SYS_FUNC_EN 0x0002
-#define REG_APS_FSMCO 0x0004
-#define REG_SYS_CLKR 0x0008
-#define REG_9346CR 0x000A
-#define REG_EE_VPD 0x000C
-#define REG_AFE_MISC 0x0010
-#define REG_SPS0_CTRL 0x0011
-#define REG_SPS_OCP_CFG 0x0018
-#define REG_RSV_CTRL 0x001C
-#define REG_RF_CTRL 0x001F
-#define REG_LDOA15_CTRL 0x0020
-#define REG_LDOV12D_CTRL 0x0021
-#define REG_LDOHCI12_CTRL 0x0022
-#define REG_LPLDO_CTRL 0x0023
-#define REG_AFE_XTAL_CTRL 0x0024
-#define REG_AFE_PLL_CTRL 0x0028
-#define REG_MAC_PHY_CTRL 0x002c
-#define REG_EFUSE_CTRL 0x0030
-#define REG_EFUSE_TEST 0x0034
-#define REG_PWR_DATA 0x0038
-#define REG_CAL_TIMER 0x003C
-#define REG_ACLK_MON 0x003E
-#define REG_GPIO_MUXCFG 0x0040
-#define REG_GPIO_IO_SEL 0x0042
-#define REG_MAC_PINMUX_CFG 0x0043
-#define REG_GPIO_PIN_CTRL 0x0044
-#define REG_GPIO_INTM 0x0048
-#define REG_LEDCFG0 0x004C
-#define REG_LEDCFG1 0x004D
-#define REG_LEDCFG2 0x004E
-#define REG_LEDCFG3 0x004F
-#define REG_LEDCFG REG_LEDCFG2
-#define REG_FSIMR 0x0050
-#define REG_FSISR 0x0054
-#define REG_HSIMR 0x0058
-#define REG_HSISR 0x005c
- /* RTL8723 WIFI/BT/GPS Multi-Function GPIO Pin Control. */
-#define REG_GPIO_PIN_CTRL_2 0x0060
- /* RTL8723 WIFI/BT/GPS Multi-Function GPIO Select. */
-#define REG_GPIO_IO_SEL_2 0x0062
- /* RTL8723 WIFI/BT/GPS Multi-Function control source. */
-#define REG_MULTI_FUNC_CTRL 0x0068
-#define REG_MCUFWDL 0x0080
-#define REG_HMEBOX_EXT_0 0x0088
-#define REG_HMEBOX_EXT_1 0x008A
-#define REG_HMEBOX_EXT_2 0x008C
-#define REG_HMEBOX_EXT_3 0x008E
- /* Host suspend counter on FPGA platform */
-#define REG_HOST_SUSP_CNT 0x00BC
- /* Efuse access protection for RTL8723 */
-#define REG_EFUSE_ACCESS 0x00CF
-#define REG_BIST_SCAN 0x00D0
-#define REG_BIST_RPT 0x00D4
-#define REG_BIST_ROM_RPT 0x00D8
-#define REG_USB_SIE_INTF 0x00E0
-#define REG_PCIE_MIO_INTF 0x00E4
-#define REG_PCIE_MIO_INTD 0x00E8
-#define REG_HPON_FSM 0x00EC
-#define REG_SYS_CFG 0x00F0
-#define REG_GPIO_OUTSTS 0x00F4 /* For RTL8723 only. */
-
-/* */
-/* */
-/* 0x0100h ~ 0x01FFh MACTOP General Configuration */
-/* */
-/* */
-#define REG_CR 0x0100
-#define REG_PBP 0x0104
-#define REG_TRXDMA_CTRL 0x010C
-#define REG_TRXFF_BNDY 0x0114
-#define REG_TRXFF_STATUS 0x0118
-#define REG_RXFF_PTR 0x011C
-#define REG_HIMR 0x0120
-#define REG_HISR 0x0124
-#define REG_HIMRE 0x0128
-#define REG_HISRE 0x012C
-#define REG_CPWM 0x012F
-#define REG_FWIMR 0x0130
-#define REG_FWISR 0x0134
-#define REG_PKTBUF_DBG_CTRL 0x0140
-#define REG_PKTBUF_DBG_DATA_L 0x0144
-#define REG_PKTBUF_DBG_DATA_H 0x0148
-
-#define REG_TC0_CTRL 0x0150
-#define REG_TC1_CTRL 0x0154
-#define REG_TC2_CTRL 0x0158
-#define REG_TC3_CTRL 0x015C
-#define REG_TC4_CTRL 0x0160
-#define REG_TCUNIT_BASE 0x0164
-#define REG_MBIST_START 0x0174
-#define REG_MBIST_DONE 0x0178
-#define REG_MBIST_FAIL 0x017C
-#define REG_C2HEVT_MSG_NORMAL 0x01A0
-#define REG_C2HEVT_CLEAR 0x01AF
-#define REG_C2HEVT_MSG_TEST 0x01B8
-#define REG_MCUTST_1 0x01c0
-#define REG_FMETHR 0x01C8
-#define REG_HMETFR 0x01CC
-#define REG_HMEBOX_0 0x01D0
-#define REG_HMEBOX_1 0x01D4
-#define REG_HMEBOX_2 0x01D8
-#define REG_HMEBOX_3 0x01DC
-
-#define REG_LLT_INIT 0x01E0
-#define REG_BB_ACCEESS_CTRL 0x01E8
-#define REG_BB_ACCESS_DATA 0x01EC
-
-
-/* */
-/* */
-/* 0x0200h ~ 0x027Fh TXDMA Configuration */
-/* */
-/* */
-#define REG_RQPN 0x0200
-#define REG_FIFOPAGE 0x0204
-#define REG_TDECTRL 0x0208
-#define REG_TXDMA_OFFSET_CHK 0x020C
-#define REG_TXDMA_STATUS 0x0210
-#define REG_RQPN_NPQ 0x0214
-
-/* */
-/* */
-/* 0x0280h ~ 0x02FFh RXDMA Configuration */
-/* */
-/* */
-#define REG_RXDMA_AGG_PG_TH 0x0280
-#define REG_RXPKT_NUM 0x0284
-#define REG_RXDMA_STATUS 0x0288
-
-
-/* */
-/* */
-/* 0x0300h ~ 0x03FFh PCIe */
-/* */
-/* */
-#define REG_PCIE_CTRL_REG 0x0300
-#define REG_INT_MIG 0x0304 /* Interrupt Migration */
- /* TX Beacon Descriptor Address */
-#define REG_BCNQ_DESA 0x0308
- /* TX High Queue Descriptor Address */
-#define REG_HQ_DESA 0x0310
- /* TX Manage Queue Descriptor Address */
-#define REG_MGQ_DESA 0x0318
- /* TX VO Queue Descriptor Address */
-#define REG_VOQ_DESA 0x0320
- /* TX VI Queue Descriptor Address */
-#define REG_VIQ_DESA 0x0328
- /* TX BE Queue Descriptor Address */
-#define REG_BEQ_DESA 0x0330
- /* TX BK Queue Descriptor Address */
-#define REG_BKQ_DESA 0x0338
- /* RX Queue Descriptor Address */
-#define REG_RX_DESA 0x0340
- /* Backdoor REG for Access Configuration */
-#define REG_DBI 0x0348
- /* MDIO for Access PCIE PHY */
-#define REG_MDIO 0x0354
- /* Debug Selection Register */
-#define REG_DBG_SEL 0x0360
- /* PCIe RPWM */
-#define REG_PCIE_HRPWM 0x0361
- /* PCIe CPWM */
-#define REG_PCIE_HCPWM 0x0363
- /* UART Control */
-#define REG_UART_CTRL 0x0364
- /* UART TX Descriptor Address */
-#define REG_UART_TX_DESA 0x0370
- /* UART Rx Descriptor Address */
-#define REG_UART_RX_DESA 0x0378
-
-
-/* spec version 11 */
-/* */
-/* */
-/* 0x0400h ~ 0x047Fh Protocol Configuration */
-/* */
-/* */
-#define REG_VOQ_INFORMATION 0x0400
-#define REG_VIQ_INFORMATION 0x0404
-#define REG_BEQ_INFORMATION 0x0408
-#define REG_BKQ_INFORMATION 0x040C
-#define REG_MGQ_INFORMATION 0x0410
-#define REG_HGQ_INFORMATION 0x0414
-#define REG_BCNQ_INFORMATION 0x0418
-
-
-#define REG_CPU_MGQ_INFORMATION 0x041C
-#define REG_FWHW_TXQ_CTRL 0x0420
-#define REG_HWSEQ_CTRL 0x0423
-#define REG_TXPKTBUF_BCNQ_BDNY 0x0424
-#define REG_TXPKTBUF_MGQ_BDNY 0x0425
-#define REG_LIFETIME_EN 0x0426
-#define REG_MULTI_BCNQ_OFFSET 0x0427
-#define REG_SPEC_SIFS 0x0428
-#define REG_RL 0x042A
-#define REG_DARFRC 0x0430
-#define REG_RARFRC 0x0438
-#define REG_RRSR 0x0440
-#define REG_ARFR0 0x0444
-#define REG_ARFR1 0x0448
-#define REG_ARFR2 0x044C
-#define REG_ARFR3 0x0450
-#define REG_AGGLEN_LMT 0x0458
-#define REG_AMPDU_MIN_SPACE 0x045C
-#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D
-#define REG_FAST_EDCA_CTRL 0x0460
-#define REG_RD_RESP_PKT_TH 0x0463
-#define REG_INIRTS_RATE_SEL 0x0480
-#define REG_INIDATA_RATE_SEL 0x0484
-
-
-#define REG_POWER_STATUS 0x04A4
-#define REG_POWER_STAGE1 0x04B4
-#define REG_POWER_STAGE2 0x04B8
-#define REG_PKT_VO_VI_LIFE_TIME 0x04C0
-#define REG_PKT_BE_BK_LIFE_TIME 0x04C2
-#define REG_STBC_SETTING 0x04C4
-#define REG_PROT_MODE_CTRL 0x04C8
-#define REG_MAX_AGGR_NUM 0x04CA
-#define REG_RTS_MAX_AGGR_NUM 0x04CB
-#define REG_BAR_MODE_CTRL 0x04CC
-#define REG_RA_TRY_RATE_AGG_LMT 0x04CF
-#define REG_NQOS_SEQ 0x04DC
-#define REG_QOS_SEQ 0x04DE
-#define REG_NEED_CPU_HANDLE 0x04E0
-#define REG_PKT_LOSE_RPT 0x04E1
-#define REG_PTCL_ERR_STATUS 0x04E2
-#define REG_DUMMY 0x04FC
-
-
-
-/* */
-/* */
-/* 0x0500h ~ 0x05FFh EDCA Configuration */
-/* */
-/* */
-#define REG_EDCA_VO_PARAM 0x0500
-#define REG_EDCA_VI_PARAM 0x0504
-#define REG_EDCA_BE_PARAM 0x0508
-#define REG_EDCA_BK_PARAM 0x050C
-#define REG_BCNTCFG 0x0510
-#define REG_PIFS 0x0512
-#define REG_RDG_PIFS 0x0513
-#define REG_SIFS_CCK 0x0514
-#define REG_SIFS_OFDM 0x0516
-#define REG_SIFS_CTX 0x0514
-#define REG_SIFS_TRX 0x0516
-#define REG_TSFTR_SYN_OFFSET 0x0518
-#define REG_AGGR_BREAK_TIME 0x051A
-#define REG_SLOT 0x051B
-#define REG_TX_PTCL_CTRL 0x0520
-#define REG_TXPAUSE 0x0522
-#define REG_DIS_TXREQ_CLR 0x0523
-#define REG_RD_CTRL 0x0524
-#define REG_TBTT_PROHIBIT 0x0540
-#define REG_RD_NAV_NXT 0x0544
-#define REG_NAV_PROT_LEN 0x0546
-#define REG_BCN_CTRL 0x0550
-#define REG_BCN_CTRL_1 0x0551
-#define REG_MBID_NUM 0x0552
-#define REG_DUAL_TSF_RST 0x0553
- /* The same as REG_MBSSID_BCN_SPACE */
-#define REG_BCN_INTERVAL 0x0554
-#define REG_MBSSID_BCN_SPACE 0x0554
-#define REG_DRVERLYINT 0x0558
-#define REG_BCNDMATIM 0x0559
-#define REG_ATIMWND 0x055A
-#define REG_BCN_MAX_ERR 0x055D
-#define REG_RXTSF_OFFSET_CCK 0x055E
-#define REG_RXTSF_OFFSET_OFDM 0x055F
-#define REG_TSFTR 0x0560
-#define REG_TSFTR1 0x0568
-#define REG_INIT_TSFTR 0x0564
-#define REG_ATIMWND_1 0x0570
-#define REG_PSTIMER 0x0580
-#define REG_TIMER0 0x0584
-#define REG_TIMER1 0x0588
-#define REG_ACMHWCTRL 0x05C0
-#define REG_ACMRSTCTRL 0x05C1
-#define REG_ACMAVG 0x05C2
-#define REG_VO_ADMTIME 0x05C4
-#define REG_VI_ADMTIME 0x05C6
-#define REG_BE_ADMTIME 0x05C8
-#define REG_EDCA_RANDOM_GEN 0x05CC
-#define REG_SCH_TXCMD 0x05D0
-
-/* define REG_FW_TSF_SYNC_CNT 0x04A0 */
-#define REG_FW_RESET_TSF_CNT_1 0x05FC
-#define REG_FW_RESET_TSF_CNT_0 0x05FD
-#define REG_FW_BCN_DIS_CNT 0x05FE
-
-/* */
-/* */
-/* 0x0600h ~ 0x07FFh WMAC Configuration */
-/* */
-/* */
-#define REG_APSD_CTRL 0x0600
-#define REG_BWOPMODE 0x0603
-#define REG_TCR 0x0604
-#define REG_RCR 0x0608
-#define REG_RX_PKT_LIMIT 0x060C
-#define REG_RX_DLK_TIME 0x060D
-#define REG_RX_DRVINFO_SZ 0x060F
-
-#define REG_MACID 0x0610
-#define REG_BSSID 0x0618
-#define REG_MAR 0x0620
-#define REG_MBIDCAMCFG 0x0628
-
-#define REG_USTIME_EDCA 0x0638
-#define REG_MAC_SPEC_SIFS 0x063A
-
-/* 20100719 Joseph: Hardware register definition change. (HW datasheet v54) */
- /* [15:8]SIFS_R2T_OFDM, [7:0]SIFS_R2T_CCK */
-#define REG_R2T_SIFS 0x063C
- /* [15:8]SIFS_T2T_OFDM, [7:0]SIFS_T2T_CCK */
-#define REG_T2T_SIFS 0x063E
-#define REG_ACKTO 0x0640
-#define REG_CTS2TO 0x0641
-#define REG_EIFS 0x0642
-
-/* WMA, BA, CCX */
-#define REG_NAV_CTRL 0x0650
-#define REG_BACAMCMD 0x0654
-#define REG_BACAMCONTENT 0x0658
-#define REG_LBDLY 0x0660
-#define REG_FWDLY 0x0661
-#define REG_RXERR_RPT 0x0664
-#define REG_WMAC_TRXPTCL_CTL 0x0668
-
-
-/* Security */
-#define REG_CAMCMD 0x0670
-#define REG_CAMWRITE 0x0674
-#define REG_CAMREAD 0x0678
-#define REG_CAMDBG 0x067C
-#define REG_SECCFG 0x0680
-
-/* Power */
-#define REG_WOW_CTRL 0x0690
-#define REG_PSSTATUS 0x0691
-#define REG_PS_RX_INFO 0x0692
-#define REG_LPNAV_CTRL 0x0694
-#define REG_WKFMCAM_CMD 0x0698
-#define REG_WKFMCAM_RWD 0x069C
-#define REG_RXFLTMAP0 0x06A0
-#define REG_RXFLTMAP1 0x06A2
-#define REG_RXFLTMAP2 0x06A4
-#define REG_BCN_PSR_RPT 0x06A8
-#define REG_CALB32K_CTRL 0x06AC
-#define REG_PKT_MON_CTRL 0x06B4
-#define REG_BT_COEX_TABLE 0x06C0
-#define REG_WMAC_RESP_TXINFO 0x06D8
-
-#define REG_MACID1 0x0700
-#define REG_BSSID1 0x0708
-
-
-/* */
-/* */
-/* 0xFE00h ~ 0xFE55h USB Configuration */
-/* */
-/* */
-#define REG_USB_INFO 0xFE17
-#define REG_USB_SPECIAL_OPTION 0xFE55
-#define REG_USB_DMA_AGG_TO 0xFE5B
-#define REG_USB_AGG_TO 0xFE5C
-#define REG_USB_AGG_TH 0xFE5D
-
-/* For test chip */
-#define REG_TEST_USB_TXQS 0xFE48
-#define REG_TEST_SIE_VID 0xFE60 /* 0xFE60~0xFE61 */
-#define REG_TEST_SIE_PID 0xFE62 /* 0xFE62~0xFE63 */
-#define REG_TEST_SIE_OPTIONAL 0xFE64
-#define REG_TEST_SIE_CHIRP_K 0xFE65
-#define REG_TEST_SIE_PHY 0xFE66 /* 0xFE66~0xFE6B */
-#define REG_TEST_SIE_MAC_ADDR 0xFE70 /* 0xFE70~0xFE75 */
-#define REG_TEST_SIE_STRING 0xFE80 /* 0xFE80~0xFEB9 */
-
-
-/* For normal chip */
-#define REG_NORMAL_SIE_VID 0xFE60 /* 0xFE60~0xFE61 */
-#define REG_NORMAL_SIE_PID 0xFE62 /* 0xFE62~0xFE63 */
-#define REG_NORMAL_SIE_OPTIONAL 0xFE64
-#define REG_NORMAL_SIE_EP 0xFE65 /* 0xFE65~0xFE67 */
-#define REG_NORMAL_SIE_PHY 0xFE68 /* 0xFE68~0xFE6B */
-#define REG_NORMAL_SIE_OPTIONAL2 0xFE6C
-#define REG_NORMAL_SIE_GPS_EP 0xFE6D /* RTL8723 only */
-#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 /* 0xFE70~0xFE75 */
-#define REG_NORMAL_SIE_STRING 0xFE80 /* 0xFE80~0xFEDF */
-
-
-/* */
-/* */
-/* Redifine 8192C register definition for compatibility */
-/* */
-/* */
-
-/* TODO: use these definition when using REG_xxx naming rule. */
-/* NOTE: DO NOT Remove these definition. Use later. */
-
- /* System Isolation Interface Control. */
-#define SYS_ISO_CTRL REG_SYS_ISO_CTRL
- /* System Function Enable. */
-#define SYS_FUNC_EN REG_SYS_FUNC_EN
-#define SYS_CLK REG_SYS_CLKR
- /* 93C46/93C56 Command Register. */
-#define CR9346 REG_9346CR
- /* E-Fuse Control. */
-#define EFUSE_CTRL REG_EFUSE_CTRL
- /* E-Fuse Test. */
-#define EFUSE_TEST REG_EFUSE_TEST
- /* Media Status register */
-#define MSR (REG_CR + 2)
-#define ISR REG_HISR
- /* Timing Sync Function Timer Register. */
-#define TSFR REG_TSFTR
-
- /* MAC ID Register, Offset 0x0050-0x0053 */
-#define MACIDR0 REG_MACID
- /* MAC ID Register, Offset 0x0054-0x0055 */
-#define MACIDR4 (REG_MACID + 4)
-
-#define PBP REG_PBP
-
- /* Redifine MACID register, to compatible prior ICs. */
-#define IDR0 MACIDR0
-#define IDR4 MACIDR4
-
-
-/* */
-/* 9. Security Control Registers (Offset: ) */
-/* */
- /* Software write CAM input content */
-#define WCAMI REG_CAMWRITE
- /* Software read/write CAM config */
-#define RCAMO REG_CAMREAD
-#define CAMDBG REG_CAMDBG
- /* Security Configuration Register */
-#define SECR REG_SECCFG
-
-/* Unused register */
-#define UnusedRegister 0x1BF
-#define DCAM UnusedRegister
-#define PSR UnusedRegister
-#define BBAddr UnusedRegister
-#define PhyDataR UnusedRegister
-
-#define InvalidBBRFValue 0x12345678
-
-/* Min Spacing related settings. */
-#define MAX_MSS_DENSITY_2T 0x13
-#define MAX_MSS_DENSITY_1T 0x0A
-
-/* */
-/* 8192C Cmd9346CR bits (Offset 0xA, 16bit) */
-/* */
- /* EEPROM enable when set 1 */
-#define CmdEEPROM_En BIT(5)
- /* System EEPROM select, 0: boot from E-FUSE,
- 1: The EEPROM used is 9346 */
-#define CmdEERPOMSEL BIT(4)
-#define Cmd9346CR_9356SEL BIT(4)
-#define AutoLoadEEPROM (CmdEEPROM_En|CmdEERPOMSEL)
-#define AutoLoadEFUSE CmdEEPROM_En
-
-/* */
-/* 8192C GPIO MUX Configuration Register (offset 0x40, 4 byte) */
-/* */
-#define GPIOSEL_GPIO 0
-#define GPIOSEL_ENBT BIT(5)
-
-/* */
-/* 8192C GPIO PIN Control Register (offset 0x44, 4 byte) */
-/* */
- /* GPIO pins input value */
-#define GPIO_IN REG_GPIO_PIN_CTRL
- /* GPIO pins output value */
-#define GPIO_OUT (REG_GPIO_PIN_CTRL+1)
- /* GPIO pins output enable when a bit is set to "1";
- otherwise, input is configured. */
-#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2)
-#define GPIO_MOD (REG_GPIO_PIN_CTRL+3)
-
-/* */
-/* 8192C (MSR) Media Status Register (Offset 0x4C, 8 bits) */
-/* */
-/*
-Network Type
-00: No link
-01: Link in ad hoc network
-10: Link in infrastructure network
-11: AP mode
-Default: 00b.
-*/
-#define MSR_NOLINK 0x00
-#define MSR_ADHOC 0x01
-#define MSR_INFRA 0x02
-#define MSR_AP 0x03
-
-/* */
-/* 6. Adaptive Control Registers (Offset: 0x0160 - 0x01CF) */
-/* */
-/* */
-/* 8192C Response Rate Set Register (offset 0x181, 24bits) */
-/* */
-#define RRSR_RSC_OFFSET 21
-#define RRSR_SHORT_OFFSET 23
-#define RRSR_RSC_BW_40M 0x600000
-#define RRSR_RSC_UPSUBCHNL 0x400000
-#define RRSR_RSC_LOWSUBCHNL 0x200000
-#define RRSR_SHORT 0x800000
-#define RRSR_1M BIT(0)
-#define RRSR_2M BIT(1)
-#define RRSR_5_5M BIT(2)
-#define RRSR_11M BIT(3)
-#define RRSR_6M BIT(4)
-#define RRSR_9M BIT(5)
-#define RRSR_12M BIT(6)
-#define RRSR_18M BIT(7)
-#define RRSR_24M BIT(8)
-#define RRSR_36M BIT(9)
-#define RRSR_48M BIT(10)
-#define RRSR_54M BIT(11)
-#define RRSR_MCS0 BIT(12)
-#define RRSR_MCS1 BIT(13)
-#define RRSR_MCS2 BIT(14)
-#define RRSR_MCS3 BIT(15)
-#define RRSR_MCS4 BIT(16)
-#define RRSR_MCS5 BIT(17)
-#define RRSR_MCS6 BIT(18)
-#define RRSR_MCS7 BIT(19)
-#define BRSR_AckShortPmb BIT(23)
-/* CCK ACK: use Short Preamble or not */
-
-/* */
-/* 8192C BW_OPMODE bits (Offset 0x203, 8bit) */
-/* */
-#define BW_OPMODE_20MHZ BIT(2)
-#define BW_OPMODE_5G BIT(1)
-#define BW_OPMODE_11J BIT(0)
-
-
-/* */
-/* 8192C CAM Config Setting (offset 0x250, 1 byte) */
-/* */
-#define CAM_VALID BIT(15)
-#define CAM_NOTVALID 0x0000
-#define CAM_USEDK BIT(5)
-
-#define CAM_CONTENT_COUNT 8
-
-#define CAM_NONE 0x0
-#define CAM_WEP40 0x01
-#define CAM_TKIP 0x02
-#define CAM_AES 0x04
-#define CAM_WEP104 0x05
-
-#define TOTAL_CAM_ENTRY 32
-#define HALF_CAM_ENTRY 16
-
-#define CAM_CONFIG_USEDK true
-#define CAM_CONFIG_NO_USEDK false
-
-#define CAM_WRITE BIT(16)
-#define CAM_READ 0x00000000
-#define CAM_POLLINIG BIT(31)
-
-#define SCR_UseDK 0x01
-#define SCR_TxSecEnable 0x02
-#define SCR_RxSecEnable 0x04
-
-
-/* */
-/* 12. Host Interrupt Status Registers (Offset: 0x0300 - 0x030F) */
-/* */
-/* */
-/* 8190 IMR/ISR bits (offset 0xfd, 8bits) */
-/* */
-#define IMR8190_DISABLED 0x0
-/* IMR DW0 Bit 0-31 */
-
-#define IMR_BCNDMAINT6 BIT(31) /* Beacon DMA Interrupt 6 */
-#define IMR_BCNDMAINT5 BIT(30) /* Beacon DMA Interrupt 5 */
-#define IMR_BCNDMAINT4 BIT(29) /* Beacon DMA Interrupt 4 */
-#define IMR_BCNDMAINT3 BIT(28) /* Beacon DMA Interrupt 3 */
-#define IMR_BCNDMAINT2 BIT(27) /* Beacon DMA Interrupt 2 */
-#define IMR_BCNDMAINT1 BIT(26) /* Beacon DMA Interrupt 1 */
-#define IMR_BCNDOK8 BIT(25) /* Beacon Queue DMA OK
- Interrupt 8 */
-#define IMR_BCNDOK7 BIT(24) /* Beacon Queue DMA OK
- Interrupt 7 */
-#define IMR_BCNDOK6 BIT(23) /* Beacon Queue DMA OK
- Interrupt 6 */
-#define IMR_BCNDOK5 BIT(22) /* Beacon Queue DMA OK
- Interrupt 5 */
-#define IMR_BCNDOK4 BIT(21) /* Beacon Queue DMA OK
- Interrupt 4 */
-#define IMR_BCNDOK3 BIT(20) /* Beacon Queue DMA OK
- Interrupt 3 */
-#define IMR_BCNDOK2 BIT(19) /* Beacon Queue DMA OK
- Interrupt 2 */
-#define IMR_BCNDOK1 BIT(18) /* Beacon Queue DMA OK
- Interrupt 1 */
-#define IMR_TIMEOUT2 BIT(17) /* Timeout interrupt 2 */
-#define IMR_TIMEOUT1 BIT(16) /* Timeout interrupt 1 */
-#define IMR_TXFOVW BIT(15) /* Transmit FIFO Overflow */
-#define IMR_PSTIMEOUT BIT(14) /* Power save time out
- interrupt */
-#define IMR_BcnInt BIT(13) /* Beacon DMA Interrupt 0 */
-#define IMR_RXFOVW BIT(12) /* Receive FIFO Overflow */
-#define IMR_RDU BIT(11) /* Receive Descriptor
- Unavailable */
-#define IMR_ATIMEND BIT(10) /* For 92C,ATIM Window
- End Interrupt */
-#define IMR_BDOK BIT(9) /* Beacon Queue DMA OK
- Interrup */
-#define IMR_HIGHDOK BIT(8) /* High Queue DMA OK
- Interrupt */
-#define IMR_TBDOK BIT(7) /* Transmit Beacon OK
- interrup */
-#define IMR_MGNTDOK BIT(6) /* Management Queue DMA OK
- Interrupt */
-#define IMR_TBDER BIT(5) /* For 92C,Transmit Beacon
- Error Interrupt */
-#define IMR_BKDOK BIT(4) /* AC_BK DMA OK Interrupt */
-#define IMR_BEDOK BIT(3) /* AC_BE DMA OK Interrupt */
-#define IMR_VIDOK BIT(2) /* AC_VI DMA OK Interrupt */
-#define IMR_VODOK BIT(1) /* AC_VO DMA Interrupt */
-#define IMR_ROK BIT(0) /* Receive DMA OK Interrupt */
-
-#define IMR_RX_MASK (IMR_ROK|IMR_RDU|IMR_RXFOVW)
-#define IMR_TX_MASK (IMR_VODOK|IMR_VIDOK|IMR_BEDOK| \
- IMR_BKDOK|IMR_MGNTDOK|IMR_HIGHDOK| \
- IMR_BDOK)
-
-/* 13. Host Interrupt Status Extension Register (Offset: 0x012C-012Eh) */
-#define IMR_BcnInt_E BIT(12)
-#define IMR_TXERR BIT(11)
-#define IMR_RXERR BIT(10)
-#define IMR_C2HCMD BIT(9)
-#define IMR_CPWM BIT(8)
-/* RSVD [2-7] */
-#define IMR_OCPINT BIT(1)
-#define IMR_WLANOFF BIT(0)
-
-
-/* 8192C EEPROM/EFUSE share register definition. */
-
-/* Default Value for EEPROM or EFUSE!!! */
-#define EEPROM_Default_TSSI 0x0
-#define EEPROM_Default_TxPowerDiff 0x0
-#define EEPROM_Default_CrystalCap 0x5
- /* Default: 2X2, RTL8192CE(QFPN68) */
-#define EEPROM_Default_BoardType 0x02
-#define EEPROM_Default_TxPower 0x1010
-#define EEPROM_Default_HT2T_TxPwr 0x10
-
-#define EEPROM_Default_LegacyHTTxPowerDiff 0x3
-#define EEPROM_Default_ThermalMeter 0x12
-
-#define EEPROM_Default_AntTxPowerDiff 0x0
-#define EEPROM_Default_TxPwDiff_CrystalCap 0x5
-#define EEPROM_Default_TxPowerLevel 0x22
-#define EEPROM_Default_HT40_2SDiff 0x0
- /* HT20<->40 default Tx Power Index Difference */
-#define EEPROM_Default_HT20_Diff 2
-#define EEPROM_Default_LegacyHTTxPowerDiff 0x3
-#define EEPROM_Default_HT40_PwrMaxOffset 0
-#define EEPROM_Default_HT20_PwrMaxOffset 0
-
-/* For debug */
-#define EEPROM_Default_PID 0x1234
-#define EEPROM_Default_VID 0x5678
-#define EEPROM_Default_CustomerID 0xAB
-#define EEPROM_Default_SubCustomerID 0xCD
-#define EEPROM_Default_Version 0
-
-#define EEPROM_CHANNEL_PLAN_FCC 0x0
-#define EEPROM_CHANNEL_PLAN_IC 0x1
-#define EEPROM_CHANNEL_PLAN_ETSI 0x2
-#define EEPROM_CHANNEL_PLAN_SPAIN 0x3
-#define EEPROM_CHANNEL_PLAN_FRANCE 0x4
-#define EEPROM_CHANNEL_PLAN_MKK 0x5
-#define EEPROM_CHANNEL_PLAN_MKK1 0x6
-#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7
-#define EEPROM_CHANNEL_PLAN_TELEC 0x8
-#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9
-#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA
-#define EEPROM_CHANNEL_PLAN_NCC 0xB
-#define EEPROM_USB_OPTIONAL1 0xE
-#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
-
-
-#define EEPROM_CID_DEFAULT 0x0
-#define EEPROM_CID_TOSHIBA 0x4
- /* CCX test. By Bruce, 2009-02-25. */
-#define EEPROM_CID_CCX 0x10
-#define EEPROM_CID_QMI 0x0D
- /* added by chiyoko for dtm, 20090108 */
-#define EEPROM_CID_WHQL 0xFE
-
-
-#define RTL_EEPROM_ID 0x8129
-
-#define SUPPORT_HW_RADIO_DETECT(pHalData) \
- (pHalData->BoardType == BOARD_MINICARD || \
- pHalData->BoardType == BOARD_USB_SOLO || \
- pHalData->BoardType == BOARD_USB_COMBO)
-
-/* */
-/* EEPROM address for Test chip */
-/* */
-#define EEPROM_TEST_USB_OPT 0x0E
-#define EEPROM_TEST_CHIRP_K 0x0F
-#define EEPROM_TEST_EP_SETTING 0x0E
-#define EEPROM_TEST_USB_PHY 0x10
-
-
-/* */
-/* EEPROM address for Normal chip */
-/* */
-#define EEPROM_NORMAL_USB_OPT 0x0E
-#define EEPROM_NORMAL_CHIRP_K 0x0E /* Changed */
-#define EEPROM_NORMAL_EP_SETTING 0x0F /* Changed */
-#define EEPROM_NORMAL_USB_PHY 0x12 /* Changed */
-
-enum {
- BOARD_USB_DONGLE = 0, /* USB dongle */
- BOARD_USB_High_PA = 1, /* USB dongle with high power PA */
- BOARD_MINICARD = 2, /* Minicard */
- BOARD_USB_SOLO = 3, /* USB solo-Slim module */
- BOARD_USB_COMBO = 4, /* USB Combo-Slim module */
-};
-
-/* Test chip and normal chip common define */
-/* */
-/* EEPROM address for both */
-/* */
-#define EEPROM_ID0 0x00
-#define EEPROM_ID1 0x01
-#define EEPROM_RTK_RSV1 0x02
-#define EEPROM_RTK_RSV2 0x03
-#define EEPROM_RTK_RSV3 0x04
-#define EEPROM_RTK_RSV4 0x05
-#define EEPROM_RTK_RSV5 0x06
-#define EEPROM_DBG_SEL 0x07
-#define EEPROM_RTK_RSV6 0x08
-#define EEPROM_VID 0x0A
-#define EEPROM_PID 0x0C
-
-#define EEPROM_MAC_ADDR 0x16
-#define EEPROM_STRING 0x1C
-#define EEPROM_SUBCUSTOMER_ID 0x59
-#define EEPROM_CCK_TX_PWR_INX 0x5A
-#define EEPROM_HT40_1S_TX_PWR_INX 0x60
-#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66
-#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69
-#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C
-#define EEPROM_HT40_MAX_PWR_OFFSET 0x6F
-#define EEPROM_HT20_MAX_PWR_OFFSET 0x72
-
-#define EEPROM_CHANNEL_PLAN 0x75
-#define EEPROM_TSSI_A 0x76
-#define EEPROM_TSSI_B 0x77
-#define EEPROM_THERMAL_METER 0x78
-#define EEPROM_RF_OPT1 0x79
-#define EEPROM_RF_OPT2 0x7A
-#define EEPROM_RF_OPT3 0x7B
-#define EEPROM_RF_OPT4 0x7C
-#define EEPROM_VERSION 0x7E
-#define EEPROM_CUSTOMER_ID 0x7F
-
- /* 0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU */
-#define EEPROM_BoardType 0x54
- /* 0x5C-0x76, Tx Power index. */
-#define EEPROM_TxPwIndex 0x5C
- /* Difference of gain index between legacy and high throughput OFDM. */
-#define EEPROM_PwDiff 0x67
- /* CCK Tx Power */
-#define EEPROM_TxPowerCCK 0x5A
-
-/* 2009/02/09 Cosa Add for SD3 requirement */
- /* HT20 Tx Power Index Difference */
-#define EEPROM_TX_PWR_HT20_DIFF 0x6e
- /* HT20<->40 default Tx Power Index Difference */
-#define DEFAULT_HT20_TXPWR_DIFF 2
- /* OFDM Tx Power Index Difference */
-#define EEPROM_TX_PWR_OFDM_DIFF 0x71
-
- /* Power diff for channel group */
-#define EEPROM_TxPWRGroup 0x73
- /* Check if power safety is need */
-#define EEPROM_Regulatory 0x79
-
- /* 92cu, 0x7E[4] */
-#define EEPROM_BLUETOOTH_COEXIST 0x7E
-#define EEPROM_NORMAL_BoardType EEPROM_RF_OPT1 /* 7:5] */
-#define BOARD_TYPE_NORMAL_MASK 0xE0
-#define BOARD_TYPE_TEST_MASK 0x0F
- /* BIT0 1 for build-in module, 0 for external dongle */
-#define EEPROM_EASY_REPLACEMENT 0x50
-/* */
-/* EPROM content definitions */
-/* */
-#define OS_LINK_SPEED BIT(5)
-
-#define BOARD_TYPE_MASK 0xF
-
-#define BT_COEXISTENCE BIT(4)
-#define BT_CO_SHIFT 4
-
-#define EP_NUMBER_MASK 0x30 /* bit 4:5 0Eh */
-#define EP_NUMBER_SHIFT 4
-
-
-#define USB_PHY_PARA_SIZE 5
-
-
-/* */
-/* EEPROM default value definitions */
-/* */
-/* Use 0xABCD instead of 0x8192 for debug */
-#define EEPROM_DEF_ID_0 0xCD /* Byte 0x00 */
-#define EEPROM_DEF_ID_1 0xAB /* Byte 0x01 */
-
-#define EEPROM_DEF_RTK_RSV_A3 0x74 /* Byte 0x03 */
-#define EEPROM_DEF_RTK_RSV_A4 0x6D /* Byte 0x04 */
-#define EEPROM_DEF_RTK_RSV_A8 0xFF /* Byte 0x08 */
-
-#define EEPROM_DEF_VID_0 0x0A /* Byte 0x0A */
-#define EEPROM_DEF_VID_1 0x0B
-
-#define EEPROM_DEF_PID_0 0x92 /* Byte 0x0C */
-#define EEPROM_DEF_PID_1 0x81
-
-
-#define EEPROM_TEST_DEF_USB_OPT 0x80 /* Byte 0x0E */
-#define EEPROM_NORMAL_DEF_USB_OPT 0x00 /* Byte 0x0E */
-
-#define EEPROM_DEF_CHIRPK 0x15 /* Byte 0x0F */
-
-#define EEPROM_DEF_USB_PHY_0 0x85 /* Byte 0x10 */
-#define EEPROM_DEF_USB_PHY_1 0x62 /* Byte 0x11 */
-#define EEPROM_DEF_USB_PHY_2 0x9E /* Byte 0x12 */
-#define EEPROM_DEF_USB_PHY_3 0x06 /* Byte 0x13 */
-
-#define EEPROM_DEF_TSSI_A 0x09 /* Byte 0x78 */
-#define EEPROM_DEF_TSSI_B 0x09 /* Byte 0x79 */
-
-
-#define EEPROM_DEF_THERMAL_METER 0x12 /* Byte 0x7A */
-
- /* Check if power safety spec is need */
-#define RF_OPTION1 0x79
-#define RF_OPTION2 0x7A
-#define RF_OPTION3 0x7B
-#define RF_OPTION4 0x7C
-
-
-#define EEPROM_USB_SN BIT(0)
-#define EEPROM_USB_REMOTE_WAKEUP BIT(1)
-#define EEPROM_USB_DEVICE_PWR BIT(2)
-#define EEPROM_EP_NUMBER (BIT(3)|BIT(4))
-
-/*===================================================================
-=====================================================================
-Here the register defines are for 92C. When the define is as same with 92C,
-we will use the 92C's define for the consistency
-So the following defines for 92C is not entire!!!!!!
-=====================================================================
-=====================================================================*/
-/*
-Based on Datasheet V33---090401
-Register Summary
-Current IOREG MAP
-0x0000h ~ 0x00FFh System Configuration (256 Bytes)
-0x0100h ~ 0x01FFh MACTOP General Configuration (256 Bytes)
-0x0200h ~ 0x027Fh TXDMA Configuration (128 Bytes)
-0x0280h ~ 0x02FFh RXDMA Configuration (128 Bytes)
-0x0300h ~ 0x03FFh PCIE EMAC Reserved Region (256 Bytes)
-0x0400h ~ 0x04FFh Protocol Configuration (256 Bytes)
-0x0500h ~ 0x05FFh EDCA Configuration (256 Bytes)
-0x0600h ~ 0x07FFh WMAC Configuration (512 Bytes)
-0x2000h ~ 0x3FFFh 8051 FW Download Region (8196 Bytes)
-*/
-
-/* */
-/* 8192C (RCR) Receive Configuration Register (Offset 0x608, 32 bits) */
-/* */
-#define RCR_APPFCS BIT(31) /* WMAC append FCS after payload*/
-#define RCR_APP_MIC BIT(30)
-#define RCR_APP_PHYSTS BIT(28)
-#define RCR_APP_ICV BIT(29)
-#define RCR_APP_PHYST_RXFF BIT(28)
-#define RCR_APP_BA_SSN BIT(27) /* Accept BA SSN */
-#define RCR_ENMBID BIT(24) /* Enable Multiple BssId. */
-#define RCR_LSIGEN BIT(23)
-#define RCR_MFBEN BIT(22)
-#define RCR_HTC_LOC_CTRL BIT(14) /* MFC<--HTC=1 MFC-->HTC=0 */
-#define RCR_AMF BIT(13) /* Accept management type frame */
-#define RCR_ACF BIT(12) /* Accept control type frame */
-#define RCR_ADF BIT(11) /* Accept data type frame */
-#define RCR_AICV BIT(9) /* Accept ICV error packet */
-#define RCR_ACRC32 BIT(8) /* Accept CRC32 error packet */
-#define RCR_CBSSID_BCN BIT(7) /* Accept BSSID match packet
- (Rx beacon, probe rsp) */
-#define RCR_CBSSID_DATA BIT(6) /* Accept BSSID match packet
- (Data) */
-#define RCR_CBSSID RCR_CBSSID_DATA /* Accept BSSID match
- packet */
-#define RCR_APWRMGT BIT(5) /* Accept power management
- packet */
-#define RCR_ADD3 BIT(4) /* Accept address 3 match
- packet */
-#define RCR_AB BIT(3) /* Accept broadcast packet */
-#define RCR_AM BIT(2) /* Accept multicast packet */
-#define RCR_APM BIT(1) /* Accept physical match packet */
-#define RCR_AAP BIT(0) /* Accept all unicast packet */
-#define RCR_MXDMA_OFFSET 8
-#define RCR_FIFO_OFFSET 13
-
-
-
-/* */
-/* 8192c USB specific Regsiter Offset and Content definition, */
-/* 2009.08.18, added by vivi. for merge 92c and 92C into one driver */
-/* */
-/* define APS_FSMCO 0x0004 same with 92Ce */
-#define RSV_CTRL 0x001C
-#define RD_CTRL 0x0524
-
-/* */
-/* */
-/* 0xFE00h ~ 0xFE55h USB Configuration */
-/* */
-/* */
-#define REG_USB_INFO 0xFE17
-#define REG_USB_SPECIAL_OPTION 0xFE55
-#define REG_USB_DMA_AGG_TO 0xFE5B
-#define REG_USB_AGG_TO 0xFE5C
-#define REG_USB_AGG_TH 0xFE5D
-
-#define REG_USB_VID 0xFE60
-#define REG_USB_PID 0xFE62
-#define REG_USB_OPTIONAL 0xFE64
-#define REG_USB_CHIRP_K 0xFE65
-#define REG_USB_PHY 0xFE66
-#define REG_USB_MAC_ADDR 0xFE70
-
-#define REG_USB_HRPWM 0xFE58
-#define REG_USB_HCPWM 0xFE57
-
-#define InvalidBBRFValue 0x12345678
-
-/* */
-/* 8192C Regsiter Bit and Content definition */
-/* */
-/* */
-/* */
-/* 0x0000h ~ 0x00FFh System Configuration */
-/* */
-/* */
-
-/* 2 SPS0_CTRL */
-#define SW18_FPWM BIT(3)
-
-
-/* 2 SYS_ISO_CTRL */
-#define ISO_MD2PP BIT(0)
-#define ISO_UA2USB BIT(1)
-#define ISO_UD2CORE BIT(2)
-#define ISO_PA2PCIE BIT(3)
-#define ISO_PD2CORE BIT(4)
-#define ISO_IP2MAC BIT(5)
-#define ISO_DIOP BIT(6)
-#define ISO_DIOE BIT(7)
-#define ISO_EB2CORE BIT(8)
-#define ISO_DIOR BIT(9)
-
-#define PWC_EV25V BIT(14)
-#define PWC_EV12V BIT(15)
-
-
-/* 2 SYS_FUNC_EN */
-#define FEN_BBRSTB BIT(0)
-#define FEN_BB_GLB_RSTn BIT(1)
-#define FEN_USBA BIT(2)
-#define FEN_UPLL BIT(3)
-#define FEN_USBD BIT(4)
-#define FEN_DIO_PCIE BIT(5)
-#define FEN_PCIEA BIT(6)
-#define FEN_PPLL BIT(7)
-#define FEN_PCIED BIT(8)
-#define FEN_DIOE BIT(9)
-#define FEN_CPUEN BIT(10)
-#define FEN_DCORE BIT(11)
-#define FEN_ELDR BIT(12)
-#define FEN_DIO_RF BIT(13)
-#define FEN_HWPDN BIT(14)
-#define FEN_MREGEN BIT(15)
-
-/* 2 APS_FSMCO */
-#define PFM_LDALL BIT(0)
-#define PFM_ALDN BIT(1)
-#define PFM_LDKP BIT(2)
-#define PFM_WOWL BIT(3)
-#define EnPDN BIT(4)
-#define PDN_PL BIT(5)
-#define APFM_ONMAC BIT(8)
-#define APFM_OFF BIT(9)
-#define APFM_RSM BIT(10)
-#define AFSM_HSUS BIT(11)
-#define AFSM_PCIE BIT(12)
-#define APDM_MAC BIT(13)
-#define APDM_HOST BIT(14)
-#define APDM_HPDN BIT(15)
-#define RDY_MACON BIT(16)
-#define SUS_HOST BIT(17)
-#define ROP_ALD BIT(20)
-#define ROP_PWR BIT(21)
-#define ROP_SPS BIT(22)
-#define SOP_MRST BIT(25)
-#define SOP_FUSE BIT(26)
-#define SOP_ABG BIT(27)
-#define SOP_AMB BIT(28)
-#define SOP_RCK BIT(29)
-#define SOP_A8M BIT(30)
-#define XOP_BTCK BIT(31)
-
-/* 2 SYS_CLKR */
-#define ANAD16V_EN BIT(0)
-#define ANA8M BIT(1)
-#define MACSLP BIT(4)
-#define LOADER_CLK_EN BIT(5)
-#define _80M_SSC_DIS BIT(7)
-#define _80M_SSC_EN_HO BIT(8)
-#define PHY_SSC_RSTB BIT(9)
-#define SEC_CLK_EN BIT(10)
-#define MAC_CLK_EN BIT(11)
-#define SYS_CLK_EN BIT(12)
-#define RING_CLK_EN BIT(13)
-
-
-/* 2 9346CR */
-
-
-#define EEDO BIT(0)
-#define EEDI BIT(1)
-#define EESK BIT(2)
-#define EECS BIT(3)
-/* define EERPROMSEL BIT(4) */
-/* define EEPROM_EN BIT(5) */
-#define BOOT_FROM_EEPROM BIT(4)
-#define EEPROM_EN BIT(5)
-#define EEM0 BIT(6)
-#define EEM1 BIT(7)
-
-
-/* 2 AFE_MISC */
-#define AFE_BGEN BIT(0)
-#define AFE_MBEN BIT(1)
-#define MAC_ID_EN BIT(7)
-
-
-/* 2 SPS0_CTRL */
-
-
-/* 2 SPS_OCP_CFG */
-
-
-/* 2 RSV_CTRL */
-#define WLOCK_ALL BIT(0)
-#define WLOCK_00 BIT(1)
-#define WLOCK_04 BIT(2)
-#define WLOCK_08 BIT(3)
-#define WLOCK_40 BIT(4)
-#define R_DIS_PRST_0 BIT(5)
-#define R_DIS_PRST_1 BIT(6)
-#define LOCK_ALL_EN BIT(7)
-
-/* 2 RF_CTRL */
-#define RF_EN BIT(0)
-#define RF_RSTB BIT(1)
-#define RF_SDMRSTB BIT(2)
-
-
-
-/* 2 LDOA15_CTRL */
-#define LDA15_EN BIT(0)
-#define LDA15_STBY BIT(1)
-#define LDA15_OBUF BIT(2)
-#define LDA15_REG_VOS BIT(3)
-#define _LDA15_VOADJ(x) (((x) & 0x7) << 4)
-
-
-
-/* 2 LDOV12D_CTRL */
-#define LDV12_EN BIT(0)
-#define LDV12_SDBY BIT(1)
-#define LPLDO_HSM BIT(2)
-#define LPLDO_LSM_DIS BIT(3)
-#define _LDV12_VADJ(x) (((x) & 0xF) << 4)
-
-
-/* 2 AFE_XTAL_CTRL */
-#define XTAL_EN BIT(0)
-#define XTAL_BSEL BIT(1)
-#define _XTAL_BOSC(x) (((x) & 0x3) << 2)
-#define _XTAL_CADJ(x) (((x) & 0xF) << 4)
-#define XTAL_GATE_USB BIT(8)
-#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9)
-#define XTAL_GATE_AFE BIT(11)
-#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12)
-#define XTAL_RF_GATE BIT(14)
-#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15)
-#define XTAL_GATE_DIG BIT(17)
-#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18)
-#define XTAL_BT_GATE BIT(20)
-#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21)
-#define _XTAL_GPIO(x) (((x) & 0x7) << 23)
-
-
-#define CKDLY_AFE BIT(26)
-#define CKDLY_USB BIT(27)
-#define CKDLY_DIG BIT(28)
-#define CKDLY_BT BIT(29)
-
-
-/* 2 AFE_PLL_CTRL */
-#define APLL_EN BIT(0)
-#define APLL_320_EN BIT(1)
-#define APLL_FREF_SEL BIT(2)
-#define APLL_EDGE_SEL BIT(3)
-#define APLL_WDOGB BIT(4)
-#define APLL_LPFEN BIT(5)
-
-#define APLL_REF_CLK_13MHZ 0x1
-#define APLL_REF_CLK_19_2MHZ 0x2
-#define APLL_REF_CLK_20MHZ 0x3
-#define APLL_REF_CLK_25MHZ 0x4
-#define APLL_REF_CLK_26MHZ 0x5
-#define APLL_REF_CLK_38_4MHZ 0x6
-#define APLL_REF_CLK_40MHZ 0x7
-
-#define APLL_320EN BIT(14)
-#define APLL_80EN BIT(15)
-#define APLL_1MEN BIT(24)
-
-
-/* 2 EFUSE_CTRL */
-#define ALD_EN BIT(18)
-#define EF_PD BIT(19)
-#define EF_FLAG BIT(31)
-
-/* 2 EFUSE_TEST (For RTL8723 partially) */
-#define EF_TRPT BIT(7)
- /* 00: Wifi Efuse, 01: BT Efuse0, 10: BT Efuse1, 11: BT Efuse2 */
-#define EF_CELL_SEL (BIT(8)|BIT(9))
-#define LDOE25_EN BIT(31)
-#define EFUSE_SEL(x) (((x) & 0x3) << 8)
-#define EFUSE_SEL_MASK 0x300
-#define EFUSE_WIFI_SEL_0 0x0
-#define EFUSE_BT_SEL_0 0x1
-#define EFUSE_BT_SEL_1 0x2
-#define EFUSE_BT_SEL_2 0x3
-
-#define EFUSE_ACCESS_ON 0x69 /* For RTL8723 only. */
-#define EFUSE_ACCESS_OFF 0x00 /* For RTL8723 only. */
-
-/* 2 PWR_DATA */
-
-/* 2 CAL_TIMER */
-
-/* 2 ACLK_MON */
-#define RSM_EN BIT(0)
-#define Timer_EN BIT(4)
-
-
-/* 2 GPIO_MUXCFG */
-#define TRSW0EN BIT(2)
-#define TRSW1EN BIT(3)
-#define EROM_EN BIT(4)
-#define EnBT BIT(5)
-#define EnUart BIT(8)
-#define Uart_910 BIT(9)
-#define EnPMAC BIT(10)
-#define SIC_SWRST BIT(11)
-#define EnSIC BIT(12)
-#define SIC_23 BIT(13)
-#define EnHDP BIT(14)
-#define SIC_LBK BIT(15)
-
-/* 2 GPIO_PIN_CTRL */
-
-/* GPIO BIT */
-#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2)
-
-/* 2 GPIO_INTM */
-
-/* 2 LEDCFG */
-#define LED0PL BIT(4)
-#define LED0DIS BIT(7)
-#define LED1DIS BIT(15)
-#define LED1PL BIT(12)
-
-#define SECCAM_CLR BIT(30)
-
-
-/* 2 FSIMR */
-
-/* 2 FSISR */
-
-
-/* 2 8051FWDL */
-/* 2 MCUFWDL */
-#define MCUFWDL_EN BIT(0)
-#define MCUFWDL_RDY BIT(1)
-#define FWDL_ChkSum_rpt BIT(2)
-#define MACINI_RDY BIT(3)
-#define BBINI_RDY BIT(4)
-#define RFINI_RDY BIT(5)
-#define WINTINI_RDY BIT(6)
-#define CPRST BIT(23)
-
-/* 2REG_HPON_FSM */
-#define BOND92CE_1T2R_CFG BIT(22)
-
-
-/* 2 REG_SYS_CFG */
-#define XCLK_VLD BIT(0)
-#define ACLK_VLD BIT(1)
-#define UCLK_VLD BIT(2)
-#define PCLK_VLD BIT(3)
-#define PCIRSTB BIT(4)
-#define V15_VLD BIT(5)
-#define TRP_B15V_EN BIT(7)
-#define SIC_IDLE BIT(8)
-#define BD_MAC2 BIT(9)
-#define BD_MAC1 BIT(10)
-#define IC_MACPHY_MODE BIT(11)
-#define CHIP_VER (BIT(12)|BIT(13)|BIT(14)|BIT(15))
-#define BT_FUNC BIT(16)
-#define VENDOR_ID BIT(19)
-#define PAD_HWPD_IDN BIT(22)
-#define TRP_VAUX_EN BIT(23)
-#define TRP_BT_EN BIT(24)
-#define BD_PKG_SEL BIT(25)
-#define BD_HCI_SEL BIT(26)
-#define TYPE_ID BIT(27)
-
-#define CHIP_VER_RTL_MASK 0xF000 /* Bit 12 ~ 15 */
-#define CHIP_VER_RTL_SHIFT 12
-
-/* 2REG_GPIO_OUTSTS (For RTL8723 only) */
-#define EFS_HCI_SEL (BIT(0)|BIT(1))
-#define PAD_HCI_SEL (BIT(2)|BIT(3))
-#define HCI_SEL (BIT(4)|BIT(5))
-#define PKG_SEL_HCI BIT(6)
-#define FEN_GPS BIT(7)
-#define FEN_BT BIT(8)
-#define FEN_WL BIT(9)
-#define FEN_PCI BIT(10)
-#define FEN_USB BIT(11)
-#define BTRF_HWPDN_N BIT(12)
-#define WLRF_HWPDN_N BIT(13)
-#define PDN_BT_N BIT(14)
-#define PDN_GPS_N BIT(15)
-#define BT_CTL_HWPDN BIT(16)
-#define GPS_CTL_HWPDN BIT(17)
-#define PPHY_SUSB BIT(20)
-#define UPHY_SUSB BIT(21)
-#define PCI_SUSEN BIT(22)
-#define USB_SUSEN BIT(23)
-#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28))
-
-/* */
-/* */
-/* 0x0100h ~ 0x01FFh MACTOP General Configuration */
-/* */
-/* */
-
-
-/* 2 Function Enable Registers */
-/* 2 CR */
-
-#define REG_LBMODE (REG_CR + 3)
-
-
-#define HCI_TXDMA_EN BIT(0)
-#define HCI_RXDMA_EN BIT(1)
-#define TXDMA_EN BIT(2)
-#define RXDMA_EN BIT(3)
-#define PROTOCOL_EN BIT(4)
-#define SCHEDULE_EN BIT(5)
-#define MACTXEN BIT(6)
-#define MACRXEN BIT(7)
-#define ENSWBCN BIT(8)
-#define ENSEC BIT(9)
-
-#define _LBMODE(x) (((x) & 0xF) << 24)
-#define MASK_LBMODE 0xF000000
-#define LOOPBACK_NORMAL 0x0
-#define LOOPBACK_IMMEDIATELY 0xB
-#define LOOPBACK_MAC_DELAY 0x3
-#define LOOPBACK_PHY 0x1
-#define LOOPBACK_DMA 0x7
-
-
-/* 2 PBP - Page Size Register */
-#define GET_RX_PAGE_SIZE(value) ((value) & 0xF)
-#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4)
-#define _PSRX_MASK 0xF
-#define _PSTX_MASK 0xF0
-#define _PSRX(x) (x)
-#define _PSTX(x) ((x) << 4)
-
-#define PBP_64 0x0
-#define PBP_128 0x1
-#define PBP_256 0x2
-#define PBP_512 0x3
-#define PBP_1024 0x4
-
-
-/* 2 TX/RXDMA */
-#define RXDMA_ARBBW_EN BIT(0)
-#define RXSHFT_EN BIT(1)
-#define RXDMA_AGG_EN BIT(2)
-#define QS_VO_QUEUE BIT(8)
-#define QS_VI_QUEUE BIT(9)
-#define QS_BE_QUEUE BIT(10)
-#define QS_BK_QUEUE BIT(11)
-#define QS_MANAGER_QUEUE BIT(12)
-#define QS_HIGH_QUEUE BIT(13)
-
-#define HQSEL_VOQ BIT(0)
-#define HQSEL_VIQ BIT(1)
-#define HQSEL_BEQ BIT(2)
-#define HQSEL_BKQ BIT(3)
-#define HQSEL_MGTQ BIT(4)
-#define HQSEL_HIQ BIT(5)
-
-/* For normal driver, 0x10C */
-#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14)
-#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12)
-#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10)
-#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8)
-#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6)
-#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4)
-
-#define QUEUE_LOW 1
-#define QUEUE_NORMAL 2
-#define QUEUE_HIGH 3
-
-
-
-/* 2 TRXFF_BNDY */
-
-
-/* 2 LLT_INIT */
-#define _LLT_NO_ACTIVE 0x0
-#define _LLT_WRITE_ACCESS 0x1
-#define _LLT_READ_ACCESS 0x2
-
-#define _LLT_INIT_DATA(x) ((x) & 0xFF)
-#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8)
-#define _LLT_OP(x) (((x) & 0x3) << 30)
-#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3)
-
-
-/* 2 BB_ACCESS_CTRL */
-#define BB_WRITE_READ_MASK (BIT(31) | BIT(30))
-#define BB_WRITE_EN BIT(30)
-#define BB_READ_EN BIT(31)
-/* define BB_ADDR_MASK 0xFFF */
-/* define _BB_ADDR(x) ((x) & BB_ADDR_MASK) */
-
-/* */
-/* */
-/* 0x0200h ~ 0x027Fh TXDMA Configuration */
-/* */
-/* */
-/* 2 RQPN */
-#define _HPQ(x) ((x) & 0xFF)
-#define _LPQ(x) (((x) & 0xFF) << 8)
-#define _PUBQ(x) (((x) & 0xFF) << 16)
- /* NOTE: in RQPN_NPQ register */
-#define _NPQ(x) ((x) & 0xFF)
-
-
-#define HPQ_PUBLIC_DIS BIT(24)
-#define LPQ_PUBLIC_DIS BIT(25)
-#define LD_RQPN BIT(31)
-
-
-/* 2 TDECTRL */
-#define BCN_VALID BIT(16)
-#define BCN_HEAD(x) (((x) & 0xFF) << 8)
-#define BCN_HEAD_MASK 0xFF00
-
-/* 2 TDECTL */
-#define BLK_DESC_NUM_SHIFT 4
-#define BLK_DESC_NUM_MASK 0xF
-
-
-/* 2 TXDMA_OFFSET_CHK */
-#define DROP_DATA_EN BIT(9)
-
-/* */
-/* */
-/* 0x0400h ~ 0x047Fh Protocol Configuration */
-/* */
-/* */
-/* 2 FWHW_TXQ_CTRL */
-#define EN_AMPDU_RTY_NEW BIT(7)
-
-/* 2 INIRTSMCS_SEL */
-#define _INIRTSMCS_SEL(x) ((x) & 0x3F)
-
-
-/* 2 SPEC SIFS */
-#define _SPEC_SIFS_CCK(x) ((x) & 0xFF)
-#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8)
-
-
-/* 2 RRSR */
-
-#define RATE_REG_BITMAP_ALL 0xFFFFF
-
-#define _RRSC_BITMAP(x) ((x) & 0xFFFFF)
-
-#define _RRSR_RSC(x) (((x) & 0x3) << 21)
-#define RRSR_RSC_RESERVED 0x0
-#define RRSR_RSC_UPPER_SUBCHANNEL 0x1
-#define RRSR_RSC_LOWER_SUBCHANNEL 0x2
-#define RRSR_RSC_DUPLICATE_MODE 0x3
-
-
-/* 2 ARFR */
-#define USE_SHORT_G1 BIT(20)
-
-/* 2 AGGLEN_LMT_L */
-#define _AGGLMT_MCS0(x) ((x) & 0xF)
-#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4)
-#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8)
-#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12)
-#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16)
-#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20)
-#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24)
-#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28)
-
-
-/* 2 RL */
-#define RETRY_LIMIT_SHORT_SHIFT 8
-#define RETRY_LIMIT_LONG_SHIFT 0
-
-
-/* 2 DARFRC */
-#define _DARF_RC1(x) ((x) & 0x1F)
-#define _DARF_RC2(x) (((x) & 0x1F) << 8)
-#define _DARF_RC3(x) (((x) & 0x1F) << 16)
-#define _DARF_RC4(x) (((x) & 0x1F) << 24)
-/* NOTE: shift starting from address (DARFRC + 4) */
-#define _DARF_RC5(x) ((x) & 0x1F)
-#define _DARF_RC6(x) (((x) & 0x1F) << 8)
-#define _DARF_RC7(x) (((x) & 0x1F) << 16)
-#define _DARF_RC8(x) (((x) & 0x1F) << 24)
-
-
-/* 2 RARFRC */
-#define _RARF_RC1(x) ((x) & 0x1F)
-#define _RARF_RC2(x) (((x) & 0x1F) << 8)
-#define _RARF_RC3(x) (((x) & 0x1F) << 16)
-#define _RARF_RC4(x) (((x) & 0x1F) << 24)
-/* NOTE: shift starting from address (RARFRC + 4) */
-#define _RARF_RC5(x) ((x) & 0x1F)
-#define _RARF_RC6(x) (((x) & 0x1F) << 8)
-#define _RARF_RC7(x) (((x) & 0x1F) << 16)
-#define _RARF_RC8(x) (((x) & 0x1F) << 24)
-
-
-/* */
-/* */
-/* 0x0500h ~ 0x05FFh EDCA Configuration */
-/* */
-/* */
-
-
-
-/* 2 EDCA setting */
-#define AC_PARAM_TXOP_LIMIT_OFFSET 16
-#define AC_PARAM_ECW_MAX_OFFSET 12
-#define AC_PARAM_ECW_MIN_OFFSET 8
-#define AC_PARAM_AIFS_OFFSET 0
-
-
-/* 2 EDCA_VO_PARAM */
-#define _AIFS(x) (x)
-#define _ECW_MAX_MIN(x) ((x) << 8)
-#define _TXOP_LIMIT(x) ((x) << 16)
-
-
-#define _BCNIFS(x) ((x) & 0xFF)
-#define _BCNECW(x) (((x) & 0xF))<< 8)
-
-
-#define _LRL(x) ((x) & 0x3F)
-#define _SRL(x) (((x) & 0x3F) << 8)
-
-
-/* 2 SIFS_CCK */
-#define _SIFS_CCK_CTX(x) ((x) & 0xFF)
-#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8);
-
-
-/* 2 SIFS_OFDM */
-#define _SIFS_OFDM_CTX(x) ((x) & 0xFF)
-#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8);
-
-
-/* 2 TBTT PROHIBIT */
-#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8)
-
-
-/* 2 REG_RD_CTRL */
-#define DIS_EDCA_CNT_DWN BIT(11)
-
-
-/* 2 BCN_CTRL */
-#define EN_MBSSID BIT(1)
-#define EN_TXBCN_RPT BIT(2)
-#define EN_BCN_FUNCTION BIT(3)
-#define DIS_TSF_UPDATE BIT(3)
-
-/* The same function but different bit field. */
-#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4)
-#define DIS_TSF_UDT0_TEST_CHIP BIT(5)
-
-/* 2 ACMHWCTRL */
-#define AcmHw_HwEn BIT(0)
-#define AcmHw_BeqEn BIT(1)
-#define AcmHw_ViqEn BIT(2)
-#define AcmHw_VoqEn BIT(3)
-#define AcmHw_BeqStatus BIT(4)
-#define AcmHw_ViqStatus BIT(5)
-#define AcmHw_VoqStatus BIT(6)
-
-
-
-/* */
-/* */
-/* 0x0600h ~ 0x07FFh WMAC Configuration */
-/* */
-/* */
-
-/* 2 APSD_CTRL */
-#define APSDOFF BIT(6)
-#define APSDOFF_STATUS BIT(7)
-
-
-/* 2 BWOPMODE */
-#define BW_20MHZ BIT(2)
-
-
-#define RATE_BITMAP_ALL 0xFFFFF
-
-/* Only use CCK 1M rate for ACK */
-#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1
-
-/* 2 TCR */
-#define TSFRST BIT(0)
-#define DIS_GCLK BIT(1)
-#define PAD_SEL BIT(2)
-#define PWR_ST BIT(6)
-#define PWRBIT_OW_EN BIT(7)
-#define ACRC BIT(8)
-#define CFENDFORM BIT(9)
-#define ICV BIT(10)
-
-
-
-/* 2 RCR */
-#define AAP BIT(0)
-#define APM BIT(1)
-#define AM BIT(2)
-#define AB BIT(3)
-#define ADD3 BIT(4)
-#define APWRMGT BIT(5)
-#define CBSSID BIT(6)
-#define CBSSID_BCN BIT(7)
-#define ACRC32 BIT(8)
-#define AICV BIT(9)
-#define ADF BIT(11)
-#define ACF BIT(12)
-#define AMF BIT(13)
-#define HTC_LOC_CTRL BIT(14)
-#define UC_DATA_EN BIT(16)
-#define BM_DATA_EN BIT(17)
-#define MFBEN BIT(22)
-#define LSIGEN BIT(23)
-#define EnMBID BIT(24)
-#define APP_BASSN BIT(27)
-#define APP_PHYSTS BIT(28)
-#define APP_ICV BIT(29)
-#define APP_MIC BIT(30)
-#define APP_FCS BIT(31)
-
-/* 2 RX_PKT_LIMIT */
-
-/* 2 RX_DLK_TIME */
-
-/* 2 MBIDCAMCFG */
-
-
-
-/* 2 AMPDU_MIN_SPACE */
-#define _MIN_SPACE(x) ((x) & 0x7)
-#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3)
-
-
-/* 2 RXERR_RPT */
-#define RXERR_TYPE_OFDM_PPDU 0
-#define RXERR_TYPE_OFDMfalse_ALARM 1
-#define RXERR_TYPE_OFDM_MPDU_OK 2
-#define RXERR_TYPE_OFDM_MPDU_FAIL 3
-#define RXERR_TYPE_CCK_PPDU 4
-#define RXERR_TYPE_CCKfalse_ALARM 5
-#define RXERR_TYPE_CCK_MPDU_OK 6
-#define RXERR_TYPE_CCK_MPDU_FAIL 7
-#define RXERR_TYPE_HT_PPDU 8
-#define RXERR_TYPE_HTfalse_ALARM 9
-#define RXERR_TYPE_HT_MPDU_TOTAL 10
-#define RXERR_TYPE_HT_MPDU_OK 11
-#define RXERR_TYPE_HT_MPDU_FAIL 12
-#define RXERR_TYPE_RX_FULL_DROP 15
-
-#define RXERR_COUNTER_MASK 0xFFFFF
-#define RXERR_RPT_RST BIT(27)
-#define _RXERR_RPT_SEL(type) ((type) << 28)
-
-
-/* 2 SECCFG */
-#define SCR_TxUseDK BIT(0) /* Force Tx Use Default Key */
-#define SCR_RxUseDK BIT(1) /* Force Rx Use Default Key */
-#define SCR_TxEncEnable BIT(2) /* Enable Tx Encryption */
-#define SCR_RxDecEnable BIT(3) /* Enable Rx Decryption */
-#define SCR_SKByA2 BIT(4) /* Search kEY BY A2 */
-#define SCR_NoSKMC BIT(5) /* No Key Search Multicast */
-
-
-
-/* */
-/* */
-/* 0xFE00h ~ 0xFE55h USB Configuration */
-/* */
-/* */
-
-/* 2 USB Information (0xFE17) */
-#define USB_IS_HIGH_SPEED 0
-#define USB_IS_FULL_SPEED 1
-#define USB_SPEED_MASK BIT(5)
-
-#define USB_NORMAL_SIE_EP_MASK 0xF
-#define USB_NORMAL_SIE_EP_SHIFT 4
-
-#define USB_TEST_EP_MASK 0x30
-#define USB_TEST_EP_SHIFT 4
-
-/* 2 Special Option */
-#define USB_AGG_EN BIT(3)
-
-
-/* 2REG_C2HEVT_CLEAR */
- /* Set by driver and notify FW that the driver has read the
- C2H command message */
-#define C2H_EVT_HOST_CLOSE 0x00
- /* Set by FW indicating that FW had set the C2H command message
- and it's not yet read by driver. */
-#define C2H_EVT_FW_CLOSE 0xFF
-
-
-/* 2REG_MULTI_FUNC_CTRL(For RTL8723 Only) */
- /* Enable GPIO[9] as WiFi HW PDn source */
-#define WL_HWPDN_EN BIT(0)
- /* WiFi HW PDn polarity control */
-#define WL_HWPDN_SL BIT(1)
- /* WiFi function enable */
-#define WL_FUNC_EN BIT(2)
- /* Enable GPIO[9] as WiFi RF HW PDn source */
-#define WL_HWROF_EN BIT(3)
- /* Enable GPIO[11] as BT HW PDn source */
-#define BT_HWPDN_EN BIT(16)
- /* BT HW PDn polarity control */
-#define BT_HWPDN_SL BIT(17)
- /* BT function enable */
-#define BT_FUNC_EN BIT(18)
- /* Enable GPIO[11] as BT/GPS RF HW PDn source */
-#define BT_HWROF_EN BIT(19)
- /* Enable GPIO[10] as GPS HW PDn source */
-#define GPS_HWPDN_EN BIT(20)
- /* GPS HW PDn polarity control */
-#define GPS_HWPDN_SL BIT(21)
- /* GPS function enable */
-#define GPS_FUNC_EN BIT(22)
-
-/* 3 REG_LIFECTRL_CTRL */
-#define HAL92C_EN_PKT_LIFE_TIME_BK BIT(3)
-#define HAL92C_EN_PKT_LIFE_TIME_BE BIT(2)
-#define HAL92C_EN_PKT_LIFE_TIME_VI BIT(1)
-#define HAL92C_EN_PKT_LIFE_TIME_VO BIT(0)
-
-#define HAL92C_MSDU_LIFE_TIME_UNIT 128 /* in us, said by Tim. */
-
-/* */
-/* General definitions */
-/* */
-
-#define LAST_ENTRY_OF_TX_PKT_BUFFER 255
-
-#define POLLING_LLT_THRESHOLD 20
-#define POLLING_READY_TIMEOUT_COUNT 1000
-
-/* Min Spacing related settings. */
-#define MAX_MSS_DENSITY_2T 0x13
-#define MAX_MSS_DENSITY_1T 0x0A
-
-/* */
-/* 8723A Regsiter offset definition */
-/* */
-#define HAL_8723A_NAV_UPPER_UNIT 128 /* micro-second */
-
-/* */
-/* */
-/* 0x0000h ~ 0x00FFh System Configuration */
-/* */
-/* */
-#define REG_SYSON_REG_LOCK 0x001C
-
-
-/* */
-/* */
-/* 0x0100h ~ 0x01FFh MACTOP General Configuration */
-/* */
-/* */
-#define REG_FTIMR 0x0138
-
-
-/* */
-/* */
-/* 0x0200h ~ 0x027Fh TXDMA Configuration */
-/* */
-/* */
-
-
-/* */
-/* */
-/* 0x0280h ~ 0x02FFh RXDMA Configuration */
-/* */
-/* */
-
-
-/* */
-/* */
-/* 0x0300h ~ 0x03FFh PCIe */
-/* */
-/* */
-
-
-/* */
-/* */
-/* 0x0400h ~ 0x047Fh Protocol Configuration */
-/* */
-/* */
-#define REG_EARLY_MODE_CONTROL 0x4D0
-
-
-/* */
-/* */
-/* 0x0500h ~ 0x05FFh EDCA Configuration */
-/* */
-/* */
-
-/* 2 BCN_CTRL */
-#define DIS_ATIM BIT(0)
-#define DIS_BCNQ_SUB BIT(1)
-#define DIS_TSF_UDT BIT(4)
-
-
-/* */
-/* */
-/* 0x0600h ~ 0x07FFh WMAC Configuration */
-/* */
-/* */
-/* */
-/* Note: */
-/* The NAV upper value is very important to WiFi 11n 5.2.3 NAV test.
- * The default value is always too small, but the WiFi TestPlan test
- * by 25,000 microseconds of NAV through sending CTS in the air. We
- * must update this value greater than 25,000 microseconds to pass the
- * item.
-* The offset of NAV_UPPER in 8192C Spec is incorrect, and the offset
-* should be 0x0652. Commented by SD1 Scott. */
-/* By Bruce, 2011-07-18. */
-/* */
-#define REG_NAV_UPPER 0x0652 /* unit of 128 */
-
-
-/* */
-/* 8723 Regsiter Bit and Content definition */
-/* */
-
-/* */
-/* */
-/* 0x0000h ~ 0x00FFh System Configuration */
-/* */
-/* */
-
-/* 2 SPS0_CTRL */
-
-/* 2 SYS_ISO_CTRL */
-
-/* 2 SYS_FUNC_EN */
-
-/* 2 APS_FSMCO */
-#define EN_WLON BIT(16)
-
-/* 2 SYS_CLKR */
-
-/* 2 9346CR */
-
-/* 2 AFE_MISC */
-
-/* 2 SPS0_CTRL */
-
-/* 2 SPS_OCP_CFG */
-
-/* 2 SYSON_REG_LOCK */
-#define WLOCK_ALL BIT(0)
-#define WLOCK_00 BIT(1)
-#define WLOCK_04 BIT(2)
-#define WLOCK_08 BIT(3)
-#define WLOCK_40 BIT(4)
-#define WLOCK_1C_B6 BIT(5)
-#define R_DIS_PRST_1 BIT(6)
-#define LOCK_ALL_EN BIT(7)
-
-/* 2 RF_CTRL */
-
-/* 2 LDOA15_CTRL */
-
-/* 2 LDOV12D_CTRL */
-
-/* 2 AFE_XTAL_CTRL */
-
-/* 2 AFE_PLL_CTRL */
-
-/* 2 EFUSE_CTRL */
-
-/* 2 EFUSE_TEST (For RTL8723 partially) */
-
-/* 2 PWR_DATA */
-
-/* 2 CAL_TIMER */
-
-/* 2 ACLK_MON */
-
-/* 2 GPIO_MUXCFG */
-
-/* 2 GPIO_PIN_CTRL */
-
-/* 2 GPIO_INTM */
-
-/* 2 LEDCFG */
-
-/* 2 FSIMR */
-
-/* 2 FSISR */
-
-/* 2 HSIMR */
-/* 8723 Host System Interrupt Mask Register (offset 0x58, 32 byte) */
-#define HSIMR_GPIO12_0_INT_EN BIT(0)
-#define HSIMR_SPS_OCP_INT_EN BIT(5)
-#define HSIMR_RON_INT_EN BIT(6)
-#define HSIMR_PDNINT_EN BIT(7)
-#define HSIMR_GPIO9_INT_EN BIT(25)
-
-/* 2 HSISR */
-/* 8723 Host System Interrupt Status Register (offset 0x5C, 32 byte) */
-#define HSISR_GPIO12_0_INT BIT(0)
-#define HSISR_SPS_OCP_INT BIT(5)
-#define HSISR_RON_INT BIT(6)
-#define HSISR_PDNINT BIT(7)
-#define HSISR_GPIO9_INT BIT(25)
-
-/* interrupt mask which needs to clear */
-#define MASK_HSISR_CLEAR (HSISR_GPIO12_0_INT | \
- HSISR_SPS_OCP_INT | \
- HSISR_RON_INT | \
- HSISR_PDNINT | \
- HSISR_GPIO9_INT)
-
-/* 2 MCUFWDL */
-#define RAM_DL_SEL BIT(7) /* 1:RAM, 0:ROM */
-
-/* 2 HPON_FSM */
-
-/* 2 SYS_CFG */
-#define RTL_ID BIT(23) /* TestChip ID,
- 1:Test(RLE); 0:MP(RL) */
-#define SPS_SEL BIT(24) /* 1:LDO regulator mode;
- 0:Switching regulator mode*/
-
-
-/* */
-/* */
-/* 0x0100h ~ 0x01FFh MACTOP General Configuration */
-/* */
-/* */
-
-/* 2 Function Enable Registers */
-
-/* 2 CR */
-#define CALTMR_EN BIT(10)
-
-/* 2 PBP - Page Size Register */
-
-/* 2 TX/RXDMA */
-
-/* 2 TRXFF_BNDY */
-
-/* 2 LLT_INIT */
-
-/* 2 BB_ACCESS_CTRL */
-
-
-/* */
-/* */
-/* 0x0200h ~ 0x027Fh TXDMA Configuration */
-/* */
-/* */
-
-/* 2 RQPN */
-
-/* 2 TDECTRL */
-
-/* 2 TDECTL */
-
-/* 2 TXDMA_OFFSET_CHK */
-
-
-/* */
-/* */
-/* 0x0400h ~ 0x047Fh Protocol Configuration */
-/* */
-/* */
-
-/* 2 FWHW_TXQ_CTRL */
-
-/* 2 INIRTSMCS_SEL */
-
-/* 2 SPEC SIFS */
-
-/* 2 RRSR */
-
-/* 2 ARFR */
-
-/* 2 AGGLEN_LMT_L */
-
-/* 2 RL */
-
-/* 2 DARFRC */
-
-/* 2 RARFRC */
-
-
-/* */
-/* */
-/* 0x0500h ~ 0x05FFh EDCA Configuration */
-/* */
-/* */
-
-/* 2 EDCA setting */
-
-/* 2 EDCA_VO_PARAM */
-
-/* 2 SIFS_CCK */
-
-/* 2 SIFS_OFDM */
-
-/* 2 TBTT PROHIBIT */
-
-/* 2 REG_RD_CTRL */
-
-/* 2 BCN_CTRL */
-
-/* 2 ACMHWCTRL */
-
-
-/* */
-/* */
-/* 0x0600h ~ 0x07FFh WMAC Configuration */
-/* */
-/* */
-
-/* 2 APSD_CTRL */
-
-/* 2 BWOPMODE */
-
-/* 2 TCR */
-
-/* 2 RCR */
-
-/* 2 RX_PKT_LIMIT */
-
-/* 2 RX_DLK_TIME */
-
-/* 2 MBIDCAMCFG */
-
-/* 2 AMPDU_MIN_SPACE */
-
-/* 2 RXERR_RPT */
-
-/* 2 SECCFG */
-
-
-/* */
-/* */
-/* 0xFE00h ~ 0xFE55h RTL8723 SDIO Configuration */
-/* */
-/* */
-
-/* I/O bus domain address mapping */
-#define WLAN_IOREG_BASE 0x10260000
-#define FIRMWARE_FIFO_BASE 0x10270000
-#define TX_HIQ_BASE 0x10310000
-#define TX_MIQ_BASE 0x10320000
-#define TX_LOQ_BASE 0x10330000
-#define RX_RX0FF_BASE 0x10340000
-
-/* SDIO host local register space mapping. */
-#define WLAN_IOREG_MSK 0x7FFF
-#define WLAN_FIFO_MSK 0x1FFF /* Aggregation Length[12:0] */
-#define WLAN_RX0FF_MSK 0x0003
-
-#define WLAN_RX0FF_DEVICE_ID 7 /* 0b[16], 111b[15:13] */
-#define WLAN_IOREG_DEVICE_ID 8 /* 1b[16] */
-
-/* 8723 EFUSE */
-#define HWSET_MAX_SIZE 256
-
-
-/* USB interrupt */
-#define UHIMR_TIMEOUT2 BIT(31)
-#define UHIMR_TIMEOUT1 BIT(30)
-#define UHIMR_PSTIMEOUT BIT(29)
-#define UHIMR_GTINT4 BIT(28)
-#define UHIMR_GTINT3 BIT(27)
-#define UHIMR_TXBCNERR BIT(26)
-#define UHIMR_TXBCNOK BIT(25)
-#define UHIMR_TSF_BIT32_TOGGLE BIT(24)
-#define UHIMR_BCNDMAINT3 BIT(23)
-#define UHIMR_BCNDMAINT2 BIT(22)
-#define UHIMR_BCNDMAINT1 BIT(21)
-#define UHIMR_BCNDMAINT0 BIT(20)
-#define UHIMR_BCNDOK3 BIT(19)
-#define UHIMR_BCNDOK2 BIT(18)
-#define UHIMR_BCNDOK1 BIT(17)
-#define UHIMR_BCNDOK0 BIT(16)
-#define UHIMR_HSISR_IND BIT(15)
-#define UHIMR_BCNDMAINT_E BIT(14)
-/* RSVD BIT(13) */
-#define UHIMR_CTW_END BIT(12)
-/* RSVD BIT(11) */
-#define UHIMR_C2HCMD BIT(10)
-#define UHIMR_CPWM2 BIT(9)
-#define UHIMR_CPWM BIT(8)
-#define UHIMR_HIGHDOK BIT(7) /* High Queue DMA OK
- Interrupt */
-#define UHIMR_MGNTDOK BIT(6) /* Management Queue DMA OK
- Interrupt */
-#define UHIMR_BKDOK BIT(5) /* AC_BK DMA OK Interrupt */
-#define UHIMR_BEDOK BIT(4) /* AC_BE DMA OK Interrupt */
-#define UHIMR_VIDOK BIT(3) /* AC_VI DMA OK Interrupt */
-#define UHIMR_VODOK BIT(2) /* AC_VO DMA Interrupt */
-#define UHIMR_RDU BIT(1) /* Receive Descriptor
- Unavailable */
-#define UHIMR_ROK BIT(0) /* Receive DMA OK Interrupt */
-
-/* USB Host Interrupt Status Extension bit */
-#define UHIMR_BCNDMAINT7 BIT(23)
-#define UHIMR_BCNDMAINT6 BIT(22)
-#define UHIMR_BCNDMAINT5 BIT(21)
-#define UHIMR_BCNDMAINT4 BIT(20)
-#define UHIMR_BCNDOK7 BIT(19)
-#define UHIMR_BCNDOK6 BIT(18)
-#define UHIMR_BCNDOK5 BIT(17)
-#define UHIMR_BCNDOK4 BIT(16)
-/* bit14-15: RSVD */
-#define UHIMR_ATIMEND_E BIT(13)
-#define UHIMR_ATIMEND BIT(12)
-#define UHIMR_TXERR BIT(11)
-#define UHIMR_RXERR BIT(10)
-#define UHIMR_TXFOVW BIT(9)
-#define UHIMR_RXFOVW BIT(8)
-/* bit2-7: RSVD */
-#define UHIMR_OCPINT BIT(1)
-/* bit0: RSVD */
-
-#define REG_USB_HIMR 0xFE38
-#define REG_USB_HIMRE 0xFE3C
-#define REG_USB_HISR 0xFE78
-#define REG_USB_HISRE 0xFE7C
-
-#define USB_INTR_CPWM_OFFSET 16
-#define USB_INTR_CONTENT_HISR_OFFSET 48
-#define USB_INTR_CONTENT_HISRE_OFFSET 52
-#define USB_INTR_CONTENT_LENGTH 56
-#define USB_C2H_CMDID_OFFSET 0
-#define USB_C2H_SEQ_OFFSET 1
-#define USB_C2H_EVENT_OFFSET 2
-/* */
-/* General definitions */
-/* */
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_sreset.h b/drivers/staging/rtl8723au/include/rtl8723a_sreset.h
deleted file mode 100644
index 6197910a4a53..000000000000
--- a/drivers/staging/rtl8723au/include/rtl8723a_sreset.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef _RTL8723A_SRESET_H_
-#define _RTL8723A_SRESET_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <rtw_sreset.h>
-
-void rtl8723a_sreset_xmit_status_check(struct rtw_adapter *padapter);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_xmit.h b/drivers/staging/rtl8723au/include/rtl8723a_xmit.h
deleted file mode 100644
index 7db29f40ab70..000000000000
--- a/drivers/staging/rtl8723au/include/rtl8723a_xmit.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTL8723A_XMIT_H__
-#define __RTL8723A_XMIT_H__
-
-/* */
-/* Queue Select Value in TxDesc */
-/* */
-#define QSLT_BK 0x2/* 0x01 */
-#define QSLT_BE 0x0
-#define QSLT_VI 0x5/* 0x4 */
-#define QSLT_VO 0x7/* 0x6 */
-#define QSLT_BEACON 0x10
-#define QSLT_HIGH 0x11
-#define QSLT_MGNT 0x12
-#define QSLT_CMD 0x13
-
-/* */
-/* defined for TX DESC Operation */
-/* */
-
-#define MAX_TID (15)
-
-/* OFFSET 0 */
-#define OFFSET_SZ 0
-#define OFFSET_SHT 16
-#define BMC BIT(24)
-#define LSG BIT(26)
-#define FSG BIT(27)
-#define OWN BIT(31)
-
-
-/* OFFSET 4 */
-#define PKT_OFFSET_SZ 0
-#define BK BIT(6)
-#define QSEL_SHT 8
-#define Rate_ID_SHT 16
-#define NAVUSEHDR BIT(20)
-#define PKT_OFFSET_SHT 26
-#define HWPC BIT(31)
-
-/* OFFSET 8 */
-#define AGG_EN BIT(29)
-
-/* OFFSET 12 */
-#define SEQ_SHT 16
-
-/* OFFSET 16 */
-#define QoS BIT(6)
-#define HW_SEQ_EN BIT(7)
-#define USERATE BIT(8)
-#define DISDATAFB BIT(10)
-#define DATA_SHORT BIT(24)
-#define DATA_BW BIT(25)
-
-/* OFFSET 20 */
-#define SGI BIT(6)
-
-struct txdesc_8723a {
- u32 pktlen:16;
- u32 offset:8;
- u32 bmc:1;
- u32 htc:1;
- u32 ls:1;
- u32 fs:1;
- u32 linip:1;
- u32 noacm:1;
- u32 gf:1;
- u32 own:1;
-
- u32 macid:5;
- u32 agg_en:1;
- u32 bk:1;
- u32 rd_en:1;
- u32 qsel:5;
- u32 rd_nav_ext:1;
- u32 lsig_txop_en:1;
- u32 pifs:1;
- u32 rate_id:4;
- u32 navusehdr:1;
- u32 en_desc_id:1;
- u32 sectype:2;
- u32 rsvd0424:2;
- u32 pkt_offset:5; /* unit: 8 bytes */
- u32 rsvd0431:1;
-
- u32 rts_rc:6;
- u32 data_rc:6;
- u32 rsvd0812:2;
- u32 bar_rty_th:2;
- u32 rsvd0816:1;
- u32 morefrag:1;
- u32 raw:1;
- u32 ccx:1;
- u32 ampdu_density:3;
- u32 bt_null:1;
- u32 ant_sel_a:1;
- u32 ant_sel_b:1;
- u32 tx_ant_cck:2;
- u32 tx_antl:2;
- u32 tx_ant_ht:2;
-
- u32 nextheadpage:8;
- u32 tailpage:8;
- u32 seq:12;
- u32 cpu_handle:1;
- u32 tag1:1;
- u32 trigger_int:1;
- u32 hwseq_en:1;
-
- u32 rtsrate:5;
- u32 ap_dcfe:1;
- u32 hwseq_sel:2;
- u32 userate:1;
- u32 disrtsfb:1;
- u32 disdatafb:1;
- u32 cts2self:1;
- u32 rtsen:1;
- u32 hw_rts_en:1;
- u32 port_id:1;
- u32 rsvd1615:3;
- u32 wait_dcts:1;
- u32 cts2ap_en:1;
- u32 data_sc:2;
- u32 data_stbc:2;
- u32 data_short:1;
- u32 data_bw:1;
- u32 rts_short:1;
- u32 rts_bw:1;
- u32 rts_sc:2;
- u32 vcs_stbc:2;
-
- u32 datarate:6;
- u32 sgi:1;
- u32 try_rate:1;
- u32 data_ratefb_lmt:5;
- u32 rts_ratefb_lmt:4;
- u32 rty_lmt_en:1;
- u32 data_rt_lmt:6;
- u32 usb_txagg_num:8;
-
- u32 txagg_a:5;
- u32 txagg_b:5;
- u32 use_max_len:1;
- u32 max_agg_num:5;
- u32 mcsg1_max_len:4;
- u32 mcsg2_max_len:4;
- u32 mcsg3_max_len:4;
- u32 mcs7_sgi_max_len:4;
-
- u32 checksum:16; /* TxBuffSize(PCIe)/CheckSum(USB) */
- u32 mcsg4_max_len:4;
- u32 mcsg5_max_len:4;
- u32 mcsg6_max_len:4;
- u32 mcs15_sgi_max_len:4;
-};
-
-#define txdesc_set_ccx_sw_8723a(txdesc, value) \
- do { \
- ((struct txdesc_8723a *)(txdesc))->mcsg4_max_len = (((value)>>8) & 0x0f); \
- ((struct txdesc_8723a *)(txdesc))->mcs15_sgi_max_len= (((value)>>4) & 0x0f); \
- ((struct txdesc_8723a *)(txdesc))->mcsg6_max_len = ((value) & 0x0f); \
- } while (0)
-
-struct txrpt_ccx_8723a {
- /* offset 0 */
- u8 tag1:1;
- u8 rsvd:4;
- u8 int_bt:1;
- u8 int_tri:1;
- u8 int_ccx:1;
-
- /* offset 1 */
- u8 mac_id:5;
- u8 pkt_drop:1;
- u8 pkt_ok:1;
- u8 bmc:1;
-
- /* offset 2 */
- u8 retry_cnt:6;
- u8 lifetime_over:1;
- u8 retry_over:1;
-
- /* offset 3 */
- u8 ccx_qtime0;
- u8 ccx_qtime1;
-
- /* offset 5 */
- u8 final_data_rate;
-
- /* offset 6 */
- u8 sw1:4;
- u8 qsel:4;
-
- /* offset 7 */
- u8 sw0;
-};
-
-#define txrpt_ccx_sw_8723a(txrpt_ccx) ((txrpt_ccx)->sw0 + ((txrpt_ccx)->sw1<<8))
-#define txrpt_ccx_qtime_8723a(txrpt_ccx) ((txrpt_ccx)->ccx_qtime0+((txrpt_ccx)->ccx_qtime1<<8))
-
-void handle_txrpt_ccx_8723a(struct rtw_adapter *adapter, void *buf);
-void rtl8723a_fill_fake_txdesc(struct rtw_adapter *padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull);
-
-int rtl8723au_hal_xmitframe_enqueue(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe);
-s32 rtl8723au_xmit_buf_handler(struct rtw_adapter *padapter);
-#define hal_xmit_handler rtl8723au_xmit_buf_handler
-bool rtl8723au_hal_xmit(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe);
-int rtl8723au_mgnt_xmit(struct rtw_adapter *padapter, struct xmit_frame *pmgntframe);
-bool rtl8723au_xmitframe_complete(struct rtw_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf);
-
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtw_ap.h b/drivers/staging/rtl8723au/include/rtw_ap.h
deleted file mode 100644
index 55a708f9fc5b..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_ap.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTW_AP_H_
-#define __RTW_AP_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-
-#ifdef CONFIG_8723AU_AP_MODE
-
-/* external function */
-
-void init_mlme_ap_info23a(struct rtw_adapter *padapter);
-void free_mlme_ap_info23a(struct rtw_adapter *padapter);
-/* void update_BCNTIM(struct rtw_adapter *padapter); */
-void rtw_add_bcn_ie(struct rtw_adapter *padapter, struct wlan_bssid_ex *pnetwork, u8 index, u8 *data, u8 len);
-void rtw_remove_bcn_ie(struct rtw_adapter *padapter, struct wlan_bssid_ex *pnetwork, u8 index);
-void update_beacon23a(struct rtw_adapter *padapter, u8 ie_id, u8 *oui, u8 tx);
-void add_RATid23a(struct rtw_adapter *padapter, struct sta_info *psta, u8 rssi_level);
-void expire_timeout_chk23a(struct rtw_adapter *padapter);
-void update_sta_info23a_apmode23a(struct rtw_adapter *padapter, struct sta_info *psta);
-int rtw_check_beacon_data23a(struct rtw_adapter *padapter,
- struct ieee80211_mgmt *mgmt, unsigned int len);
-void rtw_ap_restore_network(struct rtw_adapter *padapter);
-void rtw_set_macaddr_acl23a(struct rtw_adapter *padapter, int mode);
-
-void associated_clients_update23a(struct rtw_adapter *padapter, u8 updated);
-void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info *psta);
-u8 bss_cap_update_on_sta_leave23a(struct rtw_adapter *padapter, struct sta_info *psta);
-void sta_info_update23a(struct rtw_adapter *padapter, struct sta_info *psta);
-void ap_sta_info_defer_update23a(struct rtw_adapter *padapter, struct sta_info *psta);
-u8 ap_free_sta23a(struct rtw_adapter *padapter, struct sta_info *psta, bool active, u16 reason);
-int rtw_sta_flush23a(struct rtw_adapter *padapter);
-void start_ap_mode23a(struct rtw_adapter *padapter);
-void stop_ap_mode23a(struct rtw_adapter *padapter);
-#endif /* end of CONFIG_8723AU_AP_MODE */
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtw_cmd.h b/drivers/staging/rtl8723au/include/rtw_cmd.h
deleted file mode 100644
index d1fa95d28904..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_cmd.h
+++ /dev/null
@@ -1,815 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTW_CMD_H_
-#define __RTW_CMD_H_
-
-#include <wlan_bssdef.h>
-#include <rtw_rf.h>
-
-#define C2H_MEM_SZ (16*1024)
-
-#include <osdep_service.h>
-#include <ieee80211.h> /* <ieee80211/ieee80211.h> */
-
-
-#define MAX_CMDSZ 1024
-#define MAX_RSPSZ 512
-#define MAX_EVTSZ 1024
-
-#define CMDBUFF_ALIGN_SZ 512
-
-struct cmd_obj {
- struct work_struct work;
- struct rtw_adapter *padapter;
- u16 cmdcode;
- int res;
- u32 cmdsz;
- u8 *parmbuf;
- u8 *rsp;
- u32 rspsz;
-};
-
-struct cmd_priv {
- struct workqueue_struct *wq;
- u32 cmd_issued_cnt;
- u32 cmd_done_cnt;
- u32 rsp_cnt;
- struct rtw_adapter *padapter;
-};
-
-#define C2H_QUEUE_MAX_LEN 10
-
-struct evt_priv {
- struct workqueue_struct *wq;
- struct work_struct irq_wk;
-};
-
-#define init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code) \
-do {\
- pcmd->cmdcode = code;\
- pcmd->parmbuf = (u8 *)(pparm);\
- pcmd->cmdsz = sizeof (*pparm);\
- pcmd->rsp = NULL;\
- pcmd->rspsz = 0;\
-} while(0)
-
-struct c2h_evt_hdr {
- u8 id:4;
- u8 plen:4;
- u8 seq;
- u8 payload[0];
-};
-
-/*
- * Do not reorder - this allows for struct evt_work to be passed on to
- * rtw_c2h_wk_cmd23a() as a 'struct c2h_evt_hdr *' without making an
- * additional copy.
- */
-struct evt_work {
- union {
- struct c2h_evt_hdr c2h_evt;
- u8 buf[16];
- } u;
- struct work_struct work;
- struct rtw_adapter *adapter;
-};
-
-#define c2h_evt_exist(c2h_evt) ((c2h_evt)->id || (c2h_evt)->plen)
-
-void rtw_evt_work(struct work_struct *work);
-
-int rtw_enqueue_cmd23a(struct cmd_priv *pcmdpriv, struct cmd_obj *obj);
-void rtw_free_cmd_obj23a(struct cmd_obj *pcmd);
-
-int rtw_cmd_thread23a(void *context);
-
-int rtw_init_cmd_priv23a(struct cmd_priv *pcmdpriv);
-
-u32 rtw_init_evt_priv23a (struct evt_priv *pevtpriv);
-void rtw_free_evt_priv23a (struct evt_priv *pevtpriv);
-void rtw_evt_notify_isr(struct evt_priv *pevtpriv);
-
-enum rtw_drvextra_cmd_id
-{
- NONE_WK_CID,
- DYNAMIC_CHK_WK_CID,
- DM_CTRL_WK_CID,
- PBC_POLLING_WK_CID,
- POWER_SAVING_CTRL_WK_CID,/* IPS,AUTOSuspend */
- LPS_CTRL_WK_CID,
- ANT_SELECT_WK_CID,
- P2P_PS_WK_CID,
- P2P_PROTO_WK_CID,
- CHECK_HIQ_WK_CID,/* for softap mode, check hi queue if empty */
- C2H_WK_CID,
- RTP_TIMER_CFG_WK_CID,
- MAX_WK_CID
-};
-
-enum LPS_CTRL_TYPE
-{
- LPS_CTRL_SCAN=0,
- LPS_CTRL_JOINBSS=1,
- LPS_CTRL_CONNECT=2,
- LPS_CTRL_DISCONNECT=3,
- LPS_CTRL_SPECIAL_PACKET=4,
- LPS_CTRL_LEAVE=5,
-};
-
-enum RFINTFS {
- SWSI,
- HWSI,
- HWPI,
-};
-
-/*
-Caller Mode: Infra, Ad-HoC(C)
-
-Notes: To enter USB suspend mode
-
-Command Mode
-
-*/
-struct usb_suspend_parm {
- u32 action;/* 1: sleep, 0:resume */
-};
-
-/*
-Caller Mode: Infra, Ad-HoC
-
-Notes: To join a known BSS.
-
-Command-Event Mode
-
-*/
-
-/*
-Caller Mode: Infra, Ad-HoC(C)
-
-Notes: To disconnect the current associated BSS
-
-Command Mode
-
-*/
-struct disconnect_parm {
- u32 deauth_timeout_ms;
-};
-
-struct setopmode_parm {
- enum nl80211_iftype mode;
-};
-
-/*
-Caller Mode: AP, Ad-HoC, Infra
-
-Notes: To ask RTL8711 performing site-survey
-
-Command-Event Mode
-
-*/
-
-#define RTW_SSID_SCAN_AMOUNT 9 /* for WEXT_CSCAN_AMOUNT 9 */
-#define RTW_CHANNEL_SCAN_AMOUNT (14+37)
-struct sitesurvey_parm {
- int scan_mode; /* active: 1, passive: 0 */
- u8 ssid_num;
- u8 ch_num;
- struct cfg80211_ssid ssid[RTW_SSID_SCAN_AMOUNT];
- struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
-};
-
-/*
-Caller Mode: Any
-
-Notes: To set the auth type of RTL8711. open/shared/802.1x
-
-Command Mode
-
-*/
-struct setauth_parm {
- u8 mode; /* 0: legacy open, 1: legacy shared 2: 802.1x */
- u8 _1x; /* 0: PSK, 1: TLS */
- u8 rsvd[2];
-};
-
-/*
-Caller Mode: Infra
-
-a. algorithm: wep40, wep104, tkip & aes
-b. keytype: grp key/unicast key
-c. key contents
-
-when shared key ==> keyid is the camid
-when 802.1x ==> keyid [0:1] ==> grp key
-when 802.1x ==> keyid > 2 ==> unicast key
-
-*/
-struct setkey_parm {
- u32 algorithm; /* encryption algorithm, could be none, wep40, TKIP, CCMP, wep104 */
- u8 keyid;
- u8 grpkey; /* 1: this is the grpkey for 802.1x. 0: this is the unicast key for 802.1x */
- u8 set_tx; /* 1: main tx key for wep. 0: other key. */
- u8 key[16]; /* this could be 40 or 104 */
-};
-
-/*
-When in AP or Ad-Hoc mode, this is used to
-allocate an sw/hw entry for a newly associated sta.
-
-Command
-
-when shared key ==> algorithm/keyid
-
-*/
-struct set_stakey_parm {
- u8 addr[ETH_ALEN];
- u8 id;/* currently for erasing cam entry if algorithm == _NO_PRIVACY_ */
- u32 algorithm;
- u8 key[16];
-};
-
-struct set_stakey_rsp {
- u8 addr[ETH_ALEN];
- u8 keyid;
- u8 rsvd;
-};
-
-/*
-Caller Ad-Hoc/AP
-
-Command -Rsp(AID == CAMID) mode
-
-This is to force fw to add an sta_data entry per driver's request.
-
-FW will write an cam entry associated with it.
-
-*/
-struct set_assocsta_parm {
- u8 addr[ETH_ALEN];
-};
-
-struct set_assocsta_rsp {
- u8 cam_id;
- u8 rsvd[3];
-};
-
-/*
- Caller Ad-Hoc/AP
-
- Command mode
-
- This is to force fw to del an sta_data entry per driver's request
-
- FW will invalidate the cam entry associated with it.
-
-*/
-struct del_assocsta_parm {
- u8 addr[ETH_ALEN];
-};
-
-/*
-Caller Mode: AP/Ad-HoC(M)
-
-Notes: To notify fw that given staid has changed its power state
-
-Command Mode
-
-*/
-struct setstapwrstate_parm {
- u8 staid;
- u8 status;
- u8 hwaddr[6];
-};
-
-/*
-Caller Mode: Any
-
-Notes: To setup the basic rate of RTL8711
-
-Command Mode
-
-*/
-struct setbasicrate_parm {
- u8 basicrates[NumRates];
-};
-
-/*
-Caller Mode: Any
-
-Notes: To read the current basic rate
-
-Command-Rsp Mode
-
-*/
-struct getbasicrate_parm {
- u32 rsvd;
-};
-
-struct getbasicrate_rsp {
- u8 basicrates[NumRates];
-};
-
-/*
-Caller Mode: Any
-
-Notes: To setup the data rate of RTL8711
-
-Command Mode
-
-*/
-struct setdatarate_parm {
- u8 mac_id;
- u8 datarates[NumRates];
-};
-
-/*
-Caller Mode: Any
-
-Notes: To read the current data rate
-
-Command-Rsp Mode
-
-*/
-struct getdatarate_parm {
- u32 rsvd;
-};
-
-struct getdatarate_rsp {
- u8 datarates[NumRates];
-};
-
-
-/*
-Caller Mode: Any
-AP: AP can use the info for the contents of beacon frame
-Infra: STA can use the info when sitesurveying
-Ad-HoC(M): Like AP
-Ad-HoC(C): Like STA
-
-
-Notes: To set the phy capability of the NIC
-
-Command Mode
-
-*/
-
-struct setphyinfo_parm {
- struct regulatory_class class_sets[NUM_REGULATORYS];
- u8 status;
-};
-
-struct getphyinfo_parm {
- u32 rsvd;
-};
-
-struct getphyinfo_rsp {
- struct regulatory_class class_sets[NUM_REGULATORYS];
- u8 status;
-};
-
-/*
-Caller Mode: Any
-
-Notes: To set the channel/modem/band
-This command will be used when channel/modem/band is changed.
-
-Command Mode
-
-*/
-struct setphy_parm {
- u8 rfchannel;
- u8 modem;
-};
-
-/*
-Caller Mode: Any
-
-Notes: To get the current setting of channel/modem/band
-
-Command-Rsp Mode
-
-*/
-struct getphy_parm {
- u32 rsvd;
-};
-
-struct getphy_rsp {
- u8 rfchannel;
- u8 modem;
-};
-
-struct readBB_parm {
- u8 offset;
-};
-
-struct readBB_rsp {
- u8 value;
-};
-
-struct readTSSI_parm {
- u8 offset;
-};
-
-struct readTSSI_rsp {
- u8 value;
-};
-
-struct writeBB_parm {
- u8 offset;
- u8 value;
-};
-
-struct readRF_parm {
- u8 offset;
-};
-
-struct readRF_rsp {
- u32 value;
-};
-
-struct writeRF_parm {
- u32 offset;
- u32 value;
-};
-
-struct getrfintfs_parm {
- u8 rfintfs;
-};
-
-struct Tx_Beacon_param {
- struct wlan_bssid_ex network;
-};
-
-/* CMD param Formart for driver extra cmd handler */
-struct drvextra_cmd_parm {
- int ec_id; /* extra cmd id */
- int type_size; /* Can use this field as the type id or command size */
- unsigned char *pbuf;
-};
-
-/*------------------- Below are used for RF/BB tunning ---------------------*/
-
-struct setantenna_parm {
- u8 tx_antset;
- u8 rx_antset;
- u8 tx_antenna;
- u8 rx_antenna;
-};
-
-struct enrateadaptive_parm {
- u32 en;
-};
-
-struct settxagctbl_parm {
- u32 txagc[MAX_RATES_LENGTH];
-};
-
-struct gettxagctbl_parm {
- u32 rsvd;
-};
-
-struct gettxagctbl_rsp {
- u32 txagc[MAX_RATES_LENGTH];
-};
-
-struct setagcctrl_parm {
- u32 agcctrl; /* 0: pure hw, 1: fw */
-};
-
-struct setssup_parm {
- u32 ss_ForceUp[MAX_RATES_LENGTH];
-};
-
-struct getssup_parm {
- u32 rsvd;
-};
-
-struct getssup_rsp {
- u8 ss_ForceUp[MAX_RATES_LENGTH];
-};
-
-struct setssdlevel_parm {
- u8 ss_DLevel[MAX_RATES_LENGTH];
-};
-
-struct getssdlevel_parm {
- u32 rsvd;
-};
-
-struct getssdlevel_rsp {
- u8 ss_DLevel[MAX_RATES_LENGTH];
-};
-
-struct setssulevel_parm {
- u8 ss_ULevel[MAX_RATES_LENGTH];
-};
-
-struct getssulevel_parm {
- u32 rsvd;
-};
-
-struct getssulevel_rsp {
- u8 ss_ULevel[MAX_RATES_LENGTH];
-};
-
-struct setcountjudge_parm {
- u8 count_judge[MAX_RATES_LENGTH];
-};
-
-struct getcountjudge_parm {
- u32 rsvd;
-};
-
-struct getcountjudge_rsp {
- u8 count_judge[MAX_RATES_LENGTH];
-};
-
-struct setratable_parm {
- u8 ss_ForceUp[NumRates];
- u8 ss_ULevel[NumRates];
- u8 ss_DLevel[NumRates];
- u8 count_judge[NumRates];
-};
-
-struct getratable_parm {
- uint rsvd;
-};
-
-struct getratable_rsp {
- u8 ss_ForceUp[NumRates];
- u8 ss_ULevel[NumRates];
- u8 ss_DLevel[NumRates];
- u8 count_judge[NumRates];
-};
-
-/* to get TX,RX retry count */
-struct gettxretrycnt_parm{
- unsigned int rsvd;
-};
-struct gettxretrycnt_rsp{
- unsigned long tx_retrycnt;
-};
-
-struct getrxretrycnt_parm{
- unsigned int rsvd;
-};
-struct getrxretrycnt_rsp{
- unsigned long rx_retrycnt;
-};
-
-/* to get BCNOK,BCNERR count */
-struct getbcnokcnt_parm{
- unsigned int rsvd;
-};
-struct getbcnokcnt_rsp{
- unsigned long bcnokcnt;
-};
-
-struct getbcnerrcnt_parm{
- unsigned int rsvd;
-};
-struct getbcnerrcnt_rsp{
- unsigned long bcnerrcnt;
-};
-
-/* to get current TX power level */
-struct getcurtxpwrlevel_parm{
- unsigned int rsvd;
-};
-
-struct getcurtxpwrlevel_rsp{
- unsigned short tx_power;
-};
-
-struct setprobereqextraie_parm {
- unsigned char e_id;
- unsigned char ie_len;
- unsigned char ie[0];
-};
-
-struct setassocreqextraie_parm {
- unsigned char e_id;
- unsigned char ie_len;
- unsigned char ie[0];
-};
-
-struct setproberspextraie_parm {
- unsigned char e_id;
- unsigned char ie_len;
- unsigned char ie[0];
-};
-
-struct setassocrspextraie_parm {
- unsigned char e_id;
- unsigned char ie_len;
- unsigned char ie[0];
-};
-
-struct addBaReq_parm {
- unsigned int tid;
- u8 addr[ETH_ALEN];
-};
-
-/*H2C Handler index: 46 */
-struct set_ch_parm {
- u8 ch;
- u8 bw;
- u8 ch_offset;
-};
-
-/*H2C Handler index: 59 */
-struct SetChannelPlan_param {
- u8 channel_plan;
-};
-
-/*H2C Handler index: 60 */
-struct LedBlink_param {
- struct led_8723a *pLed;
-};
-
-/*H2C Handler index: 61 */
-struct SetChannelSwitch_param {
- u8 new_ch_no;
-};
-
-/*H2C Handler index: 62 */
-struct TDLSoption_param {
- u8 addr[ETH_ALEN];
- u8 option;
-};
-
-#define GEN_CMD_CODE(cmd) cmd ## _CMD_
-
-
-/*
-
-Result:
-0x00: success
-0x01: success, and check Response.
-0x02: cmd ignored due to duplicated sequcne number
-0x03: cmd dropped due to invalid cmd code
-0x04: reserved.
-
-*/
-
-#define H2C_RSP_OFFSET 512
-
-#define H2C_SUCCESS 0x00
-#define H2C_SUCCESS_RSP 0x01
-#define H2C_DUPLICATED 0x02
-#define H2C_DROPPED 0x03
-#define H2C_PARAMETERS_ERROR 0x04
-#define H2C_REJECTED 0x05
-#define H2C_CMD_OVERFLOW 0x06
-#define H2C_RESERVED 0x07
-
-int rtw_setassocsta_cmd(struct rtw_adapter *padapter, u8 *mac_addr);
-int rtw_setstandby_cmd(struct rtw_adapter *padapter, uint action);
-int rtw_sitesurvey_cmd23a(struct rtw_adapter *padapter, struct cfg80211_ssid *ssid, int ssid_num, struct rtw_ieee80211_channel *ch, int ch_num);
-int rtw_createbss_cmd23a(struct rtw_adapter *padapter);
-int rtw_createbss_cmd23a_ex(struct rtw_adapter *padapter, unsigned char *pbss, unsigned int sz);
-int rtw_setphy_cmd(struct rtw_adapter *padapter, u8 modem, u8 ch);
-int rtw_setstakey_cmd23a(struct rtw_adapter *padapter, u8 *psta, u8 unicast_key);
-int rtw_clearstakey_cmd23a(struct rtw_adapter *padapter, u8 *psta, u8 entry, u8 enqueue);
-int rtw_joinbss_cmd23a(struct rtw_adapter *padapter, struct wlan_network* pnetwork);
-int rtw_disassoc_cmd23a(struct rtw_adapter *padapter, u32 deauth_timeout_ms, bool enqueue);
-int rtw_setopmode_cmd23a(struct rtw_adapter *padapter, enum nl80211_iftype ifmode);
-int rtw_setdatarate_cmd(struct rtw_adapter *padapter, u8 *rateset);
-int rtw_setbasicrate_cmd(struct rtw_adapter *padapter, u8 *rateset);
-int rtw_setbbreg_cmd(struct rtw_adapter *padapter, u8 offset, u8 val);
-int rtw_setrfreg_cmd(struct rtw_adapter *padapter, u8 offset, u32 val);
-int rtw_getbbreg_cmd(struct rtw_adapter *padapter, u8 offset, u8 *pval);
-int rtw_getrfreg_cmd(struct rtw_adapter *padapter, u8 offset, u8 *pval);
-int rtw_setrfintfs_cmd(struct rtw_adapter *padapter, u8 mode);
-int rtw_setrttbl_cmd(struct rtw_adapter *padapter, struct setratable_parm *prate_table);
-int rtw_getrttbl_cmd(struct rtw_adapter *padapter, struct getratable_rsp *pval);
-
-int rtw_gettssi_cmd(struct rtw_adapter *padapter, u8 offset, u8 *pval);
-int rtw_setfwdig_cmd(struct rtw_adapter*padapter, u8 type);
-int rtw_setfwra_cmd(struct rtw_adapter*padapter, u8 type);
-
-int rtw_addbareq_cmd23a(struct rtw_adapter*padapter, u8 tid, u8 *addr);
-
-int rtw_dynamic_chk_wk_cmd23a(struct rtw_adapter *adapter);
-
-int rtw_lps_ctrl_wk_cmd23a(struct rtw_adapter*padapter, u8 lps_ctrl_type, u8 enqueue);
-
-int rtw_ps_cmd23a(struct rtw_adapter*padapter);
-
-#ifdef CONFIG_8723AU_AP_MODE
-int rtw_chk_hi_queue_cmd23a(struct rtw_adapter*padapter);
-#endif
-
-int rtw_set_chplan_cmd(struct rtw_adapter*padapter, u8 chplan, u8 enqueue);
-int rtw_led_blink_cmd(struct rtw_adapter*padapter, struct led_8723a *pLed);
-int rtw_set_csa_cmd(struct rtw_adapter*padapter, u8 new_ch_no);
-
-int rtw_c2h_wk_cmd23a(struct rtw_adapter *padapter, u8 *c2h_evt);
-
-int rtw_drvextra_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-
-void rtw_survey_cmd_callback23a(struct rtw_adapter *padapter, struct cmd_obj *pcmd);
-void rtw_disassoc_cmd23a_callback(struct rtw_adapter *padapter, struct cmd_obj *pcmd);
-void rtw_joinbss_cmd23a_callback(struct rtw_adapter *padapter, struct cmd_obj *pcmd);
-void rtw_createbss_cmd23a_callback(struct rtw_adapter *padapter, struct cmd_obj *pcmd);
-void rtw_getbbrfreg_cmdrsp_callback23a(struct rtw_adapter *padapter, struct cmd_obj *pcmd);
-
-void rtw_setstaKey_cmdrsp_callback23a(struct rtw_adapter *padapter, struct cmd_obj *pcmd);
-void rtw_setassocsta_cmdrsp_callback23a(struct rtw_adapter *padapter, struct cmd_obj *pcmd);
-
-struct _cmd_callback {
- u32 cmd_code;
- void (*callback)(struct rtw_adapter *padapter, struct cmd_obj *cmd);
-};
-
-enum rtw_h2c_cmd {
- GEN_CMD_CODE(_Read_MACREG) , /*0*/
- GEN_CMD_CODE(_Write_MACREG) ,
- GEN_CMD_CODE(_Read_BBREG) ,
- GEN_CMD_CODE(_Write_BBREG) ,
- GEN_CMD_CODE(_Read_RFREG) ,
- GEN_CMD_CODE(_Write_RFREG) , /*5*/
- GEN_CMD_CODE(_Read_EEPROM) ,
- GEN_CMD_CODE(_Write_EEPROM) ,
- GEN_CMD_CODE(_Read_EFUSE) ,
- GEN_CMD_CODE(_Write_EFUSE) ,
-
- GEN_CMD_CODE(_Read_CAM) , /*10*/
- GEN_CMD_CODE(_Write_CAM) ,
- GEN_CMD_CODE(_setBCNITV),
- GEN_CMD_CODE(_setMBIDCFG),
- GEN_CMD_CODE(_JoinBss), /*14*/
- GEN_CMD_CODE(_DisConnect) , /*15*/
- GEN_CMD_CODE(_CreateBss) ,
- GEN_CMD_CODE(_SetOpMode) ,
- GEN_CMD_CODE(_SiteSurvey), /*18*/
- GEN_CMD_CODE(_SetAuth) ,
-
- GEN_CMD_CODE(_SetKey) , /*20*/
- GEN_CMD_CODE(_SetStaKey) ,
- GEN_CMD_CODE(_SetAssocSta) ,
- GEN_CMD_CODE(_DelAssocSta) ,
- GEN_CMD_CODE(_SetStaPwrState) ,
- GEN_CMD_CODE(_SetBasicRate) , /*25*/
- GEN_CMD_CODE(_GetBasicRate) ,
- GEN_CMD_CODE(_SetDataRate) ,
- GEN_CMD_CODE(_GetDataRate) ,
- GEN_CMD_CODE(_SetPhyInfo) ,
-
- GEN_CMD_CODE(_GetPhyInfo) , /*30*/
- GEN_CMD_CODE(_SetPhy) ,
- GEN_CMD_CODE(_GetPhy) ,
- GEN_CMD_CODE(_readRssi) ,
- GEN_CMD_CODE(_readGain) ,
- GEN_CMD_CODE(_SetAtim) , /*35*/
- GEN_CMD_CODE(_SetPwrMode) ,
- GEN_CMD_CODE(_JoinbssRpt),
- GEN_CMD_CODE(_SetRaTable) ,
- GEN_CMD_CODE(_GetRaTable) ,
-
- GEN_CMD_CODE(_GetCCXReport), /*40*/
- GEN_CMD_CODE(_GetDTMReport),
- GEN_CMD_CODE(_GetTXRateStatistics),
- GEN_CMD_CODE(_SetUsbSuspend),
- GEN_CMD_CODE(_SetH2cLbk),
- GEN_CMD_CODE(_AddBAReq) , /*45*/
- GEN_CMD_CODE(_SetChannel), /*46*/
- GEN_CMD_CODE(_SetTxPower),
- GEN_CMD_CODE(_SwitchAntenna),
- GEN_CMD_CODE(_SetCrystalCap),
- GEN_CMD_CODE(_SetSingleCarrierTx), /*50*/
-
- GEN_CMD_CODE(_SetSingleToneTx),/*51*/
- GEN_CMD_CODE(_SetCarrierSuppressionTx),
- GEN_CMD_CODE(_SetContinuousTx),
- GEN_CMD_CODE(_SwitchBandwidth), /*54*/
- GEN_CMD_CODE(_TX_Beacon), /*55*/
-
- GEN_CMD_CODE(_Set_MLME_EVT), /*56*/
- GEN_CMD_CODE(_Set_Drv_Extra), /*57*/
- GEN_CMD_CODE(_Set_H2C_MSG), /*58*/
-
- GEN_CMD_CODE(_SetChannelPlan), /*59*/
- GEN_CMD_CODE(_LedBlink), /*60*/
-
- GEN_CMD_CODE(_SetChannelSwitch), /*61*/
- GEN_CMD_CODE(_TDLS), /*62*/
-
- MAX_H2CCMD
-};
-
-extern struct _cmd_callback rtw_cmd_callback[];
-
-#endif /* _CMD_H_ */
diff --git a/drivers/staging/rtl8723au/include/rtw_debug.h b/drivers/staging/rtl8723au/include/rtw_debug.h
deleted file mode 100644
index 159183e9cab0..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_debug.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- *
- ******************************************************************************/
-#ifndef __RTW_DEBUG_H__
-#define __RTW_DEBUG_H__
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-#define _drv_always_ 1
-#define _drv_emerg_ 2
-#define _drv_alert_ 3
-#define _drv_err_ 4
-#define _drv_warning_ 5
-#define _drv_notice_ 6
-#define _drv_info_ 7
-#define _drv_debug_ 8
-
-#define _module_rtl871x_xmit_c_ BIT(0)
-#define _module_xmit_osdep_c_ BIT(1)
-#define _module_rtl871x_recv_c_ BIT(2)
-#define _module_recv_osdep_c_ BIT(3)
-#define _module_rtl871x_mlme_c_ BIT(4)
-#define _module_mlme_osdep_c_ BIT(5)
-#define _module_rtl871x_sta_mgt_c_ BIT(6)
-#define _module_rtl871x_cmd_c_ BIT(7)
-#define _module_cmd_osdep_c_ BIT(8)
-#define _module_rtl871x_io_c_ BIT(9)
-#define _module_io_osdep_c_ BIT(10)
-#define _module_os_intfs_c_ BIT(11)
-#define _module_rtl871x_security_c_ BIT(12)
-#define _module_rtl871x_eeprom_c_ BIT(13)
-#define _module_hal_init_c_ BIT(14)
-#define _module_hci_hal_init_c_ BIT(15)
-#define _module_rtl871x_ioctl_c_ BIT(16)
-#define _module_rtl871x_ioctl_set_c_ BIT(17)
-#define _module_rtl871x_ioctl_query_c_ BIT(18)
-#define _module_rtl871x_pwrctrl_c_ BIT(19)
-#define _module_hci_intfs_c_ BIT(20)
-#define _module_hci_ops_c_ BIT(21)
-#define _module_osdep_service_c_ BIT(22)
-#define _module_mp_ BIT(23)
-#define _module_hci_ops_os_c_ BIT(24)
-#define _module_rtl871x_ioctl_os_c BIT(25)
-#define _module_rtl8712_cmd_c_ BIT(26)
-#define _module_rtl8192c_xmit_c_ BIT(28)
-#define _module_hal_xmit_c_ BIT(28) /* duplication intentional */
-#define _module_efuse_ BIT(29)
-#define _module_rtl8712_recv_c_ BIT(30)
-#define _module_rtl8712_led_c_ BIT(31)
-
-#undef _MODULE_DEFINE_
-
-#if defined _RTW_XMIT_C_
- #define _MODULE_DEFINE_ _module_rtl871x_xmit_c_
-#elif defined _XMIT_OSDEP_C_
- #define _MODULE_DEFINE_ _module_xmit_osdep_c_
-#elif defined _RTW_RECV_C_
- #define _MODULE_DEFINE_ _module_rtl871x_recv_c_
-#elif defined _RECV_OSDEP_C_
- #define _MODULE_DEFINE_ _module_recv_osdep_c_
-#elif defined _RTW_MLME_C_
- #define _MODULE_DEFINE_ _module_rtl871x_mlme_c_
-#elif defined _MLME_OSDEP_C_
- #define _MODULE_DEFINE_ _module_mlme_osdep_c_
-#elif defined _RTW_MLME_EXT_C_
- #define _MODULE_DEFINE_ 1
-#elif defined _RTW_STA_MGT_C_
- #define _MODULE_DEFINE_ _module_rtl871x_sta_mgt_c_
-#elif defined _RTW_CMD_C_
- #define _MODULE_DEFINE_ _module_rtl871x_cmd_c_
-#elif defined _CMD_OSDEP_C_
- #define _MODULE_DEFINE_ _module_cmd_osdep_c_
-#elif defined _RTW_IO_C_
- #define _MODULE_DEFINE_ _module_rtl871x_io_c_
-#elif defined _IO_OSDEP_C_
- #define _MODULE_DEFINE_ _module_io_osdep_c_
-#elif defined _OS_INTFS_C_
- #define _MODULE_DEFINE_ _module_os_intfs_c_
-#elif defined _RTW_SECURITY_C_
- #define _MODULE_DEFINE_ _module_rtl871x_security_c_
-#elif defined _RTW_EEPROM_C_
- #define _MODULE_DEFINE_ _module_rtl871x_eeprom_c_
-#elif defined _HAL_INTF_C_
- #define _MODULE_DEFINE_ _module_hal_init_c_
-#elif (defined _HCI_HAL_INIT_C_) || (defined _SDIO_HALINIT_C_)
- #define _MODULE_DEFINE_ _module_hci_hal_init_c_
-#elif defined _RTL871X_IOCTL_C_
- #define _MODULE_DEFINE_ _module_rtl871x_ioctl_c_
-#elif defined _RTL871X_IOCTL_SET_C_
- #define _MODULE_DEFINE_ _module_rtl871x_ioctl_set_c_
-#elif defined _RTL871X_IOCTL_QUERY_C_
- #define _MODULE_DEFINE_ _module_rtl871x_ioctl_query_c_
-#elif defined _RTL871X_PWRCTRL_C_
- #define _MODULE_DEFINE_ _module_rtl871x_pwrctrl_c_
-#elif defined _RTW_PWRCTRL_C_
- #define _MODULE_DEFINE_ 1
-#elif defined _HCI_INTF_C_
- #define _MODULE_DEFINE_ _module_hci_intfs_c_
-#elif defined _HCI_OPS_C_
- #define _MODULE_DEFINE_ _module_hci_ops_c_
-#elif defined _SDIO_OPS_C_
- #define _MODULE_DEFINE_ 1
-#elif defined _OSDEP_HCI_INTF_C_
- #define _MODULE_DEFINE_ _module_hci_intfs_c_
-#elif defined _OSDEP_SERVICE_C_
- #define _MODULE_DEFINE_ _module_osdep_service_c_
-#elif defined _HCI_OPS_OS_C_
- #define _MODULE_DEFINE_ _module_hci_ops_os_c_
-#elif defined _RTL871X_IOCTL_LINUX_C_
- #define _MODULE_DEFINE_ _module_rtl871x_ioctl_os_c
-#elif defined _RTL8712_CMD_C_
- #define _MODULE_DEFINE_ _module_rtl8712_cmd_c_
-#elif defined _RTL8192C_XMIT_C_
- #define _MODULE_DEFINE_ 1
-#elif defined _RTL8723AS_XMIT_C_
- #define _MODULE_DEFINE_ 1
-#elif defined _RTL8712_RECV_C_
- #define _MODULE_DEFINE_ _module_rtl8712_recv_c_
-#elif defined _RTL8192CU_RECV_C_
- #define _MODULE_DEFINE_ _module_rtl8712_recv_c_
-#elif defined _RTL871X_MLME_EXT_C_
- #define _MODULE_DEFINE_ _module_mlme_osdep_c_
-#elif defined _RTW_MP_C_
- #define _MODULE_DEFINE_ _module_mp_
-#elif defined _RTW_MP_IOCTL_C_
- #define _MODULE_DEFINE_ _module_mp_
-#elif defined _RTW_EFUSE_C_
- #define _MODULE_DEFINE_ _module_efuse_
-#endif
-
-#define DRIVER_PREFIX "RTL8723AU: "
-#define DEBUG_LEVEL (_drv_err_)
-#define DBG_8723A_LEVEL(_level, fmt, arg...) \
- do { \
- if (_level <= GlobalDebugLevel23A) \
- pr_info(DRIVER_PREFIX fmt, ##arg);\
- } while (0)
-
-#define DBG_8723A(...) \
- do { \
- if (_drv_err_ <= GlobalDebugLevel23A) \
- pr_info(DRIVER_PREFIX __VA_ARGS__); \
- } while (0)
-
-#define MSG_8723A(...) \
- do { \
- if (_drv_err_ <= GlobalDebugLevel23A) \
- pr_info(DRIVER_PREFIX __VA_ARGS__); \
- } while (0)
-
-extern u32 GlobalDebugLevel23A;
-
-__printf(3, 4)
-void rt_trace(int comp, int level, const char *fmt, ...);
-
-#define RT_TRACE(_Comp, _Level, Fmt, ...) \
-do { \
- if (_Level <= GlobalDebugLevel23A) \
- rt_trace(_Comp, _Level, Fmt, ##__VA_ARGS__); \
-} while (0)
-
-#define RT_PRINT_DATA(_Comp, _Level, _TitleString, _HexData, \
- _HexDataLen) \
- if (_Level <= GlobalDebugLevel23A) { \
- int __i; \
- u8 *ptr = (u8 *)_HexData; \
- pr_info("%s", DRIVER_PREFIX); \
- pr_info(_TitleString); \
- for (__i = 0; __i < (int)_HexDataLen; __i++) { \
- printk("%02X%s", ptr[__i], \
- (((__i + 1) % 4) == 0) ? " " : " "); \
- if (((__i + 1) % 16) == 0) \
- printk("\n"); \
- } \
- printk("\n"); \
- }
-
-#endif /* __RTW_DEBUG_H__ */
diff --git a/drivers/staging/rtl8723au/include/rtw_eeprom.h b/drivers/staging/rtl8723au/include/rtw_eeprom.h
deleted file mode 100644
index a86f36e49dd1..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_eeprom.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTW_EEPROM_H__
-#define __RTW_EEPROM_H__
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-#define RTL8712_EEPROM_ID 0x8712
-/* define EEPROM_MAX_SIZE 256 */
-
-#define HWSET_MAX_SIZE_512 512
-#define EEPROM_MAX_SIZE HWSET_MAX_SIZE_512
-
-#define CLOCK_RATE 50 /* 100us */
-
-/* EEPROM opcodes */
-#define EEPROM_READ_OPCODE 06
-#define EEPROM_WRITE_OPCODE 05
-#define EEPROM_ERASE_OPCODE 07
-#define EEPROM_EWEN_OPCODE 19 /* Erase/write enable */
-#define EEPROM_EWDS_OPCODE 16 /* Erase/write disable */
-
-/* Country codes */
-#define USA 0x555320
-#define EUROPE 0x1 /* temp, should be provided later */
-#define JAPAN 0x2 /* temp, should be provided later */
-
-#define EEPROM_CID_DEFAULT 0x0
-#define EEPROM_CID_ALPHA 0x1
-#define EEPROM_CID_Senao 0x3
-#define EEPROM_CID_NetCore 0x5
-#define EEPROM_CID_CAMEO 0X8
-#define EEPROM_CID_SITECOM 0x9
-#define EEPROM_CID_COREGA 0xB
-#define EEPROM_CID_EDIMAX_BELKIN 0xC
-#define EEPROM_CID_SERCOMM_BELKIN 0xE
-#define EEPROM_CID_CAMEO1 0xF
-#define EEPROM_CID_WNC_COREGA 0x12
-#define EEPROM_CID_CLEVO 0x13
-#define EEPROM_CID_WHQL 0xFE /* added by chiyoko for dtm, 20090108 */
-
-/* */
-/* Customer ID, note that: */
-/* This variable is initiailzed through EEPROM or registry, */
-/* however, its definition may be different with that in EEPROM for */
-/* EEPROM size consideration. So, we have to perform proper translation between them. */
-/* Besides, CustomerID of registry has precedence of that of EEPROM. */
-/* defined below. 060703, by rcnjko. */
-/* */
-enum rt_customer_id
-{
- RT_CID_DEFAULT = 0,
- RT_CID_8187_ALPHA0 = 1,
- RT_CID_8187_SERCOMM_PS = 2,
- RT_CID_8187_HW_LED = 3,
- RT_CID_8187_NETGEAR = 4,
- RT_CID_WHQL = 5,
- RT_CID_819x_CAMEO = 6,
- RT_CID_819x_RUNTOP = 7,
- RT_CID_819x_Senao = 8,
- RT_CID_TOSHIBA = 9, /* Merge by Jacken, 2008/01/31. */
- RT_CID_819x_Netcore = 10,
- RT_CID_Nettronix = 11,
- RT_CID_DLINK = 12,
- RT_CID_PRONET = 13,
- RT_CID_COREGA = 14,
- RT_CID_CHINA_MOBILE = 15,
- RT_CID_819x_ALPHA = 16,
- RT_CID_819x_Sitecom = 17,
- RT_CID_CCX = 18, /* It's set under CCX logo test and isn't demanded for CCX functions, but for test behavior like retry limit and tx report. By Bruce, 2009-02-17. */
- RT_CID_819x_Lenovo = 19,
- RT_CID_819x_QMI = 20,
- RT_CID_819x_Edimax_Belkin = 21,
- RT_CID_819x_Sercomm_Belkin = 22,
- RT_CID_819x_CAMEO1 = 23,
- RT_CID_819x_MSI = 24,
- RT_CID_819x_Acer = 25,
- RT_CID_819x_AzWave_ASUS = 26,
- RT_CID_819x_AzWave = 27, /* For AzWave in PCIe, The ID is AzWave use and not only Asus */
- RT_CID_819x_HP = 28,
- RT_CID_819x_WNC_COREGA = 29,
- RT_CID_819x_Arcadyan_Belkin = 30,
- RT_CID_819x_SAMSUNG = 31,
- RT_CID_819x_CLEVO = 32,
- RT_CID_819x_DELL = 33,
- RT_CID_819x_PRONETS = 34,
- RT_CID_819x_Edimax_ASUS = 35,
- RT_CID_819x_CAMEO_NETGEAR = 36,
- RT_CID_PLANEX = 37,
- RT_CID_CC_C = 38,
- RT_CID_819x_Xavi = 39,
- RT_CID_819x_FUNAI_TV = 40,
- RT_CID_819x_ALPHA_WD=41,
-};
-
-struct eeprom_priv {
- u8 mac_addr[6]; /* PermanentAddress */
- u8 bautoload_fail_flag;
- u8 bloadfile_fail_flag;
- u8 bloadmac_fail_flag;
- /* u8 bempty; */
- /* u8 sys_config; */
- /* u8 config0; */
- u16 channel_plan;
- /* u8 country_string[3]; */
- /* u8 tx_power_b[15]; */
- /* u8 tx_power_g[15]; */
- /* u8 tx_power_a[201]; */
-
- u8 EepromOrEfuse;
-
- u8 efuse_eeprom_data[HWSET_MAX_SIZE_512]; /* 92C:256bytes, 88E:512bytes, we use union set (512bytes) */
-};
-
-void eeprom_write16(struct rtw_adapter *padapter, u16 reg, u16 data);
-u16 eeprom_read16(struct rtw_adapter *padapter, u16 reg);
-void read_eeprom_content(struct rtw_adapter *padapter);
-void eeprom_read_sz(struct rtw_adapter *padapter, u16 reg, u8 *data, u32 sz);
-
-void read_eeprom_content_by_attrib(struct rtw_adapter *padapter);
-
-#endif /* __RTL871X_EEPROM_H__ */
diff --git a/drivers/staging/rtl8723au/include/rtw_efuse.h b/drivers/staging/rtl8723au/include/rtw_efuse.h
deleted file mode 100644
index c577e260f151..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_efuse.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- *
- ******************************************************************************/
-#ifndef __RTW_EFUSE_H__
-#define __RTW_EFUSE_H__
-
-#include <osdep_service.h>
-
-#define EFUSE_ERROE_HANDLE 1
-
-#define PG_STATE_HEADER 0x01
-#define PG_STATE_WORD_0 0x02
-#define PG_STATE_WORD_1 0x04
-#define PG_STATE_WORD_2 0x08
-#define PG_STATE_WORD_3 0x10
-#define PG_STATE_DATA 0x20
-
-#define PG_SWBYTE_H 0x01
-#define PG_SWBYTE_L 0x02
-
-#define PGPKT_DATA_SIZE 8
-
-#define EFUSE_WIFI 0
-#define EFUSE_BT 1
-
-enum _EFUSE_DEF_TYPE {
- TYPE_EFUSE_MAX_SECTION = 0,
- TYPE_EFUSE_REAL_CONTENT_LEN = 1,
- TYPE_AVAILABLE_EFUSE_BYTES_BANK = 2,
- TYPE_AVAILABLE_EFUSE_BYTES_TOTAL = 3,
- TYPE_EFUSE_MAP_LEN = 4,
- TYPE_EFUSE_PROTECT_BYTES_BANK = 5,
- TYPE_EFUSE_CONTENT_LEN_BANK = 6,
-};
-
-/* E-Fuse */
-#define EFUSE_MAP_SIZE 256
-
-#define EFUSE_MAX_SIZE 512
-/* end of E-Fuse */
-
-#define EFUSE_MAX_MAP_LEN 256
-#define EFUSE_MAX_HW_SIZE 512
-#define EFUSE_MAX_SECTION_BASE 16
-
-#define EXT_HEADER(header) ((header & 0x1F) == 0x0F)
-#define ALL_WORDS_DISABLED(wde) ((wde & 0x0F) == 0x0F)
-#define GET_HDR_OFFSET_2_0(header) ( (header & 0xE0) >> 5)
-
-#define EFUSE_REPEAT_THRESHOLD_ 3
-
-/* */
-/* The following is for BT Efuse definition */
-/* */
-#define EFUSE_BT_MAX_MAP_LEN 1024
-#define EFUSE_MAX_BANK 4
-#define EFUSE_MAX_BT_BANK (EFUSE_MAX_BANK-1)
-/* */
-/*--------------------------Define Parameters-------------------------------*/
-#define EFUSE_MAX_WORD_UNIT 4
-
-/*------------------------------Define structure----------------------------*/
-struct pg_pkt_struct {
- u8 offset;
- u8 word_en;
- u8 data[8];
- u8 word_cnts;
-};
-
-/*------------------------Export global variable----------------------------*/
-
-u16 efuse_GetMaxSize23a(struct rtw_adapter *padapter);
-int rtw_efuse_access23a(struct rtw_adapter *padapter, u8 bRead, u16 start_addr, u16 cnts, u8 *data);
-int rtw_efuse_map_read23a(struct rtw_adapter *padapter, u16 addr, u16 cnts, u8 *data);
-u8 rtw_efuse_map_write(struct rtw_adapter *padapter, u16 addr, u16 cnts, u8 *data);
-int rtw_BT_efuse_map_read23a(struct rtw_adapter *padapter, u16 addr, u16 cnts, u8 *data);
-u8 rtw_BT_efuse_map_write(struct rtw_adapter *padapter, u16 addr, u16 cnts, u8 *data);
-
-u16 Efuse_GetCurrentSize23a(struct rtw_adapter *pAdapter, u8 efuseType);
-u8 Efuse_CalculateWordCnts23a(u8 word_en);
-void ReadEFuseByte23a(struct rtw_adapter *Adapter, u16 _offset, u8 *pbuf);
-void EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType, u8 type, void *pOut);
-int efuse_OneByteRead23a(struct rtw_adapter *pAdapter, u16 addr, u8 *data);
-int efuse_OneByteWrite23a(struct rtw_adapter *pAdapter, u16 addr, u8 data);
-
-void Efuse_PowerSwitch23a(struct rtw_adapter *pAdapter, u8 bWrite,
- u8 PwrState);
-int Efuse_PgPacketRead23a(struct rtw_adapter *pAdapter, u8 offset, u8 *data);
-int Efuse_PgPacketWrite23a(struct rtw_adapter *pAdapter, u8 offset, u8 word_en, u8 *data);
-void efuse_WordEnableDataRead23a(u8 word_en, u8 *sourdata, u8 *targetdata);
-u8 Efuse_WordEnableDataWrite23a(struct rtw_adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data);
-
-u8 EFUSE_Read1Byte23a(struct rtw_adapter *pAdapter, u16 Address);
-void EFUSE_ShadowMapUpdate23a(struct rtw_adapter *pAdapter, u8 efuseType);
-void EFUSE_ShadowRead23a(struct rtw_adapter *pAdapter, u8 Type, u16 Offset, u32 *Value);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtw_event.h b/drivers/staging/rtl8723au/include/rtw_event.h
deleted file mode 100644
index 4557aeccc604..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_event.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef _RTW_EVENT_H_
-#define _RTW_EVENT_H_
-
-#include <osdep_service.h>
-#include <wlan_bssdef.h>
-
-/*
-Used to report a bss has been scanned
-*/
-struct survey_event {
- struct wlan_bssid_ex *bss;
-};
-
-/*
-Used to report that the requested site survey has been done.
-bss_cnt indicates the number of bss that has been reported.
-*/
-struct surveydone_event {
- unsigned int bss_cnt;
-};
-
-/*
-Used to report the link result of joinning the given bss
-join_res:
--1: authentication fail
--2: association fail
-> 0: TID
-*/
-struct joinbss_event {
- struct wlan_network network;
-};
-
-/*
-Used to report a given STA has joinned the created BSS.
-It is used in AP/Ad-HoC(M) mode.
-*/
-struct stassoc_event {
- unsigned char macaddr[6];
- unsigned char rsvd[2];
- int cam_id;
-};
-
-struct stadel_event {
- unsigned char macaddr[6];
- unsigned char rsvd[2]; /* for reason */
- int mac_id;
-};
-
-struct addba_event {
- unsigned int tid;
-};
-
-#define GEN_EVT_CODE(event) event ## _EVT_
-
-struct fwevent {
- u32 parmsize;
- void (*event_callback)(struct rtw_adapter *dev, const u8 *pbuf);
-};
-
-#endif /* _WLANEVENT_H_ */
diff --git a/drivers/staging/rtl8723au/include/rtw_ht.h b/drivers/staging/rtl8723au/include/rtw_ht.h
deleted file mode 100644
index 780eb8944118..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_ht.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef _RTW_HT_H_
-#define _RTW_HT_H_
-
-#include <osdep_service.h>
-#include "linux/ieee80211.h"
-#include "wifi.h"
-
-struct ht_priv {
- bool ht_option;
- bool ampdu_enable;/* for enable Tx A-MPDU */
- /* u8 baddbareq_issued[16]; */
- u32 tx_amsdu_enable;/* for enable Tx A-MSDU */
- u32 tx_amdsu_maxlen; /* 1: 8k, 0:4k ; default:8k, for tx */
- u32 rx_ampdu_maxlen; /* for rx reordering ctrl win_sz, updated when join_callback. */
-
- u8 bwmode;/* */
- u8 ch_offset;/* PRIME_CHNL_OFFSET */
- u8 sgi;/* short GI */
-
- /* for processing Tx A-MPDU */
- u16 agg_enable_bitmap;
- /* u8 ADDBA_retry_count; */
- u16 candidate_tid_bitmap;
-
- struct ieee80211_ht_cap ht_cap;
-};
-
-#endif /* _RTL871X_HT_H_ */
diff --git a/drivers/staging/rtl8723au/include/rtw_io.h b/drivers/staging/rtl8723au/include/rtw_io.h
deleted file mode 100644
index c8119e2c6545..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_io.h
+++ /dev/null
@@ -1,237 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-#ifndef _RTW_IO_H_
-#define _RTW_IO_H_
-
-#include <osdep_service.h>
-#include <osdep_intf.h>
-
-#include <asm/byteorder.h>
-#include <linux/semaphore.h>
-#include <linux/list.h>
-/* include <linux/smp_lock.h> */
-#include <linux/spinlock.h>
-#include <asm/atomic.h>
-
-#include <linux/usb.h>
-#include <linux/usb/ch9.h>
-
-#define rtw_usb_buffer_alloc(dev, size, dma) usb_alloc_coherent((dev), (size), (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), (dma))
-#define rtw_usb_buffer_free(dev, size, addr, dma) usb_free_coherent((dev), (size), (addr), (dma))
-
-#define NUM_IOREQ 8
-
-#define MAX_PROT_SZ (64-16)
-
-#define _IOREADY 0
-#define _IO_WAIT_COMPLETE 1
-#define _IO_WAIT_RSP 2
-
-/* IO COMMAND TYPE */
-#define _IOSZ_MASK_ (0x7F)
-#define _IO_WRITE_ BIT(7)
-#define _IO_FIXED_ BIT(8)
-#define _IO_BURST_ BIT(9)
-#define _IO_BYTE_ BIT(10)
-#define _IO_HW_ BIT(11)
-#define _IO_WORD_ BIT(12)
-#define _IO_SYNC_ BIT(13)
-#define _IO_CMDMASK_ (0x1F80)
-
-
-/*
- For prompt mode accessing, caller shall free io_req
- Otherwise, io_handler will free io_req
-*/
-
-
-
-/* IO STATUS TYPE */
-#define _IO_ERR_ BIT(2)
-#define _IO_SUCCESS_ BIT(1)
-#define _IO_DONE_ BIT(0)
-
-
-#define IO_RD32 (_IO_SYNC_ | _IO_WORD_)
-#define IO_RD16 (_IO_SYNC_ | _IO_HW_)
-#define IO_RD8 (_IO_SYNC_ | _IO_BYTE_)
-
-#define IO_RD32_ASYNC (_IO_WORD_)
-#define IO_RD16_ASYNC (_IO_HW_)
-#define IO_RD8_ASYNC (_IO_BYTE_)
-
-#define IO_WR32 (_IO_WRITE_ | _IO_SYNC_ | _IO_WORD_)
-#define IO_WR16 (_IO_WRITE_ | _IO_SYNC_ | _IO_HW_)
-#define IO_WR8 (_IO_WRITE_ | _IO_SYNC_ | _IO_BYTE_)
-
-#define IO_WR32_ASYNC (_IO_WRITE_ | _IO_WORD_)
-#define IO_WR16_ASYNC (_IO_WRITE_ | _IO_HW_)
-#define IO_WR8_ASYNC (_IO_WRITE_ | _IO_BYTE_)
-
-/*
-
- Only Sync. burst accessing is provided.
-
-*/
-
-#define IO_WR_BURST(x) (_IO_WRITE_ | _IO_SYNC_ | _IO_BURST_ | ( (x) & _IOSZ_MASK_))
-#define IO_RD_BURST(x) (_IO_SYNC_ | _IO_BURST_ | ( (x) & _IOSZ_MASK_))
-
-
-
-/* below is for the intf_option bit defition... */
-
-#define _INTF_ASYNC_ BIT(0) /* support async io */
-
-struct intf_priv;
-
-struct io_req {
- struct list_head list;
- u32 addr;
- volatile u32 val;
- u32 command;
- u32 status;
- u8 *pbuf;
- struct semaphore sema;
-
- void (*_async_io_callback)(struct rtw_adapter *padater, struct io_req *pio_req, u8 *cnxt);
- u8 *cnxt;
-};
-
-struct reg_protocol_rd {
-
-#ifdef __LITTLE_ENDIAN
-
- /* DW1 */
- u32 NumOfTrans:4;
- u32 Reserved1:4;
- u32 Reserved2:24;
- /* DW2 */
- u32 ByteCount:7;
- u32 WriteEnable:1; /* 0:read, 1:write */
- u32 FixOrContinuous:1; /* 0:continuous, 1: Fix */
- u32 BurstMode:1;
- u32 Byte1Access:1;
- u32 Byte2Access:1;
- u32 Byte4Access:1;
- u32 Reserved3:3;
- u32 Reserved4:16;
- /* DW3 */
- u32 BusAddress;
- /* DW4 */
- /* u32 Value; */
-#else
-
-
-/* DW1 */
- u32 Reserved1 :4;
- u32 NumOfTrans :4;
-
- u32 Reserved2 :24;
-
- /* DW2 */
- u32 WriteEnable : 1;
- u32 ByteCount :7;
-
-
- u32 Reserved3 : 3;
- u32 Byte4Access : 1;
-
- u32 Byte2Access : 1;
- u32 Byte1Access : 1;
- u32 BurstMode :1 ;
- u32 FixOrContinuous : 1;
-
- u32 Reserved4 : 16;
-
- /* DW3 */
- u32 BusAddress;
-
- /* DW4 */
- /* u32 Value; */
-
-#endif
-
-};
-
-
-struct reg_protocol_wt {
-
-
-#ifdef __LITTLE_ENDIAN
-
- /* DW1 */
- u32 NumOfTrans:4;
- u32 Reserved1:4;
- u32 Reserved2:24;
- /* DW2 */
- u32 ByteCount:7;
- u32 WriteEnable:1; /* 0:read, 1:write */
- u32 FixOrContinuous:1; /* 0:continuous, 1: Fix */
- u32 BurstMode:1;
- u32 Byte1Access:1;
- u32 Byte2Access:1;
- u32 Byte4Access:1;
- u32 Reserved3:3;
- u32 Reserved4:16;
- /* DW3 */
- u32 BusAddress;
- /* DW4 */
- u32 Value;
-
-#else
- /* DW1 */
- u32 Reserved1 :4;
- u32 NumOfTrans :4;
-
- u32 Reserved2 :24;
-
- /* DW2 */
- u32 WriteEnable : 1;
- u32 ByteCount :7;
-
- u32 Reserved3 : 3;
- u32 Byte4Access : 1;
-
- u32 Byte2Access : 1;
- u32 Byte1Access : 1;
- u32 BurstMode :1 ;
- u32 FixOrContinuous : 1;
-
- u32 Reserved4 : 16;
-
- /* DW3 */
- u32 BusAddress;
-
- /* DW4 */
- u32 Value;
-
-#endif
-
-};
-
-#define PlatformEFIOWrite1Byte(_a, _b, _c) \
- rtl8723au_write8(_a, _b, _c)
-#define PlatformEFIOWrite2Byte(_a, _b, _c) \
- rtl8723au_write16(_a, _b, _c)
-#define PlatformEFIOWrite4Byte(_a, _b, _c) \
- rtl8723au_write32(_a, _b, _c)
-
-#define PlatformEFIORead1Byte(_a, _b) rtl8723au_read8(_a, _b)
-#define PlatformEFIORead2Byte(_a, _b) rtl8723au_read16(_a, _b)
-#define PlatformEFIORead4Byte(_a, _b) rtl8723au_read32(_a, _b)
-
-#endif /* _RTL8711_IO_H_ */
diff --git a/drivers/staging/rtl8723au/include/rtw_mlme.h b/drivers/staging/rtl8723au/include/rtw_mlme.h
deleted file mode 100644
index dbd3a5f5c523..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_mlme.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- *
- ******************************************************************************/
-#ifndef __RTW_MLME_H_
-#define __RTW_MLME_H_
-
-#include <osdep_service.h>
-#include <mlme_osdep.h>
-#include <drv_types.h>
-#include <wlan_bssdef.h>
-
-#define MAX_BSS_CNT 128
-#define MAX_JOIN_TIMEOUT 6500
-
-/* Increase the scanning timeout because of increasing the SURVEY_TO value. */
-
-#define SCANNING_TIMEOUT 8000
-
-#define SCAN_INTERVAL (30) /* unit:2sec, 30*2 = 60sec */
-
-#define SCANQUEUE_LIFETIME 20 /* unit:sec */
-
-#define WIFI_NULL_STATE 0x00000000
-
-#define WIFI_ASOC_STATE 0x00000001 /* Under Linked state.*/
-#define WIFI_REASOC_STATE 0x00000002
-#define WIFI_SLEEP_STATE 0x00000004
-#define WIFI_STATION_STATE 0x00000008
-
-#define WIFI_AP_STATE 0x00000010
-#define WIFI_ADHOC_STATE 0x00000020
-#define WIFI_ADHOC_MASTER_STATE 0x00000040
-#define WIFI_UNDER_LINKING 0x00000080
-
-#define WIFI_UNDER_WPS 0x00000100
-#define WIFI_STA_ALIVE_CHK_STATE 0x00000400
-/* to indicate the station is under site surveying */
-#define WIFI_SITE_MONITOR 0x00000800
-
-#define WIFI_MP_STATE 0x00010000
-#define WIFI_MP_CTX_BACKGROUND 0x00020000 /* in continuous tx background */
-#define WIFI_MP_CTX_ST 0x00040000 /* in continuous tx with single-tone */
-#define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 /* pending in continuous tx background due to out of skb */
-#define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continuous tx */
-#define WIFI_MP_CTX_CCK_CS 0x00200000 /* in continuous tx with carrier suppression */
-#define WIFI_MP_LPBK_STATE 0x00400000
-
-#define _FW_UNDER_LINKING WIFI_UNDER_LINKING
-#define _FW_LINKED WIFI_ASOC_STATE
-#define _FW_UNDER_SURVEY WIFI_SITE_MONITOR
-
-
-enum dot11AuthAlgrthmNum {
- dot11AuthAlgrthm_Open = 0,
- dot11AuthAlgrthm_Shared,
- dot11AuthAlgrthm_8021X,
- dot11AuthAlgrthm_Auto,
- dot11AuthAlgrthm_MaxNum
-};
-
-/* Scan type including active and passive scan. */
-enum rt_scan_type {
- SCAN_PASSIVE,
- SCAN_ACTIVE,
- SCAN_MIX,
-};
-
-enum {
- GHZ24_50 = 0,
- GHZ_50,
- GHZ_24,
-};
-
-/*
-
-there are several "locks" in mlme_priv,
-since mlme_priv is a shared resource between many threads,
-like ISR/Call-Back functions, the OID handlers, and even timer functions.
-
-
-Each _queue has its own locks, already.
-Other items are protected by mlme_priv.lock.
-
-To avoid possible dead lock, any thread trying to modifiying mlme_priv
-SHALL not lock up more than one locks at a time!
-*/
-
-struct rt_link_detect {
- u32 NumTxOkInPeriod;
- u32 NumRxOkInPeriod;
- u32 NumRxUnicastOkInPeriod;
- bool bBusyTraffic;
- bool bTxBusyTraffic;
- bool bRxBusyTraffic;
- bool bHigherBusyTraffic; /* For interrupt migration purpose. */
- bool bHigherBusyRxTraffic; /* We may disable Tx interrupt according as Rx traffic. */
- bool bHigherBusyTxTraffic; /* We may disable Tx interrupt according as Tx traffic. */
-};
-
-struct mlme_priv {
- spinlock_t lock;
- int fw_state;
- u8 bScanInProcess;
- u8 to_join; /* flag */
- u8 to_roaming; /* roaming trying times */
-
- struct rtw_adapter *nic_hdl;
-
- u8 not_indic_disco;
- struct rtw_queue scanned_queue;
-
- struct cfg80211_ssid assoc_ssid;
- u8 assoc_bssid[6];
-
- struct wlan_network cur_network;
-
- /* uint wireless_mode; no used, remove it */
-
- u32 scan_interval;
-
- struct timer_list assoc_timer;
-
- uint assoc_by_bssid;
- uint assoc_by_rssi;
-
- struct timer_list scan_to_timer;
-
- struct timer_list set_scan_deny_timer;
- atomic_t set_scan_deny; /* 0: allowed, 1: deny */
-
- unsigned int qos_option;
-
- /* Number of non-HT AP/stations */
- int num_sta_no_ht;
-
- int num_FortyMHzIntolerant;
-
- struct ht_priv htpriv;
-
- struct rt_link_detect LinkDetectInfo;
- struct timer_list dynamic_chk_timer; /* dynamic/periodic check timer */
-
- u8 key_mask; /* use for ips to set wep key after ips_leave23a */
- u8 acm_mask; /* for wmm acm mask */
- u8 ChannelPlan;
- enum rt_scan_type scan_mode; /* active: 1, passive: 0 */
-
- u8 *wps_probe_req_ie;
- u32 wps_probe_req_ie_len;
- u8 *assoc_req;
- u32 assoc_req_len;
- u32 assoc_rsp_len;
- u8 *assoc_rsp;
-
-#ifdef CONFIG_8723AU_AP_MODE
- /* Number of associated Non-ERP stations (i.e., stations using 802.11b
- * in 802.11g BSS) */
- int num_sta_non_erp;
-
- /* Number of associated stations that do not support Short Slot Time */
- int num_sta_no_short_slot_time;
-
- /* Number of associated stations that do not support Short Preamble */
- int num_sta_no_short_preamble;
-
- int olbc; /* Overlapping Legacy BSS Condition */
-
- /* Number of HT associated stations that do not support greenfield */
- int num_sta_ht_no_gf;
-
- /* Number of associated non-HT stations */
- /* int num_sta_no_ht; */
-
- /* Number of HT associated stations 20 MHz */
- int num_sta_ht_20mhz;
-
- /* Overlapping BSS information */
- int olbc_ht;
-
- u16 ht_op_mode;
-
- spinlock_t bcn_update_lock;
- u8 update_bcn;
-
-#endif /* ifdef CONFIG_8723AU_AP_MODE */
-};
-
-void rtw_joinbss_event_prehandle23a(struct rtw_adapter *adapter, u8 *pbuf);
-void rtw_survey_event_cb23a(struct rtw_adapter *adapter, const u8 *pbuf);
-void rtw_surveydone_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf);
-void rtw23a_joinbss_event_cb(struct rtw_adapter *adapter, const u8 *pbuf);
-void rtw_stassoc_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf);
-void rtw_stadel_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf);
-
-int event_thread(void *context);
-void rtw23a_join_to_handler(unsigned long);
-
-void rtw_free_network_queue23a(struct rtw_adapter *adapter);
-int rtw_init_mlme_priv23a(struct rtw_adapter *adapter);
-
-void rtw_free_mlme_priv23a(struct mlme_priv *pmlmepriv);
-
-int rtw_do_join_adhoc(struct rtw_adapter *adapter);
-int rtw_do_join_network(struct rtw_adapter *adapter,
- struct wlan_network *candidate);
-int rtw_select_and_join_from_scanned_queue23a(struct mlme_priv *pmlmepriv);
-int rtw_set_key23a(struct rtw_adapter *adapter,
- struct security_priv *psecuritypriv, int keyid, u8 set_tx);
-int rtw_set_auth23a(struct rtw_adapter *adapter,
- struct security_priv *psecuritypriv);
-
-static inline u8 *get_bssid(struct mlme_priv *pmlmepriv)
-{ /* if sta_mode:pmlmepriv->cur_network.network.MacAddress => bssid */
- /* if adhoc_mode:pmlmepriv->cur_network.network.MacAddress => ibss mac address */
- return pmlmepriv->cur_network.network.MacAddress;
-}
-
-static inline bool check_fwstate(struct mlme_priv *pmlmepriv, int state)
-{
- if (pmlmepriv->fw_state & state)
- return true;
-
- return false;
-}
-
-static inline int get_fwstate(struct mlme_priv *pmlmepriv)
-{
- return pmlmepriv->fw_state;
-}
-
-/*
- * No Limit on the calling context,
- * therefore set it to be the critical section...
- *
- * ### NOTE:#### (!!!!)
- * MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock
- */
-static inline void set_fwstate(struct mlme_priv *pmlmepriv, int state)
-{
- pmlmepriv->fw_state |= state;
- /* FOR HW integration */
- if (_FW_UNDER_SURVEY == state)
- pmlmepriv->bScanInProcess = true;
-}
-
-static inline void _clr_fwstate_(struct mlme_priv *pmlmepriv, int state)
-{
- pmlmepriv->fw_state &= ~state;
- /* FOR HW integration */
- if (_FW_UNDER_SURVEY == state)
- pmlmepriv->bScanInProcess = false;
-}
-
-/*
- * No Limit on the calling context,
- * therefore set it to be the critical section...
- */
-static inline void clr_fwstate(struct mlme_priv *pmlmepriv, int state)
-{
- spin_lock_bh(&pmlmepriv->lock);
- if (check_fwstate(pmlmepriv, state))
- pmlmepriv->fw_state ^= state;
- spin_unlock_bh(&pmlmepriv->lock);
-}
-
-static inline void clr_fwstate_ex(struct mlme_priv *pmlmepriv, int state)
-{
- spin_lock_bh(&pmlmepriv->lock);
- _clr_fwstate_(pmlmepriv, state);
- spin_unlock_bh(&pmlmepriv->lock);
-}
-
-void rtw_disconnect_hdl23a_under_linked(struct rtw_adapter *adapter,
- struct sta_info *psta, u8 free_assoc);
-void rtw_generate_random_ibss23a(u8 *pibss);
-struct wlan_network *rtw_find_network23a(struct rtw_queue *scanned_queue, u8 *addr);
-struct wlan_network *rtw_get_oldest_wlan_network23a(struct rtw_queue *scanned_queue);
-
-void rtw_free_assoc_resources23a(struct rtw_adapter *adapter,
- int lock_scanned_queue);
-void rtw_indicate_disconnect23a(struct rtw_adapter *adapter);
-void rtw_indicate_connect23a(struct rtw_adapter *adapter);
-void rtw_scan_abort23a(struct rtw_adapter *adapter);
-
-int rtw_restruct_sec_ie23a(struct rtw_adapter *adapter, u8 *in_ie, u8 *out_ie,
- uint in_len);
-int rtw_restruct_wmm_ie23a(struct rtw_adapter *adapter, u8 *in_ie, u8 *out_ie,
- uint in_len, uint initial_out_len);
-void rtw_init_registrypriv_dev_network23a(struct rtw_adapter *adapter);
-
-void rtw_update_registrypriv_dev_network23a(struct rtw_adapter *adapter);
-
-void rtw_scan_timeout_handler23a(unsigned long data);
-
-void rtw_dynamic_check_timer_handler(unsigned long data);
-bool rtw_is_scan_deny(struct rtw_adapter *adapter);
-void rtw_clear_scan_deny(struct rtw_adapter *adapter);
-void rtw_set_scan_deny_timer_hdl(unsigned long data);
-void rtw_set_scan_deny(struct rtw_adapter *adapter, u32 ms);
-
-void rtw23a_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv);
-
-void _rtw_free_mlme_priv23a(struct mlme_priv *pmlmepriv);
-
-struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv, gfp_t gfp);
-
-int rtw_if_up23a(struct rtw_adapter *padapter);
-
-int rtw_linked_check(struct rtw_adapter *padapter);
-
-void rtw_joinbss_reset23a(struct rtw_adapter *padapter);
-
-bool rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie,
- u8 *out_ie, uint in_len, uint *pout_len);
-void rtw_update_ht_cap23a(struct rtw_adapter *padapter,
- u8 *pie, uint ie_len);
-void rtw_issue_addbareq_cmd23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe);
-
-bool rtw_is_same_ibss23a(struct rtw_adapter *adapter,
- struct wlan_network *pnetwork);
-int is_same_network23a(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst);
-
-void rtw23a_roaming(struct rtw_adapter *adapter,
- struct wlan_network *tgt_network);
-void rtw_set_roaming(struct rtw_adapter *adapter, u8 to_roaming);
-
-#endif /* __RTL871X_MLME_H_ */
diff --git a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h b/drivers/staging/rtl8723au/include/rtw_mlme_ext.h
deleted file mode 100644
index 0e7d3da91471..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h
+++ /dev/null
@@ -1,683 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTW_MLME_EXT_H_
-#define __RTW_MLME_EXT_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <wlan_bssdef.h>
-
-
-/* Commented by Albert 20101105 */
-/* Increase the SURVEY_TO value from 100 to 150 ( 100ms to 150ms ) */
-/* The Realtek 8188CE SoftAP will spend around 100ms to send the probe response after receiving the probe request. */
-/* So, this driver tried to extend the dwell time for each scanning channel. */
-/* This will increase the chance to receive the probe response from SoftAP. */
-
-#define SURVEY_TO (100)
-#define REAUTH_TO (300) /* 50) */
-#define REASSOC_TO (300) /* 50) */
-/* define DISCONNECT_TO (3000) */
-#define ADDBA_TO (2000)
-
-#define LINKED_TO (1) /* unit:2 sec, 1x2=2 sec */
-
-#define REAUTH_LIMIT (4)
-#define REASSOC_LIMIT (4)
-#define READDBA_LIMIT (2)
-
-#define ROAMING_LIMIT 8
-
-#define DYNAMIC_FUNC_DISABLE (0x0)
-
-/* ====== enum odm_ability ======== */
-/* BB ODM section BIT 0-15 */
-#define DYNAMIC_BB_DIG BIT(0)
-#define DYNAMIC_BB_RA_MASK BIT(1)
-#define DYNAMIC_BB_DYNAMIC_TXPWR BIT(2)
-#define DYNAMIC_BB_BB_FA_CNT BIT(3)
-
-#define DYNAMIC_BB_RSSI_MONITOR BIT(4)
-#define DYNAMIC_BB_CCK_PD BIT(5)
-#define DYNAMIC_BB_ANT_DIV BIT(6)
-#define DYNAMIC_BB_PWR_SAVE BIT(7)
-#define DYNAMIC_BB_PWR_TRAIN BIT(8)
-#define DYNAMIC_BB_RATE_ADAPTIVE BIT(9)
-#define DYNAMIC_BB_PATH_DIV BIT(10)
-#define DYNAMIC_BB_PSD BIT(11)
-
-/* MAC DM section BIT 16-23 */
-#define DYNAMIC_MAC_struct edca_turboURBO BIT(16)
-#define DYNAMIC_MAC_EARLY_MODE BIT(17)
-
-/* RF ODM section BIT 24-31 */
-#define DYNAMIC_RF_TX_PWR_TRACK BIT(24)
-#define DYNAMIC_RF_RX_GAIN_TRACK BIT(25)
-#define DYNAMIC_RF_CALIBRATION BIT(26)
-
-#define DYNAMIC_ALL_FUNC_ENABLE 0xFFFFFFF
-
-#define _HW_STATE_NOLINK_ 0x00
-#define _HW_STATE_ADHOC_ 0x01
-#define _HW_STATE_STATION_ 0x02
-#define _HW_STATE_AP_ 0x03
-
-
-#define _1M_RATE_ 0
-#define _2M_RATE_ 1
-#define _5M_RATE_ 2
-#define _11M_RATE_ 3
-#define _6M_RATE_ 4
-#define _9M_RATE_ 5
-#define _12M_RATE_ 6
-#define _18M_RATE_ 7
-#define _24M_RATE_ 8
-#define _36M_RATE_ 9
-#define _48M_RATE_ 10
-#define _54M_RATE_ 11
-
-
-extern unsigned char WMM_OUI23A[];
-extern unsigned char WPS_OUI23A[];
-extern unsigned char WFD_OUI23A[];
-extern unsigned char P2P_OUI23A[];
-
-extern unsigned char WMM_INFO_OUI23A[];
-extern unsigned char WMM_PARA_OUI23A[];
-
-
-/* */
-/* Channel Plan Type. */
-/* Note: */
-/* We just add new channel plan when the new channel plan is different from any of the following */
-/* channel plan. */
-/* If you just want to customize the actions(scan period or join actions) about one of the channel plan, */
-/* customize them in struct rt_channel_info in the RT_CHANNEL_LIST. */
-/* */
-enum { /* _RT_CHANNEL_DOMAIN */
- /* old channel plan mapping ===== */
- RT_CHANNEL_DOMAIN_FCC = 0x00,
- RT_CHANNEL_DOMAIN_IC = 0x01,
- RT_CHANNEL_DOMAIN_ETSI = 0x02,
- RT_CHANNEL_DOMAIN_SPAIN = 0x03,
- RT_CHANNEL_DOMAIN_FRANCE = 0x04,
- RT_CHANNEL_DOMAIN_MKK = 0x05,
- RT_CHANNEL_DOMAIN_MKK1 = 0x06,
- RT_CHANNEL_DOMAIN_ISRAEL = 0x07,
- RT_CHANNEL_DOMAIN_TELEC = 0x08,
- RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN = 0x09,
- RT_CHANNEL_DOMAIN_WORLD_WIDE_13 = 0x0A,
- RT_CHANNEL_DOMAIN_TAIWAN = 0x0B,
- RT_CHANNEL_DOMAIN_CHINA = 0x0C,
- RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO = 0x0D,
- RT_CHANNEL_DOMAIN_KOREA = 0x0E,
- RT_CHANNEL_DOMAIN_TURKEY = 0x0F,
- RT_CHANNEL_DOMAIN_JAPAN = 0x10,
- RT_CHANNEL_DOMAIN_FCC_NO_DFS = 0x11,
- RT_CHANNEL_DOMAIN_JAPAN_NO_DFS = 0x12,
- RT_CHANNEL_DOMAIN_WORLD_WIDE_5G = 0x13,
- RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS = 0x14,
-
- /* new channel plan mapping, (2GDOMAIN_5GDOMAIN) ===== */
- RT_CHANNEL_DOMAIN_WORLD_NULL = 0x20,
- RT_CHANNEL_DOMAIN_ETSI1_NULL = 0x21,
- RT_CHANNEL_DOMAIN_FCC1_NULL = 0x22,
- RT_CHANNEL_DOMAIN_MKK1_NULL = 0x23,
- RT_CHANNEL_DOMAIN_ETSI2_NULL = 0x24,
- RT_CHANNEL_DOMAIN_FCC1_FCC1 = 0x25,
- RT_CHANNEL_DOMAIN_WORLD_ETSI1 = 0x26,
- RT_CHANNEL_DOMAIN_MKK1_MKK1 = 0x27,
- RT_CHANNEL_DOMAIN_WORLD_KCC1 = 0x28,
- RT_CHANNEL_DOMAIN_WORLD_FCC2 = 0x29,
- RT_CHANNEL_DOMAIN_WORLD_FCC3 = 0x30,
- RT_CHANNEL_DOMAIN_WORLD_FCC4 = 0x31,
- RT_CHANNEL_DOMAIN_WORLD_FCC5 = 0x32,
- RT_CHANNEL_DOMAIN_WORLD_FCC6 = 0x33,
- RT_CHANNEL_DOMAIN_FCC1_FCC7 = 0x34,
- RT_CHANNEL_DOMAIN_WORLD_ETSI2 = 0x35,
- RT_CHANNEL_DOMAIN_WORLD_ETSI3 = 0x36,
- RT_CHANNEL_DOMAIN_MKK1_MKK2 = 0x37,
- RT_CHANNEL_DOMAIN_MKK1_MKK3 = 0x38,
- RT_CHANNEL_DOMAIN_FCC1_NCC1 = 0x39,
- RT_CHANNEL_DOMAIN_FCC1_NCC2 = 0x40,
- RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G = 0x41,
- /* Add new channel plan above this line=============== */
- RT_CHANNEL_DOMAIN_MAX,
- RT_CHANNEL_DOMAIN_REALTEK_DEFINE = 0x7F,
-};
-
-enum { /* _RT_CHANNEL_DOMAIN_2G */
- RT_CHANNEL_DOMAIN_2G_WORLD = 0x00, /* Worldwird 13 */
- RT_CHANNEL_DOMAIN_2G_ETSI1 = 0x01, /* Europe */
- RT_CHANNEL_DOMAIN_2G_FCC1 = 0x02, /* US */
- RT_CHANNEL_DOMAIN_2G_MKK1 = 0x03, /* Japan */
- RT_CHANNEL_DOMAIN_2G_ETSI2 = 0x04, /* France */
- RT_CHANNEL_DOMAIN_2G_NULL = 0x05,
- /* Add new channel plan above this line=============== */
- RT_CHANNEL_DOMAIN_2G_MAX,
-};
-
-enum { /* _RT_CHANNEL_DOMAIN_5G */
- RT_CHANNEL_DOMAIN_5G_NULL = 0x00,
- RT_CHANNEL_DOMAIN_5G_ETSI1 = 0x01, /* Europe */
- RT_CHANNEL_DOMAIN_5G_ETSI2 = 0x02, /* Australia, New Zealand */
- RT_CHANNEL_DOMAIN_5G_ETSI3 = 0x03, /* Russia */
- RT_CHANNEL_DOMAIN_5G_FCC1 = 0x04, /* US */
- RT_CHANNEL_DOMAIN_5G_FCC2 = 0x05, /* FCC o/w DFS Channels */
- RT_CHANNEL_DOMAIN_5G_FCC3 = 0x06, /* India, Mexico */
- RT_CHANNEL_DOMAIN_5G_FCC4 = 0x07, /* Venezuela */
- RT_CHANNEL_DOMAIN_5G_FCC5 = 0x08, /* China */
- RT_CHANNEL_DOMAIN_5G_FCC6 = 0x09, /* Israel */
- RT_CHANNEL_DOMAIN_5G_FCC7_IC1 = 0x0A, /* US, Canada */
- RT_CHANNEL_DOMAIN_5G_KCC1 = 0x0B, /* Korea */
- RT_CHANNEL_DOMAIN_5G_MKK1 = 0x0C, /* Japan */
- RT_CHANNEL_DOMAIN_5G_MKK2 = 0x0D, /* Japan (W52, W53) */
- RT_CHANNEL_DOMAIN_5G_MKK3 = 0x0E, /* Japan (W56) */
- RT_CHANNEL_DOMAIN_5G_NCC1 = 0x0F, /* Taiwan */
- RT_CHANNEL_DOMAIN_5G_NCC2 = 0x10, /* Taiwan o/w DFS */
- /* Add new channel plan above this line=============== */
- /* Driver Self Defined ===== */
- RT_CHANNEL_DOMAIN_5G_FCC = 0x11,
- RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS = 0x12,
- RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS = 0x13,
- RT_CHANNEL_DOMAIN_5G_MAX,
-};
-
-#define rtw_is_channel_plan_valid(chplan) (chplan<RT_CHANNEL_DOMAIN_MAX || chplan == RT_CHANNEL_DOMAIN_REALTEK_DEFINE)
-
-struct rt_channel_plan {
- unsigned char Channel[MAX_CHANNEL_NUM];
- unsigned char Len;
-};
-
-struct rt_channel_plan_2g {
- unsigned char Channel[MAX_CHANNEL_NUM_2G];
- unsigned char Len;
-};
-
-struct rt_channel_plan_5g {
- unsigned char Channel[MAX_CHANNEL_NUM_5G];
- unsigned char Len;
-};
-
-struct rt_channel_plan_map {
- unsigned char Index2G;
- unsigned char Index5G;
-};
-
-enum Associated_AP {
- atherosAP = 0,
- broadcomAP = 1,
- ciscoAP = 2,
- marvellAP = 3,
- ralinkAP = 4,
- realtekAP = 5,
- airgocapAP = 6,
- unknownAP = 7,
- maxAP,
-};
-
-enum { /* HT_IOT_PEER_E */
- HT_IOT_PEER_UNKNOWN = 0,
- HT_IOT_PEER_REALTEK = 1,
- HT_IOT_PEER_REALTEK_92SE = 2,
- HT_IOT_PEER_BROADCOM = 3,
- HT_IOT_PEER_RALINK = 4,
- HT_IOT_PEER_ATHEROS = 5,
- HT_IOT_PEER_CISCO = 6,
- HT_IOT_PEER_MERU = 7,
- HT_IOT_PEER_MARVELL = 8,
- HT_IOT_PEER_REALTEK_SOFTAP = 9,/* peer is RealTek SOFT_AP, by Bohn, 2009.12.17 */
- HT_IOT_PEER_SELF_SOFTAP = 10, /* Self is SoftAP */
- HT_IOT_PEER_AIRGO = 11,
- HT_IOT_PEER_INTEL = 12,
- HT_IOT_PEER_RTK_APCLIENT = 13,
- HT_IOT_PEER_REALTEK_81XX = 14,
- HT_IOT_PEER_REALTEK_WOW = 15,
- HT_IOT_PEER_TENDA = 16,
- HT_IOT_PEER_MAX = 17
-};
-
-enum SCAN_STATE {
- SCAN_DISABLE = 0,
- SCAN_START = 1,
- SCAN_TXNULL = 2,
- SCAN_PROCESS = 3,
- SCAN_COMPLETE = 4,
- SCAN_STATE_MAX,
-};
-
-struct mlme_handler {
- char *str;
- int (*func)(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-};
-
-struct action_handler {
- unsigned int num;
- char *str;
- int (*func)(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
-};
-
-struct ss_res {
- int state;
- int bss_cnt;
- int channel_idx;
- int scan_mode;
- u8 ssid_num;
- u8 ch_num;
- struct cfg80211_ssid ssid[RTW_SSID_SCAN_AMOUNT];
- struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
-};
-
-#define WIFI_FW_AUTH_NULL 0x00000100
-#define WIFI_FW_AUTH_STATE 0x00000200
-#define WIFI_FW_AUTH_SUCCESS 0x00000400
-
-#define WIFI_FW_ASSOC_STATE 0x00002000
-#define WIFI_FW_ASSOC_SUCCESS 0x00004000
-
-#define WIFI_FW_LINKING_STATE (WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE | WIFI_FW_AUTH_SUCCESS |WIFI_FW_ASSOC_STATE)
-
-struct FW_Sta_Info {
- struct sta_info *psta;
- u32 status;
- u32 rx_pkt;
- u32 retry;
- unsigned char SupportedRates[NDIS_802_11_LENGTH_RATES_EX];
-};
-
-/*
- * Usage:
- * When one iface acted as AP mode and the other iface is STA mode and scanning,
- * it should switch back to AP's operating channel periodically.
- * Parameters info:
- * When the driver scanned RTW_SCAN_NUM_OF_CH channels, it would switch back to AP's operating channel for
- * RTW_STAY_AP_CH_MILLISECOND * SURVEY_TO milliseconds.
- * Example:
- * For chip supports 2.4G + 5GHz and AP mode is operating in channel 1,
- * RTW_SCAN_NUM_OF_CH is 8, RTW_STAY_AP_CH_MILLISECOND is 3 and SURVEY_TO is 100.
- * When it's STA mode gets set_scan command,
- * it would
- * 1. Doing the scan on channel 1.2.3.4.5.6.7.8
- * 2. Back to channel 1 for 300 milliseconds
- * 3. Go through doing site survey on channel 9.10.11.36.40.44.48.52
- * 4. Back to channel 1 for 300 milliseconds
- * 5. ... and so on, till survey done.
- */
-
-struct mlme_ext_info {
- u32 state;
- u32 reauth_count;
- u32 reassoc_count;
- u32 link_count;
- u32 auth_seq;
- u32 auth_algo; /* 802.11 auth, could be open, shared, auto */
- u32 authModeToggle;
- u32 enc_algo;/* encrypt algorithm; */
- u32 key_index; /* this is only valid for legendary wep, 0~3 for key id. */
- u32 iv;
- u8 chg_txt[128];
- u16 aid;
- u16 bcn_interval;
- u16 capability;
- u8 assoc_AP_vendor;
- u8 slotTime;
- u8 preamble_mode;
- u8 WMM_enable;
- u8 ERP_enable;
- u8 ERP_IE;
- u8 HT_enable;
- u8 HT_caps_enable;
- u8 HT_info_enable;
- u8 HT_protection;
- u8 turboMode_cts2self;
- u8 turboMode_rtsen;
- u8 SM_PS;
- u8 ADDBA_retry_count;
- u8 dialogToken;
- /* Accept ADDBA Request */
- bool bAcceptAddbaReq;
- u8 bwmode_updated;
- u8 hidden_ssid_mode;
-
- struct ADDBA_request ADDBA_req;
- struct WMM_para_element WMM_param;
- struct ieee80211_ht_cap ht_cap;
- struct ieee80211_ht_operation HT_info;
- struct wlan_bssid_ex network;/* join network or bss_network, if in ap mode, it is the same to cur_network.network */
- struct FW_Sta_Info FW_sta_info[NUM_STA];
-};
-
-/* The channel information about this channel including joining, scanning, and power constraints. */
-struct rt_channel_info {
- u8 ChannelNum; /* The channel number. */
- enum rt_scan_type ScanType; /* Scan type such as passive or active scan. */
-};
-
-int rtw_ch_set_search_ch23a(struct rt_channel_info *ch_set, const u32 ch);
-
-/* P2P_MAX_REG_CLASSES - Maximum number of regulatory classes */
-#define P2P_MAX_REG_CLASSES 10
-
-/* P2P_MAX_REG_CLASS_CHANNELS - Maximum number of channels per regulatory class */
-#define P2P_MAX_REG_CLASS_CHANNELS 20
-
-/* struct p2p_channels - List of supported channels */
-struct p2p_channels {
- /* struct p2p_reg_class - Supported regulatory class */
- struct p2p_reg_class {
- /* reg_class - Regulatory class (IEEE 802.11-2007, Annex J) */
- u8 reg_class;
-
- /* channel - Supported channels */
- u8 channel[P2P_MAX_REG_CLASS_CHANNELS];
-
- /* channels - Number of channel entries in use */
- size_t channels;
- } reg_class[P2P_MAX_REG_CLASSES];
-
- /* reg_classes - Number of reg_class entries in use */
- size_t reg_classes;
-};
-
-struct p2p_oper_class_map {
- enum hw_mode {IEEE80211G, IEEE80211A} mode;
- u8 op_class;
- u8 min_chan;
- u8 max_chan;
- u8 inc;
- enum {
- BW20, BW40PLUS, BW40MINUS
- } bw;
-};
-
-struct mlme_ext_priv {
- struct rtw_adapter *padapter;
- u8 mlmeext_init;
- atomic_t event_seq;
- u16 mgnt_seq;
-
- /* struct fw_priv fwpriv; */
-
- unsigned char cur_channel;
- unsigned char cur_bwmode;
- unsigned char cur_ch_offset;/* PRIME_CHNL_OFFSET */
- unsigned char cur_wireless_mode; /* NETWORK_TYPE */
-
- unsigned char max_chan_nums;
- struct rt_channel_info channel_set[MAX_CHANNEL_NUM];
- struct p2p_channels channel_list;
- unsigned char basicrate[NumRates];
- unsigned char datarate[NumRates];
-
- struct ss_res sitesurvey_res;
- struct mlme_ext_info mlmext_info;/* for sta/adhoc mode, including current scanning/connecting/connected related info. */
- /* for ap mode, network includes ap's cap_info */
- struct timer_list survey_timer;
- struct timer_list link_timer;
- u16 chan_scan_time;
-
- u8 scan_abort;
- u8 tx_rate; /* TXRATE when USERATE is set. */
-
- u32 retry; /* retry for issue probereq */
-
- u64 TSFValue;
-
- unsigned char bstart_bss;
- u8 update_channel_plan_by_ap_done;
- /* recv_decache check for Action_public frame */
- u8 action_public_dialog_token;
- u16 action_public_rxseq;
- u8 active_keep_alive_check;
-};
-
-int init_mlme_ext_priv23a(struct rtw_adapter *padapter);
-int init_hw_mlme_ext23a(struct rtw_adapter *padapter);
-void free_mlme_ext_priv23a (struct mlme_ext_priv *pmlmeext);
-void init_mlme_ext_timer23a(struct rtw_adapter *padapter);
-void init_addba_retry_timer23a(struct sta_info *psta);
-struct xmit_frame *alloc_mgtxmitframe23a(struct xmit_priv *pxmitpriv);
-
-unsigned char networktype_to_raid23a(unsigned char network_type);
-u8 judge_network_type23a(struct rtw_adapter *padapter, unsigned char *rate,
- int ratelen);
-void get_rate_set23a(struct rtw_adapter *padapter, unsigned char *pbssrate,
- int *bssrate_len);
-void UpdateBrateTbl23a(struct rtw_adapter *padapter, u8 *mBratesOS);
-void Update23aTblForSoftAP(u8 *bssrateset, u32 bssratelen);
-
-u8 rtw_get_oper_ch23a(struct rtw_adapter *adapter);
-void rtw_set_oper_ch23a(struct rtw_adapter *adapter, u8 ch);
-void rtw_set_oper_bw23a(struct rtw_adapter *adapter, u8 bw);
-void rtw_set_oper_ch23aoffset23a(struct rtw_adapter *adapter, u8 offset);
-
-void set_channel_bwmode23a(struct rtw_adapter *padapter, unsigned char channel,
- unsigned char channel_offset, unsigned short bwmode);
-void SelectChannel23a(struct rtw_adapter *padapter, unsigned char channel);
-
-unsigned int decide_wait_for_beacon_timeout23a(unsigned int bcn_interval);
-
-void clear_cam_entry23a(struct rtw_adapter *padapter, u8 entry);
-
-void invalidate_cam_all23a(struct rtw_adapter *padapter);
-
-int allocate_fw_sta_entry23a(struct rtw_adapter *padapter);
-void flush_all_cam_entry23a(struct rtw_adapter *padapter);
-
-bool IsLegal5GChannel(struct rtw_adapter *Adapter, u8 channel);
-
-void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
- struct rtw_adapter *padapter, bool update_ie);
-
-u8 *get_my_bssid23a(struct wlan_bssid_ex *pnetwork);
-
-bool is_client_associated_to_ap23a(struct rtw_adapter *padapter);
-bool is_client_associated_to_ibss23a(struct rtw_adapter *padapter);
-bool is_IBSS_empty23a(struct rtw_adapter *padapter);
-
-unsigned char check_assoc_AP23a(u8 *pframe, uint len);
-
-int WMM_param_handler23a(struct rtw_adapter *padapter, const u8 *p);
-void WMMOnAssocRsp23a(struct rtw_adapter *padapter);
-
-void HT_caps_handler23a(struct rtw_adapter *padapter, const u8 *p);
-void HT_info_handler23a(struct rtw_adapter *padapter, const u8 *p);
-void HTOnAssocRsp23a(struct rtw_adapter *padapter);
-
-void ERP_IE_handler23a(struct rtw_adapter *padapter, const u8 *p);
-void VCS_update23a(struct rtw_adapter *padapter, struct sta_info *psta);
-
-void update_beacon23a_info(struct rtw_adapter *padapter,
- struct ieee80211_mgmt *mgmt, uint len,
- struct sta_info *psta);
-int rtw_check_bcn_info23a(struct rtw_adapter *Adapter,
- struct ieee80211_mgmt *mgmt, u32 packet_len);
-void update_IOT_info23a(struct rtw_adapter *padapter);
-void update_capinfo23a(struct rtw_adapter *Adapter, u16 updateCap);
-void update_wireless_mode23a(struct rtw_adapter *padapter);
-void update_tx_basic_rate23a(struct rtw_adapter *padapter, u8 modulation);
-void update_bmc_sta_support_rate23a(struct rtw_adapter *padapter, u32 mac_id);
-int update_sta_support_rate23a(struct rtw_adapter *padapter, u8 *pvar_ie,
- uint var_ie_len, int cam_idx);
-
-/* for sta/adhoc mode */
-void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta);
-unsigned int update_basic_rate23a(unsigned char *ptn, unsigned int ptn_sz);
-unsigned int update_supported_rate23a(unsigned char *ptn, unsigned int ptn_sz);
-unsigned int update_MSC_rate23a(struct ieee80211_ht_cap *ht_cap);
-void Update_RA_Entry23a(struct rtw_adapter *padapter, struct sta_info *psta);
-void set_sta_rate23a(struct rtw_adapter *padapter, struct sta_info *psta);
-
-int receive_disconnect23a(struct rtw_adapter *padapter,
- unsigned char *MacAddr, unsigned short reason);
-
-unsigned char get_highest_rate_idx23a(u32 mask);
-int support_short_GI23a(struct rtw_adapter *padapter,
- struct ieee80211_ht_cap *ht_cap);
-bool is_ap_in_tkip23a(struct rtw_adapter *padapter);
-bool is_ap_in_wep23a(struct rtw_adapter *padapter);
-bool should_forbid_n_rate23a(struct rtw_adapter *padapter);
-
-void report_join_res23a(struct rtw_adapter *padapter, int res);
-void report_survey_event23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame);
-void report_surveydone_event23a(struct rtw_adapter *padapter);
-void report_del_sta_event23a(struct rtw_adapter *padapter,
- unsigned char *MacAddr, unsigned short reason);
-void report_add_sta_event23a(struct rtw_adapter *padapter,
- unsigned char *MacAddr, int cam_idx);
-
-int set_tx_beacon_cmd23a(struct rtw_adapter*padapter);
-unsigned int setup_beacon_frame(struct rtw_adapter *padapter,
- unsigned char *beacon_frame);
-void update_mgnt_tx_rate23a(struct rtw_adapter *padapter, u8 rate);
-void update_mgntframe_attrib23a(struct rtw_adapter *padapter,
- struct pkt_attrib *pattrib);
-void dump_mgntframe23a(struct rtw_adapter *padapter,
- struct xmit_frame *pmgntframe);
-s32 dump_mgntframe23a_and_wait(struct rtw_adapter *padapter,
- struct xmit_frame *pmgntframe, int timeout_ms);
-s32 dump_mgntframe23a_and_wait_ack23a(struct rtw_adapter *padapter,
- struct xmit_frame *pmgntframe);
-
-void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms);
-int issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
- unsigned int power_mode, int try_cnt, int wait_ms);
-int issue_qos_nulldata23a(struct rtw_adapter *padapter, unsigned char *da, u16 tid,
- int try_cnt, int wait_ms);
-int issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
- unsigned short reason);
-void issue_action_spct_ch_switch23a(struct rtw_adapter *padapter, u8 *ra,
- u8 new_ch, u8 ch_offset);
-void issue_action_BA23a(struct rtw_adapter *padapter,
- const unsigned char *raddr,
- unsigned char action, unsigned short status);
-int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr);
-int send_beacon23a(struct rtw_adapter *padapter);
-
-void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, int join_res);
-void mlmeext_sta_del_event_callback23a(struct rtw_adapter *padapter);
-void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter, struct sta_info *psta);
-
-void linked_status_chk23a(struct rtw_adapter *padapter);
-
-#define set_survey_timer(mlmeext, ms) \
- /*DBG_8723A("%s set_survey_timer(%p, %d)\n", __func__, (mlmeext), (ms));*/ \
- mod_timer(&mlmeext->survey_timer, jiffies + msecs_to_jiffies(ms));
-
-#define set_link_timer(mlmeext, ms) \
- /*DBG_8723A("%s set_link_timer(%p, %d)\n", __func__, (mlmeext), (ms));*/ \
- mod_timer(&mlmeext->link_timer, jiffies + msecs_to_jiffies(ms));
-
-int cckrates_included23a(unsigned char *rate, int ratelen);
-int cckratesonly_included23a(unsigned char *rate, int ratelen);
-
-void process_addba_req23a(struct rtw_adapter *padapter, u8 *paddba_req, u8 *addr);
-
-void correct_TSF23a(struct rtw_adapter *padapter, struct mlme_ext_priv *pmlmeext);
-
-struct cmd_hdl {
- uint parmsize;
- int (*h2cfuns)(struct rtw_adapter *padapter, const u8 *pbuf);
-};
-
-
-int read_macreg_hdl(struct rtw_adapter *padapter, u8 *pbuf);
-int write_macreg_hdl(struct rtw_adapter *padapter, u8 *pbuf);
-int read_bbreg_hdl(struct rtw_adapter *padapter, u8 *pbuf);
-int write_bbreg_hdl(struct rtw_adapter *padapter, u8 *pbuf);
-int read_rfreg_hdl(struct rtw_adapter *padapter, u8 *pbuf);
-int write_rfreg_hdl(struct rtw_adapter *padapter, u8 *pbuf);
-
-
-int NULL_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int createbss_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int setauth_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int setkey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int set_stakey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int set_assocsta_hdl(struct rtw_adapter *padapter, const u8 *pbuf);
-int del_assocsta_hdl(struct rtw_adapter *padapter, const u8 *pbuf);
-int add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-
-int mlme_evt_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int h2c_msg_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int tx_beacon_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-int set_csa_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf); /* Kurt: Handling DFS channel switch announcement ie. */
-int tdls_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf);
-
-#define GEN_DRV_CMD_HANDLER(size, cmd) {size, &cmd ## _hdl23a},
-#define GEN_MLME_EXT_HANDLER(size, cmd) {size, cmd},
-
-struct C2HEvent_Header {
-#ifdef __LITTLE_ENDIAN
-
- unsigned int len:16;
- unsigned int ID:8;
- unsigned int seq:8;
-
-#elif defined(__BIG_ENDIAN)
-
- unsigned int seq:8;
- unsigned int ID:8;
- unsigned int len:16;
-
-#else
-
-# error "Must be LITTLE or BIG Endian"
-
-#endif
-
- unsigned int rsvd;
-};
-
-enum rtw_c2h_event {
- GEN_EVT_CODE(_Read_MACREG) = 0, /*0*/
- GEN_EVT_CODE(_Read_BBREG),
- GEN_EVT_CODE(_Read_RFREG),
- GEN_EVT_CODE(_Read_EEPROM),
- GEN_EVT_CODE(_Read_EFUSE),
- GEN_EVT_CODE(_Read_CAM), /*5*/
- GEN_EVT_CODE(_Get_BasicRate),
- GEN_EVT_CODE(_Get_DataRate),
- GEN_EVT_CODE(_Survey), /*8*/
- GEN_EVT_CODE(_SurveyDone), /*9*/
-
- GEN_EVT_CODE(_JoinBss) , /*10*/
- GEN_EVT_CODE(_AddSTA),
- GEN_EVT_CODE(_DelSTA),
- GEN_EVT_CODE(_AtimDone) ,
- GEN_EVT_CODE(_TX_Report),
- GEN_EVT_CODE(_CCX_Report), /*15*/
- GEN_EVT_CODE(_DTM_Report),
- GEN_EVT_CODE(_TX_Rate_Statistics),
- GEN_EVT_CODE(_C2HLBK),
- GEN_EVT_CODE(_FWDBG),
- GEN_EVT_CODE(_C2HFEEDBACK), /*20*/
- GEN_EVT_CODE(_ADDBA),
- GEN_EVT_CODE(_C2HBCN),
- GEN_EVT_CODE(_ReportPwrState), /* filen: only for PCIE, USB */
- GEN_EVT_CODE(_CloseRF), /* filen: only for PCIE, work around ASPM */
- MAX_C2HEVT
-};
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtw_pwrctrl.h b/drivers/staging/rtl8723au/include/rtw_pwrctrl.h
deleted file mode 100644
index 599fed9b365d..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_pwrctrl.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTW_PWRCTRL_H_
-#define __RTW_PWRCTRL_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-#define FW_PWR0 0
-#define FW_PWR1 1
-#define FW_PWR2 2
-#define FW_PWR3 3
-
-
-#define HW_PWR0 7
-#define HW_PWR1 6
-#define HW_PWR2 2
-#define HW_PWR3 0
-#define HW_PWR4 8
-
-#define FW_PWRMSK 0x7
-
-
-#define XMIT_ALIVE BIT(0)
-#define RECV_ALIVE BIT(1)
-#define CMD_ALIVE BIT(2)
-#define EVT_ALIVE BIT(3)
-
-enum Power_Mgnt {
- PS_MODE_ACTIVE = 0,
- PS_MODE_MIN,
- PS_MODE_MAX,
- PS_MODE_DTIM,
- PS_MODE_VOIP,
- PS_MODE_UAPSD_WMM,
- PS_MODE_UAPSD,
- PS_MODE_IBSS,
- PS_MODE_WWLAN,
- PM_Radio_Off,
- PM_Card_Disable,
- PS_MODE_NUM
-};
-
-
-/* BIT[2:0] = HW state
- * BIT[3] = Protocol PS state, 0: active, 1: sleep state
- * BIT[4] = sub-state
- */
-
-#define PS_DPS BIT(0)
-#define PS_LCLK (PS_DPS)
-#define PS_RF_OFF BIT(1)
-#define PS_ALL_ON BIT(2)
-#define PS_ST_ACTIVE BIT(3)
-
-#define PS_ISR_ENABLE BIT(4)
-#define PS_IMR_ENABLE BIT(5)
-#define PS_ACK BIT(6)
-#define PS_TOGGLE BIT(7)
-
-#define PS_STATE_MASK (0x0F)
-#define PS_STATE_HW_MASK (0x07)
-#define PS_SEQ_MASK (0xc0)
-
-#define PS_STATE(x) (PS_STATE_MASK & (x))
-#define PS_STATE_HW(x) (PS_STATE_HW_MASK & (x))
-#define PS_SEQ(x) (PS_SEQ_MASK & (x))
-
-#define PS_STATE_S0 (PS_DPS)
-#define PS_STATE_S1 (PS_LCLK)
-#define PS_STATE_S2 (PS_RF_OFF)
-#define PS_STATE_S3 (PS_ALL_ON)
-#define PS_STATE_S4 ((PS_ST_ACTIVE) | (PS_ALL_ON))
-
-
-#define PS_IS_RF_ON(x) ((x) & (PS_ALL_ON))
-#define PS_IS_ACTIVE(x) ((x) & (PS_ST_ACTIVE))
-#define CLR_PS_STATE(x) ((x) = ((x) & (0xF0)))
-
-
-struct reportpwrstate_parm {
- unsigned char mode;
- unsigned char state; /* the CPWM value */
- unsigned short rsvd;
-};
-
-#define LPS_DELAY_TIME (1*HZ) /* 1 sec */
-
-#define EXE_PWR_NONE 0x01
-#define EXE_PWR_IPS 0x02
-#define EXE_PWR_LPS 0x04
-
-/* RF state. */
-enum rt_rf_power_state {
- rf_on, /* RF is on after RFSleep or RFOff */
- rf_sleep, /* 802.11 Power Save mode */
- rf_off, /* HW/SW Radio OFF or Inactive Power Save */
- /* Add the new RF state above this line===== */
- rf_max
-};
-
-/* RF Off Level for IPS or HW/SW radio off */
-#define RT_RF_OFF_LEVL_ASPM BIT(0) /* PCI ASPM */
-#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /* PCI clock request */
-#define RT_RF_OFF_LEVL_PCI_D3 BIT(2) /* PCI D3 mode */
-/* NIC halt, re-init hw params */
-#define RT_RF_OFF_LEVL_HALT_NIC BIT(3)
-/* FW free, re-download the FW */
-#define RT_RF_OFF_LEVL_FREE_FW BIT(4)
-#define RT_RF_OFF_LEVL_FW_32K BIT(5) /* FW in 32k */
-/* Always enable ASPM and Clock Req in initialization. */
-#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6)
-/* When LPS is on, disable 2R if no packet is received or transmittd. */
-#define RT_RF_LPS_DISALBE_2R BIT(30)
-#define RT_RF_LPS_LEVEL_ASPM BIT(31) /* LPS with ASPM */
-
-#define RT_IN_PS_LEVEL(ppsc, _PS_FLAG) \
- ((ppsc->cur_ps_level & _PS_FLAG) ? true : false)
-#define RT_CLEAR_PS_LEVEL(ppsc, _PS_FLAG) \
- (ppsc->cur_ps_level &= (~(_PS_FLAG)))
-#define RT_SET_PS_LEVEL(ppsc, _PS_FLAG) \
- (ppsc->cur_ps_level |= _PS_FLAG)
-
-
-enum {
- PSBBREG_RF0 = 0,
- PSBBREG_RF1,
- PSBBREG_RF2,
- PSBBREG_AFE0,
- PSBBREG_TOTALCNT
-};
-
-enum { /* for ips_mode */
- IPS_NONE = 0,
- IPS_NORMAL,
- IPS_LEVEL_2,
-};
-
-struct pwrctrl_priv {
- struct semaphore lock;
- volatile u8 rpwm; /* requested power state for fw */
- volatile u8 cpwm; /* fw current power state. updated when 1.
- * read from HCPWM 2. driver lowers power level
- */
- volatile u8 tog; /* toggling */
-
- u8 pwr_mode;
- u8 smart_ps;
- u8 bcn_ant_mode;
-
- u8 bpower_saving;
-
- u8 reg_rfoff;
- u32 rfoff_reason;
-
- /* RF OFF Level */
- u32 cur_ps_level;
- u32 reg_rfps_level;
-
- uint ips_enter23a_cnts;
- uint ips_leave23a_cnts;
-
- u8 ips_mode;
- u8 ips_mode_req; /* used to accept the mode setting request */
- uint bips_processing;
- unsigned long ips_deny_time; /* deny IPS when system time is smaller */
- u8 ps_processing; /* used to mark whether in rtw_ps_processor23a */
-
- u8 bLeisurePs;
- u8 LpsIdleCount;
- u8 power_mgnt;
- u8 bFwCurrentInPSMode;
- unsigned long DelayLPSLastTimeStamp;
- u8 btcoex_rfon;
-
- u8 bInSuspend;
-#ifdef CONFIG_8723AU_BT_COEXIST
- u8 bAutoResume;
- u8 autopm_cnt;
-#endif
- u8 bSupportRemoteWakeup;
- struct timer_list pwr_state_check_timer;
- int pwr_state_check_interval;
- u8 pwr_state_check_cnts;
-
- enum rt_rf_power_state rf_pwrstate;/* cur power state */
- enum rt_rf_power_state change_rfpwrstate;
-
- u8 bkeepfwalive;
- unsigned long PS_BBRegBackup[PSBBREG_TOTALCNT];
-};
-
-#define RTW_PWR_STATE_CHK_INTERVAL 2000
-
-#define _rtw_set_pwr_state_check_timer(pwrctrlpriv, ms) \
- (mod_timer(&pwrctrlpriv->pwr_state_check_timer, jiffies + \
- msecs_to_jiffies(ms)))
-
-#define rtw_set_pwr_state_check_timer(pwrctrlpriv) \
- (_rtw_set_pwr_state_check_timer((pwrctrlpriv), \
- (pwrctrlpriv)->pwr_state_check_interval))
-
-void rtw_init_pwrctrl_priv23a(struct rtw_adapter *adapter);
-void rtw_free_pwrctrl_priv(struct rtw_adapter *adapter);
-
-void rtw_set_ps_mode23a(struct rtw_adapter *padapter, u8 ps_mode,
- u8 smart_ps, u8 bcn_ant_mode);
-void rtw_set_rpwm23a(struct rtw_adapter *padapter, u8 val8);
-void LeaveAllPowerSaveMode23a(struct rtw_adapter *adapter);
-void ips_enter23a(struct rtw_adapter *padapter);
-int ips_leave23a(struct rtw_adapter *padapter);
-
-void rtw_ps_processor23a(struct rtw_adapter *padapter);
-
-enum rt_rf_power_state RfOnOffDetect23a(struct rtw_adapter *adapter);
-
-s32 LPS_RF_ON_check23a(struct rtw_adapter *padapter, u32 delay_ms);
-void LPS_Enter23a(struct rtw_adapter *padapter);
-void LPS_Leave23a(struct rtw_adapter *padapter);
-
-void rtw_set_ips_deny23a(struct rtw_adapter *padapter, u32 ms);
-int _rtw_pwr_wakeup23a(struct rtw_adapter *padapter, u32 ips_deffer_ms,
- const char *caller);
-#define rtw_pwr_wakeup(adapter) _rtw_pwr_wakeup23a(adapter, \
- RTW_PWR_STATE_CHK_INTERVAL, __func__)
-int rtw_pm_set_ips23a(struct rtw_adapter *padapter, u8 mode);
-int rtw_pm_set_lps23a(struct rtw_adapter *padapter, u8 mode);
-
-#endif /* __RTL871X_PWRCTRL_H_ */
diff --git a/drivers/staging/rtl8723au/include/rtw_recv.h b/drivers/staging/rtl8723au/include/rtw_recv.h
deleted file mode 100644
index 85a5edb450e3..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_recv.h
+++ /dev/null
@@ -1,305 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef _RTW_RECV_H_
-#define _RTW_RECV_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <Hal8723APhyCfg.h>
-
-#define NR_RECVFRAME 256
-
-#define MAX_RXFRAME_CNT 512
-#define MAX_RX_NUMBLKS (32)
-#define RECVFRAME_HDR_ALIGN 128
-
-#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
-
-#define MAX_SUBFRAME_COUNT 64
-
-/* for Rx reordering buffer control */
-struct recv_reorder_ctrl {
- struct rtw_adapter *padapter;
- u8 enable;
- u16 indicate_seq;/* wstart_b, init_value=0xffff */
- u16 wend_b;
- u8 wsize_b;
- struct rtw_queue pending_recvframe_queue;
- struct timer_list reordering_ctrl_timer;
-};
-
-struct stainfo_rxcache {
- u16 tid_rxseq[16];
-/*
- unsigned short tid0_rxseq;
- unsigned short tid1_rxseq;
- unsigned short tid2_rxseq;
- unsigned short tid3_rxseq;
- unsigned short tid4_rxseq;
- unsigned short tid5_rxseq;
- unsigned short tid6_rxseq;
- unsigned short tid7_rxseq;
- unsigned short tid8_rxseq;
- unsigned short tid9_rxseq;
- unsigned short tid10_rxseq;
- unsigned short tid11_rxseq;
- unsigned short tid12_rxseq;
- unsigned short tid13_rxseq;
- unsigned short tid14_rxseq;
- unsigned short tid15_rxseq;
-*/
-};
-
-struct smooth_rssi_data {
- u32 elements[100]; /* array to store values */
- u32 index; /* index to current array to store */
- u32 total_num; /* num of valid elements */
- u32 total_val; /* sum of valid elements */
-};
-
-struct signal_stat {
- u8 update_req; /* used to indicate */
- u8 avg_val; /* avg of valid elements */
- u32 total_num; /* num of valid elements */
- u32 total_val; /* sum of valid elements */
-};
-
-struct phy_info {
- u8 RxPWDBAll;
- u8 SignalQuality; /* in 0-100 index. */
- u8 RxMIMOSignalQuality[RF_PATH_MAX]; /* EVM */
- u8 RxMIMOSignalStrength[RF_PATH_MAX];/* 0~100 */
- s8 RxPower; /* in dBm Translate from PWdB */
- /* Real power in dBm for this packet, no beautification and aggregation.
- * Keep this raw info to be used for the other procedures.
- */
- s8 RecvSignalPower;
- u8 BTRxRSSIPercentage;
- u8 SignalStrength; /* in 0-100 index. */
- u8 RxPwr[RF_PATH_MAX];/* per-path's pwdb */
- u8 RxSNR[RF_PATH_MAX];/* per-path's SNR */
-};
-
-
-struct rx_pkt_attrib {
- u16 pkt_len;
- u8 physt;
- u8 drvinfo_sz;
- u8 shift_sz;
- u8 hdrlen; /* the WLAN Header Len */
- u8 amsdu;
- u8 qos;
- u8 priority;
- u8 pw_save;
- u8 mdata;
- u16 seq_num;
- u8 frag_num;
- u8 mfrag;
- u8 order;
- u8 privacy; /* in frame_ctrl field */
- u8 bdecrypted;
- /* when 0 indicate no encrypt. when non-zero, indicate the algorith */
- u32 encrypt;
- u8 iv_len;
- u8 icv_len;
- u8 crc_err;
- u8 icv_err;
-
- u16 eth_type;
-
- u8 dst[ETH_ALEN];
- u8 src[ETH_ALEN];
- u8 ta[ETH_ALEN];
- u8 ra[ETH_ALEN];
- u8 bssid[ETH_ALEN];
-
- u8 ack_policy;
-
- u8 tcpchk_valid; /* 0: invalid, 1: valid */
- u8 ip_chkrpt; /* 0: incorrect, 1: correct */
- u8 tcp_chkrpt; /* 0: incorrect, 1: correct */
- u8 key_index;
-
- u8 mcs_rate;
- u8 rxht;
- u8 sgi;
- u8 pkt_rpt_type;
- u32 MacIDValidEntry[2]; /* 64 bits present 64 entry. */
- struct phy_info phy_info;
-};
-
-/* These definition is used for Rx packet reordering. */
-#define SN_LESS(a, b) (((a-b) & 0x800) != 0)
-#define SN_EQUAL(a, b) (a == b)
-#define REORDER_WAIT_TIME (50) /* (ms) */
-
-#define RECVBUFF_ALIGN_SZ 8
-
-#define RXDESC_SIZE 24
-#define RXDESC_OFFSET RXDESC_SIZE
-
-struct recv_stat {
- __le32 rxdw0;
- __le32 rxdw1;
- __le32 rxdw2;
- __le32 rxdw3;
- __le32 rxdw4;
- __le32 rxdw5;
-};
-
-/* accesser of recv_priv: rtw_recv_entry23a(dispatch / passive level); \
- * recv_thread(passive) ; returnpkt(dispatch) ; halt(passive) ;
- *
- * using enter_critical section to protect
- */
-struct recv_priv {
- spinlock_t lock;
-
- struct rtw_queue free_recv_queue;
- struct rtw_queue recv_pending_queue;
- struct rtw_queue uc_swdec_pending_queue;
-
- int free_recvframe_cnt;
-
- struct rtw_adapter *adapter;
-
- u32 bIsAnyNonBEPkts;
- u64 rx_bytes;
- u64 rx_pkts;
- u64 rx_drop;
- u64 last_rx_bytes;
-
- uint rx_icv_err;
- uint rx_largepacket_crcerr;
- uint rx_smallpacket_crcerr;
- uint rx_middlepacket_crcerr;
-
- /* u8 *pallocated_urb_buf; */
- u8 rx_pending_cnt;
-
- struct urb *int_in_urb;
-
- u8 *int_in_buf;
-
- struct tasklet_struct irq_prepare_beacon_tasklet;
- struct tasklet_struct recv_tasklet;
- struct sk_buff_head free_recv_skb_queue;
- struct sk_buff_head rx_skb_queue;
- u8 *precv_buf;
-
- /* For display the phy informatiom */
- s8 rxpwdb;
- u8 signal_strength;
- u8 signal_qual;
- u8 noise;
- int RxSNRdB[2];
- s8 RxRssi[2];
- int FalseAlmCnt_all;
-
- struct timer_list signal_stat_timer;
- u32 signal_stat_sampling_interval;
- /* u32 signal_stat_converging_constant; */
- struct signal_stat signal_qual_data;
- struct signal_stat signal_strength_data;
-};
-
-#define rtw_set_signal_stat_timer(recvpriv) \
- mod_timer(&(recvpriv)->signal_stat_timer, jiffies + \
- msecs_to_jiffies((recvpriv)->signal_stat_sampling_interval))
-
-struct sta_recv_priv {
- spinlock_t lock;
- int option;
-
- /* struct rtw_queue blk_strms[MAX_RX_NUMBLKS]; */
- struct rtw_queue defrag_q; /* keeping the fragment frame until defrag */
-
- struct stainfo_rxcache rxcache;
-
- /* uint sta_rx_bytes; */
- /* uint sta_rx_pkts; */
- /* uint sta_rx_fail; */
-
-};
-
-
-struct recv_buf {
- struct list_head list;
-
- struct rtw_adapter *adapter;
-
- struct urb *purb;
- struct sk_buff *pskb;
-};
-
-/* head ----->
- *
- * data ----->
- *
- * payload
- *
- * tail ----->
- *
- * end ----->
- *
- * len = (unsigned int )(tail - data);
- *
- */
-struct recv_frame {
- struct list_head list;
- struct sk_buff *pkt;
-
- struct rtw_adapter *adapter;
-
- struct rx_pkt_attrib attrib;
-
- struct sta_info *psta;
-
- /* for A-MPDU Rx reordering buffer control */
- struct recv_reorder_ctrl *preorder_ctrl;
-};
-
-/* get a free recv_frame from pfree_recv_queue */
-struct recv_frame *rtw_alloc_recvframe23a(struct rtw_queue *pfree_recv_queue);
-int rtw_free_recvframe23a(struct recv_frame *precvframe);
-
-int rtw_enqueue_recvframe23a(struct recv_frame *precvframe, struct rtw_queue *queue);
-
-u32 rtw_free_uc_swdec_pending_queue23a(struct rtw_adapter *adapter);
-
-struct recv_buf *rtw_dequeue_recvbuf23a(struct rtw_queue *queue);
-
-void rtw_reordering_ctrl_timeout_handler23a(unsigned long pcontext);
-
-static inline s32 translate_percentage_to_dbm(u32 SignalStrengthIndex)
-{
- s32 SignalPower; /* in dBm. */
-
- /* Translate to dBm (x=0.5y-95). */
- SignalPower = (s32)((SignalStrengthIndex + 1) >> 1);
- SignalPower -= 95;
-
- return SignalPower;
-}
-
-
-struct sta_info;
-
-void _rtw_init_sta_recv_priv23a(struct sta_recv_priv *psta_recvpriv);
-
-void mgt_dispatcher23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtw_rf.h b/drivers/staging/rtl8723au/include/rtw_rf.h
deleted file mode 100644
index a7de714137b8..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_rf.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTW_RF_H_
-#define __RTW_RF_H_
-
-#include <rtw_cmd.h>
-
-#define OFDM_PHY 1
-#define MIXED_PHY 2
-#define CCK_PHY 3
-
-#define NumRates (13)
-
-/* slot time for 11g */
-#define SHORT_SLOT_TIME 9
-#define NON_SHORT_SLOT_TIME 20
-
-/* We now define the max channels in each channel plan. */
-#define MAX_CHANNEL_NUM_2G 14
-#define MAX_CHANNEL_NUM_5G 24
-#define MAX_CHANNEL_NUM 38/* 14+24 */
-
-/* define NUM_REGULATORYS 21 */
-#define NUM_REGULATORYS 1
-
-/* Country codes */
-#define USA 0x555320
-#define EUROPE 0x1 /* temp, should be provided later */
-#define JAPAN 0x2 /* temp, should be provided later */
-
-struct regulatory_class {
- u32 starting_freq; /* MHz, */
- u8 channel_set[MAX_CHANNEL_NUM];
- u8 channel_cck_power[MAX_CHANNEL_NUM];/* dbm */
- u8 channel_ofdm_power[MAX_CHANNEL_NUM];/* dbm */
- u8 txpower_limit; /* dbm */
- u8 channel_spacing; /* MHz */
- u8 modem;
-};
-
-enum {
- cESS = 0x0001,
- cIBSS = 0x0002,
- cPollable = 0x0004,
- cPollReq = 0x0008,
- cPrivacy = 0x0010,
- cShortPreamble = 0x0020,
- cPBCC = 0x0040,
- cChannelAgility = 0x0080,
- cSpectrumMgnt = 0x0100,
- cQos = 0x0200, /* For HCCA, use with CF-Pollable and CF-PollReq */
- cShortSlotTime = 0x0400,
- cAPSD = 0x0800,
- cRM = 0x1000, /* RRM (Radio Request Measurement) */
- cDSSS_OFDM = 0x2000,
- cDelayedBA = 0x4000,
- cImmediateBA = 0x8000,
-};
-
-enum {
- PREAMBLE_LONG = 1,
- PREAMBLE_AUTO = 2,
- PREAMBLE_SHORT = 3,
-};
-
-/* Bandwidth Offset */
-#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
-#define HAL_PRIME_CHNL_OFFSET_LOWER 1
-#define HAL_PRIME_CHNL_OFFSET_UPPER 2
-
-/* Represent Channel Width in HT Capabilities */
-enum ht_channel_width {
- HT_CHANNEL_WIDTH_20 = 0,
- HT_CHANNEL_WIDTH_40 = 1,
- HT_CHANNEL_WIDTH_80 = 2,
- HT_CHANNEL_WIDTH_160 = 3,
- HT_CHANNEL_WIDTH_10 = 4,
-};
-
-/* 2007/11/15 MH Define different RF type. */
-enum {
- RF_1T2R = 0,
- RF_2T4R = 1,
- RF_2T2R = 2,
- RF_1T1R = 3,
- RF_2T2R_GREEN = 4,
- RF_819X_MAX_TYPE = 5,
-};
-
-#endif /* _RTL8711_RF_H_ */
diff --git a/drivers/staging/rtl8723au/include/rtw_security.h b/drivers/staging/rtl8723au/include/rtw_security.h
deleted file mode 100644
index 624a9d788e45..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_security.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __RTW_SECURITY_H_
-#define __RTW_SECURITY_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <net/lib80211.h>
-
-
-#define is_wep_enc(alg) (alg == WLAN_CIPHER_SUITE_WEP40 || \
- alg == WLAN_CIPHER_SUITE_WEP104)
-
-#define SHA256_MAC_LEN 32
-#define AES_BLOCK_SIZE 16
-#define AES_PRIV_SIZE (4 * 44)
-
-enum ENCRYP_PROTOCOL {
- ENCRYP_PROTOCOL_OPENSYS, /* open system */
- ENCRYP_PROTOCOL_WEP, /* WEP */
- ENCRYP_PROTOCOL_WPA, /* WPA */
- ENCRYP_PROTOCOL_WPA2, /* WPA2 */
- ENCRYP_PROTOCOL_MAX
-};
-
-#ifndef Ndis802_11AuthModeWPA2
-#define Ndis802_11AuthModeWPA2 (Ndis802_11AuthModeWPANone + 1)
-#endif
-
-#ifndef Ndis802_11AuthModeWPA2PSK
-#define Ndis802_11AuthModeWPA2PSK (Ndis802_11AuthModeWPANone + 2)
-#endif
-
-union pn48 {
- u64 val;
-
-#ifdef __LITTLE_ENDIAN
-
-struct {
- u8 TSC0;
- u8 TSC1;
- u8 TSC2;
- u8 TSC3;
- u8 TSC4;
- u8 TSC5;
- u8 TSC6;
- u8 TSC7;
-} _byte_;
-
-#elif defined(__BIG_ENDIAN)
-
-struct {
- u8 TSC7;
- u8 TSC6;
- u8 TSC5;
- u8 TSC4;
- u8 TSC3;
- u8 TSC2;
- u8 TSC1;
- u8 TSC0;
-} _byte_;
-#else
-#error Need BIG or LITTLE endian
-
-#endif
-
-};
-
-union Keytype {
- u8 skey[16];
- u32 lkey[4];
-};
-
-struct rtw_wep_key {
- u8 key[WLAN_KEY_LEN_WEP104 + 1]; /* 14 */
- u16 keylen;
-};
-
-struct rt_pmkid_list {
- u8 bUsed;
- u8 Bssid[6];
- u8 PMKID[16];
- u8 SsidBuf[33];
- u8 *ssid_octet;
- u16 ssid_length;
-};
-
-struct security_priv {
- u32 dot11AuthAlgrthm; /* 802.11 auth, could be open, shared,
- * 8021x and authswitch */
- u32 dot11PrivacyAlgrthm; /* This specifies the privacy for
- * shared auth. algorithm.
- */
- /* WEP */
- u32 dot11PrivacyKeyIndex; /* this is only valid for legendary
- * wep, 0~3 for key id. (tx key index)
- */
- struct rtw_wep_key wep_key[NUM_WEP_KEYS];
-
- u32 dot118021XGrpPrivacy; /* specify the privacy algthm.
- * used for Grp key
- */
- u32 dot118021XGrpKeyid; /* key id used for Grp Key
- * (tx key index)
- */
- union Keytype dot118021XGrpKey[4];/* 802.1x Grp Key, inx0 and inx1 */
- union Keytype dot118021XGrptxmickey[4];
- union Keytype dot118021XGrprxmickey[4];
- union pn48 dot11Grptxpn; /* PN48 used for Grp Key xmit.*/
- union pn48 dot11Grprxpn; /* PN48 used for Grp Key recv.*/
-
-#ifdef CONFIG_8723AU_AP_MODE
- /* extend security capabilities for AP_MODE */
- unsigned int dot8021xalg;/* 0:disable, 1:psk, 2:802.1x */
- unsigned int wpa_psk;/* 0:disable, bit(0): WPA, bit(1):WPA2 */
- unsigned int wpa_group_cipher;
- unsigned int wpa2_group_cipher;
- unsigned int wpa_pairwise_cipher;
- unsigned int wpa2_pairwise_cipher;
-#endif
-
- u8 wps_ie[MAX_WPS_IE_LEN];/* added in assoc req */
- int wps_ie_len;
- unsigned int binstallGrpkey:1;
- unsigned int busetkipkey:1;
- unsigned int bcheck_grpkey:1;
- unsigned int hw_decrypted:1;
- u32 ndisauthtype; /* enum ndis_802_11_auth_mode */
- u32 ndisencryptstatus; /* NDIS_802_11_ENCRYPTION_STATUS */
- struct wlan_bssid_ex sec_bss; /* for joinbss (h2c buffer) usage */
- u8 assoc_info[600];
- u8 szofcapability[256]; /* for wpa2 usage */
- u8 oidassociation[512]; /* for wpa/wpa2 usage */
- u8 supplicant_ie[256]; /* store sta security information element */
-
- /* for tkip countermeasure */
- unsigned long last_mic_err_time;
- u8 btkip_countermeasure;
- u8 btkip_wait_report;
- unsigned long btkip_countermeasure_time;
-
- /* For WPA2 Pre-Authentication. */
- struct rt_pmkid_list PMKIDList[NUM_PMKID_CACHE];
- u8 PMKIDIndex;
- u8 bWepDefaultKeyIdxSet;
-};
-
-struct sha256_state {
- u64 length;
- u32 state[8], curlen;
- u8 buf[64];
-};
-
-#define GET_ENCRY_ALGO(psecuritypriv, psta, encry_algo, bmcst)\
-do {\
- switch (psecuritypriv->dot11AuthAlgrthm) {\
- case dot11AuthAlgrthm_Open:\
- case dot11AuthAlgrthm_Shared:\
- case dot11AuthAlgrthm_Auto:\
- encry_algo = psecuritypriv->dot11PrivacyAlgrthm;\
- break;\
- case dot11AuthAlgrthm_8021X:\
- if (bmcst)\
- encry_algo = psecuritypriv->dot118021XGrpPrivacy;\
- else\
- encry_algo = psta->dot118021XPrivacy;\
- break;\
- } \
-} while (0)
-
-#define GET_TKIP_PN(iv, dot11txpn)\
-do {\
- dot11txpn._byte_.TSC0 = iv[2];\
- dot11txpn._byte_.TSC1 = iv[0];\
- dot11txpn._byte_.TSC2 = iv[4];\
- dot11txpn._byte_.TSC3 = iv[5];\
- dot11txpn._byte_.TSC4 = iv[6];\
- dot11txpn._byte_.TSC5 = iv[7];\
-} while (0)
-
-#define ROL32(A, n) (((A) << (n)) | (((A)>>(32-(n))) & ((1UL << (n)) - 1)))
-#define ROR32(A, n) ROL32((A), 32-(n))
-
-struct mic_data {
- u32 K0, K1; /* Key */
- u32 L, R; /* Current state */
- u32 M; /* Message accumulator (single word) */
- u32 nBytesInM; /* # bytes in M */
-};
-
-extern const u32 Te0[256];
-extern const u32 Te1[256];
-extern const u32 Te2[256];
-extern const u32 Te3[256];
-extern const u32 Te4[256];
-extern const u32 Td0[256];
-extern const u32 Td1[256];
-extern const u32 Td2[256];
-extern const u32 Td3[256];
-extern const u32 Td4[256];
-extern const u32 rcon[10];
-extern const u8 Td4s[256];
-extern const u8 rcons[10];
-
-#define RCON(i) (rcons[(i)] << 24)
-
-static inline u32 rotr(u32 val, int bits)
-{
- return (val >> bits) | (val << (32 - bits));
-}
-
-#define TE0(i) Te0[((i) >> 24) & 0xff]
-#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8)
-#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16)
-#define TE3(i) rotr(Te0[(i) & 0xff], 24)
-#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000)
-#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000)
-#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00)
-#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff)
-#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000)
-#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000)
-#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00)
-#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff)
-#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff)
-
-#define TD0(i) Td0[((i) >> 24) & 0xff]
-#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8)
-#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16)
-#define TD3(i) rotr(Td0[(i) & 0xff], 24)
-#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24)
-#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16)
-#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8)
-#define TD44(i) (Td4s[(i) & 0xff])
-#define TD0_(i) Td0[(i) & 0xff]
-#define TD1_(i) rotr(Td0[(i) & 0xff], 8)
-#define TD2_(i) rotr(Td0[(i) & 0xff], 16)
-#define TD3_(i) rotr(Td0[(i) & 0xff], 24)
-
-#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
- ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
-
-#define PUTU32(ct, st) { \
-(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \
-(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
-
-#define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \
- (((u32) (a)[2]) << 8) | ((u32) (a)[3]))
-
-#define WPA_PUT_LE16(a, val) \
- do { \
- (a)[1] = ((u16) (val)) >> 8; \
- (a)[0] = ((u16) (val)) & 0xff; \
- } while (0)
-
-#define WPA_PUT_BE32(a, val) \
- do { \
- (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \
- (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \
- (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \
- (a)[3] = (u8) (((u32) (val)) & 0xff); \
- } while (0)
-
-#define WPA_PUT_BE64(a, val) \
- do { \
- (a)[0] = (u8) (((u64) (val)) >> 56); \
- (a)[1] = (u8) (((u64) (val)) >> 48); \
- (a)[2] = (u8) (((u64) (val)) >> 40); \
- (a)[3] = (u8) (((u64) (val)) >> 32); \
- (a)[4] = (u8) (((u64) (val)) >> 24); \
- (a)[5] = (u8) (((u64) (val)) >> 16); \
- (a)[6] = (u8) (((u64) (val)) >> 8); \
- (a)[7] = (u8) (((u64) (val)) & 0xff); \
- } while (0)
-
-/* ===== start - public domain SHA256 implementation ===== */
-
-/* This is based on SHA256 implementation in LibTomCrypt that was released into
- * public domain by Tom St Denis. */
-
-/* the K array */
-static const unsigned long K[64] = {
- 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
- 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
- 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
- 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
- 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
- 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
- 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
- 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
- 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
- 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
- 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
- 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
- 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
-};
-
-void rtw_secmicsetkey23a(struct mic_data *pmicdata, u8 *key);
-void rtw_secmicappend23abyte23a(struct mic_data *pmicdata, u8 b);
-void rtw_secmicappend23a(struct mic_data *pmicdata, u8 *src, u32 nbBytes);
-void rtw_secgetmic23a(struct mic_data *pmicdata, u8 *dst);
-
-void rtw_seccalctkipmic23a(u8 *key, u8 *header, u8 *data, u32 data_len,
- u8 *Miccode, u8 priorityi);
-
-int rtw_aes_encrypt23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe);
-int rtw_tkip_encrypt23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe);
-void rtw_wep_encrypt23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe);
-int rtw_aes_decrypt23a(struct rtw_adapter *padapter,
- struct recv_frame *precvframe);
-int rtw_tkip_decrypt23a(struct rtw_adapter *padapter,
- struct recv_frame *precvframe);
-void rtw_wep_decrypt23a(struct rtw_adapter *padapter, struct recv_frame *precvframe);
-
-void rtw_use_tkipkey_handler23a(void *FunctionContext);
-
-#endif /* __RTL871X_SECURITY_H_ */
diff --git a/drivers/staging/rtl8723au/include/rtw_sreset.h b/drivers/staging/rtl8723au/include/rtw_sreset.h
deleted file mode 100644
index 60fa8296e1ff..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_sreset.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef _RTW_SRESET_C_
-#define _RTW_SRESET_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-struct sreset_priv {
- struct mutex silentreset_mutex;
- u8 silent_reset_inprogress;
- unsigned long last_tx_time;
- unsigned long last_tx_complete_time;
-};
-
-#include <rtl8723a_hal.h>
-
-void rtw_sreset_init(struct rtw_adapter *padapter);
-void rtw_sreset_reset_value(struct rtw_adapter *padapter);
-bool rtw_sreset_inprogress(struct rtw_adapter *padapter);
-void sreset_set_trigger_point(struct rtw_adapter *padapter, s32 tgp);
-void rtw_sreset_reset(struct rtw_adapter *active_adapter);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtw_version.h b/drivers/staging/rtl8723au/include/rtw_version.h
deleted file mode 100644
index c947733a3e3e..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_version.h
+++ /dev/null
@@ -1 +0,0 @@
-#define DRIVERVERSION "v4.1.6_7336.20130426"
diff --git a/drivers/staging/rtl8723au/include/rtw_xmit.h b/drivers/staging/rtl8723au/include/rtw_xmit.h
deleted file mode 100644
index 2b7d6d08238b..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_xmit.h
+++ /dev/null
@@ -1,385 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef _RTW_XMIT_H_
-#define _RTW_XMIT_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-#define MAX_XMITBUF_SZ 2048
-#define NR_XMITBUFF 4
-
-#define XMITBUF_ALIGN_SZ 512
-
-/* xmit extension buff defination */
-#define MAX_XMIT_EXTBUF_SZ 1536
-#define NR_XMIT_EXTBUFF 32
-
-#define MAX_NUMBLKS 1
-
-#define XMIT_VO_QUEUE 0
-#define XMIT_VI_QUEUE 1
-#define XMIT_BE_QUEUE 2
-#define XMIT_BK_QUEUE 3
-
-#define VO_QUEUE_INX 0
-#define VI_QUEUE_INX 1
-#define BE_QUEUE_INX 2
-#define BK_QUEUE_INX 3
-#define BCN_QUEUE_INX 4
-#define MGT_QUEUE_INX 5
-#define HIGH_QUEUE_INX 6
-#define TXCMD_QUEUE_INX 7
-
-#define HW_QUEUE_ENTRY 8
-
-#define WEP_IV(pattrib_iv, dot11txpn, keyidx) \
-do { \
- pattrib_iv[0] = dot11txpn._byte_.TSC0; \
- pattrib_iv[1] = dot11txpn._byte_.TSC1; \
- pattrib_iv[2] = dot11txpn._byte_.TSC2; \
- pattrib_iv[3] = ((keyidx & 0x3) << 6); \
- dot11txpn.val = (dot11txpn.val == 0xffffff) ? 0 : \
- (dot11txpn.val+1); \
-} while (0)
-
-#define TKIP_IV(pattrib_iv, dot11txpn, keyidx) \
-do { \
- pattrib_iv[0] = dot11txpn._byte_.TSC1; \
- pattrib_iv[1] = (dot11txpn._byte_.TSC1 | 0x20) & 0x7f; \
- pattrib_iv[2] = dot11txpn._byte_.TSC0; \
- pattrib_iv[3] = BIT(5) | ((keyidx & 0x3)<<6); \
- pattrib_iv[4] = dot11txpn._byte_.TSC2; \
- pattrib_iv[5] = dot11txpn._byte_.TSC3; \
- pattrib_iv[6] = dot11txpn._byte_.TSC4; \
- pattrib_iv[7] = dot11txpn._byte_.TSC5; \
- dot11txpn.val = dot11txpn.val == 0xffffffffffffULL ? 0 : \
- (dot11txpn.val+1); \
-} while (0)
-
-#define AES_IV(pattrib_iv, dot11txpn, keyidx)\
-do { \
- pattrib_iv[0] = dot11txpn._byte_.TSC0; \
- pattrib_iv[1] = dot11txpn._byte_.TSC1; \
- pattrib_iv[2] = 0; \
- pattrib_iv[3] = BIT(5) | ((keyidx & 0x3) << 6); \
- pattrib_iv[4] = dot11txpn._byte_.TSC2; \
- pattrib_iv[5] = dot11txpn._byte_.TSC3; \
- pattrib_iv[6] = dot11txpn._byte_.TSC4; \
- pattrib_iv[7] = dot11txpn._byte_.TSC5; \
- dot11txpn.val = dot11txpn.val == 0xffffffffffffULL ? 0 : \
- (dot11txpn.val+1); \
-} while (0)
-
-#define HWXMIT_ENTRY 4
-
-#define TXDESC_SIZE 32
-
-#define PACKET_OFFSET_SZ 8
-#define TXDESC_OFFSET (TXDESC_SIZE + PACKET_OFFSET_SZ)
-
-struct tx_desc {
- /* DWORD 0 */
- __le32 txdw0;
- __le32 txdw1;
- __le32 txdw2;
- __le32 txdw3;
- __le32 txdw4;
- __le32 txdw5;
- __le32 txdw6;
- __le32 txdw7;
-};
-
-union txdesc {
- struct tx_desc txdesc;
- unsigned int value[TXDESC_SIZE>>2];
-};
-
-struct hw_xmit {
- struct rtw_queue *sta_queue;
- int accnt;
-};
-
-/* reduce size */
-struct pkt_attrib {
- u16 type;
- u8 bswenc;
- u8 dhcp_pkt;
- u16 ether_type;
- u16 seqnum;
- u16 pkt_hdrlen; /* the original 802.3 pkt header len */
- u16 hdrlen; /* the WLAN Header Len */
- u32 pktlen; /* the original 802.3 pkt raw_data len */
- u32 last_txcmdsz;
- u32 encrypt; /* when 0 indicate no encrypt. */
- u8 nr_frags;
- u8 iv_len;
- u8 icv_len;
- u8 iv[18];
- u8 icv[16];
- u8 priority;
- u8 ack_policy;
- u8 mac_id;
- u8 vcs_mode; /* virtual carrier sense method */
- u8 dst[ETH_ALEN];
- u8 src[ETH_ALEN];
- u8 ta[ETH_ALEN];
- u8 ra[ETH_ALEN];
- u8 key_idx;
- u8 qos_en;
- u8 ht_en;
- u8 raid;/* rate adpative id */
- u8 bwmode;
- u8 ch_offset;/* PRIME_CHNL_OFFSET */
- u8 sgi;/* short GI */
- u8 ampdu_en;/* tx ampdu enable */
- u8 mdata;/* more data bit */
- u8 pctrl;/* per packet txdesc control enable */
- u8 triggered;/* for ap mode handling Power Saving sta */
- u8 qsel;
- u8 eosp;
- u8 rate;
- u8 retry_ctrl;
- struct sta_info *psta;
-};
-
-#define WLANHDR_OFFSET 64
-
-#define NULL_FRAMETAG 0x0
-#define DATA_FRAMETAG 0x01
-#define L2_FRAMETAG 0x02
-#define MGNT_FRAMETAG 0x03
-#define AMSDU_FRAMETAG 0x04
-
-#define EII_FRAMETAG 0x05
-#define IEEE8023_FRAMETAG 0x06
-
-#define MP_FRAMETAG 0x07
-
-#define TXAGG_FRAMETAG 0x08
-
-struct submit_ctx {
- u32 timeout_ms; /* <0: not synchronous, 0: wait forever,
- * >0: up to ms waiting
- */
- int status; /* status for operation */
- struct completion done;
-};
-
-enum {
- RTW_SCTX_SUBMITTED = -1,
- RTW_SCTX_DONE_SUCCESS = 0,
- RTW_SCTX_DONE_UNKNOWN,
- RTW_SCTX_DONE_TIMEOUT,
- RTW_SCTX_DONE_BUF_ALLOC,
- RTW_SCTX_DONE_BUF_FREE,
- RTW_SCTX_DONE_WRITE_PORT_ERR,
- RTW_SCTX_DONE_TX_DESC_NA,
- RTW_SCTX_DONE_TX_DENY,
- RTW_SCTX_DONE_CCX_PKT_FAIL,
- RTW_SCTX_DONE_DRV_STOP,
- RTW_SCTX_DONE_DEV_REMOVE,
-};
-
-void rtw_sctx_init23a(struct submit_ctx *sctx, int timeout_ms);
-int rtw_sctx_wait23a(struct submit_ctx *sctx);
-void rtw23a_sctx_done_err(struct submit_ctx **sctx, int status);
-
-struct xmit_buf {
- struct list_head list, list2;
- struct rtw_adapter *padapter;
-
- u8 *pallocated_buf;
- u8 *pbuf;
- void *priv_data;
-
- u16 ext_tag; /* 0: Normal xmitbuf, 1: extension xmitbuf. */
- u16 flags;
- u32 alloc_sz;
- u32 len;
- struct submit_ctx *sctx;
- u32 ff_hwaddr;
- struct urb *pxmit_urb[8];
- u8 bpending[8];
- int last[8];
-#if defined(DBG_XMIT_BUF) || defined(DBG_XMIT_BUF_EXT)
- u8 no;
-#endif
-};
-
-struct xmit_frame {
- struct list_head list;
- struct pkt_attrib attrib;
- struct sk_buff *pkt;
- int frame_tag;
- struct rtw_adapter *padapter;
- u8 *buf_addr;
- struct xmit_buf *pxmitbuf;
-
- s8 pkt_offset;
-
- u8 ack_report;
-
- u8 ext_tag; /* 0:data, 1:mgmt */
-};
-
-struct tx_servq {
- struct list_head tx_pending;
- struct rtw_queue sta_pending;
- int qcnt;
-};
-
-struct sta_xmit_priv {
- spinlock_t lock;
- int option;
- int apsd_setting; /* When bit mask is on, the associated edca
- * queue supports APSD.
- */
- struct tx_servq be_q; /* priority == 0,3 */
- struct tx_servq bk_q; /* priority == 1,2 */
- struct tx_servq vi_q; /* priority == 4,5 */
- struct tx_servq vo_q; /* priority == 6,7 */
- struct list_head legacy_dz;
- struct list_head apsd;
- u16 txseq_tid[16];
-};
-
-struct hw_txqueue {
- volatile int head;
- volatile int tail;
- volatile int free_sz; /* in units of 64 bytes */
- volatile int free_cmdsz;
- volatile int txsz[8];
- uint ff_hwaddr;
- uint cmd_hwaddr;
- int ac_tag;
-};
-
-struct agg_pkt_info {
- u16 offset;
- u16 pkt_len;
-};
-
-struct xmit_priv {
- spinlock_t lock;
-
- struct semaphore xmit_sema;
- struct semaphore terminate_xmitthread_sema;
-
- struct rtw_queue be_pending;
- struct rtw_queue bk_pending;
- struct rtw_queue vi_pending;
- struct rtw_queue vo_pending;
- struct rtw_queue bm_pending;
-
- int free_xmitframe_cnt;
- struct rtw_queue free_xmit_queue;
-
- int free_xframe_ext_cnt;
- struct rtw_queue free_xframe_ext_queue;
-
- uint frag_len;
-
- struct rtw_adapter *adapter;
-
- u64 tx_bytes;
- u64 tx_pkts;
- u64 tx_drop;
- u64 last_tx_bytes;
- u64 last_tx_pkts;
-
- struct hw_xmit *hwxmits;
- u8 hwxmit_entry;
- u8 vcs;
- u8 nqos_ssn;
-
- u8 wmm_para_seq[4];/* sequence for wmm ac parameter strength from
- * large to small. it's value is 0->vo, 1->vi,
- * 2->be, 3->bk.
- */
-
- struct semaphore tx_retevt;/* all tx return event; */
-
- struct tasklet_struct xmit_tasklet;
-
- struct rtw_queue free_xmitbuf_queue;
- struct list_head xmitbuf_list; /* track buffers for cleanup */
- struct rtw_queue pending_xmitbuf_queue;
- uint free_xmitbuf_cnt;
-
- struct rtw_queue free_xmit_extbuf_queue;
- struct list_head xmitextbuf_list; /* track buffers for cleanup */
- uint free_xmit_extbuf_cnt;
-
- int ack_tx;
- struct mutex ack_tx_mutex;
- struct submit_ctx ack_tx_ops;
- spinlock_t lock_sctx;
-};
-
-struct xmit_buf *rtw_alloc_xmitbuf23a_ext(struct xmit_priv *pxmitpriv);
-s32 rtw_free_xmitbuf_ext23a(struct xmit_priv *pxmitpriv,
- struct xmit_buf *pxmitbuf);
-
-struct xmit_buf *rtw_alloc_xmitbuf23a(struct xmit_priv *pxmitpriv);
-s32 rtw_free_xmitbuf23a(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf);
-
-void rtw_count_tx_stats23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe, int sz);
-void rtw_update_protection23a(struct rtw_adapter *padapter, u8 *ie, uint ie_len);
-struct xmit_frame *rtw_alloc_xmitframe23a_ext(struct xmit_priv *pxmitpriv);
-struct xmit_frame *rtw_alloc_xmitframe23a_once(struct xmit_priv *pxmitpriv);
-s32 rtw_free_xmitframe23a(struct xmit_priv *pxmitpriv,
- struct xmit_frame *pxmitframe);
-void rtw_free_xmitframe_queue23a(struct xmit_priv *pxmitpriv, struct rtw_queue *pframequeue);
-struct tx_servq *rtw_get_sta_pending23a(struct rtw_adapter *padapter,
- struct sta_info *psta, int up, u8 *ac);
-s32 rtw_xmitframe_enqueue23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe);
-struct xmit_frame *rtw_dequeue_xframe23a(struct xmit_priv *pxmitpriv,
- struct hw_xmit *phwxmit_i, int entry);
-s32 rtw_xmit23a_classifier(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe);
-s32 rtw_xmitframe_coalesce23a(struct rtw_adapter *padapter, struct sk_buff *pkt,
- struct xmit_frame *pxmitframe);
-s32 _rtw_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag);
-void _rtw_init_sta_xmit_priv23a(struct sta_xmit_priv *psta_xmitpriv);
-
-s32 rtw_txframes_pending23a(struct rtw_adapter *padapter);
-s32 rtw_txframes_sta_ac_pending23a(struct rtw_adapter *padapter,
- struct pkt_attrib *pattrib);
-void rtw_init_hwxmits23a(struct hw_xmit *phwxmit, int entry);
-int _rtw_init_xmit_priv23a(struct xmit_priv *pxmitpriv,
- struct rtw_adapter *padapter);
-void _rtw_free_xmit_priv23a(struct xmit_priv *pxmitpriv);
-void rtw_alloc_hwxmits23a(struct rtw_adapter *padapter);
-void rtw_free_hwxmits23a(struct rtw_adapter *padapter);
-int rtw_xmit23a(struct rtw_adapter *padapter, struct sk_buff *pkt);
-#if defined(CONFIG_8723AU_AP_MODE)
-int xmitframe_enqueue_for_sleeping_sta23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxmitframe);
-void stop_sta_xmit23a(struct rtw_adapter *padapter, struct sta_info *psta);
-void wakeup_sta_to_xmit23a(struct rtw_adapter *padapter, struct sta_info *psta);
-void xmit_delivery_enabled_frames23a(struct rtw_adapter *padapter,
- struct sta_info *psta);
-#endif
-u8 qos_acm23a(u8 acm_mask, u8 priority);
-u32 rtw_get_ff_hwaddr23a(struct xmit_frame *pxmitframe);
-int rtw_ack_tx_wait23a(struct xmit_priv *pxmitpriv, u32 timeout_ms);
-
-/* include after declaring struct xmit_buf, in order to avoid warning */
-#include <xmit_osdep.h>
-
-#endif /* _RTL871X_XMIT_H_ */
diff --git a/drivers/staging/rtl8723au/include/sta_info.h b/drivers/staging/rtl8723au/include/sta_info.h
deleted file mode 100644
index e7260050e533..000000000000
--- a/drivers/staging/rtl8723au/include/sta_info.h
+++ /dev/null
@@ -1,373 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __STA_INFO_H_
-#define __STA_INFO_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <wifi.h>
-
-#define IBSS_START_MAC_ID 2
-#define NUM_STA 32
-#define NUM_ACL 16
-
-
-/* if mode ==0, then the sta is allowed once the addr is hit. */
-/* if mode ==1, then the sta is rejected once the addr is non-hit. */
-struct rtw_wlan_acl_node {
- struct list_head list;
- u8 addr[ETH_ALEN];
- u8 valid;
-};
-
-/* mode=0, disable */
-/* mode=1, accept unless in deny list */
-/* mode=2, deny unless in accept list */
-struct wlan_acl_pool {
- int mode;
- int num;
- struct rtw_wlan_acl_node aclnode[NUM_ACL];
- struct rtw_queue acl_node_q;
-};
-
-struct rssi_sta {
- s32 UndecoratedSmoothedPWDB;
- s32 UndecoratedSmoothedCCK;
- s32 UndecoratedSmoothedOFDM;
- u64 PacketMap;
- u8 ValidBit;
-};
-
-struct stainfo_stats {
- u64 rx_mgnt_pkts;
- u64 rx_beacon_pkts;
- u64 rx_probereq_pkts;
- u64 rx_probersp_pkts;
- u64 rx_probersp_bm_pkts;
- u64 rx_probersp_uo_pkts;
- u64 rx_ctrl_pkts;
- u64 rx_data_pkts;
-
- u64 last_rx_mgnt_pkts;
- u64 last_rx_beacon_pkts;
- u64 last_rx_probereq_pkts;
- u64 last_rx_probersp_pkts;
- u64 last_rx_probersp_bm_pkts;
- u64 last_rx_probersp_uo_pkts;
- u64 last_rx_ctrl_pkts;
- u64 last_rx_data_pkts;
-
- u64 rx_bytes;
- u64 rx_drops;
-
- u64 tx_pkts;
- u64 tx_bytes;
- u64 tx_drops;
-
-};
-
-struct sta_info {
- spinlock_t lock;
- struct list_head list; /* free_sta_queue */
- struct list_head hash_list; /* sta_hash */
- struct rtw_adapter *padapter;
-
- struct sta_xmit_priv sta_xmitpriv;
- struct sta_recv_priv sta_recvpriv;
-
- struct rtw_queue sleep_q;
- unsigned int sleepq_len;
-
- uint state;
- uint aid;
- uint mac_id;
- uint qos_option;
- u8 hwaddr[ETH_ALEN];
-
- uint ieee8021x_blocked; /* 0: allowed, 1:blocked */
- u32 dot118021XPrivacy; /* aes, tkip... */
- union Keytype dot11tkiptxmickey;
- union Keytype dot11tkiprxmickey;
- union Keytype dot118021x_UncstKey;
- union pn48 dot11txpn; /* PN48 used for Unicast xmit. */
- union pn48 dot11rxpn; /* PN48 used for Unicast recv. */
-
-
- u8 bssrateset[16];
- u32 bssratelen;
- s32 rssi;
- s32 signal_quality;
-
- u8 cts2self;
- u8 rtsen;
-
- u8 raid;
- u8 init_rate;
- u32 ra_mask;
- u8 wireless_mode; /* NETWORK_TYPE */
- struct stainfo_stats sta_stats;
-
- /* for A-MPDU TX, ADDBA timeout check */
- struct timer_list addba_retry_timer;
-
- /* for A-MPDU Rx reordering buffer control */
- struct recv_reorder_ctrl recvreorder_ctrl[16];
-
- /* for A-MPDU Tx */
- /* unsigned char ampdu_txen_bitmap; */
- u16 BA_starting_seqctrl[16];
-
- struct ht_priv htpriv;
-
- /* Notes: */
- /* STA_Mode: */
- /* curr_network(mlme_priv/security_priv/qos/ht) + sta_info: (STA & AP) CAP/INFO */
- /* scan_q: AP CAP/INFO */
-
- /* AP_Mode: */
- /* curr_network(mlme_priv/security_priv/qos/ht) : AP CAP/INFO */
- /* sta_info: (AP & STA) CAP/INFO */
-
- struct list_head asoc_list;
- struct list_head auth_list;
-
- unsigned int expire_to;
- unsigned int auth_seq;
- unsigned int authalg;
- unsigned char chg_txt[128];
-
- u16 capability;
- int flags;
-
- int dot8021xalg;/* 0:disable, 1:psk, 2:802.1x */
- int wpa_psk;/* 0:disable, bit(0): WPA, bit(1):WPA2 */
- int wpa_group_cipher;
- int wpa2_group_cipher;
- int wpa_pairwise_cipher;
- int wpa2_pairwise_cipher;
-
- u8 bpairwise_key_installed;
-
- u8 wpa_ie[32];
-
- u8 nonerp_set;
- u8 no_short_slot_time_set;
- u8 no_short_preamble_set;
- u8 no_ht_gf_set;
- u8 no_ht_set;
- u8 ht_20mhz_set;
-
- unsigned int tx_ra_bitmap;
- u8 qos_info;
-
- u8 max_sp_len;
- u8 uapsd_bk;/* BIT(0): Delivery enabled, BIT(1): Trigger enabled */
- u8 uapsd_be;
- u8 uapsd_vi;
- u8 uapsd_vo;
-
- u8 has_legacy_ac;
- unsigned int sleepq_ac_len;
-
- /* p2p priv data */
- u8 is_p2p_device;
- u8 p2p_status_code;
-
- u8 keep_alive_trycnt;
-
- /* p2p client info */
- u8 dev_addr[ETH_ALEN];
- u8 dev_cap;
- u16 config_methods;
- u8 primary_dev_type[8];
- u8 num_of_secdev_type;
- u8 secdev_types_list[32];/* 32/8 == 4; */
- u16 dev_name_len;
- u8 dev_name[32];
- u8 *passoc_req;
- u32 assoc_req_len;
-
- /* for DM */
- struct rssi_sta rssi_stat;
-
- /* */
- /* ================ODM Relative Info======================= */
- /* Please be care, dont declare too much structure here. It will cost memory * STA support num. */
- /* */
- /* */
- /* 2011/10/20 MH Add for ODM STA info. */
- /* */
- /* Driver Write */
- u8 bValid; /* record the sta status link or not? */
- u8 rssi_level; /* for Refresh RA mask */
- /* ODM Write */
- /* 1 PHY_STATUS_INFO */
- u8 RSSI_Path[4]; /* */
- u8 RSSI_Ave;
- u8 RXEVM[4];
- u8 RXSNR[4];
-
- /* ODM Write */
- /* 1 TX_INFO (may changed by IC) */
- /* ================ODM Relative Info======================= */
- /* */
-
- /* To store the sequence number of received management frame */
- u16 RxMgmtFrameSeqNum;
-};
-
-#define sta_rx_pkts(sta) \
- (sta->sta_stats.rx_mgnt_pkts \
- + sta->sta_stats.rx_ctrl_pkts \
- + sta->sta_stats.rx_data_pkts)
-
-#define sta_last_rx_pkts(sta) \
- (sta->sta_stats.last_rx_mgnt_pkts \
- + sta->sta_stats.last_rx_ctrl_pkts \
- + sta->sta_stats.last_rx_data_pkts)
-
-#define sta_rx_data_pkts(sta) \
- (sta->sta_stats.rx_data_pkts)
-
-#define sta_last_rx_data_pkts(sta) \
- (sta->sta_stats.last_rx_data_pkts)
-
-#define sta_rx_mgnt_pkts(sta) \
- (sta->sta_stats.rx_mgnt_pkts)
-
-#define sta_last_rx_mgnt_pkts(sta) \
- (sta->sta_stats.last_rx_mgnt_pkts)
-
-#define sta_rx_beacon_pkts(sta) \
- (sta->sta_stats.rx_beacon_pkts)
-
-#define sta_last_rx_beacon_pkts(sta) \
- (sta->sta_stats.last_rx_beacon_pkts)
-
-#define sta_rx_probereq_pkts(sta) \
- (sta->sta_stats.rx_probereq_pkts)
-
-#define sta_last_rx_probereq_pkts(sta) \
- (sta->sta_stats.last_rx_probereq_pkts)
-
-#define sta_rx_probersp_pkts(sta) \
- (sta->sta_stats.rx_probersp_pkts)
-
-#define sta_last_rx_probersp_pkts(sta) \
- (sta->sta_stats.last_rx_probersp_pkts)
-
-#define sta_rx_probersp_bm_pkts(sta) \
- (sta->sta_stats.rx_probersp_bm_pkts)
-
-#define sta_last_rx_probersp_bm_pkts(sta) \
- (sta->sta_stats.last_rx_probersp_bm_pkts)
-
-#define sta_rx_probersp_uo_pkts(sta) \
- (sta->sta_stats.rx_probersp_uo_pkts)
-
-#define sta_last_rx_probersp_uo_pkts(sta) \
- (sta->sta_stats.last_rx_probersp_uo_pkts)
-
-#define sta_update_last_rx_pkts(sta) \
- do { \
- sta->sta_stats.last_rx_mgnt_pkts = sta->sta_stats.rx_mgnt_pkts; \
- sta->sta_stats.last_rx_beacon_pkts = sta->sta_stats.rx_beacon_pkts; \
- sta->sta_stats.last_rx_probereq_pkts = sta->sta_stats.rx_probereq_pkts; \
- sta->sta_stats.last_rx_probersp_pkts = sta->sta_stats.rx_probersp_pkts; \
- sta->sta_stats.last_rx_probersp_bm_pkts = sta->sta_stats.rx_probersp_bm_pkts; \
- sta->sta_stats.last_rx_probersp_uo_pkts = sta->sta_stats.rx_probersp_uo_pkts; \
- sta->sta_stats.last_rx_ctrl_pkts = sta->sta_stats.rx_ctrl_pkts; \
- sta->sta_stats.last_rx_data_pkts = sta->sta_stats.rx_data_pkts; \
- } while (0)
-
-#define STA_RX_PKTS_ARG(sta) \
- sta->sta_stats.rx_mgnt_pkts \
- , sta->sta_stats.rx_ctrl_pkts \
- , sta->sta_stats.rx_data_pkts
-
-#define STA_LAST_RX_PKTS_ARG(sta) \
- sta->sta_stats.last_rx_mgnt_pkts, \
- sta->sta_stats.last_rx_ctrl_pkts, \
- sta->sta_stats.last_rx_data_pkts
-
-#define STA_RX_PKTS_DIFF_ARG(sta) \
- sta->sta_stats.rx_mgnt_pkts - sta->sta_stats.last_rx_mgnt_pkts, \
- sta->sta_stats.rx_ctrl_pkts - sta->sta_stats.last_rx_ctrl_pkts, \
- sta->sta_stats.rx_data_pkts - sta->sta_stats.last_rx_data_pkts
-
-#define STA_PKTS_FMT "(m:%llu, c:%llu, d:%llu)"
-
-struct sta_priv {
- spinlock_t sta_hash_lock;
- struct list_head sta_hash[NUM_STA];
- int asoc_sta_count;
-
- struct rtw_adapter *padapter;
- struct list_head asoc_list;
- struct list_head auth_list;
- spinlock_t asoc_list_lock;
- spinlock_t auth_list_lock;
- u8 asoc_list_cnt;
- u8 auth_list_cnt;
-
- unsigned int auth_to; /* sec, time to expire in authenticating. */
- unsigned int assoc_to; /* sec, time to expire before associating. */
- unsigned int expire_to; /* sec , time to expire after associated. */
-
- /* pointers to STA info; based on allocated AID or NULL if AID free
- * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1
- * and so on
- */
- struct sta_info *sta_aid[NUM_STA];
-
- u16 sta_dz_bitmap;/* only support 15 stations, station aid bitmap
- * for sleeping sta. */
- u16 tim_bitmap;/* only support 15 stations,
- * aid=0~15 mapping bit0~bit15 */
-
- u16 max_num_sta;
-
- struct wlan_acl_pool acl_list;
-};
-
-static inline u32 wifi_mac_hash(const u8 *mac)
-{
- u32 x;
-
- x = mac[0];
- x = (x << 2) ^ mac[1];
- x = (x << 2) ^ mac[2];
- x = (x << 2) ^ mac[3];
- x = (x << 2) ^ mac[4];
- x = (x << 2) ^ mac[5];
-
- x ^= x >> 8;
- x = x & (NUM_STA - 1);
-
- return x;
-}
-
-int _rtw_init_sta_priv23a(struct sta_priv *pstapriv);
-int _rtw_free_sta_priv23a(struct sta_priv *pstapriv);
-
-struct sta_info *rtw_alloc_stainfo23a(struct sta_priv *pstapriv, const u8 *hwaddr, gfp_t gfp);
-int rtw_free_stainfo23a(struct rtw_adapter *padapter, struct sta_info *psta);
-void rtw_free_all_stainfo23a(struct rtw_adapter *padapter);
-struct sta_info *rtw_get_stainfo23a(struct sta_priv *pstapriv, const u8 *hwaddr);
-int rtw_init_bcmc_stainfo23a(struct rtw_adapter *padapter);
-struct sta_info *rtw_get_bcmc_stainfo23a(struct rtw_adapter *padapter);
-bool rtw_access_ctrl23a(struct rtw_adapter *padapter, u8 *mac_addr);
-
-#endif /* _STA_INFO_H_ */
diff --git a/drivers/staging/rtl8723au/include/usb_ops.h b/drivers/staging/rtl8723au/include/usb_ops.h
deleted file mode 100644
index ff11e13b24a8..000000000000
--- a/drivers/staging/rtl8723au/include/usb_ops.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __USB_OPS_H_
-#define __USB_OPS_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <osdep_intf.h>
-#include <usb_ops_linux.h>
-
-#define REALTEK_USB_VENQT_READ 0xC0
-#define REALTEK_USB_VENQT_WRITE 0x40
-#define REALTEK_USB_VENQT_CMD_REQ 0x05
-#define REALTEK_USB_VENQT_CMD_IDX 0x00
-
-enum {
- VENDOR_WRITE = 0x00,
- VENDOR_READ = 0x01,
-};
-
-#define ALIGNMENT_UNIT 16
-#define MAX_VENDOR_REQ_CMD_SIZE 254 /* 8188cu SIE Support */
-#define MAX_USB_IO_CTL_SIZE (MAX_VENDOR_REQ_CMD_SIZE +ALIGNMENT_UNIT)
-
-void rtl8723au_set_hw_type(struct rtw_adapter *padapter);
-
-void rtl8723au_recv_tasklet(void *priv);
-
-void rtl8723au_xmit_tasklet(void *priv);
-
-/* Increase and check if the continual_urb_error of this @param dvobjprive is
- * larger than MAX_CONTINUAL_URB_ERR. Return result
- */
-static inline int rtw_inc_and_chk_continual_urb_error(struct dvobj_priv *dvobj)
-{
- int ret = false;
- int value;
-
- value = atomic_inc_return(&dvobj->continual_urb_error);
- if (value > MAX_CONTINUAL_URB_ERR) {
- DBG_8723A("[dvobj:%p][ERROR] continual_urb_error:%d > %d\n",
- dvobj, value, MAX_CONTINUAL_URB_ERR);
- ret = true;
- }
- return ret;
-}
-
-/* Set the continual_urb_error of this @param dvobjprive to 0 */
-static inline void rtw_reset_continual_urb_error(struct dvobj_priv *dvobj)
-{
- atomic_set(&dvobj->continual_urb_error, 0);
-}
-
-bool rtl8723au_chip_configure(struct rtw_adapter *padapter);
-
-#endif /* __USB_OPS_H_ */
diff --git a/drivers/staging/rtl8723au/include/usb_ops_linux.h b/drivers/staging/rtl8723au/include/usb_ops_linux.h
deleted file mode 100644
index af2f14b8b360..000000000000
--- a/drivers/staging/rtl8723au/include/usb_ops_linux.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __USB_OPS_LINUX_H__
-#define __USB_OPS_LINUX_H__
-
-#define VENDOR_CMD_MAX_DATA_LEN 254
-
-#define RTW_USB_CONTROL_MSG_TIMEOUT 500/* ms */
-
-#define MAX_USBCTRL_VENDORREQ_TIMES 10
-
-int rtl8723au_read_port(struct rtw_adapter *adapter, u32 cnt,
- struct recv_buf *precvbuf);
-void rtl8723au_read_port_cancel(struct rtw_adapter *padapter);
-int rtl8723au_write_port(struct rtw_adapter *padapter, u32 addr, u32 cnt,
- struct xmit_buf *pxmitbuf);
-void rtl8723au_write_port_cancel(struct rtw_adapter *padapter);
-int rtl8723au_read_interrupt(struct rtw_adapter *adapter);
-
-u8 rtl8723au_read8(struct rtw_adapter *padapter, u16 addr);
-u16 rtl8723au_read16(struct rtw_adapter *padapter, u16 addr);
-u32 rtl8723au_read32(struct rtw_adapter *padapter, u16 addr);
-int rtl8723au_write8(struct rtw_adapter *padapter, u16 addr, u8 val);
-int rtl8723au_write16(struct rtw_adapter *padapter, u16 addr, u16 val);
-int rtl8723au_write32(struct rtw_adapter *padapter, u16 addr, u32 val);
-int rtl8723au_writeN(struct rtw_adapter *padapter,
- u16 addr, u16 length, u8 *pdata);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/wifi.h b/drivers/staging/rtl8723au/include/wifi.h
deleted file mode 100644
index 25d573c3e232..000000000000
--- a/drivers/staging/rtl8723au/include/wifi.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef _WIFI_H_
-#define _WIFI_H_
-
-/* This value is tested by WiFi 11n Test Plan 5.2.3.
- * This test verifies the WLAN NIC can update the NAV through sending
- * the CTS with large duration.
- */
-#define WiFiNavUpperUs 30000 /* 30 ms */
-
-/*-----------------------------------------------------------------------------
- Below is the definition for 802.11n
-------------------------------------------------------------------------------*/
-
-struct AC_param {
- u8 ACI_AIFSN;
- u8 CW;
- __le16 TXOP_limit;
-} __packed;
-
-struct WMM_para_element {
- unsigned char QoS_info;
- unsigned char reserved;
- struct AC_param ac_param[4];
-} __packed;
-
-struct ADDBA_request {
- u8 dialog_token;
- __le16 BA_para_set;
- __le16 BA_timeout_value;
- __le16 BA_starting_seqctrl;
-} __packed;
-
-
-/* ===============WPS Section=============== */
-/* WPS attribute ID */
-#define WPS_ATTR_VER1 0x104A
-#define WPS_ATTR_SIMPLE_CONF_STATE 0x1044
-#define WPS_ATTR_RESP_TYPE 0x103B
-#define WPS_ATTR_UUID_E 0x1047
-#define WPS_ATTR_MANUFACTURER 0x1021
-#define WPS_ATTR_MODEL_NAME 0x1023
-#define WPS_ATTR_MODEL_NUMBER 0x1024
-#define WPS_ATTR_SERIAL_NUMBER 0x1042
-#define WPS_ATTR_PRIMARY_DEV_TYPE 0x1054
-#define WPS_ATTR_SEC_DEV_TYPE_LIST 0x1055
-#define WPS_ATTR_DEVICE_NAME 0x1011
-#define WPS_ATTR_CONF_METHOD 0x1008
-#define WPS_ATTR_RF_BANDS 0x103C
-#define WPS_ATTR_DEVICE_PWID 0x1012
-#define WPS_ATTR_REQUEST_TYPE 0x103A
-#define WPS_ATTR_ASSOCIATION_STATE 0x1002
-#define WPS_ATTR_CONFIG_ERROR 0x1009
-#define WPS_ATTR_VENDOR_EXT 0x1049
-#define WPS_ATTR_SELECTED_REGISTRAR 0x1041
-
-/* WPS Configuration Method */
-#define WPS_CM_NONE 0x0000
-#define WPS_CM_LABEL 0x0004
-#define WPS_CM_DISPLYA 0x0008
-#define WPS_CM_EXTERNAL_NFC_TOKEN 0x0010
-#define WPS_CM_INTEGRATED_NFC_TOKEN 0x0020
-#define WPS_CM_NFC_INTERFACE 0x0040
-#define WPS_CM_PUSH_BUTTON 0x0080
-#define WPS_CM_KEYPAD 0x0100
-#define WPS_CM_SW_PUHS_BUTTON 0x0280
-#define WPS_CM_HW_PUHS_BUTTON 0x0480
-#define WPS_CM_SW_DISPLAY_PIN 0x2008
-#define WPS_CM_LCD_DISPLAY_PIN 0x4008
-
-#endif /* _WIFI_H_ */
diff --git a/drivers/staging/rtl8723au/include/wlan_bssdef.h b/drivers/staging/rtl8723au/include/wlan_bssdef.h
deleted file mode 100644
index 95b32e15a4d0..000000000000
--- a/drivers/staging/rtl8723au/include/wlan_bssdef.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __WLAN_BSSDEF_H__
-#define __WLAN_BSSDEF_H__
-
-
-#define MAX_IE_SZ 768
-
-
-#define NDIS_802_11_LENGTH_RATES 8
-#define NDIS_802_11_LENGTH_RATES_EX 16
-
-/* Length is the 4 bytes multiples of the sum of
- * sizeof(6 * sizeof(unsigned char)) + 2 + sizeof(struct ndis_802_11_ssid) +
- * sizeof(u32) + sizeof(long) + sizeof(enum ndis_802_11_net_type) +
- * sizeof(struct ndis_802_11_config) + sizeof(sizeof(unsigned char) *
- * NDIS_802_11_LENGTH_RATES_EX) + IELength
- *
- * Except the IELength, all other fields are fixed length. Therefore,
- * we can define a macro to present the partial sum.
- */
-
-enum ndis_802_11_auth_mode {
- Ndis802_11AuthModeOpen,
- Ndis802_11AuthModeShared,
- Ndis802_11AuthModeAutoSwitch,
- Ndis802_11AuthModeWPA,
- Ndis802_11AuthModeWPAPSK,
- Ndis802_11AuthModeWPANone,
- dis802_11AuthModeMax /* upper bound */
-};
-
-enum {
- Ndis802_11WEPEnabled,
- Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
- Ndis802_11WEPDisabled,
- Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
- Ndis802_11WEPKeyAbsent,
- Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
- Ndis802_11WEPNotSupported,
- Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
- Ndis802_11Encryption2Enabled,
- Ndis802_11Encryption2KeyAbsent,
- Ndis802_11Encryption3Enabled,
- Ndis802_11Encryption3KeyAbsent,
-};
-
-struct wlan_bcn_info {
- /* these infor get from rtw_get_encrypt_info when
- * * translate scan to UI */
- u8 encryp_protocol;/* ENCRYP_PROTOCOL_E: OPEN/WEP/WPA/WPA2 */
- int group_cipher; /* WPA/WPA2 group cipher */
- int pairwise_cipher;/* WPA/WPA2/WEP pairwise cipher */
- int is_8021x;
-
- /* bwmode 20/40 and ch_offset UP/LOW */
-};
-
-struct wlan_bssid_ex {
- u32 Length;
- u8 MacAddress[ETH_ALEN];
- u16 reserved;
- struct cfg80211_ssid Ssid;
- u32 Privacy;
- long Rssi;/* in dBM, raw data , get from PHY) */
- u16 beacon_interval;
- u16 capability;
- u64 tsf;
- u32 ATIMWindow; /* units are Kusec */
- u32 DSConfig; /* Frequency, units are kHz */
- enum nl80211_iftype ifmode;
- unsigned char SupportedRates[NDIS_802_11_LENGTH_RATES_EX];
- u8 SignalStrength;/* in percentage */
- u8 SignalQuality;/* in percentage */
- u32 IELength;
- u8 IEs[MAX_IE_SZ]; /* timestamp, beacon interval, and capability info*/
-} __packed;
-
-static inline uint get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss)
-{
- return sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + bss->IELength;
-}
-
-struct wlan_network {
- struct list_head list;
- int network_type; /* refer to ieee80211.h for 11A/B/G */
- /* set to fixed when not to be removed as site-surveying */
- int fixed;
- unsigned long last_scanned; /* timestamp for the network */
- int join_res;
- struct wlan_bssid_ex network; /* must be the last item */
- struct wlan_bcn_info BcnInfo;
-};
-
-enum VRTL_CARRIER_SENSE {
- DISABLE_VCS,
- ENABLE_VCS,
- AUTO_VCS
-};
-
-enum VCS_TYPE {
- NONE_VCS,
- RTS_CTS,
- CTS_TO_SELF
-};
-
-/* john */
-#define NUM_PRE_AUTH_KEY 16
-#define NUM_PMKID_CACHE NUM_PRE_AUTH_KEY
-
-#endif /* ifndef WLAN_BSSDEF_H_ */
diff --git a/drivers/staging/rtl8723au/include/xmit_osdep.h b/drivers/staging/rtl8723au/include/xmit_osdep.h
deleted file mode 100644
index 2be04c48656c..000000000000
--- a/drivers/staging/rtl8723au/include/xmit_osdep.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#ifndef __XMIT_OSDEP_H_
-#define __XMIT_OSDEP_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-
-#define NR_XMITFRAME 256
-
-int rtw_xmit23a_entry23a(struct sk_buff *pkt, struct net_device *pnetdev);
-
-void rtw_os_xmit_schedule23a(struct rtw_adapter *padapter);
-
-int rtw_os_xmit_resource_alloc23a(struct rtw_adapter *padapter,
- struct xmit_buf *pxmitbuf, u32 alloc_sz);
-void rtw_os_xmit_resource_free23a(struct rtw_adapter *padapter,
- struct xmit_buf *pxmitbuf);
-
-void rtw_os_pkt_complete23a(struct rtw_adapter *padapter, struct sk_buff *pkt);
-void rtw_os_xmit_complete23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxframe);
-int netdev_open23a(struct net_device *pnetdev);
-
-#endif /* __XMIT_OSDEP_H_ */
diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
deleted file mode 100644
index d0ba3778990e..000000000000
--- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
+++ /dev/null
@@ -1,3348 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _IOCTL_CFG80211_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <xmit_osdep.h>
-
-#include "ioctl_cfg80211.h"
-
-#define RTW_MAX_MGMT_TX_CNT 8
-
-#define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 65535 /* ms */
-#define RTW_MAX_NUM_PMKIDS 4
-
-static const u32 rtw_cipher_suites[] = {
- WLAN_CIPHER_SUITE_WEP40,
- WLAN_CIPHER_SUITE_WEP104,
- WLAN_CIPHER_SUITE_TKIP,
- WLAN_CIPHER_SUITE_CCMP,
-};
-
-#define RATETAB_ENT(_rate, _rateid, _flags) { \
- .bitrate = (_rate), \
- .hw_value = (_rateid), \
- .flags = (_flags), \
-}
-
-#define CHAN2G(_channel, _freq, _flags) { \
- .band = NL80211_BAND_2GHZ, \
- .center_freq = (_freq), \
- .hw_value = (_channel), \
- .flags = (_flags), \
- .max_antenna_gain = 0, \
- .max_power = 30, \
-}
-
-#define CHAN5G(_channel, _flags) { \
- .band = NL80211_BAND_5GHZ, \
- .center_freq = 5000 + (5 * (_channel)), \
- .hw_value = (_channel), \
- .flags = (_flags), \
- .max_antenna_gain = 0, \
- .max_power = 30, \
-}
-
-static struct ieee80211_rate rtw_rates[] = {
- RATETAB_ENT(10, 0x1, 0),
- RATETAB_ENT(20, 0x2, 0),
- RATETAB_ENT(55, 0x4, 0),
- RATETAB_ENT(110, 0x8, 0),
- RATETAB_ENT(60, 0x10, 0),
- RATETAB_ENT(90, 0x20, 0),
- RATETAB_ENT(120, 0x40, 0),
- RATETAB_ENT(180, 0x80, 0),
- RATETAB_ENT(240, 0x100, 0),
- RATETAB_ENT(360, 0x200, 0),
- RATETAB_ENT(480, 0x400, 0),
- RATETAB_ENT(540, 0x800, 0),
-};
-
-#define rtw_a_rates (rtw_rates + 4)
-#define RTW_A_RATES_NUM 8
-#define rtw_g_rates (rtw_rates + 0)
-#define RTW_G_RATES_NUM 12
-
-#define RTW_2G_CHANNELS_NUM 14
-#define RTW_5G_CHANNELS_NUM 37
-
-static struct ieee80211_channel rtw_2ghz_channels[] = {
- CHAN2G(1, 2412, 0),
- CHAN2G(2, 2417, 0),
- CHAN2G(3, 2422, 0),
- CHAN2G(4, 2427, 0),
- CHAN2G(5, 2432, 0),
- CHAN2G(6, 2437, 0),
- CHAN2G(7, 2442, 0),
- CHAN2G(8, 2447, 0),
- CHAN2G(9, 2452, 0),
- CHAN2G(10, 2457, 0),
- CHAN2G(11, 2462, 0),
- CHAN2G(12, 2467, 0),
- CHAN2G(13, 2472, 0),
- CHAN2G(14, 2484, 0),
-};
-
-static struct ieee80211_channel rtw_5ghz_a_channels[] = {
- CHAN5G(34, 0), CHAN5G(36, 0),
- CHAN5G(38, 0), CHAN5G(40, 0),
- CHAN5G(42, 0), CHAN5G(44, 0),
- CHAN5G(46, 0), CHAN5G(48, 0),
- CHAN5G(52, 0), CHAN5G(56, 0),
- CHAN5G(60, 0), CHAN5G(64, 0),
- CHAN5G(100, 0), CHAN5G(104, 0),
- CHAN5G(108, 0), CHAN5G(112, 0),
- CHAN5G(116, 0), CHAN5G(120, 0),
- CHAN5G(124, 0), CHAN5G(128, 0),
- CHAN5G(132, 0), CHAN5G(136, 0),
- CHAN5G(140, 0), CHAN5G(149, 0),
- CHAN5G(153, 0), CHAN5G(157, 0),
- CHAN5G(161, 0), CHAN5G(165, 0),
- CHAN5G(184, 0), CHAN5G(188, 0),
- CHAN5G(192, 0), CHAN5G(196, 0),
- CHAN5G(200, 0), CHAN5G(204, 0),
- CHAN5G(208, 0), CHAN5G(212, 0),
- CHAN5G(216, 0),
-};
-
-static void rtw_2g_channels_init(struct ieee80211_channel *channels)
-{
- memcpy((void *)channels, (void *)rtw_2ghz_channels,
- sizeof(struct ieee80211_channel) * RTW_2G_CHANNELS_NUM);
-}
-
-static void rtw_5g_channels_init(struct ieee80211_channel *channels)
-{
- memcpy((void *)channels, (void *)rtw_5ghz_a_channels,
- sizeof(struct ieee80211_channel) * RTW_5G_CHANNELS_NUM);
-}
-
-static void rtw_2g_rates_init(struct ieee80211_rate *rates)
-{
- memcpy(rates, rtw_g_rates,
- sizeof(struct ieee80211_rate) * RTW_G_RATES_NUM);
-}
-
-static void rtw_5g_rates_init(struct ieee80211_rate *rates)
-{
- memcpy(rates, rtw_a_rates,
- sizeof(struct ieee80211_rate) * RTW_A_RATES_NUM);
-}
-
-static struct ieee80211_supported_band *
-rtw_spt_band_alloc(enum nl80211_band band)
-{
- struct ieee80211_supported_band *spt_band = NULL;
- int n_channels, n_bitrates;
-
- if (band == NL80211_BAND_2GHZ) {
- n_channels = RTW_2G_CHANNELS_NUM;
- n_bitrates = RTW_G_RATES_NUM;
- } else if (band == NL80211_BAND_5GHZ) {
- n_channels = RTW_5G_CHANNELS_NUM;
- n_bitrates = RTW_A_RATES_NUM;
- } else {
- goto exit;
- }
- spt_band = kzalloc(sizeof(struct ieee80211_supported_band) +
- sizeof(struct ieee80211_channel) * n_channels +
- sizeof(struct ieee80211_rate) * n_bitrates,
- GFP_KERNEL);
- if (!spt_band)
- goto exit;
-
- spt_band->channels =
- (struct ieee80211_channel *)(((u8 *) spt_band) +
- sizeof(struct
- ieee80211_supported_band));
- spt_band->bitrates =
- (struct ieee80211_rate *)(((u8 *) spt_band->channels) +
- sizeof(struct ieee80211_channel) *
- n_channels);
- spt_band->band = band;
- spt_band->n_channels = n_channels;
- spt_band->n_bitrates = n_bitrates;
-
- if (band == NL80211_BAND_2GHZ) {
- rtw_2g_channels_init(spt_band->channels);
- rtw_2g_rates_init(spt_band->bitrates);
- } else if (band == NL80211_BAND_5GHZ) {
- rtw_5g_channels_init(spt_band->channels);
- rtw_5g_rates_init(spt_band->bitrates);
- }
-
- /* spt_band.ht_cap */
-
-exit:
- return spt_band;
-}
-
-static const struct ieee80211_txrx_stypes
-rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
- [NL80211_IFTYPE_ADHOC] = {
- .tx = 0xffff,
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
- },
- [NL80211_IFTYPE_STATION] = {
- .tx = 0xffff,
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
- },
- [NL80211_IFTYPE_AP] = {
- .tx = 0xffff,
- .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
- BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
- BIT(IEEE80211_STYPE_DISASSOC >> 4) |
- BIT(IEEE80211_STYPE_AUTH >> 4) |
- BIT(IEEE80211_STYPE_DEAUTH >> 4) |
- BIT(IEEE80211_STYPE_ACTION >> 4)
- },
- [NL80211_IFTYPE_AP_VLAN] = {
- /* copy AP */
- .tx = 0xffff,
- .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
- BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
- BIT(IEEE80211_STYPE_DISASSOC >> 4) |
- BIT(IEEE80211_STYPE_AUTH >> 4) |
- BIT(IEEE80211_STYPE_DEAUTH >> 4) |
- BIT(IEEE80211_STYPE_ACTION >> 4)
- },
- [NL80211_IFTYPE_P2P_CLIENT] = {
- .tx = 0xffff,
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
- },
- [NL80211_IFTYPE_P2P_GO] = {
- .tx = 0xffff,
- .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
- BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
- BIT(IEEE80211_STYPE_DISASSOC >> 4) |
- BIT(IEEE80211_STYPE_AUTH >> 4) |
- BIT(IEEE80211_STYPE_DEAUTH >> 4) |
- BIT(IEEE80211_STYPE_ACTION >> 4)
- },
-};
-
-static int rtw_cfg80211_inform_bss(struct rtw_adapter *padapter,
- struct wlan_network *pnetwork)
-{
- int ret = 0;
- struct ieee80211_channel *notify_channel;
- struct cfg80211_bss *bss;
- u16 channel;
- u32 freq;
- u8 *notify_ie;
- size_t notify_ielen;
- s32 notify_signal;
- struct wireless_dev *wdev = padapter->rtw_wdev;
- struct wiphy *wiphy = wdev->wiphy;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- channel = pnetwork->network.DSConfig;
- if (channel <= RTW_CH_MAX_2G_CHANNEL)
- freq = ieee80211_channel_to_frequency(channel,
- NL80211_BAND_2GHZ);
- else
- freq = ieee80211_channel_to_frequency(channel,
- NL80211_BAND_5GHZ);
-
- notify_channel = ieee80211_get_channel(wiphy, freq);
-
- notify_ie = pnetwork->network.IEs;
- notify_ielen = pnetwork->network.IELength;
-
- /* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM:
- * signal strength in mBm (100*dBm)
- */
- if (check_fwstate(pmlmepriv, _FW_LINKED) &&
- is_same_network23a(&pmlmepriv->cur_network.network,
- &pnetwork->network)) {
- notify_signal = 100 * translate_percentage_to_dbm(padapter->recvpriv.signal_strength); /* dbm */
- } else {
- notify_signal = 100 * translate_percentage_to_dbm(
- pnetwork->network.SignalStrength); /* dbm */
- }
-
- bss = cfg80211_inform_bss(wiphy, notify_channel,
- CFG80211_BSS_FTYPE_UNKNOWN,
- pnetwork->network.MacAddress,
- pnetwork->network.tsf,
- pnetwork->network.capability,
- pnetwork->network.beacon_interval,
- notify_ie, notify_ielen,
- notify_signal, GFP_ATOMIC);
-
- if (unlikely(!bss)) {
- DBG_8723A("rtw_cfg80211_inform_bss error\n");
- return -EINVAL;
- }
-
- cfg80211_put_bss(wiphy, bss);
-
- return ret;
-}
-
-void rtw_cfg80211_indicate_connect(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_network *cur_network = &pmlmepriv->cur_network;
- struct wireless_dev *pwdev = padapter->rtw_wdev;
-
- DBG_8723A("%s(padapter =%p)\n", __func__, padapter);
-
- if (pwdev->iftype != NL80211_IFTYPE_STATION &&
- pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
- return;
-
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
- return;
-
- if (padapter->mlmepriv.to_roaming > 0) {
- struct wiphy *wiphy = pwdev->wiphy;
- struct ieee80211_channel *notify_channel;
- u32 freq;
- u16 channel = cur_network->network.DSConfig;
-
- if (channel <= RTW_CH_MAX_2G_CHANNEL)
- freq =
- ieee80211_channel_to_frequency(channel,
- NL80211_BAND_2GHZ);
- else
- freq =
- ieee80211_channel_to_frequency(channel,
- NL80211_BAND_5GHZ);
-
- notify_channel = ieee80211_get_channel(wiphy, freq);
-
- DBG_8723A("%s call cfg80211_roamed\n", __func__);
- cfg80211_roamed(padapter->pnetdev, notify_channel,
- cur_network->network.MacAddress,
- pmlmepriv->assoc_req +
- sizeof(struct ieee80211_hdr_3addr) + 2,
- pmlmepriv->assoc_req_len -
- sizeof(struct ieee80211_hdr_3addr) - 2,
- pmlmepriv->assoc_rsp +
- sizeof(struct ieee80211_hdr_3addr) + 6,
- pmlmepriv->assoc_rsp_len -
- sizeof(struct ieee80211_hdr_3addr) - 6,
- GFP_ATOMIC);
- } else {
- cfg80211_connect_result(padapter->pnetdev,
- cur_network->network.MacAddress,
- pmlmepriv->assoc_req +
- sizeof(struct ieee80211_hdr_3addr) + 2,
- pmlmepriv->assoc_req_len -
- sizeof(struct ieee80211_hdr_3addr) - 2,
- pmlmepriv->assoc_rsp +
- sizeof(struct ieee80211_hdr_3addr) + 6,
- pmlmepriv->assoc_rsp_len -
- sizeof(struct ieee80211_hdr_3addr) - 6,
- WLAN_STATUS_SUCCESS, GFP_ATOMIC);
- }
-}
-
-void rtw_cfg80211_indicate_disconnect(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wireless_dev *pwdev = padapter->rtw_wdev;
-
- DBG_8723A("%s(padapter =%p)\n", __func__, padapter);
-
- if (pwdev->iftype != NL80211_IFTYPE_STATION &&
- pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
- return;
-
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
- return;
-
- if (!padapter->mlmepriv.not_indic_disco) {
- if (check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING)) {
- cfg80211_connect_result(padapter->pnetdev, NULL, NULL,
- 0, NULL, 0,
- WLAN_STATUS_UNSPECIFIED_FAILURE,
- GFP_ATOMIC);
- } else {
- cfg80211_disconnected(padapter->pnetdev, 0, NULL,
- 0, false, GFP_ATOMIC);
- }
- }
-}
-
-#ifdef CONFIG_8723AU_AP_MODE
-static int set_pairwise_key(struct rtw_adapter *padapter, struct sta_info *psta)
-{
- struct cmd_obj *ph2c;
- struct set_stakey_parm *psetstakey_para;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- int res = _SUCCESS;
-
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
-
- psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
- if (psetstakey_para == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
-
- psetstakey_para->algorithm = psta->dot118021XPrivacy;
-
- ether_addr_copy(psetstakey_para->addr, psta->hwaddr);
-
- memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
-
- res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
-
-exit:
- return res;
-}
-
-static int set_group_key(struct rtw_adapter *padapter, struct key_params *parms,
- u32 alg, u8 keyid)
-{
- struct cmd_obj *pcmd;
- struct setkey_parm *psetkeyparm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- int res = _SUCCESS;
-
- DBG_8723A("%s\n", __func__);
-
- if (keyid >= 4) {
- res = _FAIL;
- goto exit;
- }
-
- pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
- if (!pcmd) {
- res = _FAIL;
- goto exit;
- }
- psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
- if (!psetkeyparm) {
- kfree(pcmd);
- res = _FAIL;
- goto exit;
- }
-
- psetkeyparm->keyid = keyid;
- if (is_wep_enc(alg))
- padapter->mlmepriv.key_mask |= BIT(psetkeyparm->keyid);
-
- psetkeyparm->algorithm = alg;
-
- psetkeyparm->set_tx = 1;
-
- memcpy(&psetkeyparm->key, parms->key, parms->key_len);
-
- pcmd->cmdcode = _SetKey_CMD_;
- pcmd->parmbuf = (u8 *) psetkeyparm;
- pcmd->cmdsz = sizeof(struct setkey_parm);
- pcmd->rsp = NULL;
- pcmd->rspsz = 0;
-
- res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
-
-exit:
- return res;
-}
-
-static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, u8 key_index,
- int set_tx, const u8 *sta_addr,
- struct key_params *keyparms)
-{
- int key_len;
- struct sta_info *psta = NULL, *pbcmc_sta = NULL;
- struct rtw_adapter *padapter = netdev_priv(dev);
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- DBG_8723A("%s\n", __func__);
-
- if (!is_broadcast_ether_addr(sta_addr)) {
- psta = rtw_get_stainfo23a(pstapriv, sta_addr);
- if (!psta) {
- /* ret = -EINVAL; */
- DBG_8723A("rtw_set_encryption(), sta has already "
- "been removed or never been added\n");
- goto exit;
- }
- }
-
- key_len = keyparms->key_len;
-
- if (!psta && (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 ||
- keyparms->cipher == WLAN_CIPHER_SUITE_WEP104)) {
- DBG_8723A("r871x_set_encryption, crypt.alg = WEP\n");
-
- DBG_8723A("r871x_set_encryption, wep_key_idx =%d, len =%d\n",
- key_index, key_len);
-
- if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
- /* wep default key has not been set, so use
- this key index as default key. */
-
- psecuritypriv->ndisencryptstatus =
- Ndis802_11Encryption1Enabled;
- psecuritypriv->dot11PrivacyAlgrthm = keyparms->cipher;
- psecuritypriv->dot118021XGrpPrivacy = keyparms->cipher;
-
- psecuritypriv->dot11PrivacyKeyIndex = key_index;
- }
-
- memcpy(&psecuritypriv->wep_key[key_index].key,
- keyparms->key, key_len);
-
- psecuritypriv->wep_key[key_index].keylen = key_len;
-
- set_group_key(padapter, keyparms, keyparms->cipher, key_index);
-
- goto exit;
- }
-
- if (!psta) { /* group key */
- if (set_tx == 0) { /* group key */
- if (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 ||
- keyparms->cipher == WLAN_CIPHER_SUITE_WEP104) {
- DBG_8723A("%s, set group_key, WEP\n", __func__);
-
- memcpy(psecuritypriv->
- dot118021XGrpKey[key_index].skey,
- keyparms->key, key_len);
-
- psecuritypriv->dot118021XGrpPrivacy =
- keyparms->cipher;
- } else if (keyparms->cipher == WLAN_CIPHER_SUITE_TKIP) {
- DBG_8723A("%s, set group_key, TKIP\n",
- __func__);
-
- psecuritypriv->dot118021XGrpPrivacy =
- WLAN_CIPHER_SUITE_TKIP;
-
- memcpy(psecuritypriv->
- dot118021XGrpKey[key_index].skey,
- keyparms->key,
- (min(16, key_len)));
-
- /* set mic key */
- memcpy(psecuritypriv->
- dot118021XGrptxmickey[key_index].skey,
- &keyparms->key[16], 8);
- memcpy(psecuritypriv->
- dot118021XGrprxmickey[key_index].skey,
- &keyparms->key[24], 8);
-
- psecuritypriv->busetkipkey = 1;
-
- } else if (keyparms->cipher == WLAN_CIPHER_SUITE_CCMP) {
- DBG_8723A("%s, set group_key, CCMP\n",
- __func__);
-
- psecuritypriv->dot118021XGrpPrivacy =
- WLAN_CIPHER_SUITE_CCMP;
-
- memcpy(psecuritypriv->
- dot118021XGrpKey[key_index].skey,
- keyparms->key,
- (min(16, key_len)));
- } else {
- DBG_8723A("%s, set group_key, none\n",
- __func__);
-
- psecuritypriv->dot118021XGrpPrivacy = 0;
- }
-
- psecuritypriv->dot118021XGrpKeyid = key_index;
-
- psecuritypriv->binstallGrpkey = 1;
-
- psecuritypriv->dot11PrivacyAlgrthm =
- psecuritypriv->dot118021XGrpPrivacy;
-
- set_group_key(padapter, keyparms,
- psecuritypriv->dot118021XGrpPrivacy,
- key_index);
-
- pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter);
- if (pbcmc_sta) {
- pbcmc_sta->ieee8021x_blocked = false;
- /* rx will use bmc_sta's dot118021XPrivacy */
- pbcmc_sta->dot118021XPrivacy =
- psecuritypriv->dot118021XGrpPrivacy;
-
- }
-
- }
-
- goto exit;
- }
-
- if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) {
- /* psk/802_1x */
- if (set_tx == 1) {
- /* pairwise key */
- memcpy(psta->dot118021x_UncstKey.skey,
- keyparms->key, (min(16, key_len)));
-
- if (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 ||
- keyparms->cipher == WLAN_CIPHER_SUITE_WEP104) {
- DBG_8723A("%s, set pairwise key, WEP\n",
- __func__);
-
- psecuritypriv->dot118021XGrpPrivacy =
- keyparms->cipher;
- } else if (keyparms->cipher == WLAN_CIPHER_SUITE_TKIP) {
- DBG_8723A("%s, set pairwise key, TKIP\n",
- __func__);
-
- psta->dot118021XPrivacy =
- WLAN_CIPHER_SUITE_TKIP;
-
- /* set mic key */
- memcpy(psta->dot11tkiptxmickey.skey,
- &keyparms->key[16], 8);
- memcpy(psta->dot11tkiprxmickey.skey,
- &keyparms->key[24], 8);
-
- psecuritypriv->busetkipkey = 1;
-
- } else if (keyparms->cipher == WLAN_CIPHER_SUITE_CCMP) {
- DBG_8723A("%s, set pairwise key, CCMP\n",
- __func__);
-
- psta->dot118021XPrivacy =
- WLAN_CIPHER_SUITE_CCMP;
- } else {
- DBG_8723A("%s, set pairwise key, none\n",
- __func__);
-
- psta->dot118021XPrivacy = 0;
- }
-
- set_pairwise_key(padapter, psta);
-
- psta->ieee8021x_blocked = false;
-
- psta->bpairwise_key_installed = true;
- } else { /* group key??? */
- if (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 ||
- keyparms->cipher == WLAN_CIPHER_SUITE_WEP104) {
- memcpy(psecuritypriv->
- dot118021XGrpKey[key_index].skey,
- keyparms->key, key_len);
-
- psecuritypriv->dot118021XGrpPrivacy =
- keyparms->cipher;
- } else if (keyparms->cipher == WLAN_CIPHER_SUITE_TKIP) {
- psecuritypriv->dot118021XGrpPrivacy =
- WLAN_CIPHER_SUITE_TKIP;
-
- memcpy(psecuritypriv->
- dot118021XGrpKey[key_index].skey,
- keyparms->key,
- (min(16, key_len)));
-
- /* set mic key */
- memcpy(psecuritypriv->
- dot118021XGrptxmickey[key_index].skey,
- &keyparms->key[16], 8);
- memcpy(psecuritypriv->
- dot118021XGrprxmickey[key_index].skey,
- &keyparms->key[24], 8);
-
- psecuritypriv->busetkipkey = 1;
- } else if (keyparms->cipher == WLAN_CIPHER_SUITE_CCMP) {
- psecuritypriv->dot118021XGrpPrivacy =
- WLAN_CIPHER_SUITE_CCMP;
-
- memcpy(psecuritypriv->
- dot118021XGrpKey[key_index].skey,
- keyparms->key,
- (min(16, key_len)));
- } else {
- psecuritypriv->dot118021XGrpPrivacy = 0;
- }
-
- psecuritypriv->dot118021XGrpKeyid = key_index;
-
- psecuritypriv->binstallGrpkey = 1;
-
- psecuritypriv->dot11PrivacyAlgrthm =
- psecuritypriv->dot118021XGrpPrivacy;
-
- set_group_key(padapter, keyparms,
- psecuritypriv->dot118021XGrpPrivacy,
- key_index);
-
- pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter);
- if (pbcmc_sta) {
- /* rx will use bmc_sta's
- dot118021XPrivacy */
- pbcmc_sta->ieee8021x_blocked = false;
- pbcmc_sta->dot118021XPrivacy =
- psecuritypriv->dot118021XGrpPrivacy;
- }
- }
- }
-
-exit:
-
- return 0;
-}
-#endif
-
-static int rtw_cfg80211_set_encryption(struct net_device *dev, u8 key_index,
- int set_tx, const u8 *sta_addr,
- struct key_params *keyparms)
-{
- int ret = 0;
- int key_len;
- struct rtw_adapter *padapter = netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
-
- DBG_8723A("%s\n", __func__);
-
- key_len = keyparms->key_len;
-
- if (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 ||
- keyparms->cipher == WLAN_CIPHER_SUITE_WEP104) {
- RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
- "wpa_set_encryption, crypt.alg = WEP\n");
- DBG_8723A("wpa_set_encryption, crypt.alg = WEP\n");
-
- if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
- /* wep default key has not been set, so use this
- key index as default key. */
-
- psecuritypriv->ndisencryptstatus =
- Ndis802_11Encryption1Enabled;
- psecuritypriv->dot11PrivacyAlgrthm = keyparms->cipher;
- psecuritypriv->dot118021XGrpPrivacy = keyparms->cipher;
-
- psecuritypriv->dot11PrivacyKeyIndex = key_index;
- }
-
- memcpy(&psecuritypriv->wep_key[key_index].key,
- keyparms->key, key_len);
-
- psecuritypriv->wep_key[key_index].keylen = key_len;
-
- rtw_set_key23a(padapter, psecuritypriv, key_index, 0);
-
- goto exit;
- }
-
- if (padapter->securitypriv.dot11AuthAlgrthm ==
- dot11AuthAlgrthm_8021X) { /* 802_1x */
- struct sta_info *psta, *pbcmc_sta;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- if (check_fwstate(pmlmepriv,
- WIFI_STATION_STATE | WIFI_MP_STATE)) {
- /* sta mode */
- psta = rtw_get_stainfo23a(pstapriv, get_bssid(pmlmepriv));
- if (psta == NULL) {
- DBG_8723A("%s, : Obtain Sta_info fail\n",
- __func__);
- } else {
- /* Jeff: don't disable ieee8021x_blocked
- while clearing key */
- if (keyparms->cipher != IW_AUTH_CIPHER_NONE &&
- keyparms->cipher != 0)
- psta->ieee8021x_blocked = false;
-
- if ((padapter->securitypriv.ndisencryptstatus ==
- Ndis802_11Encryption2Enabled) ||
- (padapter->securitypriv.ndisencryptstatus ==
- Ndis802_11Encryption3Enabled)) {
- psta->dot118021XPrivacy =
- padapter->securitypriv.
- dot11PrivacyAlgrthm;
- }
-
- if (set_tx == 1) {
- /* pairwise key */
- DBG_8723A("%s, : set_tx == 1\n",
- __func__);
-
- memcpy(psta->dot118021x_UncstKey.skey,
- keyparms->key,
- (min(16, key_len)));
-
- if (keyparms->cipher ==
- WLAN_CIPHER_SUITE_TKIP) {
- memcpy(psta->dot11tkiptxmickey.
- skey,
- &keyparms->key[16], 8);
- memcpy(psta->dot11tkiprxmickey.
- skey,
- &keyparms->key[24], 8);
-
- padapter->securitypriv.
- busetkipkey = 0;
- }
- DBG_8723A(" ~~~~set sta key:unicastkey\n");
-
- rtw_setstakey_cmd23a(padapter,
- (unsigned char *)psta,
- true);
- } else { /* group key */
- memcpy(padapter->securitypriv.
- dot118021XGrpKey[key_index].skey,
- keyparms->key,
- (min(16, key_len)));
- memcpy(padapter->securitypriv.
- dot118021XGrptxmickey[key_index].
- skey, &keyparms->key[16], 8);
- memcpy(padapter->securitypriv.
- dot118021XGrprxmickey[key_index].
- skey, &keyparms->key[24], 8);
- padapter->securitypriv.binstallGrpkey =
- 1;
- DBG_8723A
- (" ~~~~set sta key:groupkey\n");
-
- padapter->securitypriv.
- dot118021XGrpKeyid = key_index;
-
- rtw_set_key23a(padapter,
- &padapter->securitypriv,
- key_index, 1);
- }
- }
-
- pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter);
- if (pbcmc_sta) {
- /* Jeff: don't disable ieee8021x_blocked
- while clearing key */
- if (keyparms->cipher != IW_AUTH_CIPHER_NONE &&
- keyparms->cipher != 0)
- pbcmc_sta->ieee8021x_blocked = false;
-
- if ((padapter->securitypriv.ndisencryptstatus ==
- Ndis802_11Encryption2Enabled) ||
- (padapter->securitypriv.ndisencryptstatus ==
- Ndis802_11Encryption3Enabled)) {
- pbcmc_sta->dot118021XPrivacy =
- padapter->securitypriv.
- dot11PrivacyAlgrthm;
- }
- }
- }
- }
-
-exit:
-
- DBG_8723A("%s, ret =%d\n", __func__, ret);
-
-
-
- return ret;
-}
-
-static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_index, bool pairwise,
- const u8 *mac_addr, struct key_params *params)
-{
- int set_tx, ret = 0;
- struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
- struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- u8 sta_addr[ETH_ALEN];
-
- DBG_8723A("%s(%s): adding key for %pM\n", __func__, ndev->name,
- mac_addr);
- DBG_8723A("cipher = 0x%x\n", params->cipher);
- DBG_8723A("key_len = 0x%x\n", params->key_len);
- DBG_8723A("seq_len = 0x%x\n", params->seq_len);
- DBG_8723A("key_index =%d\n", key_index);
- DBG_8723A("pairwise =%d\n", pairwise);
-
- switch (params->cipher) {
- case IW_AUTH_CIPHER_NONE:
- case WLAN_CIPHER_SUITE_WEP40:
- if (params->key_len != WLAN_KEY_LEN_WEP40) {
- ret = -EINVAL;
- goto exit;
- }
- case WLAN_CIPHER_SUITE_WEP104:
- if (params->key_len != WLAN_KEY_LEN_WEP104) {
- ret = -EINVAL;
- goto exit;
- }
- case WLAN_CIPHER_SUITE_TKIP:
- case WLAN_CIPHER_SUITE_CCMP:
- break;
- default:
- ret = -ENOTSUPP;
- goto exit;
- }
-
- if (key_index >= WEP_KEYS || params->key_len < 0) {
- ret = -EINVAL;
- goto exit;
- }
-
- eth_broadcast_addr(sta_addr);
-
- if (!mac_addr || is_broadcast_ether_addr(mac_addr))
- set_tx = 0; /* for wpa/wpa2 group key */
- else
- set_tx = 1; /* for wpa/wpa2 pairwise key */
-
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
- ret = rtw_cfg80211_set_encryption(ndev, key_index, set_tx,
- sta_addr, params);
- } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
-#ifdef CONFIG_8723AU_AP_MODE
- if (mac_addr)
- ether_addr_copy(sta_addr, mac_addr);
-
- ret = rtw_cfg80211_ap_set_encryption(ndev, key_index, set_tx,
- sta_addr, params);
-#endif
- } else {
- DBG_8723A("error! fw_state = 0x%x, iftype =%d\n",
- pmlmepriv->fw_state, rtw_wdev->iftype);
-
- }
-
-exit:
- return ret;
-}
-
-static int
-cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_index, bool pairwise, const u8 *mac_addr,
- void *cookie,
- void (*callback) (void *cookie, struct key_params *))
-{
- DBG_8723A("%s(%s)\n", __func__, ndev->name);
- return 0;
-}
-
-static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_index, bool pairwise,
- const u8 *mac_addr)
-{
- struct rtw_adapter *padapter = netdev_priv(ndev);
- struct security_priv *psecuritypriv = &padapter->securitypriv;
-
- DBG_8723A("%s(%s): key_index =%d\n", __func__, ndev->name, key_index);
-
- if (key_index == psecuritypriv->dot11PrivacyKeyIndex) {
- /* clear the flag of wep default key set. */
- psecuritypriv->bWepDefaultKeyIdxSet = 0;
- }
-
- return 0;
-}
-
-static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
- struct net_device *ndev, u8 key_index,
- bool unicast, bool multicast)
-{
- struct rtw_adapter *padapter = netdev_priv(ndev);
- struct security_priv *psecuritypriv = &padapter->securitypriv;
-
- DBG_8723A("%s(%s): key_index =%d, unicast =%d, multicast =%d.\n",
- __func__, ndev->name, key_index, unicast, multicast);
-
- if (key_index < NUM_WEP_KEYS &&
- (psecuritypriv->dot11PrivacyAlgrthm == WLAN_CIPHER_SUITE_WEP40 ||
- psecuritypriv->dot11PrivacyAlgrthm == WLAN_CIPHER_SUITE_WEP104)) {
- /* set wep default key */
- psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
-
- psecuritypriv->dot11PrivacyKeyIndex = key_index;
-
- psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40;
- psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40;
- if (psecuritypriv->wep_key[key_index].keylen == 13) {
- psecuritypriv->dot11PrivacyAlgrthm =
- WLAN_CIPHER_SUITE_WEP104;
- psecuritypriv->dot118021XGrpPrivacy =
- WLAN_CIPHER_SUITE_WEP104;
- }
-
- /* set the flag to represent that wep default key
- has been set */
- psecuritypriv->bWepDefaultKeyIdxSet = 1;
- }
-
- return 0;
-}
-
-static u16 rtw_get_cur_max_rate(struct rtw_adapter *adapter)
-{
- int i = 0;
- const u8 *p;
- u16 rate = 0, max_rate = 0;
- struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct registry_priv *pregistrypriv = &adapter->registrypriv;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
- struct ieee80211_ht_cap *pht_capie;
- u8 rf_type = 0;
- u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0;
- u16 mcs_rate = 0;
-
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
- pcur_bss->IEs, pcur_bss->IELength);
- if (p && p[1] > 0) {
- pht_capie = (struct ieee80211_ht_cap *)(p + 2);
-
- memcpy(&mcs_rate, &pht_capie->mcs, 2);
-
- /* bw_40MHz = (pht_capie->cap_info&
- IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1:0; */
- /* cur_bwmod is updated by beacon, pmlmeinfo is
- updated by association response */
- bw_40MHz = (pmlmeext->cur_bwmode &&
- (pmlmeinfo->HT_info.ht_param &
- IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) ? 1:0;
-
- /* short_GI = (pht_capie->cap_info & (IEEE80211_HT_CAP
- _SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; */
- short_GI_20 = (pmlmeinfo->ht_cap.cap_info &
- cpu_to_le16(IEEE80211_HT_CAP_SGI_20)) ? 1:0;
- short_GI_40 = (pmlmeinfo->ht_cap.cap_info &
- cpu_to_le16(IEEE80211_HT_CAP_SGI_40)) ? 1:0;
-
- rf_type = rtl8723a_get_rf_type(adapter);
- max_rate = rtw_mcs_rate23a(rf_type, bw_40MHz &
- pregistrypriv->cbw40_enable,
- short_GI_20, short_GI_40,
- &pmlmeinfo->ht_cap.mcs);
- } else {
- while (pcur_bss->SupportedRates[i] != 0 &&
- pcur_bss->SupportedRates[i] != 0xFF) {
- rate = pcur_bss->SupportedRates[i] & 0x7F;
- if (rate > max_rate)
- max_rate = rate;
- i++;
- }
-
- max_rate = max_rate * 10 / 2;
- }
-
- return max_rate;
-}
-
-static int cfg80211_rtw_get_station(struct wiphy *wiphy,
- struct net_device *ndev,
- const u8 *mac, struct station_info *sinfo)
-{
- int ret = 0;
- struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct sta_info *psta = NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- sinfo->filled = 0;
-
- if (!mac) {
- DBG_8723A("%s(%s): mac ==%p\n", __func__, ndev->name, mac);
- ret = -ENOENT;
- goto exit;
- }
-
- psta = rtw_get_stainfo23a(pstapriv, mac);
- if (psta == NULL) {
- DBG_8723A("%s, sta_info is null\n", __func__);
- ret = -ENOENT;
- goto exit;
- }
- DBG_8723A("%s(%s): mac=%pM\n", __func__, ndev->name, mac);
-
- /* for infra./P2PClient mode */
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
- check_fwstate(pmlmepriv, _FW_LINKED)) {
- struct wlan_network *cur_network = &pmlmepriv->cur_network;
-
- if (!ether_addr_equal(mac, cur_network->network.MacAddress)) {
- DBG_8723A("%s, mismatch bssid=%pM\n",
- __func__, cur_network->network.MacAddress);
- ret = -ENOENT;
- goto exit;
- }
-
- sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
- sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.
- signal_strength);
-
- sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
- sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
-
- sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
- sinfo->rx_packets = sta_rx_data_pkts(psta);
-
- sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
- sinfo->tx_packets = psta->sta_stats.tx_pkts;
- }
-
- /* for Ad-Hoc/AP mode */
- if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
- check_fwstate(pmlmepriv, WIFI_AP_STATE)) &&
- check_fwstate(pmlmepriv, _FW_LINKED)
- ) {
- /* TODO: should acquire station info... */
- }
-
-exit:
- return ret;
-}
-
-static int cfg80211_infrastructure_mode(struct rtw_adapter *padapter,
- enum nl80211_iftype ifmode)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_network *cur_network = &pmlmepriv->cur_network;
- enum nl80211_iftype old_mode;
-
- old_mode = cur_network->network.ifmode;
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_,
- "+%s: old =%d new =%d fw_state = 0x%08x\n", __func__,
- old_mode, ifmode, get_fwstate(pmlmepriv));
-
- if (old_mode != ifmode) {
- spin_lock_bh(&pmlmepriv->lock);
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- "change mode!\n");
-
- if (old_mode == NL80211_IFTYPE_AP ||
- old_mode == NL80211_IFTYPE_P2P_GO) {
- /* change to other mode from Ndis802_11APMode */
- cur_network->join_res = -1;
-
-#ifdef CONFIG_8723AU_AP_MODE
- stop_ap_mode23a(padapter);
-#endif
- }
-
- if (check_fwstate(pmlmepriv, _FW_LINKED) ||
- old_mode == NL80211_IFTYPE_ADHOC)
- rtw_disassoc_cmd23a(padapter, 0, true);
-
- if (check_fwstate(pmlmepriv, _FW_LINKED) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
- rtw_free_assoc_resources23a(padapter, 1);
-
- if (old_mode == NL80211_IFTYPE_STATION ||
- old_mode == NL80211_IFTYPE_P2P_CLIENT ||
- old_mode == NL80211_IFTYPE_ADHOC) {
- if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- /* will clr Linked_state; before this function,
- we must have chked whether issue
- dis-assoc_cmd or not */
- rtw_indicate_disconnect23a(padapter);
- }
- }
-
- cur_network->network.ifmode = ifmode;
-
- _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
-
- switch (ifmode) {
- case NL80211_IFTYPE_ADHOC:
- set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
- break;
-
- case NL80211_IFTYPE_P2P_CLIENT:
- case NL80211_IFTYPE_STATION:
- set_fwstate(pmlmepriv, WIFI_STATION_STATE);
- break;
-
- case NL80211_IFTYPE_P2P_GO:
- case NL80211_IFTYPE_AP:
- set_fwstate(pmlmepriv, WIFI_AP_STATE);
-#ifdef CONFIG_8723AU_AP_MODE
- start_ap_mode23a(padapter);
- /* rtw_indicate_connect23a(padapter); */
-#endif
- break;
-
- default:
- break;
- }
-
- /* SecClearAllKeys(adapter); */
-
- spin_unlock_bh(&pmlmepriv->lock);
- }
-
- return _SUCCESS;
-}
-
-static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
- struct net_device *ndev,
- enum nl80211_iftype type, u32 *flags,
- struct vif_params *params)
-{
- enum nl80211_iftype old_type;
- struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
- int ret = 0;
-
- DBG_8723A("%s(%s): call netdev_open23a\n", __func__, ndev->name);
-
- old_type = rtw_wdev->iftype;
- DBG_8723A("%s(%s): old_iftype =%d, new_iftype =%d\n",
- __func__, ndev->name, old_type, type);
-
- if (old_type != type) {
- pmlmeext->action_public_rxseq = 0xffff;
- pmlmeext->action_public_dialog_token = 0xff;
- }
-
- switch (type) {
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_P2P_CLIENT:
- case NL80211_IFTYPE_STATION:
- case NL80211_IFTYPE_P2P_GO:
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_UNSPECIFIED:
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- rtw_wdev->iftype = type;
-
- if (cfg80211_infrastructure_mode(padapter, type) != _SUCCESS) {
- rtw_wdev->iftype = old_type;
- ret = -EPERM;
- goto exit;
- }
-
- rtw_setopmode_cmd23a(padapter, type);
-
-exit:
- return ret;
-}
-
-void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv,
- bool aborted)
-{
- spin_lock_bh(&pwdev_priv->scan_req_lock);
- if (pwdev_priv->scan_request != NULL) {
- DBG_8723A("%s with scan req\n", __func__);
-
- if (pwdev_priv->scan_request->wiphy !=
- pwdev_priv->rtw_wdev->wiphy) {
- DBG_8723A("error wiphy compare\n");
- } else {
- struct cfg80211_scan_info info = {
- .aborted = aborted,
- };
-
- cfg80211_scan_done(pwdev_priv->scan_request, &info);
- }
-
- pwdev_priv->scan_request = NULL;
- } else {
- DBG_8723A("%s without scan req\n", __func__);
- }
- spin_unlock_bh(&pwdev_priv->scan_req_lock);
-}
-
-void rtw_cfg80211_surveydone_event_callback(struct rtw_adapter *padapter)
-{
- struct list_head *phead;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct rtw_queue *queue = &pmlmepriv->scanned_queue;
- struct wlan_network *pnetwork, *ptmp;
-
- spin_lock_bh(&pmlmepriv->scanned_queue.lock);
- phead = get_list_head(queue);
- list_for_each_entry_safe(pnetwork, ptmp, phead, list) {
- /* report network only if the current channel set
- contains the channel to which this network belongs */
- if (rtw_ch_set_search_ch23a
- (padapter->mlmeextpriv.channel_set,
- pnetwork->network.DSConfig) >= 0)
- rtw_cfg80211_inform_bss(padapter, pnetwork);
- }
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
- /* call this after other things have been done */
- rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev),
- false);
-}
-
-static int rtw_cfg80211_set_probe_req_wpsp2pie(struct rtw_adapter *padapter,
- char *buf, int len)
-{
- int ret = 0;
- const u8 *wps_ie;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- DBG_8723A("%s, ielen =%d\n", __func__, len);
-
- if (len > 0) {
- wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WPS,
- buf, len);
- if (wps_ie) {
- DBG_8723A("probe_req_wps_ielen =%d\n", wps_ie[1]);
-
- if (pmlmepriv->wps_probe_req_ie) {
- pmlmepriv->wps_probe_req_ie_len = 0;
- kfree(pmlmepriv->wps_probe_req_ie);
- pmlmepriv->wps_probe_req_ie = NULL;
- }
-
- pmlmepriv->wps_probe_req_ie = kmemdup(wps_ie, wps_ie[1],
- GFP_KERNEL);
- if (pmlmepriv->wps_probe_req_ie == NULL) {
- DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
- __func__, __LINE__);
- return -EINVAL;
- }
- pmlmepriv->wps_probe_req_ie_len = wps_ie[1];
- }
- }
-
- return ret;
-}
-
-static int cfg80211_rtw_scan(struct wiphy *wiphy,
- struct cfg80211_scan_request *request)
-{
- int i;
- u8 _status = false;
- int ret = 0;
- struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct cfg80211_ssid ssid[RTW_SSID_SCAN_AMOUNT];
- struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
- struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
- struct cfg80211_ssid *ssids = request->ssids;
- bool need_indicate_scan_done = false;
-
- DBG_8723A("%s(%s)\n", __func__, padapter->pnetdev->name);
-
- spin_lock_bh(&pwdev_priv->scan_req_lock);
- pwdev_priv->scan_request = request;
- spin_unlock_bh(&pwdev_priv->scan_req_lock);
-
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
- DBG_8723A("%s under WIFI_AP_STATE\n", __func__);
- /* need_indicate_scan_done = true; */
- /* goto check_need_indicate_scan_done; */
- }
-
- if (rtw_pwr_wakeup(padapter) == _FAIL) {
- need_indicate_scan_done = true;
- goto check_need_indicate_scan_done;
- }
-
- if (request->ie && request->ie_len > 0) {
- rtw_cfg80211_set_probe_req_wpsp2pie(padapter,
- (u8 *) request->ie,
- request->ie_len);
- }
-
- if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true) {
- DBG_8723A("%s, bBusyTraffic == true\n", __func__);
- need_indicate_scan_done = true;
- goto check_need_indicate_scan_done;
- }
- if (rtw_is_scan_deny(padapter)) {
- DBG_8723A("%s(%s): scan deny\n", __func__,
- padapter->pnetdev->name);
- need_indicate_scan_done = true;
- goto check_need_indicate_scan_done;
- }
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) ==
- true) {
- DBG_8723A("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state);
- need_indicate_scan_done = true;
- goto check_need_indicate_scan_done;
- }
-
- memset(ssid, 0, sizeof(struct cfg80211_ssid) * RTW_SSID_SCAN_AMOUNT);
- /* parsing request ssids, n_ssids */
- for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
- DBG_8723A("ssid =%s, len =%d\n", ssids[i].ssid,
- ssids[i].ssid_len);
- memcpy(ssid[i].ssid, ssids[i].ssid, ssids[i].ssid_len);
- ssid[i].ssid_len = ssids[i].ssid_len;
- }
-
- /* parsing channels, n_channels */
- memset(ch, 0,
- sizeof(struct rtw_ieee80211_channel) * RTW_CHANNEL_SCAN_AMOUNT);
-
- if (request->n_channels == 1) {
- for (i = 0; i < request->n_channels &&
- i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
- DBG_8723A("%s:(%s):" CHAN_FMT "\n",
- __func__, padapter->pnetdev->name,
- CHAN_ARG(request->channels[i]));
- ch[i].hw_value = request->channels[i]->hw_value;
- ch[i].flags = request->channels[i]->flags;
- }
- }
-
- spin_lock_bh(&pmlmepriv->lock);
- if (request->n_channels == 1) {
- memcpy(&ch[1], &ch[0], sizeof(struct rtw_ieee80211_channel));
- memcpy(&ch[2], &ch[0], sizeof(struct rtw_ieee80211_channel));
- _status = rtw_sitesurvey_cmd23a(padapter, ssid,
- RTW_SSID_SCAN_AMOUNT, ch, 3);
- } else {
- _status = rtw_sitesurvey_cmd23a(padapter, ssid,
- RTW_SSID_SCAN_AMOUNT, NULL, 0);
- }
- spin_unlock_bh(&pmlmepriv->lock);
-
- if (_status == false)
- ret = -1;
-
-check_need_indicate_scan_done:
- if (need_indicate_scan_done)
- rtw_cfg80211_surveydone_event_callback(padapter);
- return ret;
-}
-
-static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
-{
- DBG_8723A("%s\n", __func__);
- return 0;
-}
-
-static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
- struct cfg80211_ibss_params *params)
-{
- DBG_8723A("%s(%s)\n", __func__, ndev->name);
- return 0;
-}
-
-static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
-{
- DBG_8723A("%s(%s)\n", __func__, ndev->name);
- return 0;
-}
-
-static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv,
- u32 wpa_version)
-{
- DBG_8723A("%s, wpa_version =%d\n", __func__, wpa_version);
-
- if (!wpa_version) {
- psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
- return 0;
- }
-
- if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
- psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
-
-/*
- if (wpa_version & NL80211_WPA_VERSION_2)
- {
- psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
- }
-*/
-
- return 0;
-}
-
-static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
- enum nl80211_auth_type sme_auth_type)
-{
- DBG_8723A("%s, nl80211_auth_type =%d\n", __func__, sme_auth_type);
-
- switch (sme_auth_type) {
- case NL80211_AUTHTYPE_AUTOMATIC:
- psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
-
- break;
- case NL80211_AUTHTYPE_OPEN_SYSTEM:
- psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
-
- if (psecuritypriv->ndisauthtype > Ndis802_11AuthModeWPA)
- psecuritypriv->dot11AuthAlgrthm =
- dot11AuthAlgrthm_8021X;
- break;
- case NL80211_AUTHTYPE_SHARED_KEY:
- psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
-
- psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
- break;
- default:
- psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
- /* return -ENOTSUPP; */
- }
-
- return 0;
-}
-
-static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv,
- u32 cipher, bool ucast)
-{
- u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
-
- u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
- &psecuritypriv->dot118021XGrpPrivacy;
-
- DBG_8723A("%s, ucast =%d, cipher = 0x%x\n", __func__, ucast, cipher);
-
- if (!cipher) {
- *profile_cipher = 0;
- psecuritypriv->ndisencryptstatus = ndisencryptstatus;
- return 0;
- }
-
- switch (cipher) {
- case IW_AUTH_CIPHER_NONE:
- *profile_cipher = 0;
- ndisencryptstatus = Ndis802_11EncryptionDisabled;
- break;
- case WLAN_CIPHER_SUITE_WEP40:
- *profile_cipher = WLAN_CIPHER_SUITE_WEP40;
- ndisencryptstatus = Ndis802_11Encryption1Enabled;
- break;
- case WLAN_CIPHER_SUITE_WEP104:
- *profile_cipher = WLAN_CIPHER_SUITE_WEP104;
- ndisencryptstatus = Ndis802_11Encryption1Enabled;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- *profile_cipher = WLAN_CIPHER_SUITE_TKIP;
- ndisencryptstatus = Ndis802_11Encryption2Enabled;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- *profile_cipher = WLAN_CIPHER_SUITE_CCMP;
- ndisencryptstatus = Ndis802_11Encryption3Enabled;
- break;
- default:
- DBG_8723A("Unsupported cipher: 0x%x\n", cipher);
- return -ENOTSUPP;
- }
-
- if (ucast)
- psecuritypriv->ndisencryptstatus = ndisencryptstatus;
-
- return 0;
-}
-
-static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv,
- u32 key_mgt)
-{
- DBG_8723A("%s, key_mgt = 0x%x\n", __func__, key_mgt);
-
- if (key_mgt == WLAN_AKM_SUITE_8021X)
- psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
- else if (key_mgt == WLAN_AKM_SUITE_PSK)
- psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
- else
- DBG_8723A("Invalid key mgt: 0x%x\n", key_mgt);
-
- return 0;
-}
-
-static int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie,
- size_t ielen)
-{
- const u8 *wps_ie;
- int group_cipher = 0, pairwise_cipher = 0;
- int ret = 0;
- const u8 *pwpa, *pwpa2;
- int i;
-
- if (!pie || !ielen) {
- /* Treat this as normal case, but need to clear
- WIFI_UNDER_WPS */
- _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
- goto exit;
- }
- if (ielen > MAX_WPA_IE_LEN + MAX_WPS_IE_LEN + MAX_P2P_IE_LEN) {
- ret = -EINVAL;
- goto exit;
- }
-
- /* dump */
- DBG_8723A("set wpa_ie(length:%zu):\n", ielen);
- for (i = 0; i < ielen; i = i + 8)
- DBG_8723A("0x%.2x 0x%.2x 0x%.2x 0x%.2x "
- "0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
- pie[i], pie[i + 1], pie[i + 2], pie[i + 3],
- pie[i + 4], pie[i + 5], pie[i + 6], pie[i + 7]);
- if (ielen < RSN_HEADER_LEN) {
- RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
- "Ie len too short %d\n", (int)ielen);
- ret = -1;
- goto exit;
- }
-
- pwpa = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WPA,
- pie, ielen);
- if (pwpa && pwpa[1] > 0) {
- if (rtw_parse_wpa_ie23a(pwpa, pwpa[1] + 2, &group_cipher,
- &pairwise_cipher, NULL) == _SUCCESS) {
- padapter->securitypriv.dot11AuthAlgrthm =
- dot11AuthAlgrthm_8021X;
- padapter->securitypriv.ndisauthtype =
- Ndis802_11AuthModeWPAPSK;
- memcpy(padapter->securitypriv.supplicant_ie, pwpa,
- pwpa[1] + 2);
-
- DBG_8723A("got wpa_ie, wpa_ielen:%u\n", pwpa[1]);
- }
- }
-
- pwpa2 = cfg80211_find_ie(WLAN_EID_RSN, pie, ielen);
- if (pwpa2 && pwpa2[1] > 0) {
- if (rtw_parse_wpa2_ie23a (pwpa2, pwpa2[1] + 2, &group_cipher,
- &pairwise_cipher, NULL) == _SUCCESS) {
- padapter->securitypriv.dot11AuthAlgrthm =
- dot11AuthAlgrthm_8021X;
- padapter->securitypriv.ndisauthtype =
- Ndis802_11AuthModeWPA2PSK;
- memcpy(padapter->securitypriv.supplicant_ie, pwpa2,
- pwpa2[1] + 2);
-
- DBG_8723A("got wpa2_ie, wpa2_ielen:%u\n", pwpa2[1]);
- }
- }
-
- if (group_cipher == 0) {
- group_cipher = WPA_CIPHER_NONE;
- }
- if (pairwise_cipher == 0) {
- pairwise_cipher = WPA_CIPHER_NONE;
- }
-
- switch (group_cipher) {
- case WPA_CIPHER_NONE:
- padapter->securitypriv.dot118021XGrpPrivacy = 0;
- padapter->securitypriv.ndisencryptstatus =
- Ndis802_11EncryptionDisabled;
- break;
- case WPA_CIPHER_WEP40:
- padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40;
- padapter->securitypriv.ndisencryptstatus =
- Ndis802_11Encryption1Enabled;
- break;
- case WPA_CIPHER_TKIP:
- padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_TKIP;
- padapter->securitypriv.ndisencryptstatus =
- Ndis802_11Encryption2Enabled;
- break;
- case WPA_CIPHER_CCMP:
- padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_CCMP;
- padapter->securitypriv.ndisencryptstatus =
- Ndis802_11Encryption3Enabled;
- break;
- case WPA_CIPHER_WEP104:
- padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP104;
- padapter->securitypriv.ndisencryptstatus =
- Ndis802_11Encryption1Enabled;
- break;
- }
-
- switch (pairwise_cipher) {
- case WPA_CIPHER_NONE:
- padapter->securitypriv.dot11PrivacyAlgrthm = 0;
- padapter->securitypriv.ndisencryptstatus =
- Ndis802_11EncryptionDisabled;
- break;
- case WPA_CIPHER_WEP40:
- padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40;
- padapter->securitypriv.ndisencryptstatus =
- Ndis802_11Encryption1Enabled;
- break;
- case WPA_CIPHER_TKIP:
- padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_TKIP;
- padapter->securitypriv.ndisencryptstatus =
- Ndis802_11Encryption2Enabled;
- break;
- case WPA_CIPHER_CCMP:
- padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_CCMP;
- padapter->securitypriv.ndisencryptstatus =
- Ndis802_11Encryption3Enabled;
- break;
- case WPA_CIPHER_WEP104:
- padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104;
- padapter->securitypriv.ndisencryptstatus =
- Ndis802_11Encryption1Enabled;
- break;
- }
-
- wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WPS,
- pie, ielen);
- if (wps_ie && wps_ie[1] > 0) {
- DBG_8723A("got wps_ie, wps_ielen:%u\n", wps_ie[1]);
- padapter->securitypriv.wps_ie_len = wps_ie[1];
- memcpy(padapter->securitypriv.wps_ie, wps_ie,
- padapter->securitypriv.wps_ie_len);
- set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
- } else {
- _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
- }
-
- /* TKIP and AES disallow multicast packets until installing group key */
- if (padapter->securitypriv.dot11PrivacyAlgrthm ==
- WLAN_CIPHER_SUITE_TKIP ||
- padapter->securitypriv.dot11PrivacyAlgrthm ==
- WLAN_CIPHER_SUITE_CCMP)
- /* WPS open need to enable multicast */
- /* check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == true)*/
- rtl8723a_off_rcr_am(padapter);
-
- RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
- "rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n",
- pairwise_cipher,
- padapter->securitypriv.ndisencryptstatus,
- padapter->securitypriv.ndisauthtype);
-
-exit:
- if (ret)
- _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
- return ret;
-}
-
-static int rtw_cfg80211_add_wep(struct rtw_adapter *padapter,
- struct rtw_wep_key *wep, u8 keyid)
-{
- int res;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
-
- if (keyid >= NUM_WEP_KEYS) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- "%s:keyid>4 =>fail\n", __func__);
- res = _FAIL;
- goto exit;
- }
-
- switch (wep->keylen) {
- case WLAN_KEY_LEN_WEP40:
- psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- "%s:wep->KeyLength = 5\n", __func__);
- break;
- case WLAN_KEY_LEN_WEP104:
- psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- "%s:wep->KeyLength = 13\n", __func__);
- break;
- default:
- psecuritypriv->dot11PrivacyAlgrthm = 0;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- "%s:wep->KeyLength!= 5 or 13\n", __func__);
- res = _FAIL;
- goto exit;
- }
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- "%s:before memcpy, wep->KeyLength = 0x%x keyid =%x\n",
- __func__, wep->keylen, keyid);
-
- memcpy(&psecuritypriv->wep_key[keyid], wep, sizeof(struct rtw_wep_key));
-
- psecuritypriv->dot11PrivacyKeyIndex = keyid;
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- "%s:security key material : %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
- __func__,
- psecuritypriv->wep_key[keyid].key[0],
- psecuritypriv->wep_key[keyid].key[1],
- psecuritypriv->wep_key[keyid].key[2],
- psecuritypriv->wep_key[keyid].key[3],
- psecuritypriv->wep_key[keyid].key[4],
- psecuritypriv->wep_key[keyid].key[5],
- psecuritypriv->wep_key[keyid].key[6],
- psecuritypriv->wep_key[keyid].key[7],
- psecuritypriv->wep_key[keyid].key[8],
- psecuritypriv->wep_key[keyid].key[9],
- psecuritypriv->wep_key[keyid].key[10],
- psecuritypriv->wep_key[keyid].key[11],
- psecuritypriv->wep_key[keyid].key[12]);
-
- res = rtw_set_key23a(padapter, psecuritypriv, keyid, 1);
-
-exit:
-
- return res;
-}
-
-static int rtw_set_ssid(struct rtw_adapter *padapter,
- struct wlan_network *newnetwork)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_network *pnetwork = &pmlmepriv->cur_network;
- int status = _SUCCESS;
- u32 cur_time = 0;
-
- DBG_8723A_LEVEL(_drv_always_, "set ssid [%s] fw_state = 0x%08x\n",
- newnetwork->network.Ssid.ssid, get_fwstate(pmlmepriv));
-
- if (padapter->hw_init_completed == false) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- "set_ssid: hw_init_completed == false =>exit!!!\n");
- status = _FAIL;
- goto exit;
- }
-
- spin_lock_bh(&pmlmepriv->lock);
-
- DBG_8723A("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
- goto handle_tkip_countermeasure;
-
- if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- "set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n");
-
- if (pmlmepriv->assoc_ssid.ssid_len ==
- newnetwork->network.Ssid.ssid_len &&
- !memcmp(&pmlmepriv->assoc_ssid.ssid,
- newnetwork->network.Ssid.ssid,
- newnetwork->network.Ssid.ssid_len)) {
- if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_,
- _drv_err_,
- "New SSID is same SSID, fw_state = 0x%08x\n",
- get_fwstate(pmlmepriv));
-
- if (rtw_is_same_ibss23a(padapter, pnetwork)) {
- /*
- * it means driver is in
- * WIFI_ADHOC_MASTER_STATE, we needn't
- * create bss again.
- */
- goto release_mlme_lock;
- }
-
- /*
- * if in WIFI_ADHOC_MASTER_STATE |
- * WIFI_ADHOC_STATE, create bss or
- * rejoin again
- */
- rtw_disassoc_cmd23a(padapter, 0, true);
-
- if (check_fwstate(pmlmepriv, _FW_LINKED))
- rtw_indicate_disconnect23a(padapter);
-
- rtw_free_assoc_resources23a(padapter, 1);
-
- if (check_fwstate(pmlmepriv,
- WIFI_ADHOC_MASTER_STATE)) {
- _clr_fwstate_(pmlmepriv,
- WIFI_ADHOC_MASTER_STATE);
- set_fwstate(pmlmepriv,
- WIFI_ADHOC_STATE);
- }
- } else {
- rtw_lps_ctrl_wk_cmd23a(padapter,
- LPS_CTRL_JOINBSS, 1);
- }
- } else {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- "Set SSID not the same ssid\n");
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- "set_ssid =[%s] len = 0x%x\n",
- newnetwork->network.Ssid.ssid,
- newnetwork->network.Ssid.ssid_len);
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- "assoc_ssid =[%s] len = 0x%x\n",
- pmlmepriv->assoc_ssid.ssid,
- pmlmepriv->assoc_ssid.ssid_len);
-
- rtw_disassoc_cmd23a(padapter, 0, true);
-
- if (check_fwstate(pmlmepriv, _FW_LINKED))
- rtw_indicate_disconnect23a(padapter);
-
- rtw_free_assoc_resources23a(padapter, 1);
-
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
- _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
- set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
- }
- }
- }
-
-handle_tkip_countermeasure:
-
- if (padapter->securitypriv.btkip_countermeasure == true) {
- cur_time = jiffies;
-
- if ((cur_time -
- padapter->securitypriv.btkip_countermeasure_time) >
- 60 * HZ) {
- padapter->securitypriv.btkip_countermeasure = false;
- padapter->securitypriv.btkip_countermeasure_time = 0;
- } else {
- status = _FAIL;
- goto release_mlme_lock;
- }
- }
-
- memcpy(&pmlmepriv->assoc_ssid, &newnetwork->network.Ssid,
- sizeof(struct cfg80211_ssid));
-
- pmlmepriv->assoc_by_bssid = false;
-
- pmlmepriv->to_join = true;
-
- if (!check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
- pmlmepriv->cur_network.join_res = -2;
-
- status = rtw_do_join_network(padapter, newnetwork);
- if (status == _SUCCESS) {
- pmlmepriv->to_join = false;
- } else {
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
- /* switch to ADHOC_MASTER */
- status = rtw_do_join_adhoc(padapter);
- if (status != _SUCCESS)
- goto release_mlme_lock;
- } else {
- /* can't associate ; reset under-linking */
- _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
- status = _FAIL;
- pmlmepriv->to_join = false;
- }
- }
- }
-release_mlme_lock:
- spin_unlock_bh(&pmlmepriv->lock);
-
-exit:
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- "-%s: status =%d\n", __func__, status);
-
- return status;
-}
-
-static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
- struct cfg80211_connect_params *sme)
-{
- int ret = 0;
- struct list_head *phead, *plist, *ptmp;
- struct wlan_network *pnetwork = NULL;
- /* u8 matched_by_bssid = false; */
- /* u8 matched_by_ssid = false; */
- u8 matched = false;
- struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct rtw_queue *queue = &pmlmepriv->scanned_queue;
-
- DBG_8723A("=>" "%s(%s)\n", __func__, ndev->name);
- DBG_8723A("privacy =%d, key =%p, key_len =%d, key_idx =%d\n",
- sme->privacy, sme->key, sme->key_len, sme->key_idx);
-
- if (_FAIL == rtw_pwr_wakeup(padapter)) {
- ret = -EPERM;
- goto exit;
- }
-
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
- ret = -EPERM;
- goto exit;
- }
-
- if (!sme->ssid || !sme->ssid_len ||
- sme->ssid_len > IEEE80211_MAX_SSID_LEN) {
- ret = -EINVAL;
- goto exit;
- }
-
- DBG_8723A("ssid =%s, len =%zu\n", sme->ssid, sme->ssid_len);
-
- if (sme->bssid)
- DBG_8723A("bssid=%pM\n", sme->bssid);
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
- ret = -EBUSY;
- DBG_8723A("%s, fw_state = 0x%x, goto exit\n", __func__,
- pmlmepriv->fw_state);
- goto exit;
- }
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
- rtw_scan_abort23a(padapter);
- }
-
- spin_lock_bh(&queue->lock);
-
- phead = get_list_head(queue);
-
- list_for_each_safe(plist, ptmp, phead) {
- pnetwork = container_of(plist, struct wlan_network, list);
-
- if (sme->bssid) {
- if (!ether_addr_equal(pnetwork->network.MacAddress,
- sme->bssid))
- continue;
- }
-
- if (sme->ssid && sme->ssid_len) {
- if (pnetwork->network.Ssid.ssid_len != sme->ssid_len ||
- memcmp(pnetwork->network.Ssid.ssid, sme->ssid,
- sme->ssid_len))
- continue;
- }
-
- if (sme->bssid) {
- if (ether_addr_equal(pnetwork->network.MacAddress,
- sme->bssid)) {
- DBG_8723A("matched by bssid\n");
-
- matched = true;
- break;
- }
- } else if (sme->ssid && sme->ssid_len) {
- if (!memcmp(pnetwork->network.Ssid.ssid,
- sme->ssid, sme->ssid_len) &&
- pnetwork->network.Ssid.ssid_len == sme->ssid_len) {
- DBG_8723A("matched by ssid\n");
-
- matched = true;
- break;
- }
- }
- }
-
- spin_unlock_bh(&queue->lock);
-
- if (!matched || !pnetwork) {
- ret = -ENOENT;
- DBG_8723A("connect, matched == false, goto exit\n");
- goto exit;
- }
-
- if (cfg80211_infrastructure_mode(
- padapter, pnetwork->network.ifmode) != _SUCCESS) {
- ret = -EPERM;
- goto exit;
- }
-
- psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
- psecuritypriv->dot11PrivacyAlgrthm = 0;
- psecuritypriv->dot118021XGrpPrivacy = 0;
- psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
- psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
-
- ret = rtw_cfg80211_set_wpa_version(psecuritypriv,
- sme->crypto.wpa_versions);
- if (ret < 0)
- goto exit;
-
- ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
-
- if (ret < 0)
- goto exit;
-
- DBG_8723A("%s, ie_len =%zu\n", __func__, sme->ie_len);
-
- ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len);
- if (ret < 0)
- goto exit;
-
- if (sme->crypto.n_ciphers_pairwise) {
- ret = rtw_cfg80211_set_cipher(psecuritypriv,
- sme->crypto.ciphers_pairwise[0],
- true);
- if (ret < 0)
- goto exit;
- }
-
- /* For WEP Shared auth */
- if ((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared ||
- psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) &&
- sme->key) {
- struct rtw_wep_key wep_key;
- u8 wep_key_idx, wep_key_len;
- DBG_8723A("%s(): Shared/Auto WEP\n", __func__);
-
- wep_key_idx = sme->key_idx;
- wep_key_len = sme->key_len;
-
- if (wep_key_idx > WEP_KEYS || !wep_key_len ||
- wep_key_len > WLAN_KEY_LEN_WEP104) {
- ret = -EINVAL;
- goto exit;
- }
-
- wep_key_len = wep_key_len <= 5 ? 5 : 13;
-
- memset(&wep_key, 0, sizeof(struct rtw_wep_key));
-
- wep_key.keylen = wep_key_len;
-
- if (wep_key_len == 13) {
- padapter->securitypriv.dot11PrivacyAlgrthm =
- WLAN_CIPHER_SUITE_WEP104;
- padapter->securitypriv.dot118021XGrpPrivacy =
- WLAN_CIPHER_SUITE_WEP104;
- } else {
- padapter->securitypriv.dot11PrivacyAlgrthm =
- WLAN_CIPHER_SUITE_WEP40;
- padapter->securitypriv.dot118021XGrpPrivacy =
- WLAN_CIPHER_SUITE_WEP40;
- }
-
- memcpy(wep_key.key, (void *)sme->key, wep_key.keylen);
-
- if (rtw_cfg80211_add_wep(padapter, &wep_key, wep_key_idx) !=
- _SUCCESS)
- ret = -EOPNOTSUPP;
-
- if (ret < 0)
- goto exit;
- }
-
- ret = rtw_cfg80211_set_cipher(psecuritypriv,
- sme->crypto.cipher_group, false);
- if (ret < 0)
- goto exit;
-
- if (sme->crypto.n_akm_suites) {
- ret = rtw_cfg80211_set_key_mgt(psecuritypriv,
- sme->crypto.akm_suites[0]);
- if (ret < 0)
- goto exit;
- }
-
- if (psecuritypriv->ndisauthtype > 3)
- psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
-
- if (rtw_set_auth23a(padapter, psecuritypriv) != _SUCCESS) {
- ret = -EBUSY;
- goto exit;
- }
-
- /* rtw_set_802_11_encryption_mode(padapter,
- padapter->securitypriv.ndisencryptstatus); */
-
- if (rtw_set_ssid(padapter, pnetwork) != _SUCCESS) {
- ret = -EBUSY;
- goto exit;
- }
-
- DBG_8723A("set ssid:dot11AuthAlgrthm =%d, dot11PrivacyAlgrthm =%d, "
- "dot118021XGrpPrivacy =%d\n", psecuritypriv->dot11AuthAlgrthm,
- psecuritypriv->dot11PrivacyAlgrthm,
- psecuritypriv->dot118021XGrpPrivacy);
-
-exit:
-
- DBG_8723A("<=%s, ret %d\n", __func__, ret);
-
- return ret;
-}
-
-static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
- u16 reason_code)
-{
- struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
-
- DBG_8723A("%s(%s)\n", __func__, ndev->name);
-
- rtw_set_roaming(padapter, 0);
-
- if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
- rtw_scan_abort23a(padapter);
- LeaveAllPowerSaveMode23a(padapter);
- rtw_disassoc_cmd23a(padapter, 500, false);
-
- DBG_8723A("%s...call rtw_indicate_disconnect23a\n", __func__);
-
- padapter->mlmepriv.not_indic_disco = true;
- rtw_indicate_disconnect23a(padapter);
- padapter->mlmepriv.not_indic_disco = false;
-
- rtw_free_assoc_resources23a(padapter, 1);
- }
-
- return 0;
-}
-
-static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
- struct wireless_dev *wdev,
- enum nl80211_tx_power_setting type, int mbm)
-{
- DBG_8723A("%s\n", __func__);
- return 0;
-}
-
-static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
- struct wireless_dev *wdev, int *dbm)
-{
- DBG_8723A("%s\n", __func__);
- *dbm = 12;
- return 0;
-}
-
-inline bool rtw_cfg80211_pwr_mgmt(struct rtw_adapter *adapter)
-{
- struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(adapter->rtw_wdev);
- return rtw_wdev_priv->power_mgmt;
-}
-
-static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
- struct net_device *ndev,
- bool enabled, int timeout)
-{
- struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
- struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(padapter->rtw_wdev);
-
- DBG_8723A("%s(%s): enabled:%u, timeout:%d\n",
- __func__, ndev->name, enabled, timeout);
-
- rtw_wdev_priv->power_mgmt = enabled;
-
- if (!enabled)
- LPS_Leave23a(padapter);
-
- return 0;
-}
-
-static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
- struct net_device *netdev,
- struct cfg80211_pmksa *pmksa)
-{
- u8 index, blInserted = false;
- struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
- struct security_priv *psecuritypriv = &padapter->securitypriv;
-
- DBG_8723A("%s(%s)\n", __func__, netdev->name);
-
- if (is_zero_ether_addr(pmksa->bssid))
- return -EINVAL;
-
- blInserted = false;
-
- /* overwrite PMKID */
- for (index = 0; index < NUM_PMKID_CACHE; index++) {
- if (ether_addr_equal(psecuritypriv->PMKIDList[index].Bssid,
- pmksa->bssid)) {
- /* BSSID is matched, the same AP => rewrite with
- new PMKID. */
- DBG_8723A("%s(%s): BSSID exists in the PMKList.\n",
- __func__, netdev->name);
-
- memcpy(psecuritypriv->PMKIDList[index].PMKID,
- pmksa->pmkid, WLAN_PMKID_LEN);
- psecuritypriv->PMKIDList[index].bUsed = true;
- psecuritypriv->PMKIDIndex = index + 1;
- blInserted = true;
- break;
- }
- }
-
- if (!blInserted) {
- /* Find a new entry */
- DBG_8723A("%s(%s): Use new entry index = %d for this PMKID\n",
- __func__, netdev->name, psecuritypriv->PMKIDIndex);
-
- ether_addr_copy(
- psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
- Bssid, pmksa->bssid);
- memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
- PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
-
- psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed =
- true;
- psecuritypriv->PMKIDIndex++;
- if (psecuritypriv->PMKIDIndex == 16) {
- psecuritypriv->PMKIDIndex = 0;
- }
- }
-
- return 0;
-}
-
-static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
- struct net_device *netdev,
- struct cfg80211_pmksa *pmksa)
-{
- u8 index, bMatched = false;
- struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
- struct security_priv *psecuritypriv = &padapter->securitypriv;
-
- DBG_8723A("%s(%s)\n", __func__, netdev->name);
-
- for (index = 0; index < NUM_PMKID_CACHE; index++) {
- if (ether_addr_equal(psecuritypriv->PMKIDList[index].Bssid,
- pmksa->bssid)) {
- /* BSSID is matched, the same AP => Remove this PMKID
- information and reset it. */
- eth_zero_addr(psecuritypriv->PMKIDList[index].Bssid);
- memset(psecuritypriv->PMKIDList[index].PMKID, 0x00,
- WLAN_PMKID_LEN);
- psecuritypriv->PMKIDList[index].bUsed = false;
- bMatched = true;
- break;
- }
- }
-
- if (false == bMatched) {
- DBG_8723A("%s(%s): do not have matched BSSID\n", __func__,
- netdev->name);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
- struct net_device *netdev)
-{
- struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
- struct security_priv *psecuritypriv = &padapter->securitypriv;
-
- DBG_8723A("%s(%s)\n", __func__, netdev->name);
-
- memset(&psecuritypriv->PMKIDList[0], 0x00,
- sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
- psecuritypriv->PMKIDIndex = 0;
-
- return 0;
-}
-
-#ifdef CONFIG_8723AU_AP_MODE
-void rtw_cfg80211_indicate_sta_assoc(struct rtw_adapter *padapter,
- u8 *pmgmt_frame, uint frame_len)
-{
- s32 freq;
- int channel;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct net_device *ndev = padapter->pnetdev;
-
- DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name);
-
-#if defined(RTW_USE_CFG80211_STA_EVENT)
- {
- struct station_info sinfo;
- u8 ie_offset;
-
- if (ieee80211_is_assoc_req(hdr->frame_control))
- ie_offset = offsetof(struct ieee80211_mgmt,
- u.assoc_req.variable);
- else /* WIFI_REASSOCREQ */
- ie_offset = offsetof(struct ieee80211_mgmt,
- u.reassoc_req.variable);
-
- sinfo.filled = 0;
- sinfo.assoc_req_ies = pmgmt_frame + ie_offset;
- sinfo.assoc_req_ies_len = frame_len - ie_offset;
- cfg80211_new_sta(ndev, hdr->addr2, &sinfo, GFP_ATOMIC);
- }
-#else /* defined(RTW_USE_CFG80211_STA_EVENT) */
- channel = pmlmeext->cur_channel;
- if (channel <= RTW_CH_MAX_2G_CHANNEL)
- freq = ieee80211_channel_to_frequency(channel,
- NL80211_BAND_2GHZ);
- else
- freq = ieee80211_channel_to_frequency(channel,
- NL80211_BAND_5GHZ);
-
- cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, pmgmt_frame, frame_len,
- 0);
-#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
-}
-
-void rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter,
- unsigned char *da,
- unsigned short reason)
-{
- s32 freq;
- int channel;
- uint frame_len;
- struct ieee80211_mgmt mgmt;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct net_device *ndev = padapter->pnetdev;
-
- DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name);
-
- memset(&mgmt, 0, sizeof(struct ieee80211_mgmt));
-
-#if defined(RTW_USE_CFG80211_STA_EVENT)
- cfg80211_del_sta(ndev, da, GFP_ATOMIC);
-#else /* defined(RTW_USE_CFG80211_STA_EVENT) */
- channel = pmlmeext->cur_channel;
- if (channel <= RTW_CH_MAX_2G_CHANNEL)
- freq = ieee80211_channel_to_frequency(channel,
- NL80211_BAND_2GHZ);
- else
- freq = ieee80211_channel_to_frequency(channel,
- NL80211_BAND_5GHZ);
-
- mgmt.frame_control =
- cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH);
-
- ether_addr_copy(mgmt.da, myid(&padapter->eeprompriv));
- ether_addr_copy(mgmt.sa, da);
- ether_addr_copy(mgmt.bssid, get_my_bssid23a(&pmlmeinfo->network));
-
- mgmt.seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
- pmlmeext->mgnt_seq++;
-
- mgmt.u.disassoc.reason_code = cpu_to_le16(reason);
-
- frame_len = sizeof(struct ieee80211_hdr_3addr) + 2;
-
- cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, (u8 *)&mgmt, frame_len,
- 0);
-#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
-}
-
-static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
-{
- DBG_8723A("%s\n", __func__);
-
- return 0;
-}
-
-static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
-{
- DBG_8723A("%s\n", __func__);
-
- return 0;
-}
-
-static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb,
- struct net_device *ndev)
-{
- int ret = 0;
- int rtap_len;
- int qos_len = 0;
- int dot11_hdr_len = 24;
- int snap_len = 6;
- unsigned char *pdata;
- unsigned char src_mac_addr[6];
- unsigned char dst_mac_addr[6];
- struct ieee80211_hdr *dot11_hdr;
- struct ieee80211_radiotap_header *rtap_hdr;
- struct rtw_adapter *padapter = netdev_priv(ndev);
-
- DBG_8723A("%s(%s)\n", __func__, ndev->name);
-
- if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
- goto fail;
-
- rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
- if (unlikely(rtap_hdr->it_version))
- goto fail;
-
- rtap_len = ieee80211_get_radiotap_len(skb->data);
- if (unlikely(skb->len < rtap_len))
- goto fail;
-
- if (rtap_len != 14) {
- DBG_8723A("radiotap len (should be 14): %d\n", rtap_len);
- goto fail;
- }
-
- /* Skip the ratio tap header */
- skb_pull(skb, rtap_len);
-
- dot11_hdr = (struct ieee80211_hdr *)skb->data;
- /* Check if the QoS bit is set */
- if (ieee80211_is_data(dot11_hdr->frame_control)) {
- /* Check if this ia a Wireless Distribution System (WDS) frame
- * which has 4 MAC addresses
- */
- if (ieee80211_is_data_qos(dot11_hdr->frame_control))
- qos_len = IEEE80211_QOS_CTL_LEN;
- if (ieee80211_has_a4(dot11_hdr->frame_control))
- dot11_hdr_len += 6;
-
- memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
- memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
-
- /*
- * Skip the 802.11 header, QoS (if any) and SNAP,
- * but leave spaces for two MAC addresses
- */
- skb_pull(skb, dot11_hdr_len + qos_len + snap_len -
- ETH_ALEN * 2);
- pdata = (unsigned char *)skb->data;
- ether_addr_copy(pdata, dst_mac_addr);
- ether_addr_copy(pdata + ETH_ALEN, src_mac_addr);
-
- DBG_8723A("should be eapol packet\n");
-
- /* Use the real net device to transmit the packet */
- ret = rtw_xmit23a_entry23a(skb, padapter->pnetdev);
-
- return ret;
-
- } else if (ieee80211_is_action(dot11_hdr->frame_control)) {
- struct ieee80211_mgmt *mgmt;
- /* only for action frames */
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- /* u8 category, action, OUI_Subtype, dialogToken = 0; */
- /* unsigned char *frame_body; */
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- u32 len = skb->len;
- u8 category, action;
-
- mgmt = (struct ieee80211_mgmt *)dot11_hdr;
-
- DBG_8723A("RTW_Tx:da=%pM via %s(%s)\n",
- mgmt->da, __func__, ndev->name);
- category = mgmt->u.action.category;
- action = mgmt->u.action.u.wme_action.action_code;
- DBG_8723A("RTW_Tx:category(%u), action(%u)\n",
- category, action);
-
- /* starting alloc mgmt frame to dump it */
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (pmgntframe == NULL)
- goto fail;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
- pattrib->retry_ctrl = false;
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
-
- memcpy(pframe, skb->data, len);
- pattrib->pktlen = len;
-
- /* update seq number */
- pmlmeext->mgnt_seq = le16_to_cpu(dot11_hdr->seq_ctrl) >> 4;
- pattrib->seqnum = pmlmeext->mgnt_seq;
- pmlmeext->mgnt_seq++;
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
- }
-
-fail:
-
- dev_kfree_skb(skb);
-
- return 0;
-}
-
-static int
-rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
-{
- DBG_8723A("%s\n", __func__);
-
- return 0;
-}
-
-static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
- .ndo_open = rtw_cfg80211_monitor_if_open,
- .ndo_stop = rtw_cfg80211_monitor_if_close,
- .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
- .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
-};
-
-static int rtw_cfg80211_add_monitor_if(struct rtw_adapter *padapter, char *name,
- unsigned char name_assign_type,
- struct net_device **ndev)
-{
- int ret = 0;
- struct net_device *mon_ndev = NULL;
- struct wireless_dev *mon_wdev = NULL;
- struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
-
- if (!name) {
- DBG_8723A("%s(%s): without specific name\n",
- __func__, padapter->pnetdev->name);
- ret = -EINVAL;
- goto out;
- }
-
- if (pwdev_priv->pmon_ndev) {
- DBG_8723A("%s(%s): monitor interface exist: %s\n", __func__,
- padapter->pnetdev->name, pwdev_priv->pmon_ndev->name);
- ret = -EBUSY;
- goto out;
- }
-
- mon_ndev = alloc_etherdev(sizeof(struct rtw_adapter));
- if (!mon_ndev) {
- DBG_8723A("%s(%s): allocate ndev fail\n", __func__,
- padapter->pnetdev->name);
- ret = -ENOMEM;
- goto out;
- }
-
- mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
- strncpy(mon_ndev->name, name, IFNAMSIZ);
- mon_ndev->name[IFNAMSIZ - 1] = 0;
- mon_ndev->name_assign_type = name_assign_type;
- mon_ndev->destructor = rtw_ndev_destructor;
-
- mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
-
- /* wdev */
- mon_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
- if (!mon_wdev) {
- ret = -ENOMEM;
- goto out;
- }
-
- mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
- mon_wdev->netdev = mon_ndev;
- mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
- mon_ndev->ieee80211_ptr = mon_wdev;
-
- ret = register_netdevice(mon_ndev);
- if (ret) {
- goto out;
- }
-
- *ndev = pwdev_priv->pmon_ndev = mon_ndev;
- memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ + 1);
-
-out:
- if (ret) {
- kfree(mon_wdev);
- mon_wdev = NULL;
- }
-
- if (ret && mon_ndev) {
- free_netdev(mon_ndev);
- *ndev = mon_ndev = NULL;
- }
-
- return ret;
-}
-
-static struct wireless_dev *
-cfg80211_rtw_add_virtual_intf(struct wiphy *wiphy, const char *name,
- unsigned char name_assign_type,
- enum nl80211_iftype type, u32 *flags,
- struct vif_params *params)
-{
- int ret = 0;
- struct net_device *ndev = NULL;
- struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
-
- DBG_8723A("%s(%s): wiphy:%s, name:%s, type:%d\n", __func__,
- padapter->pnetdev->name, wiphy_name(wiphy), name, type);
-
- switch (type) {
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_AP_VLAN:
- case NL80211_IFTYPE_WDS:
- case NL80211_IFTYPE_MESH_POINT:
- ret = -ENODEV;
- break;
- case NL80211_IFTYPE_MONITOR:
- ret =
- rtw_cfg80211_add_monitor_if(padapter, (char *)name,
- name_assign_type, &ndev);
- break;
-
- case NL80211_IFTYPE_P2P_CLIENT:
- case NL80211_IFTYPE_STATION:
- ret = -ENODEV;
- break;
-
- case NL80211_IFTYPE_P2P_GO:
- case NL80211_IFTYPE_AP:
- ret = -ENODEV;
- break;
- default:
- ret = -ENODEV;
- DBG_8723A("Unsupported interface type\n");
- break;
- }
-
- DBG_8723A("%s(%s): ndev:%p, ret:%d\n", __func__,
- padapter->pnetdev->name,
- ndev, ret);
-
- return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
-}
-
-static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
- struct wireless_dev *wdev)
-{
- struct rtw_wdev_priv *pwdev_priv =
- (struct rtw_wdev_priv *)wiphy_priv(wiphy);
- struct net_device *ndev;
- ndev = wdev ? wdev->netdev : NULL;
-
- if (!ndev)
- goto exit;
-
- unregister_netdevice(ndev);
-
- if (ndev == pwdev_priv->pmon_ndev) {
- pwdev_priv->pmon_ndev = NULL;
- pwdev_priv->ifname_mon[0] = '\0';
- DBG_8723A("%s(%s): remove monitor interface\n",
- __func__, ndev->name);
- }
-
-exit:
- return 0;
-}
-
-static int rtw_add_beacon(struct rtw_adapter *adapter, const u8 *head,
- size_t head_len, const u8 *tail, size_t tail_len)
-{
- int ret = 0;
- u8 *pbuf;
- uint len, ielen, wps_ielen = 0;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct wlan_bssid_ex *bss = &pmlmepriv->cur_network.network;
- const struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)head;
- struct ieee80211_mgmt *tmpmgmt;
- /* struct sta_priv *pstapriv = &padapter->stapriv; */
-
- DBG_8723A("%s beacon_head_len =%zu, beacon_tail_len =%zu\n",
- __func__, head_len, tail_len);
-
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
- return -EINVAL;
-
- if (head_len < offsetof(struct ieee80211_mgmt, u.beacon.variable))
- return -EINVAL;
-
- pbuf = kzalloc(head_len + tail_len, GFP_KERNEL);
- if (!pbuf)
- return -ENOMEM;
- tmpmgmt = (struct ieee80211_mgmt *)pbuf;
-
- bss->beacon_interval = get_unaligned_le16(&mgmt->u.beacon.beacon_int);
- bss->capability = get_unaligned_le16(&mgmt->u.beacon.capab_info);
- bss->tsf = get_unaligned_le64(&mgmt->u.beacon.timestamp);
-
- /* 24 = beacon header len. */
- memcpy(pbuf, (void *)head, head_len);
- memcpy(pbuf + head_len, (void *)tail, tail_len);
-
- len = head_len + tail_len;
- ielen = len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
- /* check wps ie if inclued */
- if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
- WLAN_OUI_TYPE_MICROSOFT_WPS,
- tmpmgmt->u.beacon.variable, ielen))
- DBG_8723A("add bcn, wps_ielen =%d\n", wps_ielen);
-
- /* pbss_network->IEs will not include p2p_ie, wfd ie */
- rtw_ies_remove_ie23a(tmpmgmt->u.beacon.variable, &ielen, 0,
- WLAN_EID_VENDOR_SPECIFIC, P2P_OUI23A, 4);
- rtw_ies_remove_ie23a(tmpmgmt->u.beacon.variable, &ielen, 0,
- WLAN_EID_VENDOR_SPECIFIC, WFD_OUI23A, 4);
-
- len = ielen + offsetof(struct ieee80211_mgmt, u.beacon.variable);
- if (rtw_check_beacon_data23a(adapter, tmpmgmt, len) == _SUCCESS) {
- ret = 0;
- } else {
- ret = -EINVAL;
- }
-
- kfree(pbuf);
-
- return ret;
-}
-
-static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
- struct cfg80211_ap_settings *settings)
-{
- int ret = 0;
- struct rtw_adapter *adapter = wiphy_to_adapter(wiphy);
-
- DBG_8723A("%s(%s): hidden_ssid:%d, auth_type:%d\n",
- __func__, ndev->name, settings->hidden_ssid,
- settings->auth_type);
-
- ret = rtw_add_beacon(adapter, settings->beacon.head,
- settings->beacon.head_len, settings->beacon.tail,
- settings->beacon.tail_len);
-
- adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode =
- settings->hidden_ssid;
-
- if (settings->ssid && settings->ssid_len) {
- struct wlan_bssid_ex *pbss_network =
- &adapter->mlmepriv.cur_network.network;
- struct wlan_bssid_ex *pbss_network_ext =
- &adapter->mlmeextpriv.mlmext_info.network;
-
- memcpy(pbss_network->Ssid.ssid, (void *)settings->ssid,
- settings->ssid_len);
- pbss_network->Ssid.ssid_len = settings->ssid_len;
- memcpy(pbss_network_ext->Ssid.ssid, (void *)settings->ssid,
- settings->ssid_len);
- pbss_network_ext->Ssid.ssid_len = settings->ssid_len;
- }
-
- return ret;
-}
-
-static int cfg80211_rtw_change_beacon(struct wiphy *wiphy,
- struct net_device *ndev,
- struct cfg80211_beacon_data *info)
-{
- int ret = 0;
- struct rtw_adapter *adapter = wiphy_to_adapter(wiphy);
-
- DBG_8723A("%s(%s)\n", __func__, ndev->name);
-
- ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail,
- info->tail_len);
-
- return ret;
-}
-
-static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
-{
- DBG_8723A("%s(%s)\n", __func__, ndev->name);
- return 0;
-}
-
-static int cfg80211_rtw_add_station(struct wiphy *wiphy,
- struct net_device *ndev, const u8 *mac,
- struct station_parameters *params)
-{
- DBG_8723A("%s(%s)\n", __func__, ndev->name);
-
- return 0;
-}
-
-static int cfg80211_rtw_del_station(struct wiphy *wiphy,
- struct net_device *ndev,
- struct station_del_parameters *params)
-{
- const u8 *mac = params->mac;
- int ret = 0;
- struct list_head *phead;
- u8 updated = 0;
- struct sta_info *psta, *ptmp;
- struct rtw_adapter *padapter = netdev_priv(ndev);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- DBG_8723A("+%s(%s)\n", __func__, ndev->name);
-
- if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != true) {
- DBG_8723A("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n",
- __func__);
- return -EINVAL;
- }
-
- if (!mac) {
- DBG_8723A("flush all sta, and cam_entry\n");
-
- flush_all_cam_entry23a(padapter); /* clear CAM */
-
- ret = rtw_sta_flush23a(padapter);
-
- return ret;
- }
-
- DBG_8723A("free sta macaddr=%pM\n", mac);
-
- if (is_broadcast_ether_addr(mac))
- return -EINVAL;
-
- spin_lock_bh(&pstapriv->asoc_list_lock);
- phead = &pstapriv->asoc_list;
- /* check asoc_queue */
- list_for_each_entry_safe(psta, ptmp, phead, asoc_list) {
- if (ether_addr_equal(mac, psta->hwaddr)) {
- if (psta->dot8021xalg == 1 &&
- psta->bpairwise_key_installed == false) {
- DBG_8723A("%s, sta's dot8021xalg = 1 and "
- "key_installed = false\n", __func__);
- } else {
- DBG_8723A("free psta =%p, aid =%d\n", psta,
- psta->aid);
-
- list_del_init(&psta->asoc_list);
- pstapriv->asoc_list_cnt--;
-
- /* spin_unlock_bh(&pstapriv->asoc_list_lock); */
- updated =
- ap_free_sta23a(padapter, psta, true,
- WLAN_REASON_DEAUTH_LEAVING);
- /* spin_lock_bh(&pstapriv->asoc_list_lock); */
-
- psta = NULL;
-
- break;
- }
- }
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
-
- associated_clients_update23a(padapter, updated);
-
- DBG_8723A("-%s(%s)\n", __func__, ndev->name);
-
- return ret;
-}
-
-static int cfg80211_rtw_change_station(struct wiphy *wiphy,
- struct net_device *ndev, const u8 *mac,
- struct station_parameters *params)
-{
- DBG_8723A("%s(%s)\n", __func__, ndev->name);
- return 0;
-}
-
-static int cfg80211_rtw_dump_station(struct wiphy *wiphy,
- struct net_device *ndev, int idx, u8 *mac,
- struct station_info *sinfo)
-{
- DBG_8723A("%s(%s)\n", __func__, ndev->name);
-
- /* TODO: dump scanned queue */
-
- return -ENOENT;
-}
-
-static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
- struct bss_parameters *params)
-{
- DBG_8723A("%s(%s)\n", __func__, ndev->name);
- return 0;
-}
-#endif /* CONFIG_8723AU_AP_MODE */
-
-static int _cfg80211_rtw_mgmt_tx(struct rtw_adapter *padapter, u8 tx_ch,
- const u8 *buf, size_t len)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- int ret = _FAIL;
- struct ieee80211_hdr *pwlanhdr;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- if (_FAIL == rtw_pwr_wakeup(padapter)) {
- ret = -EFAULT;
- goto exit;
- }
-
- rtw_set_scan_deny(padapter, 1000);
-
- rtw_scan_abort23a(padapter);
-
- if (tx_ch != rtw_get_oper_ch23a(padapter)) {
- if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED))
- pmlmeext->cur_channel = tx_ch;
- set_channel_bwmode23a(padapter, tx_ch,
- HAL_PRIME_CHNL_OFFSET_DONT_CARE,
- HT_CHANNEL_WIDTH_20);
- }
-
- /* starting alloc mgmt frame to dump it */
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (!pmgntframe) {
- /* ret = -ENOMEM; */
- ret = _FAIL;
- goto exit;
- }
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
- pattrib->retry_ctrl = false;
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *) (pmgntframe->buf_addr) + TXDESC_OFFSET;
-
- memcpy(pframe, (void *)buf, len);
- pattrib->pktlen = len;
-
- pwlanhdr = (struct ieee80211_hdr *)pframe;
- /* update seq number */
- pmlmeext->mgnt_seq = le16_to_cpu(pwlanhdr->seq_ctrl) >> 4;
- pattrib->seqnum = pmlmeext->mgnt_seq;
- pmlmeext->mgnt_seq++;
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
-
- if (ret != _SUCCESS)
- DBG_8723A("%s, ack == false\n", __func__);
- else
- DBG_8723A("%s, ack == true\n", __func__);
-
-exit:
-
- DBG_8723A("%s, ret =%d\n", __func__, ret);
-
- return ret;
-}
-
-static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
- struct cfg80211_mgmt_tx_params *params,
- u64 *cookie)
-{
- struct rtw_adapter *padapter =
- (struct rtw_adapter *)wiphy_to_adapter(wiphy);
- int ret = 0;
- int tx_ret;
- u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
- u32 dump_cnt = 0;
- bool ack = true;
- u8 category, action;
- unsigned long start = jiffies;
- size_t len = params->len;
- struct ieee80211_channel *chan = params->chan;
- const u8 *buf = params->buf;
- struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *)buf;
- u8 tx_ch = (u8) ieee80211_frequency_to_channel(chan->center_freq);
-
- if (!ieee80211_is_action(hdr->frame_control))
- return -EINVAL;
-
- /* cookie generation */
- *cookie = (unsigned long)buf;
-
- DBG_8723A("%s(%s): len =%zu, ch =%d\n", __func__,
- padapter->pnetdev->name, len, tx_ch);
-
- /* indicate ack before issue frame to avoid racing with rsp frame */
- cfg80211_mgmt_tx_status(padapter->rtw_wdev, *cookie, buf, len, ack,
- GFP_KERNEL);
-
- DBG_8723A("RTW_Tx:tx_ch =%d, da =%pM\n", tx_ch, hdr->da);
- category = hdr->u.action.category;
- action = hdr->u.action.u.wme_action.action_code;
- DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category, action);
-
- do {
- dump_cnt++;
- tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
- } while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
-
- if (tx_ret != _SUCCESS || dump_cnt > 1) {
- DBG_8723A("%s(%s): %s (%d/%d) in %d ms\n",
- __func__, padapter->pnetdev->name,
- tx_ret == _SUCCESS ? "OK" : "FAIL", dump_cnt,
- dump_limit, jiffies_to_msecs(jiffies - start));
- }
-
- return ret;
-}
-
-static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
- struct wireless_dev *wdev,
- u16 frame_type, bool reg)
-{
- if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
- return;
-
- return;
-}
-
-static struct cfg80211_ops rtw_cfg80211_ops = {
- .change_virtual_intf = cfg80211_rtw_change_iface,
- .add_key = cfg80211_rtw_add_key,
- .get_key = cfg80211_rtw_get_key,
- .del_key = cfg80211_rtw_del_key,
- .set_default_key = cfg80211_rtw_set_default_key,
- .get_station = cfg80211_rtw_get_station,
- .scan = cfg80211_rtw_scan,
- .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
- .connect = cfg80211_rtw_connect,
- .disconnect = cfg80211_rtw_disconnect,
- .join_ibss = cfg80211_rtw_join_ibss,
- .leave_ibss = cfg80211_rtw_leave_ibss,
- .set_tx_power = cfg80211_rtw_set_txpower,
- .get_tx_power = cfg80211_rtw_get_txpower,
- .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
- .set_pmksa = cfg80211_rtw_set_pmksa,
- .del_pmksa = cfg80211_rtw_del_pmksa,
- .flush_pmksa = cfg80211_rtw_flush_pmksa,
-
-#ifdef CONFIG_8723AU_AP_MODE
- .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
- .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
-
- .start_ap = cfg80211_rtw_start_ap,
- .change_beacon = cfg80211_rtw_change_beacon,
- .stop_ap = cfg80211_rtw_stop_ap,
-
- .add_station = cfg80211_rtw_add_station,
- .del_station = cfg80211_rtw_del_station,
- .change_station = cfg80211_rtw_change_station,
- .dump_station = cfg80211_rtw_dump_station,
- .change_bss = cfg80211_rtw_change_bss,
-#endif /* CONFIG_8723AU_AP_MODE */
-
- .mgmt_tx = cfg80211_rtw_mgmt_tx,
- .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
-};
-
-static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap,
- enum nl80211_band band, u8 rf_type)
-{
-
-#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
-#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
-
- ht_cap->ht_supported = true;
-
- ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
- IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
- IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
-
- /*
- *Maximum length of AMPDU that the STA can receive.
- *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
- */
- ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
-
- /*Minimum MPDU start spacing , */
- ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
-
- ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
-
- /*
- *hw->wiphy->bands[NL80211_BAND_2GHZ]
- *base on ant_num
- *rx_mask: RX mask
- *if rx_ant = 1 rx_mask[0]= 0xff;==>MCS0-MCS7
- *if rx_ant = 2 rx_mask[1]= 0xff;==>MCS8-MCS15
- *if rx_ant >= 3 rx_mask[2]= 0xff;
- *if BW_40 rx_mask[4]= 0x01;
- *highest supported RX rate
- */
- if (rf_type == RF_1T1R) {
- ht_cap->mcs.rx_mask[0] = 0xFF;
- ht_cap->mcs.rx_mask[1] = 0x00;
- ht_cap->mcs.rx_mask[4] = 0x01;
-
- ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7);
- } else if ((rf_type == RF_1T2R) || (rf_type == RF_2T2R)) {
- ht_cap->mcs.rx_mask[0] = 0xFF;
- ht_cap->mcs.rx_mask[1] = 0xFF;
- ht_cap->mcs.rx_mask[4] = 0x01;
-
- ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);
- } else {
- DBG_8723A("%s, error rf_type =%d\n", __func__, rf_type);
- }
-
-}
-
-void rtw_cfg80211_init_wiphy(struct rtw_adapter *padapter)
-{
- u8 rf_type;
- struct ieee80211_supported_band *bands;
- struct wireless_dev *pwdev = padapter->rtw_wdev;
- struct wiphy *wiphy = pwdev->wiphy;
-
- rf_type = rtl8723a_get_rf_type(padapter);
-
- DBG_8723A("%s:rf_type =%d\n", __func__, rf_type);
-
- /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
- {
- bands = wiphy->bands[NL80211_BAND_2GHZ];
- if (bands)
- rtw_cfg80211_init_ht_capab(&bands->ht_cap,
- NL80211_BAND_2GHZ,
- rf_type);
- }
-
- /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
- {
- bands = wiphy->bands[NL80211_BAND_5GHZ];
- if (bands)
- rtw_cfg80211_init_ht_capab(&bands->ht_cap,
- NL80211_BAND_5GHZ,
- rf_type);
- }
-}
-
-static void rtw_cfg80211_preinit_wiphy(struct rtw_adapter *padapter,
- struct wiphy *wiphy)
-{
- wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-
- wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
- wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
- wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
-
- wiphy->max_remain_on_channel_duration =
- RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
-
- wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC) |
-#ifdef CONFIG_8723AU_AP_MODE
- BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) |
-#endif
- 0;
-
-#ifdef CONFIG_8723AU_AP_MODE
- wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
-#endif /* CONFIG_8723AU_AP_MODE */
-
- wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
-
- /*
- wiphy->iface_combinations = &rtw_combinations;
- wiphy->n_iface_combinations = 1;
- */
-
- wiphy->cipher_suites = rtw_cipher_suites;
- wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
-
- /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
- wiphy->bands[NL80211_BAND_2GHZ] =
- rtw_spt_band_alloc(NL80211_BAND_2GHZ);
- /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
- wiphy->bands[NL80211_BAND_5GHZ] =
- rtw_spt_band_alloc(NL80211_BAND_5GHZ);
-
- wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
- wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
-
- if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
- wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
- else
- wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
-}
-
-int rtw_wdev_alloc(struct rtw_adapter *padapter, struct device *dev)
-{
- int ret = 0;
- struct wiphy *wiphy;
- struct wireless_dev *wdev;
- struct rtw_wdev_priv *pwdev_priv;
- struct net_device *pnetdev = padapter->pnetdev;
-
- DBG_8723A("%s(padapter =%p)\n", __func__, padapter);
-
- /* wiphy */
- wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wdev_priv));
- if (!wiphy) {
- DBG_8723A("Couldn't allocate wiphy device\n");
- ret = -ENOMEM;
- goto exit;
- }
-
- /* wdev */
- wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
- if (!wdev) {
- ret = -ENOMEM;
- goto free_wiphy;
- }
-
- set_wiphy_dev(wiphy, dev);
- rtw_cfg80211_preinit_wiphy(padapter, wiphy);
-
- ret = wiphy_register(wiphy);
- if (ret < 0) {
- DBG_8723A("Couldn't register wiphy device\n");
- goto free_wdev;
- }
-
- wdev->wiphy = wiphy;
- wdev->netdev = pnetdev;
- /* wdev->iftype = NL80211_IFTYPE_STATION; */
- /* for rtw_setopmode_cmd23a() in cfg80211_rtw_change_iface() */
- wdev->iftype = NL80211_IFTYPE_MONITOR;
- padapter->rtw_wdev = wdev;
- pnetdev->ieee80211_ptr = wdev;
-
- /* init pwdev_priv */
- pwdev_priv = wdev_to_priv(wdev);
- pwdev_priv->rtw_wdev = wdev;
- pwdev_priv->pmon_ndev = NULL;
- pwdev_priv->ifname_mon[0] = '\0';
- pwdev_priv->padapter = padapter;
- pwdev_priv->scan_request = NULL;
- spin_lock_init(&pwdev_priv->scan_req_lock);
-
- pwdev_priv->p2p_enabled = false;
-
- if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
- pwdev_priv->power_mgmt = true;
- else
- pwdev_priv->power_mgmt = false;
-
- return ret;
-free_wdev:
- kfree(wdev);
-free_wiphy:
- wiphy_free(wiphy);
-exit:
- return ret;
-}
-
-void rtw_wdev_free(struct wireless_dev *wdev)
-{
- DBG_8723A("%s(wdev =%p)\n", __func__, wdev);
-
- if (!wdev)
- return;
-
- kfree(wdev->wiphy->bands[NL80211_BAND_2GHZ]);
- kfree(wdev->wiphy->bands[NL80211_BAND_5GHZ]);
-
- wiphy_free(wdev->wiphy);
-
- kfree(wdev);
-}
-
-void rtw_wdev_unregister(struct wireless_dev *wdev)
-{
- struct rtw_wdev_priv *pwdev_priv;
-
- DBG_8723A("%s(wdev =%p)\n", __func__, wdev);
-
- if (!wdev)
- return;
-
- pwdev_priv = wdev_to_priv(wdev);
-
- rtw_cfg80211_indicate_scan_done(pwdev_priv, true);
-
- if (pwdev_priv->pmon_ndev) {
- DBG_8723A("%s, unregister monitor interface\n", __func__);
- unregister_netdev(pwdev_priv->pmon_ndev);
- }
-
- wiphy_unregister(wdev->wiphy);
-}
diff --git a/drivers/staging/rtl8723au/os_dep/mlme_linux.c b/drivers/staging/rtl8723au/os_dep/mlme_linux.c
deleted file mode 100644
index ca24369f1208..000000000000
--- a/drivers/staging/rtl8723au/os_dep/mlme_linux.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-
-#define _MLME_OSDEP_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <mlme_osdep.h>
-
-static struct rt_pmkid_list backupPMKIDList[NUM_PMKID_CACHE];
-
-void rtw_reset_securitypriv23a(struct rtw_adapter *adapter)
-{
- u8 backupPMKIDIndex = 0;
- u8 backupTKIPCountermeasure = 0x00;
- unsigned long backupTKIPcountermeasure_time = 0;
-
- if (adapter->securitypriv.dot11AuthAlgrthm ==
- dot11AuthAlgrthm_8021X) { /* 802.1x */
- /* We have to backup the PMK information for WiFi PMK
- * Caching test item.
- * Backup the btkip_countermeasure information.
- * When the countermeasure is trigger, the driver have to
- * disconnect with AP for 60 seconds.
- */
- memcpy(&backupPMKIDList[0], &adapter->securitypriv.PMKIDList[0],
- sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
- backupPMKIDIndex = adapter->securitypriv.PMKIDIndex;
- backupTKIPCountermeasure = adapter->securitypriv.btkip_countermeasure;
- backupTKIPcountermeasure_time = adapter->securitypriv.btkip_countermeasure_time;
-
- memset((unsigned char *)&adapter->securitypriv, 0,
- sizeof (struct security_priv));
- /* Restore the PMK information to securitypriv structure
- * for the following connection.
- */
- memcpy(&adapter->securitypriv.PMKIDList[0], &backupPMKIDList[0],
- sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
- adapter->securitypriv.PMKIDIndex = backupPMKIDIndex;
- adapter->securitypriv.btkip_countermeasure = backupTKIPCountermeasure;
- adapter->securitypriv.btkip_countermeasure_time = backupTKIPcountermeasure_time;
-
- adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
- adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
- } else { /* reset values in securitypriv */
- struct security_priv *psec_priv = &adapter->securitypriv;
-
- /* open system */
- psec_priv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
- psec_priv->dot11PrivacyAlgrthm = 0;
- psec_priv->dot11PrivacyKeyIndex = 0;
-
- psec_priv->dot118021XGrpPrivacy = 0;
- psec_priv->dot118021XGrpKeyid = 1;
-
- psec_priv->ndisauthtype = Ndis802_11AuthModeOpen;
- psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled;
- }
-}
-
-void rtw_os_indicate_disconnect23a(struct rtw_adapter *adapter)
-{
- /* Do it first for tx broadcast pkt after disconnection issue! */
- netif_carrier_off(adapter->pnetdev);
-
- rtw_cfg80211_indicate_disconnect(adapter);
-
- rtw_reset_securitypriv23a(adapter);
-}
diff --git a/drivers/staging/rtl8723au/os_dep/os_intfs.c b/drivers/staging/rtl8723au/os_dep/os_intfs.c
deleted file mode 100644
index b8848c25beb4..000000000000
--- a/drivers/staging/rtl8723au/os_dep/os_intfs.c
+++ /dev/null
@@ -1,852 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _OS_INTFS_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <xmit_osdep.h>
-#include <recv_osdep.h>
-#include <hal_intf.h>
-#include <rtw_version.h>
-
-#include <rtl8723a_hal.h>
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Realtek Wireless Lan Driver");
-MODULE_AUTHOR("Realtek Semiconductor Corp.");
-MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
-MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@redhat.com>");
-MODULE_VERSION(DRIVERVERSION);
-MODULE_FIRMWARE("rtlwifi/rtl8723aufw_A.bin");
-MODULE_FIRMWARE("rtlwifi/rtl8723aufw_B.bin");
-MODULE_FIRMWARE("rtlwifi/rtl8723aufw_B_NoBT.bin");
-
-/* module param defaults */
-static int rtw_chip_version;
-static int rtw_rfintfs = HWPI;
-static int rtw_debug = 1;
-
-static int rtw_channel = 1;/* ad-hoc support requirement */
-static int rtw_wireless_mode = WIRELESS_11BG_24N;
-static int rtw_vrtl_carrier_sense = AUTO_VCS;
-static int rtw_vcs_type = RTS_CTS;/* */
-static int rtw_rts_thresh = 2347;/* */
-static int rtw_frag_thresh = 2346;/* */
-static int rtw_preamble = PREAMBLE_LONG;/* long, short, auto */
-static int rtw_scan_mode = 1;/* active, passive */
-static int rtw_adhoc_tx_pwr = 1;
-static int rtw_soft_ap;
-static int rtw_power_mgnt = 1;
-static int rtw_ips_mode = IPS_NORMAL;
-
-static int rtw_smart_ps = 2;
-
-module_param(rtw_ips_mode, int, 0644);
-MODULE_PARM_DESC(rtw_ips_mode, "The default IPS mode");
-
-static int rtw_long_retry_lmt = 7;
-static int rtw_short_retry_lmt = 7;
-static int rtw_busy_thresh = 40;
-static int rtw_ack_policy = NORMAL_ACK;
-
-static int rtw_acm_method;/* 0:By SW 1:By HW. */
-
-static int rtw_wmm_enable = 1;/* default is set to enable the wmm. */
-static int rtw_uapsd_enable;
-
-static int rtw_ht_enable = 1;
-/* 0 :diable, bit(0): enable 2.4g, bit(1): enable 5g */
-static int rtw_cbw40_enable = 3;
-static int rtw_ampdu_enable = 1;/* for enable tx_ampdu */
-/* 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, default is set to enable
- * 2.4GHZ for IOT issue with bufflao's AP at 5GHZ
- */
-static int rtw_rx_stbc = 1;
-static int rtw_ampdu_amsdu;/* 0: disabled, 1:enabled, 2:auto */
-
-/* Use 2 path Tx to transmit MCS0~7 and legacy mode */
-static int rtw_lowrate_two_xmit = 1;
-
-/* int rf_config = RF_1T2R; 1T2R */
-static int rtw_rf_config = RF_819X_MAX_TYPE; /* auto */
-static int rtw_low_power;
-static int rtw_wifi_spec;
-static int rtw_channel_plan = RT_CHANNEL_DOMAIN_MAX;
-
-#ifdef CONFIG_8723AU_BT_COEXIST
-static int rtw_btcoex_enable = 1;
-static int rtw_bt_iso = 2;/* 0:Low, 1:High, 2:From Efuse */
-/* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy, 5.OtherBusy */
-static int rtw_bt_sco = 3;
-/* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
-static int rtw_bt_ampdu = 1;
-#endif
-
-/* 0:Reject AP's Add BA req, 1:Accept AP's Add BA req. */
-static int rtw_AcceptAddbaReq = true;
-
-static int rtw_antdiv_cfg = 2; /* 0:OFF , 1:ON, 2:decide by Efuse config */
-static int rtw_antdiv_type; /* 0:decide by efuse */
-
-static int rtw_enusbss;/* 0:disable, 1:enable */
-
-static int rtw_hwpdn_mode = 2;/* 0:disable, 1:enable, 2: by EFUSE config */
-
-static int rtw_hwpwrp_detect; /* HW power ping detect 0:disable , 1:enable */
-
-static int rtw_hw_wps_pbc = 1;
-
-static int rtw_80211d;
-
-static int rtw_regulatory_id = 0xff;/* Regulatory tab id, 0xff = follow efuse's setting */
-
-module_param(rtw_regulatory_id, int, 0644);
-
-static char *ifname = "wlan%d";
-module_param(ifname, charp, 0644);
-MODULE_PARM_DESC(ifname, "The default name to allocate for first interface");
-
-static char *if2name = "wlan%d";
-module_param(if2name, charp, 0644);
-MODULE_PARM_DESC(if2name, "The default name to allocate for second interface");
-
-module_param(rtw_channel_plan, int, 0644);
-module_param(rtw_chip_version, int, 0644);
-module_param(rtw_rfintfs, int, 0644);
-module_param(rtw_channel, int, 0644);
-module_param(rtw_wmm_enable, int, 0644);
-module_param(rtw_vrtl_carrier_sense, int, 0644);
-module_param(rtw_vcs_type, int, 0644);
-module_param(rtw_busy_thresh, int, 0644);
-module_param(rtw_ht_enable, int, 0644);
-module_param(rtw_cbw40_enable, int, 0644);
-module_param(rtw_ampdu_enable, int, 0644);
-module_param(rtw_rx_stbc, int, 0644);
-module_param(rtw_ampdu_amsdu, int, 0644);
-
-module_param(rtw_lowrate_two_xmit, int, 0644);
-
-module_param(rtw_rf_config, int, 0644);
-module_param(rtw_power_mgnt, int, 0644);
-module_param(rtw_smart_ps, int, 0644);
-module_param(rtw_low_power, int, 0644);
-module_param(rtw_wifi_spec, int, 0644);
-
-module_param(rtw_antdiv_cfg, int, 0644);
-
-module_param(rtw_enusbss, int, 0644);
-module_param(rtw_hwpdn_mode, int, 0644);
-module_param(rtw_hwpwrp_detect, int, 0644);
-
-module_param(rtw_hw_wps_pbc, int, 0644);
-
-static uint rtw_max_roaming_times = 2;
-module_param(rtw_max_roaming_times, uint, 0644);
-MODULE_PARM_DESC(rtw_max_roaming_times, "The max roaming times to try");
-
-module_param(rtw_80211d, int, 0644);
-MODULE_PARM_DESC(rtw_80211d, "Enable 802.11d mechanism");
-
-#ifdef CONFIG_8723AU_BT_COEXIST
-module_param(rtw_btcoex_enable, int, 0644);
-MODULE_PARM_DESC(rtw_btcoex_enable, "Enable BT co-existence mechanism");
-#endif
-
-static uint rtw_notch_filter;
-module_param(rtw_notch_filter, uint, 0644);
-MODULE_PARM_DESC(rtw_notch_filter, "0:Disable, 1:Enable, 2:Enable only for P2P");
-module_param_named(debug, rtw_debug, int, 0444);
-MODULE_PARM_DESC(debug, "Set debug level (1-9) (default 1)");
-
-static int netdev_close(struct net_device *pnetdev);
-
-static void loadparam(struct rtw_adapter *padapter, struct net_device *pnetdev)
-{
- struct registry_priv *registry_par = &padapter->registrypriv;
-
- GlobalDebugLevel23A = rtw_debug;
- registry_par->chip_version = (u8)rtw_chip_version;
- registry_par->rfintfs = (u8)rtw_rfintfs;
- memcpy(registry_par->ssid.ssid, "ANY", 3);
- registry_par->ssid.ssid_len = 3;
- registry_par->channel = (u8)rtw_channel;
- registry_par->wireless_mode = (u8)rtw_wireless_mode;
- registry_par->vrtl_carrier_sense = (u8)rtw_vrtl_carrier_sense;
- registry_par->vcs_type = (u8)rtw_vcs_type;
- registry_par->rts_thresh = (u16)rtw_rts_thresh;
- registry_par->frag_thresh = (u16)rtw_frag_thresh;
- registry_par->preamble = (u8)rtw_preamble;
- registry_par->scan_mode = (u8)rtw_scan_mode;
- registry_par->adhoc_tx_pwr = (u8)rtw_adhoc_tx_pwr;
- registry_par->soft_ap = (u8)rtw_soft_ap;
- registry_par->smart_ps = (u8)rtw_smart_ps;
- registry_par->power_mgnt = (u8)rtw_power_mgnt;
- registry_par->ips_mode = (u8)rtw_ips_mode;
- registry_par->long_retry_lmt = (u8)rtw_long_retry_lmt;
- registry_par->short_retry_lmt = (u8)rtw_short_retry_lmt;
- registry_par->busy_thresh = (u16)rtw_busy_thresh;
- registry_par->ack_policy = (u8)rtw_ack_policy;
- registry_par->acm_method = (u8)rtw_acm_method;
- /* UAPSD */
- registry_par->wmm_enable = (u8)rtw_wmm_enable;
- registry_par->uapsd_enable = (u8)rtw_uapsd_enable;
- registry_par->ht_enable = (u8)rtw_ht_enable;
- registry_par->cbw40_enable = (u8)rtw_cbw40_enable;
- registry_par->ampdu_enable = (u8)rtw_ampdu_enable;
- registry_par->rx_stbc = (u8)rtw_rx_stbc;
- registry_par->ampdu_amsdu = (u8)rtw_ampdu_amsdu;
- registry_par->lowrate_two_xmit = (u8)rtw_lowrate_two_xmit;
- registry_par->rf_config = (u8)rtw_rf_config;
- registry_par->low_power = (u8)rtw_low_power;
- registry_par->wifi_spec = (u8)rtw_wifi_spec;
- registry_par->channel_plan = (u8)rtw_channel_plan;
-#ifdef CONFIG_8723AU_BT_COEXIST
- registry_par->btcoex = (u8)rtw_btcoex_enable;
- registry_par->bt_iso = (u8)rtw_bt_iso;
- registry_par->bt_sco = (u8)rtw_bt_sco;
- registry_par->bt_ampdu = (u8)rtw_bt_ampdu;
-#endif
- registry_par->bAcceptAddbaReq = (u8)rtw_AcceptAddbaReq;
- registry_par->antdiv_cfg = (u8)rtw_antdiv_cfg;
- registry_par->antdiv_type = (u8)rtw_antdiv_type;
-
- /* 0:disable, 1:enable, 2:by EFUSE config */
- registry_par->hwpdn_mode = (u8)rtw_hwpdn_mode;
- /* 0:disable, 1:enable */
- registry_par->hwpwrp_detect = (u8)rtw_hwpwrp_detect;
- registry_par->hw_wps_pbc = (u8)rtw_hw_wps_pbc;
- registry_par->max_roaming_times = (u8)rtw_max_roaming_times;
- registry_par->enable80211d = (u8)rtw_80211d;
- snprintf(registry_par->ifname, 16, "%s", ifname);
- snprintf(registry_par->if2name, 16, "%s", if2name);
- registry_par->notch_filter = (u8)rtw_notch_filter;
- registry_par->regulatory_tid = (u8)rtw_regulatory_id;
-}
-
-static int rtw_net_set_mac_address(struct net_device *pnetdev, void *p)
-{
- struct rtw_adapter *padapter = netdev_priv(pnetdev);
- struct sockaddr *addr = p;
-
- if (!padapter->bup)
- ether_addr_copy(padapter->eeprompriv.mac_addr, addr->sa_data);
- return 0;
-}
-
-static struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev)
-{
- struct rtw_adapter *padapter = netdev_priv(pnetdev);
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct recv_priv *precvpriv = &padapter->recvpriv;
-
- padapter->stats.tx_packets = pxmitpriv->tx_pkts;
- padapter->stats.rx_packets = precvpriv->rx_pkts;
- padapter->stats.tx_dropped = pxmitpriv->tx_drop;
- padapter->stats.rx_dropped = precvpriv->rx_drop;
- padapter->stats.tx_bytes = pxmitpriv->tx_bytes;
- padapter->stats.rx_bytes = precvpriv->rx_bytes;
-
- return &padapter->stats;
-}
-
-/*
- * AC to queue mapping
- *
- * AC_VO -> queue 0
- * AC_VI -> queue 1
- * AC_BE -> queue 2
- * AC_BK -> queue 3
- */
-static const u16 rtw_1d_to_queue[8] = { 2, 3, 3, 2, 1, 1, 0, 0 };
-
-/* Given a data frame determine the 802.1p/1d tag to use. */
-static u32 rtw_classify8021d(struct sk_buff *skb)
-{
- u32 dscp;
-
- /* skb->priority values from 256->263 are magic values to
- * directly indicate a specific 802.1d priority. This is used
- * to allow 802.1d priority to be passed directly in from VLAN
- * tags, etc.
- */
- if (skb->priority >= 256 && skb->priority <= 263)
- return skb->priority - 256;
- switch (skb->protocol) {
- case htons(ETH_P_IP):
- dscp = ip_hdr(skb)->tos & 0xfc;
- break;
- default:
- return 0;
- }
- return dscp >> 5;
-}
-
-static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb,
- void *accel_priv,
- select_queue_fallback_t fallback)
-{
- struct rtw_adapter *padapter = netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- skb->priority = rtw_classify8021d(skb);
-
- if (pmlmepriv->acm_mask != 0)
- skb->priority = qos_acm23a(pmlmepriv->acm_mask, skb->priority);
- return rtw_1d_to_queue[skb->priority];
-}
-
-u16 rtw_recv_select_queue23a(struct sk_buff *skb)
-{
- struct iphdr *piphdr;
- struct ethhdr *eth = (struct ethhdr *)skb->data;
- unsigned int dscp;
- u16 eth_type = get_unaligned_be16(&eth->h_proto);
- u32 priority;
- u8 *pdata = skb->data;
-
- switch (eth_type) {
- case ETH_P_IP:
- piphdr = (struct iphdr *)(pdata + ETH_HLEN);
- dscp = piphdr->tos & 0xfc;
- priority = dscp >> 5;
- break;
- default:
- priority = 0;
- }
- return rtw_1d_to_queue[priority];
-}
-
-static const struct net_device_ops rtw_netdev_ops = {
- .ndo_open = netdev_open23a,
- .ndo_stop = netdev_close,
- .ndo_start_xmit = rtw_xmit23a_entry23a,
- .ndo_select_queue = rtw_select_queue,
- .ndo_set_mac_address = rtw_net_set_mac_address,
- .ndo_get_stats = rtw_net_get_stats,
-};
-
-int rtw_init_netdev23a_name23a(struct net_device *pnetdev, const char *ifname)
-{
- if (dev_alloc_name(pnetdev, ifname) < 0) {
- RT_TRACE(_module_os_intfs_c_, _drv_err_,
- "dev_alloc_name, fail!\n");
- }
- netif_carrier_off(pnetdev);
- return 0;
-}
-
-static const struct device_type wlan_type = {
- .name = "wlan",
-};
-
-struct net_device *rtw_init_netdev23a(struct rtw_adapter *old_padapter)
-{
- struct rtw_adapter *padapter;
- struct net_device *pnetdev;
-
- RT_TRACE(_module_os_intfs_c_, _drv_info_, "+init_net_dev\n");
-
- pnetdev = alloc_etherdev_mq(sizeof(struct rtw_adapter), 4);
- if (!pnetdev)
- return NULL;
-
- pnetdev->dev.type = &wlan_type;
- padapter = netdev_priv(pnetdev);
- padapter->pnetdev = pnetdev;
-
- DBG_8723A("register rtw_netdev_ops to netdev_ops\n");
- pnetdev->netdev_ops = &rtw_netdev_ops;
-
- pnetdev->watchdog_timeo = HZ*3; /* 3 second timeout */
-
- loadparam(padapter, pnetdev);
- return pnetdev;
-}
-
-static int rtw_init_default_value(struct rtw_adapter *padapter)
-{
- struct registry_priv *pregistrypriv = &padapter->registrypriv;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
-
- /* xmit_priv */
- pxmitpriv->vcs = pregistrypriv->vcs_type;
- /* pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; */
- pxmitpriv->frag_len = pregistrypriv->frag_thresh;
-
- /* mlme_priv */
- pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */
- pmlmepriv->scan_mode = SCAN_ACTIVE;
-
- /* ht_priv */
- pmlmepriv->htpriv.ampdu_enable = false;/* set to disabled */
-
- /* security_priv */
- psecuritypriv->binstallGrpkey = 0;
-
- /* open system */
- psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
- psecuritypriv->dot11PrivacyAlgrthm = 0;
-
- psecuritypriv->dot11PrivacyKeyIndex = 0;
-
- psecuritypriv->dot118021XGrpPrivacy = 0;
- psecuritypriv->dot118021XGrpKeyid = 1;
-
- psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
- psecuritypriv->ndisencryptstatus = Ndis802_11WEPDisabled;
-
- /* registry_priv */
- rtw_init_registrypriv_dev_network23a(padapter);
- rtw_update_registrypriv_dev_network23a(padapter);
-
- /* hal_priv */
- rtl8723a_init_default_value(padapter);
-
- /* misc. */
- padapter->bReadPortCancel = false;
- padapter->bWritePortCancel = false;
- return _SUCCESS;
-}
-
-int rtw_reset_drv_sw23a(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
-
- /* hal_priv */
- rtl8723a_init_default_value(padapter);
- padapter->bReadPortCancel = false;
- padapter->bWritePortCancel = false;
- pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */
-
- padapter->xmitpriv.tx_pkts = 0;
- padapter->recvpriv.rx_pkts = 0;
-
- pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
-
- _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING);
-
- rtw_sreset_reset_value(padapter);
- pwrctrlpriv->pwr_state_check_cnts = 0;
-
- /* mlmeextpriv */
- padapter->mlmeextpriv.sitesurvey_res.state = SCAN_DISABLE;
-
- rtw_set_signal_stat_timer(&padapter->recvpriv);
- return _SUCCESS;
-}
-
-int rtw_init_drv_sw23a(struct rtw_adapter *padapter)
-{
- int ret8 = _SUCCESS;
-
- RT_TRACE(_module_os_intfs_c_, _drv_info_, "+rtw_init_drv_sw23a\n");
-
- if (rtw_init_cmd_priv23a(&padapter->cmdpriv) == _FAIL) {
- RT_TRACE(_module_os_intfs_c_, _drv_err_,
- "Can't init cmd_priv\n");
- ret8 = _FAIL;
- goto exit;
- }
-
- padapter->cmdpriv.padapter = padapter;
-
- if (rtw_init_evt_priv23a(&padapter->evtpriv) == _FAIL) {
- RT_TRACE(_module_os_intfs_c_, _drv_err_,
- "Can't init evt_priv\n");
- ret8 = _FAIL;
- goto exit;
- }
-
- if (rtw_init_mlme_priv23a(padapter) == _FAIL) {
- RT_TRACE(_module_os_intfs_c_, _drv_err_,
- "Can't init mlme_priv\n");
- ret8 = _FAIL;
- goto exit;
- }
-
-
- if (init_mlme_ext_priv23a(padapter) == _FAIL) {
- RT_TRACE(_module_os_intfs_c_, _drv_err_,
- "Can't init mlme_ext_priv\n");
- ret8 = _FAIL;
- goto exit;
- }
-
- if (_rtw_init_xmit_priv23a(&padapter->xmitpriv, padapter) == _FAIL) {
- DBG_8723A("Can't _rtw_init_xmit_priv23a\n");
- ret8 = _FAIL;
- goto exit;
- }
-
- if (_rtw_init_recv_priv23a(&padapter->recvpriv, padapter) == _FAIL) {
- DBG_8723A("Can't _rtw_init_recv_priv23a\n");
- ret8 = _FAIL;
- goto exit;
- }
-
- if (_rtw_init_sta_priv23a(&padapter->stapriv) == _FAIL) {
- DBG_8723A("Can't _rtw_init_sta_priv23a\n");
- ret8 = _FAIL;
- goto exit;
- }
-
- padapter->stapriv.padapter = padapter;
- padapter->setband = GHZ24_50;
- rtw_init_bcmc_stainfo23a(padapter);
-
- rtw_init_pwrctrl_priv23a(padapter);
-
- ret8 = rtw_init_default_value(padapter);
-
- rtl8723a_init_dm_priv(padapter);
-
- rtw_sreset_init(padapter);
-
-exit:
-
- RT_TRACE(_module_os_intfs_c_, _drv_info_, "-rtw_init_drv_sw23a\n");
- return ret8;
-}
-
-void rtw_cancel_all_timer23a(struct rtw_adapter *padapter)
-{
- RT_TRACE(_module_os_intfs_c_, _drv_info_,
- "+rtw_cancel_all_timer23a\n");
-
- del_timer_sync(&padapter->mlmepriv.assoc_timer);
- RT_TRACE(_module_os_intfs_c_, _drv_info_,
- "%s:cancel association timer complete!\n", __func__);
-
- del_timer_sync(&padapter->mlmepriv.scan_to_timer);
- RT_TRACE(_module_os_intfs_c_, _drv_info_,
- "%s:cancel scan_to_timer!\n", __func__);
-
- del_timer_sync(&padapter->mlmepriv.dynamic_chk_timer);
- RT_TRACE(_module_os_intfs_c_, _drv_info_,
- "%s:cancel dynamic_chk_timer!\n", __func__);
-
- del_timer_sync(&padapter->pwrctrlpriv.pwr_state_check_timer);
-
- del_timer_sync(&padapter->mlmepriv.set_scan_deny_timer);
- rtw_clear_scan_deny(padapter);
- RT_TRACE(_module_os_intfs_c_, _drv_info_,
- "%s:cancel set_scan_deny_timer!\n", __func__);
-
- del_timer_sync(&padapter->recvpriv.signal_stat_timer);
-}
-
-int rtw_free_drv_sw23a(struct rtw_adapter *padapter)
-{
- RT_TRACE(_module_os_intfs_c_, _drv_info_, "==>rtw_free_drv_sw23a\n");
-
- free_mlme_ext_priv23a(&padapter->mlmeextpriv);
-
- rtw_free_evt_priv23a(&padapter->evtpriv);
-
- rtw_free_mlme_priv23a(&padapter->mlmepriv);
-
- _rtw_free_xmit_priv23a(&padapter->xmitpriv);
-
- /* will free bcmc_stainfo here */
- _rtw_free_sta_priv23a(&padapter->stapriv);
-
- _rtw_free_recv_priv23a(&padapter->recvpriv);
-
- rtw_free_pwrctrl_priv(padapter);
-
- kfree(padapter->HalData);
- padapter->HalData = NULL;
-
- RT_TRACE(_module_os_intfs_c_, _drv_info_, "-rtw_free_drv_sw23a\n");
- return _SUCCESS;
-}
-
-static int _rtw_drv_register_netdev(struct rtw_adapter *padapter, char *name)
-{
- struct net_device *pnetdev = padapter->pnetdev;
- int ret = _SUCCESS;
-
- /* alloc netdev name */
- rtw_init_netdev23a_name23a(pnetdev, name);
-
- ether_addr_copy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr);
-
- /* Tell the network stack we exist */
- if (register_netdev(pnetdev)) {
- DBG_8723A("%s(%s): Failed!\n", __func__, pnetdev->name);
- ret = _FAIL;
- goto error_register_netdev;
- }
- DBG_8723A("%s, MAC Address (if%d) = %pM\n",
- __func__, padapter->iface_id + 1, pnetdev->dev_addr);
- return ret;
-
-error_register_netdev:
-
- if (padapter->iface_id > IFACE_ID0) {
- rtw_free_drv_sw23a(padapter);
-
- free_netdev(pnetdev);
- }
- return ret;
-}
-
-int rtw_drv_register_netdev(struct rtw_adapter *if1)
-{
- struct dvobj_priv *dvobj = if1->dvobj;
- int i, status = _SUCCESS;
-
- if (dvobj->iface_nums >= IFACE_ID_MAX) {
- status = _FAIL; /* -EINVAL */
- goto exit;
- }
-
- for (i = 0; i < dvobj->iface_nums; i++) {
- struct rtw_adapter *padapter = dvobj->padapters[i];
-
- if (padapter) {
- char *name;
-
- if (padapter->iface_id == IFACE_ID0)
- name = if1->registrypriv.ifname;
- else if (padapter->iface_id == IFACE_ID1)
- name = if1->registrypriv.if2name;
- else
- name = "wlan%d";
- status = _rtw_drv_register_netdev(padapter, name);
- if (status != _SUCCESS)
- break;
- }
- }
-
-exit:
- return status;
-}
-
-int netdev_open23a(struct net_device *pnetdev)
-{
- struct rtw_adapter *padapter = netdev_priv(pnetdev);
- struct pwrctrl_priv *pwrctrlpriv;
- int ret = 0;
- int status;
-
- RT_TRACE(_module_os_intfs_c_, _drv_info_, "+871x_drv - dev_open\n");
- DBG_8723A("+871x_drv - drv_open, bup =%d\n", padapter->bup);
-
- mutex_lock(&adapter_to_dvobj(padapter)->hw_init_mutex);
-
- pwrctrlpriv = &padapter->pwrctrlpriv;
-
- if (!padapter->bup) {
- padapter->bDriverStopped = false;
- padapter->bSurpriseRemoved = false;
- padapter->bCardDisableWOHSM = false;
-
- status = rtl8723au_hal_init(padapter);
- if (status == _FAIL) {
- RT_TRACE(_module_os_intfs_c_, _drv_err_,
- "rtl871x_hal_init(): Can't init h/w!\n");
- goto netdev_open23a_error;
- }
-
- DBG_8723A("MAC Address = %pM\n", pnetdev->dev_addr);
-
- if (init_hw_mlme_ext23a(padapter) == _FAIL) {
- DBG_8723A("can't init mlme_ext_priv\n");
- goto netdev_open23a_error;
- }
-
- rtl8723au_inirp_init(padapter);
-
- rtw_cfg80211_init_wiphy(padapter);
-
- padapter->bup = true;
- }
- padapter->net_closed = false;
-
- mod_timer(&padapter->mlmepriv.dynamic_chk_timer,
- jiffies + msecs_to_jiffies(2000));
-
- padapter->pwrctrlpriv.bips_processing = false;
- rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv);
-
- /* netif_carrier_on(pnetdev);call this func when
- rtw23a_joinbss_event_cb return success */
- if (!rtw_netif_queue_stopped(pnetdev))
- netif_tx_start_all_queues(pnetdev);
- else
- netif_tx_wake_all_queues(pnetdev);
-
- RT_TRACE(_module_os_intfs_c_, _drv_info_, "-871x_drv - dev_open\n");
- DBG_8723A("-871x_drv - drv_open, bup =%d\n", padapter->bup);
-exit:
- mutex_unlock(&adapter_to_dvobj(padapter)->hw_init_mutex);
- return ret;
-
-netdev_open23a_error:
- padapter->bup = false;
-
- netif_carrier_off(pnetdev);
- netif_tx_stop_all_queues(pnetdev);
-
- RT_TRACE(_module_os_intfs_c_, _drv_err_,
- "-871x_drv - dev_open, fail!\n");
- DBG_8723A("-871x_drv - drv_open fail, bup =%d\n", padapter->bup);
-
- ret = -1;
- goto exit;
-}
-
-static int ips_netdrv_open(struct rtw_adapter *padapter)
-{
- int status = _SUCCESS;
-
- padapter->net_closed = false;
- DBG_8723A("===> %s.........\n", __func__);
-
- padapter->bDriverStopped = false;
- padapter->bSurpriseRemoved = false;
- padapter->bCardDisableWOHSM = false;
-
- status = rtl8723au_hal_init(padapter);
- if (status == _FAIL) {
- RT_TRACE(_module_os_intfs_c_, _drv_err_,
- "ips_netdrv_open(): Can't init h/w!\n");
- goto netdev_open23a_error;
- }
-
- rtl8723au_inirp_init(padapter);
-
- rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv);
- mod_timer(&padapter->mlmepriv.dynamic_chk_timer,
- jiffies + msecs_to_jiffies(5000));
-
- return _SUCCESS;
-
-netdev_open23a_error:
- /* padapter->bup = false; */
- DBG_8723A("-ips_netdrv_open - drv_open failure, bup =%d\n",
- padapter->bup);
-
- return _FAIL;
-}
-
-int rtw_ips_pwr_up23a(struct rtw_adapter *padapter)
-{
- int result;
- unsigned long start_time = jiffies;
-
- DBG_8723A("===> rtw_ips_pwr_up23a..............\n");
- rtw_reset_drv_sw23a(padapter);
-
- result = ips_netdrv_open(padapter);
-
- DBG_8723A("<=== rtw_ips_pwr_up23a.............. in %dms\n",
- jiffies_to_msecs(jiffies - start_time));
- return result;
-}
-
-void rtw_ips_pwr_down23a(struct rtw_adapter *padapter)
-{
- unsigned long start_time = jiffies;
-
- DBG_8723A("===> rtw_ips_pwr_down23a...................\n");
-
- padapter->bCardDisableWOHSM = true;
- padapter->net_closed = true;
-
- rtw_ips_dev_unload23a(padapter);
- padapter->bCardDisableWOHSM = false;
- DBG_8723A("<=== rtw_ips_pwr_down23a..................... in %dms\n",
- jiffies_to_msecs(jiffies - start_time));
-}
-
-void rtw_ips_dev_unload23a(struct rtw_adapter *padapter)
-{
- rtl8723a_fifo_cleanup(padapter);
-
- rtl8723a_usb_intf_stop(padapter);
-
- /* s5. */
- if (!padapter->bSurpriseRemoved)
- rtl8723au_hal_deinit(padapter);
-}
-
-int pm_netdev_open23a(struct net_device *pnetdev, u8 bnormal)
-{
- int status;
-
- if (bnormal)
- status = netdev_open23a(pnetdev);
- else
- status = (_SUCCESS == ips_netdrv_open(netdev_priv(pnetdev))) ?
- (0) : (-1);
-
- return status;
-}
-
-static int netdev_close(struct net_device *pnetdev)
-{
- struct rtw_adapter *padapter = netdev_priv(pnetdev);
-
- RT_TRACE(_module_os_intfs_c_, _drv_info_, "+871x_drv - drv_close\n");
-
- padapter->net_closed = true;
-
- if (padapter->pwrctrlpriv.rf_pwrstate == rf_on) {
- DBG_8723A("(2)871x_drv - drv_close, bup =%d, "
- "hw_init_completed =%d\n", padapter->bup,
- padapter->hw_init_completed);
-
- /* s1. */
- if (pnetdev) {
- if (!rtw_netif_queue_stopped(pnetdev))
- netif_tx_stop_all_queues(pnetdev);
- }
-
- /* s2. */
- LeaveAllPowerSaveMode23a(padapter);
- rtw_disassoc_cmd23a(padapter, 500, false);
- /* s2-2. indicate disconnect to os */
- rtw_indicate_disconnect23a(padapter);
- /* s2-3. */
- rtw_free_assoc_resources23a(padapter, 1);
- /* s2-4. */
- rtw_free_network_queue23a(padapter);
- }
-
- rtw_scan_abort23a(padapter);
-
- RT_TRACE(_module_os_intfs_c_, _drv_info_, "-871x_drv - drv_close\n");
- DBG_8723A("-871x_drv - drv_close, bup =%d\n", padapter->bup);
-
- return 0;
-}
-
-void rtw_ndev_destructor(struct net_device *ndev)
-{
- DBG_8723A("%s(%s)\n", __func__, ndev->name);
- kfree(ndev->ieee80211_ptr);
- free_netdev(ndev);
-}
-
-void _rtw_init_queue23a(struct rtw_queue *pqueue)
-{
- INIT_LIST_HEAD(&pqueue->queue);
- spin_lock_init(&pqueue->lock);
-}
diff --git a/drivers/staging/rtl8723au/os_dep/recv_linux.c b/drivers/staging/rtl8723au/os_dep/recv_linux.c
deleted file mode 100644
index 084b506ae161..000000000000
--- a/drivers/staging/rtl8723au/os_dep/recv_linux.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _RECV_OSDEP_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-#include <wifi.h>
-#include <recv_osdep.h>
-
-#include <osdep_intf.h>
-
-#include <usb_ops.h>
-
-void rtw_handle_tkip_mic_err23a(struct rtw_adapter *padapter, u8 bgroup)
-{
- enum nl80211_key_type key_type = 0;
- union iwreq_data wrqu;
- struct iw_michaelmicfailure ev;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- unsigned long cur_time;
-
- if (psecuritypriv->last_mic_err_time == 0) {
- psecuritypriv->last_mic_err_time = jiffies;
- } else {
- cur_time = jiffies;
-
- if (cur_time - psecuritypriv->last_mic_err_time < 60*HZ) {
- psecuritypriv->btkip_countermeasure = true;
- psecuritypriv->last_mic_err_time = 0;
- psecuritypriv->btkip_countermeasure_time = cur_time;
- } else {
- psecuritypriv->last_mic_err_time = jiffies;
- }
- }
-
- if (bgroup)
- key_type |= NL80211_KEYTYPE_GROUP;
- else
- key_type |= NL80211_KEYTYPE_PAIRWISE;
-
- cfg80211_michael_mic_failure(padapter->pnetdev,
- (u8 *)&pmlmepriv->assoc_bssid[0],
- key_type, -1, NULL, GFP_ATOMIC);
-
- memset(&ev, 0x00, sizeof(ev));
- if (bgroup)
- ev.flags |= IW_MICFAILURE_GROUP;
- else
- ev.flags |= IW_MICFAILURE_PAIRWISE;
-
- ev.src_addr.sa_family = ARPHRD_ETHER;
- ether_addr_copy(ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[0]);
-
- memset(&wrqu, 0x00, sizeof(wrqu));
- wrqu.data.length = sizeof(ev);
-}
-
-int rtw_recv_indicatepkt23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame)
-{
- struct recv_priv *precvpriv;
- struct sk_buff *skb;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- precvpriv = &padapter->recvpriv;
-
- skb = precv_frame->pkt;
- if (!skb) {
- RT_TRACE(_module_recv_osdep_c_, _drv_err_,
- "rtw_recv_indicatepkt23a():skb == NULL!!!!\n");
- goto _recv_indicatepkt_drop;
- }
-
- RT_TRACE(_module_recv_osdep_c_, _drv_info_,
- "rtw_recv_indicatepkt23a():skb != NULL !!!\n");
- RT_TRACE(_module_recv_osdep_c_, _drv_info_,
- "rtw_recv_indicatepkt23a():precv_frame->hdr.rx_data =%p\n",
- precv_frame->pkt->data);
- RT_TRACE(_module_recv_osdep_c_, _drv_info_,
- "skb->head =%p skb->data =%p skb->tail =%p skb->end =%p skb->len =%d\n",
- skb->head, skb->data,
- skb_tail_pointer(skb), skb_end_pointer(skb), skb->len);
-
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
- struct sk_buff *pskb2 = NULL;
- struct sta_info *psta = NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
- int bmcast = is_multicast_ether_addr(pattrib->dst);
-
- /* DBG_8723A("bmcast =%d\n", bmcast); */
-
- if (!ether_addr_equal(pattrib->dst,
- myid(&padapter->eeprompriv))) {
- /* DBG_8723A("not ap psta =%p, addr =%pM\n", psta, pattrib->dst); */
- if (bmcast) {
- psta = rtw_get_bcmc_stainfo23a(padapter);
- pskb2 = skb_clone(skb, GFP_ATOMIC);
- } else {
- psta = rtw_get_stainfo23a(pstapriv, pattrib->dst);
- }
-
- if (psta) {
- struct net_device *pnetdev = padapter->pnetdev;
-
- /* DBG_8723A("directly forwarding to the rtw_xmit23a_entry23a\n"); */
-
- /* skb->ip_summed = CHECKSUM_NONE; */
- skb->dev = pnetdev;
- skb_set_queue_mapping(skb, rtw_recv_select_queue23a(skb));
-
- rtw_xmit23a_entry23a(skb, pnetdev);
-
- if (bmcast)
- skb = pskb2;
- else
- goto _recv_indicatepkt_end;
- }
- } else { /* to APself */
- /* DBG_8723A("to APSelf\n"); */
- }
- }
-
- skb->ip_summed = CHECKSUM_NONE;
- skb->dev = padapter->pnetdev;
- skb->protocol = eth_type_trans(skb, padapter->pnetdev);
-
- netif_rx(skb);
-
-_recv_indicatepkt_end:
-
- precv_frame->pkt = NULL; /* pointers to NULL before rtw_free_recvframe23a() */
-
- rtw_free_recvframe23a(precv_frame);
-
- RT_TRACE(_module_recv_osdep_c_, _drv_info_,
- "rtw_recv_indicatepkt23a :after netif_rx!!!!\n");
- return _SUCCESS;
-
-_recv_indicatepkt_drop:
-
- rtw_free_recvframe23a(precv_frame);
- return _FAIL;
-}
-
-void rtw_init_recv_timer23a(struct recv_reorder_ctrl *preorder_ctrl)
-{
- setup_timer(&preorder_ctrl->reordering_ctrl_timer,
- rtw_reordering_ctrl_timeout_handler23a,
- (unsigned long)preorder_ctrl);
-}
diff --git a/drivers/staging/rtl8723au/os_dep/usb_intf.c b/drivers/staging/rtl8723au/os_dep/usb_intf.c
deleted file mode 100644
index cf83efffbffd..000000000000
--- a/drivers/staging/rtl8723au/os_dep/usb_intf.c
+++ /dev/null
@@ -1,627 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _HCI_INTF_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <recv_osdep.h>
-#include <xmit_osdep.h>
-#include <hal_intf.h>
-#include <rtw_version.h>
-#include <osdep_intf.h>
-#include <usb_ops.h>
-#include <rtl8723a_hal.h>
-
-static int rtw_suspend(struct usb_interface *intf, pm_message_t message);
-static int rtw_resume(struct usb_interface *intf);
-static int rtw_drv_init(struct usb_interface *pusb_intf,
- const struct usb_device_id *pdid);
-static void rtw_disconnect(struct usb_interface *pusb_intf);
-
-#define USB_VENDER_ID_REALTEK 0x0BDA
-
-#define RTL8723A_USB_IDS \
- {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x8724, \
- 0xff, 0xff, 0xff)}, /* 8723AU 1*1 */ \
- {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x1724, \
- 0xff, 0xff, 0xff)}, /* 8723AU 1*1 */ \
- {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x0724, \
- 0xff, 0xff, 0xff)}, /* 8723AU 1*1 */
-
-static struct usb_device_id rtl8723a_usb_id_tbl[] = {
- RTL8723A_USB_IDS
- {} /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, rtl8723a_usb_id_tbl);
-
-static struct usb_driver rtl8723a_usb_drv = {
- .name = (char *)"rtl8723au",
- .probe = rtw_drv_init,
- .disconnect = rtw_disconnect,
- .id_table = rtl8723a_usb_id_tbl,
- .suspend = rtw_suspend,
- .resume = rtw_resume,
- .reset_resume = rtw_resume,
-};
-
-static struct usb_driver *usb_drv = &rtl8723a_usb_drv;
-
-static int rtw_init_intf_priv(struct dvobj_priv *dvobj)
-{
- mutex_init(&dvobj->usb_vendor_req_mutex);
-
- return _SUCCESS;
-}
-
-static int rtw_deinit_intf_priv(struct dvobj_priv *dvobj)
-{
- mutex_destroy(&dvobj->usb_vendor_req_mutex);
-
- return _SUCCESS;
-}
-
-static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
-{
- struct dvobj_priv *pdvobjpriv;
- struct usb_host_config *phost_conf;
- struct usb_config_descriptor *pconf_desc;
- struct usb_host_interface *phost_iface;
- struct usb_interface_descriptor *piface_desc;
- struct usb_endpoint_descriptor *pendp_desc;
- struct usb_device *pusbd;
- int i, status = _FAIL;
-
- pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL);
- if (!pdvobjpriv)
- goto exit;
-
- mutex_init(&pdvobjpriv->hw_init_mutex);
- mutex_init(&pdvobjpriv->h2c_fwcmd_mutex);
- mutex_init(&pdvobjpriv->setch_mutex);
- mutex_init(&pdvobjpriv->setbw_mutex);
-
- pdvobjpriv->pusbintf = usb_intf;
- pusbd = interface_to_usbdev(usb_intf);
- pdvobjpriv->pusbdev = pusbd;
- usb_set_intfdata(usb_intf, pdvobjpriv);
-
- pdvobjpriv->RtNumInPipes = 0;
- pdvobjpriv->RtNumOutPipes = 0;
-
- phost_conf = pusbd->actconfig;
- pconf_desc = &phost_conf->desc;
-
- phost_iface = &usb_intf->altsetting[0];
- piface_desc = &phost_iface->desc;
-
- pdvobjpriv->NumInterfaces = pconf_desc->bNumInterfaces;
- pdvobjpriv->InterfaceNumber = piface_desc->bInterfaceNumber;
- pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints;
-
- for (i = 0; i < pdvobjpriv->nr_endpoint; i++) {
- pendp_desc = &phost_iface->endpoint[i].desc;
-
- DBG_8723A("\nusb_endpoint_descriptor(%d):\n", i);
- DBG_8723A("bLength =%x\n", pendp_desc->bLength);
- DBG_8723A("bDescriptorType =%x\n", pendp_desc->bDescriptorType);
- DBG_8723A("bEndpointAddress =%x\n",
- pendp_desc->bEndpointAddress);
- DBG_8723A("wMaxPacketSize =%d\n",
- le16_to_cpu(pendp_desc->wMaxPacketSize));
- DBG_8723A("bInterval =%x\n", pendp_desc->bInterval);
-
- if (usb_endpoint_is_bulk_in(pendp_desc)) {
- DBG_8723A("usb_endpoint_is_bulk_in = %x\n",
- usb_endpoint_num(pendp_desc));
- pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] =
- usb_endpoint_num(pendp_desc);
- pdvobjpriv->RtNumInPipes++;
- } else if (usb_endpoint_is_int_in(pendp_desc)) {
- DBG_8723A("usb_endpoint_is_int_in = %x, Interval = "
- "%x\n", usb_endpoint_num(pendp_desc),
- pendp_desc->bInterval);
- pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] =
- usb_endpoint_num(pendp_desc);
- pdvobjpriv->RtNumInPipes++;
- } else if (usb_endpoint_is_bulk_out(pendp_desc)) {
- DBG_8723A("usb_endpoint_is_bulk_out = %x\n",
- usb_endpoint_num(pendp_desc));
- pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] =
- usb_endpoint_num(pendp_desc);
- pdvobjpriv->RtNumOutPipes++;
- }
- pdvobjpriv->ep_num[i] = usb_endpoint_num(pendp_desc);
- }
- DBG_8723A("nr_endpoint =%d, in_num =%d, out_num =%d\n\n",
- pdvobjpriv->nr_endpoint, pdvobjpriv->RtNumInPipes,
- pdvobjpriv->RtNumOutPipes);
-
- if (pusbd->speed == USB_SPEED_HIGH) {
- pdvobjpriv->ishighspeed = true;
- DBG_8723A("USB_SPEED_HIGH\n");
- } else {
- pdvobjpriv->ishighspeed = false;
- DBG_8723A("NON USB_SPEED_HIGH\n");
- }
-
- if (rtw_init_intf_priv(pdvobjpriv) == _FAIL) {
- RT_TRACE(_module_os_intfs_c_, _drv_err_,
- "Can't INIT rtw_init_intf_priv\n");
- goto free_dvobj;
- }
- /* 3 misc */
- rtw_reset_continual_urb_error(pdvobjpriv);
- usb_get_dev(pusbd);
- status = _SUCCESS;
-free_dvobj:
- if (status != _SUCCESS && pdvobjpriv) {
- usb_set_intfdata(usb_intf, NULL);
- mutex_destroy(&pdvobjpriv->hw_init_mutex);
- mutex_destroy(&pdvobjpriv->h2c_fwcmd_mutex);
- mutex_destroy(&pdvobjpriv->setch_mutex);
- mutex_destroy(&pdvobjpriv->setbw_mutex);
- kfree(pdvobjpriv);
- pdvobjpriv = NULL;
- }
-exit:
- return pdvobjpriv;
-}
-
-static void usb_dvobj_deinit(struct usb_interface *usb_intf)
-{
- struct dvobj_priv *dvobj = usb_get_intfdata(usb_intf);
-
- usb_set_intfdata(usb_intf, NULL);
- if (dvobj) {
- /* Modify condition for 92DU DMDP 2010.11.18, by Thomas */
- if ((dvobj->NumInterfaces != 2 && dvobj->NumInterfaces != 3) ||
- (dvobj->InterfaceNumber == 1)) {
- if (interface_to_usbdev(usb_intf)->state !=
- USB_STATE_NOTATTACHED) {
- /* If we didn't unplug usb dongle and
- * remove/insert module, driver fails on
- * sitesurvey for the first time when
- * device is up .
- * Reset usb port for sitesurvey fail issue.
- */
- DBG_8723A("usb attached..., try to reset usb device\n");
- usb_reset_device(interface_to_usbdev(usb_intf));
- }
- }
- rtw_deinit_intf_priv(dvobj);
- mutex_destroy(&dvobj->hw_init_mutex);
- mutex_destroy(&dvobj->h2c_fwcmd_mutex);
- mutex_destroy(&dvobj->setch_mutex);
- mutex_destroy(&dvobj->setbw_mutex);
- kfree(dvobj);
- }
- usb_put_dev(interface_to_usbdev(usb_intf));
-}
-
-void rtl8723a_usb_intf_stop(struct rtw_adapter *padapter)
-{
- RT_TRACE(_module_hci_intfs_c_, _drv_err_, "+usb_intf_stop\n");
-
- /* disable_hw_interrupt */
- if (!padapter->bSurpriseRemoved) {
- /* device still exists, so driver can do i/o operation
- * TODO:
- */
- RT_TRACE(_module_hci_intfs_c_, _drv_err_,
- "SurpriseRemoved == false\n");
- }
-
- /* cancel in irp */
- rtl8723au_inirp_deinit(padapter);
-
- /* cancel out irp */
- rtl8723au_write_port_cancel(padapter);
-
- /* todo:cancel other irps */
- RT_TRACE(_module_hci_intfs_c_, _drv_err_, "-usb_intf_stop\n");
-}
-
-static void rtw_dev_unload(struct rtw_adapter *padapter)
-{
- struct submit_ctx *pack_tx_ops = &padapter->xmitpriv.ack_tx_ops;
-
- RT_TRACE(_module_hci_intfs_c_, _drv_err_, "+rtw_dev_unload\n");
-
- if (padapter->bup) {
- DBG_8723A("===> rtw_dev_unload\n");
-
- padapter->bDriverStopped = true;
- if (padapter->xmitpriv.ack_tx)
- rtw23a_sctx_done_err(&pack_tx_ops,
- RTW_SCTX_DONE_DRV_STOP);
-
- /* s3. */
- rtl8723a_usb_intf_stop(padapter);
-
- /* s4. */
- flush_workqueue(padapter->cmdpriv.wq);
-
- /* s5. */
- if (!padapter->bSurpriseRemoved) {
- rtl8723au_hal_deinit(padapter);
- padapter->bSurpriseRemoved = true;
- }
- padapter->bup = false;
- } else {
- RT_TRACE(_module_hci_intfs_c_, _drv_err_,
- "r871x_dev_unload():padapter->bup == false\n");
- }
- DBG_8723A("<=== rtw_dev_unload\n");
- RT_TRACE(_module_hci_intfs_c_, _drv_err_, "-rtw_dev_unload\n");
-}
-
-static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message)
-{
- struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
- struct rtw_adapter *padapter = dvobj->if1;
- struct net_device *pnetdev = padapter->pnetdev;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- int ret = 0;
- unsigned long start_time = jiffies;
-
- DBG_8723A("==> %s (%s:%d)\n", __func__, current->comm, current->pid);
-
- if ((!padapter->bup) || (padapter->bDriverStopped) ||
- (padapter->bSurpriseRemoved)) {
- DBG_8723A("padapter->bup =%d bDriverStopped =%d bSurpriseRemoved = %d\n",
- padapter->bup, padapter->bDriverStopped,
- padapter->bSurpriseRemoved);
- goto exit;
- }
- pwrpriv->bInSuspend = true;
- rtw_cancel_all_timer23a(padapter);
- LeaveAllPowerSaveMode23a(padapter);
-
- down(&pwrpriv->lock);
- /* padapter->net_closed = true; */
- /* s1. */
- if (pnetdev) {
- netif_carrier_off(pnetdev);
- netif_tx_stop_all_queues(pnetdev);
- }
-
- /* s2. */
- rtw_disassoc_cmd23a(padapter, 0, false);
-
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
- check_fwstate(pmlmepriv, _FW_LINKED)) {
- DBG_8723A("%s:%d %s(%pM), length:%d assoc_ssid.length:%d\n",
- __func__, __LINE__,
- pmlmepriv->cur_network.network.Ssid.ssid,
- pmlmepriv->cur_network.network.MacAddress,
- pmlmepriv->cur_network.network.Ssid.ssid_len,
- pmlmepriv->assoc_ssid.ssid_len);
-
- rtw_set_roaming(padapter, 1);
- }
- /* s2-2. indicate disconnect to os */
- rtw_indicate_disconnect23a(padapter);
- /* s2-3. */
- rtw_free_assoc_resources23a(padapter, 1);
- /* s2-4. */
- rtw_free_network_queue23a(padapter);
-
- rtw_dev_unload(padapter);
- up(&pwrpriv->lock);
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
- rtw_cfg80211_indicate_scan_done(
- wdev_to_priv(padapter->rtw_wdev), true);
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
- rtw_indicate_disconnect23a(padapter);
-
-exit:
- DBG_8723A("<=== %s return %d.............. in %dms\n", __func__,
- ret, jiffies_to_msecs(jiffies - start_time));
-
- return ret;
-}
-
-static int rtw_resume(struct usb_interface *pusb_intf)
-{
- struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
- struct rtw_adapter *padapter = dvobj->if1;
- struct net_device *pnetdev;
- struct pwrctrl_priv *pwrpriv = NULL;
- int ret = -1;
- unsigned long start_time = jiffies;
-
- DBG_8723A("==> %s (%s:%d)\n", __func__, current->comm, current->pid);
-
- if (!padapter)
- goto exit;
- pnetdev = padapter->pnetdev;
- pwrpriv = &padapter->pwrctrlpriv;
-
- down(&pwrpriv->lock);
- rtw_reset_drv_sw23a(padapter);
- pwrpriv->bkeepfwalive = false;
-
- DBG_8723A("bkeepfwalive(%x)\n", pwrpriv->bkeepfwalive);
- if (pm_netdev_open23a(pnetdev, true) != 0) {
- up(&pwrpriv->lock);
- goto exit;
- }
-
- netif_device_attach(pnetdev);
- netif_carrier_on(pnetdev);
-
- up(&pwrpriv->lock);
-
- if (padapter->pid[1] != 0) {
- DBG_8723A("pid[1]:%d\n", padapter->pid[1]);
- kill_pid(find_vpid(padapter->pid[1]), SIGUSR2, 1);
- }
-
- rtw23a_roaming(padapter, NULL);
-
- ret = 0;
-exit:
- if (pwrpriv)
- pwrpriv->bInSuspend = false;
- DBG_8723A("<=== %s return %d.............. in %dms\n", __func__,
- ret, jiffies_to_msecs(jiffies - start_time));
-
- return ret;
-}
-
-/*
- * drv_init() - a device potentially for us
- *
- * notes: drv_init() is called when the bus driver has located a card
- * for us to support.
- * We accept the new device by returning 0.
- */
-static struct rtw_adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
- struct usb_interface *pusb_intf,
- const struct usb_device_id *pdid)
-{
- struct rtw_adapter *padapter = NULL;
- struct net_device *pnetdev = NULL;
- int status = _FAIL;
-
- pnetdev = rtw_init_netdev23a(padapter);
- if (!pnetdev)
- goto free_adapter;
- padapter = netdev_priv(pnetdev);
-
- padapter->dvobj = dvobj;
- padapter->bDriverStopped = true;
- dvobj->if1 = padapter;
- dvobj->padapters[dvobj->iface_nums++] = padapter;
- padapter->iface_id = IFACE_ID0;
-
- rtl8723au_set_hw_type(padapter);
-
- SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj));
-
- if (rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj)))
- goto free_adapter;
-
- /* step 2. allocate HalData */
- padapter->HalData = kzalloc(sizeof(struct hal_data_8723a), GFP_KERNEL);
- if (!padapter->HalData)
- goto free_wdev;
-
- /* step read_chip_version */
- rtl8723a_read_chip_version(padapter);
-
- /* step usb endpoint mapping */
- if (!rtl8723au_chip_configure(padapter))
- goto free_hal_data;
-
- /* step read efuse/eeprom data and get mac_addr */
- rtl8723a_read_adapter_info(padapter);
-
- /* step 5. */
- if (rtw_init_drv_sw23a(padapter) == _FAIL) {
- RT_TRACE(_module_hci_intfs_c_, _drv_err_,
- "Initialize driver software resource Failed!\n");
- goto free_hal_data;
- }
-
-#ifdef CONFIG_PM
- if (padapter->pwrctrlpriv.bSupportRemoteWakeup) {
- dvobj->pusbdev->do_remote_wakeup = 1;
- pusb_intf->needs_remote_wakeup = 1;
- device_init_wakeup(&pusb_intf->dev, 1);
- DBG_8723A("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~~~~\n");
- DBG_8723A("\n padapter->pwrctrlpriv.bSupportRemoteWakeup~~~[%d]~~~\n",
- device_may_wakeup(&pusb_intf->dev));
- }
-#endif
- /* 2012-07-11 Move here to prevent the 8723AS-VAU BT
- * auto suspend influence
- */
- if (usb_autopm_get_interface(pusb_intf) < 0)
- DBG_8723A("can't get autopm:\n");
-#ifdef CONFIG_8723AU_BT_COEXIST
- padapter->pwrctrlpriv.autopm_cnt = 1;
-#endif
-
- /* If the eeprom mac address is corrupted, assign a random address */
- if (is_broadcast_ether_addr(padapter->eeprompriv.mac_addr) ||
- is_zero_ether_addr(padapter->eeprompriv.mac_addr))
- eth_random_addr(padapter->eeprompriv.mac_addr);
-
- DBG_8723A("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n",
- padapter->bDriverStopped, padapter->bSurpriseRemoved,
- padapter->bup, padapter->hw_init_completed
- );
- status = _SUCCESS;
-
-free_hal_data:
- if (status != _SUCCESS)
- kfree(padapter->HalData);
-free_wdev:
- if (status != _SUCCESS) {
- rtw_wdev_unregister(padapter->rtw_wdev);
- rtw_wdev_free(padapter->rtw_wdev);
- }
-free_adapter:
- if (status != _SUCCESS) {
- if (pnetdev)
- free_netdev(pnetdev);
- padapter = NULL;
- }
- return padapter;
-}
-
-static void rtw_usb_if1_deinit(struct rtw_adapter *if1)
-{
- struct net_device *pnetdev = if1->pnetdev;
- struct mlme_priv *pmlmepriv = &if1->mlmepriv;
-
- if (check_fwstate(pmlmepriv, _FW_LINKED))
- rtw_disassoc_cmd23a(if1, 0, false);
-
-#ifdef CONFIG_8723AU_AP_MODE
- free_mlme_ap_info23a(if1);
-#endif
-
- if (pnetdev)
- unregister_netdev(pnetdev); /* will call netdev_close() */
-
- rtw_cancel_all_timer23a(if1);
-
- rtw_dev_unload(if1);
-
- DBG_8723A("+r871xu_dev_remove, hw_init_completed =%d\n",
- if1->hw_init_completed);
-
- if (if1->rtw_wdev) {
- rtw_wdev_unregister(if1->rtw_wdev);
- rtw_wdev_free(if1->rtw_wdev);
- }
-
-#ifdef CONFIG_8723AU_BT_COEXIST
- if (1 == if1->pwrctrlpriv.autopm_cnt) {
- usb_autopm_put_interface(adapter_to_dvobj(if1)->pusbintf);
- if1->pwrctrlpriv.autopm_cnt--;
- }
-#endif
-
- rtw_free_drv_sw23a(if1);
-
- if (pnetdev)
- free_netdev(pnetdev);
-}
-
-static int rtw_drv_init(struct usb_interface *pusb_intf,
- const struct usb_device_id *pdid)
-{
- struct rtw_adapter *if1 = NULL;
- struct dvobj_priv *dvobj;
- struct usb_device *udev;
- int status = _FAIL;
-
- RT_TRACE(_module_hci_intfs_c_, _drv_err_, "+rtw_drv_init\n");
-
- /* Initialize dvobj_priv */
- dvobj = usb_dvobj_init(pusb_intf);
- if (!dvobj) {
- RT_TRACE(_module_hci_intfs_c_, _drv_err_,
- "initialize device object priv Failed!\n");
- goto exit;
- }
-
- udev = dvobj->pusbdev;
- dev_warn(&udev->dev, "WARNING: The rtl8723au driver is deprecated!");
- dev_warn(&udev->dev, "Please use the rtl8xxxu driver for this device!");
-
- if1 = rtw_usb_if1_init(dvobj, pusb_intf, pdid);
- if (!if1) {
- DBG_8723A("rtw_init_primary_adapter Failed!\n");
- goto free_dvobj;
- }
-
- /* dev_alloc_name && register_netdev */
- status = rtw_drv_register_netdev(if1);
- if (status != _SUCCESS)
- goto free_if1;
- RT_TRACE(_module_hci_intfs_c_, _drv_err_,
- "-871x_drv - drv_init, success!\n");
-
- status = _SUCCESS;
-
-free_if1:
- if (status != _SUCCESS && if1)
- rtw_usb_if1_deinit(if1);
-free_dvobj:
- if (status != _SUCCESS)
- usb_dvobj_deinit(pusb_intf);
-exit:
- return status == _SUCCESS ? 0 : -ENODEV;
-}
-
-/* dev_remove() - our device is being removed */
-static void rtw_disconnect(struct usb_interface *pusb_intf)
-{
- struct dvobj_priv *dvobj;
- struct rtw_adapter *padapter;
- struct net_device *pnetdev;
- struct mlme_priv *pmlmepriv;
-
- dvobj = usb_get_intfdata(pusb_intf);
- if (!dvobj)
- return;
-
- padapter = dvobj->if1;
- pnetdev = padapter->pnetdev;
- pmlmepriv = &padapter->mlmepriv;
-
- usb_set_intfdata(pusb_intf, NULL);
-
- RT_TRACE(_module_hci_intfs_c_, _drv_err_, "+dev_remove()\n");
-
- rtw_pm_set_ips23a(padapter, IPS_NONE);
- rtw_pm_set_lps23a(padapter, PS_MODE_ACTIVE);
-
- LeaveAllPowerSaveMode23a(padapter);
-
- rtw_usb_if1_deinit(padapter);
-
- usb_dvobj_deinit(pusb_intf);
-
- RT_TRACE(_module_hci_intfs_c_, _drv_err_, "-dev_remove()\n");
- DBG_8723A("-r871xu_dev_remove, done\n");
-}
-
-static int __init rtw_drv_entry(void)
-{
- RT_TRACE(_module_hci_intfs_c_, _drv_err_, "+rtw_drv_entry\n");
- return usb_register(usb_drv);
-}
-
-static void __exit rtw_drv_halt(void)
-{
- RT_TRACE(_module_hci_intfs_c_, _drv_err_, "+rtw_drv_halt\n");
- DBG_8723A("+rtw_drv_halt\n");
-
- usb_deregister(usb_drv);
-
- DBG_8723A("-rtw_drv_halt\n");
-}
-
-module_init(rtw_drv_entry);
-module_exit(rtw_drv_halt);
diff --git a/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c b/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c
deleted file mode 100644
index cf4a50618670..000000000000
--- a/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _USB_OPS_LINUX_C_
-
-#include <drv_types.h>
-#include <usb_ops_linux.h>
-#include <rtw_sreset.h>
-
-void rtl8723au_read_port_cancel(struct rtw_adapter *padapter)
-{
- struct recv_buf *precvbuf;
- int i;
-
- precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf;
-
- DBG_8723A("%s\n", __func__);
-
- padapter->bReadPortCancel = true;
-
- for (i = 0; i < NR_RECVBUFF ; i++) {
- if (precvbuf->purb)
- usb_kill_urb(precvbuf->purb);
- precvbuf++;
- }
- usb_kill_urb(padapter->recvpriv.int_in_urb);
-}
-
-static void usb_write_port23a_complete(struct urb *purb)
-{
- struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context;
- struct rtw_adapter *padapter = pxmitbuf->padapter;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct hal_data_8723a *phaldata;
- unsigned long irqL;
-
- switch (pxmitbuf->flags) {
- case HIGH_QUEUE_INX:
-#ifdef CONFIG_8723AU_AP_MODE
- rtw_chk_hi_queue_cmd23a(padapter);
-#endif
- break;
- default:
- break;
- }
-
- if (padapter->bSurpriseRemoved || padapter->bDriverStopped ||
- padapter->bWritePortCancel) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_write_port23a_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
- padapter->bDriverStopped, padapter->bSurpriseRemoved);
- DBG_8723A("%s(): TX Warning! bDriverStopped(%d) OR "
- "bSurpriseRemoved(%d) bWritePortCancel(%d) "
- "pxmitbuf->ext_tag(%x)\n", __func__,
- padapter->bDriverStopped, padapter->bSurpriseRemoved,
- padapter->bReadPortCancel, pxmitbuf->ext_tag);
-
- goto check_completion;
- }
-
- if (purb->status) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_write_port23a_complete : purb->status(%d) != 0\n",
- purb->status);
- DBG_8723A("###=> urb_write_port_complete status(%d)\n",
- purb->status);
- if (purb->status == -EPIPE || purb->status == -EPROTO) {
- } else if (purb->status == -EINPROGRESS) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_write_port23a_complete: EINPROGESS\n");
- goto check_completion;
- } else if (purb->status == -ENOENT) {
- DBG_8723A("%s: -ENOENT\n", __func__);
- goto check_completion;
- } else if (purb->status == -ECONNRESET) {
- DBG_8723A("%s: -ECONNRESET\n", __func__);
- goto check_completion;
- } else if (purb->status == -ESHUTDOWN) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_write_port23a_complete: ESHUTDOWN\n");
- padapter->bDriverStopped = true;
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_write_port23a_complete:bDriverStopped = true\n");
- goto check_completion;
- } else {
- padapter->bSurpriseRemoved = true;
- DBG_8723A("bSurpriseRemoved = true\n");
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_write_port23a_complete:bSurpriseRemoved = true\n");
- goto check_completion;
- }
- }
- phaldata = GET_HAL_DATA(padapter);
- phaldata->srestpriv.last_tx_complete_time = jiffies;
-
-check_completion:
- spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
- rtw23a_sctx_done_err(&pxmitbuf->sctx,
- purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR :
- RTW_SCTX_DONE_SUCCESS);
- spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
-
- rtw_free_xmitbuf23a(pxmitpriv, pxmitbuf);
-
- tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
-}
-
-int rtl8723au_write_port(struct rtw_adapter *padapter, u32 addr, u32 cnt,
- struct xmit_buf *pxmitbuf)
-{
- struct urb *purb = NULL;
- struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct xmit_frame *pxmitframe;
- struct usb_device *pusbd = pdvobj->pusbdev;
- unsigned long irqL;
- unsigned int pipe, ep_num;
- int status;
- int ret = _FAIL;
-
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_, "+usb_write_port23a\n");
-
- if (padapter->bDriverStopped || padapter->bSurpriseRemoved) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "%s:(padapter->bDriverStopped || padapter->bSurpriseRemoved)!!!\n",
- __func__);
- rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY);
- goto exit;
- }
-
- pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
- spin_lock_irqsave(&pxmitpriv->lock, irqL);
-
- switch (addr) {
- case VO_QUEUE_INX:
- pxmitbuf->flags = VO_QUEUE_INX;
- break;
- case VI_QUEUE_INX:
- pxmitbuf->flags = VI_QUEUE_INX;
- break;
- case BE_QUEUE_INX:
- pxmitbuf->flags = BE_QUEUE_INX;
- break;
- case BK_QUEUE_INX:
- pxmitbuf->flags = BK_QUEUE_INX;
- break;
- case HIGH_QUEUE_INX:
- pxmitbuf->flags = HIGH_QUEUE_INX;
- break;
- default:
- pxmitbuf->flags = MGT_QUEUE_INX;
- break;
- }
-
- spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
-
- purb = pxmitbuf->pxmit_urb[0];
-
- /* translate DMA FIFO addr to pipehandle */
- ep_num = pdvobj->Queue2Pipe[addr];
- pipe = usb_sndbulkpipe(pusbd, ep_num);
-
- usb_fill_bulk_urb(purb, pusbd, pipe,
- pxmitframe->buf_addr, /* pxmitbuf->pbuf */
- cnt, usb_write_port23a_complete,
- pxmitbuf);/* context is pxmitbuf */
-
- status = usb_submit_urb(purb, GFP_ATOMIC);
- if (!status) {
- struct hal_data_8723a *phaldata = GET_HAL_DATA(padapter);
- phaldata->srestpriv.last_tx_time = jiffies;
- } else {
- rtw23a_sctx_done_err(&pxmitbuf->sctx,
- RTW_SCTX_DONE_WRITE_PORT_ERR);
- DBG_8723A("usb_write_port23a, status =%d\n", status);
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- "usb_write_port23a(): usb_submit_urb, status =%x\n",
- status);
-
- switch (status) {
- case -ENODEV:
- padapter->bDriverStopped = true;
- break;
- default:
- break;
- }
- goto exit;
- }
- ret = _SUCCESS;
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_, "-usb_write_port23a\n");
-
-exit:
- if (ret != _SUCCESS)
- rtw_free_xmitbuf23a(pxmitpriv, pxmitbuf);
-
- return ret;
-}
-
-void rtl8723au_write_port_cancel(struct rtw_adapter *padapter)
-{
- struct xmit_buf *pxmitbuf;
- int j;
-
- DBG_8723A("%s\n", __func__);
-
- padapter->bWritePortCancel = true;
-
- list_for_each_entry(pxmitbuf, &padapter->xmitpriv.xmitbuf_list,
- list2) {
- for (j = 0; j < 8; j++) {
- if (pxmitbuf->pxmit_urb[j])
- usb_kill_urb(pxmitbuf->pxmit_urb[j]);
- }
- }
- list_for_each_entry(pxmitbuf, &padapter->xmitpriv.xmitextbuf_list,
- list2) {
- for (j = 0; j < 8; j++) {
- if (pxmitbuf->pxmit_urb[j])
- usb_kill_urb(pxmitbuf->pxmit_urb[j]);
- }
- }
-}
diff --git a/drivers/staging/rtl8723au/os_dep/xmit_linux.c b/drivers/staging/rtl8723au/os_dep/xmit_linux.c
deleted file mode 100644
index 64be72ac38ee..000000000000
--- a/drivers/staging/rtl8723au/os_dep/xmit_linux.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.
- *
- ******************************************************************************/
-#define _XMIT_OSDEP_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-#include <linux/if_ether.h>
-#include <linux/ip.h>
-#include <wifi.h>
-#include <mlme_osdep.h>
-#include <xmit_osdep.h>
-#include <osdep_intf.h>
-
-int rtw_os_xmit_resource_alloc23a(struct rtw_adapter *padapter,
- struct xmit_buf *pxmitbuf, u32 alloc_sz)
-{
- int i;
-
- pxmitbuf->pallocated_buf = kzalloc(alloc_sz, GFP_KERNEL);
- if (pxmitbuf->pallocated_buf == NULL)
- return _FAIL;
-
- pxmitbuf->pbuf = PTR_ALIGN(pxmitbuf->pallocated_buf, XMITBUF_ALIGN_SZ);
-
- for (i = 0; i < 8; i++) {
- pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
- if (!pxmitbuf->pxmit_urb[i]) {
- DBG_8723A("pxmitbuf->pxmit_urb[i]==NULL");
- return _FAIL;
- }
- }
- return _SUCCESS;
-}
-
-void rtw_os_xmit_resource_free23a(struct rtw_adapter *padapter,
- struct xmit_buf *pxmitbuf)
-{
- int i;
-
- for (i = 0; i < 8; i++)
- usb_free_urb(pxmitbuf->pxmit_urb[i]);
- kfree(pxmitbuf->pallocated_buf);
-}
-
-#define WMM_XMIT_THRESHOLD (NR_XMITFRAME*2/5)
-
-void rtw_os_pkt_complete23a(struct rtw_adapter *padapter, struct sk_buff *pkt)
-{
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- u16 queue;
-
- queue = skb_get_queue_mapping(pkt);
- if (padapter->registrypriv.wifi_spec) {
- if (__netif_subqueue_stopped(padapter->pnetdev, queue) &&
- (pxmitpriv->hwxmits[queue].accnt < WMM_XMIT_THRESHOLD))
- netif_wake_subqueue(padapter->pnetdev, queue);
- } else {
- if (__netif_subqueue_stopped(padapter->pnetdev, queue))
- netif_wake_subqueue(padapter->pnetdev, queue);
- }
- dev_kfree_skb_any(pkt);
-}
-
-void rtw_os_xmit_complete23a(struct rtw_adapter *padapter,
- struct xmit_frame *pxframe)
-{
- if (pxframe->pkt)
- rtw_os_pkt_complete23a(padapter, pxframe->pkt);
-
- pxframe->pkt = NULL;
-}
-
-void rtw_os_xmit_schedule23a(struct rtw_adapter *padapter)
-{
- struct xmit_priv *pxmitpriv;
-
- if (!padapter)
- return;
- pxmitpriv = &padapter->xmitpriv;
-
- spin_lock_bh(&pxmitpriv->lock);
-
- if (rtw_txframes_pending23a(padapter))
- tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
- spin_unlock_bh(&pxmitpriv->lock);
-}
-
-static void rtw_check_xmit_resource(struct rtw_adapter *padapter,
- struct sk_buff *pkt)
-{
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- u16 queue;
-
- queue = skb_get_queue_mapping(pkt);
- if (padapter->registrypriv.wifi_spec) {
- /* No free space for Tx, tx_worker is too slow */
- if (pxmitpriv->hwxmits[queue].accnt > WMM_XMIT_THRESHOLD)
- netif_stop_subqueue(padapter->pnetdev, queue);
- } else {
- if (pxmitpriv->free_xmitframe_cnt <= 4) {
- if (!netif_tx_queue_stopped(netdev_get_tx_queue(padapter->pnetdev, queue)))
- netif_stop_subqueue(padapter->pnetdev, queue);
- }
- }
-}
-
-int rtw_xmit23a_entry23a(struct sk_buff *skb, struct net_device *pnetdev)
-{
- struct rtw_adapter *padapter = netdev_priv(pnetdev);
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- int res = 0;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, "+xmit_enry\n");
-
- if (!rtw_if_up23a(padapter)) {
- RT_TRACE(_module_xmit_osdep_c_, _drv_err_,
- "rtw_xmit23a_entry23a: rtw_if_up23a fail\n");
- goto drop_packet;
- }
-
- rtw_check_xmit_resource(padapter, skb);
-
- res = rtw_xmit23a(padapter, skb);
- if (res < 0)
- goto drop_packet;
-
- pxmitpriv->tx_pkts++;
- RT_TRACE(_module_xmit_osdep_c_, _drv_info_,
- "rtw_xmit23a_entry23a: tx_pkts=%d\n",
- (u32)pxmitpriv->tx_pkts);
- goto exit;
-
-drop_packet:
- pxmitpriv->tx_drop++;
- dev_kfree_skb_any(skb);
- RT_TRACE(_module_xmit_osdep_c_, _drv_notice_,
- "rtw_xmit23a_entry23a: drop, tx_drop=%d\n",
- (u32)pxmitpriv->tx_drop);
-exit:
- return 0;
-}
diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c
index 0f0cd4a03cd4..f27df0b4cb44 100644
--- a/drivers/staging/rts5208/ms.c
+++ b/drivers/staging/rts5208/ms.c
@@ -63,12 +63,12 @@ static int ms_transfer_tpc(struct rtsx_chip *chip, u8 trans_mode,
rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
- 0x01, PINGPONG_BUFFER);
+ 0x01, PINGPONG_BUFFER);
rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER,
- 0xFF, MS_TRANSFER_START | trans_mode);
+ 0xFF, MS_TRANSFER_START | trans_mode);
rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER,
- MS_TRANSFER_END, MS_TRANSFER_END);
+ MS_TRANSFER_END, MS_TRANSFER_END);
rtsx_add_cmd(chip, READ_REG_CMD, MS_TRANS_CFG, 0, 0);
@@ -109,8 +109,8 @@ static int ms_transfer_tpc(struct rtsx_chip *chip, u8 trans_mode,
}
static int ms_transfer_data(struct rtsx_chip *chip, u8 trans_mode,
- u8 tpc, u16 sec_cnt, u8 cfg, bool mode_2k,
- int use_sg, void *buf, int buf_len)
+ u8 tpc, u16 sec_cnt, u8 cfg, bool mode_2k,
+ int use_sg, void *buf, int buf_len)
{
int retval;
u8 val, err_code = 0;
@@ -206,7 +206,7 @@ static int ms_write_bytes(struct rtsx_chip *chip,
rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
- 0x01, PINGPONG_BUFFER);
+ 0x01, PINGPONG_BUFFER);
rtsx_add_cmd(chip, WRITE_REG_CMD,
MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES);
@@ -253,7 +253,7 @@ static int ms_write_bytes(struct rtsx_chip *chip,
}
static int ms_read_bytes(struct rtsx_chip *chip,
- u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len)
+ u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len)
{
struct ms_info *ms_card = &chip->ms_card;
int retval, i;
@@ -270,12 +270,12 @@ static int ms_read_bytes(struct rtsx_chip *chip,
rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
- 0x01, PINGPONG_BUFFER);
+ 0x01, PINGPONG_BUFFER);
rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF,
- MS_TRANSFER_START | MS_TM_READ_BYTES);
+ MS_TRANSFER_START | MS_TM_READ_BYTES);
rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER,
- MS_TRANSFER_END, MS_TRANSFER_END);
+ MS_TRANSFER_END, MS_TRANSFER_END);
for (i = 0; i < data_len - 1; i++)
rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0);
@@ -284,7 +284,7 @@ static int ms_read_bytes(struct rtsx_chip *chip,
rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len, 0, 0);
else
rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len - 1,
- 0, 0);
+ 0, 0);
retval = rtsx_send_cmd(chip, MS_CARD, 5000);
if (retval < 0) {
@@ -334,8 +334,8 @@ static int ms_read_bytes(struct rtsx_chip *chip,
return STATUS_SUCCESS;
}
-static int ms_set_rw_reg_addr(struct rtsx_chip *chip,
- u8 read_start, u8 read_cnt, u8 write_start, u8 write_cnt)
+static int ms_set_rw_reg_addr(struct rtsx_chip *chip, u8 read_start,
+ u8 read_cnt, u8 write_start, u8 write_cnt)
{
int retval, i;
u8 data[4];
@@ -1417,7 +1417,6 @@ static int ms_read_status_reg(struct rtsx_chip *chip)
return STATUS_SUCCESS;
}
-
static int ms_read_extra_data(struct rtsx_chip *chip,
u16 block_addr, u8 page_num, u8 *buf, int buf_len)
{
@@ -1582,7 +1581,6 @@ static int ms_write_extra_data(struct rtsx_chip *chip,
return STATUS_SUCCESS;
}
-
static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num)
{
struct ms_info *ms_card = &chip->ms_card;
@@ -1667,7 +1665,6 @@ static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num)
return STATUS_SUCCESS;
}
-
static int ms_set_bad_block(struct rtsx_chip *chip, u16 phy_blk)
{
struct ms_info *ms_card = &chip->ms_card;
@@ -1738,7 +1735,6 @@ static int ms_set_bad_block(struct rtsx_chip *chip, u16 phy_blk)
return STATUS_SUCCESS;
}
-
static int ms_erase_block(struct rtsx_chip *chip, u16 phy_blk)
{
struct ms_info *ms_card = &chip->ms_card;
@@ -1808,7 +1804,6 @@ ERASE_RTY:
return STATUS_SUCCESS;
}
-
static void ms_set_page_status(u16 log_blk, u8 type, u8 *extra, int extra_len)
{
if (!extra || (extra_len < MS_EXTRA_SIZE))
@@ -2152,7 +2147,6 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
return STATUS_SUCCESS;
}
-
static int reset_ms(struct rtsx_chip *chip)
{
struct ms_info *ms_card = &chip->ms_card;
@@ -2471,7 +2465,7 @@ static u16 ms_get_l2p_tbl(struct rtsx_chip *chip, int seg_no, u16 log_off)
if (!ms_card->segment)
return 0xFFFF;
- segment = &(ms_card->segment[seg_no]);
+ segment = &ms_card->segment[seg_no];
if (segment->l2p_table)
return segment->l2p_table[log_off];
@@ -2488,7 +2482,7 @@ static void ms_set_l2p_tbl(struct rtsx_chip *chip,
if (!ms_card->segment)
return;
- segment = &(ms_card->segment[seg_no]);
+ segment = &ms_card->segment[seg_no];
if (segment->l2p_table)
segment->l2p_table[log_off] = phy_blk;
}
@@ -2500,7 +2494,7 @@ static void ms_set_unused_block(struct rtsx_chip *chip, u16 phy_blk)
int seg_no;
seg_no = (int)phy_blk >> 9;
- segment = &(ms_card->segment[seg_no]);
+ segment = &ms_card->segment[seg_no];
segment->free_table[segment->set_index++] = phy_blk;
if (segment->set_index >= MS_FREE_TABLE_CNT)
@@ -2515,7 +2509,7 @@ static u16 ms_get_unused_block(struct rtsx_chip *chip, int seg_no)
struct zone_entry *segment;
u16 phy_blk;
- segment = &(ms_card->segment[seg_no]);
+ segment = &ms_card->segment[seg_no];
if (segment->unused_blk_cnt <= 0)
return 0xFFFF;
@@ -2544,7 +2538,7 @@ static int ms_arbitrate_l2p(struct rtsx_chip *chip, u16 phy_blk,
u16 tmp_blk;
seg_no = (int)phy_blk >> 9;
- segment = &(ms_card->segment[seg_no]);
+ segment = &ms_card->segment[seg_no];
tmp_blk = segment->l2p_table[log_off];
if (us1 != us2) {
@@ -2608,7 +2602,7 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no)
else
table_size = 496;
- segment = &(ms_card->segment[seg_no]);
+ segment = &ms_card->segment[seg_no];
if (!segment->l2p_table) {
segment->l2p_table = vmalloc(table_size * 2);
@@ -2717,7 +2711,7 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no)
us2 = extra[0] & 0x10;
(void)ms_arbitrate_l2p(chip, phy_blk,
- log_blk-ms_start_idx[seg_no], us1, us2);
+ log_blk - ms_start_idx[seg_no], us1, us2);
continue;
}
@@ -2809,7 +2803,6 @@ BUILD_FAIL:
return STATUS_FAIL;
}
-
int reset_ms_card(struct rtsx_chip *chip)
{
struct ms_info *ms_card = &chip->ms_card;
@@ -2896,7 +2889,6 @@ static int mspro_set_rw_cmd(struct rtsx_chip *chip,
return STATUS_SUCCESS;
}
-
void mspro_stop_seq_mode(struct rtsx_chip *chip)
{
struct ms_info *ms_card = &chip->ms_card;
@@ -3312,7 +3304,6 @@ int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip,
return STATUS_FAIL;
}
-
static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk,
u16 log_blk, u8 start_page, u8 end_page,
u8 *buf, unsigned int *index,
@@ -3719,7 +3710,6 @@ static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk,
return STATUS_SUCCESS;
}
-
static int ms_finish_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
u16 log_blk, u8 page_off)
{
@@ -3770,7 +3760,7 @@ static int ms_prepare_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
int ms_delay_write(struct rtsx_chip *chip)
{
struct ms_info *ms_card = &chip->ms_card;
- struct ms_delay_write_tag *delay_write = &(ms_card->delay_write);
+ struct ms_delay_write_tag *delay_write = &ms_card->delay_write;
int retval;
if (delay_write->delay_write_flag) {
@@ -3816,7 +3806,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip,
u8 start_page, end_page = 0, page_cnt;
u8 *ptr;
#ifdef MS_DELAY_WRITE
- struct ms_delay_write_tag *delay_write = &(ms_card->delay_write);
+ struct ms_delay_write_tag *delay_write = &ms_card->delay_write;
#endif
ms_set_err_code(chip, MS_NO_ERROR);
@@ -3996,7 +3986,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip,
for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1;
seg_no++) {
- if (log_blk < ms_start_idx[seg_no+1])
+ if (log_blk < ms_start_idx[seg_no + 1])
break;
}
@@ -4082,13 +4072,12 @@ int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
return retval;
}
-
void ms_free_l2p_tbl(struct rtsx_chip *chip)
{
struct ms_info *ms_card = &chip->ms_card;
int i = 0;
- if (ms_card->segment != NULL) {
+ if (ms_card->segment) {
for (i = 0; i < ms_card->segment_cnt; i++) {
vfree(ms_card->segment[i].l2p_table);
ms_card->segment[i].l2p_table = NULL;
@@ -4313,7 +4302,7 @@ int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip)
if (retval != STATUS_SUCCESS) {
set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
rtsx_trace(chip);
- goto GetEKBFinish;
+ goto free_buffer;
}
retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA,
@@ -4322,19 +4311,20 @@ int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip)
set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
rtsx_clear_ms_error(chip);
rtsx_trace(chip);
- goto GetEKBFinish;
+ goto free_buffer;
}
if (check_ms_err(chip)) {
set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN);
rtsx_clear_ms_error(chip);
rtsx_trace(chip);
- return STATUS_FAIL;
+ retval = STATUS_FAIL;
+ goto free_buffer;
}
bufflen = min_t(int, 1052, scsi_bufflen(srb));
rtsx_stor_set_xfer_buf(buf, bufflen, srb);
-GetEKBFinish:
+free_buffer:
kfree(buf);
return retval;
}
@@ -4566,7 +4556,7 @@ int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip)
if (retval != STATUS_SUCCESS) {
set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
rtsx_trace(chip);
- goto GetICVFinish;
+ goto free_buffer;
}
retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA,
@@ -4575,19 +4565,20 @@ int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip)
set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
rtsx_clear_ms_error(chip);
rtsx_trace(chip);
- goto GetICVFinish;
+ goto free_buffer;
}
if (check_ms_err(chip)) {
set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
rtsx_clear_ms_error(chip);
rtsx_trace(chip);
- return STATUS_FAIL;
+ retval = STATUS_FAIL;
+ goto free_buffer;
}
bufflen = min_t(int, 1028, scsi_bufflen(srb));
rtsx_stor_set_xfer_buf(buf, bufflen, srb);
-GetICVFinish:
+free_buffer:
kfree(buf);
return retval;
}
@@ -4657,8 +4648,8 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip)
rtsx_send_cmd_no_wait(chip);
- retval = rtsx_transfer_data(chip, MS_CARD, buf + 4 + i*512,
- 512, 0, DMA_TO_DEVICE, 3000);
+ retval = rtsx_transfer_data(chip, MS_CARD, buf + 4 + i * 512,
+ 512, 0, DMA_TO_DEVICE, 3000);
if ((retval < 0) || check_ms_err(chip)) {
rtsx_clear_ms_error(chip);
if (ms_card->mg_auth == 0) {
@@ -4705,7 +4696,7 @@ SetICVFinish:
void ms_cleanup_work(struct rtsx_chip *chip)
{
- struct ms_info *ms_card = &(chip->ms_card);
+ struct ms_info *ms_card = &chip->ms_card;
if (CHK_MSPRO(ms_card)) {
if (ms_card->seq_mode) {
@@ -4770,7 +4761,7 @@ int ms_power_off_card3v3(struct rtsx_chip *chip)
int release_ms_card(struct rtsx_chip *chip)
{
- struct ms_info *ms_card = &(chip->ms_card);
+ struct ms_info *ms_card = &chip->ms_card;
int retval;
#ifdef MS_DELAY_WRITE
diff --git a/drivers/staging/rts5208/ms.h b/drivers/staging/rts5208/ms.h
index d919170f2720..d7686399df97 100644
--- a/drivers/staging/rts5208/ms.h
+++ b/drivers/staging/rts5208/ms.h
@@ -125,7 +125,6 @@
#define Pro_CatagoryReg 0x06
#define Pro_ClassReg 0x07
-
#define Pro_SystemParm 0x10
#define Pro_DataCount1 0x11
#define Pro_DataCount0 0x12
diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c
index 25d095a5ade7..5d65a5cdc748 100644
--- a/drivers/staging/rts5208/rtsx.c
+++ b/drivers/staging/rts5208/rtsx.c
@@ -34,27 +34,27 @@ MODULE_DESCRIPTION("Realtek PCI-Express card reader rts5208/rts5288 driver");
MODULE_LICENSE("GPL");
static unsigned int delay_use = 1;
-module_param(delay_use, uint, S_IRUGO | S_IWUSR);
+module_param(delay_use, uint, 0644);
MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device");
static int ss_en;
-module_param(ss_en, int, S_IRUGO | S_IWUSR);
+module_param(ss_en, int, 0644);
MODULE_PARM_DESC(ss_en, "enable selective suspend");
static int ss_interval = 50;
-module_param(ss_interval, int, S_IRUGO | S_IWUSR);
+module_param(ss_interval, int, 0644);
MODULE_PARM_DESC(ss_interval, "Interval to enter ss state in seconds");
static int auto_delink_en;
-module_param(auto_delink_en, int, S_IRUGO | S_IWUSR);
+module_param(auto_delink_en, int, 0644);
MODULE_PARM_DESC(auto_delink_en, "enable auto delink");
static unsigned char aspm_l0s_l1_en;
-module_param(aspm_l0s_l1_en, byte, S_IRUGO | S_IWUSR);
+module_param(aspm_l0s_l1_en, byte, 0644);
MODULE_PARM_DESC(aspm_l0s_l1_en, "enable device aspm");
static int msi_en;
-module_param(msi_en, int, S_IRUGO | S_IWUSR);
+module_param(msi_en, int, 0644);
MODULE_PARM_DESC(msi_en, "enable msi");
static irqreturn_t rtsx_interrupt(int irq, void *dev_id);
@@ -81,14 +81,16 @@ static int slave_alloc(struct scsi_device *sdev)
static int slave_configure(struct scsi_device *sdev)
{
- /* Scatter-gather buffers (all but the last) must have a length
+ /*
+ * Scatter-gather buffers (all but the last) must have a length
* divisible by the bulk maxpacket size. Otherwise a data packet
* would end up being short, causing a premature end to the data
* transfer. Since high-speed bulk pipes have a maxpacket size
* of 512, we'll use that as the scsi device queue's DMA alignment
* mask. Guaranteeing proper alignment of the first buffer will
* have the desired effect because, except at the beginning and
- * the end, scatter-gather buffers follow page boundaries. */
+ * the end, scatter-gather buffers follow page boundaries.
+ */
blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
/* Set the SCSI level to at least 2. We'll leave it at 3 if that's
@@ -111,7 +113,6 @@ static int slave_configure(struct scsi_device *sdev)
return 0;
}
-
/***********************************************************************
* /proc/scsi/ functions
***********************************************************************/
@@ -130,7 +131,7 @@ static int queuecommand_lck(struct scsi_cmnd *srb,
struct rtsx_chip *chip = dev->chip;
/* check for state-transition errors */
- if (chip->srb != NULL) {
+ if (chip->srb) {
dev_err(&dev->pci->dev, "Error: chip->srb = %p\n",
chip->srb);
return SCSI_MLQUEUE_HOST_BUSY;
@@ -186,8 +187,10 @@ static int command_abort(struct scsi_cmnd *srb)
return SUCCESS;
}
-/* This invokes the transport reset mechanism to reset the state of the
- * device */
+/*
+ * This invokes the transport reset mechanism to reset the state of the
+ * device
+ */
static int device_reset(struct scsi_cmnd *srb)
{
int result = 0;
@@ -209,7 +212,6 @@ static int bus_reset(struct scsi_cmnd *srb)
return result < 0 ? FAILED : SUCCESS;
}
-
/*
* this defines our host template, with which we'll allocate hosts
*/
@@ -259,7 +261,6 @@ static struct scsi_host_template rtsx_host_template = {
.module = THIS_MODULE
};
-
static int rtsx_acquire_irq(struct rtsx_dev *dev)
{
struct rtsx_chip *chip = dev->chip;
@@ -282,7 +283,6 @@ static int rtsx_acquire_irq(struct rtsx_dev *dev)
return 0;
}
-
int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val)
{
struct pci_dev *pdev;
@@ -515,7 +515,6 @@ SkipForAbort:
complete_and_exit(&dev->control_exit, 0);
}
-
static int rtsx_polling_thread(void *__dev)
{
struct rtsx_dev *dev = __dev;
@@ -625,7 +624,6 @@ Exit:
return IRQ_HANDLED;
}
-
/* Release all our dynamic resources */
static void rtsx_release_resources(struct rtsx_dev *dev)
{
@@ -660,15 +658,19 @@ static void rtsx_release_resources(struct rtsx_dev *dev)
kfree(dev->chip);
}
-/* First stage of disconnect processing: stop all commands and remove
- * the host */
+/*
+ * First stage of disconnect processing: stop all commands and remove
+ * the host
+ */
static void quiesce_and_remove_host(struct rtsx_dev *dev)
{
struct Scsi_Host *host = rtsx_to_host(dev);
struct rtsx_chip *chip = dev->chip;
- /* Prevent new transfers, stop the current command, and
- * interrupt a SCSI-scan or device-reset delay */
+ /*
+ * Prevent new transfers, stop the current command, and
+ * interrupt a SCSI-scan or device-reset delay
+ */
mutex_lock(&dev->dev_mutex);
scsi_lock(host);
rtsx_set_stat(chip, RTSX_STAT_DISCONNECT);
@@ -680,9 +682,11 @@ static void quiesce_and_remove_host(struct rtsx_dev *dev)
/* Wait some time to let other threads exist */
wait_timeout(100);
- /* queuecommand won't accept any new commands and the control
+ /*
+ * queuecommand won't accept any new commands and the control
* thread won't execute a previously-queued command. If there
- * is such a command pending, complete it with an error. */
+ * is such a command pending, complete it with an error.
+ */
mutex_lock(&dev->dev_mutex);
if (chip->srb) {
chip->srb->result = DID_NO_CONNECT << 16;
@@ -702,8 +706,10 @@ static void release_everything(struct rtsx_dev *dev)
{
rtsx_release_resources(dev);
- /* Drop our reference to the host; the SCSI core will free it
- * when the refcount becomes 0. */
+ /*
+ * Drop our reference to the host; the SCSI core will free it
+ * when the refcount becomes 0.
+ */
scsi_host_put(rtsx_to_host(dev));
}
@@ -942,8 +948,10 @@ static int rtsx_probe(struct pci_dev *pci,
rtsx_init_chip(dev->chip);
- /* set the supported max_lun and max_id for the scsi host
- * NOTE: the minimal value of max_id is 1 */
+ /*
+ * set the supported max_lun and max_id for the scsi host
+ * NOTE: the minimal value of max_id is 1
+ */
host->max_id = 1;
host->max_lun = dev->chip->max_lun;
@@ -994,7 +1002,6 @@ errout:
return err;
}
-
static void rtsx_remove(struct pci_dev *pci)
{
struct rtsx_dev *dev = pci_get_drvdata(pci);
diff --git a/drivers/staging/rts5208/rtsx.h b/drivers/staging/rts5208/rtsx.h
index 1396263e13e6..e725b10ed087 100644
--- a/drivers/staging/rts5208/rtsx.h
+++ b/drivers/staging/rts5208/rtsx.h
@@ -70,14 +70,13 @@
#define rtsx_write_config_byte(chip, where, val) \
pci_write_config_byte((chip)->rtsx->pci, where, val)
-#define wait_timeout_x(task_state, msecs) \
-do { \
- set_current_state((task_state)); \
- schedule_timeout((msecs) * HZ / 1000); \
+#define wait_timeout_x(task_state, msecs) \
+do { \
+ set_current_state((task_state)); \
+ schedule_timeout((msecs) * HZ / 1000); \
} while (0)
#define wait_timeout(msecs) wait_timeout_x(TASK_INTERRUPTIBLE, (msecs))
-
#define STATE_TRANS_NONE 0
#define STATE_TRANS_CMD 1
#define STATE_TRANS_BUF 2
@@ -89,8 +88,6 @@ do { \
#define SCSI_LUN(srb) ((srb)->device->lun)
-typedef unsigned long DELAY_PARA_T;
-
struct rtsx_chip;
struct rtsx_dev {
@@ -131,16 +128,15 @@ struct rtsx_dev {
struct rtsx_chip *chip;
};
-typedef struct rtsx_dev rtsx_dev_t;
-
/* Convert between rtsx_dev and the corresponding Scsi_Host */
static inline struct Scsi_Host *rtsx_to_host(struct rtsx_dev *dev)
{
- return container_of((void *) dev, struct Scsi_Host, hostdata);
+ return container_of((void *)dev, struct Scsi_Host, hostdata);
}
+
static inline struct rtsx_dev *host_to_rtsx(struct Scsi_Host *host)
{
- return (struct rtsx_dev *) host->hostdata;
+ return (struct rtsx_dev *)host->hostdata;
}
static inline void get_current_time(u8 *timeval_buf, int buf_len)
@@ -165,8 +161,10 @@ static inline void get_current_time(u8 *timeval_buf, int buf_len)
timeval_buf[7] = (u8)(tv_usec);
}
-/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the
- * single queue element srb for write access */
+/*
+ * The scsi_lock() and scsi_unlock() macros protect the sm_state and the
+ * single queue element srb for write access
+ */
#define scsi_unlock(host) spin_unlock_irq(host->host_lock)
#define scsi_lock(host) spin_lock_irq(host->host_lock)
diff --git a/drivers/staging/rts5208/rtsx_card.c b/drivers/staging/rts5208/rtsx_card.c
index 231833a3045e..97717744962d 100644
--- a/drivers/staging/rts5208/rtsx_card.c
+++ b/drivers/staging/rts5208/rtsx_card.c
@@ -631,21 +631,21 @@ void rtsx_init_cards(struct rtsx_chip *chip)
int switch_ssc_clock(struct rtsx_chip *chip, int clk)
{
int retval;
- u8 N = (u8)(clk - 2), min_N, max_N;
+ u8 n = (u8)(clk - 2), min_n, max_n;
u8 mcu_cnt, div, max_div, ssc_depth, ssc_depth_mask;
int sd_vpclk_phase_reset = 0;
if (chip->cur_clk == clk)
return STATUS_SUCCESS;
- min_N = 60;
- max_N = 120;
+ min_n = 60;
+ max_n = 120;
max_div = CLK_DIV_4;
dev_dbg(rtsx_dev(chip), "Switch SSC clock to %dMHz (cur_clk = %d)\n",
clk, chip->cur_clk);
- if ((clk <= 2) || (N > max_N)) {
+ if ((clk <= 2) || (n > max_n)) {
rtsx_trace(chip);
return STATUS_FAIL;
}
@@ -655,15 +655,15 @@ int switch_ssc_clock(struct rtsx_chip *chip, int clk)
mcu_cnt = 7;
div = CLK_DIV_1;
- while ((N < min_N) && (div < max_div)) {
- N = (N + 2) * 2 - 2;
+ while ((n < min_n) && (div < max_div)) {
+ n = (n + 2) * 2 - 2;
div++;
}
- dev_dbg(rtsx_dev(chip), "N = %d, div = %d\n", N, div);
+ dev_dbg(rtsx_dev(chip), "n = %d, div = %d\n", n, div);
if (chip->ssc_en) {
ssc_depth = 0x01;
- N -= 2;
+ n -= 2;
} else {
ssc_depth = 0;
}
@@ -677,7 +677,7 @@ int switch_ssc_clock(struct rtsx_chip *chip, int clk)
rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0xFF, (div << 4) | mcu_cnt);
rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, ssc_depth_mask, ssc_depth);
- rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N);
+ rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, n);
rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB);
if (sd_vpclk_phase_reset) {
rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL,
@@ -1027,26 +1027,26 @@ int card_share_mode(struct rtsx_chip *chip, int card)
if (CHECK_PID(chip, 0x5208)) {
mask = CARD_SHARE_MASK;
- if (card == SD_CARD)
+ if (card == SD_CARD) {
value = CARD_SHARE_48_SD;
- else if (card == MS_CARD)
+ } else if (card == MS_CARD) {
value = CARD_SHARE_48_MS;
- else if (card == XD_CARD)
+ } else if (card == XD_CARD) {
value = CARD_SHARE_48_XD;
- else {
+ } else {
rtsx_trace(chip);
return STATUS_FAIL;
}
} else if (CHECK_PID(chip, 0x5288)) {
mask = 0x03;
- if (card == SD_CARD)
+ if (card == SD_CARD) {
value = CARD_SHARE_BAROSSA_SD;
- else if (card == MS_CARD)
+ } else if (card == MS_CARD) {
value = CARD_SHARE_BAROSSA_MS;
- else if (card == XD_CARD)
+ } else if (card == XD_CARD) {
value = CARD_SHARE_BAROSSA_XD;
- else {
+ } else {
rtsx_trace(chip);
return STATUS_FAIL;
}
@@ -1065,7 +1065,6 @@ int card_share_mode(struct rtsx_chip *chip, int card)
return STATUS_SUCCESS;
}
-
int select_card(struct rtsx_chip *chip, int card)
{
int retval;
@@ -1073,15 +1072,15 @@ int select_card(struct rtsx_chip *chip, int card)
if (chip->cur_card != card) {
u8 mod;
- if (card == SD_CARD)
+ if (card == SD_CARD) {
mod = SD_MOD_SEL;
- else if (card == MS_CARD)
+ } else if (card == MS_CARD) {
mod = MS_MOD_SEL;
- else if (card == XD_CARD)
+ } else if (card == XD_CARD) {
mod = XD_MOD_SEL;
- else if (card == SPI_CARD)
+ } else if (card == SPI_CARD) {
mod = SPI_MOD_SEL;
- else {
+ } else {
rtsx_trace(chip);
return STATUS_FAIL;
}
diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c
index bcc4b666d79f..a10dd6220a7b 100644
--- a/drivers/staging/rts5208/rtsx_chip.c
+++ b/drivers/staging/rts5208/rtsx_chip.c
@@ -743,7 +743,7 @@ static inline int check_sd_speed_prior(u32 sd_speed_prior)
int i;
for (i = 0; i < 4; i++) {
- u8 tmp = (u8)(sd_speed_prior >> (i*8));
+ u8 tmp = (u8)(sd_speed_prior >> (i * 8));
if ((tmp < 0x01) || (tmp > 0x04)) {
fake_para = true;
@@ -760,7 +760,7 @@ static inline int check_sd_current_prior(u32 sd_current_prior)
int i;
for (i = 0; i < 4; i++) {
- u8 tmp = (u8)(sd_current_prior >> (i*8));
+ u8 tmp = (u8)(sd_current_prior >> (i * 8));
if (tmp > 0x03) {
fake_para = true;
@@ -2288,7 +2288,7 @@ int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
ptr = buf;
reg_addr = PPBUF_BASE2;
- for (i = 0; i < buf_len/256; i++) {
+ for (i = 0; i < buf_len / 256; i++) {
rtsx_init_cmd(chip);
for (j = 0; j < 256; j++)
@@ -2304,10 +2304,10 @@ int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
ptr += 256;
}
- if (buf_len%256) {
+ if (buf_len % 256) {
rtsx_init_cmd(chip);
- for (j = 0; j < buf_len%256; j++)
+ for (j = 0; j < buf_len % 256; j++)
rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0);
retval = rtsx_send_cmd(chip, 0, 250);
@@ -2317,7 +2317,7 @@ int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
}
}
- memcpy(ptr, rtsx_get_cmd_data(chip), buf_len%256);
+ memcpy(ptr, rtsx_get_cmd_data(chip), buf_len % 256);
return STATUS_SUCCESS;
}
@@ -2336,7 +2336,7 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
ptr = buf;
reg_addr = PPBUF_BASE2;
- for (i = 0; i < buf_len/256; i++) {
+ for (i = 0; i < buf_len / 256; i++) {
rtsx_init_cmd(chip);
for (j = 0; j < 256; j++) {
@@ -2352,10 +2352,10 @@ int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len)
}
}
- if (buf_len%256) {
+ if (buf_len % 256) {
rtsx_init_cmd(chip);
- for (j = 0; j < buf_len%256; j++) {
+ for (j = 0; j < buf_len % 256; j++) {
rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF,
*ptr);
ptr++;
diff --git a/drivers/staging/rts5208/rtsx_chip.h b/drivers/staging/rts5208/rtsx_chip.h
index c08164f3247e..f36642817c6e 100644
--- a/drivers/staging/rts5208/rtsx_chip.h
+++ b/drivers/staging/rts5208/rtsx_chip.h
@@ -44,8 +44,10 @@
#define MG_SET_ICV_SLOW
/* HW may miss ERR/CMDNK signal when sampling INT status. */
#define MS_SAMPLE_INT_ERR
- /* HW DO NOT support Wait_INT function during READ_BYTES
- * transfer mode */
+ /*
+ * HW DO NOT support Wait_INT function
+ * during READ_BYTES transfer mode
+ */
#define READ_BYTES_WAIT_INT
#endif
@@ -101,18 +103,17 @@
#define TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */
#define TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */
-
-/*-----------------------------------
- Start-Stop-Unit
------------------------------------*/
+/*
+ * Start-Stop-Unit
+ */
#define STOP_MEDIUM 0x00 /* access disable */
#define MAKE_MEDIUM_READY 0x01 /* access enable */
#define UNLOAD_MEDIUM 0x02 /* unload */
#define LOAD_MEDIUM 0x03 /* load */
-/*-----------------------------------
- STANDARD_INQUIRY
------------------------------------*/
+/*
+ * STANDARD_INQUIRY
+ */
#define QULIFIRE 0x00
#define AENC_FNC 0x00
#define TRML_IOP 0x00
@@ -129,17 +130,15 @@
#define PRDCT_REV_LEN 4 /* Product LOT Length */
/* Dynamic flag definitions: used in set_bit() etc. */
-#define RTSX_FLIDX_TRANS_ACTIVE 18 /* 0x00040000 transfer is active */
-#define RTSX_FLIDX_ABORTING 20 /* 0x00100000 abort is in
- * progress */
-#define RTSX_FLIDX_DISCONNECTING 21 /* 0x00200000 disconnect
- * in progress */
+#define RTSX_FLIDX_TRANS_ACTIVE 18 /* 0x00040000 transfer is active */
+#define RTSX_FLIDX_ABORTING 20 /* 0x00100000 abort is in progress */
+#define RTSX_FLIDX_DISCONNECTING 21 /* 0x00200000 disconnect in progress */
+
#define ABORTING_OR_DISCONNECTING ((1UL << US_FLIDX_ABORTING) | \
(1UL << US_FLIDX_DISCONNECTING))
-#define RTSX_FLIDX_RESETTING 22 /* 0x00400000 device reset
- * in progress */
-#define RTSX_FLIDX_TIMED_OUT 23 /* 0x00800000 SCSI
- * midlayer timed out */
+
+#define RTSX_FLIDX_RESETTING 22 /* 0x00400000 device reset in progress */
+#define RTSX_FLIDX_TIMED_OUT 23 /* 0x00800000 SCSI midlayer timed out */
#define DRCT_ACCESS_DEV 0x00 /* Direct Access Device */
#define RMB_DISC 0x80 /* The Device is Removable */
@@ -174,9 +173,9 @@
#define FIRST_RESET 0x01
#define USED_EXIST 0x02
-/*-----------------------------------
- SENSE_DATA
------------------------------------*/
+/*
+ * SENSE_DATA
+ */
/*---- valid ----*/
#define SENSE_VALID 0x80 /* Sense data is valid as SCSI2 */
#define SENSE_INVALID 0x00 /* Sense data is invalid as SCSI2 */
@@ -228,7 +227,6 @@
#define ASCQ_LOAD_EJCT_ERR 0x00
#define ASCQ_WRITE_PROTECT 0x00
-
struct sense_data_t {
unsigned char err_code; /* error code */
/* bit7 : valid */
@@ -268,22 +266,22 @@ struct sense_data_t {
#define TRIG_DMA (0x01 << 31)
/* Bus interrupt pending register */
-#define CMD_DONE_INT (1 << 31)
-#define DATA_DONE_INT (1 << 30)
-#define TRANS_OK_INT (1 << 29)
-#define TRANS_FAIL_INT (1 << 28)
-#define XD_INT (1 << 27)
-#define MS_INT (1 << 26)
-#define SD_INT (1 << 25)
-#define GPIO0_INT (1 << 24)
-#define OC_INT (1 << 23)
-#define SD_WRITE_PROTECT (1 << 19)
-#define XD_EXIST (1 << 18)
-#define MS_EXIST (1 << 17)
-#define SD_EXIST (1 << 16)
+#define CMD_DONE_INT BIT(31)
+#define DATA_DONE_INT BIT(30)
+#define TRANS_OK_INT BIT(29)
+#define TRANS_FAIL_INT BIT(28)
+#define XD_INT BIT(27)
+#define MS_INT BIT(26)
+#define SD_INT BIT(25)
+#define GPIO0_INT BIT(24)
+#define OC_INT BIT(23)
+#define SD_WRITE_PROTECT BIT(19)
+#define XD_EXIST BIT(18)
+#define MS_EXIST BIT(17)
+#define SD_EXIST BIT(16)
#define DELINK_INT GPIO0_INT
-#define MS_OC_INT (1 << 23)
-#define SD_OC_INT (1 << 22)
+#define MS_OC_INT BIT(23)
+#define SD_OC_INT BIT(22)
#define CARD_INT (XD_INT | MS_INT | SD_INT)
#define NEED_COMPLETE_INT (DATA_DONE_INT | TRANS_OK_INT | TRANS_FAIL_INT)
@@ -305,7 +303,6 @@ struct sense_data_t {
#define MS_OC_INT_EN (1 << 23)
#define SD_OC_INT_EN (1 << 22)
-
#define READ_REG_CMD 0
#define WRITE_REG_CMD 1
#define CHECK_REG_CMD 2
@@ -313,7 +310,6 @@ struct sense_data_t {
#define HOST_TO_DEVICE 0
#define DEVICE_TO_HOST 1
-
#define RTSX_RESV_BUF_LEN 4096
#define HOST_CMDS_BUF_LEN 1024
#define HOST_SG_TBL_BUF_LEN (RTSX_RESV_BUF_LEN - HOST_CMDS_BUF_LEN)
@@ -332,7 +328,6 @@ struct sense_data_t {
#define XD_FREE_TABLE_CNT 1200
#define MS_FREE_TABLE_CNT 512
-
/* Bit Operation */
#define SET_BIT(data, idx) ((data) |= 1 << (idx))
#define CLR_BIT(data, idx) ((data) &= ~(1 << (idx)))
@@ -618,7 +613,6 @@ struct spi_info {
int spi_clock;
};
-
#ifdef _MSG_TRACE
struct trace_msg_t {
u16 line;
@@ -689,7 +683,7 @@ struct trace_msg_t {
#define CLR_SDIO_IGNORED(chip) ((chip)->sdio_func_exist &= ~SDIO_IGNORED)
struct rtsx_chip {
- rtsx_dev_t *rtsx;
+ struct rtsx_dev *rtsx;
u32 int_reg; /* Bus interrupt pending register */
char max_lun;
@@ -712,9 +706,9 @@ struct rtsx_chip {
int cur_card;
unsigned long need_release; /* need release bit map */
- unsigned long need_reset; /* need reset
- * bit map */
- /* Flag to indicate that this card is just resumed from SS state,
+ unsigned long need_reset; /* need reset bit map */
+ /*
+ * Flag to indicate that this card is just resumed from SS state,
* and need released before being resetted
*/
unsigned long need_reinit;
@@ -732,8 +726,10 @@ struct rtsx_chip {
u8 card_ejected; /* card ejected bit map */
u8 card_wp; /* card write protected bit map */
- u8 lun_mc; /* flag to indicate whether to answer
- * MediaChange */
+ u8 lun_mc; /*
+ * flag to indicate whether to answer
+ * MediaChange
+ */
#ifndef LED_AUTO_BLINK
int led_toggle_counter;
diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c
index d2031044ea34..becb4bba166c 100644
--- a/drivers/staging/rts5208/rtsx_scsi.c
+++ b/drivers/staging/rts5208/rtsx_scsi.c
@@ -484,14 +484,14 @@ static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip)
u8 card = get_lun_card(chip, lun);
bool pro_formatter_flag = false;
unsigned char inquiry_buf[] = {
- QULIFIRE|DRCT_ACCESS_DEV,
- RMB_DISC|0x0D,
+ QULIFIRE | DRCT_ACCESS_DEV,
+ RMB_DISC | 0x0D,
0x00,
0x01,
0x1f,
0x02,
0,
- REL_ADR|WBUS_32|WBUS_16|SYNC|LINKED|CMD_QUE|SFT_RE,
+ REL_ADR | WBUS_32 | WBUS_16 | SYNC | LINKED | CMD_QUE | SFT_RE,
};
if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
@@ -558,7 +558,6 @@ static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip)
return TRANSPORT_GOOD;
}
-
static int start_stop_unit(struct scsi_cmnd *srb, struct rtsx_chip *chip)
{
unsigned int lun = SCSI_LUN(srb);
@@ -594,7 +593,6 @@ static int start_stop_unit(struct scsi_cmnd *srb, struct rtsx_chip *chip)
return TRANSPORT_ERROR;
}
-
static int allow_medium_removal(struct scsi_cmnd *srb, struct rtsx_chip *chip)
{
int prevent;
@@ -613,7 +611,6 @@ static int allow_medium_removal(struct scsi_cmnd *srb, struct rtsx_chip *chip)
return TRANSPORT_GOOD;
}
-
static int request_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip)
{
struct sense_data_t *sense;
@@ -1400,7 +1397,7 @@ static int trace_msg_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
buf_len = 4 + ((2 + MSG_FUNC_LEN + MSG_FILE_LEN + TIME_VAL_LEN) *
TRACE_ITEM_CNT);
- if ((scsi_bufflen(srb) < buf_len) || (scsi_sglist(srb) == NULL)) {
+ if ((scsi_bufflen(srb) < buf_len) || !scsi_sglist(srb)) {
set_sense_type(chip, SCSI_LUN(srb),
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
rtsx_trace(chip);
@@ -1521,7 +1518,7 @@ static int write_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
static int set_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip)
{
- unsigned lun = SCSI_LUN(srb);
+ unsigned int lun = SCSI_LUN(srb);
if (srb->cmnd[3] == 1) {
/* Variable Clock */
@@ -1989,8 +1986,8 @@ static int read_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip)
return TRANSPORT_FAILED;
}
- buf[2*i] = (u8)(val >> 8);
- buf[2*i+1] = (u8)val;
+ buf[2 * i] = (u8)(val >> 8);
+ buf[2 * i + 1] = (u8)val;
}
len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb),
@@ -2048,7 +2045,7 @@ static int write_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip)
}
for (i = 0; i < len / 2; i++) {
- val = ((u16)buf[2*i] << 8) | buf[2*i+1];
+ val = ((u16)buf[2 * i] << 8) | buf[2 * i + 1];
retval = rtsx_write_phy_register(chip, addr + i, val);
if (retval != STATUS_SUCCESS) {
vfree(buf);
@@ -2604,7 +2601,6 @@ static int app_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
return result;
}
-
static int read_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
{
u8 rtsx_status[16];
@@ -3071,18 +3067,18 @@ static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip)
buf[i++] = 0x80;
if ((dev_info_id == 0x10) || (dev_info_id == 0x13)) {
/* System Information */
- memcpy(buf+i, ms_card->raw_sys_info, 96);
+ memcpy(buf + i, ms_card->raw_sys_info, 96);
} else {
/* Model Name */
- memcpy(buf+i, ms_card->raw_model_name, 48);
+ memcpy(buf + i, ms_card->raw_model_name, 48);
}
rtsx_stor_set_xfer_buf(buf, buf_len, srb);
if (dev_info_id == 0x15)
- scsi_set_resid(srb, scsi_bufflen(srb)-0x3C);
+ scsi_set_resid(srb, scsi_bufflen(srb) - 0x3C);
else
- scsi_set_resid(srb, scsi_bufflen(srb)-0x6C);
+ scsi_set_resid(srb, scsi_bufflen(srb) - 0x6C);
kfree(buf);
return STATUS_SUCCESS;
diff --git a/drivers/staging/rts5208/rtsx_sys.h b/drivers/staging/rts5208/rtsx_sys.h
index 0b6b4d4f1fea..f49bed9ec76a 100644
--- a/drivers/staging/rts5208/rtsx_sys.h
+++ b/drivers/staging/rts5208/rtsx_sys.h
@@ -28,8 +28,6 @@
#include "rtsx_chip.h"
#include "rtsx_card.h"
-typedef dma_addr_t ULONG_PTR;
-
static inline void rtsx_exclusive_enter_ss(struct rtsx_chip *chip)
{
struct rtsx_dev *dev = chip->rtsx;
diff --git a/drivers/staging/rts5208/rtsx_transport.h b/drivers/staging/rts5208/rtsx_transport.h
index 899bc2079dbe..479137398c3d 100644
--- a/drivers/staging/rts5208/rtsx_transport.h
+++ b/drivers/staging/rts5208/rtsx_transport.h
@@ -38,7 +38,6 @@ void rtsx_stor_get_xfer_buf(unsigned char *buffer,
unsigned int buflen, struct scsi_cmnd *srb);
void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-
#define rtsx_init_cmd(chip) ((chip)->ci = 0)
void rtsx_add_cmd(struct rtsx_chip *chip,
diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c
index 6219e047557e..b0bbb36f8988 100644
--- a/drivers/staging/rts5208/sd.c
+++ b/drivers/staging/rts5208/sd.c
@@ -1428,7 +1428,6 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width)
continue;
}
-
if (func_to_switch)
break;
@@ -1437,9 +1436,9 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width)
func_to_switch);
#ifdef SUPPORT_SD_LOCK
- if ((sd_card->sd_lock_status & SD_SDR_RST)
- && (DDR50_SUPPORT == func_to_switch)
- && (sd_card->func_group1_mask & SDR50_SUPPORT_MASK)) {
+ if ((sd_card->sd_lock_status & SD_SDR_RST) &&
+ (func_to_switch == DDR50_SUPPORT) &&
+ (sd_card->func_group1_mask & SDR50_SUPPORT_MASK)) {
func_to_switch = SDR50_SUPPORT;
dev_dbg(rtsx_dev(chip), "Using SDR50 instead of DDR50 for SD Lock\n");
}
@@ -2589,16 +2588,12 @@ Switch_Fail:
#endif
retval = sd_prepare_reset(chip);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
retval = sd_dummy_clock(chip);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && try_sdio) {
int rty_cnt = 0;
@@ -2606,8 +2601,7 @@ Switch_Fail:
for (; rty_cnt < chip->sdio_retry_cnt; rty_cnt++) {
if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
sd_set_err_code(chip, SD_NO_CARD);
- rtsx_trace(chip);
- return STATUS_FAIL;
+ goto Status_Fail;
}
retval = sd_send_cmd_get_rsp(chip, IO_SEND_OP_COND, 0,
@@ -2619,8 +2613,7 @@ Switch_Fail:
dev_dbg(rtsx_dev(chip), "SD_IO card (Function number: %d)!\n",
func_num);
chip->sd_io = 1;
- rtsx_trace(chip);
- return STATUS_FAIL;
+ goto Status_Fail;
}
break;
@@ -2638,10 +2631,8 @@ Switch_Fail:
RTY_SD_RST:
retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0,
NULL, 0);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
wait_timeout(20);
@@ -2659,10 +2650,8 @@ RTY_SD_RST:
retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0,
SD_RSP_TYPE_R0, NULL, 0);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
wait_timeout(20);
}
@@ -2673,39 +2662,32 @@ RTY_SD_RST:
if (retval != STATUS_SUCCESS) {
if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
sd_set_err_code(chip, SD_NO_CARD);
- rtsx_trace(chip);
- return STATUS_FAIL;
+ goto Status_Fail;
}
j++;
- if (j < 3) {
+ if (j < 3)
goto RTY_SD_RST;
- } else {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ else
+ goto Status_Fail;
}
retval = sd_send_cmd_get_rsp(chip, SD_APP_OP_COND, voltage,
SD_RSP_TYPE_R3, rsp, 5);
if (retval != STATUS_SUCCESS) {
k++;
- if (k < 3) {
+ if (k < 3)
goto RTY_SD_RST;
- } else {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ else
+ goto Status_Fail;
}
i++;
wait_timeout(20);
} while (!(rsp[1] & 0x80) && (i < 255));
- if (i == 255) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (i == 255)
+ goto Status_Fail;
if (hi_cap_flow) {
if (rsp[1] & 0x40)
@@ -2722,26 +2704,20 @@ RTY_SD_RST:
if (support_1v8) {
retval = sd_voltage_switch(chip);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
}
retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2,
NULL, 0);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
for (i = 0; i < 3; i++) {
retval = sd_send_cmd_get_rsp(chip, SEND_RELATIVE_ADDR, 0,
SD_RSP_TYPE_R6, rsp, 5);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
sd_card->sd_addr = (u32)rsp[1] << 24;
sd_card->sd_addr += (u32)rsp[2] << 16;
@@ -2751,24 +2727,18 @@ RTY_SD_RST:
}
retval = sd_check_csd(chip, 1);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
retval = sd_select_card(chip, 1);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
#ifdef SUPPORT_SD_LOCK
SD_UNLOCK_ENTRY:
retval = sd_update_lock_status(chip);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
if (sd_card->sd_lock_status & SD_LOCKED) {
sd_card->sd_lock_status |= (SD_LOCK_1BIT_MODE | SD_PWD_EXIST);
@@ -2780,32 +2750,24 @@ SD_UNLOCK_ENTRY:
retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
retval = sd_send_cmd_get_rsp(chip, SET_CLR_CARD_DETECT, 0,
SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
if (support_1v8) {
retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2,
SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
switch_bus_width = SD_BUS_WIDTH_4;
} else {
@@ -2814,16 +2776,12 @@ SD_UNLOCK_ENTRY:
retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1,
NULL, 0);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
if (!(sd_card->raw_csd[4] & 0x40))
sd_dont_switch = true;
@@ -2862,17 +2820,13 @@ SD_UNLOCK_ENTRY:
if (!support_1v8) {
retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2,
SD_RSP_TYPE_R1, NULL, 0);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
}
#ifdef SUPPORT_SD_LOCK
@@ -2890,10 +2844,8 @@ SD_UNLOCK_ENTRY:
}
retval = sd_set_init_para(chip);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
if (CHK_SD_DDR50(sd_card))
retval = sd_ddr_tuning(chip);
@@ -2902,14 +2854,11 @@ SD_UNLOCK_ENTRY:
if (retval != STATUS_SUCCESS) {
if (sd20_mode) {
- rtsx_trace(chip);
- return STATUS_FAIL;
+ goto Status_Fail;
} else {
retval = sd_init_power(chip);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
try_sdio = false;
sd20_mode = true;
@@ -2930,14 +2879,11 @@ SD_UNLOCK_ENTRY:
retval = sd_read_lba0(chip);
if (retval != STATUS_SUCCESS) {
if (sd20_mode) {
- rtsx_trace(chip);
- return STATUS_FAIL;
+ goto Status_Fail;
} else {
retval = sd_init_power(chip);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
try_sdio = false;
sd20_mode = true;
@@ -2948,10 +2894,8 @@ SD_UNLOCK_ENTRY:
}
retval = sd_check_wp_state(chip);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
chip->card_bus_width[chip->card2lun[SD_CARD]] = 4;
@@ -2973,8 +2917,11 @@ SD_UNLOCK_ENTRY:
#endif
return STATUS_SUCCESS;
-}
+Status_Fail:
+ rtsx_trace(chip);
+ return STATUS_FAIL;
+}
static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width)
{
@@ -3105,7 +3052,6 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width)
return SWITCH_FAIL;
}
-
static int mmc_switch_timing_bus(struct rtsx_chip *chip, bool switch_ddr)
{
struct sd_info *sd_card = &(chip->sd_card);
@@ -3230,7 +3176,6 @@ static int mmc_switch_timing_bus(struct rtsx_chip *chip, bool switch_ddr)
return STATUS_SUCCESS;
}
-
static int reset_mmc(struct rtsx_chip *chip)
{
struct sd_info *sd_card = &(chip->sd_card);
diff --git a/drivers/staging/rts5208/spi.c b/drivers/staging/rts5208/spi.c
index 26eb2a184f91..13c539c83838 100644
--- a/drivers/staging/rts5208/spi.c
+++ b/drivers/staging/rts5208/spi.c
@@ -39,7 +39,8 @@ static int spi_init(struct rtsx_chip *chip)
int retval;
retval = rtsx_write_register(chip, SPI_CONTROL, 0xFF,
- CS_POLARITY_LOW | DTO_MSB_FIRST | SPI_MASTER | SPI_MODE0 | SPI_AUTO);
+ CS_POLARITY_LOW | DTO_MSB_FIRST
+ | SPI_MASTER | SPI_MODE0 | SPI_AUTO);
if (retval) {
rtsx_trace(chip);
return retval;
diff --git a/drivers/staging/rts5208/spi.h b/drivers/staging/rts5208/spi.h
index fc824b5d8d59..c8d2beacd9e5 100644
--- a/drivers/staging/rts5208/spi.h
+++ b/drivers/staging/rts5208/spi.h
@@ -61,5 +61,4 @@ int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip);
int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip);
int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip);
-
#endif /* __REALTEK_RTSX_SPI_H */
diff --git a/drivers/staging/rts5208/xd.c b/drivers/staging/rts5208/xd.c
index fc1dfe0991d4..1de02bb98839 100644
--- a/drivers/staging/rts5208/xd.c
+++ b/drivers/staging/rts5208/xd.c
@@ -834,7 +834,6 @@ static int xd_check_data_blank(u8 *redunt)
!= (XD_ECC1_ALL1 | XD_ECC2_ALL1))
return 0;
-
for (i = 0; i < 4; i++) {
if (redunt[RESERVED0 + i] != 0xFF)
return 0;
@@ -938,7 +937,7 @@ static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk)
dev_dbg(rtsx_dev(chip), "Set unused block to index %d\n",
zone->set_index);
- zone->free_table[zone->set_index++] = (u16) (phy_blk & 0x3ff);
+ zone->free_table[zone->set_index++] = (u16)(phy_blk & 0x3ff);
if (zone->set_index >= XD_FREE_TABLE_CNT)
zone->set_index = 0;
zone->unused_blk_cnt++;
@@ -1402,7 +1401,6 @@ static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk)
return STATUS_FAIL;
}
-
static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no)
{
struct xd_info *xd_card = &(chip->xd_card);
@@ -1624,10 +1622,8 @@ static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk,
u8 reg_val, page_cnt;
int zone_no, retval, i;
- if (start_page > end_page) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (start_page > end_page)
+ goto Status_Fail;
page_cnt = end_page - start_page;
zone_no = (int)(log_blk / 1000);
@@ -1643,8 +1639,7 @@ static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk,
if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
xd_set_err_code(chip, XD_NO_CARD);
- rtsx_trace(chip);
- return STATUS_FAIL;
+ goto Status_Fail;
}
}
}
@@ -1679,8 +1674,7 @@ static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk,
if (retval == -ETIMEDOUT) {
xd_set_err_code(chip, XD_TO_ERROR);
- rtsx_trace(chip);
- return STATUS_FAIL;
+ goto Status_Fail;
} else {
rtsx_trace(chip);
goto Fail;
@@ -1713,8 +1707,7 @@ Fail:
if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
xd_set_err_code(chip, XD_NO_CARD);
- rtsx_trace(chip);
- return STATUS_FAIL;
+ goto Status_Fail;
}
xd_set_err_code(chip, XD_ECC_ERROR);
@@ -1722,8 +1715,7 @@ Fail:
new_blk = xd_get_unused_block(chip, zone_no);
if (new_blk == NO_NEW_BLK) {
XD_CLR_BAD_OLDBLK(xd_card);
- rtsx_trace(chip);
- return STATUS_FAIL;
+ goto Status_Fail;
}
retval = xd_copy_page(chip, phy_blk, new_blk, 0,
@@ -1737,8 +1729,7 @@ Fail:
XD_CLR_BAD_NEWBLK(xd_card);
}
XD_CLR_BAD_OLDBLK(xd_card);
- rtsx_trace(chip);
- return STATUS_FAIL;
+ goto Status_Fail;
}
xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF));
xd_erase_block(chip, phy_blk);
@@ -1746,6 +1737,7 @@ Fail:
XD_CLR_BAD_OLDBLK(xd_card);
}
+Status_Fail:
rtsx_trace(chip);
return STATUS_FAIL;
}
@@ -1830,7 +1822,6 @@ static int xd_prepare_write(struct rtsx_chip *chip,
return STATUS_SUCCESS;
}
-
static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk,
u32 new_blk, u32 log_blk, u8 start_page,
u8 end_page, u8 *buf, unsigned int *index,
@@ -1845,10 +1836,8 @@ static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk,
dev_dbg(rtsx_dev(chip), "%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n",
__func__, old_blk, new_blk, log_blk);
- if (start_page > end_page) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (start_page > end_page)
+ goto Status_Fail;
page_cnt = end_page - start_page;
zone_no = (int)(log_blk / 1000);
@@ -1857,10 +1846,8 @@ static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk,
page_addr = (new_blk << xd_card->block_shift) + start_page;
retval = xd_send_cmd(chip, READ1_1);
- if (retval != STATUS_SUCCESS) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
+ if (retval != STATUS_SUCCESS)
+ goto Status_Fail;
rtsx_init_cmd(chip);
@@ -1895,8 +1882,7 @@ static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk,
if (retval == -ETIMEDOUT) {
xd_set_err_code(chip, XD_TO_ERROR);
- rtsx_trace(chip);
- return STATUS_FAIL;
+ goto Status_Fail;
} else {
rtsx_trace(chip);
goto Fail;
@@ -1936,6 +1922,7 @@ Fail:
xd_mark_bad_block(chip, new_blk);
}
+Status_Fail:
rtsx_trace(chip);
return STATUS_FAIL;
}
@@ -2000,7 +1987,6 @@ int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
return STATUS_FAIL;
}
-
if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
chip->card_fail |= XD_CARD;
set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT);
diff --git a/drivers/staging/slicoss/slic.h b/drivers/staging/slicoss/slic.h
index cc0afeeb68c1..420546d43002 100644
--- a/drivers/staging/slicoss/slic.h
+++ b/drivers/staging/slicoss/slic.h
@@ -92,6 +92,7 @@ struct slic_rcvbuf_info {
u32 lasttime;
u32 lastid;
};
+
/*
* SLIC Handle structure. Used to restrict handle values to
* 32 bits by using an index rather than an address.
@@ -223,8 +224,8 @@ struct mcast_address {
struct slic_iface_stats {
/*
- * Stats
- */
+ * Stats
+ */
u64 xmt_bytes;
u64 xmt_ucast;
u64 xmt_mcast;
@@ -351,10 +352,35 @@ struct base_driver {
uint cardnuminuse[SLIC_MAX_CARDS];
};
-struct slic_shmem {
- volatile u32 isr;
- volatile u32 linkstatus;
- volatile struct slic_stats inicstats;
+struct slic_stats {
+ /* xmit stats */
+ u64 xmit_tcp_bytes;
+ u64 xmit_tcp_segs;
+ u64 xmit_bytes;
+ u64 xmit_collisions;
+ u64 xmit_unicasts;
+ u64 xmit_other_error;
+ u64 xmit_excess_collisions;
+ /* rcv stats */
+ u64 rcv_tcp_bytes;
+ u64 rcv_tcp_segs;
+ u64 rcv_bytes;
+ u64 rcv_unicasts;
+ u64 rcv_other_error;
+ u64 rcv_drops;
+};
+
+struct slic_shmem_data {
+ u32 isr;
+ u32 lnkstatus;
+ struct slic_stats stats;
+};
+
+struct slic_shmemory {
+ dma_addr_t isr_phaddr;
+ dma_addr_t lnkstatus_phaddr;
+ dma_addr_t stats_phaddr;
+ struct slic_shmem_data __iomem *shmem_data;
};
struct slic_upr {
@@ -414,10 +440,9 @@ struct adapter {
u32 intrregistered;
uint isp_initialized;
uint gennumber;
- struct slic_shmem *pshmem;
+ struct slic_shmemory shmem;
dma_addr_t phys_shmem;
- u32 isrcopy;
- __iomem struct slic_regs *slic_regs;
+ void __iomem *regs;
unsigned char state;
unsigned char linkstate;
unsigned char linkspeed;
@@ -444,8 +469,8 @@ struct adapter {
struct slic_cmdqueue cmdq_all;
struct slic_cmdqmem cmdqmem;
/*
- * SLIC Handles
- */
+ * SLIC Handles
+ */
/* Object handles*/
struct slic_handle slic_handles[SLIC_CMDQ_MAXCMDS + 1];
/* Free object handles*/
@@ -487,6 +512,34 @@ struct adapter {
struct slicnet_stats slic_stats;
};
+static inline u32 slic_read32(struct adapter *adapter, unsigned int reg)
+{
+ return ioread32(adapter->regs + reg);
+}
+
+static inline void slic_write32(struct adapter *adapter, unsigned int reg,
+ u32 val)
+{
+ iowrite32(val, adapter->regs + reg);
+}
+
+static inline void slic_write64(struct adapter *adapter, unsigned int reg,
+ u32 val, u32 hiaddr)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->bit64reglock, flags);
+ slic_write32(adapter, SLIC_REG_ADDR_UPPER, hiaddr);
+ slic_write32(adapter, reg, val);
+ mmiowb();
+ spin_unlock_irqrestore(&adapter->bit64reglock, flags);
+}
+
+static inline void slic_flush_write(struct adapter *adapter)
+{
+ ioread32(adapter->regs + SLIC_REG_HOSTID);
+}
+
#define UPDATE_STATS(largestat, newstat, oldstat) \
{ \
if ((newstat) < (oldstat)) \
diff --git a/drivers/staging/slicoss/slichw.h b/drivers/staging/slicoss/slichw.h
index 9723b4a104f7..49cb91aa02bb 100644
--- a/drivers/staging/slicoss/slichw.h
+++ b/drivers/staging/slicoss/slichw.h
@@ -289,224 +289,118 @@ struct slic_rspbuf {
u32 pad2[4];
};
-struct slic_regs {
- u32 slic_reset; /* Reset Register */
- u32 pad0;
-
- u32 slic_icr; /* Interrupt Control Register */
- u32 pad2;
-#define SLIC_ICR 0x0008
-
- u32 slic_isp; /* Interrupt status pointer */
- u32 pad1;
-#define SLIC_ISP 0x0010
-
- u32 slic_isr; /* Interrupt status */
- u32 pad3;
-#define SLIC_ISR 0x0018
-
- u32 slic_hbar; /* Header buffer address reg */
- u32 pad4;
- /*
- * 31-8 - phy addr of set of contiguous hdr buffers
- * 7-0 - number of buffers passed
- * Buffers are 256 bytes long on 256-byte boundaries.
- */
-#define SLIC_HBAR 0x0020
-#define SLIC_HBAR_CNT_MSK 0x000000FF
-
- u32 slic_dbar; /* Data buffer handle & address reg */
- u32 pad5;
-
- /* 4 sets of registers; Buffers are 2K bytes long 2 per 4K page. */
-#define SLIC_DBAR 0x0028
-#define SLIC_DBAR_SIZE 2048
-
- u32 slic_cbar; /* Xmt Cmd buf addr regs.*/
- /*
- * 1 per XMT interface
- * 31-5 - phy addr of host command buffer
- * 4-0 - length of cmd in multiples of 32 bytes
- * Buffers are 32 bytes up to 512 bytes long
- */
-#define SLIC_CBAR 0x0030
-#define SLIC_CBAR_LEN_MSK 0x0000001F
-#define SLIC_CBAR_ALIGN 0x00000020
-
- u32 slic_wcs; /* write control store*/
-#define SLIC_WCS 0x0034
-#define SLIC_WCS_START 0x80000000 /*Start the SLIC (Jump to WCS)*/
-#define SLIC_WCS_COMPARE 0x40000000 /* Compare with value in WCS*/
-
- u32 slic_rbar; /* Response buffer address reg.*/
- u32 pad7;
- /*
- * 31-8 - phy addr of set of contiguous response buffers
- * 7-0 - number of buffers passed
- * Buffers are 32 bytes long on 32-byte boundaries.
- */
-#define SLIC_RBAR 0x0038
-#define SLIC_RBAR_CNT_MSK 0x000000FF
-#define SLIC_RBAR_SIZE 32
-
- u32 slic_stats; /* read statistics (UPR) */
- u32 pad8;
-#define SLIC_RSTAT 0x0040
-
- u32 slic_rlsr; /* read link status */
- u32 pad9;
-#define SLIC_LSTAT 0x0048
-
- u32 slic_wmcfg; /* Write Mac Config */
- u32 pad10;
-#define SLIC_WMCFG 0x0050
-
- u32 slic_wphy; /* Write phy register */
- u32 pad11;
-#define SLIC_WPHY 0x0058
-
- u32 slic_rcbar; /* Rcv Cmd buf addr reg */
- u32 pad12;
-#define SLIC_RCBAR 0x0060
-
- u32 slic_rconfig; /* Read SLIC Config*/
- u32 pad13;
-#define SLIC_RCONFIG 0x0068
-
- u32 slic_intagg; /* Interrupt aggregation time */
- u32 pad14;
-#define SLIC_INTAGG 0x0070
-
- u32 slic_wxcfg; /* Write XMIT config reg*/
- u32 pad16;
-#define SLIC_WXCFG 0x0078
-
- u32 slic_wrcfg; /* Write RCV config reg*/
- u32 pad17;
-#define SLIC_WRCFG 0x0080
-
- u32 slic_wraddral; /* Write rcv addr a low*/
- u32 pad18;
-#define SLIC_WRADDRAL 0x0088
-
- u32 slic_wraddrah; /* Write rcv addr a high*/
- u32 pad19;
-#define SLIC_WRADDRAH 0x0090
-
- u32 slic_wraddrbl; /* Write rcv addr b low*/
- u32 pad20;
-#define SLIC_WRADDRBL 0x0098
-
- u32 slic_wraddrbh; /* Write rcv addr b high*/
- u32 pad21;
-#define SLIC_WRADDRBH 0x00a0
-
- u32 slic_mcastlow; /* Low bits of mcast mask*/
- u32 pad22;
-#define SLIC_MCASTLOW 0x00a8
-
- u32 slic_mcasthigh; /* High bits of mcast mask*/
- u32 pad23;
-#define SLIC_MCASTHIGH 0x00b0
-
- u32 slic_ping; /* Ping the card*/
- u32 pad24;
-#define SLIC_PING 0x00b8
-
- u32 slic_dump_cmd; /* Dump command */
- u32 pad25;
-#define SLIC_DUMP_CMD 0x00c0
-
- u32 slic_dump_data; /* Dump data pointer */
- u32 pad26;
-#define SLIC_DUMP_DATA 0x00c8
-
- u32 slic_pcistatus; /* Read card's pci_status register */
- u32 pad27;
-#define SLIC_PCISTATUS 0x00d0
-
- u32 slic_wrhostid; /* Write hostid field */
- u32 pad28;
-#define SLIC_WRHOSTID 0x00d8
-#define SLIC_RDHOSTID_1GB 0x1554
-#define SLIC_RDHOSTID_2GB 0x1554
-
- u32 slic_low_power; /* Put card in a low power state */
- u32 pad29;
-#define SLIC_LOW_POWER 0x00e0
-
- u32 slic_quiesce; /* force slic into quiescent state
- * before soft reset
- */
- u32 pad30;
-#define SLIC_QUIESCE 0x00e8
-
- u32 slic_reset_iface;/* reset interface queues */
- u32 pad31;
-#define SLIC_RESET_IFACE 0x00f0
-
- u32 slic_addr_upper;/* Bits 63-32 for host i/f addrs */
- u32 pad32;
-#define SLIC_ADDR_UPPER 0x00f8 /*Register is only written when it has changed*/
-
- u32 slic_hbar64; /* 64 bit Header buffer address reg */
- u32 pad33;
-#define SLIC_HBAR64 0x0100
-
- u32 slic_dbar64; /* 64 bit Data buffer handle & address reg */
- u32 pad34;
-#define SLIC_DBAR64 0x0108
-
- u32 slic_cbar64; /* 64 bit Xmt Cmd buf addr regs. */
- u32 pad35;
-#define SLIC_CBAR64 0x0110
-
- u32 slic_rbar64; /* 64 bit Response buffer address reg.*/
- u32 pad36;
-#define SLIC_RBAR64 0x0118
-
- u32 slic_rcbar64; /* 64 bit Rcv Cmd buf addr reg*/
- u32 pad37;
-#define SLIC_RCBAR64 0x0120
-
- u32 slic_stats64; /* read statistics (64 bit UPR) */
- u32 pad38;
-#define SLIC_RSTAT64 0x0128
-
- u32 slic_rcv_wcs; /*Download Gigabit RCV sequencer ucode*/
- u32 pad39;
-#define SLIC_RCV_WCS 0x0130
-#define SLIC_RCVWCS_BEGIN 0x40000000
-#define SLIC_RCVWCS_FINISH 0x80000000
-
- u32 slic_wrvlanid; /* Write VlanId field */
- u32 pad40;
-#define SLIC_WRVLANID 0x0138
-
- u32 slic_read_xf_info; /* Read Transformer info */
- u32 pad41;
-#define SLIC_READ_XF_INFO 0x0140
-
- u32 slic_write_xf_info; /* Write Transformer info */
- u32 pad42;
-#define SLIC_WRITE_XF_INFO 0x0148
-
- u32 RSVD1; /* TOE Only */
- u32 pad43;
-
- u32 RSVD2; /* TOE Only */
- u32 pad44;
-
- u32 RSVD3; /* TOE Only */
- u32 pad45;
-
- u32 RSVD4; /* TOE Only */
- u32 pad46;
-
- u32 slic_ticks_per_sec; /* Write card ticks per second */
- u32 pad47;
-#define SLIC_TICKS_PER_SEC 0x0170
-};
+/* Reset Register */
+#define SLIC_REG_RESET 0x0000
+/* Interrupt Control Register */
+#define SLIC_REG_ICR 0x0008
+/* Interrupt status pointer */
+#define SLIC_REG_ISP 0x0010
+/* Interrupt status */
+#define SLIC_REG_ISR 0x0018
+/*
+ * Header buffer address reg
+ * 31-8 - phy addr of set of contiguous hdr buffers
+ * 7-0 - number of buffers passed
+ * Buffers are 256 bytes long on 256-byte boundaries.
+ */
+#define SLIC_REG_HBAR 0x0020
+/*
+ * Data buffer handle & address reg
+ * 4 sets of registers; Buffers are 2K bytes long 2 per 4K page.
+ */
+#define SLIC_REG_DBAR 0x0028
+/*
+ * Xmt Cmd buf addr regs.
+ * 1 per XMT interface
+ * 31-5 - phy addr of host command buffer
+ * 4-0 - length of cmd in multiples of 32 bytes
+ * Buffers are 32 bytes up to 512 bytes long
+ */
+#define SLIC_REG_CBAR 0x0030
+/* Write control store */
+#define SLIC_REG_WCS 0x0034
+/*
+ * Response buffer address reg.
+ * 31-8 - phy addr of set of contiguous response buffers
+ * 7-0 - number of buffers passed
+ * Buffers are 32 bytes long on 32-byte boundaries.
+ */
+#define SLIC_REG_RBAR 0x0038
+/* Read statistics (UPR) */
+#define SLIC_REG_RSTAT 0x0040
+/* Read link status */
+#define SLIC_REG_LSTAT 0x0048
+/* Write Mac Config */
+#define SLIC_REG_WMCFG 0x0050
+/* Write phy register */
+#define SLIC_REG_WPHY 0x0058
+/* Rcv Cmd buf addr reg */
+#define SLIC_REG_RCBAR 0x0060
+/* Read SLIC Config*/
+#define SLIC_REG_RCONFIG 0x0068
+/* Interrupt aggregation time */
+#define SLIC_REG_INTAGG 0x0070
+/* Write XMIT config reg */
+#define SLIC_REG_WXCFG 0x0078
+/* Write RCV config reg */
+#define SLIC_REG_WRCFG 0x0080
+/* Write rcv addr a low */
+#define SLIC_REG_WRADDRAL 0x0088
+/* Write rcv addr a high */
+#define SLIC_REG_WRADDRAH 0x0090
+/* Write rcv addr b low */
+#define SLIC_REG_WRADDRBL 0x0098
+/* Write rcv addr b high */
+#define SLIC_REG_WRADDRBH 0x00a0
+/* Low bits of mcast mask */
+#define SLIC_REG_MCASTLOW 0x00a8
+/* High bits of mcast mask */
+#define SLIC_REG_MCASTHIGH 0x00b0
+/* Ping the card */
+#define SLIC_REG_PING 0x00b8
+/* Dump command */
+#define SLIC_REG_DUMP_CMD 0x00c0
+/* Dump data pointer */
+#define SLIC_REG_DUMP_DATA 0x00c8
+/* Read card's pci_status register */
+#define SLIC_REG_PCISTATUS 0x00d0
+/* Write hostid field */
+#define SLIC_REG_WRHOSTID 0x00d8
+/* Put card in a low power state */
+#define SLIC_REG_LOW_POWER 0x00e0
+/* Force slic into quiescent state before soft reset */
+#define SLIC_REG_QUIESCE 0x00e8
+/* Reset interface queues */
+#define SLIC_REG_RESET_IFACE 0x00f0
+/*
+ * Register is only written when it has changed.
+ * Bits 63-32 for host i/f addrs.
+ */
+#define SLIC_REG_ADDR_UPPER 0x00f8
+/* 64 bit Header buffer address reg */
+#define SLIC_REG_HBAR64 0x0100
+/* 64 bit Data buffer handle & address reg */
+#define SLIC_REG_DBAR64 0x0108
+/* 64 bit Xmt Cmd buf addr regs. */
+#define SLIC_REG_CBAR64 0x0110
+/* 64 bit Response buffer address reg.*/
+#define SLIC_REG_RBAR64 0x0118
+/* 64 bit Rcv Cmd buf addr reg*/
+#define SLIC_REG_RCBAR64 0x0120
+/* Read statistics (64 bit UPR) */
+#define SLIC_REG_RSTAT64 0x0128
+/* Download Gigabit RCV sequencer ucode */
+#define SLIC_REG_RCV_WCS 0x0130
+/* Write VlanId field */
+#define SLIC_REG_WRVLANID 0x0138
+/* Read Transformer info */
+#define SLIC_REG_READ_XF_INFO 0x0140
+/* Write Transformer info */
+#define SLIC_REG_WRITE_XF_INFO 0x0148
+/* Write card ticks per second */
+#define SLIC_REG_TICKS_PER_SEC 0x0170
+
+#define SLIC_REG_HOSTID 0x1554
enum UPR_REQUEST {
SLIC_UPR_STATS,
@@ -565,85 +459,6 @@ struct slic_pnp_capabilities {
struct slicpm_wakeup_capabilities wakeup_capabilities;
};
-struct xmt_stats {
- u32 xmit_tcp_bytes;
- u32 xmit_tcp_segs;
- u32 xmit_bytes;
- u32 xmit_collisions;
- u32 xmit_unicasts;
- u32 xmit_other_error;
- u32 xmit_excess_collisions;
-};
-
-struct rcv_stats {
- u32 rcv_tcp_bytes;
- u32 rcv_tcp_segs;
- u32 rcv_bytes;
- u32 rcv_unicasts;
- u32 rcv_other_error;
- u32 rcv_drops;
-};
-
-struct xmt_statsgb {
- u64 xmit_tcp_bytes;
- u64 xmit_tcp_segs;
- u64 xmit_bytes;
- u64 xmit_collisions;
- u64 xmit_unicasts;
- u64 xmit_other_error;
- u64 xmit_excess_collisions;
-};
-
-struct rcv_statsgb {
- u64 rcv_tcp_bytes;
- u64 rcv_tcp_segs;
- u64 rcv_bytes;
- u64 rcv_unicasts;
- u64 rcv_other_error;
- u64 rcv_drops;
-};
-
-struct slic_stats {
- union {
- struct {
- struct xmt_stats xmt100;
- struct rcv_stats rcv100;
- } stats_100;
- struct {
- struct xmt_statsgb xmtGB;
- struct rcv_statsgb rcvGB;
- } stats_GB;
- } u;
-};
-
-#define xmit_tcp_segs100 u.stats_100.xmt100.xmit_tcp_segs
-#define xmit_tcp_bytes100 u.stats_100.xmt100.xmit_tcp_bytes
-#define xmit_bytes100 u.stats_100.xmt100.xmit_bytes
-#define xmit_collisions100 u.stats_100.xmt100.xmit_collisions
-#define xmit_unicasts100 u.stats_100.xmt100.xmit_unicasts
-#define xmit_other_error100 u.stats_100.xmt100.xmit_other_error
-#define xmit_excess_collisions100 u.stats_100.xmt100.xmit_excess_collisions
-#define rcv_tcp_segs100 u.stats_100.rcv100.rcv_tcp_segs
-#define rcv_tcp_bytes100 u.stats_100.rcv100.rcv_tcp_bytes
-#define rcv_bytes100 u.stats_100.rcv100.rcv_bytes
-#define rcv_unicasts100 u.stats_100.rcv100.rcv_unicasts
-#define rcv_other_error100 u.stats_100.rcv100.rcv_other_error
-#define rcv_drops100 u.stats_100.rcv100.rcv_drops
-#define xmit_tcp_segs_gb u.stats_GB.xmtGB.xmit_tcp_segs
-#define xmit_tcp_bytes_gb u.stats_GB.xmtGB.xmit_tcp_bytes
-#define xmit_bytes_gb u.stats_GB.xmtGB.xmit_bytes
-#define xmit_collisions_gb u.stats_GB.xmtGB.xmit_collisions
-#define xmit_unicasts_gb u.stats_GB.xmtGB.xmit_unicasts
-#define xmit_other_error_gb u.stats_GB.xmtGB.xmit_other_error
-#define xmit_excess_collisions_gb u.stats_GB.xmtGB.xmit_excess_collisions
-
-#define rcv_tcp_segs_gb u.stats_GB.rcvGB.rcv_tcp_segs
-#define rcv_tcp_bytes_gb u.stats_GB.rcvGB.rcv_tcp_bytes
-#define rcv_bytes_gb u.stats_GB.rcvGB.rcv_bytes
-#define rcv_unicasts_gb u.stats_GB.rcvGB.rcv_unicasts
-#define rcv_other_error_gb u.stats_GB.rcvGB.rcv_other_error
-#define rcv_drops_gb u.stats_GB.rcvGB.rcv_drops
-
struct slic_config_mac {
u8 macaddrA[6];
};
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c
index ac126d4f3117..062307ad7fed 100644
--- a/drivers/staging/slicoss/slicoss.c
+++ b/drivers/staging/slicoss/slicoss.c
@@ -124,31 +124,10 @@ static const struct pci_device_id slic_pci_tbl[] = {
{ 0 }
};
-static struct ethtool_ops slic_ethtool_ops;
+static const struct ethtool_ops slic_ethtool_ops;
MODULE_DEVICE_TABLE(pci, slic_pci_tbl);
-static inline void slic_reg32_write(void __iomem *reg, u32 value, bool flush)
-{
- writel(value, reg);
- if (flush)
- mb();
-}
-
-static inline void slic_reg64_write(struct adapter *adapter, void __iomem *reg,
- u32 value, void __iomem *regh, u32 paddrh,
- bool flush)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&adapter->bit64reglock, flags);
- writel(paddrh, regh);
- writel(value, reg);
- if (flush)
- mb();
- spin_unlock_irqrestore(&adapter->bit64reglock, flags);
-}
-
static void slic_mcast_set_bit(struct adapter *adapter, char *address)
{
unsigned char crcpoly;
@@ -172,8 +151,6 @@ static void slic_mcast_set_bit(struct adapter *adapter, char *address)
static void slic_mcast_set_mask(struct adapter *adapter)
{
- __iomem struct slic_regs *slic_regs = adapter->slic_regs;
-
if (adapter->macopts & (MAC_ALLMCAST | MAC_PROMISC)) {
/*
* Turn on all multicast addresses. We have to do this for
@@ -181,18 +158,17 @@ static void slic_mcast_set_mask(struct adapter *adapter)
* Microcode from having to keep state about the MAC
* configuration.
*/
- slic_reg32_write(&slic_regs->slic_mcastlow, 0xFFFFFFFF, FLUSH);
- slic_reg32_write(&slic_regs->slic_mcasthigh, 0xFFFFFFFF,
- FLUSH);
+ slic_write32(adapter, SLIC_REG_MCASTLOW, 0xFFFFFFFF);
+ slic_write32(adapter, SLIC_REG_MCASTHIGH, 0xFFFFFFFF);
} else {
/*
* Commit our multicast mast to the SLIC by writing to the
* multicast address mask registers
*/
- slic_reg32_write(&slic_regs->slic_mcastlow,
- (u32)(adapter->mcastmask & 0xFFFFFFFF), FLUSH);
- slic_reg32_write(&slic_regs->slic_mcasthigh,
- (u32)((adapter->mcastmask >> 32) & 0xFFFFFFFF), FLUSH);
+ slic_write32(adapter, SLIC_REG_MCASTLOW,
+ (u32)(adapter->mcastmask & 0xFFFFFFFF));
+ slic_write32(adapter, SLIC_REG_MCASTHIGH,
+ (u32)((adapter->mcastmask >> 32) & 0xFFFFFFFF));
}
}
@@ -208,13 +184,6 @@ static void slic_timer_ping(ulong dev)
add_timer(&adapter->pingtimer);
}
-static void slic_unmap_mmio_space(struct adapter *adapter)
-{
- if (adapter->slic_regs)
- iounmap(adapter->slic_regs);
- adapter->slic_regs = NULL;
-}
-
/*
* slic_link_config
*
@@ -224,7 +193,6 @@ static void slic_unmap_mmio_space(struct adapter *adapter)
static void slic_link_config(struct adapter *adapter,
u32 linkspeed, u32 linkduplex)
{
- u32 __iomem *wphy;
u32 speed;
u32 duplex;
u32 phy_config;
@@ -239,8 +207,6 @@ static void slic_link_config(struct adapter *adapter,
if (linkduplex > LINK_AUTOD)
linkduplex = LINK_AUTOD;
- wphy = &adapter->slic_regs->slic_wphy;
-
if ((linkspeed == LINK_AUTOSPEED) || (linkspeed == LINK_1000MB)) {
if (adapter->flags & ADAPT_FLAGS_FIBERMEDIA) {
/*
@@ -252,7 +218,7 @@ static void slic_link_config(struct adapter *adapter,
phy_advreg = (MIICR_REG_4 | (PAR_ADV1000XFD));
/* enable PAUSE frames */
phy_advreg |= PAR_ASYMPAUSE_FIBER;
- slic_reg32_write(wphy, phy_advreg, FLUSH);
+ slic_write32(adapter, SLIC_REG_WPHY, phy_advreg);
if (linkspeed == LINK_AUTOSPEED) {
/* reset phy, enable auto-neg */
@@ -260,14 +226,17 @@ static void slic_link_config(struct adapter *adapter,
(MIICR_REG_PCR |
(PCR_RESET | PCR_AUTONEG |
PCR_AUTONEG_RST));
- slic_reg32_write(wphy, phy_config, FLUSH);
+ slic_write32(adapter, SLIC_REG_WPHY,
+ phy_config);
} else { /* forced 1000 Mb FD*/
/*
* power down phy to break link
* this may not work)
*/
phy_config = (MIICR_REG_PCR | PCR_POWERDOWN);
- slic_reg32_write(wphy, phy_config, FLUSH);
+ slic_write32(adapter, SLIC_REG_WPHY,
+ phy_config);
+ slic_flush_write(adapter);
/*
* wait, Marvell says 1 sec,
* try to get away with 10 ms
@@ -282,7 +251,8 @@ static void slic_link_config(struct adapter *adapter,
(MIICR_REG_PCR |
(PCR_RESET | PCR_SPEED_1000 |
PCR_DUPLEX_FULL));
- slic_reg32_write(wphy, phy_config, FLUSH);
+ slic_write32(adapter, SLIC_REG_WPHY,
+ phy_config);
}
} else { /* copper gigabit */
@@ -309,10 +279,10 @@ static void slic_link_config(struct adapter *adapter,
phy_advreg |= PAR_ASYMPAUSE;
/* required by the Cicada PHY */
phy_advreg |= PAR_802_3;
- slic_reg32_write(wphy, phy_advreg, FLUSH);
+ slic_write32(adapter, SLIC_REG_WPHY, phy_advreg);
/* advertise FD only @1000 Mb */
phy_gctlreg = (MIICR_REG_9 | (PGC_ADV1000FD));
- slic_reg32_write(wphy, phy_gctlreg, FLUSH);
+ slic_write32(adapter, SLIC_REG_WPHY, phy_gctlreg);
if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
/*
@@ -321,20 +291,23 @@ static void slic_link_config(struct adapter *adapter,
*/
phy_config =
(MIICR_REG_16 | (MRV_REG16_XOVERON));
- slic_reg32_write(wphy, phy_config, FLUSH);
+ slic_write32(adapter, SLIC_REG_WPHY,
+ phy_config);
/* reset phy, enable auto-neg */
phy_config =
(MIICR_REG_PCR |
(PCR_RESET | PCR_AUTONEG |
PCR_AUTONEG_RST));
- slic_reg32_write(wphy, phy_config, FLUSH);
+ slic_write32(adapter, SLIC_REG_WPHY,
+ phy_config);
} else { /* it's a Cicada PHY */
/* enable and restart auto-neg (don't reset) */
phy_config =
(MIICR_REG_PCR |
(PCR_AUTONEG | PCR_AUTONEG_RST));
- slic_reg32_write(wphy, phy_config, FLUSH);
+ slic_write32(adapter, SLIC_REG_WPHY,
+ phy_config);
}
}
} else {
@@ -354,13 +327,13 @@ static void slic_link_config(struct adapter *adapter,
* disable auto crossover
*/
phy_config = (MIICR_REG_16 | (MRV_REG16_XOVEROFF));
- slic_reg32_write(wphy, phy_config, FLUSH);
+ slic_write32(adapter, SLIC_REG_WPHY, phy_config);
}
/* power down phy to break link (this may not work) */
phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN | speed | duplex));
- slic_reg32_write(wphy, phy_config, FLUSH);
-
+ slic_write32(adapter, SLIC_REG_WPHY, phy_config);
+ slic_flush_write(adapter);
/* wait, Marvell says 1 sec, try to get away with 10 ms */
mdelay(10);
@@ -372,11 +345,11 @@ static void slic_link_config(struct adapter *adapter,
*/
phy_config =
(MIICR_REG_PCR | (PCR_RESET | speed | duplex));
- slic_reg32_write(wphy, phy_config, FLUSH);
+ slic_write32(adapter, SLIC_REG_WPHY, phy_config);
} else { /* it's a Cicada PHY */
/* disable auto-neg, set speed, powerup */
phy_config = (MIICR_REG_PCR | (speed | duplex));
- slic_reg32_write(wphy, phy_config, FLUSH);
+ slic_write32(adapter, SLIC_REG_WPHY, phy_config);
}
}
}
@@ -386,7 +359,6 @@ static int slic_card_download_gbrcv(struct adapter *adapter)
const struct firmware *fw;
const char *file = "";
int ret;
- __iomem struct slic_regs *slic_regs = adapter->slic_regs;
u32 codeaddr;
u32 instruction;
int index = 0;
@@ -427,27 +399,28 @@ static int slic_card_download_gbrcv(struct adapter *adapter)
break;
}
/* start download */
- slic_reg32_write(&slic_regs->slic_rcv_wcs, SLIC_RCVWCS_BEGIN, FLUSH);
+ slic_write32(adapter, SLIC_REG_RCV_WCS, SLIC_RCVWCS_BEGIN);
/* download the rcv sequencer ucode */
for (codeaddr = 0; codeaddr < rcvucodelen; codeaddr++) {
/* write out instruction address */
- slic_reg32_write(&slic_regs->slic_rcv_wcs, codeaddr, FLUSH);
+ slic_write32(adapter, SLIC_REG_RCV_WCS, codeaddr);
instruction = *(u32 *)(fw->data + index);
index += 4;
/* write out the instruction data low addr */
- slic_reg32_write(&slic_regs->slic_rcv_wcs, instruction, FLUSH);
+ slic_write32(adapter, SLIC_REG_RCV_WCS, instruction);
instruction = *(u8 *)(fw->data + index);
index++;
/* write out the instruction data high addr */
- slic_reg32_write(&slic_regs->slic_rcv_wcs, (u8)instruction,
- FLUSH);
+ slic_write32(adapter, SLIC_REG_RCV_WCS, instruction);
}
/* download finished */
release_firmware(fw);
- slic_reg32_write(&slic_regs->slic_rcv_wcs, SLIC_RCVWCS_FINISH, FLUSH);
+ slic_write32(adapter, SLIC_REG_RCV_WCS, SLIC_RCVWCS_FINISH);
+ slic_flush_write(adapter);
+
return 0;
}
@@ -462,7 +435,6 @@ static int slic_card_download(struct adapter *adapter)
u32 section;
int thissectionsize;
int codeaddr;
- __iomem struct slic_regs *slic_regs = adapter->slic_regs;
u32 instruction;
u32 baseaddress;
u32 i;
@@ -506,17 +478,17 @@ static int slic_card_download(struct adapter *adapter)
for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
/* Write out instruction address */
- slic_reg32_write(&slic_regs->slic_wcs,
- baseaddress + codeaddr, FLUSH);
+ slic_write32(adapter, SLIC_REG_WCS,
+ baseaddress + codeaddr);
/* Write out instruction to low addr */
- slic_reg32_write(&slic_regs->slic_wcs,
- instruction, FLUSH);
+ slic_write32(adapter, SLIC_REG_WCS,
+ instruction);
instruction = *(u32 *)(fw->data + index);
index += 4;
/* Write out instruction to high addr */
- slic_reg32_write(&slic_regs->slic_wcs,
- instruction, FLUSH);
+ slic_write32(adapter, SLIC_REG_WCS,
+ instruction);
instruction = *(u32 *)(fw->data + index);
index += 4;
}
@@ -531,27 +503,25 @@ static int slic_card_download(struct adapter *adapter)
for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
/* Write out instruction address */
- slic_reg32_write(&slic_regs->slic_wcs,
- SLIC_WCS_COMPARE | (baseaddress + codeaddr),
- FLUSH);
+ slic_write32(adapter, SLIC_REG_WCS,
+ SLIC_WCS_COMPARE | (baseaddress +
+ codeaddr));
/* Write out instruction to low addr */
- slic_reg32_write(&slic_regs->slic_wcs, instruction,
- FLUSH);
+ slic_write32(adapter, SLIC_REG_WCS, instruction);
instruction = *(u32 *)(fw->data + index);
index += 4;
/* Write out instruction to high addr */
- slic_reg32_write(&slic_regs->slic_wcs, instruction,
- FLUSH);
+ slic_write32(adapter, SLIC_REG_WCS, instruction);
instruction = *(u32 *)(fw->data + index);
index += 4;
-
}
}
release_firmware(fw);
/* Everything OK, kick off the card */
mdelay(10);
- slic_reg32_write(&slic_regs->slic_wcs, SLIC_WCS_START, FLUSH);
+ slic_write32(adapter, SLIC_REG_WCS, SLIC_WCS_START);
+ slic_flush_write(adapter);
/*
* stall for 20 ms, long enough for ucode to init card
* and reach mainloop
@@ -583,19 +553,21 @@ static void slic_adapter_set_hwaddr(struct adapter *adapter)
static void slic_intagg_set(struct adapter *adapter, u32 value)
{
- slic_reg32_write(&adapter->slic_regs->slic_intagg, value, FLUSH);
+ slic_write32(adapter, SLIC_REG_INTAGG, value);
adapter->card->loadlevel_current = value;
}
static void slic_soft_reset(struct adapter *adapter)
{
if (adapter->card->state == CARD_UP) {
- slic_reg32_write(&adapter->slic_regs->slic_quiesce, 0, FLUSH);
+ slic_write32(adapter, SLIC_REG_QUIESCE, 0);
+ slic_flush_write(adapter);
mdelay(1);
}
- slic_reg32_write(&adapter->slic_regs->slic_reset, SLIC_RESET_MAGIC,
- FLUSH);
+ slic_write32(adapter, SLIC_REG_RESET, SLIC_RESET_MAGIC);
+ slic_flush_write(adapter);
+
mdelay(1);
}
@@ -603,17 +575,16 @@ static void slic_mac_address_config(struct adapter *adapter)
{
u32 value;
u32 value2;
- __iomem struct slic_regs *slic_regs = adapter->slic_regs;
value = ntohl(*(__be32 *)&adapter->currmacaddr[2]);
- slic_reg32_write(&slic_regs->slic_wraddral, value, FLUSH);
- slic_reg32_write(&slic_regs->slic_wraddrbl, value, FLUSH);
+ slic_write32(adapter, SLIC_REG_WRADDRAL, value);
+ slic_write32(adapter, SLIC_REG_WRADDRBL, value);
value2 = (u32)((adapter->currmacaddr[0] << 8 |
adapter->currmacaddr[1]) & 0xFFFF);
- slic_reg32_write(&slic_regs->slic_wraddrah, value2, FLUSH);
- slic_reg32_write(&slic_regs->slic_wraddrbh, value2, FLUSH);
+ slic_write32(adapter, SLIC_REG_WRADDRAH, value2);
+ slic_write32(adapter, SLIC_REG_WRADDRBH, value2);
/*
* Write our multicast mask out to the card. This is done
@@ -626,7 +597,6 @@ static void slic_mac_address_config(struct adapter *adapter)
static void slic_mac_config(struct adapter *adapter)
{
u32 value;
- __iomem struct slic_regs *slic_regs = adapter->slic_regs;
/* Setup GMAC gaps */
if (adapter->linkspeed == LINK_1000MB) {
@@ -650,7 +620,7 @@ static void slic_mac_config(struct adapter *adapter)
}
/* write mac config */
- slic_reg32_write(&slic_regs->slic_wmcfg, value, FLUSH);
+ slic_write32(adapter, SLIC_REG_WMCFG, value);
/* setup mac addresses */
slic_mac_address_config(adapter);
@@ -660,7 +630,6 @@ static void slic_config_set(struct adapter *adapter, bool linkchange)
{
u32 value;
u32 RcrReset;
- __iomem struct slic_regs *slic_regs = adapter->slic_regs;
if (linkchange) {
/* Setup MAC */
@@ -677,7 +646,7 @@ static void slic_config_set(struct adapter *adapter, bool linkchange)
GXCR_XMTEN | /* Enable transmit */
GXCR_PAUSEEN); /* Enable pause */
- slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
+ slic_write32(adapter, SLIC_REG_WXCFG, value);
/* Setup rcvcfg last */
value = (RcrReset | /* Reset, if linkchange */
@@ -690,7 +659,7 @@ static void slic_config_set(struct adapter *adapter, bool linkchange)
value = (GXCR_RESET | /* Always reset */
GXCR_XMTEN); /* Enable transmit */
- slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
+ slic_write32(adapter, SLIC_REG_WXCFG, value);
/* Setup rcvcfg last */
value = (RcrReset | /* Reset, if linkchange */
@@ -707,7 +676,7 @@ static void slic_config_set(struct adapter *adapter, bool linkchange)
if (adapter->macopts & MAC_PROMISC)
value |= GRCR_RCVALL;
- slic_reg32_write(&slic_regs->slic_wrcfg, value, FLUSH);
+ slic_write32(adapter, SLIC_REG_WRCFG, value);
}
/*
@@ -717,24 +686,23 @@ static void slic_config_clear(struct adapter *adapter)
{
u32 value;
u32 phy_config;
- __iomem struct slic_regs *slic_regs = adapter->slic_regs;
/* Setup xmtcfg */
value = (GXCR_RESET | /* Always reset */
GXCR_PAUSEEN); /* Enable pause */
- slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
+ slic_write32(adapter, SLIC_REG_WXCFG, value);
value = (GRCR_RESET | /* Always reset */
GRCR_CTLEN | /* Enable CTL frames */
GRCR_ADDRAEN | /* Address A enable */
(GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
- slic_reg32_write(&slic_regs->slic_wrcfg, value, FLUSH);
+ slic_write32(adapter, SLIC_REG_WRCFG, value);
/* power down phy */
phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN));
- slic_reg32_write(&slic_regs->slic_wphy, phy_config, FLUSH);
+ slic_write32(adapter, SLIC_REG_WPHY, phy_config);
}
static bool slic_mac_filter(struct adapter *adapter,
@@ -810,13 +778,11 @@ static void slic_timer_load_check(ulong cardaddr)
{
struct sliccard *card = (struct sliccard *)cardaddr;
struct adapter *adapter = card->master;
- u32 __iomem *intagg;
u32 load = card->events;
u32 level = 0;
if ((adapter) && (adapter->state == ADAPT_UP) &&
(card->state == CARD_UP) && (slic_global.dynamic_intagg)) {
- intagg = &adapter->slic_regs->slic_intagg;
if (adapter->devid == SLIC_1GB_DEVICE_ID) {
if (adapter->linkspeed == LINK_1000MB)
level = 100;
@@ -836,7 +802,7 @@ static void slic_timer_load_check(ulong cardaddr)
}
if (card->loadlevel_current != level) {
card->loadlevel_current = level;
- slic_reg32_write(intagg, level, FLUSH);
+ slic_write32(adapter, SLIC_REG_INTAGG, level);
}
} else {
if (load > SLIC_LOAD_5)
@@ -853,7 +819,7 @@ static void slic_timer_load_check(ulong cardaddr)
level = SLIC_INTAGG_0;
if (card->loadlevel_current != level) {
card->loadlevel_current = level;
- slic_reg32_write(intagg, level, FLUSH);
+ slic_write32(adapter, SLIC_REG_INTAGG, level);
}
}
}
@@ -897,7 +863,6 @@ static int slic_upr_queue_request(struct adapter *adapter,
static void slic_upr_start(struct adapter *adapter)
{
struct slic_upr *upr;
- __iomem struct slic_regs *slic_regs = adapter->slic_regs;
upr = adapter->upr_list;
if (!upr)
@@ -909,31 +874,27 @@ static void slic_upr_start(struct adapter *adapter)
switch (upr->upr_request) {
case SLIC_UPR_STATS:
if (upr->upr_data_h == 0) {
- slic_reg32_write(&slic_regs->slic_stats, upr->upr_data,
- FLUSH);
+ slic_write32(adapter, SLIC_REG_RSTAT, upr->upr_data);
} else {
- slic_reg64_write(adapter, &slic_regs->slic_stats64,
- upr->upr_data,
- &slic_regs->slic_addr_upper,
- upr->upr_data_h, FLUSH);
+ slic_write64(adapter, SLIC_REG_RSTAT64, upr->upr_data,
+ upr->upr_data_h);
}
break;
case SLIC_UPR_RLSR:
- slic_reg64_write(adapter, &slic_regs->slic_rlsr, upr->upr_data,
- &slic_regs->slic_addr_upper, upr->upr_data_h,
- FLUSH);
+ slic_write64(adapter, SLIC_REG_LSTAT, upr->upr_data,
+ upr->upr_data_h);
break;
case SLIC_UPR_RCONFIG:
- slic_reg64_write(adapter, &slic_regs->slic_rconfig,
- upr->upr_data, &slic_regs->slic_addr_upper,
- upr->upr_data_h, FLUSH);
+ slic_write64(adapter, SLIC_REG_RCONFIG, upr->upr_data,
+ upr->upr_data_h);
break;
case SLIC_UPR_PING:
- slic_reg32_write(&slic_regs->slic_ping, 1, FLUSH);
+ slic_write32(adapter, SLIC_REG_PING, 1);
break;
}
+ slic_flush_write(adapter);
}
static int slic_upr_request(struct adapter *adapter,
@@ -961,42 +922,34 @@ err_unlock_irq:
static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
{
- u32 linkstatus = adapter->pshmem->linkstatus;
+ struct slic_shmemory *sm = &adapter->shmem;
+ struct slic_shmem_data *sm_data = sm->shmem_data;
+ u32 lst = sm_data->lnkstatus;
uint linkup;
unsigned char linkspeed;
unsigned char linkduplex;
if ((isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
- struct slic_shmem *pshmem;
+ dma_addr_t phaddr = sm->lnkstatus_phaddr;
- pshmem = (struct slic_shmem *)(unsigned long)
- adapter->phys_shmem;
-#if BITS_PER_LONG == 64
- slic_upr_queue_request(adapter,
- SLIC_UPR_RLSR,
- SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
- SLIC_GET_ADDR_HIGH(&pshmem->linkstatus),
+ slic_upr_queue_request(adapter, SLIC_UPR_RLSR,
+ cpu_to_le32(lower_32_bits(phaddr)),
+ cpu_to_le32(upper_32_bits(phaddr)),
0, 0);
-#else
- slic_upr_queue_request(adapter,
- SLIC_UPR_RLSR,
- (u32)&pshmem->linkstatus,
- SLIC_GET_ADDR_HIGH(pshmem), 0, 0);
-#endif
return;
}
if (adapter->state != ADAPT_UP)
return;
- linkup = linkstatus & GIG_LINKUP ? LINK_UP : LINK_DOWN;
- if (linkstatus & GIG_SPEED_1000)
+ linkup = lst & GIG_LINKUP ? LINK_UP : LINK_DOWN;
+ if (lst & GIG_SPEED_1000)
linkspeed = LINK_1000MB;
- else if (linkstatus & GIG_SPEED_100)
+ else if (lst & GIG_SPEED_100)
linkspeed = LINK_100MB;
else
linkspeed = LINK_10MB;
- if (linkstatus & GIG_FULLDUPLEX)
+ if (lst & GIG_FULLDUPLEX)
linkduplex = LINK_FULLD;
else
linkduplex = LINK_HALFD;
@@ -1016,6 +969,7 @@ static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
/* link has gone from up to down */
if (linkup == LINK_DOWN) {
adapter->linkstate = LINK_DOWN;
+ netif_carrier_off(adapter->netdev);
return;
}
@@ -1027,7 +981,7 @@ static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
/* setup the mac */
slic_config_set(adapter, true);
adapter->linkstate = LINK_UP;
- netif_start_queue(adapter->netdev);
+ netif_carrier_on(adapter->netdev);
}
}
@@ -1047,81 +1001,65 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
upr->next = NULL;
adapter->upr_busy = 0;
switch (upr->upr_request) {
- case SLIC_UPR_STATS:
- {
- struct slic_stats *slicstats =
- (struct slic_stats *)&adapter->pshmem->inicstats;
- struct slic_stats *newstats = slicstats;
- struct slic_stats *old = &adapter->inicstats_prev;
- struct slicnet_stats *stst = &adapter->slic_stats;
-
- if (isr & ISR_UPCERR) {
- dev_err(&adapter->netdev->dev,
- "SLIC_UPR_STATS command failed isr[%x]\n",
- isr);
-
- break;
- }
- UPDATE_STATS_GB(stst->tcp.xmit_tcp_segs,
- newstats->xmit_tcp_segs_gb,
- old->xmit_tcp_segs_gb);
-
- UPDATE_STATS_GB(stst->tcp.xmit_tcp_bytes,
- newstats->xmit_tcp_bytes_gb,
- old->xmit_tcp_bytes_gb);
-
- UPDATE_STATS_GB(stst->tcp.rcv_tcp_segs,
- newstats->rcv_tcp_segs_gb,
- old->rcv_tcp_segs_gb);
-
- UPDATE_STATS_GB(stst->tcp.rcv_tcp_bytes,
- newstats->rcv_tcp_bytes_gb,
- old->rcv_tcp_bytes_gb);
-
- UPDATE_STATS_GB(stst->iface.xmt_bytes,
- newstats->xmit_bytes_gb,
- old->xmit_bytes_gb);
-
- UPDATE_STATS_GB(stst->iface.xmt_ucast,
- newstats->xmit_unicasts_gb,
- old->xmit_unicasts_gb);
-
- UPDATE_STATS_GB(stst->iface.rcv_bytes,
- newstats->rcv_bytes_gb,
- old->rcv_bytes_gb);
-
- UPDATE_STATS_GB(stst->iface.rcv_ucast,
- newstats->rcv_unicasts_gb,
- old->rcv_unicasts_gb);
-
- UPDATE_STATS_GB(stst->iface.xmt_errors,
- newstats->xmit_collisions_gb,
- old->xmit_collisions_gb);
-
- UPDATE_STATS_GB(stst->iface.xmt_errors,
- newstats->xmit_excess_collisions_gb,
- old->xmit_excess_collisions_gb);
-
- UPDATE_STATS_GB(stst->iface.xmt_errors,
- newstats->xmit_other_error_gb,
- old->xmit_other_error_gb);
-
- UPDATE_STATS_GB(stst->iface.rcv_errors,
- newstats->rcv_other_error_gb,
- old->rcv_other_error_gb);
-
- UPDATE_STATS_GB(stst->iface.rcv_discards,
- newstats->rcv_drops_gb,
- old->rcv_drops_gb);
-
- if (newstats->rcv_drops_gb > old->rcv_drops_gb) {
- adapter->rcv_drops +=
- (newstats->rcv_drops_gb -
- old->rcv_drops_gb);
- }
- memcpy(old, newstats, sizeof(struct slic_stats));
+ case SLIC_UPR_STATS: {
+ struct slic_shmemory *sm = &adapter->shmem;
+ struct slic_shmem_data *sm_data = sm->shmem_data;
+ struct slic_stats *stats = &sm_data->stats;
+ struct slic_stats *old = &adapter->inicstats_prev;
+ struct slicnet_stats *stst = &adapter->slic_stats;
+
+ if (isr & ISR_UPCERR) {
+ dev_err(&adapter->netdev->dev,
+ "SLIC_UPR_STATS command failed isr[%x]\n", isr);
break;
}
+
+ UPDATE_STATS_GB(stst->tcp.xmit_tcp_segs, stats->xmit_tcp_segs,
+ old->xmit_tcp_segs);
+
+ UPDATE_STATS_GB(stst->tcp.xmit_tcp_bytes, stats->xmit_tcp_bytes,
+ old->xmit_tcp_bytes);
+
+ UPDATE_STATS_GB(stst->tcp.rcv_tcp_segs, stats->rcv_tcp_segs,
+ old->rcv_tcp_segs);
+
+ UPDATE_STATS_GB(stst->tcp.rcv_tcp_bytes, stats->rcv_tcp_bytes,
+ old->rcv_tcp_bytes);
+
+ UPDATE_STATS_GB(stst->iface.xmt_bytes, stats->xmit_bytes,
+ old->xmit_bytes);
+
+ UPDATE_STATS_GB(stst->iface.xmt_ucast, stats->xmit_unicasts,
+ old->xmit_unicasts);
+
+ UPDATE_STATS_GB(stst->iface.rcv_bytes, stats->rcv_bytes,
+ old->rcv_bytes);
+
+ UPDATE_STATS_GB(stst->iface.rcv_ucast, stats->rcv_unicasts,
+ old->rcv_unicasts);
+
+ UPDATE_STATS_GB(stst->iface.xmt_errors, stats->xmit_collisions,
+ old->xmit_collisions);
+
+ UPDATE_STATS_GB(stst->iface.xmt_errors,
+ stats->xmit_excess_collisions,
+ old->xmit_excess_collisions);
+
+ UPDATE_STATS_GB(stst->iface.xmt_errors, stats->xmit_other_error,
+ old->xmit_other_error);
+
+ UPDATE_STATS_GB(stst->iface.rcv_errors, stats->rcv_other_error,
+ old->rcv_other_error);
+
+ UPDATE_STATS_GB(stst->iface.rcv_discards, stats->rcv_drops,
+ old->rcv_drops);
+
+ if (stats->rcv_drops > old->rcv_drops)
+ adapter->rcv_drops += (stats->rcv_drops -
+ old->rcv_drops);
+ memcpy_fromio(old, stats, sizeof(*stats));
+ break;
+ }
case SLIC_UPR_RLSR:
slic_link_upr_complete(adapter, isr);
break;
@@ -1186,7 +1124,6 @@ static int slic_rspqueue_init(struct adapter *adapter)
{
int i;
struct slic_rspqueue *rspq = &adapter->rspqueue;
- __iomem struct slic_regs *slic_regs = adapter->slic_regs;
u32 paddrh = 0;
memset(rspq, 0, sizeof(struct slic_rspqueue));
@@ -1205,14 +1142,12 @@ static int slic_rspqueue_init(struct adapter *adapter)
}
if (paddrh == 0) {
- slic_reg32_write(&slic_regs->slic_rbar,
- (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
- DONT_FLUSH);
+ slic_write32(adapter, SLIC_REG_RBAR,
+ rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE);
} else {
- slic_reg64_write(adapter, &slic_regs->slic_rbar64,
- (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
- &slic_regs->slic_addr_upper,
- paddrh, DONT_FLUSH);
+ slic_write64(adapter, SLIC_REG_RBAR64,
+ rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE,
+ paddrh);
}
}
rspq->offset = 0;
@@ -1233,9 +1168,9 @@ static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter)
if (++rspq->offset < SLIC_RSPQ_BUFSINPAGE) {
rspq->rspbuf++;
} else {
- slic_reg64_write(adapter, &adapter->slic_regs->slic_rbar64,
- (rspq->paddr[rspq->pageindex] | SLIC_RSPQ_BUFSINPAGE),
- &adapter->slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+ slic_write64(adapter, SLIC_REG_RBAR64,
+ rspq->paddr[rspq->pageindex] |
+ SLIC_RSPQ_BUFSINPAGE, 0);
rspq->pageindex = (rspq->pageindex + 1) % rspq->num_pages;
rspq->offset = 0;
rspq->rspbuf = (struct slic_rspbuf *)
@@ -1569,14 +1504,11 @@ retry_rcvqfill:
}
#endif
if (paddrh == 0) {
- slic_reg32_write(&adapter->slic_regs->slic_hbar,
- (u32)paddrl, DONT_FLUSH);
+ slic_write32(adapter, SLIC_REG_HBAR,
+ (u32)paddrl);
} else {
- slic_reg64_write(adapter,
- &adapter->slic_regs->slic_hbar64,
- paddrl,
- &adapter->slic_regs->slic_addr_upper,
- paddrh, DONT_FLUSH);
+ slic_write64(adapter, SLIC_REG_HBAR64, paddrl,
+ paddrh);
}
if (rcvq->head)
rcvq->tail->next = skb;
@@ -1698,14 +1630,10 @@ static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb)
dev_err(dev, " rcvq->tail[%p]\n", rcvq->tail);
dev_err(dev, " rcvq->count[%x]\n", rcvq->count);
}
- if (paddrh == 0) {
- slic_reg32_write(&adapter->slic_regs->slic_hbar, (u32)paddrl,
- DONT_FLUSH);
- } else {
- slic_reg64_write(adapter, &adapter->slic_regs->slic_hbar64,
- paddrl, &adapter->slic_regs->slic_addr_upper,
- paddrh, DONT_FLUSH);
- }
+ if (paddrh == 0)
+ slic_write32(adapter, SLIC_REG_HBAR, (u32)paddrl);
+ else
+ slic_write64(adapter, SLIC_REG_HBAR64, paddrl, paddrh);
if (rcvq->head)
rcvq->tail->next = skb;
else
@@ -1728,26 +1656,17 @@ static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb)
static int slic_link_event_handler(struct adapter *adapter)
{
int status;
- struct slic_shmem *pshmem;
+ struct slic_shmemory *sm = &adapter->shmem;
+ dma_addr_t phaddr = sm->lnkstatus_phaddr;
if (adapter->state != ADAPT_UP) {
/* Adapter is not operational. Ignore. */
return -ENODEV;
}
-
- pshmem = (struct slic_shmem *)(unsigned long)adapter->phys_shmem;
-
-#if BITS_PER_LONG == 64
- status = slic_upr_request(adapter,
- SLIC_UPR_RLSR,
- SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
- SLIC_GET_ADDR_HIGH(&pshmem->linkstatus),
- 0, 0);
-#else
+ /* no 4GB wrap guaranteed */
status = slic_upr_request(adapter, SLIC_UPR_RLSR,
- (u32)&pshmem->linkstatus, /* no 4GB wrap guaranteed */
- 0, 0, 0);
-#endif
+ cpu_to_le32(lower_32_bits(phaddr)),
+ cpu_to_le32(upper_32_bits(phaddr)), 0, 0);
return status;
}
@@ -1757,12 +1676,13 @@ static void slic_init_cleanup(struct adapter *adapter)
adapter->intrregistered = 0;
free_irq(adapter->netdev->irq, adapter->netdev);
}
- if (adapter->pshmem) {
- pci_free_consistent(adapter->pcidev,
- sizeof(struct slic_shmem),
- adapter->pshmem, adapter->phys_shmem);
- adapter->pshmem = NULL;
- adapter->phys_shmem = (dma_addr_t)(unsigned long)NULL;
+
+ if (adapter->shmem.shmem_data) {
+ struct slic_shmemory *sm = &adapter->shmem;
+ struct slic_shmem_data *sm_data = sm->shmem_data;
+
+ pci_free_consistent(adapter->pcidev, sizeof(*sm_data), sm_data,
+ sm->isr_phaddr);
}
if (adapter->pingtimerset) {
@@ -2147,13 +2067,16 @@ static irqreturn_t slic_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct adapter *adapter = netdev_priv(dev);
+ struct slic_shmemory *sm = &adapter->shmem;
+ struct slic_shmem_data *sm_data = sm->shmem_data;
u32 isr;
- if ((adapter->pshmem) && (adapter->pshmem->isr)) {
- slic_reg32_write(&adapter->slic_regs->slic_icr,
- ICR_INT_MASK, FLUSH);
- isr = adapter->isrcopy = adapter->pshmem->isr;
- adapter->pshmem->isr = 0;
+ if (sm_data->isr) {
+ slic_write32(adapter, SLIC_REG_ICR, ICR_INT_MASK);
+ slic_flush_write(adapter);
+
+ isr = sm_data->isr;
+ sm_data->isr = 0;
adapter->num_isrs++;
switch (adapter->card->state) {
case CARD_UP:
@@ -2169,10 +2092,9 @@ static irqreturn_t slic_interrupt(int irq, void *dev_id)
break;
}
- adapter->isrcopy = 0;
adapter->all_reg_writes += 2;
adapter->isr_reg_writes++;
- slic_reg32_write(&adapter->slic_regs->slic_isr, 0, FLUSH);
+ slic_write32(adapter, SLIC_REG_ISR, 0);
} else {
adapter->false_interrupts++;
}
@@ -2224,13 +2146,11 @@ static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
}
#endif
if (hcmd->paddrh == 0) {
- slic_reg32_write(&adapter->slic_regs->slic_cbar,
- (hcmd->paddrl | hcmd->cmdsize), DONT_FLUSH);
+ slic_write32(adapter, SLIC_REG_CBAR, (hcmd->paddrl |
+ hcmd->cmdsize));
} else {
- slic_reg64_write(adapter, &adapter->slic_regs->slic_cbar64,
- (hcmd->paddrl | hcmd->cmdsize),
- &adapter->slic_regs->slic_addr_upper,
- hcmd->paddrh, DONT_FLUSH);
+ slic_write64(adapter, SLIC_REG_CBAR64,
+ hcmd->paddrl | hcmd->cmdsize, hcmd->paddrh);
}
xmit_done:
return NETDEV_TX_OK;
@@ -2290,8 +2210,8 @@ static int slic_if_init(struct adapter *adapter, unsigned long *flags)
{
struct sliccard *card = adapter->card;
struct net_device *dev = adapter->netdev;
- __iomem struct slic_regs *slic_regs = adapter->slic_regs;
- struct slic_shmem *pshmem;
+ struct slic_shmemory *sm = &adapter->shmem;
+ struct slic_shmem_data *sm_data = sm->shmem_data;
int rc;
/* adapter should be down at this point */
@@ -2335,28 +2255,20 @@ static int slic_if_init(struct adapter *adapter, unsigned long *flags)
adapter->queues_initialized = 1;
}
- slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+ slic_write32(adapter, SLIC_REG_ICR, ICR_INT_OFF);
+ slic_flush_write(adapter);
mdelay(1);
if (!adapter->isp_initialized) {
unsigned long flags;
- pshmem = (struct slic_shmem *)(unsigned long)
- adapter->phys_shmem;
-
spin_lock_irqsave(&adapter->bit64reglock, flags);
-
-#if BITS_PER_LONG == 64
- slic_reg32_write(&slic_regs->slic_addr_upper,
- SLIC_GET_ADDR_HIGH(&pshmem->isr), DONT_FLUSH);
- slic_reg32_write(&slic_regs->slic_isp,
- SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
-#else
- slic_reg32_write(&slic_regs->slic_addr_upper, 0, DONT_FLUSH);
- slic_reg32_write(&slic_regs->slic_isp, (u32)&pshmem->isr,
- FLUSH);
-#endif
+ slic_write32(adapter, SLIC_REG_ADDR_UPPER,
+ cpu_to_le32(upper_32_bits(sm->isr_phaddr)));
+ slic_write32(adapter, SLIC_REG_ISP,
+ cpu_to_le32(lower_32_bits(sm->isr_phaddr)));
spin_unlock_irqrestore(&adapter->bit64reglock, flags);
+
adapter->isp_initialized = 1;
}
@@ -2383,17 +2295,20 @@ static int slic_if_init(struct adapter *adapter, unsigned long *flags)
/*
* clear any pending events, then enable interrupts
*/
- adapter->isrcopy = 0;
- adapter->pshmem->isr = 0;
- slic_reg32_write(&slic_regs->slic_isr, 0, FLUSH);
- slic_reg32_write(&slic_regs->slic_icr, ICR_INT_ON, FLUSH);
+ sm_data->isr = 0;
+ slic_write32(adapter, SLIC_REG_ISR, 0);
+ slic_write32(adapter, SLIC_REG_ICR, ICR_INT_ON);
slic_link_config(adapter, LINK_AUTOSPEED, LINK_AUTOD);
+ slic_flush_write(adapter);
+
rc = slic_link_event_handler(adapter);
if (rc) {
/* disable interrupts then clear pending events */
- slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
- slic_reg32_write(&slic_regs->slic_isr, 0, FLUSH);
+ slic_write32(adapter, SLIC_REG_ICR, ICR_INT_OFF);
+ slic_write32(adapter, SLIC_REG_ISR, 0);
+ slic_flush_write(adapter);
+
if (adapter->pingtimerset) {
del_timer(&adapter->pingtimer);
adapter->pingtimerset = 0;
@@ -2417,7 +2332,7 @@ static int slic_entry_open(struct net_device *dev)
unsigned long flags;
int status;
- netif_stop_queue(adapter->netdev);
+ netif_carrier_off(dev);
spin_lock_irqsave(&slic_global.driver_lock, flags);
if (!adapter->activated) {
@@ -2440,6 +2355,9 @@ static int slic_entry_open(struct net_device *dev)
spin_unlock:
spin_unlock_irqrestore(&slic_global.driver_lock, flags);
+
+ netif_start_queue(adapter->netdev);
+
return status;
}
@@ -2463,7 +2381,7 @@ static void slic_entry_remove(struct pci_dev *pcidev)
unregister_netdev(dev);
slic_adapter_freeresources(adapter);
- slic_unmap_mmio_space(adapter);
+ iounmap(adapter->regs);
/* free multicast addresses */
mlist = adapter->mcastaddrs;
@@ -2497,7 +2415,6 @@ static int slic_entry_halt(struct net_device *dev)
{
struct adapter *adapter = netdev_priv(dev);
struct sliccard *card = adapter->card;
- __iomem struct slic_regs *slic_regs = adapter->slic_regs;
unsigned long flags;
spin_lock_irqsave(&slic_global.driver_lock, flags);
@@ -2507,7 +2424,7 @@ static int slic_entry_halt(struct net_device *dev)
adapter->upr_list = NULL;
adapter->upr_busy = 0;
adapter->devflags_prev = 0;
- slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+ slic_write32(adapter, SLIC_REG_ICR, ICR_INT_OFF);
adapter->all_reg_writes++;
adapter->icr_reg_writes++;
slic_config_clear(adapter);
@@ -2517,8 +2434,10 @@ static int slic_entry_halt(struct net_device *dev)
adapter->activated = 0;
}
#ifdef AUTOMATIC_RESET
- slic_reg32_write(&slic_regs->slic_reset_iface, 0, FLUSH);
+ slic_write32(adapter, SLIC_REG_RESET_IFACE, 0);
#endif
+ slic_flush_write(adapter);
+
/*
* Reset the adapter's cmd queues
*/
@@ -2530,6 +2449,9 @@ static int slic_entry_halt(struct net_device *dev)
#endif
spin_unlock_irqrestore(&slic_global.driver_lock, flags);
+
+ netif_carrier_off(dev);
+
return 0;
}
@@ -2661,14 +2583,14 @@ static void slic_config_pci(struct pci_dev *pcidev)
static int slic_card_init(struct sliccard *card, struct adapter *adapter)
{
- __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+ struct slic_shmemory *sm = &adapter->shmem;
+ struct slic_shmem_data *sm_data = sm->shmem_data;
struct slic_eeprom *peeprom;
struct oslic_eeprom *pOeeprom;
dma_addr_t phys_config;
u32 phys_configh;
u32 phys_configl;
u32 i = 0;
- struct slic_shmem *pshmem;
int status;
uint macaddrs = card->card_size;
ushort eecodesize;
@@ -2695,27 +2617,26 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
sizeof(struct slic_eeprom),
&phys_config);
- phys_configl = SLIC_GET_ADDR_LOW(phys_config);
- phys_configh = SLIC_GET_ADDR_HIGH(phys_config);
-
if (!peeprom) {
dev_err(&adapter->pcidev->dev,
"Failed to allocate DMA memory for EEPROM.\n");
return -ENOMEM;
}
+ phys_configl = SLIC_GET_ADDR_LOW(phys_config);
+ phys_configh = SLIC_GET_ADDR_HIGH(phys_config);
+
memset(peeprom, 0, sizeof(struct slic_eeprom));
- slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+ slic_write32(adapter, SLIC_REG_ICR, ICR_INT_OFF);
+ slic_flush_write(adapter);
mdelay(1);
- pshmem = (struct slic_shmem *)(unsigned long)
- adapter->phys_shmem;
spin_lock_irqsave(&adapter->bit64reglock, flags);
- slic_reg32_write(&slic_regs->slic_addr_upper,
- SLIC_GET_ADDR_HIGH(&pshmem->isr), DONT_FLUSH);
- slic_reg32_write(&slic_regs->slic_isp,
- SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
+ slic_write32(adapter, SLIC_REG_ADDR_UPPER,
+ cpu_to_le32(upper_32_bits(sm->isr_phaddr)));
+ slic_write32(adapter, SLIC_REG_ISP,
+ cpu_to_le32(lower_32_bits(sm->isr_phaddr)));
spin_unlock_irqrestore(&adapter->bit64reglock, flags);
status = slic_config_get(adapter, phys_configl, phys_configh);
@@ -2726,33 +2647,31 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
}
for (;;) {
- if (adapter->pshmem->isr) {
- if (adapter->pshmem->isr & ISR_UPC) {
- adapter->pshmem->isr = 0;
- slic_reg64_write(adapter,
- &slic_regs->slic_isp, 0,
- &slic_regs->slic_addr_upper,
- 0, FLUSH);
- slic_reg32_write(&slic_regs->slic_isr,
- 0, FLUSH);
+ if (sm_data->isr) {
+ if (sm_data->isr & ISR_UPC) {
+ sm_data->isr = 0;
+ slic_write64(adapter, SLIC_REG_ISP, 0,
+ 0);
+ slic_write32(adapter, SLIC_REG_ISR, 0);
+ slic_flush_write(adapter);
slic_upr_request_complete(adapter, 0);
break;
}
- adapter->pshmem->isr = 0;
- slic_reg32_write(&slic_regs->slic_isr,
- 0, FLUSH);
+ sm_data->isr = 0;
+ slic_write32(adapter, SLIC_REG_ISR, 0);
+ slic_flush_write(adapter);
} else {
mdelay(1);
i++;
if (i > 5000) {
dev_err(&adapter->pcidev->dev,
"Fetch of config data timed out.\n");
- slic_reg64_write(adapter,
- &slic_regs->slic_isp, 0,
- &slic_regs->slic_addr_upper,
- 0, FLUSH);
+ slic_write64(adapter, SLIC_REG_ISP,
+ 0, 0);
+ slic_flush_write(adapter);
+
status = -EINVAL;
goto card_init_err;
}
@@ -2796,7 +2715,6 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
/* see if the EEPROM is valid by checking it's checksum */
if ((eecodesize <= MAX_EECODE_SIZE) &&
(eecodesize >= MIN_EECODE_SIZE)) {
-
ee_chksum =
*(u16 *)((char *)peeprom + (eecodesize - 2));
/*
@@ -2830,9 +2748,8 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
peeprom, phys_config);
if (!card->config.EepromValid) {
- slic_reg64_write(adapter, &slic_regs->slic_isp, 0,
- &slic_regs->slic_addr_upper,
- 0, FLUSH);
+ slic_write64(adapter, SLIC_REG_ISP, 0, 0);
+ slic_flush_write(adapter);
dev_err(&adapter->pcidev->dev, "EEPROM invalid.\n");
return -EINVAL;
}
@@ -2896,14 +2813,17 @@ static void slic_init_driver(void)
}
}
-static void slic_init_adapter(struct net_device *netdev,
- struct pci_dev *pcidev,
- const struct pci_device_id *pci_tbl_entry,
- void __iomem *memaddr, int chip_idx)
+static int slic_init_adapter(struct net_device *netdev,
+ struct pci_dev *pcidev,
+ const struct pci_device_id *pci_tbl_entry,
+ void __iomem *memaddr, int chip_idx)
{
ushort index;
struct slic_handle *pslic_handle;
struct adapter *adapter = netdev_priv(netdev);
+ struct slic_shmemory *sm = &adapter->shmem;
+ struct slic_shmem_data *sm_data;
+ dma_addr_t phaddr;
/* adapter->pcidev = pcidev;*/
adapter->vendid = pci_tbl_entry->vendor;
@@ -2912,7 +2832,7 @@ static void slic_init_adapter(struct net_device *netdev,
adapter->busnumber = pcidev->bus->number;
adapter->slotnumber = ((pcidev->devfn >> 3) & 0x1F);
adapter->functionnumber = (pcidev->devfn & 0x7);
- adapter->slic_regs = memaddr;
+ adapter->regs = memaddr;
adapter->irq = pcidev->irq;
adapter->chipid = chip_idx;
adapter->port = 0;
@@ -2932,19 +2852,23 @@ static void slic_init_adapter(struct net_device *netdev,
*/
for (index = 1, pslic_handle = &adapter->slic_handles[1];
index < SLIC_CMDQ_MAXCMDS; index++, pslic_handle++) {
-
pslic_handle->token.handle_index = index;
pslic_handle->type = SLIC_HANDLE_FREE;
pslic_handle->next = adapter->pfree_slic_handles;
adapter->pfree_slic_handles = pslic_handle;
}
- adapter->pshmem = (struct slic_shmem *)
- pci_alloc_consistent(adapter->pcidev,
- sizeof(struct slic_shmem),
- &adapter->
- phys_shmem);
- if (adapter->pshmem)
- memset(adapter->pshmem, 0, sizeof(struct slic_shmem));
+ sm_data = pci_zalloc_consistent(adapter->pcidev, sizeof(*sm_data),
+ &phaddr);
+ if (!sm_data)
+ return -ENOMEM;
+
+ sm->shmem_data = sm_data;
+ sm->isr_phaddr = phaddr;
+ sm->lnkstatus_phaddr = phaddr + offsetof(struct slic_shmem_data,
+ lnkstatus);
+ sm->stats_phaddr = phaddr + offsetof(struct slic_shmem_data, stats);
+
+ return 0;
}
static const struct net_device_ops slic_netdev_ops = {
@@ -2964,27 +2888,9 @@ static u32 slic_card_locate(struct adapter *adapter)
struct sliccard *card = slic_global.slic_card;
struct physcard *physcard = slic_global.phys_card;
ushort card_hostid;
- u16 __iomem *hostid_reg;
uint i;
- uint rdhostid_offset = 0;
-
- switch (adapter->devid) {
- case SLIC_2GB_DEVICE_ID:
- rdhostid_offset = SLIC_RDHOSTID_2GB;
- break;
- case SLIC_1GB_DEVICE_ID:
- rdhostid_offset = SLIC_RDHOSTID_1GB;
- break;
- default:
- return -ENODEV;
- }
- hostid_reg =
- (u16 __iomem *)(((u8 __iomem *)(adapter->slic_regs)) +
- rdhostid_offset);
-
- /* read the 16 bit hostid from SRAM */
- card_hostid = (ushort)readw(hostid_reg);
+ card_hostid = slic_read32(adapter, SLIC_REG_HOSTID);
/* Initialize a new card structure if need be */
if (card_hostid == SLIC_HOSTID_DEFAULT) {
@@ -3130,7 +3036,7 @@ static int slic_entry_probe(struct pci_dev *pcidev,
mmio_start = pci_resource_start(pcidev, 0);
mmio_len = pci_resource_len(pcidev, 0);
- memmapped_ioaddr = ioremap(mmio_start, mmio_len);
+ memmapped_ioaddr = ioremap_nocache(mmio_start, mmio_len);
if (!memmapped_ioaddr) {
dev_err(&pcidev->dev, "cannot remap MMIO region %lx @ %lx\n",
mmio_len, mmio_start);
@@ -3142,13 +3048,17 @@ static int slic_entry_probe(struct pci_dev *pcidev,
slic_init_driver();
- slic_init_adapter(netdev,
- pcidev, pci_tbl_entry, memmapped_ioaddr, cards_found);
+ err = slic_init_adapter(netdev, pcidev, pci_tbl_entry, memmapped_ioaddr,
+ cards_found);
+ if (err) {
+ dev_err(&pcidev->dev, "failed to init adapter: %i\n", err);
+ goto err_out_unmap;
+ }
err = slic_card_locate(adapter);
if (err) {
dev_err(&pcidev->dev, "cannot locate card\n");
- goto err_out_unmap;
+ goto err_clean_init;
}
card = adapter->card;
@@ -3160,7 +3070,7 @@ static int slic_entry_probe(struct pci_dev *pcidev,
err = slic_card_init(card, adapter);
if (err)
- goto err_out_unmap;
+ goto err_clean_init;
slic_adapter_set_hwaddr(adapter);
@@ -3168,17 +3078,21 @@ static int slic_entry_probe(struct pci_dev *pcidev,
netdev->irq = adapter->irq;
netdev->netdev_ops = &slic_netdev_ops;
+ netif_carrier_off(netdev);
+
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err) {
dev_err(&pcidev->dev, "Cannot register net device, aborting.\n");
- goto err_out_unmap;
+ goto err_clean_init;
}
cards_found++;
return 0;
+err_clean_init:
+ slic_init_cleanup(adapter);
err_out_unmap:
iounmap(memmapped_ioaddr);
err_out_free_netdev:
@@ -3209,7 +3123,7 @@ static void __exit slic_module_cleanup(void)
pci_unregister_driver(&slic_driver);
}
-static struct ethtool_ops slic_ethtool_ops = {
+static const struct ethtool_ops slic_ethtool_ops = {
.get_coalesce = slic_get_coalesce,
.set_coalesce = slic_set_coalesce
};
diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c
index f80ee776677f..839d6730bde9 100644
--- a/drivers/staging/sm750fb/ddk750_chip.c
+++ b/drivers/staging/sm750fb/ddk750_chip.c
@@ -6,11 +6,9 @@
#include "ddk750_chip.h"
#include "ddk750_power.h"
-/* n / d + 1 / 2 = (2n + d) / 2d */
-#define roundedDiv(num, denom) ((2 * (num) + (denom)) / (2 * (denom)))
#define MHz(x) ((x) * 1000000)
-logical_chip_type_t getChipType(void)
+logical_chip_type_t sm750_get_chip_type(void)
{
unsigned short physicalID;
char physicalRev;
@@ -37,7 +35,7 @@ static unsigned int get_mxclk_freq(void)
unsigned int pll_reg;
unsigned int M, N, OD, POD;
- if (getChipType() == SM750LE)
+ if (sm750_get_chip_type() == SM750LE)
return MHz(130);
pll_reg = PEEK32(MXCLK_PLL_CTRL);
@@ -60,7 +58,7 @@ static void setChipClock(unsigned int frequency)
unsigned int ulActualMxClk;
/* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */
- if (getChipType() == SM750LE)
+ if (sm750_get_chip_type() == SM750LE)
return;
if (frequency) {
@@ -71,9 +69,10 @@ static void setChipClock(unsigned int frequency)
pll.clockType = MXCLK_PLL;
/*
- * Call calcPllValue() to fill up the other fields for PLL structure.
- * Sometime, the chip cannot set up the exact clock required by User.
- * Return value from calcPllValue() gives the actual possible clock.
+ * Call calcPllValue() to fill the other fields of PLL structure.
+ * Sometime, the chip cannot set up the exact clock
+ * required by the User.
+ * Return value of calcPllValue gives the actual possible clock.
*/
ulActualMxClk = calcPllValue(frequency, &pll);
@@ -86,18 +85,22 @@ static void setMemoryClock(unsigned int frequency)
{
unsigned int reg, divisor;
- /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */
- if (getChipType() == SM750LE)
+ /* Cheok_0509: For SM750LE, the memory clock is fixed.
+ * Nothing to set.
+ */
+ if (sm750_get_chip_type() == SM750LE)
return;
if (frequency) {
- /* Set the frequency to the maximum frequency that the DDR Memory can take
- which is 336MHz. */
+ /*
+ * Set the frequency to the maximum frequency
+ * that the DDR Memory can take which is 336MHz.
+ */
if (frequency > MHz(336))
frequency = MHz(336);
/* Calculate the divisor */
- divisor = roundedDiv(get_mxclk_freq(), frequency);
+ divisor = DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency);
/* Set the corresponding divisor in the register. */
reg = PEEK32(CURRENT_GATE) & ~CURRENT_GATE_M2XCLK_MASK;
@@ -133,18 +136,21 @@ static void setMasterClock(unsigned int frequency)
{
unsigned int reg, divisor;
- /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */
- if (getChipType() == SM750LE)
+ /* Cheok_0509: For SM750LE, the memory clock is fixed.
+ * Nothing to set.
+ */
+ if (sm750_get_chip_type() == SM750LE)
return;
if (frequency) {
- /* Set the frequency to the maximum frequency that the SM750 engine can
- run, which is about 190 MHz. */
+ /* Set the frequency to the maximum frequency
+ * that the SM750 engine can run, which is about 190 MHz.
+ */
if (frequency > MHz(190))
frequency = MHz(190);
/* Calculate the divisor */
- divisor = roundedDiv(get_mxclk_freq(), frequency);
+ divisor = DIV_ROUND_CLOSEST(get_mxclk_freq(), frequency);
/* Set the corresponding divisor in the register. */
reg = PEEK32(CURRENT_GATE) & ~CURRENT_GATE_MCLK_MASK;
@@ -174,7 +180,7 @@ unsigned int ddk750_getVMSize(void)
unsigned int data;
/* sm750le only use 64 mb memory*/
- if (getChipType() == SM750LE)
+ if (sm750_get_chip_type() == SM750LE)
return SZ_64M;
/* for 750,always use power mode0*/
@@ -213,7 +219,7 @@ int ddk750_initHw(initchip_param_t *pInitParam)
reg |= (CURRENT_GATE_DISPLAY | CURRENT_GATE_LOCALMEM);
setCurrentGate(reg);
- if (getChipType() != SM750LE) {
+ if (sm750_get_chip_type() != SM750LE) {
/* set panel pll and graphic mode via mmio_88 */
reg = PEEK32(VGA_CONFIGURATION);
reg |= (VGA_CONFIGURATION_PLL | VGA_CONFIGURATION_MODE);
@@ -236,9 +242,10 @@ int ddk750_initHw(initchip_param_t *pInitParam)
setMasterClock(MHz(pInitParam->masterClock));
- /* Reset the memory controller. If the memory controller is not reset in SM750,
- the system might hang when sw accesses the memory.
- The memory should be resetted after changing the MXCLK.
+ /* Reset the memory controller.
+ * If the memory controller is not reset in SM750,
+ * the system might hang when sw accesses the memory.
+ * The memory should be resetted after changing the MXCLK.
*/
if (pInitParam->resetMemory == 1) {
reg = PEEK32(MISC_CTRL);
@@ -282,24 +289,27 @@ int ddk750_initHw(initchip_param_t *pInitParam)
}
/*
- monk liu @ 4/6/2011:
- re-write the calculatePLL function of ddk750.
- the original version function does not use some mathematics tricks and shortcut
- when it doing the calculation of the best N,M,D combination
- I think this version gives a little upgrade in speed
-
- 750 pll clock formular:
- Request Clock = (Input Clock * M )/(N * X)
-
- Input Clock = 14318181 hz
- X = 2 power D
- D ={0,1,2,3,4,5,6}
- M = {1,...,255}
- N = {2,...,15}
-*/
+ * monk liu @ 4/6/2011:
+ * re-write the calculatePLL function of ddk750.
+ * the original version function does not use
+ * some mathematics tricks and shortcut
+ * when it doing the calculation of the best N,M,D combination
+ * I think this version gives a little upgrade in speed
+ *
+ * 750 pll clock formular:
+ * Request Clock = (Input Clock * M )/(N * X)
+ *
+ * Input Clock = 14318181 hz
+ * X = 2 power D
+ * D ={0,1,2,3,4,5,6}
+ * M = {1,...,255}
+ * N = {2,...,15}
+ */
unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll)
{
- /* as sm750 register definition, N located in 2,15 and M located in 1,255 */
+ /* as sm750 register definition,
+ * N located in 2,15 and M located in 1,255
+ */
int N, M, X, d;
int mini_diff;
unsigned int RN, quo, rem, fl_quo;
@@ -308,9 +318,11 @@ unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll)
const int max_OD = 3;
int max_d = 6;
- if (getChipType() == SM750LE) {
- /* SM750LE don't have prgrammable PLL and M/N values to work on.
- Just return the requested clock. */
+ if (sm750_get_chip_type() == SM750LE) {
+ /* SM750LE don't have
+ * programmable PLL and M/N values to work on.
+ * Just return the requested clock.
+ */
return request_orig;
}
@@ -319,19 +331,23 @@ unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll)
request = request_orig / 1000;
input = pll->inputFreq / 1000;
- /* for MXCLK register , no POD provided, so need be treated differently */
+ /* for MXCLK register,
+ * no POD provided, so need be treated differently
+ */
if (pll->clockType == MXCLK_PLL)
max_d = 3;
for (N = 15; N > 1; N--) {
- /* RN will not exceed maximum long if @request <= 285 MHZ (for 32bit cpu) */
+ /* RN will not exceed maximum long
+ * if @request <= 285 MHZ (for 32bit cpu)
+ */
RN = N * request;
quo = RN / input;
rem = RN % input;/* rem always small than 14318181 */
fl_quo = (rem * 10000 / input);
for (d = max_d; d >= 0; d--) {
- X = (1 << d);
+ X = BIT(d);
M = quo * X;
M += fl_quo * X / 10000;
/* round step */
diff --git a/drivers/staging/sm750fb/ddk750_chip.h b/drivers/staging/sm750fb/ddk750_chip.h
index 0891384ef3e5..14357fd1cc6b 100644
--- a/drivers/staging/sm750fb/ddk750_chip.h
+++ b/drivers/staging/sm750fb/ddk750_chip.h
@@ -69,7 +69,7 @@ typedef struct _initchip_param_t {
}
initchip_param_t;
-logical_chip_type_t getChipType(void);
+logical_chip_type_t sm750_get_chip_type(void);
unsigned int calcPllValue(unsigned int request, pll_value_t *pll);
unsigned int formatPllReg(pll_value_t *pPLL);
void ddk750_set_mmio(void __iomem *, unsigned short, char);
diff --git a/drivers/staging/sm750fb/ddk750_display.c b/drivers/staging/sm750fb/ddk750_display.c
index ca4973ee49e4..4023c476b9e4 100644
--- a/drivers/staging/sm750fb/ddk750_display.c
+++ b/drivers/staging/sm750fb/ddk750_display.c
@@ -68,8 +68,10 @@ static void waitNextVerticalSync(int ctrl, int delay)
if (!ctrl) {
/* primary controller */
- /* Do not wait when the Primary PLL is off or display control is already off.
- This will prevent the software to wait forever. */
+ /*
+ * Do not wait when the Primary PLL is off or display control is
+ * already off. This will prevent the software to wait forever.
+ */
if (!(PEEK32(PANEL_PLL_CTRL) & PLL_CTRL_POWER) ||
!(PEEK32(PANEL_DISPLAY_CTRL) & DISPLAY_CTRL_TIMING)) {
return;
@@ -88,9 +90,10 @@ static void waitNextVerticalSync(int ctrl, int delay)
}
} else {
-
- /* Do not wait when the Primary PLL is off or display control is already off.
- This will prevent the software to wait forever. */
+ /*
+ * Do not wait when the Primary PLL is off or display control is
+ * already off. This will prevent the software to wait forever.
+ */
if (!(PEEK32(CRT_PLL_CTRL) & PLL_CTRL_POWER) ||
!(PEEK32(CRT_DISPLAY_CTRL) & DISPLAY_CTRL_TIMING)) {
return;
@@ -134,7 +137,6 @@ static void swPanelPowerSequence(int disp, int delay)
reg |= (disp ? PANEL_DISPLAY_CTRL_FPEN : 0);
POKE32(PANEL_DISPLAY_CTRL, reg);
primaryWaitVerticalSync(delay);
-
}
void ddk750_setLogicalDispOut(disp_output_t output)
@@ -159,7 +161,6 @@ void ddk750_setLogicalDispOut(disp_output_t output)
/*se blank off */
reg &= ~CRT_DISPLAY_CTRL_BLANK;
POKE32(CRT_DISPLAY_CTRL, reg);
-
}
if (output & PRI_TP_USAGE) {
diff --git a/drivers/staging/sm750fb/ddk750_display.h b/drivers/staging/sm750fb/ddk750_display.h
index ca35aa1df9d7..e3fde428c52b 100644
--- a/drivers/staging/sm750fb/ddk750_display.h
+++ b/drivers/staging/sm750fb/ddk750_display.h
@@ -2,100 +2,98 @@
#define DDK750_DISPLAY_H__
/* panel path select
- 80000[29:28]
-*/
+ * 80000[29:28]
+ */
#define PNL_2_OFFSET 0
#define PNL_2_MASK (3 << PNL_2_OFFSET)
#define PNL_2_USAGE (PNL_2_MASK << 16)
-#define PNL_2_PRI ((0 << PNL_2_OFFSET)|PNL_2_USAGE)
-#define PNL_2_SEC ((2 << PNL_2_OFFSET)|PNL_2_USAGE)
+#define PNL_2_PRI ((0 << PNL_2_OFFSET) | PNL_2_USAGE)
+#define PNL_2_SEC ((2 << PNL_2_OFFSET) | PNL_2_USAGE)
/* primary timing & plane enable bit
- 1: 80000[8] & 80000[2] on
- 0: both off
-*/
+ * 1: 80000[8] & 80000[2] on
+ * 0: both off
+ */
#define PRI_TP_OFFSET 4
#define PRI_TP_MASK BIT(PRI_TP_OFFSET)
#define PRI_TP_USAGE (PRI_TP_MASK << 16)
-#define PRI_TP_ON ((0x1 << PRI_TP_OFFSET)|PRI_TP_USAGE)
-#define PRI_TP_OFF ((0x0 << PRI_TP_OFFSET)|PRI_TP_USAGE)
+#define PRI_TP_ON ((0x1 << PRI_TP_OFFSET) | PRI_TP_USAGE)
+#define PRI_TP_OFF ((0x0 << PRI_TP_OFFSET) | PRI_TP_USAGE)
/* panel sequency status
- 80000[27:24]
-*/
+ * 80000[27:24]
+ */
#define PNL_SEQ_OFFSET 6
#define PNL_SEQ_MASK BIT(PNL_SEQ_OFFSET)
#define PNL_SEQ_USAGE (PNL_SEQ_MASK << 16)
-#define PNL_SEQ_ON (BIT(PNL_SEQ_OFFSET)|PNL_SEQ_USAGE)
-#define PNL_SEQ_OFF ((0 << PNL_SEQ_OFFSET)|PNL_SEQ_USAGE)
+#define PNL_SEQ_ON (BIT(PNL_SEQ_OFFSET) | PNL_SEQ_USAGE)
+#define PNL_SEQ_OFF ((0 << PNL_SEQ_OFFSET) | PNL_SEQ_USAGE)
/* dual digital output
- 80000[19]
-*/
+ * 80000[19]
+ */
#define DUAL_TFT_OFFSET 8
#define DUAL_TFT_MASK BIT(DUAL_TFT_OFFSET)
#define DUAL_TFT_USAGE (DUAL_TFT_MASK << 16)
-#define DUAL_TFT_ON (BIT(DUAL_TFT_OFFSET)|DUAL_TFT_USAGE)
-#define DUAL_TFT_OFF ((0 << DUAL_TFT_OFFSET)|DUAL_TFT_USAGE)
+#define DUAL_TFT_ON (BIT(DUAL_TFT_OFFSET) | DUAL_TFT_USAGE)
+#define DUAL_TFT_OFF ((0 << DUAL_TFT_OFFSET) | DUAL_TFT_USAGE)
/* secondary timing & plane enable bit
- 1:80200[8] & 80200[2] on
- 0: both off
-*/
+ * 1:80200[8] & 80200[2] on
+ * 0: both off
+ */
#define SEC_TP_OFFSET 5
#define SEC_TP_MASK BIT(SEC_TP_OFFSET)
#define SEC_TP_USAGE (SEC_TP_MASK << 16)
-#define SEC_TP_ON ((0x1 << SEC_TP_OFFSET)|SEC_TP_USAGE)
-#define SEC_TP_OFF ((0x0 << SEC_TP_OFFSET)|SEC_TP_USAGE)
+#define SEC_TP_ON ((0x1 << SEC_TP_OFFSET) | SEC_TP_USAGE)
+#define SEC_TP_OFF ((0x0 << SEC_TP_OFFSET) | SEC_TP_USAGE)
/* crt path select
- 80200[19:18]
-*/
+ * 80200[19:18]
+ */
#define CRT_2_OFFSET 2
#define CRT_2_MASK (3 << CRT_2_OFFSET)
#define CRT_2_USAGE (CRT_2_MASK << 16)
-#define CRT_2_PRI ((0x0 << CRT_2_OFFSET)|CRT_2_USAGE)
-#define CRT_2_SEC ((0x2 << CRT_2_OFFSET)|CRT_2_USAGE)
+#define CRT_2_PRI ((0x0 << CRT_2_OFFSET) | CRT_2_USAGE)
+#define CRT_2_SEC ((0x2 << CRT_2_OFFSET) | CRT_2_USAGE)
/* DAC affect both DVI and DSUB
- 4[20]
-*/
+ * 4[20]
+ */
#define DAC_OFFSET 7
#define DAC_MASK BIT(DAC_OFFSET)
#define DAC_USAGE (DAC_MASK << 16)
-#define DAC_ON ((0x0 << DAC_OFFSET)|DAC_USAGE)
-#define DAC_OFF ((0x1 << DAC_OFFSET)|DAC_USAGE)
+#define DAC_ON ((0x0 << DAC_OFFSET) | DAC_USAGE)
+#define DAC_OFF ((0x1 << DAC_OFFSET) | DAC_USAGE)
/* DPMS only affect D-SUB head
- 0[31:30]
-*/
+ * 0[31:30]
+ */
#define DPMS_OFFSET 9
#define DPMS_MASK (3 << DPMS_OFFSET)
#define DPMS_USAGE (DPMS_MASK << 16)
-#define DPMS_OFF ((3 << DPMS_OFFSET)|DPMS_USAGE)
-#define DPMS_ON ((0 << DPMS_OFFSET)|DPMS_USAGE)
+#define DPMS_OFF ((3 << DPMS_OFFSET) | DPMS_USAGE)
+#define DPMS_ON ((0 << DPMS_OFFSET) | DPMS_USAGE)
-/*
- LCD1 means panel path TFT1 & panel path DVI (so enable DAC)
- CRT means crt path DSUB
-*/
+/* LCD1 means panel path TFT1 & panel path DVI (so enable DAC)
+ * CRT means crt path DSUB
+ */
typedef enum _disp_output_t {
- do_LCD1_PRI = PNL_2_PRI|PRI_TP_ON|PNL_SEQ_ON|DAC_ON,
- do_LCD1_SEC = PNL_2_SEC|SEC_TP_ON|PNL_SEQ_ON|DAC_ON,
- do_LCD2_PRI = CRT_2_PRI|PRI_TP_ON|DUAL_TFT_ON,
- do_LCD2_SEC = CRT_2_SEC|SEC_TP_ON|DUAL_TFT_ON,
- /*
- do_DSUB_PRI = CRT_2_PRI|PRI_TP_ON|DPMS_ON|DAC_ON,
- do_DSUB_SEC = CRT_2_SEC|SEC_TP_ON|DPMS_ON|DAC_ON,
- */
- do_CRT_PRI = CRT_2_PRI|PRI_TP_ON|DPMS_ON|DAC_ON,
- do_CRT_SEC = CRT_2_SEC|SEC_TP_ON|DPMS_ON|DAC_ON,
+ do_LCD1_PRI = PNL_2_PRI | PRI_TP_ON | PNL_SEQ_ON | DAC_ON,
+ do_LCD1_SEC = PNL_2_SEC | SEC_TP_ON | PNL_SEQ_ON | DAC_ON,
+ do_LCD2_PRI = CRT_2_PRI | PRI_TP_ON | DUAL_TFT_ON,
+ do_LCD2_SEC = CRT_2_SEC | SEC_TP_ON | DUAL_TFT_ON,
+ /* do_DSUB_PRI = CRT_2_PRI | PRI_TP_ON | DPMS_ON|DAC_ON,
+ * do_DSUB_SEC = CRT_2_SEC | SEC_TP_ON | DPMS_ON|DAC_ON,
+ */
+ do_CRT_PRI = CRT_2_PRI | PRI_TP_ON | DPMS_ON | DAC_ON,
+ do_CRT_SEC = CRT_2_SEC | SEC_TP_ON | DPMS_ON | DAC_ON,
}
disp_output_t;
diff --git a/drivers/staging/sm750fb/ddk750_dvi.c b/drivers/staging/sm750fb/ddk750_dvi.c
index a4a255007c8d..8252f771ef9e 100644
--- a/drivers/staging/sm750fb/ddk750_dvi.c
+++ b/drivers/staging/sm750fb/ddk750_dvi.c
@@ -6,9 +6,11 @@
#include "ddk750_sii164.h"
-/* This global variable contains all the supported driver and its corresponding
- function API. Please set the function pointer to NULL whenever the function
- is not supported. */
+/*
+ * This global variable contains all the supported driver and its corresponding
+ * function API. Please set the function pointer to NULL whenever the function
+ * is not supported.
+ */
static dvi_ctrl_device_t g_dcftSupportedDviController[] = {
#ifdef DVI_CTRL_SII164
{
diff --git a/drivers/staging/sm750fb/ddk750_hwi2c.c b/drivers/staging/sm750fb/ddk750_hwi2c.c
index 39c3e1cdbc0c..d391c127ead7 100644
--- a/drivers/staging/sm750fb/ddk750_hwi2c.c
+++ b/drivers/staging/sm750fb/ddk750_hwi2c.c
@@ -21,7 +21,7 @@ unsigned char bus_speed_mode
POKE32(GPIO_MUX, value);
/* Enable Hardware I2C power.
- TODO: Check if we need to enable GPIO power?
+ * TODO: Check if we need to enable GPIO power?
*/
enableI2C(1);
diff --git a/drivers/staging/sm750fb/ddk750_mode.c b/drivers/staging/sm750fb/ddk750_mode.c
index ccb4e067661a..05b83646c2d5 100644
--- a/drivers/staging/sm750fb/ddk750_mode.c
+++ b/drivers/staging/sm750fb/ddk750_mode.c
@@ -4,15 +4,14 @@
#include "ddk750_mode.h"
#include "ddk750_chip.h"
-/*
- SM750LE only:
- This function takes care extra registers and bit fields required to set
- up a mode in SM750LE
-
- Explanation about Display Control register:
- HW only supports 7 predefined pixel clocks, and clock select is
- in bit 29:27 of Display Control register.
-*/
+/* SM750LE only:
+ * This function takes care extra registers and bit fields required to set
+ * up a mode in SM750LE
+ *
+ * Explanation about Display Control register:
+ * HW only supports 7 predefined pixel clocks, and clock select is
+ * in bit 29:27 of Display Control register.
+ */
static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, unsigned long dispControl)
{
unsigned long x, y;
@@ -21,9 +20,9 @@ static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam,
y = pModeParam->vertical_display_end;
/* SM750LE has to set up the top-left and bottom-right
- registers as well.
- Note that normal SM750/SM718 only use those two register for
- auto-centering mode.
+ * registers as well.
+ * Note that normal SM750/SM718 only use those two register for
+ * auto-centering mode.
*/
POKE32(CRT_AUTO_CENTERING_TL, 0);
@@ -33,8 +32,8 @@ static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam,
((x - 1) & CRT_AUTO_CENTERING_BR_RIGHT_MASK));
/* Assume common fields in dispControl have been properly set before
- calling this function.
- This function only sets the extra fields in dispControl.
+ * calling this function.
+ * This function only sets the extra fields in dispControl.
*/
/* Clear bit 29:27 of display control register */
@@ -63,7 +62,7 @@ static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam,
dispControl |= (CRT_DISPLAY_CTRL_CRTSELECT | CRT_DISPLAY_CTRL_RGBBIT);
/* Set bit 14 of display controller */
- dispControl = DISPLAY_CTRL_CLOCK_PHASE;
+ dispControl |= DISPLAY_CTRL_CLOCK_PHASE;
POKE32(CRT_DISPLAY_CTRL, dispControl);
@@ -117,7 +116,7 @@ static int programModeRegisters(mode_parameter_t *pModeParam, pll_value_t *pll)
if (pModeParam->horizontal_sync_polarity)
tmp |= DISPLAY_CTRL_HSYNC_PHASE;
- if (getChipType() == SM750LE) {
+ if (sm750_get_chip_type() == SM750LE) {
displayControlAdjust_SM750LE(pModeParam, tmp);
} else {
reg = PEEK32(CRT_DISPLAY_CTRL) &
@@ -209,7 +208,7 @@ int ddk750_setModeTiming(mode_parameter_t *parm, clock_type_t clock)
pll.clockType = clock;
uiActualPixelClk = calcPllValue(parm->pixel_clock, &pll);
- if (getChipType() == SM750LE) {
+ if (sm750_get_chip_type() == SM750LE) {
/* set graphic mode via IO method */
outb_p(0x88, 0x3d4);
outb_p(0x06, 0x3d5);
diff --git a/drivers/staging/sm750fb/ddk750_power.c b/drivers/staging/sm750fb/ddk750_power.c
index b3c3791b95bd..7cc6169f884e 100644
--- a/drivers/staging/sm750fb/ddk750_power.c
+++ b/drivers/staging/sm750fb/ddk750_power.c
@@ -6,7 +6,7 @@ void ddk750_setDPMS(DPMS_t state)
{
unsigned int value;
- if (getChipType() == SM750LE) {
+ if (sm750_get_chip_type() == SM750LE) {
value = PEEK32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_DPMS_MASK;
value |= (state << CRT_DISPLAY_CTRL_DPMS_SHIFT);
POKE32(CRT_DISPLAY_CTRL, value);
@@ -19,7 +19,7 @@ void ddk750_setDPMS(DPMS_t state)
static unsigned int getPowerMode(void)
{
- if (getChipType() == SM750LE)
+ if (sm750_get_chip_type() == SM750LE)
return 0;
return PEEK32(POWER_MODE_CTRL) & POWER_MODE_CTRL_MODE_MASK;
}
@@ -35,7 +35,7 @@ void setPowerMode(unsigned int powerMode)
control_value = PEEK32(POWER_MODE_CTRL) & ~POWER_MODE_CTRL_MODE_MASK;
- if (getChipType() == SM750LE)
+ if (sm750_get_chip_type() == SM750LE)
return;
switch (powerMode) {
diff --git a/drivers/staging/sm750fb/ddk750_sii164.c b/drivers/staging/sm750fb/ddk750_sii164.c
index 67f36e71da7e..99a8683e6383 100644
--- a/drivers/staging/sm750fb/ddk750_sii164.c
+++ b/drivers/staging/sm750fb/ddk750_sii164.c
@@ -174,8 +174,8 @@ long sii164InitChip(
i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
/* De-skew enabled with default 111b value.
- This will fix some artifacts problem in some mode on board 2.2.
- Somehow this fix does not affect board 2.1.
+ * This fixes some artifacts problem in some mode on board 2.2.
+ * Somehow this fix does not affect board 2.1.
*/
if (deskewEnable == 0)
config = SII164_DESKEW_DISABLE;
@@ -344,7 +344,8 @@ void sii164EnableHotPlugDetection(
detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
/* Depending on each DVI controller, need to enable the hot plug based on each
- individual chip design. */
+ * individual chip design.
+ */
if (enableHotPlug != 0)
sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI);
else
diff --git a/drivers/staging/sm750fb/ddk750_swi2c.c b/drivers/staging/sm750fb/ddk750_swi2c.c
index 8d644a7cba52..72a42330e7a1 100644
--- a/drivers/staging/sm750fb/ddk750_swi2c.c
+++ b/drivers/staging/sm750fb/ddk750_swi2c.c
@@ -89,12 +89,12 @@ static void sw_i2c_wait(void)
* always be non-zero,which makes the while loop
* never finish.
* use non-ultimate for loop below is safe
- * */
+ */
/* Change wait algorithm to use PCI bus clock,
- it's more reliable than counter loop ..
- write 0x61 to 0x3ce and read from 0x3cf
- */
+ * it's more reliable than counter loop ..
+ * write 0x61 to 0x3ce and read from 0x3cf
+ */
int i, tmp;
for (i = 0; i < 600; i++) {
@@ -403,7 +403,7 @@ long sm750_sw_i2c_init(
if ((clk_gpio > 31) || (data_gpio > 31))
return -1;
- if (getChipType() == SM750LE)
+ if (sm750_get_chip_type() == SM750LE)
return sm750le_i2c_init(clk_gpio, data_gpio);
/* Initialize the GPIO pin for the i2c Clock Register */
@@ -501,8 +501,8 @@ long sm750_sw_i2c_write_reg(
sw_i2c_start();
/* Send the device address and read the data. All should return success
- in order for the writing processed to be successful
- */
+ * in order for the writing processed to be successful
+ */
if ((sw_i2c_write_byte(addr) != 0) ||
(sw_i2c_write_byte(reg) != 0) ||
(sw_i2c_write_byte(data) != 0)) {
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 6ed004e40855..7d90e250142c 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -1176,7 +1176,7 @@ static int __init lynxfb_setup(char *options)
else {
strcat(tmp, opt);
tmp += strlen(opt);
- if (options != NULL)
+ if (options)
*tmp++ = ':';
else
*tmp++ = 0;
diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h
index 8e70ce0d6da4..ff31c5c9cc6f 100644
--- a/drivers/staging/sm750fb/sm750.h
+++ b/drivers/staging/sm750fb/sm750.h
@@ -147,17 +147,17 @@ struct lynxfb_output {
int dpms;
int paths;
/* which paths(s) this output stands for,for sm750:
- paths=1:means output for panel paths
- paths=2:means output for crt paths
- paths=3:means output for both panel and crt paths
- */
+ * paths=1:means output for panel paths
+ * paths=2:means output for crt paths
+ * paths=3:means output for both panel and crt paths
+ */
int *channel;
/* which channel these outputs linked with,for sm750:
- *channel=0 means primary channel
- *channel=1 means secondary channel
- output->channel ==> &crtc->channel
- */
+ * *channel=0 means primary channel
+ * *channel=1 means secondary channel
+ * output->channel ==> &crtc->channel
+ */
void *priv;
int (*proc_setBLANK)(struct lynxfb_output*, int);
diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c
index 9aa4066ac86d..38adae6b5d83 100644
--- a/drivers/staging/sm750fb/sm750_accel.c
+++ b/drivers/staging/sm750fb/sm750_accel.c
@@ -67,7 +67,8 @@ void hw_de_init(struct lynx_accel *accel)
/* set2dformat only be called from setmode functions
* but if you need dual framebuffer driver,need call set2dformat
- * every time you use 2d function */
+ * every time you use 2d function
+ */
void hw_set2dformat(struct lynx_accel *accel, int fmt)
{
@@ -90,7 +91,8 @@ int hw_fillrect(struct lynx_accel *accel,
if (accel->de_wait() != 0) {
/* int time wait and always busy,seems hardware
- * got something error */
+ * got something error
+ */
pr_debug("De engine always busy\n");
return -1;
}
@@ -152,24 +154,26 @@ unsigned int rop2) /* ROP value */
/* Determine direction of operation */
if (sy < dy) {
/* +----------+
- |S |
- | +----------+
- | | | |
- | | | |
- +---|------+ |
- | D|
- +----------+ */
+ * |S |
+ * | +----------+
+ * | | | |
+ * | | | |
+ * +---|------+ |
+ * | D|
+ * +----------+
+ */
nDirection = BOTTOM_TO_TOP;
} else if (sy > dy) {
/* +----------+
- |D |
- | +----------+
- | | | |
- | | | |
- +---|------+ |
- | S|
- +----------+ */
+ * |D |
+ * | +----------+
+ * | | | |
+ * | | | |
+ * +---|------+ |
+ * | S|
+ * +----------+
+ */
nDirection = TOP_TO_BOTTOM;
} else {
@@ -177,22 +181,24 @@ unsigned int rop2) /* ROP value */
if (sx <= dx) {
/* +------+---+------+
- |S | | D|
- | | | |
- | | | |
- | | | |
- +------+---+------+ */
+ * |S | | D|
+ * | | | |
+ * | | | |
+ * | | | |
+ * +------+---+------+
+ */
nDirection = RIGHT_TO_LEFT;
} else {
/* sx > dx */
/* +------+---+------+
- |D | | S|
- | | | |
- | | | |
- | | | |
- +------+---+------+ */
+ * |D | | S|
+ * | | | |
+ * | | | |
+ * | | | |
+ * +------+---+------+
+ */
nDirection = LEFT_TO_RIGHT;
}
@@ -208,32 +214,36 @@ unsigned int rop2) /* ROP value */
}
/* Note:
- DE_FOREGROUND are DE_BACKGROUND are don't care.
- DE_COLOR_COMPARE and DE_COLOR_COMPARE_MAKS are set by set deSetTransparency().
+ * DE_FOREGROUND are DE_BACKGROUND are don't care.
+ * DE_COLOR_COMPARE and DE_COLOR_COMPARE_MAKS
+ * are set by set deSetTransparency().
*/
/* 2D Source Base.
- It is an address offset (128 bit aligned) from the beginning of frame buffer.
+ * It is an address offset (128 bit aligned)
+ * from the beginning of frame buffer.
*/
write_dpr(accel, DE_WINDOW_SOURCE_BASE, sBase); /* dpr40 */
/* 2D Destination Base.
- It is an address offset (128 bit aligned) from the beginning of frame buffer.
+ * It is an address offset (128 bit aligned)
+ * from the beginning of frame buffer.
*/
write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase); /* dpr44 */
/* Program pitch (distance between the 1st points of two adjacent lines).
- Note that input pitch is BYTE value, but the 2D Pitch register uses
- pixel values. Need Byte to pixel conversion.
- */
+ * Note that input pitch is BYTE value, but the 2D Pitch register uses
+ * pixel values. Need Byte to pixel conversion.
+ */
write_dpr(accel, DE_PITCH,
((dPitch / Bpp << DE_PITCH_DESTINATION_SHIFT) &
DE_PITCH_DESTINATION_MASK) |
(sPitch / Bpp & DE_PITCH_SOURCE_MASK)); /* dpr10 */
/* Screen Window width in Pixels.
- 2D engine uses this value to calculate the linear address in frame buffer for a given point.
- */
+ * 2D engine uses this value to calculate the linear address in frame buffer
+ * for a given point.
+ */
write_dpr(accel, DE_WINDOW_WIDTH,
((dPitch / Bpp << DE_WINDOW_WIDTH_DST_SHIFT) &
DE_WINDOW_WIDTH_DST_MASK) |
@@ -307,33 +317,37 @@ int hw_imageblit(struct lynx_accel *accel,
return -1;
/* 2D Source Base.
- Use 0 for HOST Blt.
+ * Use 0 for HOST Blt.
*/
write_dpr(accel, DE_WINDOW_SOURCE_BASE, 0);
/* 2D Destination Base.
- It is an address offset (128 bit aligned) from the beginning of frame buffer.
+ * It is an address offset (128 bit aligned)
+ * from the beginning of frame buffer.
*/
write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase);
/* Program pitch (distance between the 1st points of two adjacent lines).
- Note that input pitch is BYTE value, but the 2D Pitch register uses
- pixel values. Need Byte to pixel conversion.
- */
+ * Note that input pitch is BYTE value, but the 2D Pitch register uses
+ * pixel values. Need Byte to pixel conversion.
+ */
write_dpr(accel, DE_PITCH,
((dPitch / bytePerPixel << DE_PITCH_DESTINATION_SHIFT) &
DE_PITCH_DESTINATION_MASK) |
(dPitch / bytePerPixel & DE_PITCH_SOURCE_MASK)); /* dpr10 */
/* Screen Window width in Pixels.
- 2D engine uses this value to calculate the linear address in frame buffer for a given point.
+ * 2D engine uses this value to calculate the linear address
+ * in frame buffer for a given point.
*/
write_dpr(accel, DE_WINDOW_WIDTH,
((dPitch / bytePerPixel << DE_WINDOW_WIDTH_DST_SHIFT) &
DE_WINDOW_WIDTH_DST_MASK) |
(dPitch / bytePerPixel & DE_WINDOW_WIDTH_SRC_MASK));
- /* Note: For 2D Source in Host Write, only X_K1_MONO field is needed, and Y_K2 field is not used.
- For mono bitmap, use startBit for X_K1. */
+ /* Note: For 2D Source in Host Write, only X_K1_MONO field is needed,
+ * and Y_K2 field is not used.
+ * For mono bitmap, use startBit for X_K1.
+ */
write_dpr(accel, DE_SOURCE,
(startBit << DE_SOURCE_X_K1_SHIFT) &
DE_SOURCE_X_K1_MONO_MASK); /* dpr00 */
diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c
index 2daeedd88c30..7dd208caa5eb 100644
--- a/drivers/staging/sm750fb/sm750_hw.c
+++ b/drivers/staging/sm750fb/sm750_hw.c
@@ -35,17 +35,17 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
pr_info("mmio phyAddr = %lx\n", sm750_dev->vidreg_start);
/* reserve the vidreg space of smi adaptor
- * if you do this, u need to add release region code
+ * if you do this, you need to add release region code
* in lynxfb_remove, or memory will not be mapped again
* successfully
- * */
+ */
ret = pci_request_region(pdev, 1, "sm750fb");
if (ret) {
pr_err("Can not request PCI regions.\n");
goto exit;
}
- /* now map mmio and vidmem*/
+ /* now map mmio and vidmem */
sm750_dev->pvReg = ioremap_nocache(sm750_dev->vidreg_start,
sm750_dev->vidreg_size);
if (!sm750_dev->pvReg) {
@@ -56,7 +56,6 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
pr_info("mmio virtual addr = %p\n", sm750_dev->pvReg);
}
-
sm750_dev->accel.dprBase = sm750_dev->pvReg + DE_BASE_ADDR_TYPE1;
sm750_dev->accel.dpPortBase = sm750_dev->pvReg + DE_PORT_ADDR_TYPE1;
@@ -64,10 +63,10 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
sm750_dev->vidmem_start = pci_resource_start(pdev, 0);
/* don't use pdev_resource[x].end - resource[x].start to
- * calculate the resource size,its only the maximum available
- * size but not the actual size,use
+ * calculate the resource size, it's only the maximum available
+ * size but not the actual size, using
* @ddk750_getVMSize function can be safe.
- * */
+ */
sm750_dev->vidmem_size = ddk750_getVMSize();
pr_info("video memory phyAddr = %lx, size = %u bytes\n",
sm750_dev->vidmem_start, sm750_dev->vidmem_size);
@@ -86,33 +85,31 @@ exit:
return ret;
}
-
-
int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
{
struct init_status *parm;
parm = &sm750_dev->initParm;
if (parm->chip_clk == 0)
- parm->chip_clk = (getChipType() == SM750LE) ?
+ parm->chip_clk = (sm750_get_chip_type() == SM750LE) ?
DEFAULT_SM750LE_CHIP_CLOCK :
DEFAULT_SM750_CHIP_CLOCK;
if (parm->mem_clk == 0)
parm->mem_clk = parm->chip_clk;
if (parm->master_clk == 0)
- parm->master_clk = parm->chip_clk/3;
+ parm->master_clk = parm->chip_clk / 3;
ddk750_initHw((initchip_param_t *)&sm750_dev->initParm);
- /* for sm718,open pci burst */
+ /* for sm718, open pci burst */
if (sm750_dev->devid == 0x718) {
POKE32(SYSTEM_CTRL,
PEEK32(SYSTEM_CTRL) | SYSTEM_CTRL_PCI_BURST);
}
- if (getChipType() != SM750LE) {
+ if (sm750_get_chip_type() != SM750LE) {
unsigned int val;
- /* does user need CRT ?*/
+ /* does user need CRT? */
if (sm750_dev->nocrt) {
POKE32(MISC_CTRL,
PEEK32(MISC_CTRL) | MISC_CTRL_DAC_POWER_OFF);
@@ -144,19 +141,21 @@ int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
}
POKE32(PANEL_DISPLAY_CTRL, val);
} else {
- /* for 750LE ,no DVI chip initialization makes Monitor no signal */
- /* Set up GPIO for software I2C to program DVI chip in the
- Xilinx SP605 board, in order to have video signal.
+ /* for 750LE, no DVI chip initialization
+ * makes Monitor no signal
+ *
+ * Set up GPIO for software I2C to program DVI chip in the
+ * Xilinx SP605 board, in order to have video signal.
*/
sm750_sw_i2c_init(0, 1);
/* Customer may NOT use CH7301 DVI chip, which has to be
- initialized differently.
- */
+ * initialized differently.
+ */
if (sm750_sw_i2c_read_reg(0xec, 0x4a) == 0x95) {
/* The following register values for CH7301 are from
- Chrontel app note and our experiment.
- */
+ * Chrontel app note and our experiment.
+ */
pr_info("yes,CH7301 DVI chip found\n");
sm750_sw_i2c_write_reg(0xec, 0x1d, 0x16);
sm750_sw_i2c_write_reg(0xec, 0x21, 0x9);
@@ -173,7 +172,8 @@ int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
}
int hw_sm750_output_setMode(struct lynxfb_output *output,
- struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix)
+ struct fb_var_screeninfo *var,
+ struct fb_fix_screeninfo *fix)
{
int ret;
disp_output_t dispSet;
@@ -183,8 +183,7 @@ int hw_sm750_output_setMode(struct lynxfb_output *output,
dispSet = 0;
channel = *output->channel;
-
- if (getChipType() != SM750LE) {
+ if (sm750_get_chip_type() != SM750LE) {
if (channel == sm750_primary) {
pr_info("primary channel\n");
if (output->paths & sm750_panel)
@@ -198,11 +197,10 @@ int hw_sm750_output_setMode(struct lynxfb_output *output,
dispSet |= do_LCD1_SEC;
if (output->paths & sm750_crt)
dispSet |= do_CRT_SEC;
-
}
ddk750_setLogicalDispOut(dispSet);
} else {
- /* just open DISPLAY_CONTROL_750LE register bit 3:0*/
+ /* just open DISPLAY_CONTROL_750LE register bit 3:0 */
u32 reg;
reg = PEEK32(DISPLAY_CONTROL_750LE);
@@ -214,7 +212,8 @@ int hw_sm750_output_setMode(struct lynxfb_output *output,
return ret;
}
-int hw_sm750_crtc_checkMode(struct lynxfb_crtc *crtc, struct fb_var_screeninfo *var)
+int hw_sm750_crtc_checkMode(struct lynxfb_crtc *crtc,
+ struct fb_var_screeninfo *var)
{
struct sm750_dev *sm750_dev;
struct lynxfb_par *par = container_of(crtc, struct lynxfb_par, crtc);
@@ -233,19 +232,15 @@ int hw_sm750_crtc_checkMode(struct lynxfb_crtc *crtc, struct fb_var_screeninfo *
break;
default:
return -EINVAL;
-
}
return 0;
}
-
-/*
- set the controller's mode for @crtc charged with @var and @fix parameters
-*/
+/* set the controller's mode for @crtc charged with @var and @fix parameters */
int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc,
- struct fb_var_screeninfo *var,
- struct fb_fix_screeninfo *fix)
+ struct fb_var_screeninfo *var,
+ struct fb_fix_screeninfo *fix)
{
int ret, fmt;
u32 reg;
@@ -254,7 +249,6 @@ int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc,
struct sm750_dev *sm750_dev;
struct lynxfb_par *par;
-
ret = 0;
par = container_of(crtc, struct lynxfb_par, crtc);
sm750_dev = par->dev;
@@ -278,17 +272,22 @@ int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc,
/* set timing */
modparm.pixel_clock = ps_to_hz(var->pixclock);
- modparm.vertical_sync_polarity = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? POS:NEG;
- modparm.horizontal_sync_polarity = (var->sync & FB_SYNC_VERT_HIGH_ACT) ? POS:NEG;
- modparm.clock_phase_polarity = (var->sync & FB_SYNC_COMP_HIGH_ACT) ? POS:NEG;
+ modparm.vertical_sync_polarity = (var->sync & FB_SYNC_HOR_HIGH_ACT)
+ ? POS : NEG;
+ modparm.horizontal_sync_polarity = (var->sync & FB_SYNC_VERT_HIGH_ACT)
+ ? POS : NEG;
+ modparm.clock_phase_polarity = (var->sync & FB_SYNC_COMP_HIGH_ACT)
+ ? POS : NEG;
modparm.horizontal_display_end = var->xres;
modparm.horizontal_sync_width = var->hsync_len;
modparm.horizontal_sync_start = var->xres + var->right_margin;
- modparm.horizontal_total = var->xres + var->left_margin + var->right_margin + var->hsync_len;
+ modparm.horizontal_total = var->xres + var->left_margin +
+ var->right_margin + var->hsync_len;
modparm.vertical_display_end = var->yres;
modparm.vertical_sync_height = var->vsync_len;
modparm.vertical_sync_start = var->yres + var->lower_margin;
- modparm.vertical_total = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
+ modparm.vertical_total = var->yres + var->upper_margin +
+ var->lower_margin + var->vsync_len;
/* choose pll */
if (crtc->channel != sm750_secondary)
@@ -304,12 +303,14 @@ int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc,
}
if (crtc->channel != sm750_secondary) {
- /* set pitch, offset ,width,start address ,etc... */
+ /* set pitch, offset, width, start address, etc... */
POKE32(PANEL_FB_ADDRESS,
crtc->oScreen & PANEL_FB_ADDRESS_ADDRESS_MASK);
reg = var->xres * (var->bits_per_pixel >> 3);
- /* crtc->channel is not equal to par->index on numeric,be aware of that */
+ /* crtc->channel is not equal to par->index on numeric,
+ * be aware of that
+ */
reg = ALIGN(reg, crtc->line_pad);
reg = (reg << PANEL_FB_WIDTH_WIDTH_SHIFT) &
PANEL_FB_WIDTH_WIDTH_MASK;
@@ -321,8 +322,8 @@ int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc,
reg |= (var->xoffset & PANEL_WINDOW_WIDTH_X_MASK);
POKE32(PANEL_WINDOW_WIDTH, reg);
- reg = ((var->yres_virtual - 1) <<
- PANEL_WINDOW_HEIGHT_HEIGHT_SHIFT);
+ reg = (var->yres_virtual - 1) <<
+ PANEL_WINDOW_HEIGHT_HEIGHT_SHIFT;
reg &= PANEL_WINDOW_HEIGHT_HEIGHT_MASK;
reg |= (var->yoffset & PANEL_WINDOW_HEIGHT_Y_MASK);
POKE32(PANEL_WINDOW_HEIGHT, reg);
@@ -341,7 +342,9 @@ int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc,
/* not implemented now */
POKE32(CRT_FB_ADDRESS, crtc->oScreen);
reg = var->xres * (var->bits_per_pixel >> 3);
- /* crtc->channel is not equal to par->index on numeric,be aware of that */
+ /* crtc->channel is not equal to par->index on numeric,
+ * be aware of that
+ */
reg = ALIGN(reg, crtc->line_pad) << CRT_FB_WIDTH_WIDTH_SHIFT;
reg &= CRT_FB_WIDTH_WIDTH_MASK;
reg |= (fix->line_length & CRT_FB_WIDTH_OFFSET_MASK);
@@ -352,20 +355,19 @@ int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc,
reg |= ((var->bits_per_pixel >> 4) &
CRT_DISPLAY_CTRL_FORMAT_MASK);
POKE32(CRT_DISPLAY_CTRL, reg);
-
}
-
exit:
return ret;
}
int hw_sm750_setColReg(struct lynxfb_crtc *crtc, ushort index,
- ushort red, ushort green, ushort blue)
+ ushort red, ushort green, ushort blue)
{
static unsigned int add[] = {PANEL_PALETTE_RAM, CRT_PALETTE_RAM};
- POKE32(add[crtc->channel] + index*4, (red<<16)|(green<<8)|blue);
+ POKE32(add[crtc->channel] + index * 4,
+ (red << 16) | (green << 8) | blue);
return 0;
}
@@ -414,7 +416,9 @@ int hw_sm750_setBLANK(struct lynxfb_output *output, int blank)
{
unsigned int dpms, pps, crtdb;
- dpms = pps = crtdb = 0;
+ dpms = 0;
+ pps = 0;
+ crtdb = 0;
switch (blank) {
case FB_BLANK_UNBLANK:
@@ -461,14 +465,13 @@ int hw_sm750_setBLANK(struct lynxfb_output *output, int blank)
return 0;
}
-
void hw_sm750_initAccel(struct sm750_dev *sm750_dev)
{
u32 reg;
enable2DEngine(1);
- if (getChipType() == SM750LE) {
+ if (sm750_get_chip_type() == SM750LE) {
reg = PEEK32(DE_STATE1);
reg |= DE_STATE1_DE_ABORT;
POKE32(DE_STATE1, reg);
@@ -509,7 +512,6 @@ int hw_sm750le_deWait(void)
return -1;
}
-
int hw_sm750_deWait(void)
{
int i = 0x10000000;
@@ -529,10 +531,10 @@ int hw_sm750_deWait(void)
}
int hw_sm750_pan_display(struct lynxfb_crtc *crtc,
- const struct fb_var_screeninfo *var,
- const struct fb_info *info)
+ const struct fb_var_screeninfo *var,
+ const struct fb_info *info)
{
- uint32_t total;
+ u32 total;
/* check params */
if ((var->xoffset + var->xres > var->xres_virtual) ||
(var->yoffset + var->yres > var->yres_virtual)) {
diff --git a/drivers/staging/speakup/devsynth.c b/drivers/staging/speakup/devsynth.c
index 84989711ae67..58abd1d85105 100644
--- a/drivers/staging/speakup/devsynth.c
+++ b/drivers/staging/speakup/devsynth.c
@@ -34,7 +34,7 @@ static ssize_t speakup_file_write(struct file *fp, const char __user *buffer,
synth_write(buf, bytes);
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
}
- return (ssize_t) nbytes;
+ return (ssize_t)nbytes;
}
static ssize_t speakup_file_read(struct file *fp, char __user *buf,
diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c
index 528cbdce4227..e744aa9730ff 100644
--- a/drivers/staging/speakup/kobjects.c
+++ b/drivers/staging/speakup/kobjects.c
@@ -251,7 +251,7 @@ static ssize_t keymap_show(struct kobject *kobj, struct kobj_attribute *attr,
}
cp += sprintf(cp, "0, %d\n", KEY_MAP_VER);
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
- return (int)(cp-buf);
+ return (int)(cp - buf);
}
/*
@@ -288,8 +288,8 @@ static ssize_t keymap_store(struct kobject *kobj, struct kobj_attribute *attr,
cp = spk_s2uchar(cp, cp1);
cp1++;
}
- i = (int)cp1[-2]+1;
- i *= (int)cp1[-1]+1;
+ i = (int)cp1[-2] + 1;
+ i *= (int)cp1[-1] + 1;
i += 2; /* 0 and last map ver */
if (cp1[-3] != KEY_MAP_VER || cp1[-1] > 10 ||
i+SHIFT_TBL_SIZE+4 >= sizeof(spk_key_buf)) {
@@ -350,9 +350,9 @@ static ssize_t silent_store(struct kobject *kobj, struct kobj_attribute *attr,
} else {
shut = 0;
}
- if (ch&4)
+ if (ch & 4)
shut |= 0x40;
- if (ch&1)
+ if (ch & 1)
spk_shut_up |= shut;
else
spk_shut_up &= ~shut;
@@ -411,11 +411,13 @@ static ssize_t synth_direct_store(struct kobject *kobj,
int len;
int bytes;
const char *ptr = buf;
+ unsigned long flags;
if (!synth)
return -EPERM;
len = strlen(buf);
+ spin_lock_irqsave(&speakup_info.spinlock, flags);
while (len > 0) {
bytes = min_t(size_t, len, 250);
strncpy(tmp, ptr, bytes);
@@ -425,6 +427,7 @@ static ssize_t synth_direct_store(struct kobject *kobj,
ptr += bytes;
len -= bytes;
}
+ spin_unlock_irqrestore(&speakup_info.spinlock, flags);
return count;
}
@@ -973,11 +976,11 @@ static struct attribute *i18n_attrs[] = {
* created for the attributes with the directory being the name of the
* attribute group.
*/
-static struct attribute_group main_attr_group = {
+static const struct attribute_group main_attr_group = {
.attrs = main_attrs,
};
-static struct attribute_group i18n_attr_group = {
+static const struct attribute_group i18n_attr_group = {
.attrs = i18n_attrs,
.name = "i18n",
};
diff --git a/drivers/staging/speakup/synth.c b/drivers/staging/speakup/synth.c
index 4f462c35fdd9..54b2f3918628 100644
--- a/drivers/staging/speakup/synth.c
+++ b/drivers/staging/speakup/synth.c
@@ -18,7 +18,7 @@
#include "serialio.h"
#define MAXSYNTHS 16 /* Max number of synths in array. */
-static struct spk_synth *synths[MAXSYNTHS];
+static struct spk_synth *synths[MAXSYNTHS + 1];
struct spk_synth *synth;
char spk_pitch_buff[32] = "";
static int module_status;
@@ -407,7 +407,7 @@ static int do_synth_init(struct spk_synth *in_synth)
if (!spk_quiet_boot)
synth_printf("%s found\n", synth->long_name);
if (synth->attributes.name
- && sysfs_create_group(speakup_kobj, &(synth->attributes)) < 0)
+ && sysfs_create_group(speakup_kobj, &synth->attributes) < 0)
return -ENOMEM;
synth_flags = synth->flags;
wake_up_interruptible_all(&speakup_event);
@@ -429,7 +429,7 @@ void synth_release(void)
del_timer(&thread_timer);
spin_unlock_irqrestore(&speakup_info.spinlock, flags);
if (synth->attributes.name)
- sysfs_remove_group(speakup_kobj, &(synth->attributes));
+ sysfs_remove_group(speakup_kobj, &synth->attributes);
for (var = synth->vars; var->var_id != MAXVARS; var++)
speakup_unregister_var(var->var_id);
spk_stop_serial_interrupt();
diff --git a/drivers/staging/speakup/varhandlers.c b/drivers/staging/speakup/varhandlers.c
index e1393d2a2b0f..21186e3dc7ad 100644
--- a/drivers/staging/speakup/varhandlers.c
+++ b/drivers/staging/speakup/varhandlers.c
@@ -276,7 +276,7 @@ int spk_set_mask_bits(const char *input, const int which, const int how)
u_char *cp;
short mask = spk_punc_info[which].mask;
- if (how&1) {
+ if (how & 1) {
for (cp = (u_char *)spk_punc_info[3].value; *cp; cp++)
spk_chartab[*cp] &= ~mask;
}
@@ -290,14 +290,14 @@ int spk_set_mask_bits(const char *input, const int which, const int how)
if (mask < PUNC) {
if (!(spk_chartab[*cp] & PUNC))
break;
- } else if (spk_chartab[*cp]&B_NUM)
+ } else if (spk_chartab[*cp] & B_NUM)
break;
}
if (*cp)
return -EINVAL;
cp = (u_char *)input;
}
- if (how&2) {
+ if (how & 2) {
for (; *cp; cp++)
if (*cp > SPACE)
spk_chartab[*cp] |= mask;
diff --git a/drivers/staging/unisys/include/channel.h b/drivers/staging/unisys/include/channel.h
index db4e6b28755b..259ef6487959 100644
--- a/drivers/staging/unisys/include/channel.h
+++ b/drivers/staging/unisys/include/channel.h
@@ -75,28 +75,6 @@ enum channel_clientstate {
/* access channel anytime */
};
-static inline const u8 *
-ULTRA_CHANNELCLI_STRING(u32 state)
-{
- switch (state) {
- case CHANNELCLI_DETACHED:
- return (const u8 *)("DETACHED");
- case CHANNELCLI_DISABLED:
- return (const u8 *)("DISABLED");
- case CHANNELCLI_ATTACHING:
- return (const u8 *)("ATTACHING");
- case CHANNELCLI_ATTACHED:
- return (const u8 *)("ATTACHED");
- case CHANNELCLI_BUSY:
- return (const u8 *)("BUSY");
- case CHANNELCLI_OWNED:
- return (const u8 *)("OWNED");
- default:
- break;
- }
- return (const u8 *)("?");
-}
-
#define SPAR_CHANNEL_SERVER_READY(ch) \
(readl(&(ch)->srv_state) == CHANNELSRV_READY)
@@ -132,22 +110,6 @@ ULTRA_CHANNELCLI_STRING(u32 state)
/* throttling invalid boot channel statetransition error due to busy channel */
#define ULTRA_CLIERRORBOOT_THROTTLEMSG_BUSY 0x04
-/* Values for ULTRA_CHANNEL_PROTOCOL.CliErrorOS: */
-/* throttling invalid guest OS channel statetransition error due to
- * client disabled
- */
-#define ULTRA_CLIERROROS_THROTTLEMSG_DISABLED 0x01
-
-/* throttling invalid guest OS channel statetransition error due to
- * client not attached
- */
-#define ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED 0x02
-
-/* throttling invalid guest OS channel statetransition error due to
- * busy channel
- */
-#define ULTRA_CLIERROROS_THROTTLEMSG_BUSY 0x04
-
/* Values for ULTRA_CHANNEL_PROTOCOL.Features: This define exists so
* that windows guest can look at the FeatureFlags in the io channel,
* and configure the windows driver to use interrupts or not based on
@@ -347,148 +309,6 @@ static inline int spar_check_channel_server(uuid_le typeuuid, char *name,
return 1;
}
-/* Given a file pathname <s> (with '/' or '\' separating directory nodes),
- * returns a pointer to the beginning of a node within that pathname such
- * that the number of nodes from that pointer to the end of the string is
- * NOT more than <n>. Note that if the pathname has less than <n> nodes
- * in it, the return pointer will be to the beginning of the string.
- */
-static inline u8 *
-pathname_last_n_nodes(u8 *s, unsigned int n)
-{
- u8 *p = s;
- unsigned int node_count = 0;
-
- while (*p != '\0') {
- if ((*p == '/') || (*p == '\\'))
- node_count++;
- p++;
- }
- if (node_count <= n)
- return s;
- while (n > 0) {
- p--;
- if (p == s)
- break; /* should never happen, unless someone
- * is changing the string while we are
- * looking at it!!
- */
- if ((*p == '/') || (*p == '\\'))
- n--;
- }
- return p + 1;
-}
-
-static inline int
-spar_channel_client_acquire_os(void __iomem *ch, u8 *id)
-{
- struct channel_header __iomem *hdr = ch;
-
- if (readl(&hdr->cli_state_os) == CHANNELCLI_DISABLED) {
- if ((readb(&hdr->cli_error_os)
- & ULTRA_CLIERROROS_THROTTLEMSG_DISABLED) == 0) {
- /* we are NOT throttling this message */
- writeb(readb(&hdr->cli_error_os) |
- ULTRA_CLIERROROS_THROTTLEMSG_DISABLED,
- &hdr->cli_error_os);
- /* throttle until acquire successful */
-
- pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED\n",
- id);
- }
- return 0;
- }
- if ((readl(&hdr->cli_state_os) != CHANNELCLI_OWNED) &&
- (readl(&hdr->cli_state_boot) == CHANNELCLI_DISABLED)) {
- /* Our competitor is DISABLED, so we can transition to OWNED */
- pr_info("%s Channel StateTransition (%s) %s(%d)-->%s(%d)\n",
- id, "cli_state_os",
- ULTRA_CHANNELCLI_STRING(readl(&hdr->cli_state_os)),
- readl(&hdr->cli_state_os),
- ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED),
- CHANNELCLI_OWNED);
- writel(CHANNELCLI_OWNED, &hdr->cli_state_os);
- mb(); /* required for channel synch */
- }
- if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED) {
- if (readb(&hdr->cli_error_os)) {
- /* we are in an error msg throttling state;
- * come out of it
- */
- pr_info("%s Channel OS client acquire now successful\n",
- id);
- writeb(0, &hdr->cli_error_os);
- }
- return 1;
- }
-
- /* We have to do it the "hard way". We transition to BUSY,
- * and can use the channel iff our competitor has not also
- * transitioned to BUSY.
- */
- if (readl(&hdr->cli_state_os) != CHANNELCLI_ATTACHED) {
- if ((readb(&hdr->cli_error_os)
- & ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED) == 0) {
- /* we are NOT throttling this message */
- writeb(readb(&hdr->cli_error_os) |
- ULTRA_CLIERROROS_THROTTLEMSG_NOTATTACHED,
- &hdr->cli_error_os);
- /* throttle until acquire successful */
- pr_info("%s Channel StateTransition INVALID! - acquire failed because OS client NOT ATTACHED (state=%s(%d))\n",
- id, ULTRA_CHANNELCLI_STRING(
- readl(&hdr->cli_state_os)),
- readl(&hdr->cli_state_os));
- }
- return 0;
- }
- writel(CHANNELCLI_BUSY, &hdr->cli_state_os);
- mb(); /* required for channel synch */
- if (readl(&hdr->cli_state_boot) == CHANNELCLI_BUSY) {
- if ((readb(&hdr->cli_error_os)
- & ULTRA_CLIERROROS_THROTTLEMSG_BUSY) == 0) {
- /* we are NOT throttling this message */
- writeb(readb(&hdr->cli_error_os) |
- ULTRA_CLIERROROS_THROTTLEMSG_BUSY,
- &hdr->cli_error_os);
- /* throttle until acquire successful */
- pr_info("%s Channel StateTransition failed - host OS acquire failed because boot BUSY\n",
- id);
- }
- /* reset busy */
- writel(CHANNELCLI_ATTACHED, &hdr->cli_state_os);
- mb(); /* required for channel synch */
- return 0;
- }
- if (readb(&hdr->cli_error_os)) {
- /* we are in an error msg throttling state; come out of it */
- pr_info("%s Channel OS client acquire now successful\n", id);
- writeb(0, &hdr->cli_error_os);
- }
- return 1;
-}
-
-static inline void
-spar_channel_client_release_os(void __iomem *ch, u8 *id)
-{
- struct channel_header __iomem *hdr = ch;
-
- if (readb(&hdr->cli_error_os)) {
- /* we are in an error msg throttling state; come out of it */
- pr_info("%s Channel OS client error state cleared\n", id);
- writeb(0, &hdr->cli_error_os);
- }
- if (readl(&hdr->cli_state_os) == CHANNELCLI_OWNED)
- return;
- if (readl(&hdr->cli_state_os) != CHANNELCLI_BUSY) {
- pr_info("%s Channel StateTransition INVALID! - release failed because OS client NOT BUSY (state=%s(%d))\n",
- id, ULTRA_CHANNELCLI_STRING(
- readl(&hdr->cli_state_os)),
- readl(&hdr->cli_state_os));
- /* return; */
- }
- writel(CHANNELCLI_ATTACHED, &hdr->cli_state_os); /* release busy */
-}
-
/*
* Routine Description:
* Tries to insert the prebuilt signal pointed to by pSignal into the nth
@@ -569,4 +389,45 @@ unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue,
unsigned char spar_signalqueue_empty(struct channel_header __iomem *ch,
u32 queue);
+/*
+ * CHANNEL Guids
+ */
+
+/* {414815ed-c58c-11da-95a9-00e08161165f} */
+#define SPAR_VHBA_CHANNEL_PROTOCOL_UUID \
+ UUID_LE(0x414815ed, 0xc58c, 0x11da, \
+ 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f)
+static const uuid_le spar_vhba_channel_protocol_uuid =
+ SPAR_VHBA_CHANNEL_PROTOCOL_UUID;
+#define SPAR_VHBA_CHANNEL_PROTOCOL_UUID_STR \
+ "414815ed-c58c-11da-95a9-00e08161165f"
+
+/* {8cd5994d-c58e-11da-95a9-00e08161165f} */
+#define SPAR_VNIC_CHANNEL_PROTOCOL_UUID \
+ UUID_LE(0x8cd5994d, 0xc58e, 0x11da, \
+ 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f)
+static const uuid_le spar_vnic_channel_protocol_uuid =
+ SPAR_VNIC_CHANNEL_PROTOCOL_UUID;
+#define SPAR_VNIC_CHANNEL_PROTOCOL_UUID_STR \
+ "8cd5994d-c58e-11da-95a9-00e08161165f"
+
+/* {72120008-4AAB-11DC-8530-444553544200} */
+#define SPAR_SIOVM_UUID \
+ UUID_LE(0x72120008, 0x4AAB, 0x11DC, \
+ 0x85, 0x30, 0x44, 0x45, 0x53, 0x54, 0x42, 0x00)
+static const uuid_le spar_siovm_uuid = SPAR_SIOVM_UUID;
+
+/* {5b52c5ac-e5f5-4d42-8dff-429eaecd221f} */
+#define SPAR_CONTROLDIRECTOR_CHANNEL_PROTOCOL_UUID \
+ UUID_LE(0x5b52c5ac, 0xe5f5, 0x4d42, \
+ 0x8d, 0xff, 0x42, 0x9e, 0xae, 0xcd, 0x22, 0x1f)
+
+static const uuid_le spar_controldirector_channel_protocol_uuid =
+ SPAR_CONTROLDIRECTOR_CHANNEL_PROTOCOL_UUID;
+
+/* {b4e79625-aede-4eAA-9e11-D3eddcd4504c} */
+#define SPAR_DIAG_POOL_CHANNEL_PROTOCOL_UUID \
+ UUID_LE(0xb4e79625, 0xaede, 0x4eaa, \
+ 0x9e, 0x11, 0xd3, 0xed, 0xdc, 0xd4, 0x50, 0x4c)
+
#endif
diff --git a/drivers/staging/unisys/include/channel_guid.h b/drivers/staging/unisys/include/channel_guid.h
deleted file mode 100644
index 17cb499cb53c..000000000000
--- a/drivers/staging/unisys/include/channel_guid.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-/*
- * CHANNEL Guids
- */
-
-/* {414815ed-c58c-11da-95a9-00e08161165f} */
-#define SPAR_VHBA_CHANNEL_PROTOCOL_UUID \
- UUID_LE(0x414815ed, 0xc58c, 0x11da, \
- 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f)
-static const uuid_le spar_vhba_channel_protocol_uuid =
- SPAR_VHBA_CHANNEL_PROTOCOL_UUID;
-#define SPAR_VHBA_CHANNEL_PROTOCOL_UUID_STR \
- "414815ed-c58c-11da-95a9-00e08161165f"
-
-/* {8cd5994d-c58e-11da-95a9-00e08161165f} */
-#define SPAR_VNIC_CHANNEL_PROTOCOL_UUID \
- UUID_LE(0x8cd5994d, 0xc58e, 0x11da, \
- 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f)
-static const uuid_le spar_vnic_channel_protocol_uuid =
- SPAR_VNIC_CHANNEL_PROTOCOL_UUID;
-#define SPAR_VNIC_CHANNEL_PROTOCOL_UUID_STR \
- "8cd5994d-c58e-11da-95a9-00e08161165f"
-
-/* {72120008-4AAB-11DC-8530-444553544200} */
-#define SPAR_SIOVM_UUID \
- UUID_LE(0x72120008, 0x4AAB, 0x11DC, \
- 0x85, 0x30, 0x44, 0x45, 0x53, 0x54, 0x42, 0x00)
-static const uuid_le spar_siovm_uuid = SPAR_SIOVM_UUID;
-
-/* {5b52c5ac-e5f5-4d42-8dff-429eaecd221f} */
-#define SPAR_CONTROLDIRECTOR_CHANNEL_PROTOCOL_UUID \
- UUID_LE(0x5b52c5ac, 0xe5f5, 0x4d42, \
- 0x8d, 0xff, 0x42, 0x9e, 0xae, 0xcd, 0x22, 0x1f)
-
-static const uuid_le spar_controldirector_channel_protocol_uuid =
- SPAR_CONTROLDIRECTOR_CHANNEL_PROTOCOL_UUID;
-
-/* {b4e79625-aede-4eAA-9e11-D3eddcd4504c} */
-#define SPAR_DIAG_POOL_CHANNEL_PROTOCOL_UUID \
- UUID_LE(0xb4e79625, 0xaede, 0x4eaa, \
- 0x9e, 0x11, 0xd3, 0xed, 0xdc, 0xd4, 0x50, 0x4c)
diff --git a/drivers/staging/unisys/include/diagchannel.h b/drivers/staging/unisys/include/diagchannel.h
deleted file mode 100644
index 6e813c77b97e..000000000000
--- a/drivers/staging/unisys/include/diagchannel.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-#ifndef _DIAG_CHANNEL_H_
-#define _DIAG_CHANNEL_H_
-
-/* Levels of severity for diagnostic events, in order from lowest severity to
- * highest (i.e. fatal errors are the most severe, and should always be logged,
- * but info events rarely need to be logged except during debugging). The
- * values DIAG_SEVERITY_ENUM_BEGIN and DIAG_SEVERITY_ENUM_END are not valid
- * severity values. They exist merely to dilineate the list, so that future
- * additions won't require changes to the driver (i.e. when checking for
- * out-of-range severities in SetSeverity). The values DIAG_SEVERITY_OVERRIDE
- * and DIAG_SEVERITY_SHUTOFF are not valid severity values for logging events
- * but they are valid for controlling the amount of event data. Changes made
- * to the enum, need to be reflected in s-Par.
- */
-enum diag_severity {
- DIAG_SEVERITY_VERBOSE = 0,
- DIAG_SEVERITY_INFO = 1,
- DIAG_SEVERITY_WARNING = 2,
- DIAG_SEVERITY_ERR = 3,
- DIAG_SEVERITY_PRINT = 4,
-};
-
-#endif
diff --git a/drivers/staging/unisys/include/guestlinuxdebug.h b/drivers/staging/unisys/include/guestlinuxdebug.h
deleted file mode 100644
index b81287f5e2c3..000000000000
--- a/drivers/staging/unisys/include/guestlinuxdebug.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-#ifndef __GUESTLINUXDEBUG_H__
-#define __GUESTLINUXDEBUG_H__
-
-/*
- * This file contains supporting interface for "vmcallinterface.h", particularly
- * regarding adding additional structure and functionality to linux
- * ISSUE_IO_VMCALL_POSTCODE_SEVERITY
- */
-
-/******* INFO ON ISSUE_POSTCODE_LINUX() BELOW *******/
-enum driver_pc { /* POSTCODE driver identifier tuples */
- /* visorchipset driver files */
- VISOR_CHIPSET_PC = 0xA0,
- VISOR_CHIPSET_PC_controlvm_c = 0xA1,
- VISOR_CHIPSET_PC_controlvm_cm2 = 0xA2,
- VISOR_CHIPSET_PC_controlvm_direct_c = 0xA3,
- VISOR_CHIPSET_PC_file_c = 0xA4,
- VISOR_CHIPSET_PC_parser_c = 0xA5,
- VISOR_CHIPSET_PC_testing_c = 0xA6,
- VISOR_CHIPSET_PC_visorchipset_main_c = 0xA7,
- VISOR_CHIPSET_PC_visorswitchbus_c = 0xA8,
- /* visorbus driver files */
- VISOR_BUS_PC = 0xB0,
- VISOR_BUS_PC_businst_attr_c = 0xB1,
- VISOR_BUS_PC_channel_attr_c = 0xB2,
- VISOR_BUS_PC_devmajorminor_attr_c = 0xB3,
- VISOR_BUS_PC_visorbus_main_c = 0xB4,
- /* visorclientbus driver files */
- VISOR_CLIENT_BUS_PC = 0xC0,
- VISOR_CLIENT_BUS_PC_visorclientbus_main_c = 0xC1,
- /* virt hba driver files */
- VIRT_HBA_PC = 0xC2,
- VIRT_HBA_PC_virthba_c = 0xC3,
- /* virtpci driver files */
- VIRT_PCI_PC = 0xC4,
- VIRT_PCI_PC_virtpci_c = 0xC5,
- /* virtnic driver files */
- VIRT_NIC_PC = 0xC6,
- VIRT_NIC_P_virtnic_c = 0xC7,
- /* uislib driver files */
- UISLIB_PC = 0xD0,
- UISLIB_PC_uislib_c = 0xD1,
- UISLIB_PC_uisqueue_c = 0xD2,
- UISLIB_PC_uisthread_c = 0xD3,
- UISLIB_PC_uisutils_c = 0xD4,
-};
-
-enum event_pc { /* POSTCODE event identifier tuples */
- ATTACH_PORT_ENTRY_PC = 0x001,
- ATTACH_PORT_FAILURE_PC = 0x002,
- ATTACH_PORT_SUCCESS_PC = 0x003,
- BUS_FAILURE_PC = 0x004,
- BUS_CREATE_ENTRY_PC = 0x005,
- BUS_CREATE_FAILURE_PC = 0x006,
- BUS_CREATE_EXIT_PC = 0x007,
- BUS_CONFIGURE_ENTRY_PC = 0x008,
- BUS_CONFIGURE_FAILURE_PC = 0x009,
- BUS_CONFIGURE_EXIT_PC = 0x00A,
- CHIPSET_INIT_ENTRY_PC = 0x00B,
- CHIPSET_INIT_SUCCESS_PC = 0x00C,
- CHIPSET_INIT_FAILURE_PC = 0x00D,
- CHIPSET_INIT_EXIT_PC = 0x00E,
- CREATE_WORKQUEUE_PC = 0x00F,
- CREATE_WORKQUEUE_FAILED_PC = 0x0A0,
- CONTROLVM_INIT_FAILURE_PC = 0x0A1,
- DEVICE_CREATE_ENTRY_PC = 0x0A2,
- DEVICE_CREATE_FAILURE_PC = 0x0A3,
- DEVICE_CREATE_SUCCESS_PC = 0x0A4,
- DEVICE_CREATE_EXIT_PC = 0x0A5,
- DEVICE_ADD_PC = 0x0A6,
- DEVICE_REGISTER_FAILURE_PC = 0x0A7,
- DEVICE_CHANGESTATE_ENTRY_PC = 0x0A8,
- DEVICE_CHANGESTATE_FAILURE_PC = 0x0A9,
- DEVICE_CHANGESTATE_EXIT_PC = 0x0AA,
- DRIVER_ENTRY_PC = 0x0AB,
- DRIVER_EXIT_PC = 0x0AC,
- MALLOC_FAILURE_PC = 0x0AD,
- QUEUE_DELAYED_WORK_PC = 0x0AE,
- UISLIB_THREAD_FAILURE_PC = 0x0B7,
- VBUS_CHANNEL_ENTRY_PC = 0x0B8,
- VBUS_CHANNEL_FAILURE_PC = 0x0B9,
- VBUS_CHANNEL_EXIT_PC = 0x0BA,
- VHBA_CREATE_ENTRY_PC = 0x0BB,
- VHBA_CREATE_FAILURE_PC = 0x0BC,
- VHBA_CREATE_EXIT_PC = 0x0BD,
- VHBA_CREATE_SUCCESS_PC = 0x0BE,
- VHBA_COMMAND_HANDLER_PC = 0x0BF,
- VHBA_PROBE_ENTRY_PC = 0x0C0,
- VHBA_PROBE_FAILURE_PC = 0x0C1,
- VHBA_PROBE_EXIT_PC = 0x0C2,
- VNIC_CREATE_ENTRY_PC = 0x0C3,
- VNIC_CREATE_FAILURE_PC = 0x0C4,
- VNIC_CREATE_SUCCESS_PC = 0x0C5,
- VNIC_PROBE_ENTRY_PC = 0x0C6,
- VNIC_PROBE_FAILURE_PC = 0x0C7,
- VNIC_PROBE_EXIT_PC = 0x0C8,
- VPCI_CREATE_ENTRY_PC = 0x0C9,
- VPCI_CREATE_FAILURE_PC = 0x0CA,
- VPCI_CREATE_EXIT_PC = 0x0CB,
- VPCI_PROBE_ENTRY_PC = 0x0CC,
- VPCI_PROBE_FAILURE_PC = 0x0CD,
- VPCI_PROBE_EXIT_PC = 0x0CE,
- CRASH_DEV_ENTRY_PC = 0x0CF,
- CRASH_DEV_EXIT_PC = 0x0D0,
- CRASH_DEV_HADDR_NULL = 0x0D1,
- CRASH_DEV_CONTROLVM_NULL = 0x0D2,
- CRASH_DEV_RD_BUS_FAIULRE_PC = 0x0D3,
- CRASH_DEV_RD_DEV_FAIULRE_PC = 0x0D4,
- CRASH_DEV_BUS_NULL_FAILURE_PC = 0x0D5,
- CRASH_DEV_DEV_NULL_FAILURE_PC = 0x0D6,
- CRASH_DEV_CTRL_RD_FAILURE_PC = 0x0D7,
- CRASH_DEV_COUNT_FAILURE_PC = 0x0D8,
- SAVE_MSG_BUS_FAILURE_PC = 0x0D9,
- SAVE_MSG_DEV_FAILURE_PC = 0x0DA,
- CALLHOME_INIT_FAILURE_PC = 0x0DB
-};
-
-#ifdef __GNUC__
-
-#define POSTCODE_SEVERITY_ERR DIAG_SEVERITY_ERR
-#define POSTCODE_SEVERITY_WARNING DIAG_SEVERITY_WARNING
-/* TODO-> Info currently doesn't show, so we set info=warning */
-#define POSTCODE_SEVERITY_INFO DIAG_SEVERITY_PRINT
-
-/* example call of POSTCODE_LINUX_2(VISOR_CHIPSET_PC, POSTCODE_SEVERITY_ERR);
- * Please also note that the resulting postcode is in hex, so if you are
- * searching for the __LINE__ number, convert it first to decimal. The line
- * number combined with driver and type of call, will allow you to track down
- * exactly what line an error occurred on, or where the last driver
- * entered/exited from.
- */
-
-/* BASE FUNCTIONS */
-#define POSTCODE_LINUX_A(DRIVER_PC, EVENT_PC, pc32bit, severity) \
-do { \
- unsigned long long post_code_temp; \
- post_code_temp = (((u64)DRIVER_PC) << 56) | (((u64)EVENT_PC) << 44) | \
- ((((u64)__LINE__) & 0xFFF) << 32) | \
- (((u64)pc32bit) & 0xFFFFFFFF); \
- ISSUE_IO_VMCALL_POSTCODE_SEVERITY(post_code_temp, severity); \
-} while (0)
-
-#define POSTCODE_LINUX_B(DRIVER_PC, EVENT_PC, pc16bit1, pc16bit2, severity) \
-do { \
- unsigned long long post_code_temp; \
- post_code_temp = (((u64)DRIVER_PC) << 56) | (((u64)EVENT_PC) << 44) | \
- ((((u64)__LINE__) & 0xFFF) << 32) | \
- ((((u64)pc16bit1) & 0xFFFF) << 16) | \
- (((u64)pc16bit2) & 0xFFFF); \
- ISSUE_IO_VMCALL_POSTCODE_SEVERITY(post_code_temp, severity); \
-} while (0)
-
-/* MOST COMMON */
-#define POSTCODE_LINUX_2(EVENT_PC, severity) \
- POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, 0x0000, severity)
-
-#define POSTCODE_LINUX_3(EVENT_PC, pc32bit, severity) \
- POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, pc32bit, severity)
-
-#define POSTCODE_LINUX_4(EVENT_PC, pc16bit1, pc16bit2, severity) \
- POSTCODE_LINUX_B(CURRENT_FILE_PC, EVENT_PC, pc16bit1, \
- pc16bit2, severity)
-
-#endif
-#endif
diff --git a/drivers/staging/unisys/include/iochannel.h b/drivers/staging/unisys/include/iochannel.h
index 5ccf81485d72..cba4433bcd51 100644
--- a/drivers/staging/unisys/include/iochannel.h
+++ b/drivers/staging/unisys/include/iochannel.h
@@ -33,7 +33,6 @@
#include <linux/dma-direction.h>
#include "channel.h"
-#include "channel_guid.h"
#define ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE
#define ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE
diff --git a/drivers/staging/unisys/include/periodic_work.h b/drivers/staging/unisys/include/periodic_work.h
deleted file mode 100644
index 0b3335a4b206..000000000000
--- a/drivers/staging/unisys/include/periodic_work.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* periodic_work.h
- *
- * Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-#ifndef __PERIODIC_WORK_H__
-#define __PERIODIC_WORK_H__
-
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-
-/* PERIODIC_WORK an opaque structure to users.
- * Fields are declared only in the implementation .c files.
- */
-struct periodic_work;
-
-struct periodic_work *
-visor_periodic_work_create(ulong jiffy_interval,
- struct workqueue_struct *workqueue,
- void (*workfunc)(void *),
- void *workfuncarg,
- const char *devnam);
-void visor_periodic_work_destroy(struct periodic_work *pw);
-bool visor_periodic_work_nextperiod(struct periodic_work *pw);
-bool visor_periodic_work_start(struct periodic_work *pw);
-bool visor_periodic_work_stop(struct periodic_work *pw);
-
-#endif
diff --git a/drivers/staging/unisys/include/vbushelper.h b/drivers/staging/unisys/include/vbushelper.h
deleted file mode 100644
index f1b6aacb79d7..000000000000
--- a/drivers/staging/unisys/include/vbushelper.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* vbushelper.h
- *
- * Copyright (C) 2011 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-#ifndef __VBUSHELPER_H__
-#define __VBUSHELPER_H__
-
-/* TARGET_HOSTNAME specified as -DTARGET_HOSTNAME=\"thename\" on the
- * command line
- */
-
-#define TARGET_HOSTNAME "linuxguest"
-
-static inline void bus_device_info_init(
- struct ultra_vbus_deviceinfo *bus_device_info_ptr,
- const char *dev_type, const char *drv_name,
- const char *ver, const char *ver_tag)
-{
- memset(bus_device_info_ptr, 0, sizeof(struct ultra_vbus_deviceinfo));
- snprintf(bus_device_info_ptr->devtype,
- sizeof(bus_device_info_ptr->devtype),
- "%s", (dev_type) ? dev_type : "unknownType");
- snprintf(bus_device_info_ptr->drvname,
- sizeof(bus_device_info_ptr->drvname),
- "%s", (drv_name) ? drv_name : "unknownDriver");
- snprintf(bus_device_info_ptr->infostrs,
- sizeof(bus_device_info_ptr->infostrs), "%s\t%s\t%s",
- (ver) ? ver : "unknownVer",
- (ver_tag) ? ver_tag : "unknownVerTag",
- TARGET_HOSTNAME);
-}
-
-#endif
diff --git a/drivers/staging/unisys/include/version.h b/drivers/staging/unisys/include/version.h
deleted file mode 100644
index 83d1da7a2f81..000000000000
--- a/drivers/staging/unisys/include/version.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-/* version.h */
-
-/* Common version/release info needed by all components goes here.
- * (This file must compile cleanly in all environments.)
- * Ultimately, this will be combined with defines generated dynamically as
- * part of the sysgen, and some of the defines below may in fact end up
- * being replaced with dynamically generated ones.
- */
-#ifndef __VERSION_H__
-#define __VERSION_H__
-
-#define SPARVER1 "1"
-#define SPARVER2 "0"
-#define SPARVER3 "0"
-#define SPARVER4 "0"
-
-#define VERSION SPARVER1 "." SPARVER2 "." SPARVER3 "." SPARVER4
-
-/* Here are various version forms needed in Windows environments.
- */
-#define VISOR_PRODUCTVERSION SPARVERCOMMA
-#define VISOR_PRODUCTVERSION_STR SPARVER1 "." SPARVER2 "." SPARVER3 "." \
- SPARVER4
-#define VISOR_OBJECTVERSION_STR SPARVER1 "," SPARVER2 "," SPARVER3 "," \
- SPARVER4
-
-#define COPYRIGHT "Unisys Corporation"
-#define COPYRIGHTDATE "2010 - 2013"
-
-#endif
diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h
index 9baf1ec70d01..677627c72c4c 100644
--- a/drivers/staging/unisys/include/visorbus.h
+++ b/drivers/staging/unisys/include/visorbus.h
@@ -34,8 +34,9 @@
#include <linux/poll.h>
#include <linux/kernel.h>
#include <linux/uuid.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
-#include "periodic_work.h"
#include "channel.h"
struct visor_driver;
@@ -65,8 +66,6 @@ struct visor_channeltype_descriptor {
* struct visor_driver - Information provided by each visor driver when it
* registers with the visorbus driver.
* @name: Name of the visor driver.
- * @version: The numbered version of the driver (x.x.xxx).
- * @vertag: A human readable version string.
* @owner: The module owner.
* @channel_types: Types of channels handled by this driver, ending with
* a zero GUID. Our specialized BUS.match() method knows
@@ -93,12 +92,9 @@ struct visor_channeltype_descriptor {
* @resume: Behaves similar to pause.
* @driver: Private reference to the device driver. For use by bus
* driver only.
- * @version_attr: Private version field. For use by bus driver only.
*/
struct visor_driver {
const char *name;
- const char *version;
- const char *vertag;
struct module *owner;
struct visor_channeltype_descriptor *channel_types;
int (*probe)(struct visor_device *dev);
@@ -111,7 +107,6 @@ struct visor_driver {
/* These fields are for private use by the bus driver only. */
struct device_driver driver;
- struct driver_attribute version_attr;
};
#define to_visor_driver(x) ((x) ? \
@@ -120,33 +115,33 @@ struct visor_driver {
/**
* struct visor_device - A device type for things "plugged" into the visorbus
* bus
- * visorchannel: Points to the channel that the device is
+ * @visorchannel: Points to the channel that the device is
* associated with.
- * channel_type_guid: Identifies the channel type to the bus driver.
- * device: Device struct meant for use by the bus driver
+ * @channel_type_guid: Identifies the channel type to the bus driver.
+ * @device: Device struct meant for use by the bus driver
* only.
- * list_all: Used by the bus driver to enumerate devices.
- * periodic_work: Device work queue. Private use by bus driver
- * only.
- * being_removed: Indicates that the device is being removed from
+ * @list_all: Used by the bus driver to enumerate devices.
+ * @timer: Timer fired periodically to do interrupt-type
+ * activity.
+ * @being_removed: Indicates that the device is being removed from
* the bus. Private bus driver use only.
- * visordriver_callback_lock: Used by the bus driver to lock when handling
+ * @visordriver_callback_lock: Used by the bus driver to lock when handling
* channel events.
- * pausing: Indicates that a change towards a paused state.
+ * @pausing: Indicates that a change towards a paused state.
* is in progress. Only modified by the bus driver.
- * resuming: Indicates that a change towards a running state
+ * @resuming: Indicates that a change towards a running state
* is in progress. Only modified by the bus driver.
- * chipset_bus_no: Private field used by the bus driver.
- * chipset_dev_no: Private field used the bus driver.
- * state: Used to indicate the current state of the
+ * @chipset_bus_no: Private field used by the bus driver.
+ * @chipset_dev_no: Private field used the bus driver.
+ * @state: Used to indicate the current state of the
* device.
- * inst: Unique GUID for this instance of the device.
- * name: Name of the device.
- * pending_msg_hdr: For private use by bus driver to respond to
+ * @inst: Unique GUID for this instance of the device.
+ * @name: Name of the device.
+ * @pending_msg_hdr: For private use by bus driver to respond to
* hypervisor requests.
- * vbus_hdr_info: A pointer to header info. Private use by bus
+ * @vbus_hdr_info: A pointer to header info. Private use by bus
* driver.
- * partition_uuid: Indicates client partion id. This should be the
+ * @partition_uuid: Indicates client partion id. This should be the
* same across all visor_devices in the current
* guest. Private use by bus driver only.
*/
@@ -157,9 +152,10 @@ struct visor_device {
/* These fields are for private use by the bus driver only. */
struct device device;
struct list_head list_all;
- struct periodic_work *periodic_work;
+ struct timer_list timer;
+ bool timer_active;
bool being_removed;
- struct semaphore visordriver_callback_lock;
+ struct mutex visordriver_callback_lock;
bool pausing;
bool resuming;
u32 chipset_bus_no;
@@ -174,7 +170,6 @@ struct visor_device {
#define to_visor_device(x) container_of(x, struct visor_device, device)
-#ifndef STANDALONE_CLIENT
int visorbus_register_visor_driver(struct visor_driver *);
void visorbus_unregister_visor_driver(struct visor_driver *);
int visorbus_read_channel(struct visor_device *dev,
@@ -183,50 +178,34 @@ int visorbus_read_channel(struct visor_device *dev,
int visorbus_write_channel(struct visor_device *dev,
unsigned long offset, void *src,
unsigned long nbytes);
-int visorbus_clear_channel(struct visor_device *dev,
- unsigned long offset, u8 ch, unsigned long nbytes);
void visorbus_enable_channel_interrupts(struct visor_device *dev);
void visorbus_disable_channel_interrupts(struct visor_device *dev);
-#endif
-/* Note that for visorchannel_create()
- * <channel_bytes> and <guid> arguments may be 0 if we are a channel CLIENT.
- * In this case, the values can simply be read from the channel header.
+/* Levels of severity for diagnostic events, in order from lowest severity to
+ * highest (i.e. fatal errors are the most severe, and should always be logged,
+ * but info events rarely need to be logged except during debugging). The
+ * values DIAG_SEVERITY_ENUM_BEGIN and DIAG_SEVERITY_ENUM_END are not valid
+ * severity values. They exist merely to dilineate the list, so that future
+ * additions won't require changes to the driver (i.e. when checking for
+ * out-of-range severities in SetSeverity). The values DIAG_SEVERITY_OVERRIDE
+ * and DIAG_SEVERITY_SHUTOFF are not valid severity values for logging events
+ * but they are valid for controlling the amount of event data. Changes made
+ * to the enum, need to be reflected in s-Par.
*/
-struct visorchannel *visorchannel_create(u64 physaddr,
- unsigned long channel_bytes,
- gfp_t gfp, uuid_le guid);
-struct visorchannel *visorchannel_create_with_lock(u64 physaddr,
- unsigned long channel_bytes,
- gfp_t gfp, uuid_le guid);
-void visorchannel_destroy(struct visorchannel *channel);
-int visorchannel_read(struct visorchannel *channel, ulong offset,
- void *local, ulong nbytes);
-int visorchannel_write(struct visorchannel *channel, ulong offset,
- void *local, ulong nbytes);
-int visorchannel_clear(struct visorchannel *channel, ulong offset,
- u8 ch, ulong nbytes);
-bool visorchannel_signalremove(struct visorchannel *channel, u32 queue,
- void *msg);
-bool visorchannel_signalinsert(struct visorchannel *channel, u32 queue,
- void *msg);
-bool visorchannel_signalempty(struct visorchannel *channel, u32 queue);
+enum diag_severity {
+ DIAG_SEVERITY_VERBOSE = 0,
+ DIAG_SEVERITY_INFO = 1,
+ DIAG_SEVERITY_WARNING = 2,
+ DIAG_SEVERITY_ERR = 3,
+ DIAG_SEVERITY_PRINT = 4,
+};
-int visorchannel_signalqueue_slots_avail(struct visorchannel *channel,
- u32 queue);
-int visorchannel_signalqueue_max_slots(struct visorchannel *channel, u32 queue);
-u64 visorchannel_get_physaddr(struct visorchannel *channel);
-ulong visorchannel_get_nbytes(struct visorchannel *channel);
-char *visorchannel_id(struct visorchannel *channel, char *s);
-char *visorchannel_zoneid(struct visorchannel *channel, char *s);
-u64 visorchannel_get_clientpartition(struct visorchannel *channel);
-int visorchannel_set_clientpartition(struct visorchannel *channel,
- u64 partition_handle);
+int visorchannel_signalremove(struct visorchannel *channel, u32 queue,
+ void *msg);
+int visorchannel_signalinsert(struct visorchannel *channel, u32 queue,
+ void *msg);
+bool visorchannel_signalempty(struct visorchannel *channel, u32 queue);
uuid_le visorchannel_get_uuid(struct visorchannel *channel);
-char *visorchannel_uuid_id(uuid_le *guid, char *s);
-void visorchannel_debug(struct visorchannel *channel, int num_queues,
- struct seq_file *seq, u32 off);
-void __iomem *visorchannel_get_header(struct visorchannel *channel);
#define BUS_ROOT_DEVICE UINT_MAX
struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no,
diff --git a/drivers/staging/unisys/visorbus/Makefile b/drivers/staging/unisys/visorbus/Makefile
index fc790e7592fc..f3730d8c953e 100644
--- a/drivers/staging/unisys/visorbus/Makefile
+++ b/drivers/staging/unisys/visorbus/Makefile
@@ -7,6 +7,5 @@ obj-$(CONFIG_UNISYS_VISORBUS) += visorbus.o
visorbus-y := visorbus_main.o
visorbus-y += visorchannel.o
visorbus-y += visorchipset.o
-visorbus-y += periodic_work.o
ccflags-y += -Idrivers/staging/unisys/include
diff --git a/drivers/staging/unisys/visorbus/controlvmchannel.h b/drivers/staging/unisys/visorbus/controlvmchannel.h
index 03e36fb6a5a0..f0bfc4ded892 100644
--- a/drivers/staging/unisys/visorbus/controlvmchannel.h
+++ b/drivers/staging/unisys/visorbus/controlvmchannel.h
@@ -482,4 +482,80 @@ struct spar_controlvm_parameters_header {
u32 reserved; /* Natural alignment */
};
+/* General Errors------------------------------------------------------[0-99] */
+#define CONTROLVM_RESP_SUCCESS 0
+#define CONTROLVM_RESP_ERROR_ALREADY_DONE 1
+#define CONTROLVM_RESP_ERROR_IOREMAP_FAILED 2
+#define CONTROLVM_RESP_ERROR_KMALLOC_FAILED 3
+#define CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN 4
+#define CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT 5
+
+/* CONTROLVM_INIT_CHIPSET-------------------------------------------[100-199] */
+#define CONTROLVM_RESP_ERROR_CLIENT_SWITCHCOUNT_NONZERO 100
+#define CONTROLVM_RESP_ERROR_EXPECTED_CHIPSET_INIT 101
+
+/* Maximum Limit----------------------------------------------------[200-299] */
+#define CONTROLVM_RESP_ERROR_MAX_BUSES 201 /* BUS_CREATE */
+#define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 /* DEVICE_CREATE */
+/* Payload and Parameter Related------------------------------------[400-499] */
+#define CONTROLVM_RESP_ERROR_PAYLOAD_INVALID 400 /* SWITCH_ATTACHEXTPORT,
+ * DEVICE_CONFIGURE
+ */
+#define CONTROLVM_RESP_ERROR_INITIATOR_PARAMETER_INVALID 401 /* Multiple */
+#define CONTROLVM_RESP_ERROR_TARGET_PARAMETER_INVALID 402 /* DEVICE_CONFIGURE */
+#define CONTROLVM_RESP_ERROR_CLIENT_PARAMETER_INVALID 403 /* DEVICE_CONFIGURE */
+/* Specified[Packet Structure] Value-------------------------------[500-599] */
+#define CONTROLVM_RESP_ERROR_BUS_INVALID 500 /* SWITCH_ATTACHINTPORT,
+ * BUS_CONFIGURE,
+ * DEVICE_CREATE,
+ * DEVICE_CONFIG
+ * DEVICE_DESTROY
+ */
+#define CONTROLVM_RESP_ERROR_DEVICE_INVALID 501 /* SWITCH_ATTACHINTPORT */
+ /* DEVICE_CREATE,
+ * DEVICE_CONFIGURE,
+ * DEVICE_DESTROY
+ */
+#define CONTROLVM_RESP_ERROR_CHANNEL_INVALID 502 /* DEVICE_CREATE,
+ * DEVICE_CONFIGURE
+ */
+/* Partition Driver Callback Interface----------------------[600-699] */
+#define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE 604 /* BUS_CREATE,
+ * BUS_DESTROY,
+ * DEVICE_CREATE,
+ * DEVICE_DESTROY
+ */
+/* Unable to invoke VIRTPCI callback */
+#define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR 605
+ /* BUS_CREATE,
+ * BUS_DESTROY,
+ * DEVICE_CREATE,
+ * DEVICE_DESTROY
+ */
+/* VIRTPCI Callback returned error */
+#define CONTROLVM_RESP_ERROR_GENERIC_DRIVER_CALLBACK_ERROR 606
+ /* SWITCH_ATTACHEXTPORT,
+ * SWITCH_DETACHEXTPORT
+ * DEVICE_CONFIGURE
+ */
+
+/* generic device callback returned error */
+/* Bus Related------------------------------------------------------[700-799] */
+#define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 /* BUS_DESTROY */
+/* Channel Related--------------------------------------------------[800-899] */
+#define CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN 800 /* GET_CHANNELINFO,
+ * DEVICE_DESTROY
+ */
+#define CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL 801 /* DEVICE_CREATE */
+/* Chipset Shutdown Related---------------------------------------[1000-1099] */
+#define CONTROLVM_RESP_ERROR_CHIPSET_SHUTDOWN_FAILED 1000
+#define CONTROLVM_RESP_ERROR_CHIPSET_SHUTDOWN_ALREADY_ACTIVE 1001
+
+/* Chipset Stop Related-------------------------------------------[1100-1199] */
+#define CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_BUS 1100
+#define CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_SWITCH 1101
+
+/* Device Related-------------------------------------------------[1400-1499] */
+#define CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT 1400
+
#endif /* __CONTROLVMCHANNEL_H__ */
diff --git a/drivers/staging/unisys/visorbus/controlvmcompletionstatus.h b/drivers/staging/unisys/visorbus/controlvmcompletionstatus.h
deleted file mode 100644
index 23ad0ea6c9fc..000000000000
--- a/drivers/staging/unisys/visorbus/controlvmcompletionstatus.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* controlvmcompletionstatus.c
- *
- * Copyright (C) 2010 - 2015 UNISYS CORPORATION
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-/* Defines for all valid values returned in the response message header
- * completionStatus field. See controlvmchannel.h for description of
- * the header: _CONTROLVM_MESSAGE_HEADER.
- */
-
-#ifndef __CONTROLVMCOMPLETIONSTATUS_H__
-#define __CONTROLVMCOMPLETIONSTATUS_H__
-
-/* General Errors------------------------------------------------------[0-99] */
-#define CONTROLVM_RESP_SUCCESS 0
-#define CONTROLVM_RESP_ERROR_ALREADY_DONE 1
-#define CONTROLVM_RESP_ERROR_IOREMAP_FAILED 2
-#define CONTROLVM_RESP_ERROR_KMALLOC_FAILED 3
-#define CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN 4
-#define CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT 5
-
-/* CONTROLVM_INIT_CHIPSET-------------------------------------------[100-199] */
-#define CONTROLVM_RESP_ERROR_CLIENT_SWITCHCOUNT_NONZERO 100
-#define CONTROLVM_RESP_ERROR_EXPECTED_CHIPSET_INIT 101
-
-/* Maximum Limit----------------------------------------------------[200-299] */
-#define CONTROLVM_RESP_ERROR_MAX_BUSES 201 /* BUS_CREATE */
-#define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 /* DEVICE_CREATE */
-/* Payload and Parameter Related------------------------------------[400-499] */
-#define CONTROLVM_RESP_ERROR_PAYLOAD_INVALID 400 /* SWITCH_ATTACHEXTPORT,
- * DEVICE_CONFIGURE
- */
-#define CONTROLVM_RESP_ERROR_INITIATOR_PARAMETER_INVALID 401 /* Multiple */
-#define CONTROLVM_RESP_ERROR_TARGET_PARAMETER_INVALID 402 /* DEVICE_CONFIGURE */
-#define CONTROLVM_RESP_ERROR_CLIENT_PARAMETER_INVALID 403 /* DEVICE_CONFIGURE */
-/* Specified[Packet Structure] Value-------------------------------[500-599] */
-#define CONTROLVM_RESP_ERROR_BUS_INVALID 500 /* SWITCH_ATTACHINTPORT,
- * BUS_CONFIGURE,
- * DEVICE_CREATE,
- * DEVICE_CONFIG
- * DEVICE_DESTROY
- */
-#define CONTROLVM_RESP_ERROR_DEVICE_INVALID 501 /* SWITCH_ATTACHINTPORT */
- /* DEVICE_CREATE,
- * DEVICE_CONFIGURE,
- * DEVICE_DESTROY
- */
-#define CONTROLVM_RESP_ERROR_CHANNEL_INVALID 502 /* DEVICE_CREATE,
- * DEVICE_CONFIGURE
- */
-/* Partition Driver Callback Interface----------------------[600-699] */
-#define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE 604 /* BUS_CREATE,
- * BUS_DESTROY,
- * DEVICE_CREATE,
- * DEVICE_DESTROY
- */
-/* Unable to invoke VIRTPCI callback */
-#define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR 605
- /* BUS_CREATE,
- * BUS_DESTROY,
- * DEVICE_CREATE,
- * DEVICE_DESTROY
- */
-/* VIRTPCI Callback returned error */
-#define CONTROLVM_RESP_ERROR_GENERIC_DRIVER_CALLBACK_ERROR 606
- /* SWITCH_ATTACHEXTPORT,
- * SWITCH_DETACHEXTPORT
- * DEVICE_CONFIGURE
- */
-
-/* generic device callback returned error */
-/* Bus Related------------------------------------------------------[700-799] */
-#define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 /* BUS_DESTROY */
-/* Channel Related--------------------------------------------------[800-899] */
-#define CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN 800 /* GET_CHANNELINFO,
- * DEVICE_DESTROY
- */
-#define CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL 801 /* DEVICE_CREATE */
-/* Chipset Shutdown Related---------------------------------------[1000-1099] */
-#define CONTROLVM_RESP_ERROR_CHIPSET_SHUTDOWN_FAILED 1000
-#define CONTROLVM_RESP_ERROR_CHIPSET_SHUTDOWN_ALREADY_ACTIVE 1001
-
-/* Chipset Stop Related-------------------------------------------[1100-1199] */
-#define CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_BUS 1100
-#define CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_SWITCH 1101
-
-/* Device Related-------------------------------------------------[1400-1499] */
-#define CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT 1400
-
-#endif /* __CONTROLVMCOMPLETIONSTATUS_H__ not defined */
diff --git a/drivers/staging/unisys/visorbus/iovmcall_gnuc.h b/drivers/staging/unisys/visorbus/iovmcall_gnuc.h
deleted file mode 100644
index 98ea7f381a3c..000000000000
--- a/drivers/staging/unisys/visorbus/iovmcall_gnuc.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (C) 2010 - 2015 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-/* Linux GCC Version (32-bit and 64-bit) */
-static inline unsigned long
-__unisys_vmcall_gnuc(unsigned long tuple, unsigned long reg_ebx,
- unsigned long reg_ecx)
-{
- unsigned long result = 0;
- unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
-
- cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx);
- if (!(cpuid_ecx & 0x80000000))
- return -EPERM;
-
- __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
- "a"(tuple), "b"(reg_ebx), "c"(reg_ecx));
- return result;
-}
-
-static inline unsigned long
-__unisys_extended_vmcall_gnuc(unsigned long long tuple,
- unsigned long long reg_ebx,
- unsigned long long reg_ecx,
- unsigned long long reg_edx)
-{
- unsigned long result = 0;
- unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
-
- cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx);
- if (!(cpuid_ecx & 0x80000000))
- return -EPERM;
-
- __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
- "a"(tuple), "b"(reg_ebx), "c"(reg_ecx), "d"(reg_edx));
- return result;
-}
diff --git a/drivers/staging/unisys/visorbus/periodic_work.c b/drivers/staging/unisys/visorbus/periodic_work.c
deleted file mode 100644
index 00b152764f84..000000000000
--- a/drivers/staging/unisys/visorbus/periodic_work.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* periodic_work.c
- *
- * Copyright (C) 2010 - 2015 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-/*
- * Helper functions to schedule periodic work in Linux kernel mode.
- */
-#include <linux/sched.h>
-
-#include "periodic_work.h"
-
-#define MYDRVNAME "periodic_work"
-
-struct periodic_work {
- rwlock_t lock;
- struct delayed_work work;
- void (*workfunc)(void *);
- void *workfuncarg;
- bool is_scheduled;
- bool want_to_stop;
- ulong jiffy_interval;
- struct workqueue_struct *workqueue;
- const char *devnam;
-};
-
-static void periodic_work_func(struct work_struct *work)
-{
- struct periodic_work *pw;
-
- pw = container_of(work, struct periodic_work, work.work);
- (*pw->workfunc)(pw->workfuncarg);
-}
-
-struct periodic_work
-*visor_periodic_work_create(ulong jiffy_interval,
- struct workqueue_struct *workqueue,
- void (*workfunc)(void *),
- void *workfuncarg,
- const char *devnam)
-{
- struct periodic_work *pw;
-
- pw = kzalloc(sizeof(*pw), GFP_KERNEL | __GFP_NORETRY);
- if (!pw)
- return NULL;
-
- rwlock_init(&pw->lock);
- pw->jiffy_interval = jiffy_interval;
- pw->workqueue = workqueue;
- pw->workfunc = workfunc;
- pw->workfuncarg = workfuncarg;
- pw->devnam = devnam;
- return pw;
-}
-EXPORT_SYMBOL_GPL(visor_periodic_work_create);
-
-void visor_periodic_work_destroy(struct periodic_work *pw)
-{
- kfree(pw);
-}
-EXPORT_SYMBOL_GPL(visor_periodic_work_destroy);
-
-/** Call this from your periodic work worker function to schedule the next
- * call.
- * If this function returns false, there was a failure and the
- * periodic work is no longer scheduled
- */
-bool visor_periodic_work_nextperiod(struct periodic_work *pw)
-{
- bool rc = false;
-
- write_lock(&pw->lock);
- if (pw->want_to_stop) {
- pw->is_scheduled = false;
- pw->want_to_stop = false;
- rc = true; /* yes, true; see visor_periodic_work_stop() */
- goto unlock;
- } else if (!queue_delayed_work(pw->workqueue, &pw->work,
- pw->jiffy_interval)) {
- pw->is_scheduled = false;
- rc = false;
- goto unlock;
- }
- rc = true;
-unlock:
- write_unlock(&pw->lock);
- return rc;
-}
-EXPORT_SYMBOL_GPL(visor_periodic_work_nextperiod);
-
-/** This function returns true iff new periodic work was actually started.
- * If this function returns false, then no work was started
- * (either because it was already started, or because of a failure).
- */
-bool visor_periodic_work_start(struct periodic_work *pw)
-{
- bool rc = false;
-
- write_lock(&pw->lock);
- if (pw->is_scheduled) {
- rc = false;
- goto unlock;
- }
- if (pw->want_to_stop) {
- rc = false;
- goto unlock;
- }
- INIT_DELAYED_WORK(&pw->work, &periodic_work_func);
- if (!queue_delayed_work(pw->workqueue, &pw->work,
- pw->jiffy_interval)) {
- rc = false;
- goto unlock;
- }
- pw->is_scheduled = true;
- rc = true;
-unlock:
- write_unlock(&pw->lock);
- return rc;
-}
-EXPORT_SYMBOL_GPL(visor_periodic_work_start);
-
-/** This function returns true iff your call actually stopped the periodic
- * work.
- *
- * -- PAY ATTENTION... this is important --
- *
- * NO NO #1
- *
- * Do NOT call this function from some function that is running on the
- * same workqueue as the work you are trying to stop might be running
- * on! If you violate this rule, visor_periodic_work_stop() MIGHT work,
- * but it also MIGHT get hung up in an infinite loop saying
- * "waiting for delayed work...". This will happen if the delayed work
- * you are trying to cancel has been put in the workqueue list, but can't
- * run yet because we are running that same workqueue thread right now.
- *
- * Bottom line: If you need to call visor_periodic_work_stop() from a
- * workitem, be sure the workitem is on a DIFFERENT workqueue than the
- * workitem that you are trying to cancel.
- *
- * If I could figure out some way to check for this "no no" condition in
- * the code, I would. It would have saved me the trouble of writing this
- * long comment. And also, don't think this is some "theoretical" race
- * condition. It is REAL, as I have spent the day chasing it.
- *
- * NO NO #2
- *
- * Take close note of the locks that you own when you call this function.
- * You must NOT own any locks that are needed by the periodic work
- * function that is currently installed. If you DO, a deadlock may result,
- * because stopping the periodic work often involves waiting for the last
- * iteration of the periodic work function to complete. Again, if you hit
- * this deadlock, you will get hung up in an infinite loop saying
- * "waiting for delayed work...".
- */
-bool visor_periodic_work_stop(struct periodic_work *pw)
-{
- bool stopped_something = false;
-
- write_lock(&pw->lock);
- stopped_something = pw->is_scheduled && (!pw->want_to_stop);
- while (pw->is_scheduled) {
- pw->want_to_stop = true;
- if (cancel_delayed_work(&pw->work)) {
- /* We get here if the delayed work was pending as
- * delayed work, but was NOT run.
- */
- WARN_ON(!pw->is_scheduled);
- pw->is_scheduled = false;
- } else {
- /* If we get here, either the delayed work:
- * - was run, OR,
- * - is running RIGHT NOW on another processor, OR,
- * - wasn't even scheduled (there is a miniscule
- * timing window where this could be the case)
- * flush_workqueue() would make sure it is finished
- * executing, but that still isn't very useful, which
- * explains the loop...
- */
- }
- if (pw->is_scheduled) {
- write_unlock(&pw->lock);
- schedule_timeout_interruptible(msecs_to_jiffies(10));
- write_lock(&pw->lock);
- } else {
- pw->want_to_stop = false;
- }
- }
- write_unlock(&pw->lock);
- return stopped_something;
-}
-EXPORT_SYMBOL_GPL(visor_periodic_work_stop);
diff --git a/drivers/staging/unisys/visorbus/vbuschannel.h b/drivers/staging/unisys/visorbus/vbuschannel.h
index 90fa12e62f26..e97917522f6a 100644
--- a/drivers/staging/unisys/visorbus/vbuschannel.h
+++ b/drivers/staging/unisys/visorbus/vbuschannel.h
@@ -23,7 +23,6 @@
* the client devices and client drivers for the server end to see.
*/
#include <linux/uuid.h>
-#include "vbusdeviceinfo.h"
#include "channel.h"
/* {193b331b-c58f-11da-95a9-00e08161165f} */
@@ -58,6 +57,216 @@ static const uuid_le spar_vbus_channel_protocol_uuid =
actual_bytes))
#pragma pack(push, 1) /* both GCC and VC now allow this pragma */
+
+/*
+ * An array of this struct is present in the channel area for each vbus.
+ * (See vbuschannel.h.)
+ * It is filled in by the client side to provide info about the device
+ * and driver from the client's perspective.
+ */
+struct ultra_vbus_deviceinfo {
+ u8 devtype[16]; /* short string identifying the device type */
+ u8 drvname[16]; /* driver .sys file name */
+ u8 infostrs[96]; /* kernel version */
+ u8 reserved[128]; /* pad size to 256 bytes */
+};
+
+/**
+ * vbuschannel_sanitize_buffer() - remove non-printable chars from buffer
+ * @p: destination buffer where chars are written to
+ * @remain: number of bytes that can be written starting at #p
+ * @src: pointer to source buffer
+ * @srcmax: number of valid characters at #src
+ *
+ * Reads chars from the buffer at @src for @srcmax bytes, and writes to
+ * the buffer at @p, which is @remain bytes long, ensuring never to
+ * overflow the buffer at @p, using the following rules:
+ * - printable characters are simply copied from the buffer at @src to the
+ * buffer at @p
+ * - intervening streaks of non-printable characters in the buffer at @src
+ * are replaced with a single space in the buffer at @p
+ * Note that we pay no attention to '\0'-termination.
+ *
+ * Pass @p == NULL and @remain == 0 for this special behavior -- In this
+ * case, we simply return the number of bytes that WOULD HAVE been written
+ * to a buffer at @p, had it been infinitely big.
+ *
+ * Return: the number of bytes written to @p (or WOULD HAVE been written to
+ * @p, as described in the previous paragraph)
+ */
+static inline int
+vbuschannel_sanitize_buffer(char *p, int remain, char *src, int srcmax)
+{
+ int chars = 0;
+ int nonprintable_streak = 0;
+
+ while (srcmax > 0) {
+ if ((*src >= ' ') && (*src < 0x7f)) {
+ if (nonprintable_streak) {
+ if (remain > 0) {
+ *p = ' ';
+ p++;
+ remain--;
+ chars++;
+ } else if (!p) {
+ chars++;
+ }
+ nonprintable_streak = 0;
+ }
+ if (remain > 0) {
+ *p = *src;
+ p++;
+ remain--;
+ chars++;
+ } else if (!p) {
+ chars++;
+ }
+ } else {
+ nonprintable_streak = 1;
+ }
+ src++;
+ srcmax--;
+ }
+ return chars;
+}
+
+#define VBUSCHANNEL_ADDACHAR(ch, p, remain, chars) \
+ do { \
+ if (remain <= 0) \
+ break; \
+ *p = ch; \
+ p++; chars++; remain--; \
+ } while (0)
+
+/**
+ * vbuschannel_itoa() - convert non-negative int to string
+ * @p: destination string
+ * @remain: max number of bytes that can be written to @p
+ * @num: input int to convert
+ *
+ * Converts the non-negative value at @num to an ascii decimal string
+ * at @p, writing at most @remain bytes. Note there is NO '\0' termination
+ * written to @p.
+ *
+ * Return: number of bytes written to @p
+ *
+ */
+static inline int
+vbuschannel_itoa(char *p, int remain, int num)
+{
+ int digits = 0;
+ char s[32];
+ int i;
+
+ if (num == 0) {
+ /* '0' is a special case */
+ if (remain <= 0)
+ return 0;
+ *p = '0';
+ return 1;
+ }
+ /* form a backwards decimal ascii string in <s> */
+ while (num > 0) {
+ if (digits >= (int)sizeof(s))
+ return 0;
+ s[digits++] = (num % 10) + '0';
+ num = num / 10;
+ }
+ if (remain < digits) {
+ /* not enough room left at <p> to hold number, so fill with
+ * '?'
+ */
+ for (i = 0; i < remain; i++, p++)
+ *p = '?';
+ return remain;
+ }
+ /* plug in the decimal ascii string representing the number, by */
+ /* reversing the string we just built in <s> */
+ i = digits;
+ while (i > 0) {
+ i--;
+ *p = s[i];
+ p++;
+ }
+ return digits;
+}
+
+/**
+ * vbuschannel_devinfo_to_string() - format a struct ultra_vbus_deviceinfo
+ * to a printable string
+ * @devinfo: the struct ultra_vbus_deviceinfo to format
+ * @p: destination string area
+ * @remain: size of destination string area in bytes
+ * @devix: the device index to be included in the output data, or -1 if no
+ * device index is to be included
+ *
+ * Reads @devInfo, and converts its contents to a printable string at @p,
+ * writing at most @remain bytes. Note there is NO '\0' termination
+ * written to @p.
+ *
+ * Return: number of bytes written to @p
+ */
+static inline int
+vbuschannel_devinfo_to_string(struct ultra_vbus_deviceinfo *devinfo,
+ char *p, int remain, int devix)
+{
+ char *psrc;
+ int nsrc, x, i, pad;
+ int chars = 0;
+
+ psrc = &devinfo->devtype[0];
+ nsrc = sizeof(devinfo->devtype);
+ if (vbuschannel_sanitize_buffer(NULL, 0, psrc, nsrc) <= 0)
+ return 0;
+
+ /* emit device index */
+ if (devix >= 0) {
+ VBUSCHANNEL_ADDACHAR('[', p, remain, chars);
+ x = vbuschannel_itoa(p, remain, devix);
+ p += x;
+ remain -= x;
+ chars += x;
+ VBUSCHANNEL_ADDACHAR(']', p, remain, chars);
+ } else {
+ VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+ VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+ VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+ }
+
+ /* emit device type */
+ x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
+ p += x;
+ remain -= x;
+ chars += x;
+ pad = 15 - x; /* pad device type to be exactly 15 chars */
+ for (i = 0; i < pad; i++)
+ VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+ VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+
+ /* emit driver name */
+ psrc = &devinfo->drvname[0];
+ nsrc = sizeof(devinfo->drvname);
+ x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
+ p += x;
+ remain -= x;
+ chars += x;
+ pad = 15 - x; /* pad driver name to be exactly 15 chars */
+ for (i = 0; i < pad; i++)
+ VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+ VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+
+ /* emit strings */
+ psrc = &devinfo->infostrs[0];
+ nsrc = sizeof(devinfo->infostrs);
+ x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
+ p += x;
+ remain -= x;
+ chars += x;
+ VBUSCHANNEL_ADDACHAR('\n', p, remain, chars);
+
+ return chars;
+}
+
struct spar_vbus_headerinfo {
u32 struct_bytes; /* size of this struct in bytes */
u32 device_info_struct_bytes; /* sizeof(ULTRA_VBUS_DEVICEINFO) */
diff --git a/drivers/staging/unisys/visorbus/vbusdeviceinfo.h b/drivers/staging/unisys/visorbus/vbusdeviceinfo.h
deleted file mode 100644
index abdab4ad0b36..000000000000
--- a/drivers/staging/unisys/visorbus/vbusdeviceinfo.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/* Copyright (C) 2010 - 2015 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- */
-
-#ifndef __VBUSDEVICEINFO_H__
-#define __VBUSDEVICEINFO_H__
-
-#include <linux/types.h>
-
-#pragma pack(push, 1) /* both GCC and VC now allow this pragma */
-
-/* An array of this struct is present in the channel area for each vbus.
- * (See vbuschannel.h.)
- * It is filled in by the client side to provide info about the device
- * and driver from the client's perspective.
- */
-struct ultra_vbus_deviceinfo {
- u8 devtype[16]; /* short string identifying the device type */
- u8 drvname[16]; /* driver .sys file name */
- u8 infostrs[96]; /* sequence of tab-delimited id strings: */
- /* <DRIVER_REV> <DRIVER_VERTAG> <DRIVER_COMPILETIME> */
- u8 reserved[128]; /* pad size to 256 bytes */
-};
-
-#pragma pack(pop)
-
-/* Reads chars from the buffer at <src> for <srcmax> bytes, and writes to
- * the buffer at <p>, which is <remain> bytes long, ensuring never to
- * overflow the buffer at <p>, using the following rules:
- * - printable characters are simply copied from the buffer at <src> to the
- * buffer at <p>
- * - intervening streaks of non-printable characters in the buffer at <src>
- * are replaced with a single space in the buffer at <p>
- * Note that we pay no attention to '\0'-termination.
- * Returns the number of bytes written to <p>.
- *
- * Pass <p> == NULL and <remain> == 0 for this special behavior. In this
- * case, we simply return the number of bytes that WOULD HAVE been written
- * to a buffer at <p>, had it been infinitely big.
- */
-static inline int
-vbuschannel_sanitize_buffer(char *p, int remain, char *src, int srcmax)
-{
- int chars = 0;
- int nonprintable_streak = 0;
-
- while (srcmax > 0) {
- if ((*src >= ' ') && (*src < 0x7f)) {
- if (nonprintable_streak) {
- if (remain > 0) {
- *p = ' ';
- p++;
- remain--;
- chars++;
- } else if (!p) {
- chars++;
- }
- nonprintable_streak = 0;
- }
- if (remain > 0) {
- *p = *src;
- p++;
- remain--;
- chars++;
- } else if (!p) {
- chars++;
- }
- } else {
- nonprintable_streak = 1;
- }
- src++;
- srcmax--;
- }
- return chars;
-}
-
-#define VBUSCHANNEL_ADDACHAR(ch, p, remain, chars) \
- do { \
- if (remain <= 0) \
- break; \
- *p = ch; \
- p++; chars++; remain--; \
- } while (0)
-
-/* Converts the non-negative value at <num> to an ascii decimal string
- * at <p>, writing at most <remain> bytes. Note there is NO '\0' termination
- * written to <p>.
- *
- * Returns the number of bytes written to <p>.
- *
- * Note that we create this function because we need to do this operation in
- * an environment-independent way (since we are in a common header file).
- */
-static inline int
-vbuschannel_itoa(char *p, int remain, int num)
-{
- int digits = 0;
- char s[32];
- int i;
-
- if (num == 0) {
- /* '0' is a special case */
- if (remain <= 0)
- return 0;
- *p = '0';
- return 1;
- }
- /* form a backwards decimal ascii string in <s> */
- while (num > 0) {
- if (digits >= (int)sizeof(s))
- return 0;
- s[digits++] = (num % 10) + '0';
- num = num / 10;
- }
- if (remain < digits) {
- /* not enough room left at <p> to hold number, so fill with
- * '?'
- */
- for (i = 0; i < remain; i++, p++)
- *p = '?';
- return remain;
- }
- /* plug in the decimal ascii string representing the number, by */
- /* reversing the string we just built in <s> */
- i = digits;
- while (i > 0) {
- i--;
- *p = s[i];
- p++;
- }
- return digits;
-}
-
-/* Reads <devInfo>, and converts its contents to a printable string at <p>,
- * writing at most <remain> bytes. Note there is NO '\0' termination
- * written to <p>.
- *
- * Pass <devix> >= 0 if you want a device index presented.
- *
- * Returns the number of bytes written to <p>.
- */
-static inline int
-vbuschannel_devinfo_to_string(struct ultra_vbus_deviceinfo *devinfo,
- char *p, int remain, int devix)
-{
- char *psrc;
- int nsrc, x, i, pad;
- int chars = 0;
-
- psrc = &devinfo->devtype[0];
- nsrc = sizeof(devinfo->devtype);
- if (vbuschannel_sanitize_buffer(NULL, 0, psrc, nsrc) <= 0)
- return 0;
-
- /* emit device index */
- if (devix >= 0) {
- VBUSCHANNEL_ADDACHAR('[', p, remain, chars);
- x = vbuschannel_itoa(p, remain, devix);
- p += x;
- remain -= x;
- chars += x;
- VBUSCHANNEL_ADDACHAR(']', p, remain, chars);
- } else {
- VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
- VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
- VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
- }
-
- /* emit device type */
- x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
- p += x;
- remain -= x;
- chars += x;
- pad = 15 - x; /* pad device type to be exactly 15 chars */
- for (i = 0; i < pad; i++)
- VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
- VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
-
- /* emit driver name */
- psrc = &devinfo->drvname[0];
- nsrc = sizeof(devinfo->drvname);
- x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
- p += x;
- remain -= x;
- chars += x;
- pad = 15 - x; /* pad driver name to be exactly 15 chars */
- for (i = 0; i < pad; i++)
- VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
- VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
-
- /* emit strings */
- psrc = &devinfo->infostrs[0];
- nsrc = sizeof(devinfo->infostrs);
- x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
- p += x;
- remain -= x;
- chars += x;
- VBUSCHANNEL_ADDACHAR('\n', p, remain, chars);
-
- return chars;
-}
-
-#endif
diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c
index d32b8980a1cf..fec0a54916fe 100644
--- a/drivers/staging/unisys/visorbus/visorbus_main.c
+++ b/drivers/staging/unisys/visorbus/visorbus_main.c
@@ -18,62 +18,22 @@
#include "visorbus.h"
#include "visorbus_private.h"
-#include "version.h"
-#include "periodic_work.h"
-#include "vbuschannel.h"
-#include "guestlinuxdebug.h"
#include "vmcallinterface.h"
#define MYDRVNAME "visorbus"
/* module parameters */
-static int visorbus_debug;
static int visorbus_forcematch;
static int visorbus_forcenomatch;
-static int visorbus_debugref;
-#define SERIALLOOPBACKCHANADDR (100 * 1024 * 1024)
/* Display string that is guaranteed to be no longer the 99 characters*/
#define LINESIZE 99
#define CURRENT_FILE_PC VISOR_BUS_PC_visorbus_main_c
-#define POLLJIFFIES_TESTWORK 100
#define POLLJIFFIES_NORMALCHANNEL 10
static int busreg_rc = -ENODEV; /* stores the result from bus registration */
-static int visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env);
-static int visorbus_match(struct device *xdev, struct device_driver *xdrv);
-static void fix_vbus_dev_info(struct visor_device *visordev);
-
-/* BUS type attributes
- *
- * define & implement display of bus attributes under
- * /sys/bus/visorbus.
- *
- */
-
-static ssize_t version_show(struct bus_type *bus, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%s\n", VERSION);
-}
-
-static BUS_ATTR_RO(version);
-
-static struct attribute *visorbus_bus_attrs[] = {
- &bus_attr_version.attr,
- NULL,
-};
-
-static const struct attribute_group visorbus_bus_group = {
- .attrs = visorbus_bus_attrs,
-};
-
-static const struct attribute_group *visorbus_bus_groups[] = {
- &visorbus_bus_group,
- NULL,
-};
-
/*
* DEVICE type attributes
*
@@ -106,61 +66,14 @@ static const struct attribute_group *visorbus_dev_groups[] = {
NULL,
};
-/** This describes the TYPE of bus.
- * (Don't confuse this with an INSTANCE of the bus.)
- */
-struct bus_type visorbus_type = {
- .name = "visorbus",
- .match = visorbus_match,
- .uevent = visorbus_uevent,
- .dev_groups = visorbus_dev_groups,
- .bus_groups = visorbus_bus_groups,
-};
-
-static struct delayed_work periodic_work;
-
-/* YES, we need 2 workqueues.
- * The reason is, workitems on the test queue may need to cancel
- * workitems on the other queue. You will be in for trouble if you try to
- * do this with workitems queued on the same workqueue.
- */
-static struct workqueue_struct *periodic_test_workqueue;
-static struct workqueue_struct *periodic_dev_workqueue;
-static long long bus_count; /** number of bus instances */
- /** ever-increasing */
-
-static void chipset_bus_create(struct visor_device *bus_info);
-static void chipset_bus_destroy(struct visor_device *bus_info);
-static void chipset_device_create(struct visor_device *dev_info);
-static void chipset_device_destroy(struct visor_device *dev_info);
-static void chipset_device_pause(struct visor_device *dev_info);
-static void chipset_device_resume(struct visor_device *dev_info);
-
-/** These functions are implemented herein, and are called by the chipset
- * driver to notify us about specific events.
- */
-static struct visorchipset_busdev_notifiers chipset_notifiers = {
- .bus_create = chipset_bus_create,
- .bus_destroy = chipset_bus_destroy,
- .device_create = chipset_device_create,
- .device_destroy = chipset_device_destroy,
- .device_pause = chipset_device_pause,
- .device_resume = chipset_device_resume,
-};
-
-/** These functions are implemented in the chipset driver, and we call them
- * herein when we want to acknowledge a specific event.
- */
-static struct visorchipset_busdev_responders chipset_responders;
-
/* filled in with info about parent chipset driver when we register with it */
static struct ultra_vbus_deviceinfo chipset_driverinfo;
/* filled in with info about this driver, wrt it servicing client busses */
static struct ultra_vbus_deviceinfo clientbus_driverinfo;
-/** list of visor_device structs, linked via .list_all */
+/* list of visor_device structs, linked via .list_all */
static LIST_HEAD(list_all_bus_instances);
-/** list of visor_device structs, linked via .list_all */
+/* list of visor_device structs, linked via .list_all */
static LIST_HEAD(list_all_device_instances);
static int
@@ -177,9 +90,14 @@ visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env)
return 0;
}
-/* This is called automatically upon adding a visor_device (device_add), or
- * adding a visor_driver (visorbus_register_visor_driver), and returns 1 iff the
- * provided driver can control the specified device.
+/**
+ * visorbus_match() - called automatically upon adding a visor_device
+ * (device_add), or adding a visor_driver
+ * (visorbus_register_visor_driver)
+ * @xdev: struct device for the device being matched
+ * @xdrv: struct device_driver for driver to match device against
+ *
+ * Return: 1 iff the provided driver can control the specified device
*/
static int
visorbus_match(struct device *xdev, struct device_driver *xdrv)
@@ -211,9 +129,22 @@ visorbus_match(struct device *xdev, struct device_driver *xdrv)
return 0;
}
-/** This is called when device_unregister() is called for the bus device
- * instance, after all other tasks involved with destroying the device
- * are complete.
+/*
+ * This describes the TYPE of bus.
+ * (Don't confuse this with an INSTANCE of the bus.)
+ */
+struct bus_type visorbus_type = {
+ .name = "visorbus",
+ .match = visorbus_match,
+ .uevent = visorbus_uevent,
+ .dev_groups = visorbus_dev_groups,
+};
+
+/**
+ * visorbus_releae_busdevice() - called when device_unregister() is called for
+ * the bus device instance, after all other tasks
+ * involved with destroying the dev are complete
+ * @xdev: struct device for the bus being released
*/
static void
visorbus_release_busdevice(struct device *xdev)
@@ -223,18 +154,16 @@ visorbus_release_busdevice(struct device *xdev)
kfree(dev);
}
-/** This is called when device_unregister() is called for each child
- * device instance.
+/**
+ * visorbus_release_device() - called when device_unregister() is called for
+ * each child device instance
+ * @xdev: struct device for the visor device being released
*/
static void
visorbus_release_device(struct device *xdev)
{
struct visor_device *dev = to_visor_device(xdev);
- if (dev->periodic_work) {
- visor_periodic_work_destroy(dev->periodic_work);
- dev->periodic_work = NULL;
- }
if (dev->visorchannel) {
visorchannel_destroy(dev->visorchannel);
dev->visorchannel = NULL;
@@ -242,9 +171,11 @@ visorbus_release_device(struct device *xdev)
kfree(dev);
}
-/* begin implementation of specific channel attributes to appear under
-* /sys/bus/visorbus<x>/dev<y>/channel
-*/
+/*
+ * begin implementation of specific channel attributes to appear under
+ * /sys/bus/visorbus<x>/dev<y>/channel
+ */
+
static ssize_t physaddr_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -349,15 +280,11 @@ static const struct attribute_group *visorbus_channel_groups[] = {
/* end implementation of specific channel attributes */
-/* BUS instance attributes
+/*
+ * BUS instance attributes
*
* define & implement display of bus attributes under
- * /sys/bus/visorbus/busses/visorbus<n>.
- *
- * This is a bit hoaky because the kernel does not yet have the infrastructure
- * to separate bus INSTANCE attributes from bus TYPE attributes...
- * so we roll our own. See businst.c / businst.h.
- *
+ * /sys/bus/visorbus/devices/visorbus<n>.
*/
static ssize_t partition_handle_show(struct device *dev,
@@ -434,8 +361,8 @@ static ssize_t client_bus_info_show(struct device *dev,
if (vdev->name)
partition_name = vdev->name;
shift = snprintf(pos, remain,
- "Client device / client driver info for %s eartition (vbus #%d):\n",
- partition_name, vdev->chipset_dev_no);
+ "Client device / client driver info for %s partition (vbus #%u):\n",
+ partition_name, vdev->chipset_bus_no);
pos += shift;
remain -= shift;
shift = visorchannel_read(channel,
@@ -508,103 +435,48 @@ static const struct attribute_group *visorbus_groups[] = {
NULL
};
-/* DRIVER attributes
- *
- * define & implement display of driver attributes under
- * /sys/bus/visorbus/drivers/<drivername>.
- *
- */
-
-static ssize_t
-DRIVER_ATTR_version(struct device_driver *xdrv, char *buf)
-{
- struct visor_driver *drv = to_visor_driver(xdrv);
-
- return snprintf(buf, PAGE_SIZE, "%s\n", drv->version);
-}
-
-static int
-register_driver_attributes(struct visor_driver *drv)
-{
- struct driver_attribute version =
- __ATTR(version, S_IRUGO, DRIVER_ATTR_version, NULL);
- drv->version_attr = version;
- return driver_create_file(&drv->driver, &drv->version_attr);
-}
-
-static void
-unregister_driver_attributes(struct visor_driver *drv)
-{
- driver_remove_file(&drv->driver, &drv->version_attr);
-}
-
static void
-dev_periodic_work(void *xdev)
+dev_periodic_work(unsigned long __opaque)
{
- struct visor_device *dev = xdev;
+ struct visor_device *dev = (struct visor_device *)__opaque;
struct visor_driver *drv = to_visor_driver(dev->device.driver);
- down(&dev->visordriver_callback_lock);
if (drv->channel_interrupt)
drv->channel_interrupt(dev);
- up(&dev->visordriver_callback_lock);
- if (!visor_periodic_work_nextperiod(dev->periodic_work))
- put_device(&dev->device);
+ mod_timer(&dev->timer, jiffies + POLLJIFFIES_NORMALCHANNEL);
}
static void
dev_start_periodic_work(struct visor_device *dev)
{
- if (dev->being_removed)
+ if (dev->being_removed || dev->timer_active)
return;
/* now up by at least 2 */
get_device(&dev->device);
- if (!visor_periodic_work_start(dev->periodic_work))
- put_device(&dev->device);
+ dev->timer.expires = jiffies + POLLJIFFIES_NORMALCHANNEL;
+ add_timer(&dev->timer);
+ dev->timer_active = true;
}
static void
dev_stop_periodic_work(struct visor_device *dev)
{
- if (visor_periodic_work_stop(dev->periodic_work))
- put_device(&dev->device);
-}
-
-/** This is called automatically upon adding a visor_device (device_add), or
- * adding a visor_driver (visorbus_register_visor_driver), but only after
- * visorbus_match has returned 1 to indicate a successful match between
- * driver and device.
- */
-static int
-visordriver_probe_device(struct device *xdev)
-{
- int res;
- struct visor_driver *drv;
- struct visor_device *dev;
-
- drv = to_visor_driver(xdev->driver);
- dev = to_visor_device(xdev);
-
- if (!drv->probe)
- return -ENODEV;
-
- down(&dev->visordriver_callback_lock);
- dev->being_removed = false;
-
- res = drv->probe(dev);
- if (res >= 0) {
- /* success: reference kept via unmatched get_device() */
- get_device(&dev->device);
- fix_vbus_dev_info(dev);
- }
-
- up(&dev->visordriver_callback_lock);
- return res;
+ if (!dev->timer_active)
+ return;
+ del_timer_sync(&dev->timer);
+ dev->timer_active = false;
+ put_device(&dev->device);
}
-/** This is called when device_unregister() is called for each child device
- * instance, to notify the appropriate visorbus_driver that the device is
- * going away, and to decrease the reference count of the device.
+/**
+ * visordriver_remove_device() - handle visor device going away
+ * @xdev: struct device for the visor device being removed
+ *
+ * This is called when device_unregister() is called for each child device
+ * instance, to notify the appropriate visorbus function driver that the device
+ * is going away, and to decrease the reference count of the device.
+ *
+ * Return: 0 iff successful
*/
static int
visordriver_remove_device(struct device *xdev)
@@ -614,105 +486,44 @@ visordriver_remove_device(struct device *xdev)
dev = to_visor_device(xdev);
drv = to_visor_driver(xdev->driver);
- down(&dev->visordriver_callback_lock);
+ mutex_lock(&dev->visordriver_callback_lock);
dev->being_removed = true;
if (drv->remove)
drv->remove(dev);
- up(&dev->visordriver_callback_lock);
+ mutex_unlock(&dev->visordriver_callback_lock);
dev_stop_periodic_work(dev);
put_device(&dev->device);
return 0;
}
-/** A particular type of visor driver calls this function to register
- * the driver. The caller MUST fill in the following fields within the
- * #drv structure:
- * name, version, owner, channel_types, probe, remove
+/**
+ * visorbus_unregister_visor_driver() - unregisters the provided driver
+ * @drv: the driver to unregister
*
- * Here's how the whole Linux bus / driver / device model works.
- *
- * At system start-up, the visorbus kernel module is loaded, which registers
- * visorbus_type as a bus type, using bus_register().
- *
- * All kernel modules that support particular device types on a
- * visorbus bus are loaded. Each of these kernel modules calls
- * visorbus_register_visor_driver() in their init functions, passing a
- * visor_driver struct. visorbus_register_visor_driver() in turn calls
- * register_driver(&visor_driver.driver). This .driver member is
- * initialized with generic methods (like probe), whose sole responsibility
- * is to act as a broker for the real methods, which are within the
- * visor_driver struct. (This is the way the subclass behavior is
- * implemented, since visor_driver is essentially a subclass of the
- * generic driver.) Whenever a driver_register() happens, core bus code in
- * the kernel does (see device_attach() in drivers/base/dd.c):
- *
- * for each dev associated with the bus (the bus that driver is on) that
- * does not yet have a driver
- * if bus.match(dev,newdriver) == yes_matched ** .match specified
- * ** during bus_register().
- * newdriver.probe(dev) ** for visor drivers, this will call
- * ** the generic driver.probe implemented in visorbus.c,
- * ** which in turn calls the probe specified within the
- * ** struct visor_driver (which was specified by the
- * ** actual device driver as part of
- * ** visorbus_register_visor_driver()).
- *
- * The above dance also happens when a new device appears.
- * So the question is, how are devices created within the system?
- * Basically, just call device_add(dev). See pci_bus_add_devices().
- * pci_scan_device() shows an example of how to build a device struct. It
- * returns the newly-created struct to pci_scan_single_device(), who adds it
- * to the list of devices at PCIBUS.devices. That list of devices is what
- * is traversed by pci_bus_add_devices().
- *
- */
-int visorbus_register_visor_driver(struct visor_driver *drv)
-{
- int rc = 0;
-
- if (busreg_rc < 0)
- return -ENODEV; /*can't register on a nonexistent bus*/
-
- drv->driver.name = drv->name;
- drv->driver.bus = &visorbus_type;
- drv->driver.probe = visordriver_probe_device;
- drv->driver.remove = visordriver_remove_device;
- drv->driver.owner = drv->owner;
-
- /* driver_register does this:
- * bus_add_driver(drv)
- * ->if (drv.bus) ** (bus_type) **
- * driver_attach(drv)
- * for each dev with bus type of drv.bus
- * if (!dev.drv) ** no driver assigned yet **
- * if (bus.match(dev,drv)) [visorbus_match]
- * dev.drv = drv
- * if (!drv.probe(dev)) [visordriver_probe_device]
- * dev.drv = NULL
- */
-
- rc = driver_register(&drv->driver);
- if (rc < 0)
- return rc;
- rc = register_driver_attributes(drv);
- if (rc < 0)
- driver_unregister(&drv->driver);
- return rc;
-}
-EXPORT_SYMBOL_GPL(visorbus_register_visor_driver);
-
-/** A particular type of visor driver calls this function to unregister
- * the driver, i.e., within its module_exit function.
+ * A visor function driver calls this function to unregister the driver,
+ * i.e., within its module_exit function.
*/
void
visorbus_unregister_visor_driver(struct visor_driver *drv)
{
- unregister_driver_attributes(drv);
driver_unregister(&drv->driver);
}
EXPORT_SYMBOL_GPL(visorbus_unregister_visor_driver);
+/**
+ * visorbus_read_channel() - reads from the designated channel into
+ * the provided buffer
+ * @dev: the device whose channel is read from
+ * @offset: the offset into the channel at which reading starts
+ * @dest: the destination buffer that is written into from the channel
+ * @nbytes: the number of bytes to read from the channel
+ *
+ * If receiving a message, use the visorchannel_signalremove()
+ * function instead.
+ *
+ * Return: integer indicating success (zero) or failure (non-zero)
+ */
int
visorbus_read_channel(struct visor_device *dev, unsigned long offset,
void *dest, unsigned long nbytes)
@@ -721,6 +532,19 @@ visorbus_read_channel(struct visor_device *dev, unsigned long offset,
}
EXPORT_SYMBOL_GPL(visorbus_read_channel);
+/**
+ * visorbus_write_channel() - writes the provided buffer into the designated
+ * channel
+ * @dev: the device whose channel is written to
+ * @offset: the offset into the channel at which writing starts
+ * @src: the source buffer that is written into the channel
+ * @nbytes: the number of bytes to write into the channel
+ *
+ * If sending a message, use the visorchannel_signalinsert()
+ * function instead.
+ *
+ * Return: integer indicating success (zero) or failure (non-zero)
+ */
int
visorbus_write_channel(struct visor_device *dev, unsigned long offset,
void *src, unsigned long nbytes)
@@ -729,16 +553,13 @@ visorbus_write_channel(struct visor_device *dev, unsigned long offset,
}
EXPORT_SYMBOL_GPL(visorbus_write_channel);
-int
-visorbus_clear_channel(struct visor_device *dev, unsigned long offset, u8 ch,
- unsigned long nbytes)
-{
- return visorchannel_clear(dev->visorchannel, offset, ch, nbytes);
-}
-EXPORT_SYMBOL_GPL(visorbus_clear_channel);
-
-/** We don't really have a real interrupt, so for now we just call the
- * interrupt function periodically...
+/**
+ * visorbus_enable_channel_interrupts() - enables interrupts on the
+ * designated device
+ * @dev: the device on which to enable interrupts
+ *
+ * Currently we don't yet have a real interrupt, so for now we just call the
+ * interrupt function periodically via a timer.
*/
void
visorbus_enable_channel_interrupts(struct visor_device *dev)
@@ -747,6 +568,11 @@ visorbus_enable_channel_interrupts(struct visor_device *dev)
}
EXPORT_SYMBOL_GPL(visorbus_enable_channel_interrupts);
+/**
+ * visorbus_disable_channel_interrupts() - disables interrupts on the
+ * designated device
+ * @dev: the device on which to disable interrupts
+ */
void
visorbus_disable_channel_interrupts(struct visor_device *dev)
{
@@ -754,19 +580,28 @@ visorbus_disable_channel_interrupts(struct visor_device *dev)
}
EXPORT_SYMBOL_GPL(visorbus_disable_channel_interrupts);
-/** This is how everything starts from the device end.
- * This function is called when a channel first appears via a ControlVM
- * message. In response, this function allocates a visor_device to
- * correspond to the new channel, and attempts to connect it the appropriate
- * driver. If the appropriate driver is found, the visor_driver.probe()
- * function for that driver will be called, and will be passed the new
- * visor_device that we just created.
+/**
+ * create_visor_device() - create visor device as a result of receiving the
+ * controlvm device_create message for a new device
+ * @dev: a freshly-zeroed struct visor_device, containing only filled-in values
+ * for chipset_bus_no and chipset_dev_no, that will be initialized
+ *
+ * This is how everything starts from the device end.
+ * This function is called when a channel first appears via a ControlVM
+ * message. In response, this function allocates a visor_device to
+ * correspond to the new channel, and attempts to connect it the appropriate
+ * driver. If the appropriate driver is found, the visor_driver.probe()
+ * function for that driver will be called, and will be passed the new
+ * visor_device that we just created.
+ *
+ * It's ok if the appropriate driver is not yet loaded, because in that case
+ * the new device struct will just stick around in the bus' list of devices.
+ * When the appropriate driver calls visorbus_register_visor_driver(), the
+ * visor_driver.probe() for the new driver will be called with the new
+ * device.
*
- * It's ok if the appropriate driver is not yet loaded, because in that case
- * the new device struct will just stick around in the bus' list of devices.
- * When the appropriate driver calls visorbus_register_visor_driver(), the
- * visor_driver.probe() for the new driver will be called with the new
- * device.
+ * Return: 0 if successful, otherwise the negative value returned by
+ * device_add() indicating the reason for failure
*/
static int
create_visor_device(struct visor_device *dev)
@@ -778,33 +613,27 @@ create_visor_device(struct visor_device *dev)
POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, chipset_dev_no, chipset_bus_no,
POSTCODE_SEVERITY_INFO);
- sema_init(&dev->visordriver_callback_lock, 1); /* unlocked */
+ mutex_init(&dev->visordriver_callback_lock);
dev->device.bus = &visorbus_type;
dev->device.groups = visorbus_channel_groups;
device_initialize(&dev->device);
dev->device.release = visorbus_release_device;
/* keep a reference just for us (now 2) */
get_device(&dev->device);
- dev->periodic_work =
- visor_periodic_work_create(POLLJIFFIES_NORMALCHANNEL,
- periodic_dev_workqueue,
- dev_periodic_work,
- dev, dev_name(&dev->device));
- if (!dev->periodic_work) {
- POSTCODE_LINUX_3(DEVICE_CREATE_FAILURE_PC, chipset_dev_no,
- DIAG_SEVERITY_ERR);
- err = -EINVAL;
- goto err_put;
- }
+ init_timer(&dev->timer);
+ dev->timer.data = (unsigned long)(dev);
+ dev->timer.function = dev_periodic_work;
- /* bus_id must be a unique name with respect to this bus TYPE
+ /*
+ * bus_id must be a unique name with respect to this bus TYPE
* (NOT bus instance). That's why we need to include the bus
* number within the name.
*/
dev_set_name(&dev->device, "vbus%u:dev%u",
chipset_bus_no, chipset_dev_no);
- /* device_add does this:
+ /*
+ * device_add does this:
* bus_add_device(dev)
* ->device_attach(dev)
* ->for each driver drv registered on the bus that dev is on
@@ -864,11 +693,20 @@ get_vbus_header_info(struct visorchannel *chan,
return 0;
}
-/* Write the contents of <info> to the struct
- * spar_vbus_channel_protocol.chp_info.
+/**
+ * write_vbus_chp_info() - write the contents of <info> to the struct
+ * spar_vbus_channel_protocol.chp_info
+ * @chan: indentifies the s-Par channel that will be updated
+ * @hdr_info: used to find appropriate channel offset to write data
+ * @info: contains the information to write
+ *
+ * Writes chipset info into the channel memory to be used for diagnostic
+ * purposes.
+ *
+ * Returns no value since this is debug information and not needed for
+ * device functionality.
*/
-
-static int
+static void
write_vbus_chp_info(struct visorchannel *chan,
struct spar_vbus_headerinfo *hdr_info,
struct ultra_vbus_deviceinfo *info)
@@ -876,18 +714,25 @@ write_vbus_chp_info(struct visorchannel *chan,
int off = sizeof(struct channel_header) + hdr_info->chp_info_offset;
if (hdr_info->chp_info_offset == 0)
- return -EFAULT;
+ return;
- if (visorchannel_write(chan, off, info, sizeof(*info)) < 0)
- return -EFAULT;
- return 0;
+ visorchannel_write(chan, off, info, sizeof(*info));
}
-/* Write the contents of <info> to the struct
- * spar_vbus_channel_protocol.bus_info.
+/**
+ * write_vbus_bus_info() - write the contents of <info> to the struct
+ * spar_vbus_channel_protocol.bus_info
+ * @chan: indentifies the s-Par channel that will be updated
+ * @hdr_info: used to find appropriate channel offset to write data
+ * @info: contains the information to write
+ *
+ * Writes bus info into the channel memory to be used for diagnostic
+ * purposes.
+ *
+ * Returns no value since this is debug information and not needed for
+ * device functionality.
*/
-
-static int
+static void
write_vbus_bus_info(struct visorchannel *chan,
struct spar_vbus_headerinfo *hdr_info,
struct ultra_vbus_deviceinfo *info)
@@ -895,37 +740,46 @@ write_vbus_bus_info(struct visorchannel *chan,
int off = sizeof(struct channel_header) + hdr_info->bus_info_offset;
if (hdr_info->bus_info_offset == 0)
- return -EFAULT;
+ return;
- if (visorchannel_write(chan, off, info, sizeof(*info)) < 0)
- return -EFAULT;
- return 0;
+ visorchannel_write(chan, off, info, sizeof(*info));
}
-/* Write the contents of <info> to the
- * struct spar_vbus_channel_protocol.dev_info[<devix>].
+/**
+ * write_vbus_dev_info() - write the contents of <info> to the struct
+ * spar_vbus_channel_protocol.dev_info[<devix>]
+ * @chan: indentifies the s-Par channel that will be updated
+ * @hdr_info: used to find appropriate channel offset to write data
+ * @info: contains the information to write
+ * @devix: the relative device number (0..n-1) of the device on the bus
+ *
+ * Writes device info into the channel memory to be used for diagnostic
+ * purposes.
+ *
+ * Returns no value since this is debug information and not needed for
+ * device functionality.
*/
-static int
+static void
write_vbus_dev_info(struct visorchannel *chan,
struct spar_vbus_headerinfo *hdr_info,
- struct ultra_vbus_deviceinfo *info, int devix)
+ struct ultra_vbus_deviceinfo *info, unsigned int devix)
{
int off =
(sizeof(struct channel_header) + hdr_info->dev_info_offset) +
(hdr_info->device_info_struct_bytes * devix);
if (hdr_info->dev_info_offset == 0)
- return -EFAULT;
+ return;
- if (visorchannel_write(chan, off, info, sizeof(*info)) < 0)
- return -EFAULT;
- return 0;
+ visorchannel_write(chan, off, info, sizeof(*info));
}
-/* For a child device just created on a client bus, fill in
- * information about the driver that is controlling this device into
- * the the appropriate slot within the vbus channel of the bus
- * instance.
+/**
+ * fix_vbus_dev_info() - for a child device just created on a client bus, fill
+ * in information about the driver that is controlling
+ * this device into the the appropriate slot within the
+ * vbus channel of the bus instance
+ * @visordev: struct visor_device for the desired device
*/
static void
fix_vbus_dev_info(struct visor_device *visordev)
@@ -933,8 +787,8 @@ fix_vbus_dev_info(struct visor_device *visordev)
int i;
struct visor_device *bdev;
struct visor_driver *visordrv;
- int bus_no = visordev->chipset_bus_no;
- int dev_no = visordev->chipset_dev_no;
+ u32 bus_no = visordev->chipset_bus_no;
+ u32 dev_no = visordev->chipset_dev_no;
struct ultra_vbus_deviceinfo dev_info;
const char *chan_type_name = NULL;
struct spar_vbus_headerinfo *hdr_info;
@@ -942,17 +796,16 @@ fix_vbus_dev_info(struct visor_device *visordev)
if (!visordev->device.driver)
return;
- hdr_info = (struct spar_vbus_headerinfo *)visordev->vbus_hdr_info;
- if (!hdr_info)
- return;
-
bdev = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL);
if (!bdev)
return;
-
+ hdr_info = (struct spar_vbus_headerinfo *)bdev->vbus_hdr_info;
+ if (!hdr_info)
+ return;
visordrv = to_visor_driver(visordev->device.driver);
- /* Within the list of device types (by GUID) that the driver
+ /*
+ * Within the list of device types (by GUID) that the driver
* says it supports, find out which one of those types matches
* the type of this device, so that we can include the device
* type name
@@ -966,20 +819,148 @@ fix_vbus_dev_info(struct visor_device *visordev)
}
}
- bus_device_info_init(&dev_info, chan_type_name,
- visordrv->name, visordrv->version,
- visordrv->vertag);
+ bus_device_info_init(&dev_info, chan_type_name, visordrv->name);
write_vbus_dev_info(bdev->visorchannel, hdr_info, &dev_info, dev_no);
- /* Re-write bus+chipset info, because it is possible that this
- * was previously written by our evil counterpart, virtpci.
- */
+ /*
+ * Re-write bus+chipset info, because it is possible that this
+ * was previously written by our evil counterpart, virtpci.
+ */
write_vbus_chp_info(bdev->visorchannel, hdr_info, &chipset_driverinfo);
write_vbus_bus_info(bdev->visorchannel, hdr_info,
&clientbus_driverinfo);
}
-/** Create a device instance for the visor bus itself.
+/**
+ * visordriver_probe_device() - handle new visor device coming online
+ * @xdev: struct device for the visor device being probed
+ *
+ * This is called automatically upon adding a visor_device (device_add), or
+ * adding a visor_driver (visorbus_register_visor_driver), but only after
+ * visorbus_match() has returned 1 to indicate a successful match between
+ * driver and device.
+ *
+ * If successful, a reference to the device will be held onto via get_device().
+ *
+ * Return: 0 if successful, meaning the function driver's probe() function
+ * was successful with this device, otherwise a negative errno
+ * value indicating failure reason
+ */
+static int
+visordriver_probe_device(struct device *xdev)
+{
+ int res;
+ struct visor_driver *drv;
+ struct visor_device *dev;
+
+ drv = to_visor_driver(xdev->driver);
+ dev = to_visor_device(xdev);
+
+ if (!drv->probe)
+ return -ENODEV;
+
+ mutex_lock(&dev->visordriver_callback_lock);
+ dev->being_removed = false;
+
+ res = drv->probe(dev);
+ if (res >= 0) {
+ /* success: reference kept via unmatched get_device() */
+ get_device(&dev->device);
+ fix_vbus_dev_info(dev);
+ }
+
+ mutex_unlock(&dev->visordriver_callback_lock);
+ return res;
+}
+
+/**
+ * visorbus_register_visor_driver() - registers the provided visor driver
+ * for handling one or more visor device
+ * types (channel_types)
+ * @drv: the driver to register
+ *
+ * A visor function driver calls this function to register
+ * the driver. The caller MUST fill in the following fields within the
+ * #drv structure:
+ * name, version, owner, channel_types, probe, remove
+ *
+ * Here's how the whole Linux bus / driver / device model works.
+ *
+ * At system start-up, the visorbus kernel module is loaded, which registers
+ * visorbus_type as a bus type, using bus_register().
+ *
+ * All kernel modules that support particular device types on a
+ * visorbus bus are loaded. Each of these kernel modules calls
+ * visorbus_register_visor_driver() in their init functions, passing a
+ * visor_driver struct. visorbus_register_visor_driver() in turn calls
+ * register_driver(&visor_driver.driver). This .driver member is
+ * initialized with generic methods (like probe), whose sole responsibility
+ * is to act as a broker for the real methods, which are within the
+ * visor_driver struct. (This is the way the subclass behavior is
+ * implemented, since visor_driver is essentially a subclass of the
+ * generic driver.) Whenever a driver_register() happens, core bus code in
+ * the kernel does (see device_attach() in drivers/base/dd.c):
+ *
+ * for each dev associated with the bus (the bus that driver is on) that
+ * does not yet have a driver
+ * if bus.match(dev,newdriver) == yes_matched ** .match specified
+ * ** during bus_register().
+ * newdriver.probe(dev) ** for visor drivers, this will call
+ * ** the generic driver.probe implemented in visorbus.c,
+ * ** which in turn calls the probe specified within the
+ * ** struct visor_driver (which was specified by the
+ * ** actual device driver as part of
+ * ** visorbus_register_visor_driver()).
+ *
+ * The above dance also happens when a new device appears.
+ * So the question is, how are devices created within the system?
+ * Basically, just call device_add(dev). See pci_bus_add_devices().
+ * pci_scan_device() shows an example of how to build a device struct. It
+ * returns the newly-created struct to pci_scan_single_device(), who adds it
+ * to the list of devices at PCIBUS.devices. That list of devices is what
+ * is traversed by pci_bus_add_devices().
+ *
+ * Return: integer indicating success (zero) or failure (non-zero)
+ */
+int visorbus_register_visor_driver(struct visor_driver *drv)
+{
+ int rc = 0;
+
+ if (busreg_rc < 0)
+ return -ENODEV; /*can't register on a nonexistent bus*/
+
+ drv->driver.name = drv->name;
+ drv->driver.bus = &visorbus_type;
+ drv->driver.probe = visordriver_probe_device;
+ drv->driver.remove = visordriver_remove_device;
+ drv->driver.owner = drv->owner;
+
+ /*
+ * driver_register does this:
+ * bus_add_driver(drv)
+ * ->if (drv.bus) ** (bus_type) **
+ * driver_attach(drv)
+ * for each dev with bus type of drv.bus
+ * if (!dev.drv) ** no driver assigned yet **
+ * if (bus.match(dev,drv)) [visorbus_match]
+ * dev.drv = drv
+ * if (!drv.probe(dev)) [visordriver_probe_device]
+ * dev.drv = NULL
+ */
+
+ rc = driver_register(&drv->driver);
+ if (rc < 0)
+ driver_unregister(&drv->driver);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(visorbus_register_visor_driver);
+
+/**
+ * create_bus_instance() - create a device instance for the visor bus itself
+ * @dev: struct visor_device indicating the bus instance
+ *
+ * Return: 0 for success, otherwise negative errno value indicating reason for
+ * failure
*/
static int
create_bus_instance(struct visor_device *dev)
@@ -1014,25 +995,26 @@ create_bus_instance(struct visor_device *dev)
} else {
kfree(hdr_info);
}
- bus_count++;
list_add_tail(&dev->list_all, &list_all_bus_instances);
dev_set_drvdata(&dev->device, dev);
return 0;
}
-/** Remove a device instance for the visor bus itself.
+/**
+ * remove_bus_instance() - remove a device instance for the visor bus itself
+ * @dev: struct visor_device indentifying the bus to remove
*/
static void
remove_bus_instance(struct visor_device *dev)
{
- /* Note that this will result in the release method for
+ /*
+ * Note that this will result in the release method for
* dev->dev being called, which will call
* visorbus_release_busdevice(). This has something to do with
* the put_device() done in device_unregister(), but I have never
* successfully been able to trace thru the code to see where/how
* release() gets called. But I know it does.
*/
- bus_count--;
if (dev->visorchannel) {
visorchannel_destroy(dev->visorchannel);
dev->visorchannel = NULL;
@@ -1042,8 +1024,11 @@ remove_bus_instance(struct visor_device *dev)
device_unregister(&dev->device);
}
-/** Create and register the one-and-only one instance of
- * the visor bus type (visorbus_type).
+/**
+ * create_bus_type() - create and register the one-and-only one instance of
+ * the visor bus type (visorbus_type)
+ * Return: 0 for success, otherwise negative errno value returned by
+ * bus_register() indicating the reason for failure
*/
static int
create_bus_type(void)
@@ -1052,7 +1037,9 @@ create_bus_type(void)
return busreg_rc;
}
-/** Remove the one-and-only one instance of the visor bus type (visorbus_type).
+/**
+ * remove_bus_type() - remove the one-and-only one instance of the visor bus
+ * type (visorbus_type)
*/
static void
remove_bus_type(void)
@@ -1060,7 +1047,8 @@ remove_bus_type(void)
bus_unregister(&visorbus_type);
}
-/** Remove all child visor bus device instances.
+/**
+ * remove_all_visor_devices() - remove all child visor bus device instances
*/
static void
remove_all_visor_devices(void)
@@ -1075,7 +1063,7 @@ remove_all_visor_devices(void)
}
}
-static void
+void
chipset_bus_create(struct visor_device *dev)
{
int rc;
@@ -1092,19 +1080,17 @@ chipset_bus_create(struct visor_device *dev)
POSTCODE_LINUX_3(CHIPSET_INIT_SUCCESS_PC, bus_no,
POSTCODE_SEVERITY_INFO);
- if (chipset_responders.bus_create)
- (*chipset_responders.bus_create) (dev, rc);
+ bus_create_response(dev, rc);
}
-static void
+void
chipset_bus_destroy(struct visor_device *dev)
{
remove_bus_instance(dev);
- if (chipset_responders.bus_destroy)
- (*chipset_responders.bus_destroy)(dev, 0);
+ bus_destroy_response(dev, 0);
}
-static void
+void
chipset_device_create(struct visor_device *dev_info)
{
int rc;
@@ -1115,8 +1101,7 @@ chipset_device_create(struct visor_device *dev_info)
POSTCODE_SEVERITY_INFO);
rc = create_visor_device(dev_info);
- if (chipset_responders.device_create)
- chipset_responders.device_create(dev_info, rc);
+ device_create_response(dev_info, rc);
if (rc < 0)
POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
@@ -1126,18 +1111,22 @@ chipset_device_create(struct visor_device *dev_info)
POSTCODE_SEVERITY_INFO);
}
-static void
+void
chipset_device_destroy(struct visor_device *dev_info)
{
remove_visor_device(dev_info);
- if (chipset_responders.device_destroy)
- (*chipset_responders.device_destroy) (dev_info, 0);
+ device_destroy_response(dev_info, 0);
}
-/* This is the callback function specified for a function driver, to
- * be called when a pending "pause device" operation has been
- * completed.
+/**
+ * pause_state_change_complete() - the callback function to be called by a
+ * visorbus function driver when a
+ * pending "pause device" operation has
+ * completed
+ * @dev: struct visor_device identifying the paused device
+ * @status: 0 iff the pause state change completed successfully, otherwise
+ * a negative errno value indicating the reason for failure
*/
static void
pause_state_change_complete(struct visor_device *dev, int status)
@@ -1146,19 +1135,18 @@ pause_state_change_complete(struct visor_device *dev, int status)
return;
dev->pausing = false;
- if (!chipset_responders.device_pause) /* this can never happen! */
- return;
- /* Notify the chipset driver that the pause is complete, which
- * will presumably want to send some sort of response to the
- * initiator.
- */
- (*chipset_responders.device_pause) (dev, status);
+ device_pause_response(dev, status);
}
-/* This is the callback function specified for a function driver, to
- * be called when a pending "resume device" operation has been
- * completed.
+/**
+ * resume_state_change_complete() - the callback function to be called by a
+ * visorbus function driver when a
+ * pending "resume device" operation has
+ * completed
+ * @dev: struct visor_device identifying the resumed device
+ * @status: 0 iff the resume state change completed successfully, otherwise
+ * a negative errno value indicating the reason for failure
*/
static void
resume_state_change_complete(struct visor_device *dev, int status)
@@ -1167,19 +1155,25 @@ resume_state_change_complete(struct visor_device *dev, int status)
return;
dev->resuming = false;
- if (!chipset_responders.device_resume) /* this can never happen! */
- return;
- /* Notify the chipset driver that the resume is complete,
+ /*
+ * Notify the chipset driver that the resume is complete,
* which will presumably want to send some sort of response to
* the initiator.
*/
- (*chipset_responders.device_resume) (dev, status);
+ device_resume_response(dev, status);
}
-/* Tell the subordinate function driver for a specific device to pause
- * or resume that device. Result is returned asynchronously via a
- * callback function.
+/**
+ * initiate_chipset_device_pause_resume() - start a pause or resume operation
+ * for a visor device
+ * @dev: struct visor_device identifying the device being paused or resumed
+ * @is_pause: true to indicate pause operation, false to indicate resume
+ *
+ * Tell the subordinate function driver for a specific device to pause
+ * or resume that device. Success/failure result is returned asynchronously
+ * via a callback function; see pause_state_change_complete() and
+ * resume_state_change_complete().
*/
static void
initiate_chipset_device_pause_resume(struct visor_device *dev, bool is_pause)
@@ -1189,9 +1183,9 @@ initiate_chipset_device_pause_resume(struct visor_device *dev, bool is_pause)
void (*notify_func)(struct visor_device *dev, int response) = NULL;
if (is_pause)
- notify_func = chipset_responders.device_pause;
+ notify_func = device_pause_response;
else
- notify_func = chipset_responders.device_resume;
+ notify_func = device_resume_response;
if (!notify_func)
return;
@@ -1206,7 +1200,8 @@ initiate_chipset_device_pause_resume(struct visor_device *dev, bool is_pause)
return;
}
- /* Note that even though both drv->pause() and drv->resume
+ /*
+ * Note that even though both drv->pause() and drv->resume
* specify a callback function, it is NOT necessary for us to
* increment our local module usage count. Reason is, there
* is already a linkage dependency between child function
@@ -1246,33 +1241,41 @@ initiate_chipset_device_pause_resume(struct visor_device *dev, bool is_pause)
}
}
-static void
+/**
+ * chipset_device_pause() - start a pause operation for a visor device
+ * @dev_info: struct visor_device identifying the device being paused
+ *
+ * Tell the subordinate function driver for a specific device to pause
+ * that device. Success/failure result is returned asynchronously
+ * via a callback function; see pause_state_change_complete().
+ */
+void
chipset_device_pause(struct visor_device *dev_info)
{
initiate_chipset_device_pause_resume(dev_info, true);
}
-static void
+/**
+ * chipset_device_resume() - start a resume operation for a visor device
+ * @dev_info: struct visor_device identifying the device being resumed
+ *
+ * Tell the subordinate function driver for a specific device to resume
+ * that device. Success/failure result is returned asynchronously
+ * via a callback function; see resume_state_change_complete().
+ */
+void
chipset_device_resume(struct visor_device *dev_info)
{
initiate_chipset_device_pause_resume(dev_info, false);
}
-struct channel_size_info {
- uuid_le guid;
- unsigned long min_size;
- unsigned long max_size;
-};
-
int
visorbus_init(void)
{
int err;
POSTCODE_LINUX_3(DRIVER_ENTRY_PC, 0, POSTCODE_SEVERITY_INFO);
- bus_device_info_init(&clientbus_driverinfo,
- "clientbus", "visorbus",
- VERSION, NULL);
+ bus_device_info_init(&clientbus_driverinfo, "clientbus", "visorbus");
err = create_bus_type();
if (err < 0) {
@@ -1280,19 +1283,7 @@ visorbus_init(void)
goto error;
}
- periodic_dev_workqueue = create_singlethread_workqueue("visorbus_dev");
- if (!periodic_dev_workqueue) {
- POSTCODE_LINUX_2(CREATE_WORKQUEUE_PC, DIAG_SEVERITY_ERR);
- err = -ENOMEM;
- goto error;
- }
-
- /* This enables us to receive notifications when devices appear for
- * which this service partition is to be a server for.
- */
- visorchipset_register_busdev(&chipset_notifiers,
- &chipset_responders,
- &chipset_driverinfo);
+ bus_device_info_init(&chipset_driverinfo, "chipset", "visorchipset");
return 0;
@@ -1306,20 +1297,8 @@ visorbus_exit(void)
{
struct list_head *listentry, *listtmp;
- visorchipset_register_busdev(NULL, NULL, NULL);
remove_all_visor_devices();
- flush_workqueue(periodic_dev_workqueue); /* better not be any work! */
- destroy_workqueue(periodic_dev_workqueue);
- periodic_dev_workqueue = NULL;
-
- if (periodic_test_workqueue) {
- cancel_delayed_work(&periodic_work);
- flush_workqueue(periodic_test_workqueue);
- destroy_workqueue(periodic_test_workqueue);
- periodic_test_workqueue = NULL;
- }
-
list_for_each_safe(listentry, listtmp, &list_all_bus_instances) {
struct visor_device *dev = list_entry(listentry,
struct visor_device,
@@ -1329,9 +1308,6 @@ visorbus_exit(void)
remove_bus_type();
}
-module_param_named(debug, visorbus_debug, int, S_IRUGO);
-MODULE_PARM_DESC(visorbus_debug, "1 to debug");
-
module_param_named(forcematch, visorbus_forcematch, int, S_IRUGO);
MODULE_PARM_DESC(visorbus_forcematch,
"1 to force a successful dev <--> drv match");
@@ -1339,6 +1315,3 @@ MODULE_PARM_DESC(visorbus_forcematch,
module_param_named(forcenomatch, visorbus_forcenomatch, int, S_IRUGO);
MODULE_PARM_DESC(visorbus_forcenomatch,
"1 to force an UNsuccessful dev <--> drv match");
-
-module_param_named(debugref, visorbus_debugref, int, S_IRUGO);
-MODULE_PARM_DESC(visorbus_debugref, "1 to debug reference counting");
diff --git a/drivers/staging/unisys/visorbus/visorbus_private.h b/drivers/staging/unisys/visorbus/visorbus_private.h
index 39edd2018453..15403fb52847 100644
--- a/drivers/staging/unisys/visorbus/visorbus_private.h
+++ b/drivers/staging/unisys/visorbus/visorbus_private.h
@@ -1,4 +1,4 @@
-/* visorchipset.h
+/* visorbus_private.h
*
* Copyright (C) 2010 - 2015 UNISYS CORPORATION
* All rights reserved.
@@ -14,55 +14,72 @@
* details.
*/
-#ifndef __VISORCHIPSET_H__
-#define __VISORCHIPSET_H__
+#ifndef __VISORBUS_PRIVATE_H__
+#define __VISORBUS_PRIVATE_H__
#include <linux/uuid.h>
+#include <linux/utsname.h>
#include "controlvmchannel.h"
-#include "vbusdeviceinfo.h"
-#include "vbushelper.h"
+#include "vbuschannel.h"
-/* These functions will be called from within visorchipset when certain
- * events happen. (The implementation of these functions is outside of
- * visorchipset.)
+/* TARGET_HOSTNAME specified as -DTARGET_HOSTNAME=\"thename\" on the
+ * command line
*/
-struct visorchipset_busdev_notifiers {
- void (*bus_create)(struct visor_device *bus_info);
- void (*bus_destroy)(struct visor_device *bus_info);
- void (*device_create)(struct visor_device *bus_info);
- void (*device_destroy)(struct visor_device *bus_info);
- void (*device_pause)(struct visor_device *bus_info);
- void (*device_resume)(struct visor_device *bus_info);
-};
-/* These functions live inside visorchipset, and will be called to indicate
- * responses to specific events (by code outside of visorchipset).
- * For now, the value for each response is simply either:
- * 0 = it worked
- * -1 = it failed
- */
-struct visorchipset_busdev_responders {
- void (*bus_create)(struct visor_device *p, int response);
- void (*bus_destroy)(struct visor_device *p, int response);
- void (*device_create)(struct visor_device *p, int response);
- void (*device_destroy)(struct visor_device *p, int response);
- void (*device_pause)(struct visor_device *p, int response);
- void (*device_resume)(struct visor_device *p, int response);
-};
+static inline void bus_device_info_init(
+ struct ultra_vbus_deviceinfo *bus_device_info_ptr,
+ const char *dev_type, const char *drv_name)
+{
+ memset(bus_device_info_ptr, 0, sizeof(struct ultra_vbus_deviceinfo));
+ snprintf(bus_device_info_ptr->devtype,
+ sizeof(bus_device_info_ptr->devtype),
+ "%s", (dev_type) ? dev_type : "unknownType");
+ snprintf(bus_device_info_ptr->drvname,
+ sizeof(bus_device_info_ptr->drvname),
+ "%s", (drv_name) ? drv_name : "unknownDriver");
+ snprintf(bus_device_info_ptr->infostrs,
+ sizeof(bus_device_info_ptr->infostrs), "kernel ver. %s",
+ utsname()->release);
+}
-/** Register functions (in the bus driver) to get called by visorchipset
- * whenever a bus or device appears for which this guest is to be the
- * client for. visorchipset will fill in <responders>, to indicate
- * functions the bus driver should call to indicate message responses.
- */
-void
-visorchipset_register_busdev(
- struct visorchipset_busdev_notifiers *notifiers,
- struct visorchipset_busdev_responders *responders,
- struct ultra_vbus_deviceinfo *driver_info);
+void chipset_bus_create(struct visor_device *bus_info);
+void chipset_bus_destroy(struct visor_device *bus_info);
+void chipset_device_create(struct visor_device *dev_info);
+void chipset_device_destroy(struct visor_device *dev_info);
+void chipset_device_pause(struct visor_device *dev_info);
+void chipset_device_resume(struct visor_device *dev_info);
+
+void bus_create_response(struct visor_device *p, int response);
+void bus_destroy_response(struct visor_device *p, int response);
+void device_create_response(struct visor_device *p, int response);
+void device_destroy_response(struct visor_device *p, int response);
+void device_resume_response(struct visor_device *p, int response);
+void device_pause_response(struct visor_device *p, int response);
-/* visorbus init and exit functions */
int visorbus_init(void);
void visorbus_exit(void);
+
+/* visorchannel access functions */
+
+struct visorchannel *visorchannel_create(u64 physaddr,
+ unsigned long channel_bytes,
+ gfp_t gfp, uuid_le guid);
+struct visorchannel *visorchannel_create_with_lock(u64 physaddr,
+ unsigned long channel_bytes,
+ gfp_t gfp, uuid_le guid);
+void visorchannel_destroy(struct visorchannel *channel);
+int visorchannel_read(struct visorchannel *channel, ulong offset,
+ void *local, ulong nbytes);
+int visorchannel_write(struct visorchannel *channel, ulong offset,
+ void *local, ulong nbytes);
+u64 visorchannel_get_physaddr(struct visorchannel *channel);
+ulong visorchannel_get_nbytes(struct visorchannel *channel);
+char *visorchannel_id(struct visorchannel *channel, char *s);
+char *visorchannel_zoneid(struct visorchannel *channel, char *s);
+u64 visorchannel_get_clientpartition(struct visorchannel *channel);
+int visorchannel_set_clientpartition(struct visorchannel *channel,
+ u64 partition_handle);
+char *visorchannel_uuid_id(uuid_le *guid, char *s);
+void __iomem *visorchannel_get_header(struct visorchannel *channel);
#endif
diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c
index 43373582cf1d..300a65dc5c6c 100644
--- a/drivers/staging/unisys/visorbus/visorchannel.c
+++ b/drivers/staging/unisys/visorbus/visorchannel.c
@@ -15,14 +15,13 @@
*/
/*
- * This provides Supervisor channel communication primitives, which are
+ * This provides s-Par channel communication primitives, which are
* independent of the mechanism used to access the channel data.
*/
#include <linux/uuid.h>
#include <linux/io.h>
-#include "version.h"
#include "visorbus.h"
#include "controlvmchannel.h"
@@ -55,110 +54,6 @@ struct visorchannel {
uuid_le inst;
};
-/* Creates the struct visorchannel abstraction for a data area in memory,
- * but does NOT modify this data area.
- */
-static struct visorchannel *
-visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes,
- gfp_t gfp, unsigned long off,
- uuid_le guid, bool needs_lock)
-{
- struct visorchannel *channel;
- int err;
- size_t size = sizeof(struct channel_header);
-
- if (physaddr == 0)
- return NULL;
-
- channel = kzalloc(sizeof(*channel), gfp);
- if (!channel)
- return NULL;
-
- channel->needs_lock = needs_lock;
- spin_lock_init(&channel->insert_lock);
- spin_lock_init(&channel->remove_lock);
-
- /* Video driver constains the efi framebuffer so it will get a
- * conflict resource when requesting its full mem region. Since
- * we are only using the efi framebuffer for video we can ignore
- * this. Remember that we haven't requested it so we don't try to
- * release later on.
- */
- channel->requested = request_mem_region(physaddr, size, MYDRVNAME);
- if (!channel->requested) {
- if (uuid_le_cmp(guid, spar_video_guid)) {
- /* Not the video channel we care about this */
- goto err_destroy_channel;
- }
- }
-
- channel->mapped = memremap(physaddr, size, MEMREMAP_WB);
- if (!channel->mapped) {
- release_mem_region(physaddr, size);
- goto err_destroy_channel;
- }
-
- channel->physaddr = physaddr;
- channel->nbytes = size;
-
- err = visorchannel_read(channel, 0, &channel->chan_hdr,
- sizeof(struct channel_header));
- if (err)
- goto err_destroy_channel;
-
- /* we had better be a CLIENT of this channel */
- if (channel_bytes == 0)
- channel_bytes = (ulong)channel->chan_hdr.size;
- if (uuid_le_cmp(guid, NULL_UUID_LE) == 0)
- guid = channel->chan_hdr.chtype;
-
- memunmap(channel->mapped);
- if (channel->requested)
- release_mem_region(channel->physaddr, channel->nbytes);
- channel->mapped = NULL;
- channel->requested = request_mem_region(channel->physaddr,
- channel_bytes, MYDRVNAME);
- if (!channel->requested) {
- if (uuid_le_cmp(guid, spar_video_guid)) {
- /* Different we care about this */
- goto err_destroy_channel;
- }
- }
-
- channel->mapped = memremap(channel->physaddr, channel_bytes,
- MEMREMAP_WB);
- if (!channel->mapped) {
- release_mem_region(channel->physaddr, channel_bytes);
- goto err_destroy_channel;
- }
-
- channel->nbytes = channel_bytes;
- channel->guid = guid;
- return channel;
-
-err_destroy_channel:
- visorchannel_destroy(channel);
- return NULL;
-}
-
-struct visorchannel *
-visorchannel_create(u64 physaddr, unsigned long channel_bytes,
- gfp_t gfp, uuid_le guid)
-{
- return visorchannel_create_guts(physaddr, channel_bytes, gfp, 0, guid,
- false);
-}
-EXPORT_SYMBOL_GPL(visorchannel_create);
-
-struct visorchannel *
-visorchannel_create_with_lock(u64 physaddr, unsigned long channel_bytes,
- gfp_t gfp, uuid_le guid)
-{
- return visorchannel_create_guts(physaddr, channel_bytes, gfp, 0, guid,
- true);
-}
-EXPORT_SYMBOL_GPL(visorchannel_create_with_lock);
-
void
visorchannel_destroy(struct visorchannel *channel)
{
@@ -171,21 +66,18 @@ visorchannel_destroy(struct visorchannel *channel)
}
kfree(channel);
}
-EXPORT_SYMBOL_GPL(visorchannel_destroy);
u64
visorchannel_get_physaddr(struct visorchannel *channel)
{
return channel->physaddr;
}
-EXPORT_SYMBOL_GPL(visorchannel_get_physaddr);
ulong
visorchannel_get_nbytes(struct visorchannel *channel)
{
return channel->nbytes;
}
-EXPORT_SYMBOL_GPL(visorchannel_get_nbytes);
char *
visorchannel_uuid_id(uuid_le *guid, char *s)
@@ -193,28 +85,24 @@ visorchannel_uuid_id(uuid_le *guid, char *s)
sprintf(s, "%pUL", guid);
return s;
}
-EXPORT_SYMBOL_GPL(visorchannel_uuid_id);
char *
visorchannel_id(struct visorchannel *channel, char *s)
{
return visorchannel_uuid_id(&channel->guid, s);
}
-EXPORT_SYMBOL_GPL(visorchannel_id);
char *
visorchannel_zoneid(struct visorchannel *channel, char *s)
{
return visorchannel_uuid_id(&channel->chan_hdr.zone_uuid, s);
}
-EXPORT_SYMBOL_GPL(visorchannel_zoneid);
u64
visorchannel_get_clientpartition(struct visorchannel *channel)
{
return channel->chan_hdr.partition_handle;
}
-EXPORT_SYMBOL_GPL(visorchannel_get_clientpartition);
int
visorchannel_set_clientpartition(struct visorchannel *channel,
@@ -223,8 +111,13 @@ visorchannel_set_clientpartition(struct visorchannel *channel,
channel->chan_hdr.partition_handle = partition_handle;
return 0;
}
-EXPORT_SYMBOL_GPL(visorchannel_set_clientpartition);
+/**
+ * visorchannel_get_uuid() - queries the UUID of the designated channel
+ * @channel: the channel to query
+ *
+ * Return: the UUID of the provided channel
+ */
uuid_le
visorchannel_get_uuid(struct visorchannel *channel)
{
@@ -243,7 +136,6 @@ visorchannel_read(struct visorchannel *channel, ulong offset,
return 0;
}
-EXPORT_SYMBOL_GPL(visorchannel_read);
int
visorchannel_write(struct visorchannel *channel, ulong offset,
@@ -265,156 +157,125 @@ visorchannel_write(struct visorchannel *channel, ulong offset,
return 0;
}
-EXPORT_SYMBOL_GPL(visorchannel_write);
-
-int
-visorchannel_clear(struct visorchannel *channel, ulong offset, u8 ch,
- ulong nbytes)
-{
- int err;
- int bufsize = PAGE_SIZE;
- int written = 0;
- u8 *buf;
-
- buf = (u8 *)__get_free_page(GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- memset(buf, ch, bufsize);
-
- while (nbytes > 0) {
- int thisbytes = bufsize;
-
- if (nbytes < thisbytes)
- thisbytes = nbytes;
- err = visorchannel_write(channel, offset + written,
- buf, thisbytes);
- if (err)
- goto out_free_page;
-
- written += thisbytes;
- nbytes -= thisbytes;
- }
- err = 0;
-
-out_free_page:
- free_page((unsigned long)buf);
- return err;
-}
-EXPORT_SYMBOL_GPL(visorchannel_clear);
void __iomem *
visorchannel_get_header(struct visorchannel *channel)
{
return (void __iomem *)&channel->chan_hdr;
}
-EXPORT_SYMBOL_GPL(visorchannel_get_header);
-/** Return offset of a specific SIGNAL_QUEUE_HEADER from the beginning of a
- * channel header
+/*
+ * Return offset of a specific SIGNAL_QUEUE_HEADER from the beginning of a
+ * channel header
*/
#define SIG_QUEUE_OFFSET(chan_hdr, q) \
((chan_hdr)->ch_space_offset + \
((q) * sizeof(struct signal_queue_header)))
-/** Return offset of a specific queue entry (data) from the beginning of a
- * channel header
+/*
+ * Return offset of a specific queue entry (data) from the beginning of a
+ * channel header
*/
#define SIG_DATA_OFFSET(chan_hdr, q, sig_hdr, slot) \
(SIG_QUEUE_OFFSET(chan_hdr, q) + (sig_hdr)->sig_base_offset + \
((slot) * (sig_hdr)->signal_size))
-/** Write the contents of a specific field within a SIGNAL_QUEUE_HEADER back
- * into host memory
+/*
+ * Write the contents of a specific field within a SIGNAL_QUEUE_HEADER back
+ * into host memory
*/
#define SIG_WRITE_FIELD(channel, queue, sig_hdr, FIELD) \
- (visorchannel_write(channel, \
- SIG_QUEUE_OFFSET(&channel->chan_hdr, queue) +\
- offsetof(struct signal_queue_header, FIELD), \
- &((sig_hdr)->FIELD), \
- sizeof((sig_hdr)->FIELD)) >= 0)
+ visorchannel_write(channel, \
+ SIG_QUEUE_OFFSET(&channel->chan_hdr, queue) +\
+ offsetof(struct signal_queue_header, FIELD), \
+ &((sig_hdr)->FIELD), \
+ sizeof((sig_hdr)->FIELD))
-static bool
+static int
sig_read_header(struct visorchannel *channel, u32 queue,
struct signal_queue_header *sig_hdr)
{
- int err;
-
if (channel->chan_hdr.ch_space_offset < sizeof(struct channel_header))
- return false;
+ return -EINVAL;
/* Read the appropriate SIGNAL_QUEUE_HEADER into local memory. */
- err = visorchannel_read(channel,
- SIG_QUEUE_OFFSET(&channel->chan_hdr, queue),
- sig_hdr, sizeof(struct signal_queue_header));
- if (err)
- return false;
-
- return true;
+ return visorchannel_read(channel,
+ SIG_QUEUE_OFFSET(&channel->chan_hdr, queue),
+ sig_hdr, sizeof(struct signal_queue_header));
}
-static inline bool
+static inline int
sig_read_data(struct visorchannel *channel, u32 queue,
struct signal_queue_header *sig_hdr, u32 slot, void *data)
{
- int err;
int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue,
sig_hdr, slot);
- err = visorchannel_read(channel, signal_data_offset,
- data, sig_hdr->signal_size);
- if (err)
- return false;
-
- return true;
+ return visorchannel_read(channel, signal_data_offset,
+ data, sig_hdr->signal_size);
}
-static inline bool
+static inline int
sig_write_data(struct visorchannel *channel, u32 queue,
struct signal_queue_header *sig_hdr, u32 slot, void *data)
{
- int err;
int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue,
sig_hdr, slot);
- err = visorchannel_write(channel, signal_data_offset,
- data, sig_hdr->signal_size);
- if (err)
- return false;
-
- return true;
+ return visorchannel_write(channel, signal_data_offset,
+ data, sig_hdr->signal_size);
}
-static bool
+static int
signalremove_inner(struct visorchannel *channel, u32 queue, void *msg)
{
struct signal_queue_header sig_hdr;
+ int error;
+
+ error = sig_read_header(channel, queue, &sig_hdr);
+ if (error)
+ return error;
- if (!sig_read_header(channel, queue, &sig_hdr))
- return false;
if (sig_hdr.head == sig_hdr.tail)
- return false; /* no signals to remove */
+ return -EIO; /* no signals to remove */
sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots;
- if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg))
- return false;
+
+ error = sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg);
+ if (error)
+ return error;
+
sig_hdr.num_received++;
- /* For each data field in SIGNAL_QUEUE_HEADER that was modified,
+ /*
+ * For each data field in SIGNAL_QUEUE_HEADER that was modified,
* update host memory.
*/
mb(); /* required for channel synch */
- if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail))
- return false;
- if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received))
- return false;
- return true;
+
+ error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail);
+ if (error)
+ return error;
+ error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received);
+ if (error)
+ return error;
+
+ return 0;
}
-bool
+/**
+ * visorchannel_signalremove() - removes a message from the designated
+ * channel/queue
+ * @channel: the channel the message will be removed from
+ * @queue: the queue the message will be removed from
+ * @msg: the message to remove
+ *
+ * Return: integer error code indicating the status of the removal
+ */
+int
visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
{
- bool rc;
+ int rc;
unsigned long flags;
if (channel->needs_lock) {
@@ -429,6 +290,15 @@ visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
}
EXPORT_SYMBOL_GPL(visorchannel_signalremove);
+/**
+ * visorchannel_signalempty() - checks if the designated channel/queue
+ * contains any messages
+ * @channel: the channel to query
+ * @queue: the queue in the channel to query
+ *
+ * Return: boolean indicating whether any messages in the designated
+ * channel/queue are present
+ */
bool
visorchannel_signalempty(struct visorchannel *channel, u32 queue)
{
@@ -439,7 +309,7 @@ visorchannel_signalempty(struct visorchannel *channel, u32 queue)
if (channel->needs_lock)
spin_lock_irqsave(&channel->remove_lock, flags);
- if (!sig_read_header(channel, queue, &sig_hdr))
+ if (sig_read_header(channel, queue, &sig_hdr))
rc = true;
if (sig_hdr.head == sig_hdr.tail)
rc = true;
@@ -450,13 +320,15 @@ visorchannel_signalempty(struct visorchannel *channel, u32 queue)
}
EXPORT_SYMBOL_GPL(visorchannel_signalempty);
-static bool
+static int
signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
{
struct signal_queue_header sig_hdr;
+ int error;
- if (!sig_read_header(channel, queue, &sig_hdr))
- return false;
+ error = sig_read_header(channel, queue, &sig_hdr);
+ if (error)
+ return error;
sig_hdr.head = (sig_hdr.head + 1) % sig_hdr.max_slots;
if (sig_hdr.head == sig_hdr.tail) {
@@ -467,169 +339,176 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
num_overflows),
&sig_hdr.num_overflows,
sizeof(sig_hdr.num_overflows));
- return false;
+ return -EIO;
}
- if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg))
- return false;
+ error = sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg);
+ if (error)
+ return error;
sig_hdr.num_sent++;
- /* For each data field in SIGNAL_QUEUE_HEADER that was modified,
+ /*
+ * For each data field in SIGNAL_QUEUE_HEADER that was modified,
* update host memory.
*/
mb(); /* required for channel synch */
- if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head))
- return false;
- if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent))
- return false;
- return true;
+ error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, head);
+ if (error)
+ return error;
+ error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent);
+ if (error)
+ return error;
+
+ return 0;
}
-bool
-visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg)
+/**
+ * visorchannel_create_guts() - creates the struct visorchannel abstraction
+ * for a data area in memory, but does NOT modify
+ * this data area
+ * @physaddr: physical address of start of channel
+ * @channel_bytes: size of the channel in bytes; this may 0 if the channel has
+ * already been initialized in memory (which is true for all
+ * channels provided to guest environments by the s-Par
+ * back-end), in which case the actual channel size will be
+ * read from the channel header in memory
+ * @gfp: gfp_t to use when allocating memory for the data struct
+ * @guid: uuid that identifies channel type; this may 0 if the channel
+ * has already been initialized in memory (which is true for all
+ * channels provided to guest environments by the s-Par
+ * back-end), in which case the actual channel guid will be
+ * read from the channel header in memory
+ * @needs_lock: must specify true if you have multiple threads of execution
+ * that will be calling visorchannel methods of this
+ * visorchannel at the same time
+ *
+ * Return: pointer to visorchannel that was created if successful,
+ * otherwise NULL
+ */
+static struct visorchannel *
+visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes,
+ gfp_t gfp, uuid_le guid, bool needs_lock)
{
- bool rc;
- unsigned long flags;
+ struct visorchannel *channel;
+ int err;
+ size_t size = sizeof(struct channel_header);
- if (channel->needs_lock) {
- spin_lock_irqsave(&channel->insert_lock, flags);
- rc = signalinsert_inner(channel, queue, msg);
- spin_unlock_irqrestore(&channel->insert_lock, flags);
- } else {
- rc = signalinsert_inner(channel, queue, msg);
+ if (physaddr == 0)
+ return NULL;
+
+ channel = kzalloc(sizeof(*channel), gfp);
+ if (!channel)
+ return NULL;
+
+ channel->needs_lock = needs_lock;
+ spin_lock_init(&channel->insert_lock);
+ spin_lock_init(&channel->remove_lock);
+
+ /*
+ * Video driver constains the efi framebuffer so it will get a
+ * conflict resource when requesting its full mem region. Since
+ * we are only using the efi framebuffer for video we can ignore
+ * this. Remember that we haven't requested it so we don't try to
+ * release later on.
+ */
+ channel->requested = request_mem_region(physaddr, size, MYDRVNAME);
+ if (!channel->requested) {
+ if (uuid_le_cmp(guid, spar_video_guid)) {
+ /* Not the video channel we care about this */
+ goto err_destroy_channel;
+ }
}
- return rc;
-}
-EXPORT_SYMBOL_GPL(visorchannel_signalinsert);
+ channel->mapped = memremap(physaddr, size, MEMREMAP_WB);
+ if (!channel->mapped) {
+ release_mem_region(physaddr, size);
+ goto err_destroy_channel;
+ }
-int
-visorchannel_signalqueue_slots_avail(struct visorchannel *channel, u32 queue)
-{
- struct signal_queue_header sig_hdr;
- u32 slots_avail, slots_used;
- u32 head, tail;
-
- if (!sig_read_header(channel, queue, &sig_hdr))
- return 0;
- head = sig_hdr.head;
- tail = sig_hdr.tail;
- if (head < tail)
- head = head + sig_hdr.max_slots;
- slots_used = head - tail;
- slots_avail = sig_hdr.max_signals - slots_used;
- return (int)slots_avail;
-}
-EXPORT_SYMBOL_GPL(visorchannel_signalqueue_slots_avail);
+ channel->physaddr = physaddr;
+ channel->nbytes = size;
-int
-visorchannel_signalqueue_max_slots(struct visorchannel *channel, u32 queue)
-{
- struct signal_queue_header sig_hdr;
+ err = visorchannel_read(channel, 0, &channel->chan_hdr,
+ sizeof(struct channel_header));
+ if (err)
+ goto err_destroy_channel;
+
+ /* we had better be a CLIENT of this channel */
+ if (channel_bytes == 0)
+ channel_bytes = (ulong)channel->chan_hdr.size;
+ if (uuid_le_cmp(guid, NULL_UUID_LE) == 0)
+ guid = channel->chan_hdr.chtype;
+
+ memunmap(channel->mapped);
+ if (channel->requested)
+ release_mem_region(channel->physaddr, channel->nbytes);
+ channel->mapped = NULL;
+ channel->requested = request_mem_region(channel->physaddr,
+ channel_bytes, MYDRVNAME);
+ if (!channel->requested) {
+ if (uuid_le_cmp(guid, spar_video_guid)) {
+ /* Different we care about this */
+ goto err_destroy_channel;
+ }
+ }
+
+ channel->mapped = memremap(channel->physaddr, channel_bytes,
+ MEMREMAP_WB);
+ if (!channel->mapped) {
+ release_mem_region(channel->physaddr, channel_bytes);
+ goto err_destroy_channel;
+ }
+
+ channel->nbytes = channel_bytes;
+ channel->guid = guid;
+ return channel;
- if (!sig_read_header(channel, queue, &sig_hdr))
- return 0;
- return (int)sig_hdr.max_signals;
+err_destroy_channel:
+ visorchannel_destroy(channel);
+ return NULL;
}
-EXPORT_SYMBOL_GPL(visorchannel_signalqueue_max_slots);
-static void
-sigqueue_debug(struct signal_queue_header *q, int which, struct seq_file *seq)
+struct visorchannel *
+visorchannel_create(u64 physaddr, unsigned long channel_bytes,
+ gfp_t gfp, uuid_le guid)
{
- seq_printf(seq, "Signal Queue #%d\n", which);
- seq_printf(seq, " VersionId = %lu\n", (ulong)q->version);
- seq_printf(seq, " Type = %lu\n", (ulong)q->chtype);
- seq_printf(seq, " oSignalBase = %llu\n",
- (long long)q->sig_base_offset);
- seq_printf(seq, " SignalSize = %lu\n", (ulong)q->signal_size);
- seq_printf(seq, " MaxSignalSlots = %lu\n",
- (ulong)q->max_slots);
- seq_printf(seq, " MaxSignals = %lu\n", (ulong)q->max_signals);
- seq_printf(seq, " FeatureFlags = %-16.16Lx\n",
- (long long)q->features);
- seq_printf(seq, " NumSignalsSent = %llu\n",
- (long long)q->num_sent);
- seq_printf(seq, " NumSignalsReceived = %llu\n",
- (long long)q->num_received);
- seq_printf(seq, " NumOverflows = %llu\n",
- (long long)q->num_overflows);
- seq_printf(seq, " Head = %lu\n", (ulong)q->head);
- seq_printf(seq, " Tail = %lu\n", (ulong)q->tail);
+ return visorchannel_create_guts(physaddr, channel_bytes, gfp, guid,
+ false);
}
-void
-visorchannel_debug(struct visorchannel *channel, int num_queues,
- struct seq_file *seq, u32 off)
+struct visorchannel *
+visorchannel_create_with_lock(u64 physaddr, unsigned long channel_bytes,
+ gfp_t gfp, uuid_le guid)
{
- u64 addr = 0;
- ulong nbytes = 0, nbytes_region = 0;
- struct channel_header hdr;
- struct channel_header *phdr = &hdr;
- int i = 0;
- int errcode = 0;
+ return visorchannel_create_guts(physaddr, channel_bytes, gfp, guid,
+ true);
+}
- if (!channel)
- return;
+/**
+ * visorchannel_signalinsert() - inserts a message into the designated
+ * channel/queue
+ * @channel: the channel the message will be added to
+ * @queue: the queue the message will be added to
+ * @msg: the message to insert
+ *
+ * Return: integer error code indicating the status of the insertion
+ */
+int
+visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg)
+{
+ int rc;
+ unsigned long flags;
- addr = visorchannel_get_physaddr(channel);
- nbytes_region = visorchannel_get_nbytes(channel);
- errcode = visorchannel_read(channel, off,
- phdr, sizeof(struct channel_header));
- if (errcode < 0) {
- seq_printf(seq,
- "Read of channel header failed with errcode=%d)\n",
- errcode);
- if (off == 0) {
- phdr = &channel->chan_hdr;
- seq_puts(seq, "(following data may be stale)\n");
- } else {
- return;
- }
+ if (channel->needs_lock) {
+ spin_lock_irqsave(&channel->insert_lock, flags);
+ rc = signalinsert_inner(channel, queue, msg);
+ spin_unlock_irqrestore(&channel->insert_lock, flags);
+ } else {
+ rc = signalinsert_inner(channel, queue, msg);
}
- nbytes = (ulong)(phdr->size);
- seq_printf(seq, "--- Begin channel @0x%-16.16Lx for 0x%lx bytes (region=0x%lx bytes) ---\n",
- addr + off, nbytes, nbytes_region);
- seq_printf(seq, "Type = %pUL\n", &phdr->chtype);
- seq_printf(seq, "ZoneGuid = %pUL\n", &phdr->zone_uuid);
- seq_printf(seq, "Signature = 0x%-16.16Lx\n",
- (long long)phdr->signature);
- seq_printf(seq, "LegacyState = %lu\n", (ulong)phdr->legacy_state);
- seq_printf(seq, "SrvState = %lu\n", (ulong)phdr->srv_state);
- seq_printf(seq, "CliStateBoot = %lu\n", (ulong)phdr->cli_state_boot);
- seq_printf(seq, "CliStateOS = %lu\n", (ulong)phdr->cli_state_os);
- seq_printf(seq, "HeaderSize = %lu\n", (ulong)phdr->header_size);
- seq_printf(seq, "Size = %llu\n", (long long)phdr->size);
- seq_printf(seq, "Features = 0x%-16.16llx\n",
- (long long)phdr->features);
- seq_printf(seq, "PartitionHandle = 0x%-16.16llx\n",
- (long long)phdr->partition_handle);
- seq_printf(seq, "Handle = 0x%-16.16llx\n",
- (long long)phdr->handle);
- seq_printf(seq, "VersionId = %lu\n", (ulong)phdr->version_id);
- seq_printf(seq, "oChannelSpace = %llu\n",
- (long long)phdr->ch_space_offset);
- if ((phdr->ch_space_offset == 0) || (errcode < 0))
- ;
- else
- for (i = 0; i < num_queues; i++) {
- struct signal_queue_header q;
-
- errcode = visorchannel_read(channel,
- off +
- phdr->ch_space_offset +
- (i * sizeof(q)),
- &q, sizeof(q));
- if (errcode < 0) {
- seq_printf(seq,
- "failed to read signal queue #%d from channel @0x%-16.16Lx errcode=%d\n",
- i, addr, errcode);
- continue;
- }
- sigqueue_debug(&q, i, seq);
- }
- seq_printf(seq, "--- End channel @0x%-16.16Lx for 0x%lx bytes ---\n",
- addr + off, nbytes);
+
+ return rc;
}
-EXPORT_SYMBOL_GPL(visorchannel_debug);
+EXPORT_SYMBOL_GPL(visorchannel_signalinsert);
diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c
index d248c946a13b..59871495ea85 100644
--- a/drivers/staging/unisys/visorbus/visorchipset.c
+++ b/drivers/staging/unisys/visorbus/visorchipset.c
@@ -25,21 +25,12 @@
#include <linux/uuid.h>
#include <linux/crash_dump.h>
-#include "channel_guid.h"
-#include "controlvmchannel.h"
-#include "controlvmcompletionstatus.h"
-#include "guestlinuxdebug.h"
-#include "periodic_work.h"
-#include "version.h"
#include "visorbus.h"
#include "visorbus_private.h"
#include "vmcallinterface.h"
#define CURRENT_FILE_PC VISOR_CHIPSET_PC_visorchipset_main_c
-#define MAX_NAME_SIZE 128
-#define MAX_IP_SIZE 50
-#define MAXOUTSTANDINGCHANNELCOMMAND 256
#define POLLJIFFIES_CONTROLVMCHANNEL_FAST 1
#define POLLJIFFIES_CONTROLVMCHANNEL_SLOW 100
@@ -58,9 +49,6 @@
* Module parameters
*/
static int visorchipset_major;
-static int visorchipset_visorbusregwait = 1; /* default is on */
-static unsigned long controlvm_payload_bytes_buffered;
-static u32 dump_vhba_bus;
static int
visorchipset_open(struct inode *inode, struct file *file)
@@ -79,15 +67,15 @@ visorchipset_release(struct inode *inode, struct file *file)
return 0;
}
-/* When the controlvm channel is idle for at least MIN_IDLE_SECONDS,
-* we switch to slow polling mode. As soon as we get a controlvm
-* message, we switch back to fast polling mode.
-*/
+/*
+ * When the controlvm channel is idle for at least MIN_IDLE_SECONDS,
+ * we switch to slow polling mode. As soon as we get a controlvm
+ * message, we switch back to fast polling mode.
+ */
#define MIN_IDLE_SECONDS 10
static unsigned long poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST;
/* when we got our last controlvm message */
static unsigned long most_recent_message_jiffies;
-static int visorbusregistered;
struct parser_context {
unsigned long allocbytes;
@@ -99,51 +87,36 @@ struct parser_context {
};
static struct delayed_work periodic_controlvm_work;
-static DEFINE_SEMAPHORE(notifier_lock);
static struct cdev file_cdev;
static struct visorchannel **file_controlvm_channel;
-static struct controlvm_message_packet g_devicechangestate_packet;
-
-static LIST_HEAD(bus_info_list);
-static LIST_HEAD(dev_info_list);
static struct visorchannel *controlvm_channel;
/* Manages the request payload in the controlvm channel */
struct visor_controlvm_payload_info {
u8 *ptr; /* pointer to base address of payload pool */
- u64 offset; /* offset from beginning of controlvm
+ u64 offset; /*
+ * offset from beginning of controlvm
* channel to beginning of payload * pool
*/
u32 bytes; /* number of bytes in payload pool */
};
static struct visor_controlvm_payload_info controlvm_payload_info;
+static unsigned long controlvm_payload_bytes_buffered;
-/* The following globals are used to handle the scenario where we are unable to
- * offload the payload from a controlvm message due to memory requirements. In
+/*
+ * The following globals are used to handle the scenario where we are unable to
+ * offload the payload from a controlvm message due to memory requirements. In
* this scenario, we simply stash the controlvm message, then attempt to
* process it again the next time controlvm_periodic_work() runs.
*/
static struct controlvm_message controlvm_pending_msg;
static bool controlvm_pending_msg_valid;
-/* This identifies a data buffer that has been received via a controlvm messages
- * in a remote --> local CONTROLVM_TRANSMIT_FILE conversation.
- */
-struct putfile_buffer_entry {
- struct list_head next; /* putfile_buffer_entry list */
- struct parser_context *parser_ctx; /* points to input data buffer */
-};
-
-/* List of struct putfile_request *, via next_putfile_request member.
- * Each entry in this list identifies an outstanding TRANSMIT_FILE
- * conversation.
- */
-static LIST_HEAD(putfile_request_list);
-
-/* This describes a buffer and its current state of transfer (e.g., how many
+/*
+ * This describes a buffer and its current state of transfer (e.g., how many
* bytes have already been supplied as putfile data, and how many bytes are
* remaining) for a putfile_request.
*/
@@ -155,8 +128,9 @@ struct putfile_active_buffer {
};
#define PUTFILE_REQUEST_SIG 0x0906101302281211
-/* This identifies a single remote --> local CONTROLVM_TRANSMIT_FILE
- * conversation. Structs of this type are dynamically linked into
+/*
+ * This identifies a single remote --> local CONTROLVM_TRANSMIT_FILE
+ * conversation. Structs of this type are dynamically linked into
* <Putfile_request_list>.
*/
struct putfile_request {
@@ -168,7 +142,8 @@ struct putfile_request {
/* link to next struct putfile_request */
struct list_head next_putfile_request;
- /* head of putfile_buffer_entry list, which describes the data to be
+ /*
+ * head of putfile_buffer_entry list, which describes the data to be
* supplied as putfile data;
* - this list is added to when controlvm messages come in that supply
* file data
@@ -184,11 +159,13 @@ struct putfile_request {
/* data not yet read within current putfile_buffer_entry */
struct putfile_active_buffer active_buf;
- /* <0 = failed, 0 = in-progress, >0 = successful; */
- /* note that this must be set with req_list_lock, and if you set <0, */
- /* it is your responsibility to also free up all of the other objects */
- /* in this struct (like input_buffer_list, active_buf.parser_ctx) */
- /* before releasing the lock */
+ /*
+ * <0 = failed, 0 = in-progress, >0 = successful;
+ * note that this must be set with req_list_lock, and if you set <0,
+ * it is your responsibility to also free up all of the other objects
+ * in this struct (like input_buffer_list, active_buf.parser_ctx)
+ * before releasing the lock
+ */
int completion_status;
};
@@ -199,289 +176,11 @@ struct parahotplug_request {
struct controlvm_message msg;
};
-static LIST_HEAD(parahotplug_request_list);
-static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* lock for above */
-static void parahotplug_process_list(void);
-
-/* Manages the info for a CONTROLVM_DUMP_CAPTURESTATE /
- * CONTROLVM_REPORTEVENT.
- */
-static struct visorchipset_busdev_notifiers busdev_notifiers;
-
-static void bus_create_response(struct visor_device *p, int response);
-static void bus_destroy_response(struct visor_device *p, int response);
-static void device_create_response(struct visor_device *p, int response);
-static void device_destroy_response(struct visor_device *p, int response);
-static void device_resume_response(struct visor_device *p, int response);
-
-static void visorchipset_device_pause_response(struct visor_device *p,
- int response);
-
-static struct visorchipset_busdev_responders busdev_responders = {
- .bus_create = bus_create_response,
- .bus_destroy = bus_destroy_response,
- .device_create = device_create_response,
- .device_destroy = device_destroy_response,
- .device_pause = visorchipset_device_pause_response,
- .device_resume = device_resume_response,
-};
-
/* info for /dev/visorchipset */
-static dev_t major_dev = -1; /**< indicates major num for device */
+static dev_t major_dev = -1; /*< indicates major num for device */
/* prototypes for attributes */
static ssize_t toolaction_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-static ssize_t toolaction_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count);
-static DEVICE_ATTR_RW(toolaction);
-
-static ssize_t boottotool_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-static ssize_t boottotool_store(struct device *dev,
- struct device_attribute *attr, const char *buf,
- size_t count);
-static DEVICE_ATTR_RW(boottotool);
-
-static ssize_t error_show(struct device *dev, struct device_attribute *attr,
- char *buf);
-static ssize_t error_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count);
-static DEVICE_ATTR_RW(error);
-
-static ssize_t textid_show(struct device *dev, struct device_attribute *attr,
- char *buf);
-static ssize_t textid_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count);
-static DEVICE_ATTR_RW(textid);
-
-static ssize_t remaining_steps_show(struct device *dev,
- struct device_attribute *attr, char *buf);
-static ssize_t remaining_steps_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count);
-static DEVICE_ATTR_RW(remaining_steps);
-
-static ssize_t devicedisabled_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count);
-static DEVICE_ATTR_WO(devicedisabled);
-
-static ssize_t deviceenabled_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count);
-static DEVICE_ATTR_WO(deviceenabled);
-
-static struct attribute *visorchipset_install_attrs[] = {
- &dev_attr_toolaction.attr,
- &dev_attr_boottotool.attr,
- &dev_attr_error.attr,
- &dev_attr_textid.attr,
- &dev_attr_remaining_steps.attr,
- NULL
-};
-
-static struct attribute_group visorchipset_install_group = {
- .name = "install",
- .attrs = visorchipset_install_attrs
-};
-
-static struct attribute *visorchipset_parahotplug_attrs[] = {
- &dev_attr_devicedisabled.attr,
- &dev_attr_deviceenabled.attr,
- NULL
-};
-
-static struct attribute_group visorchipset_parahotplug_group = {
- .name = "parahotplug",
- .attrs = visorchipset_parahotplug_attrs
-};
-
-static const struct attribute_group *visorchipset_dev_groups[] = {
- &visorchipset_install_group,
- &visorchipset_parahotplug_group,
- NULL
-};
-
-static void visorchipset_dev_release(struct device *dev)
-{
-}
-
-/* /sys/devices/platform/visorchipset */
-static struct platform_device visorchipset_platform_device = {
- .name = "visorchipset",
- .id = -1,
- .dev.groups = visorchipset_dev_groups,
- .dev.release = visorchipset_dev_release,
-};
-
-/* Function prototypes */
-static void controlvm_respond(struct controlvm_message_header *msg_hdr,
- int response);
-static void controlvm_respond_chipset_init(
- struct controlvm_message_header *msg_hdr, int response,
- enum ultra_chipset_feature features);
-static void controlvm_respond_physdev_changestate(
- struct controlvm_message_header *msg_hdr, int response,
- struct spar_segment_state state);
-
-static void parser_done(struct parser_context *ctx);
-
-static struct parser_context *
-parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry)
-{
- int allocbytes = sizeof(struct parser_context) + bytes;
- struct parser_context *ctx;
-
- if (retry)
- *retry = false;
-
- /*
- * alloc an 0 extra byte to ensure payload is
- * '\0'-terminated
- */
- allocbytes++;
- if ((controlvm_payload_bytes_buffered + bytes)
- > MAX_CONTROLVM_PAYLOAD_BYTES) {
- if (retry)
- *retry = true;
- return NULL;
- }
- ctx = kzalloc(allocbytes, GFP_KERNEL | __GFP_NORETRY);
- if (!ctx) {
- if (retry)
- *retry = true;
- return NULL;
- }
-
- ctx->allocbytes = allocbytes;
- ctx->param_bytes = bytes;
- ctx->curr = NULL;
- ctx->bytes_remaining = 0;
- ctx->byte_stream = false;
- if (local) {
- void *p;
-
- if (addr > virt_to_phys(high_memory - 1))
- goto err_finish_ctx;
- p = __va((unsigned long)(addr));
- memcpy(ctx->data, p, bytes);
- } else {
- void *mapping = memremap(addr, bytes, MEMREMAP_WB);
-
- if (!mapping)
- goto err_finish_ctx;
- memcpy(ctx->data, mapping, bytes);
- memunmap(mapping);
- }
-
- ctx->byte_stream = true;
- controlvm_payload_bytes_buffered += ctx->param_bytes;
-
- return ctx;
-
-err_finish_ctx:
- parser_done(ctx);
- return NULL;
-}
-
-static uuid_le
-parser_id_get(struct parser_context *ctx)
-{
- struct spar_controlvm_parameters_header *phdr = NULL;
-
- if (!ctx)
- return NULL_UUID_LE;
- phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
- return phdr->id;
-}
-
-/** Describes the state from the perspective of which controlvm messages have
- * been received for a bus or device.
- */
-
-enum PARSER_WHICH_STRING {
- PARSERSTRING_INITIATOR,
- PARSERSTRING_TARGET,
- PARSERSTRING_CONNECTION,
- PARSERSTRING_NAME, /* TODO: only PARSERSTRING_NAME is used ? */
-};
-
-static void
-parser_param_start(struct parser_context *ctx,
- enum PARSER_WHICH_STRING which_string)
-{
- struct spar_controlvm_parameters_header *phdr = NULL;
-
- if (!ctx)
- return;
-
- phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
- switch (which_string) {
- case PARSERSTRING_INITIATOR:
- ctx->curr = ctx->data + phdr->initiator_offset;
- ctx->bytes_remaining = phdr->initiator_length;
- break;
- case PARSERSTRING_TARGET:
- ctx->curr = ctx->data + phdr->target_offset;
- ctx->bytes_remaining = phdr->target_length;
- break;
- case PARSERSTRING_CONNECTION:
- ctx->curr = ctx->data + phdr->connection_offset;
- ctx->bytes_remaining = phdr->connection_length;
- break;
- case PARSERSTRING_NAME:
- ctx->curr = ctx->data + phdr->name_offset;
- ctx->bytes_remaining = phdr->name_length;
- break;
- default:
- break;
- }
-}
-
-static void parser_done(struct parser_context *ctx)
-{
- if (!ctx)
- return;
- controlvm_payload_bytes_buffered -= ctx->param_bytes;
- kfree(ctx);
-}
-
-static void *
-parser_string_get(struct parser_context *ctx)
-{
- u8 *pscan;
- unsigned long nscan;
- int value_length = -1;
- void *value = NULL;
- int i;
-
- if (!ctx)
- return NULL;
- pscan = ctx->curr;
- nscan = ctx->bytes_remaining;
- if (nscan == 0)
- return NULL;
- if (!pscan)
- return NULL;
- for (i = 0, value_length = -1; i < nscan; i++)
- if (pscan[i] == '\0') {
- value_length = i;
- break;
- }
- if (value_length < 0) /* '\0' was not included in the length */
- value_length = nscan;
- value = kmalloc(value_length + 1, GFP_KERNEL | __GFP_NORETRY);
- if (!value)
- return NULL;
- if (value_length > 0)
- memcpy(value, pscan, value_length);
- ((u8 *)(value))[value_length] = '\0';
- return value;
-}
-
-static ssize_t toolaction_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
@@ -513,6 +212,7 @@ static ssize_t toolaction_store(struct device *dev,
return ret;
return count;
}
+static DEVICE_ATTR_RW(toolaction);
static ssize_t boottotool_show(struct device *dev,
struct device_attribute *attr,
@@ -549,6 +249,7 @@ static ssize_t boottotool_store(struct device *dev,
return ret;
return count;
}
+static DEVICE_ATTR_RW(boottotool);
static ssize_t error_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -580,6 +281,7 @@ static ssize_t error_store(struct device *dev, struct device_attribute *attr,
return ret;
return count;
}
+static DEVICE_ATTR_RW(error);
static ssize_t textid_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -612,6 +314,7 @@ static ssize_t textid_store(struct device *dev, struct device_attribute *attr,
return ret;
return count;
}
+static DEVICE_ATTR_RW(textid);
static ssize_t remaining_steps_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -644,6 +347,103 @@ static ssize_t remaining_steps_store(struct device *dev,
return ret;
return count;
}
+static DEVICE_ATTR_RW(remaining_steps);
+
+static uuid_le
+parser_id_get(struct parser_context *ctx)
+{
+ struct spar_controlvm_parameters_header *phdr = NULL;
+
+ if (!ctx)
+ return NULL_UUID_LE;
+ phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
+ return phdr->id;
+}
+
+/*
+ * Describes the state from the perspective of which controlvm messages have
+ * been received for a bus or device.
+ */
+
+enum PARSER_WHICH_STRING {
+ PARSERSTRING_INITIATOR,
+ PARSERSTRING_TARGET,
+ PARSERSTRING_CONNECTION,
+ PARSERSTRING_NAME, /* TODO: only PARSERSTRING_NAME is used ? */
+};
+
+static void
+parser_param_start(struct parser_context *ctx,
+ enum PARSER_WHICH_STRING which_string)
+{
+ struct spar_controlvm_parameters_header *phdr = NULL;
+
+ if (!ctx)
+ return;
+
+ phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
+ switch (which_string) {
+ case PARSERSTRING_INITIATOR:
+ ctx->curr = ctx->data + phdr->initiator_offset;
+ ctx->bytes_remaining = phdr->initiator_length;
+ break;
+ case PARSERSTRING_TARGET:
+ ctx->curr = ctx->data + phdr->target_offset;
+ ctx->bytes_remaining = phdr->target_length;
+ break;
+ case PARSERSTRING_CONNECTION:
+ ctx->curr = ctx->data + phdr->connection_offset;
+ ctx->bytes_remaining = phdr->connection_length;
+ break;
+ case PARSERSTRING_NAME:
+ ctx->curr = ctx->data + phdr->name_offset;
+ ctx->bytes_remaining = phdr->name_length;
+ break;
+ default:
+ break;
+ }
+}
+
+static void parser_done(struct parser_context *ctx)
+{
+ if (!ctx)
+ return;
+ controlvm_payload_bytes_buffered -= ctx->param_bytes;
+ kfree(ctx);
+}
+
+static void *
+parser_string_get(struct parser_context *ctx)
+{
+ u8 *pscan;
+ unsigned long nscan;
+ int value_length = -1;
+ void *value = NULL;
+ int i;
+
+ if (!ctx)
+ return NULL;
+ pscan = ctx->curr;
+ nscan = ctx->bytes_remaining;
+ if (nscan == 0)
+ return NULL;
+ if (!pscan)
+ return NULL;
+ for (i = 0, value_length = -1; i < nscan; i++)
+ if (pscan[i] == '\0') {
+ value_length = i;
+ break;
+ }
+ if (value_length < 0) /* '\0' was not included in the length */
+ value_length = nscan;
+ value = kmalloc(value_length + 1, GFP_KERNEL | __GFP_NORETRY);
+ if (!value)
+ return NULL;
+ if (value_length > 0)
+ memcpy(value, pscan, value_length);
+ ((u8 *)(value))[value_length] = '\0';
+ return value;
+}
struct visor_busdev {
u32 bus_no;
@@ -683,32 +483,36 @@ struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no,
vdev = to_visor_device(dev);
return vdev;
}
-EXPORT_SYMBOL(visorbus_get_device_by_id);
-void
-visorchipset_register_busdev(
- struct visorchipset_busdev_notifiers *notifiers,
- struct visorchipset_busdev_responders *responders,
- struct ultra_vbus_deviceinfo *driver_info)
-{
- down(&notifier_lock);
- if (!notifiers) {
- memset(&busdev_notifiers, 0,
- sizeof(busdev_notifiers));
- visorbusregistered = 0; /* clear flag */
- } else {
- busdev_notifiers = *notifiers;
- visorbusregistered = 1; /* set flag */
+static void
+controlvm_init_response(struct controlvm_message *msg,
+ struct controlvm_message_header *msg_hdr, int response)
+{
+ memset(msg, 0, sizeof(struct controlvm_message));
+ memcpy(&msg->hdr, msg_hdr, sizeof(struct controlvm_message_header));
+ msg->hdr.payload_bytes = 0;
+ msg->hdr.payload_vm_offset = 0;
+ msg->hdr.payload_max_bytes = 0;
+ if (response < 0) {
+ msg->hdr.flags.failed = 1;
+ msg->hdr.completion_status = (u32)(-response);
}
- if (responders)
- *responders = busdev_responders;
- if (driver_info)
- bus_device_info_init(driver_info, "chipset", "visorchipset",
- VERSION, NULL);
+}
+
+static void
+controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr,
+ int response,
+ enum ultra_chipset_feature features)
+{
+ struct controlvm_message outmsg;
- up(&notifier_lock);
+ controlvm_init_response(&outmsg, msg_hdr, response);
+ outmsg.cmd.init_chipset.features = features;
+ if (visorchannel_signalinsert(controlvm_channel,
+ CONTROLVM_QUEUE_REQUEST, &outmsg)) {
+ return;
+ }
}
-EXPORT_SYMBOL_GPL(visorchipset_register_busdev);
static void
chipset_init(struct controlvm_message *inmsg)
@@ -725,14 +529,16 @@ chipset_init(struct controlvm_message *inmsg)
chipset_inited = 1;
POSTCODE_LINUX_2(CHIPSET_INIT_EXIT_PC, POSTCODE_SEVERITY_INFO);
- /* Set features to indicate we support parahotplug (if Command
+ /*
+ * Set features to indicate we support parahotplug (if Command
* also supports it).
*/
features =
inmsg->cmd.init_chipset.
features & ULTRA_CHIPSET_FEATURE_PARA_HOTPLUG;
- /* Set the "reply" bit so Command knows this is a
+ /*
+ * Set the "reply" bit so Command knows this is a
* features-aware driver.
*/
features |= ULTRA_CHIPSET_FEATURE_REPLY;
@@ -743,21 +549,6 @@ out_respond:
}
static void
-controlvm_init_response(struct controlvm_message *msg,
- struct controlvm_message_header *msg_hdr, int response)
-{
- memset(msg, 0, sizeof(struct controlvm_message));
- memcpy(&msg->hdr, msg_hdr, sizeof(struct controlvm_message_header));
- msg->hdr.payload_bytes = 0;
- msg->hdr.payload_vm_offset = 0;
- msg->hdr.payload_max_bytes = 0;
- if (response < 0) {
- msg->hdr.flags.failed = 1;
- msg->hdr.completion_status = (u32)(-response);
- }
-}
-
-static void
controlvm_respond(struct controlvm_message_header *msg_hdr, int response)
{
struct controlvm_message outmsg;
@@ -766,23 +557,8 @@ controlvm_respond(struct controlvm_message_header *msg_hdr, int response)
if (outmsg.hdr.flags.test_message == 1)
return;
- if (!visorchannel_signalinsert(controlvm_channel,
- CONTROLVM_QUEUE_REQUEST, &outmsg)) {
- return;
- }
-}
-
-static void
-controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr,
- int response,
- enum ultra_chipset_feature features)
-{
- struct controlvm_message outmsg;
-
- controlvm_init_response(&outmsg, msg_hdr, response);
- outmsg.cmd.init_chipset.features = features;
- if (!visorchannel_signalinsert(controlvm_channel,
- CONTROLVM_QUEUE_REQUEST, &outmsg)) {
+ if (visorchannel_signalinsert(controlvm_channel,
+ CONTROLVM_QUEUE_REQUEST, &outmsg)) {
return;
}
}
@@ -796,8 +572,8 @@ static void controlvm_respond_physdev_changestate(
controlvm_init_response(&outmsg, msg_hdr, response);
outmsg.cmd.device_change_state.state = state;
outmsg.cmd.device_change_state.flags.phys_device = 1;
- if (!visorchannel_signalinsert(controlvm_channel,
- CONTROLVM_QUEUE_REQUEST, &outmsg)) {
+ if (visorchannel_signalinsert(controlvm_channel,
+ CONTROLVM_QUEUE_REQUEST, &outmsg)) {
return;
}
}
@@ -894,8 +670,8 @@ device_changestate_responder(enum controlvm_id cmd_id,
outmsg.cmd.device_change_state.dev_no = dev_no;
outmsg.cmd.device_change_state.state = response_state;
- if (!visorchannel_signalinsert(controlvm_channel,
- CONTROLVM_QUEUE_REQUEST, &outmsg))
+ if (visorchannel_signalinsert(controlvm_channel,
+ CONTROLVM_QUEUE_REQUEST, &outmsg))
return;
}
@@ -920,20 +696,20 @@ bus_epilog(struct visor_device *bus_info,
{
struct controlvm_message_header *pmsg_hdr = NULL;
- down(&notifier_lock);
-
if (!bus_info) {
- /* relying on a valid passed in response code */
- /* be lazy and re-use msg_hdr for this failure, is this ok?? */
+ /*
+ * relying on a valid passed in response code
+ * be lazy and re-use msg_hdr for this failure, is this ok??
+ */
pmsg_hdr = msg_hdr;
- goto out_respond_and_unlock;
+ goto out_respond;
}
if (bus_info->pending_msg_hdr) {
/* only non-NULL if dev is still waiting on a response */
response = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT;
pmsg_hdr = bus_info->pending_msg_hdr;
- goto out_respond_and_unlock;
+ goto out_respond;
}
if (need_response) {
@@ -942,7 +718,7 @@ bus_epilog(struct visor_device *bus_info,
POSTCODE_LINUX_4(MALLOC_FAILURE_PC, cmd,
bus_info->chipset_bus_no,
POSTCODE_SEVERITY_ERR);
- goto out_unlock;
+ return;
}
memcpy(pmsg_hdr, msg_hdr,
@@ -953,25 +729,16 @@ bus_epilog(struct visor_device *bus_info,
if (response == CONTROLVM_RESP_SUCCESS) {
switch (cmd) {
case CONTROLVM_BUS_CREATE:
- if (busdev_notifiers.bus_create) {
- (*busdev_notifiers.bus_create) (bus_info);
- goto out_unlock;
- }
+ chipset_bus_create(bus_info);
break;
case CONTROLVM_BUS_DESTROY:
- if (busdev_notifiers.bus_destroy) {
- (*busdev_notifiers.bus_destroy) (bus_info);
- goto out_unlock;
- }
+ chipset_bus_destroy(bus_info);
break;
}
}
-out_respond_and_unlock:
+out_respond:
bus_responder(cmd, pmsg_hdr, response);
-
-out_unlock:
- up(&notifier_lock);
}
static void
@@ -980,31 +747,29 @@ device_epilog(struct visor_device *dev_info,
struct controlvm_message_header *msg_hdr, int response,
bool need_response, bool for_visorbus)
{
- struct visorchipset_busdev_notifiers *notifiers;
struct controlvm_message_header *pmsg_hdr = NULL;
- notifiers = &busdev_notifiers;
-
- down(&notifier_lock);
if (!dev_info) {
- /* relying on a valid passed in response code */
- /* be lazy and re-use msg_hdr for this failure, is this ok?? */
+ /*
+ * relying on a valid passed in response code
+ * be lazy and re-use msg_hdr for this failure, is this ok??
+ */
pmsg_hdr = msg_hdr;
- goto out_respond_and_unlock;
+ goto out_respond;
}
if (dev_info->pending_msg_hdr) {
/* only non-NULL if dev is still waiting on a response */
response = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT;
pmsg_hdr = dev_info->pending_msg_hdr;
- goto out_respond_and_unlock;
+ goto out_respond;
}
if (need_response) {
pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL);
if (!pmsg_hdr) {
response = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
- goto out_respond_and_unlock;
+ goto out_respond;
}
memcpy(pmsg_hdr, msg_hdr,
@@ -1015,48 +780,34 @@ device_epilog(struct visor_device *dev_info,
if (response >= 0) {
switch (cmd) {
case CONTROLVM_DEVICE_CREATE:
- if (notifiers->device_create) {
- (*notifiers->device_create) (dev_info);
- goto out_unlock;
- }
+ chipset_device_create(dev_info);
break;
case CONTROLVM_DEVICE_CHANGESTATE:
/* ServerReady / ServerRunning / SegmentStateRunning */
if (state.alive == segment_state_running.alive &&
state.operating ==
segment_state_running.operating) {
- if (notifiers->device_resume) {
- (*notifiers->device_resume) (dev_info);
- goto out_unlock;
- }
+ chipset_device_resume(dev_info);
}
/* ServerNotReady / ServerLost / SegmentStateStandby */
else if (state.alive == segment_state_standby.alive &&
state.operating ==
segment_state_standby.operating) {
- /* technically this is standby case
+ /*
+ * technically this is standby case
* where server is lost
*/
- if (notifiers->device_pause) {
- (*notifiers->device_pause) (dev_info);
- goto out_unlock;
- }
+ chipset_device_pause(dev_info);
}
break;
case CONTROLVM_DEVICE_DESTROY:
- if (notifiers->device_destroy) {
- (*notifiers->device_destroy) (dev_info);
- goto out_unlock;
- }
+ chipset_device_destroy(dev_info);
break;
}
}
-out_respond_and_unlock:
+out_respond:
device_responder(cmd, pmsg_hdr, response);
-
-out_unlock:
- up(&notifier_lock);
}
static void
@@ -1103,10 +854,8 @@ bus_create(struct controlvm_message *inmsg)
goto out_bus_epilog;
}
bus_info->visorchannel = visorchannel;
- if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, spar_siovm_uuid) == 0) {
- dump_vhba_bus = bus_no;
+ if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, spar_siovm_uuid) == 0)
save_crash_message(inmsg, CRASH_BUS);
- }
POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus_no, POSTCODE_SEVERITY_INFO);
@@ -1303,11 +1052,19 @@ my_device_destroy(struct controlvm_message *inmsg)
inmsg->hdr.flags.response_expected == 1, 1);
}
-/* When provided with the physical address of the controlvm channel
+/**
+ * initialize_controlvm_payload_info() - init controlvm_payload_info struct
+ * @phys_addr: the physical address of controlvm channel
+ * @offset: the offset to payload
+ * @bytes: the size of the payload in bytes
+ * @info: the returning valid struct
+ *
+ * When provided with the physical address of the controlvm channel
* (phys_addr), the offset to the payload area we need to manage
* (offset), and the size of this payload area (bytes), fills in the
- * controlvm_payload_info struct. Returns true for success or false
- * for failure.
+ * controlvm_payload_info struct.
+ *
+ * Return: CONTROLVM_RESP_SUCCESS for success or a negative for failure
*/
static int
initialize_controlvm_payload_info(u64 phys_addr, u64 offset, u32 bytes,
@@ -1371,95 +1128,14 @@ initialize_controlvm_payload(void)
&controlvm_payload_info);
}
-/* Send ACTION=online for DEVPATH=/sys/devices/platform/visorchipset.
- * Returns CONTROLVM_RESP_xxx code.
- */
-static int
-visorchipset_chipset_ready(void)
-{
- kobject_uevent(&visorchipset_platform_device.dev.kobj, KOBJ_ONLINE);
- return CONTROLVM_RESP_SUCCESS;
-}
-
-static int
-visorchipset_chipset_selftest(void)
-{
- char env_selftest[20];
- char *envp[] = { env_selftest, NULL };
-
- sprintf(env_selftest, "SPARSP_SELFTEST=%d", 1);
- kobject_uevent_env(&visorchipset_platform_device.dev.kobj, KOBJ_CHANGE,
- envp);
- return CONTROLVM_RESP_SUCCESS;
-}
-
-/* Send ACTION=offline for DEVPATH=/sys/devices/platform/visorchipset.
- * Returns CONTROLVM_RESP_xxx code.
- */
-static int
-visorchipset_chipset_notready(void)
-{
- kobject_uevent(&visorchipset_platform_device.dev.kobj, KOBJ_OFFLINE);
- return CONTROLVM_RESP_SUCCESS;
-}
-
-static void
-chipset_ready(struct controlvm_message_header *msg_hdr)
-{
- int rc = visorchipset_chipset_ready();
-
- if (rc != CONTROLVM_RESP_SUCCESS)
- rc = -rc;
- if (msg_hdr->flags.response_expected)
- controlvm_respond(msg_hdr, rc);
-}
-
-static void
-chipset_selftest(struct controlvm_message_header *msg_hdr)
-{
- int rc = visorchipset_chipset_selftest();
-
- if (rc != CONTROLVM_RESP_SUCCESS)
- rc = -rc;
- if (msg_hdr->flags.response_expected)
- controlvm_respond(msg_hdr, rc);
-}
-
-static void
-chipset_notready(struct controlvm_message_header *msg_hdr)
-{
- int rc = visorchipset_chipset_notready();
-
- if (rc != CONTROLVM_RESP_SUCCESS)
- rc = -rc;
- if (msg_hdr->flags.response_expected)
- controlvm_respond(msg_hdr, rc);
-}
-
-/* This is your "one-stop" shop for grabbing the next message from the
- * CONTROLVM_QUEUE_EVENT queue in the controlvm channel.
- */
-static bool
-read_controlvm_event(struct controlvm_message *msg)
-{
- if (visorchannel_signalremove(controlvm_channel,
- CONTROLVM_QUEUE_EVENT, msg)) {
- /* got a message */
- if (msg->hdr.flags.test_message == 1)
- return false;
- return true;
- }
- return false;
-}
-
/*
- * The general parahotplug flow works as follows. The visorchipset
+ * The general parahotplug flow works as follows. The visorchipset
* driver receives a DEVICE_CHANGESTATE message from Command
- * specifying a physical device to enable or disable. The CONTROLVM
+ * specifying a physical device to enable or disable. The CONTROLVM
* message handler calls parahotplug_process_message, which then adds
* the message to a global list and kicks off a udev event which
* causes a user level script to enable or disable the specified
- * device. The udev script then writes to
+ * device. The udev script then writes to
* /proc/visorchipset/parahotplug, which causes parahotplug_proc_write
* to get called, at which point the appropriate CONTROLVM message is
* retrieved from the list and responded to.
@@ -1467,9 +1143,11 @@ read_controlvm_event(struct controlvm_message *msg)
#define PARAHOTPLUG_TIMEOUT_MS 2000
-/*
- * Generate unique int to match an outstanding CONTROLVM message with a
- * udev script /proc response
+/**
+ * parahotplug_next_id() - generate unique int to match an outstanding CONTROLVM
+ * message with a udev script /proc response
+ *
+ * Return: a unique integer value
*/
static int
parahotplug_next_id(void)
@@ -1479,9 +1157,12 @@ parahotplug_next_id(void)
return atomic_inc_return(&id);
}
-/*
- * Returns the time (in jiffies) when a CONTROLVM message on the list
- * should expire -- PARAHOTPLUG_TIMEOUT_MS in the future
+/**
+ * parahotplug_next_expiration() - returns the time (in jiffies) when a
+ * CONTROLVM message on the list should expire
+ * -- PARAHOTPLUG_TIMEOUT_MS in the future
+ *
+ * Return: expected expiration time (in jiffies)
*/
static unsigned long
parahotplug_next_expiration(void)
@@ -1489,9 +1170,13 @@ parahotplug_next_expiration(void)
return jiffies + msecs_to_jiffies(PARAHOTPLUG_TIMEOUT_MS);
}
-/*
- * Create a parahotplug_request, which is basically a wrapper for a
- * CONTROLVM_MESSAGE that we can stick on a list
+/**
+ * parahotplug_request_create() - create a parahotplug_request, which is
+ * basically a wrapper for a CONTROLVM_MESSAGE
+ * that we can stick on a list
+ * @msg: the message to insert in the request
+ *
+ * Return: the request containing the provided message
*/
static struct parahotplug_request *
parahotplug_request_create(struct controlvm_message *msg)
@@ -1509,8 +1194,9 @@ parahotplug_request_create(struct controlvm_message *msg)
return req;
}
-/*
- * Free a parahotplug_request.
+/**
+ * parahotplug_request_destroy() - free a parahotplug_request
+ * @req: the request to deallocate
*/
static void
parahotplug_request_destroy(struct parahotplug_request *req)
@@ -1518,71 +1204,19 @@ parahotplug_request_destroy(struct parahotplug_request *req)
kfree(req);
}
-/*
- * Cause uevent to run the user level script to do the disable/enable
- * specified in (the CONTROLVM message in) the specified
- * parahotplug_request
- */
-static void
-parahotplug_request_kickoff(struct parahotplug_request *req)
-{
- struct controlvm_message_packet *cmd = &req->msg.cmd;
- char env_cmd[40], env_id[40], env_state[40], env_bus[40], env_dev[40],
- env_func[40];
- char *envp[] = {
- env_cmd, env_id, env_state, env_bus, env_dev, env_func, NULL
- };
-
- sprintf(env_cmd, "SPAR_PARAHOTPLUG=1");
- sprintf(env_id, "SPAR_PARAHOTPLUG_ID=%d", req->id);
- sprintf(env_state, "SPAR_PARAHOTPLUG_STATE=%d",
- cmd->device_change_state.state.active);
- sprintf(env_bus, "SPAR_PARAHOTPLUG_BUS=%d",
- cmd->device_change_state.bus_no);
- sprintf(env_dev, "SPAR_PARAHOTPLUG_DEVICE=%d",
- cmd->device_change_state.dev_no >> 3);
- sprintf(env_func, "SPAR_PARAHOTPLUG_FUNCTION=%d",
- cmd->device_change_state.dev_no & 0x7);
-
- kobject_uevent_env(&visorchipset_platform_device.dev.kobj, KOBJ_CHANGE,
- envp);
-}
-
-/*
- * Remove any request from the list that's been on there too long and
- * respond with an error.
- */
-static void
-parahotplug_process_list(void)
-{
- struct list_head *pos;
- struct list_head *tmp;
-
- spin_lock(&parahotplug_request_list_lock);
-
- list_for_each_safe(pos, tmp, &parahotplug_request_list) {
- struct parahotplug_request *req =
- list_entry(pos, struct parahotplug_request, list);
-
- if (!time_after_eq(jiffies, req->expiration))
- continue;
-
- list_del(pos);
- if (req->msg.hdr.flags.response_expected)
- controlvm_respond_physdev_changestate(
- &req->msg.hdr,
- CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT,
- req->msg.cmd.device_change_state.state);
- parahotplug_request_destroy(req);
- }
-
- spin_unlock(&parahotplug_request_list_lock);
-}
+static LIST_HEAD(parahotplug_request_list);
+static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* lock for above */
-/*
+/**
+ * parahotplug_request_complete() - mark request as complete
+ * @id: the id of the request
+ * @active: indicates whether the request is assigned to active partition
+ *
* Called from the /proc handler, which means the user script has
- * finished the enable/disable. Find the matching identifier, and
+ * finished the enable/disable. Find the matching identifier, and
* respond to the CONTROLVM message with success.
+ *
+ * Return: 0 on success or -EINVAL on failure
*/
static int
parahotplug_request_complete(int id, u16 active)
@@ -1597,7 +1231,8 @@ parahotplug_request_complete(int id, u16 active)
struct parahotplug_request *req =
list_entry(pos, struct parahotplug_request, list);
if (req->id == id) {
- /* Found a match. Remove it from the list and
+ /*
+ * Found a match. Remove it from the list and
* respond.
*/
list_del(pos);
@@ -1616,8 +1251,142 @@ parahotplug_request_complete(int id, u16 active)
return -EINVAL;
}
-/*
- * Enables or disables a PCI device by kicking off a udev script
+/**
+ * devicedisabled_store() - disables the hotplug device
+ * @dev: sysfs interface variable not utilized in this function
+ * @attr: sysfs interface variable not utilized in this function
+ * @buf: buffer containing the device id
+ * @count: the size of the buffer
+ *
+ * The parahotplug/devicedisabled interface gets called by our support script
+ * when an SR-IOV device has been shut down. The ID is passed to the script
+ * and then passed back when the device has been removed.
+ *
+ * Return: the size of the buffer for success or negative for error
+ */
+static ssize_t devicedisabled_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned int id;
+ int err;
+
+ if (kstrtouint(buf, 10, &id))
+ return -EINVAL;
+
+ err = parahotplug_request_complete(id, 0);
+ if (err < 0)
+ return err;
+ return count;
+}
+static DEVICE_ATTR_WO(devicedisabled);
+
+/**
+ * deviceenabled_store() - enables the hotplug device
+ * @dev: sysfs interface variable not utilized in this function
+ * @attr: sysfs interface variable not utilized in this function
+ * @buf: buffer containing the device id
+ * @count: the size of the buffer
+ *
+ * The parahotplug/deviceenabled interface gets called by our support script
+ * when an SR-IOV device has been recovered. The ID is passed to the script
+ * and then passed back when the device has been brought back up.
+ *
+ * Return: the size of the buffer for success or negative for error
+ */
+static ssize_t deviceenabled_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned int id;
+
+ if (kstrtouint(buf, 10, &id))
+ return -EINVAL;
+
+ parahotplug_request_complete(id, 1);
+ return count;
+}
+static DEVICE_ATTR_WO(deviceenabled);
+
+static struct attribute *visorchipset_install_attrs[] = {
+ &dev_attr_toolaction.attr,
+ &dev_attr_boottotool.attr,
+ &dev_attr_error.attr,
+ &dev_attr_textid.attr,
+ &dev_attr_remaining_steps.attr,
+ NULL
+};
+
+static struct attribute_group visorchipset_install_group = {
+ .name = "install",
+ .attrs = visorchipset_install_attrs
+};
+
+static struct attribute *visorchipset_parahotplug_attrs[] = {
+ &dev_attr_devicedisabled.attr,
+ &dev_attr_deviceenabled.attr,
+ NULL
+};
+
+static struct attribute_group visorchipset_parahotplug_group = {
+ .name = "parahotplug",
+ .attrs = visorchipset_parahotplug_attrs
+};
+
+static const struct attribute_group *visorchipset_dev_groups[] = {
+ &visorchipset_install_group,
+ &visorchipset_parahotplug_group,
+ NULL
+};
+
+static void visorchipset_dev_release(struct device *dev)
+{
+}
+
+/* /sys/devices/platform/visorchipset */
+static struct platform_device visorchipset_platform_device = {
+ .name = "visorchipset",
+ .id = -1,
+ .dev.groups = visorchipset_dev_groups,
+ .dev.release = visorchipset_dev_release,
+};
+
+/**
+ * parahotplug_request_kickoff() - initiate parahotplug request
+ * @req: the request to initiate
+ *
+ * Cause uevent to run the user level script to do the disable/enable specified
+ * in the parahotplug_request.
+ */
+static void
+parahotplug_request_kickoff(struct parahotplug_request *req)
+{
+ struct controlvm_message_packet *cmd = &req->msg.cmd;
+ char env_cmd[40], env_id[40], env_state[40], env_bus[40], env_dev[40],
+ env_func[40];
+ char *envp[] = {
+ env_cmd, env_id, env_state, env_bus, env_dev, env_func, NULL
+ };
+
+ sprintf(env_cmd, "SPAR_PARAHOTPLUG=1");
+ sprintf(env_id, "SPAR_PARAHOTPLUG_ID=%d", req->id);
+ sprintf(env_state, "SPAR_PARAHOTPLUG_STATE=%d",
+ cmd->device_change_state.state.active);
+ sprintf(env_bus, "SPAR_PARAHOTPLUG_BUS=%d",
+ cmd->device_change_state.bus_no);
+ sprintf(env_dev, "SPAR_PARAHOTPLUG_DEVICE=%d",
+ cmd->device_change_state.dev_no >> 3);
+ sprintf(env_func, "SPAR_PARAHOTPLUG_FUNCTION=%d",
+ cmd->device_change_state.dev_no & 0x7);
+
+ kobject_uevent_env(&visorchipset_platform_device.dev.kobj, KOBJ_CHANGE,
+ envp);
+}
+
+/**
+ * parahotplug_process_message() - enables or disables a PCI device by kicking
+ * off a udev script
+ * @inmsg: the message indicating whether to enable or disable
*/
static void
parahotplug_process_message(struct controlvm_message *inmsg)
@@ -1630,14 +1399,16 @@ parahotplug_process_message(struct controlvm_message *inmsg)
return;
if (inmsg->cmd.device_change_state.state.active) {
- /* For enable messages, just respond with success
- * right away. This is a bit of a hack, but there are
- * issues with the early enable messages we get (with
- * either the udev script not detecting that the device
- * is up, or not getting called at all). Fortunately
- * the messages that get lost don't matter anyway, as
- * devices are automatically enabled at
- * initialization.
+ /*
+ * For enable messages, just respond with success
+ * right away. This is a bit of a hack, but there are
+ * issues with the early enable messages we get (with
+ * either the udev script not detecting that the device
+ * is up, or not getting called at all). Fortunately
+ * the messages that get lost don't matter anyway, as
+ *
+ * devices are automatically enabled at
+ * initialization.
*/
parahotplug_request_kickoff(req);
controlvm_respond_physdev_changestate
@@ -1646,11 +1417,12 @@ parahotplug_process_message(struct controlvm_message *inmsg)
inmsg->cmd.device_change_state.state);
parahotplug_request_destroy(req);
} else {
- /* For disable messages, add the request to the
- * request list before kicking off the udev script. It
- * won't get responded to until the script has
- * indicated it's done.
- */
+ /*
+ * For disable messages, add the request to the
+ * request list before kicking off the udev script. It
+ * won't get responded to until the script has
+ * indicated it's done.
+ */
spin_lock(&parahotplug_request_list_lock);
list_add_tail(&req->list, &parahotplug_request_list);
spin_unlock(&parahotplug_request_list_lock);
@@ -1659,113 +1431,77 @@ parahotplug_process_message(struct controlvm_message *inmsg)
}
}
-/* Process a controlvm message.
- * Return result:
- * false - this function will return false only in the case where the
- * controlvm message was NOT processed, but processing must be
- * retried before reading the next controlvm message; a
- * scenario where this can occur is when we need to throttle
- * the allocation of memory in which to copy out controlvm
- * payload data
- * true - processing of the controlvm message completed,
- * either successfully or with an error.
+/**
+ * visorchipset_chipset_ready() - sends chipset_ready action
+ *
+ * Send ACTION=online for DEVPATH=/sys/devices/platform/visorchipset.
+ *
+ * Return: CONTROLVM_RESP_SUCCESS
*/
-static bool
-handle_command(struct controlvm_message inmsg, u64 channel_addr)
+static int
+visorchipset_chipset_ready(void)
{
- struct controlvm_message_packet *cmd = &inmsg.cmd;
- u64 parm_addr;
- u32 parm_bytes;
- struct parser_context *parser_ctx = NULL;
- bool local_addr;
- struct controlvm_message ackmsg;
+ kobject_uevent(&visorchipset_platform_device.dev.kobj, KOBJ_ONLINE);
+ return CONTROLVM_RESP_SUCCESS;
+}
- /* create parsing context if necessary */
- local_addr = (inmsg.hdr.flags.test_message == 1);
- if (channel_addr == 0)
- return true;
- parm_addr = channel_addr + inmsg.hdr.payload_vm_offset;
- parm_bytes = inmsg.hdr.payload_bytes;
+static int
+visorchipset_chipset_selftest(void)
+{
+ char env_selftest[20];
+ char *envp[] = { env_selftest, NULL };
- /* Parameter and channel addresses within test messages actually lie
- * within our OS-controlled memory. We need to know that, because it
- * makes a difference in how we compute the virtual address.
- */
- if (parm_addr && parm_bytes) {
- bool retry = false;
+ sprintf(env_selftest, "SPARSP_SELFTEST=%d", 1);
+ kobject_uevent_env(&visorchipset_platform_device.dev.kobj, KOBJ_CHANGE,
+ envp);
+ return CONTROLVM_RESP_SUCCESS;
+}
- parser_ctx =
- parser_init_byte_stream(parm_addr, parm_bytes,
- local_addr, &retry);
- if (!parser_ctx && retry)
- return false;
- }
+/**
+ * visorchipset_chipset_notready() - sends chipset_notready action
+ *
+ * Send ACTION=offline for DEVPATH=/sys/devices/platform/visorchipset.
+ *
+ * Return: CONTROLVM_RESP_SUCCESS
+ */
+static int
+visorchipset_chipset_notready(void)
+{
+ kobject_uevent(&visorchipset_platform_device.dev.kobj, KOBJ_OFFLINE);
+ return CONTROLVM_RESP_SUCCESS;
+}
- if (!local_addr) {
- controlvm_init_response(&ackmsg, &inmsg.hdr,
- CONTROLVM_RESP_SUCCESS);
- if (controlvm_channel)
- visorchannel_signalinsert(controlvm_channel,
- CONTROLVM_QUEUE_ACK,
- &ackmsg);
- }
- switch (inmsg.hdr.id) {
- case CONTROLVM_CHIPSET_INIT:
- chipset_init(&inmsg);
- break;
- case CONTROLVM_BUS_CREATE:
- bus_create(&inmsg);
- break;
- case CONTROLVM_BUS_DESTROY:
- bus_destroy(&inmsg);
- break;
- case CONTROLVM_BUS_CONFIGURE:
- bus_configure(&inmsg, parser_ctx);
- break;
- case CONTROLVM_DEVICE_CREATE:
- my_device_create(&inmsg);
- break;
- case CONTROLVM_DEVICE_CHANGESTATE:
- if (cmd->device_change_state.flags.phys_device) {
- parahotplug_process_message(&inmsg);
- } else {
- /* save the hdr and cmd structures for later use */
- /* when sending back the response to Command */
- my_device_changestate(&inmsg);
- g_devicechangestate_packet = inmsg.cmd;
- break;
- }
- break;
- case CONTROLVM_DEVICE_DESTROY:
- my_device_destroy(&inmsg);
- break;
- case CONTROLVM_DEVICE_CONFIGURE:
- /* no op for now, just send a respond that we passed */
- if (inmsg.hdr.flags.response_expected)
- controlvm_respond(&inmsg.hdr, CONTROLVM_RESP_SUCCESS);
- break;
- case CONTROLVM_CHIPSET_READY:
- chipset_ready(&inmsg.hdr);
- break;
- case CONTROLVM_CHIPSET_SELFTEST:
- chipset_selftest(&inmsg.hdr);
- break;
- case CONTROLVM_CHIPSET_STOP:
- chipset_notready(&inmsg.hdr);
- break;
- default:
- if (inmsg.hdr.flags.response_expected)
- controlvm_respond
- (&inmsg.hdr,
- -CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN);
- break;
- }
+static void
+chipset_ready(struct controlvm_message_header *msg_hdr)
+{
+ int rc = visorchipset_chipset_ready();
- if (parser_ctx) {
- parser_done(parser_ctx);
- parser_ctx = NULL;
- }
- return true;
+ if (rc != CONTROLVM_RESP_SUCCESS)
+ rc = -rc;
+ if (msg_hdr->flags.response_expected)
+ controlvm_respond(msg_hdr, rc);
+}
+
+static void
+chipset_selftest(struct controlvm_message_header *msg_hdr)
+{
+ int rc = visorchipset_chipset_selftest();
+
+ if (rc != CONTROLVM_RESP_SUCCESS)
+ rc = -rc;
+ if (msg_hdr->flags.response_expected)
+ controlvm_respond(msg_hdr, rc);
+}
+
+static void
+chipset_notready(struct controlvm_message_header *msg_hdr)
+{
+ int rc = visorchipset_chipset_notready();
+
+ if (rc != CONTROLVM_RESP_SUCCESS)
+ rc = -rc;
+ if (msg_hdr->flags.response_expected)
+ controlvm_respond(msg_hdr, rc);
}
static inline unsigned int
@@ -1796,76 +1532,6 @@ static u64 controlvm_get_channel_address(void)
}
static void
-controlvm_periodic_work(struct work_struct *work)
-{
- struct controlvm_message inmsg;
- bool got_command = false;
- bool handle_command_failed = false;
-
- /* make sure visorbus server is registered for controlvm callbacks */
- if (visorchipset_visorbusregwait && !visorbusregistered)
- goto cleanup;
-
- while (visorchannel_signalremove(controlvm_channel,
- CONTROLVM_QUEUE_RESPONSE,
- &inmsg))
- ;
- if (!got_command) {
- if (controlvm_pending_msg_valid) {
- /* we throttled processing of a prior
- * msg, so try to process it again
- * rather than reading a new one
- */
- inmsg = controlvm_pending_msg;
- controlvm_pending_msg_valid = false;
- got_command = true;
- } else {
- got_command = read_controlvm_event(&inmsg);
- }
- }
-
- handle_command_failed = false;
- while (got_command && (!handle_command_failed)) {
- most_recent_message_jiffies = jiffies;
- if (handle_command(inmsg,
- visorchannel_get_physaddr
- (controlvm_channel)))
- got_command = read_controlvm_event(&inmsg);
- else {
- /* this is a scenario where throttling
- * is required, but probably NOT an
- * error...; we stash the current
- * controlvm msg so we will attempt to
- * reprocess it on our next loop
- */
- handle_command_failed = true;
- controlvm_pending_msg = inmsg;
- controlvm_pending_msg_valid = true;
- }
- }
-
- /* parahotplug_worker */
- parahotplug_process_list();
-
-cleanup:
-
- if (time_after(jiffies,
- most_recent_message_jiffies + (HZ * MIN_IDLE_SECONDS))) {
- /* it's been longer than MIN_IDLE_SECONDS since we
- * processed our last controlvm message; slow down the
- * polling
- */
- if (poll_jiffies != POLLJIFFIES_CONTROLVMCHANNEL_SLOW)
- poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_SLOW;
- } else {
- if (poll_jiffies != POLLJIFFIES_CONTROLVMCHANNEL_FAST)
- poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST;
- }
-
- schedule_delayed_work(&periodic_controlvm_work, poll_jiffies);
-}
-
-static void
setup_crash_devices_work_queue(struct work_struct *work)
{
struct controlvm_message local_crash_bus_msg;
@@ -1874,13 +1540,6 @@ setup_crash_devices_work_queue(struct work_struct *work)
u32 local_crash_msg_offset;
u16 local_crash_msg_count;
- /* make sure visorbus is registered for controlvm callbacks */
- if (visorchipset_visorbusregwait && !visorbusregistered) {
- poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_SLOW;
- schedule_delayed_work(&periodic_controlvm_work, poll_jiffies);
- return;
- }
-
POSTCODE_LINUX_2(CRASH_DEV_ENTRY_PC, POSTCODE_SEVERITY_INFO);
/* send init chipset msg */
@@ -1958,7 +1617,7 @@ setup_crash_devices_work_queue(struct work_struct *work)
POSTCODE_LINUX_2(CRASH_DEV_EXIT_PC, POSTCODE_SEVERITY_INFO);
}
-static void
+void
bus_create_response(struct visor_device *bus_info, int response)
{
if (response >= 0)
@@ -1971,7 +1630,7 @@ bus_create_response(struct visor_device *bus_info, int response)
bus_info->pending_msg_hdr = NULL;
}
-static void
+void
bus_destroy_response(struct visor_device *bus_info, int response)
{
bus_responder(CONTROLVM_BUS_DESTROY, bus_info->pending_msg_hdr,
@@ -1981,7 +1640,7 @@ bus_destroy_response(struct visor_device *bus_info, int response)
bus_info->pending_msg_hdr = NULL;
}
-static void
+void
device_create_response(struct visor_device *dev_info, int response)
{
if (response >= 0)
@@ -1994,7 +1653,7 @@ device_create_response(struct visor_device *dev_info, int response)
dev_info->pending_msg_hdr = NULL;
}
-static void
+void
device_destroy_response(struct visor_device *dev_info, int response)
{
device_responder(CONTROLVM_DEVICE_DESTROY, dev_info->pending_msg_hdr,
@@ -2004,9 +1663,9 @@ device_destroy_response(struct visor_device *dev_info, int response)
dev_info->pending_msg_hdr = NULL;
}
-static void
-visorchipset_device_pause_response(struct visor_device *dev_info,
- int response)
+void
+device_pause_response(struct visor_device *dev_info,
+ int response)
{
device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE,
dev_info, response,
@@ -2016,7 +1675,7 @@ visorchipset_device_pause_response(struct visor_device *dev_info,
dev_info->pending_msg_hdr = NULL;
}
-static void
+void
device_resume_response(struct visor_device *dev_info, int response)
{
device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE,
@@ -2027,40 +1686,6 @@ device_resume_response(struct visor_device *dev_info, int response)
dev_info->pending_msg_hdr = NULL;
}
-/* The parahotplug/devicedisabled interface gets called by our support script
- * when an SR-IOV device has been shut down. The ID is passed to the script
- * and then passed back when the device has been removed.
- */
-static ssize_t devicedisabled_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- unsigned int id;
-
- if (kstrtouint(buf, 10, &id))
- return -EINVAL;
-
- parahotplug_request_complete(id, 0);
- return count;
-}
-
-/* The parahotplug/deviceenabled interface gets called by our support script
- * when an SR-IOV device has been recovered. The ID is passed to the script
- * and then passed back when the device has been brought back up.
- */
-static ssize_t deviceenabled_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- unsigned int id;
-
- if (kstrtouint(buf, 10, &id))
- return -EINVAL;
-
- parahotplug_request_complete(id, 1);
- return count;
-}
-
static int
visorchipset_mmap(struct file *file, struct vm_area_struct *vma)
{
@@ -2191,6 +1816,298 @@ visorchipset_file_cleanup(dev_t major_dev)
unregister_chrdev_region(major_dev, 1);
}
+static struct parser_context *
+parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry)
+{
+ int allocbytes = sizeof(struct parser_context) + bytes;
+ struct parser_context *ctx;
+
+ if (retry)
+ *retry = false;
+
+ /*
+ * alloc an 0 extra byte to ensure payload is
+ * '\0'-terminated
+ */
+ allocbytes++;
+ if ((controlvm_payload_bytes_buffered + bytes)
+ > MAX_CONTROLVM_PAYLOAD_BYTES) {
+ if (retry)
+ *retry = true;
+ return NULL;
+ }
+ ctx = kzalloc(allocbytes, GFP_KERNEL | __GFP_NORETRY);
+ if (!ctx) {
+ if (retry)
+ *retry = true;
+ return NULL;
+ }
+
+ ctx->allocbytes = allocbytes;
+ ctx->param_bytes = bytes;
+ ctx->curr = NULL;
+ ctx->bytes_remaining = 0;
+ ctx->byte_stream = false;
+ if (local) {
+ void *p;
+
+ if (addr > virt_to_phys(high_memory - 1))
+ goto err_finish_ctx;
+ p = __va((unsigned long)(addr));
+ memcpy(ctx->data, p, bytes);
+ } else {
+ void *mapping = memremap(addr, bytes, MEMREMAP_WB);
+
+ if (!mapping)
+ goto err_finish_ctx;
+ memcpy(ctx->data, mapping, bytes);
+ memunmap(mapping);
+ }
+
+ ctx->byte_stream = true;
+ controlvm_payload_bytes_buffered += ctx->param_bytes;
+
+ return ctx;
+
+err_finish_ctx:
+ parser_done(ctx);
+ return NULL;
+}
+
+/**
+ * handle_command() - process a controlvm message
+ * @inmsg: the message to process
+ * @channel_addr: address of the controlvm channel
+ *
+ * Return:
+ * false - this function will return false only in the case where the
+ * controlvm message was NOT processed, but processing must be
+ * retried before reading the next controlvm message; a
+ * scenario where this can occur is when we need to throttle
+ * the allocation of memory in which to copy out controlvm
+ * payload data
+ * true - processing of the controlvm message completed,
+ * either successfully or with an error
+ */
+static bool
+handle_command(struct controlvm_message inmsg, u64 channel_addr)
+{
+ struct controlvm_message_packet *cmd = &inmsg.cmd;
+ u64 parm_addr;
+ u32 parm_bytes;
+ struct parser_context *parser_ctx = NULL;
+ bool local_addr;
+ struct controlvm_message ackmsg;
+
+ /* create parsing context if necessary */
+ local_addr = (inmsg.hdr.flags.test_message == 1);
+ if (channel_addr == 0)
+ return true;
+ parm_addr = channel_addr + inmsg.hdr.payload_vm_offset;
+ parm_bytes = inmsg.hdr.payload_bytes;
+
+ /*
+ * Parameter and channel addresses within test messages actually lie
+ * within our OS-controlled memory. We need to know that, because it
+ * makes a difference in how we compute the virtual address.
+ */
+ if (parm_addr && parm_bytes) {
+ bool retry = false;
+
+ parser_ctx =
+ parser_init_byte_stream(parm_addr, parm_bytes,
+ local_addr, &retry);
+ if (!parser_ctx && retry)
+ return false;
+ }
+
+ if (!local_addr) {
+ controlvm_init_response(&ackmsg, &inmsg.hdr,
+ CONTROLVM_RESP_SUCCESS);
+ if (controlvm_channel)
+ visorchannel_signalinsert(controlvm_channel,
+ CONTROLVM_QUEUE_ACK,
+ &ackmsg);
+ }
+ switch (inmsg.hdr.id) {
+ case CONTROLVM_CHIPSET_INIT:
+ chipset_init(&inmsg);
+ break;
+ case CONTROLVM_BUS_CREATE:
+ bus_create(&inmsg);
+ break;
+ case CONTROLVM_BUS_DESTROY:
+ bus_destroy(&inmsg);
+ break;
+ case CONTROLVM_BUS_CONFIGURE:
+ bus_configure(&inmsg, parser_ctx);
+ break;
+ case CONTROLVM_DEVICE_CREATE:
+ my_device_create(&inmsg);
+ break;
+ case CONTROLVM_DEVICE_CHANGESTATE:
+ if (cmd->device_change_state.flags.phys_device) {
+ parahotplug_process_message(&inmsg);
+ } else {
+ /*
+ * save the hdr and cmd structures for later use
+ * when sending back the response to Command
+ */
+ my_device_changestate(&inmsg);
+ break;
+ }
+ break;
+ case CONTROLVM_DEVICE_DESTROY:
+ my_device_destroy(&inmsg);
+ break;
+ case CONTROLVM_DEVICE_CONFIGURE:
+ /* no op for now, just send a respond that we passed */
+ if (inmsg.hdr.flags.response_expected)
+ controlvm_respond(&inmsg.hdr, CONTROLVM_RESP_SUCCESS);
+ break;
+ case CONTROLVM_CHIPSET_READY:
+ chipset_ready(&inmsg.hdr);
+ break;
+ case CONTROLVM_CHIPSET_SELFTEST:
+ chipset_selftest(&inmsg.hdr);
+ break;
+ case CONTROLVM_CHIPSET_STOP:
+ chipset_notready(&inmsg.hdr);
+ break;
+ default:
+ if (inmsg.hdr.flags.response_expected)
+ controlvm_respond
+ (&inmsg.hdr,
+ -CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN);
+ break;
+ }
+
+ if (parser_ctx) {
+ parser_done(parser_ctx);
+ parser_ctx = NULL;
+ }
+ return true;
+}
+
+/**
+ * read_controlvm_event() - retreives the next message from the
+ * CONTROLVM_QUEUE_EVENT queue in the controlvm
+ * channel
+ * @msg: pointer to the retrieved message
+ *
+ * Return: true if a valid message was retrieved or false otherwise
+ */
+static bool
+read_controlvm_event(struct controlvm_message *msg)
+{
+ if (!visorchannel_signalremove(controlvm_channel,
+ CONTROLVM_QUEUE_EVENT, msg)) {
+ /* got a message */
+ if (msg->hdr.flags.test_message == 1)
+ return false;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * parahotplug_process_list() - remove any request from the list that's been on
+ * there too long and respond with an error
+ */
+static void
+parahotplug_process_list(void)
+{
+ struct list_head *pos;
+ struct list_head *tmp;
+
+ spin_lock(&parahotplug_request_list_lock);
+
+ list_for_each_safe(pos, tmp, &parahotplug_request_list) {
+ struct parahotplug_request *req =
+ list_entry(pos, struct parahotplug_request, list);
+
+ if (!time_after_eq(jiffies, req->expiration))
+ continue;
+
+ list_del(pos);
+ if (req->msg.hdr.flags.response_expected)
+ controlvm_respond_physdev_changestate(
+ &req->msg.hdr,
+ CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT,
+ req->msg.cmd.device_change_state.state);
+ parahotplug_request_destroy(req);
+ }
+
+ spin_unlock(&parahotplug_request_list_lock);
+}
+
+static void
+controlvm_periodic_work(struct work_struct *work)
+{
+ struct controlvm_message inmsg;
+ bool got_command = false;
+ bool handle_command_failed = false;
+
+ while (!visorchannel_signalremove(controlvm_channel,
+ CONTROLVM_QUEUE_RESPONSE,
+ &inmsg))
+ ;
+ if (!got_command) {
+ if (controlvm_pending_msg_valid) {
+ /*
+ * we throttled processing of a prior
+ * msg, so try to process it again
+ * rather than reading a new one
+ */
+ inmsg = controlvm_pending_msg;
+ controlvm_pending_msg_valid = false;
+ got_command = true;
+ } else {
+ got_command = read_controlvm_event(&inmsg);
+ }
+ }
+
+ handle_command_failed = false;
+ while (got_command && (!handle_command_failed)) {
+ most_recent_message_jiffies = jiffies;
+ if (handle_command(inmsg,
+ visorchannel_get_physaddr
+ (controlvm_channel)))
+ got_command = read_controlvm_event(&inmsg);
+ else {
+ /*
+ * this is a scenario where throttling
+ * is required, but probably NOT an
+ * error...; we stash the current
+ * controlvm msg so we will attempt to
+ * reprocess it on our next loop
+ */
+ handle_command_failed = true;
+ controlvm_pending_msg = inmsg;
+ controlvm_pending_msg_valid = true;
+ }
+ }
+
+ /* parahotplug_worker */
+ parahotplug_process_list();
+
+ if (time_after(jiffies,
+ most_recent_message_jiffies + (HZ * MIN_IDLE_SECONDS))) {
+ /*
+ * it's been longer than MIN_IDLE_SECONDS since we
+ * processed our last controlvm message; slow down the
+ * polling
+ */
+ if (poll_jiffies != POLLJIFFIES_CONTROLVMCHANNEL_SLOW)
+ poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_SLOW;
+ } else {
+ if (poll_jiffies != POLLJIFFIES_CONTROLVMCHANNEL_FAST)
+ poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST;
+ }
+
+ schedule_delayed_work(&periodic_controlvm_work, poll_jiffies);
+}
+
static int
visorchipset_init(struct acpi_device *acpi_device)
{
@@ -2202,7 +2119,6 @@ visorchipset_init(struct acpi_device *acpi_device)
if (!addr)
goto error;
- memset(&busdev_notifiers, 0, sizeof(busdev_notifiers));
memset(&controlvm_payload_info, 0, sizeof(controlvm_payload_info));
controlvm_channel = visorchannel_create_with_lock(addr, 0,
@@ -2341,15 +2257,10 @@ static void exit_unisys(void)
module_param_named(major, visorchipset_major, int, S_IRUGO);
MODULE_PARM_DESC(visorchipset_major,
"major device number to use for the device node");
-module_param_named(visorbusregwait, visorchipset_visorbusregwait, int, S_IRUGO);
-MODULE_PARM_DESC(visorchipset_visorbusregwait,
- "1 to have the module wait for the visor bus to register");
module_init(init_unisys);
module_exit(exit_unisys);
MODULE_AUTHOR("Unisys");
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Supervisor chipset driver for service partition: ver "
- VERSION);
-MODULE_VERSION(VERSION);
+MODULE_DESCRIPTION("s-Par visorbus driver for virtual device buses");
diff --git a/drivers/staging/unisys/visorbus/vmcallinterface.h b/drivers/staging/unisys/visorbus/vmcallinterface.h
index c043fa41ceda..86e695d5a441 100644
--- a/drivers/staging/unisys/visorbus/vmcallinterface.h
+++ b/drivers/staging/unisys/visorbus/vmcallinterface.h
@@ -20,11 +20,39 @@
* Virtualization. The VMCALLs are provided by Monitor and used by IO code
* running on IO Partitions.
*/
+static inline unsigned long
+__unisys_vmcall_gnuc(unsigned long tuple, unsigned long reg_ebx,
+ unsigned long reg_ecx)
+{
+ unsigned long result = 0;
+ unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
-#ifdef __GNUC__
-#include "iovmcall_gnuc.h"
-#endif /* */
-#include "diagchannel.h"
+ cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx);
+ if (!(cpuid_ecx & 0x80000000))
+ return -EPERM;
+
+ __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
+ "a"(tuple), "b"(reg_ebx), "c"(reg_ecx));
+ return result;
+}
+
+static inline unsigned long
+__unisys_extended_vmcall_gnuc(unsigned long long tuple,
+ unsigned long long reg_ebx,
+ unsigned long long reg_ecx,
+ unsigned long long reg_edx)
+{
+ unsigned long result = 0;
+ unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
+
+ cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx);
+ if (!(cpuid_ecx & 0x80000000))
+ return -EPERM;
+
+ __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
+ "a"(tuple), "b"(reg_ebx), "c"(reg_ecx), "d"(reg_edx));
+ return result;
+}
#ifdef VMCALL_IO_CONTROLVM_ADDR
#undef VMCALL_IO_CONTROLVM_ADDR
@@ -57,7 +85,6 @@ enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */
#define VMCALL_SUCCESS 0
#define VMCALL_SUCCESSFUL(result) (result == 0)
-#ifdef __GNUC__
#define unisys_vmcall(tuple, reg_ebx, reg_ecx) \
__unisys_vmcall_gnuc(tuple, reg_ebx, reg_ecx)
#define unisys_extended_vmcall(tuple, reg_ebx, reg_ecx, reg_edx) \
@@ -74,7 +101,6 @@ enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */
#define ISSUE_IO_VMCALL_POSTCODE_SEVERITY(postcode, severity) \
ISSUE_IO_EXTENDED_VMCALL(VMCALL_POST_CODE_LOGEVENT, severity, \
MDS_APPOS, postcode)
-#endif
/* Structures for IO VMCALLs */
@@ -89,4 +115,156 @@ struct vmcall_io_controlvm_addr_params {
u8 unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */
} __packed;
+/******* INFO ON ISSUE_POSTCODE_LINUX() BELOW *******/
+enum driver_pc { /* POSTCODE driver identifier tuples */
+ /* visorchipset driver files */
+ VISOR_CHIPSET_PC = 0xA0,
+ VISOR_CHIPSET_PC_controlvm_c = 0xA1,
+ VISOR_CHIPSET_PC_controlvm_cm2 = 0xA2,
+ VISOR_CHIPSET_PC_controlvm_direct_c = 0xA3,
+ VISOR_CHIPSET_PC_file_c = 0xA4,
+ VISOR_CHIPSET_PC_parser_c = 0xA5,
+ VISOR_CHIPSET_PC_testing_c = 0xA6,
+ VISOR_CHIPSET_PC_visorchipset_main_c = 0xA7,
+ VISOR_CHIPSET_PC_visorswitchbus_c = 0xA8,
+ /* visorbus driver files */
+ VISOR_BUS_PC = 0xB0,
+ VISOR_BUS_PC_businst_attr_c = 0xB1,
+ VISOR_BUS_PC_channel_attr_c = 0xB2,
+ VISOR_BUS_PC_devmajorminor_attr_c = 0xB3,
+ VISOR_BUS_PC_visorbus_main_c = 0xB4,
+ /* visorclientbus driver files */
+ VISOR_CLIENT_BUS_PC = 0xC0,
+ VISOR_CLIENT_BUS_PC_visorclientbus_main_c = 0xC1,
+ /* virt hba driver files */
+ VIRT_HBA_PC = 0xC2,
+ VIRT_HBA_PC_virthba_c = 0xC3,
+ /* virtpci driver files */
+ VIRT_PCI_PC = 0xC4,
+ VIRT_PCI_PC_virtpci_c = 0xC5,
+ /* virtnic driver files */
+ VIRT_NIC_PC = 0xC6,
+ VIRT_NIC_P_virtnic_c = 0xC7,
+ /* uislib driver files */
+ UISLIB_PC = 0xD0,
+ UISLIB_PC_uislib_c = 0xD1,
+ UISLIB_PC_uisqueue_c = 0xD2,
+ /* 0xD3 RESERVED */
+ UISLIB_PC_uisutils_c = 0xD4,
+};
+
+enum event_pc { /* POSTCODE event identifier tuples */
+ ATTACH_PORT_ENTRY_PC = 0x001,
+ ATTACH_PORT_FAILURE_PC = 0x002,
+ ATTACH_PORT_SUCCESS_PC = 0x003,
+ BUS_FAILURE_PC = 0x004,
+ BUS_CREATE_ENTRY_PC = 0x005,
+ BUS_CREATE_FAILURE_PC = 0x006,
+ BUS_CREATE_EXIT_PC = 0x007,
+ BUS_CONFIGURE_ENTRY_PC = 0x008,
+ BUS_CONFIGURE_FAILURE_PC = 0x009,
+ BUS_CONFIGURE_EXIT_PC = 0x00A,
+ CHIPSET_INIT_ENTRY_PC = 0x00B,
+ CHIPSET_INIT_SUCCESS_PC = 0x00C,
+ CHIPSET_INIT_FAILURE_PC = 0x00D,
+ CHIPSET_INIT_EXIT_PC = 0x00E,
+ CREATE_WORKQUEUE_PC = 0x00F,
+ CREATE_WORKQUEUE_FAILED_PC = 0x0A0,
+ CONTROLVM_INIT_FAILURE_PC = 0x0A1,
+ DEVICE_CREATE_ENTRY_PC = 0x0A2,
+ DEVICE_CREATE_FAILURE_PC = 0x0A3,
+ DEVICE_CREATE_SUCCESS_PC = 0x0A4,
+ DEVICE_CREATE_EXIT_PC = 0x0A5,
+ DEVICE_ADD_PC = 0x0A6,
+ DEVICE_REGISTER_FAILURE_PC = 0x0A7,
+ DEVICE_CHANGESTATE_ENTRY_PC = 0x0A8,
+ DEVICE_CHANGESTATE_FAILURE_PC = 0x0A9,
+ DEVICE_CHANGESTATE_EXIT_PC = 0x0AA,
+ DRIVER_ENTRY_PC = 0x0AB,
+ DRIVER_EXIT_PC = 0x0AC,
+ MALLOC_FAILURE_PC = 0x0AD,
+ QUEUE_DELAYED_WORK_PC = 0x0AE,
+ /* 0x0B7 RESERVED */
+ VBUS_CHANNEL_ENTRY_PC = 0x0B8,
+ VBUS_CHANNEL_FAILURE_PC = 0x0B9,
+ VBUS_CHANNEL_EXIT_PC = 0x0BA,
+ VHBA_CREATE_ENTRY_PC = 0x0BB,
+ VHBA_CREATE_FAILURE_PC = 0x0BC,
+ VHBA_CREATE_EXIT_PC = 0x0BD,
+ VHBA_CREATE_SUCCESS_PC = 0x0BE,
+ VHBA_COMMAND_HANDLER_PC = 0x0BF,
+ VHBA_PROBE_ENTRY_PC = 0x0C0,
+ VHBA_PROBE_FAILURE_PC = 0x0C1,
+ VHBA_PROBE_EXIT_PC = 0x0C2,
+ VNIC_CREATE_ENTRY_PC = 0x0C3,
+ VNIC_CREATE_FAILURE_PC = 0x0C4,
+ VNIC_CREATE_SUCCESS_PC = 0x0C5,
+ VNIC_PROBE_ENTRY_PC = 0x0C6,
+ VNIC_PROBE_FAILURE_PC = 0x0C7,
+ VNIC_PROBE_EXIT_PC = 0x0C8,
+ VPCI_CREATE_ENTRY_PC = 0x0C9,
+ VPCI_CREATE_FAILURE_PC = 0x0CA,
+ VPCI_CREATE_EXIT_PC = 0x0CB,
+ VPCI_PROBE_ENTRY_PC = 0x0CC,
+ VPCI_PROBE_FAILURE_PC = 0x0CD,
+ VPCI_PROBE_EXIT_PC = 0x0CE,
+ CRASH_DEV_ENTRY_PC = 0x0CF,
+ CRASH_DEV_EXIT_PC = 0x0D0,
+ CRASH_DEV_HADDR_NULL = 0x0D1,
+ CRASH_DEV_CONTROLVM_NULL = 0x0D2,
+ CRASH_DEV_RD_BUS_FAIULRE_PC = 0x0D3,
+ CRASH_DEV_RD_DEV_FAIULRE_PC = 0x0D4,
+ CRASH_DEV_BUS_NULL_FAILURE_PC = 0x0D5,
+ CRASH_DEV_DEV_NULL_FAILURE_PC = 0x0D6,
+ CRASH_DEV_CTRL_RD_FAILURE_PC = 0x0D7,
+ CRASH_DEV_COUNT_FAILURE_PC = 0x0D8,
+ SAVE_MSG_BUS_FAILURE_PC = 0x0D9,
+ SAVE_MSG_DEV_FAILURE_PC = 0x0DA,
+ CALLHOME_INIT_FAILURE_PC = 0x0DB
+};
+
+#define POSTCODE_SEVERITY_ERR DIAG_SEVERITY_ERR
+#define POSTCODE_SEVERITY_WARNING DIAG_SEVERITY_WARNING
+/* TODO-> Info currently doesn't show, so we set info=warning */
+#define POSTCODE_SEVERITY_INFO DIAG_SEVERITY_PRINT
+
+/* example call of POSTCODE_LINUX_2(VISOR_CHIPSET_PC, POSTCODE_SEVERITY_ERR);
+ * Please also note that the resulting postcode is in hex, so if you are
+ * searching for the __LINE__ number, convert it first to decimal. The line
+ * number combined with driver and type of call, will allow you to track down
+ * exactly what line an error occurred on, or where the last driver
+ * entered/exited from.
+ */
+
+/* BASE FUNCTIONS */
+#define POSTCODE_LINUX_A(DRIVER_PC, EVENT_PC, pc32bit, severity) \
+do { \
+ unsigned long long post_code_temp; \
+ post_code_temp = (((u64)DRIVER_PC) << 56) | (((u64)EVENT_PC) << 44) | \
+ ((((u64)__LINE__) & 0xFFF) << 32) | \
+ (((u64)pc32bit) & 0xFFFFFFFF); \
+ ISSUE_IO_VMCALL_POSTCODE_SEVERITY(post_code_temp, severity); \
+} while (0)
+
+#define POSTCODE_LINUX_B(DRIVER_PC, EVENT_PC, pc16bit1, pc16bit2, severity) \
+do { \
+ unsigned long long post_code_temp; \
+ post_code_temp = (((u64)DRIVER_PC) << 56) | (((u64)EVENT_PC) << 44) | \
+ ((((u64)__LINE__) & 0xFFF) << 32) | \
+ ((((u64)pc16bit1) & 0xFFFF) << 16) | \
+ (((u64)pc16bit2) & 0xFFFF); \
+ ISSUE_IO_VMCALL_POSTCODE_SEVERITY(post_code_temp, severity); \
+} while (0)
+
+/* MOST COMMON */
+#define POSTCODE_LINUX_2(EVENT_PC, severity) \
+ POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, 0x0000, severity)
+
+#define POSTCODE_LINUX_3(EVENT_PC, pc32bit, severity) \
+ POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, pc32bit, severity)
+
+#define POSTCODE_LINUX_4(EVENT_PC, pc16bit1, pc16bit2, severity) \
+ POSTCODE_LINUX_B(CURRENT_FILE_PC, EVENT_PC, pc16bit1, \
+ pc16bit2, severity)
+
#endif /* __IOMONINTF_H__ */
diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c
index 120ba2097e02..5a7a87efed27 100644
--- a/drivers/staging/unisys/visorhba/visorhba_main.c
+++ b/drivers/staging/unisys/visorhba/visorhba_main.c
@@ -36,21 +36,6 @@
#define MAX_PENDING_REQUESTS (MIN_NUMSIGNALS * 2)
#define VISORHBA_ERROR_COUNT 30
-static int visorhba_queue_command_lck(struct scsi_cmnd *scsicmd,
- void (*visorhba_cmnd_done)
- (struct scsi_cmnd *));
-#ifdef DEF_SCSI_QCMD
-static DEF_SCSI_QCMD(visorhba_queue_command)
-#else
-#define visorhba_queue_command visorhba_queue_command_lck
-#endif
-static int visorhba_probe(struct visor_device *dev);
-static void visorhba_remove(struct visor_device *dev);
-static int visorhba_pause(struct visor_device *dev,
- visorbus_state_complete_func complete_func);
-static int visorhba_resume(struct visor_device *dev,
- visorbus_state_complete_func complete_func);
-
static struct dentry *visorhba_debugfs_dir;
/* GUIDS for HBA channel type supported by this driver */
@@ -62,20 +47,6 @@ static struct visor_channeltype_descriptor visorhba_channel_types[] = {
{ NULL_UUID_LE, NULL }
};
-/* This is used to tell the visor bus driver which types of visor devices
- * we support, and what functions to call when a visor device that we support
- * is attached or removed.
- */
-static struct visor_driver visorhba_driver = {
- .name = "visorhba",
- .owner = THIS_MODULE,
- .channel_types = visorhba_channel_types,
- .probe = visorhba_probe,
- .remove = visorhba_remove,
- .pause = visorhba_pause,
- .resume = visorhba_resume,
- .channel_interrupt = NULL,
-};
MODULE_DEVICE_TABLE(visorbus, visorhba_channel_types);
MODULE_ALIAS("visorbus:" SPAR_VHBA_CHANNEL_PROTOCOL_UUID_STR);
@@ -364,9 +335,9 @@ static int forward_taskmgmt_command(enum task_mgmt_types tasktype,
dev_dbg(&scsidev->sdev_gendev,
"visorhba: initiating type=%d taskmgmt command\n", tasktype);
- if (!visorchannel_signalinsert(devdata->dev->visorchannel,
- IOCHAN_TO_IOPART,
- cmdrsp))
+ if (visorchannel_signalinsert(devdata->dev->visorchannel,
+ IOCHAN_TO_IOPART,
+ cmdrsp))
goto err_del_scsipending_ent;
/* It can take the Service Partition up to 35 seconds to complete
@@ -567,9 +538,9 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd,
}
cmdrsp->scsi.guest_phys_entries = scsi_sg_count(scsicmd);
- if (!visorchannel_signalinsert(devdata->dev->visorchannel,
- IOCHAN_TO_IOPART,
- cmdrsp))
+ if (visorchannel_signalinsert(devdata->dev->visorchannel,
+ IOCHAN_TO_IOPART,
+ cmdrsp))
/* queue must be full and we aren't going to wait */
goto err_del_scsipending_ent;
@@ -580,6 +551,12 @@ err_del_scsipending_ent:
return SCSI_MLQUEUE_DEVICE_BUSY;
}
+#ifdef DEF_SCSI_QCMD
+static DEF_SCSI_QCMD(visorhba_queue_command)
+#else
+#define visorhba_queue_command visorhba_queue_command_lck
+#endif
+
/**
* visorhba_slave_alloc - called when new disk is discovered
* @scsidev: New disk
@@ -950,9 +927,9 @@ drain_queue(struct uiscmdrsp *cmdrsp, struct visorhba_devdata *devdata)
struct scsi_cmnd *scsicmd;
while (1) {
- if (!visorchannel_signalremove(devdata->dev->visorchannel,
- IOCHAN_FROM_IOPART,
- cmdrsp))
+ if (visorchannel_signalremove(devdata->dev->visorchannel,
+ IOCHAN_FROM_IOPART,
+ cmdrsp))
break; /* queue empty */
if (cmdrsp->cmdtype == CMD_SCSI_TYPE) {
@@ -1186,6 +1163,21 @@ static void visorhba_remove(struct visor_device *dev)
debugfs_remove_recursive(devdata->debugfs_dir);
}
+/* This is used to tell the visor bus driver which types of visor devices
+ * we support, and what functions to call when a visor device that we support
+ * is attached or removed.
+ */
+static struct visor_driver visorhba_driver = {
+ .name = "visorhba",
+ .owner = THIS_MODULE,
+ .channel_types = visorhba_channel_types,
+ .probe = visorhba_probe,
+ .remove = visorhba_remove,
+ .pause = visorhba_pause,
+ .resume = visorhba_resume,
+ .channel_interrupt = NULL,
+};
+
/**
* visorhba_init - driver init routine
*
@@ -1228,4 +1220,4 @@ module_exit(visorhba_exit);
MODULE_AUTHOR("Unisys");
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("s-Par hba driver");
+MODULE_DESCRIPTION("s-Par HBA driver for virtual SCSI host busses");
diff --git a/drivers/staging/unisys/visorinput/ultrainputreport.h b/drivers/staging/unisys/visorinput/ultrainputreport.h
index 1bc3d2064080..53dde7c53809 100644
--- a/drivers/staging/unisys/visorinput/ultrainputreport.h
+++ b/drivers/staging/unisys/visorinput/ultrainputreport.h
@@ -17,8 +17,6 @@
#include <linux/types.h>
-#include "ultrainputreport.h"
-
/* Identifies mouse and keyboard activity which is specified by the firmware to
* the host using the cmsimpleinput protocol. @ingroup coretypes
*/
diff --git a/drivers/staging/unisys/visorinput/visorinput.c b/drivers/staging/unisys/visorinput/visorinput.c
index d67cd76327c0..6f94b646f7c5 100644
--- a/drivers/staging/unisys/visorinput/visorinput.c
+++ b/drivers/staging/unisys/visorinput/visorinput.c
@@ -29,9 +29,7 @@
#include <linux/kernel.h>
#include <linux/uuid.h>
-#include "version.h"
#include "visorbus.h"
-#include "channel.h"
#include "ultrainputreport.h"
/* Keyboard channel {c73416d0-b0b8-44af-b304-9d2ae99f1b3d} */
@@ -63,9 +61,10 @@ enum visorinput_device_type {
*/
struct visorinput_devdata {
struct visor_device *dev;
- struct rw_semaphore lock_visor_dev; /* lock for dev */
+ struct mutex lock_visor_dev; /* lock for dev */
struct input_dev *visorinput_dev;
bool paused;
+ bool interrupts_enabled;
unsigned int keycode_table_bytes; /* size of following array */
/* for keyboard devices: visorkbd_keycode[] + visorkbd_ext_keycode[] */
unsigned char keycode_table[0];
@@ -228,7 +227,21 @@ static int visorinput_open(struct input_dev *visorinput_dev)
return -EINVAL;
}
dev_dbg(&visorinput_dev->dev, "%s opened\n", __func__);
+
+ /*
+ * If we're not paused, really enable interrupts.
+ * Regardless of whether we are paused, set a flag indicating
+ * interrupts should be enabled so when we resume, interrupts
+ * will really be enabled.
+ */
+ mutex_lock(&devdata->lock_visor_dev);
+ devdata->interrupts_enabled = true;
+ if (devdata->paused)
+ goto out_unlock;
visorbus_enable_channel_interrupts(devdata->dev);
+
+out_unlock:
+ mutex_unlock(&devdata->lock_visor_dev);
return 0;
}
@@ -243,20 +256,35 @@ static void visorinput_close(struct input_dev *visorinput_dev)
return;
}
dev_dbg(&visorinput_dev->dev, "%s closed\n", __func__);
+
+ /*
+ * If we're not paused, really disable interrupts.
+ * Regardless of whether we are paused, set a flag indicating
+ * interrupts should be disabled so when we resume we will
+ * not re-enable them.
+ */
+
+ mutex_lock(&devdata->lock_visor_dev);
+ devdata->interrupts_enabled = false;
+ if (devdata->paused)
+ goto out_unlock;
visorbus_disable_channel_interrupts(devdata->dev);
+
+out_unlock:
+ mutex_unlock(&devdata->lock_visor_dev);
}
/*
- * register_client_keyboard() initializes and returns a Linux input node that
+ * setup_client_keyboard() initializes and returns a Linux input node that
* we can use to deliver keyboard inputs to Linux. We of course do this when
* we see keyboard inputs coming in on a keyboard channel.
*/
static struct input_dev *
-register_client_keyboard(void *devdata, /* opaque on purpose */
- unsigned char *keycode_table)
+setup_client_keyboard(void *devdata, /* opaque on purpose */
+ unsigned char *keycode_table)
{
- int i, error;
+ int i;
struct input_dev *visorinput_dev;
visorinput_dev = input_allocate_device();
@@ -290,18 +318,12 @@ register_client_keyboard(void *devdata, /* opaque on purpose */
visorinput_dev->close = visorinput_close;
input_set_drvdata(visorinput_dev, devdata); /* pre input_register! */
- error = input_register_device(visorinput_dev);
- if (error) {
- input_free_device(visorinput_dev);
- return NULL;
- }
return visorinput_dev;
}
static struct input_dev *
-register_client_mouse(void *devdata /* opaque on purpose */)
+setup_client_mouse(void *devdata /* opaque on purpose */)
{
- int error;
struct input_dev *visorinput_dev = NULL;
int xres, yres;
struct fb_info *fb0;
@@ -336,13 +358,6 @@ register_client_mouse(void *devdata /* opaque on purpose */)
visorinput_dev->open = visorinput_open;
visorinput_dev->close = visorinput_close;
input_set_drvdata(visorinput_dev, devdata); /* pre input_register! */
-
- error = input_register_device(visorinput_dev);
- if (error) {
- input_free_device(visorinput_dev);
- return NULL;
- }
-
input_set_capability(visorinput_dev, EV_REL, REL_WHEEL);
return visorinput_dev;
@@ -360,9 +375,19 @@ devdata_create(struct visor_device *dev, enum visorinput_device_type devtype)
devdata = kzalloc(sizeof(*devdata) + extra_bytes, GFP_KERNEL);
if (!devdata)
return NULL;
+ mutex_init(&devdata->lock_visor_dev);
+ mutex_lock(&devdata->lock_visor_dev);
devdata->dev = dev;
/*
+ * visorinput_open() can be called as soon as input_register_device()
+ * happens, and that will enable channel interrupts. Setting paused
+ * prevents us from getting into visorinput_channel_interrupt() prior
+ * to the device structure being totally initialized.
+ */
+ devdata->paused = true;
+
+ /*
* This is an input device in a client guest partition,
* so we need to create whatever input nodes are necessary to
* deliver our inputs to the guest OS.
@@ -374,23 +399,49 @@ devdata_create(struct visor_device *dev, enum visorinput_device_type devtype)
KEYCODE_TABLE_BYTES);
memcpy(devdata->keycode_table + KEYCODE_TABLE_BYTES,
visorkbd_ext_keycode, KEYCODE_TABLE_BYTES);
- devdata->visorinput_dev = register_client_keyboard
+ devdata->visorinput_dev = setup_client_keyboard
(devdata, devdata->keycode_table);
if (!devdata->visorinput_dev)
goto cleanups_register;
break;
case visorinput_mouse:
- devdata->visorinput_dev = register_client_mouse(devdata);
+ devdata->visorinput_dev = setup_client_mouse(devdata);
if (!devdata->visorinput_dev)
goto cleanups_register;
break;
}
- init_rwsem(&devdata->lock_visor_dev);
+ dev_set_drvdata(&dev->device, devdata);
+ mutex_unlock(&devdata->lock_visor_dev);
+
+ /*
+ * Device struct is completely set up now, with the exception of
+ * visorinput_dev being registered.
+ * We need to unlock before we register the device, because this
+ * can cause an on-stack call of visorinput_open(), which would
+ * deadlock if we had the lock.
+ */
+ if (input_register_device(devdata->visorinput_dev)) {
+ input_free_device(devdata->visorinput_dev);
+ goto err_kfree_devdata;
+ }
+
+ mutex_lock(&devdata->lock_visor_dev);
+ /*
+ * Establish calls to visorinput_channel_interrupt() if that is
+ * the desired state that we've kept track of in interrupts_enabled
+ * while the device was being created.
+ */
+ devdata->paused = false;
+ if (devdata->interrupts_enabled)
+ visorbus_enable_channel_interrupts(dev);
+ mutex_unlock(&devdata->lock_visor_dev);
return devdata;
cleanups_register:
+ mutex_unlock(&devdata->lock_visor_dev);
+err_kfree_devdata:
kfree(devdata);
return NULL;
}
@@ -398,7 +449,6 @@ cleanups_register:
static int
visorinput_probe(struct visor_device *dev)
{
- struct visorinput_devdata *devdata = NULL;
uuid_le guid;
enum visorinput_device_type devtype;
@@ -409,10 +459,9 @@ visorinput_probe(struct visor_device *dev)
devtype = visorinput_keyboard;
else
return -ENODEV;
- devdata = devdata_create(dev, devtype);
- if (!devdata)
+ visorbus_disable_channel_interrupts(dev);
+ if (!devdata_create(dev, devtype))
return -ENOMEM;
- dev_set_drvdata(&dev->device, devdata);
return 0;
}
@@ -431,6 +480,7 @@ visorinput_remove(struct visor_device *dev)
if (!devdata)
return;
+ mutex_lock(&devdata->lock_visor_dev);
visorbus_disable_channel_interrupts(dev);
/*
@@ -438,10 +488,10 @@ visorinput_remove(struct visor_device *dev)
* in visorinput_channel_interrupt()
*/
- down_write(&devdata->lock_visor_dev);
dev_set_drvdata(&dev->device, NULL);
+ mutex_unlock(&devdata->lock_visor_dev);
+
unregister_client_input(devdata->visorinput_dev);
- up_write(&devdata->lock_visor_dev);
kfree(devdata);
}
@@ -529,15 +579,9 @@ visorinput_channel_interrupt(struct visor_device *dev)
if (!devdata)
return;
- down_write(&devdata->lock_visor_dev);
- if (devdata->paused) /* don't touch device/channel when paused */
- goto out_locked;
-
visorinput_dev = devdata->visorinput_dev;
- if (!visorinput_dev)
- goto out_locked;
- while (visorchannel_signalremove(dev->visorchannel, 0, &r)) {
+ while (!visorchannel_signalremove(dev->visorchannel, 0, &r)) {
scancode = r.activity.arg1;
keycode = scancode_to_keycode(scancode);
switch (r.activity.action) {
@@ -611,8 +655,6 @@ visorinput_channel_interrupt(struct visor_device *dev)
break;
}
}
-out_locked:
- up_write(&devdata->lock_visor_dev);
}
static int
@@ -627,16 +669,24 @@ visorinput_pause(struct visor_device *dev,
goto out;
}
- down_write(&devdata->lock_visor_dev);
+ mutex_lock(&devdata->lock_visor_dev);
if (devdata->paused) {
rc = -EBUSY;
goto out_locked;
}
+ if (devdata->interrupts_enabled)
+ visorbus_disable_channel_interrupts(dev);
+
+ /*
+ * due to above, at this time no thread of execution will be
+ * in visorinput_channel_interrupt()
+ */
+
devdata->paused = true;
complete_func(dev, 0);
rc = 0;
out_locked:
- up_write(&devdata->lock_visor_dev);
+ mutex_unlock(&devdata->lock_visor_dev);
out:
return rc;
}
@@ -652,16 +702,25 @@ visorinput_resume(struct visor_device *dev,
rc = -ENODEV;
goto out;
}
- down_write(&devdata->lock_visor_dev);
+ mutex_lock(&devdata->lock_visor_dev);
if (!devdata->paused) {
rc = -EBUSY;
goto out_locked;
}
devdata->paused = false;
complete_func(dev, 0);
+
+ /*
+ * Re-establish calls to visorinput_channel_interrupt() if that is
+ * the desired state that we've kept track of in interrupts_enabled
+ * while the device was paused.
+ */
+ if (devdata->interrupts_enabled)
+ visorbus_enable_channel_interrupts(dev);
+
rc = 0;
out_locked:
- up_write(&devdata->lock_visor_dev);
+ mutex_unlock(&devdata->lock_visor_dev);
out:
return rc;
}
@@ -675,7 +734,6 @@ static struct visor_channeltype_descriptor visorinput_channel_types[] = {
static struct visor_driver visorinput_driver = {
.name = "visorinput",
- .vertag = NULL,
.owner = THIS_MODULE,
.channel_types = visorinput_channel_types,
.probe = visorinput_probe,
@@ -704,8 +762,7 @@ MODULE_DEVICE_TABLE(visorbus, visorinput_channel_types);
MODULE_AUTHOR("Unisys");
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("s-Par human input driver for guest Linux");
-MODULE_VERSION(VERSION);
+MODULE_DESCRIPTION("s-Par human input driver for virtual keyboard/mouse");
MODULE_ALIAS("visorbus:" SPAR_MOUSE_CHANNEL_PROTOCOL_UUID_STR);
MODULE_ALIAS("visorbus:" SPAR_KEYBOARD_CHANNEL_PROTOCOL_UUID_STR);
diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c
index a28388d3ddc2..136700756485 100644
--- a/drivers/staging/unisys/visornic/visornic_main.c
+++ b/drivers/staging/unisys/visornic/visornic_main.c
@@ -29,8 +29,6 @@
#include "iochannel.h"
#define VISORNIC_INFINITE_RSP_WAIT 0
-#define VISORNICSOPENMAX 32
-#define MAXDEVICES 16384
/* MAX_BUF = 64 lines x 32 MAXVNIC x 80 characters
* = 163840 bytes
@@ -38,27 +36,6 @@
#define MAX_BUF 163840
#define NAPI_WEIGHT 64
-static int visornic_probe(struct visor_device *dev);
-static void visornic_remove(struct visor_device *dev);
-static int visornic_pause(struct visor_device *dev,
- visorbus_state_complete_func complete_func);
-static int visornic_resume(struct visor_device *dev,
- visorbus_state_complete_func complete_func);
-
-/* DEBUGFS declarations */
-static ssize_t info_debugfs_read(struct file *file, char __user *buf,
- size_t len, loff_t *offset);
-static ssize_t enable_ints_write(struct file *file, const char __user *buf,
- size_t len, loff_t *ppos);
-static struct dentry *visornic_debugfs_dir;
-static const struct file_operations debugfs_info_fops = {
- .read = info_debugfs_read,
-};
-
-static const struct file_operations debugfs_enable_ints_fops = {
- .write = enable_ints_write,
-};
-
/* GUIDS for director channel type supported by this driver. */
static struct visor_channeltype_descriptor visornic_channel_types[] = {
/* Note that the only channel type we expect to be reported by the
@@ -77,23 +54,6 @@ MODULE_DEVICE_TABLE(visorbus, visornic_channel_types);
*/
MODULE_ALIAS("visorbus:" SPAR_VNIC_CHANNEL_PROTOCOL_UUID_STR);
-/* This is used to tell the visor bus driver which types of visor devices
- * we support, and what functions to call when a visor device that we support
- * is attached or removed.
- */
-static struct visor_driver visornic_driver = {
- .name = "visornic",
- .version = "1.0.0.0",
- .vertag = NULL,
- .owner = THIS_MODULE,
- .channel_types = visornic_channel_types,
- .probe = visornic_probe,
- .remove = visornic_remove,
- .pause = visornic_pause,
- .resume = visornic_resume,
- .channel_interrupt = NULL,
-};
-
struct chanstat {
unsigned long got_rcv;
unsigned long got_enbdisack;
@@ -181,9 +141,6 @@ struct visornic_devdata {
struct uiscmdrsp cmdrsp[SIZEOF_CMDRSP];
};
-static int visornic_poll(struct napi_struct *napi, int budget);
-static void poll_for_irq(unsigned long v);
-
/**
* visor_copy_fragsinfo_from_skb(
* @skb_in: skbuff that we are pulling the frags from
@@ -289,6 +246,10 @@ static ssize_t enable_ints_write(struct file *file,
return count;
}
+static const struct file_operations debugfs_enable_ints_fops = {
+ .write = enable_ints_write,
+};
+
/**
* visornic_serverdown_complete - IOPART went down, pause device
* @work: Work queue it was scheduled on
@@ -425,9 +386,9 @@ post_skb(struct uiscmdrsp *cmdrsp,
if ((cmdrsp->net.rcvpost.frag.pi_off + skb->len) <= PI_PAGE_SIZE) {
cmdrsp->net.type = NET_RCV_POST;
cmdrsp->cmdtype = CMD_NET_TYPE;
- if (visorchannel_signalinsert(devdata->dev->visorchannel,
- IOCHAN_TO_IOPART,
- cmdrsp)) {
+ if (!visorchannel_signalinsert(devdata->dev->visorchannel,
+ IOCHAN_TO_IOPART,
+ cmdrsp)) {
atomic_inc(&devdata->num_rcvbuf_in_iovm);
devdata->chstat.sent_post++;
} else {
@@ -454,9 +415,9 @@ send_enbdis(struct net_device *netdev, int state,
devdata->cmdrsp_rcv->net.enbdis.context = netdev;
devdata->cmdrsp_rcv->net.type = NET_RCV_ENBDIS;
devdata->cmdrsp_rcv->cmdtype = CMD_NET_TYPE;
- if (visorchannel_signalinsert(devdata->dev->visorchannel,
- IOCHAN_TO_IOPART,
- devdata->cmdrsp_rcv))
+ if (!visorchannel_signalinsert(devdata->dev->visorchannel,
+ IOCHAN_TO_IOPART,
+ devdata->cmdrsp_rcv))
devdata->chstat.sent_enbdis++;
}
@@ -920,8 +881,8 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}
- if (!visorchannel_signalinsert(devdata->dev->visorchannel,
- IOCHAN_TO_IOPART, cmdrsp)) {
+ if (visorchannel_signalinsert(devdata->dev->visorchannel,
+ IOCHAN_TO_IOPART, cmdrsp)) {
netif_stop_queue(netdev);
spin_unlock_irqrestore(&devdata->priv_lock, flags);
devdata->busy_cnt++;
@@ -1522,6 +1483,11 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf,
return bytes_read;
}
+static struct dentry *visornic_debugfs_dir;
+static const struct file_operations debugfs_info_fops = {
+ .read = info_debugfs_read,
+};
+
/**
* send_rcv_posts_if_needed
* @devdata: visornic device
@@ -1573,9 +1539,9 @@ send_rcv_posts_if_needed(struct visornic_devdata *devdata)
static void
drain_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata)
{
- while (visorchannel_signalremove(devdata->dev->visorchannel,
- IOCHAN_FROM_IOPART,
- cmdrsp))
+ while (!visorchannel_signalremove(devdata->dev->visorchannel,
+ IOCHAN_FROM_IOPART,
+ cmdrsp))
;
}
@@ -1586,7 +1552,7 @@ drain_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata)
*
* Drain the respones queue of any responses from the IO partition.
* Process the responses as we get them.
- * Returns when response queue is empty or when the threadd stops.
+ * Returns when response queue is empty or when the thread stops.
*/
static void
service_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata,
@@ -1599,9 +1565,9 @@ service_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata,
/* TODO: CLIENT ACQUIRE -- Don't really need this at the
* moment
*/
- if (!visorchannel_signalremove(devdata->dev->visorchannel,
- IOCHAN_FROM_IOPART,
- cmdrsp))
+ if (visorchannel_signalremove(devdata->dev->visorchannel,
+ IOCHAN_FROM_IOPART,
+ cmdrsp))
break; /* queue empty */
switch (cmdrsp->net.type) {
@@ -2061,6 +2027,21 @@ static int visornic_resume(struct visor_device *dev,
return 0;
}
+/* This is used to tell the visor bus driver which types of visor devices
+ * we support, and what functions to call when a visor device that we support
+ * is attached or removed.
+ */
+static struct visor_driver visornic_driver = {
+ .name = "visornic",
+ .owner = THIS_MODULE,
+ .channel_types = visornic_channel_types,
+ .probe = visornic_probe,
+ .remove = visornic_remove,
+ .pause = visornic_pause,
+ .resume = visornic_resume,
+ .channel_interrupt = NULL,
+};
+
/**
* visornic_init - Init function
*
@@ -2115,5 +2096,4 @@ module_exit(visornic_cleanup);
MODULE_AUTHOR("Unisys");
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("sPAR nic driver for sparlinux: ver 1.0.0.0");
-MODULE_VERSION("1.0.0.0");
+MODULE_DESCRIPTION("s-Par NIC driver for virtual network devices");
diff --git a/drivers/staging/vc04_services/Kconfig b/drivers/staging/vc04_services/Kconfig
new file mode 100644
index 000000000000..9676fb29075a
--- /dev/null
+++ b/drivers/staging/vc04_services/Kconfig
@@ -0,0 +1,9 @@
+config BCM2708_VCHIQ
+ tristate "Videocore VCHIQ"
+ depends on RASPBERRYPI_FIRMWARE && BROKEN
+ default y
+ help
+ Kernel to VideoCore communication interface for the
+ BCM2708 family of products.
+ Defaults to Y when the Broadcom Videocore services
+ are included in the build, N otherwise.
diff --git a/drivers/staging/vc04_services/Makefile b/drivers/staging/vc04_services/Makefile
new file mode 100644
index 000000000000..90ab4781df2c
--- /dev/null
+++ b/drivers/staging/vc04_services/Makefile
@@ -0,0 +1,14 @@
+obj-$(CONFIG_BCM2708_VCHIQ) += vchiq.o
+
+vchiq-objs := \
+ interface/vchiq_arm/vchiq_core.o \
+ interface/vchiq_arm/vchiq_arm.o \
+ interface/vchiq_arm/vchiq_kern_lib.o \
+ interface/vchiq_arm/vchiq_2835_arm.o \
+ interface/vchiq_arm/vchiq_debugfs.o \
+ interface/vchiq_arm/vchiq_shim.o \
+ interface/vchiq_arm/vchiq_util.o \
+ interface/vchiq_arm/vchiq_connected.o \
+
+ccflags-y += -DVCOS_VERIFY_BKPTS=1 -Idrivers/staging/vc04_services -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000
+
diff --git a/drivers/staging/vc04_services/interface/vchi/connections/connection.h b/drivers/staging/vc04_services/interface/vchi/connections/connection.h
new file mode 100644
index 000000000000..fef6ac34c6d2
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchi/connections/connection.h
@@ -0,0 +1,328 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CONNECTION_H_
+#define CONNECTION_H_
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/semaphore.h>
+
+#include "interface/vchi/vchi_cfg_internal.h"
+#include "interface/vchi/vchi_common.h"
+#include "interface/vchi/message_drivers/message.h"
+
+/******************************************************************************
+ Global defs
+ *****************************************************************************/
+
+// Opaque handle for a connection / service pair
+typedef struct opaque_vchi_connection_connected_service_handle_t *VCHI_CONNECTION_SERVICE_HANDLE_T;
+
+// opaque handle to the connection state information
+typedef struct opaque_vchi_connection_info_t VCHI_CONNECTION_STATE_T;
+
+typedef struct vchi_connection_t VCHI_CONNECTION_T;
+
+
+/******************************************************************************
+ API
+ *****************************************************************************/
+
+// Routine to init a connection with a particular low level driver
+typedef VCHI_CONNECTION_STATE_T * (*VCHI_CONNECTION_INIT_T)( struct vchi_connection_t * connection,
+ const VCHI_MESSAGE_DRIVER_T * driver );
+
+// Routine to control CRC enabling at a connection level
+typedef int32_t (*VCHI_CONNECTION_CRC_CONTROL_T)( VCHI_CONNECTION_STATE_T *state_handle,
+ VCHI_CRC_CONTROL_T control );
+
+// Routine to create a service
+typedef int32_t (*VCHI_CONNECTION_SERVICE_CONNECT_T)( VCHI_CONNECTION_STATE_T *state_handle,
+ int32_t service_id,
+ uint32_t rx_fifo_size,
+ uint32_t tx_fifo_size,
+ int server,
+ VCHI_CALLBACK_T callback,
+ void *callback_param,
+ int32_t want_crc,
+ int32_t want_unaligned_bulk_rx,
+ int32_t want_unaligned_bulk_tx,
+ VCHI_CONNECTION_SERVICE_HANDLE_T *service_handle );
+
+// Routine to close a service
+typedef int32_t (*VCHI_CONNECTION_SERVICE_DISCONNECT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle );
+
+// Routine to queue a message
+typedef int32_t (*VCHI_CONNECTION_SERVICE_QUEUE_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
+ const void *data,
+ uint32_t data_size,
+ VCHI_FLAGS_T flags,
+ void *msg_handle );
+
+// scatter-gather (vector) message queueing
+typedef int32_t (*VCHI_CONNECTION_SERVICE_QUEUE_MESSAGEV_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
+ VCHI_MSG_VECTOR_T *vector,
+ uint32_t count,
+ VCHI_FLAGS_T flags,
+ void *msg_handle );
+
+// Routine to dequeue a message
+typedef int32_t (*VCHI_CONNECTION_SERVICE_DEQUEUE_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
+ void *data,
+ uint32_t max_data_size_to_read,
+ uint32_t *actual_msg_size,
+ VCHI_FLAGS_T flags );
+
+// Routine to peek at a message
+typedef int32_t (*VCHI_CONNECTION_SERVICE_PEEK_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
+ void **data,
+ uint32_t *msg_size,
+ VCHI_FLAGS_T flags );
+
+// Routine to hold a message
+typedef int32_t (*VCHI_CONNECTION_SERVICE_HOLD_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
+ void **data,
+ uint32_t *msg_size,
+ VCHI_FLAGS_T flags,
+ void **message_handle );
+
+// Routine to initialise a received message iterator
+typedef int32_t (*VCHI_CONNECTION_SERVICE_LOOKAHEAD_MESSAGE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
+ VCHI_MSG_ITER_T *iter,
+ VCHI_FLAGS_T flags );
+
+// Routine to release a held message
+typedef int32_t (*VCHI_CONNECTION_HELD_MSG_RELEASE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
+ void *message_handle );
+
+// Routine to get info on a held message
+typedef int32_t (*VCHI_CONNECTION_HELD_MSG_INFO_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
+ void *message_handle,
+ void **data,
+ int32_t *msg_size,
+ uint32_t *tx_timestamp,
+ uint32_t *rx_timestamp );
+
+// Routine to check whether the iterator has a next message
+typedef int32_t (*VCHI_CONNECTION_MSG_ITER_HAS_NEXT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service,
+ const VCHI_MSG_ITER_T *iter );
+
+// Routine to advance the iterator
+typedef int32_t (*VCHI_CONNECTION_MSG_ITER_NEXT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service,
+ VCHI_MSG_ITER_T *iter,
+ void **data,
+ uint32_t *msg_size );
+
+// Routine to remove the last message returned by the iterator
+typedef int32_t (*VCHI_CONNECTION_MSG_ITER_REMOVE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service,
+ VCHI_MSG_ITER_T *iter );
+
+// Routine to hold the last message returned by the iterator
+typedef int32_t (*VCHI_CONNECTION_MSG_ITER_HOLD_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service,
+ VCHI_MSG_ITER_T *iter,
+ void **msg_handle );
+
+// Routine to transmit bulk data
+typedef int32_t (*VCHI_CONNECTION_BULK_QUEUE_TRANSMIT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
+ const void *data_src,
+ uint32_t data_size,
+ VCHI_FLAGS_T flags,
+ void *bulk_handle );
+
+// Routine to receive data
+typedef int32_t (*VCHI_CONNECTION_BULK_QUEUE_RECEIVE_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service_handle,
+ void *data_dst,
+ uint32_t data_size,
+ VCHI_FLAGS_T flags,
+ void *bulk_handle );
+
+// Routine to report if a server is available
+typedef int32_t (*VCHI_CONNECTION_SERVER_PRESENT)( VCHI_CONNECTION_STATE_T *state, int32_t service_id, int32_t peer_flags );
+
+// Routine to report the number of RX slots available
+typedef int (*VCHI_CONNECTION_RX_SLOTS_AVAILABLE)( const VCHI_CONNECTION_STATE_T *state );
+
+// Routine to report the RX slot size
+typedef uint32_t (*VCHI_CONNECTION_RX_SLOT_SIZE)( const VCHI_CONNECTION_STATE_T *state );
+
+// Callback to indicate that the other side has added a buffer to the rx bulk DMA FIFO
+typedef void (*VCHI_CONNECTION_RX_BULK_BUFFER_ADDED)(VCHI_CONNECTION_STATE_T *state,
+ int32_t service,
+ uint32_t length,
+ MESSAGE_TX_CHANNEL_T channel,
+ uint32_t channel_params,
+ uint32_t data_length,
+ uint32_t data_offset);
+
+// Callback to inform a service that a Xon or Xoff message has been received
+typedef void (*VCHI_CONNECTION_FLOW_CONTROL)(VCHI_CONNECTION_STATE_T *state, int32_t service_id, int32_t xoff);
+
+// Callback to inform a service that a server available reply message has been received
+typedef void (*VCHI_CONNECTION_SERVER_AVAILABLE_REPLY)(VCHI_CONNECTION_STATE_T *state, int32_t service_id, uint32_t flags);
+
+// Callback to indicate that bulk auxiliary messages have arrived
+typedef void (*VCHI_CONNECTION_BULK_AUX_RECEIVED)(VCHI_CONNECTION_STATE_T *state);
+
+// Callback to indicate that bulk auxiliary messages have arrived
+typedef void (*VCHI_CONNECTION_BULK_AUX_TRANSMITTED)(VCHI_CONNECTION_STATE_T *state, void *handle);
+
+// Callback with all the connection info you require
+typedef void (*VCHI_CONNECTION_INFO)(VCHI_CONNECTION_STATE_T *state, uint32_t protocol_version, uint32_t slot_size, uint32_t num_slots, uint32_t min_bulk_size);
+
+// Callback to inform of a disconnect
+typedef void (*VCHI_CONNECTION_DISCONNECT)(VCHI_CONNECTION_STATE_T *state, uint32_t flags);
+
+// Callback to inform of a power control request
+typedef void (*VCHI_CONNECTION_POWER_CONTROL)(VCHI_CONNECTION_STATE_T *state, MESSAGE_TX_CHANNEL_T channel, int32_t enable);
+
+// allocate memory suitably aligned for this connection
+typedef void * (*VCHI_BUFFER_ALLOCATE)(VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, uint32_t * length);
+
+// free memory allocated by buffer_allocate
+typedef void (*VCHI_BUFFER_FREE)(VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, void * address);
+
+
+/******************************************************************************
+ System driver struct
+ *****************************************************************************/
+
+struct opaque_vchi_connection_api_t
+{
+ // Routine to init the connection
+ VCHI_CONNECTION_INIT_T init;
+
+ // Connection-level CRC control
+ VCHI_CONNECTION_CRC_CONTROL_T crc_control;
+
+ // Routine to connect to or create service
+ VCHI_CONNECTION_SERVICE_CONNECT_T service_connect;
+
+ // Routine to disconnect from a service
+ VCHI_CONNECTION_SERVICE_DISCONNECT_T service_disconnect;
+
+ // Routine to queue a message
+ VCHI_CONNECTION_SERVICE_QUEUE_MESSAGE_T service_queue_msg;
+
+ // scatter-gather (vector) message queue
+ VCHI_CONNECTION_SERVICE_QUEUE_MESSAGEV_T service_queue_msgv;
+
+ // Routine to dequeue a message
+ VCHI_CONNECTION_SERVICE_DEQUEUE_MESSAGE_T service_dequeue_msg;
+
+ // Routine to peek at a message
+ VCHI_CONNECTION_SERVICE_PEEK_MESSAGE_T service_peek_msg;
+
+ // Routine to hold a message
+ VCHI_CONNECTION_SERVICE_HOLD_MESSAGE_T service_hold_msg;
+
+ // Routine to initialise a received message iterator
+ VCHI_CONNECTION_SERVICE_LOOKAHEAD_MESSAGE_T service_look_ahead_msg;
+
+ // Routine to release a message
+ VCHI_CONNECTION_HELD_MSG_RELEASE_T held_msg_release;
+
+ // Routine to get information on a held message
+ VCHI_CONNECTION_HELD_MSG_INFO_T held_msg_info;
+
+ // Routine to check for next message on iterator
+ VCHI_CONNECTION_MSG_ITER_HAS_NEXT_T msg_iter_has_next;
+
+ // Routine to get next message on iterator
+ VCHI_CONNECTION_MSG_ITER_NEXT_T msg_iter_next;
+
+ // Routine to remove the last message returned by iterator
+ VCHI_CONNECTION_MSG_ITER_REMOVE_T msg_iter_remove;
+
+ // Routine to hold the last message returned by iterator
+ VCHI_CONNECTION_MSG_ITER_HOLD_T msg_iter_hold;
+
+ // Routine to transmit bulk data
+ VCHI_CONNECTION_BULK_QUEUE_TRANSMIT_T bulk_queue_transmit;
+
+ // Routine to receive data
+ VCHI_CONNECTION_BULK_QUEUE_RECEIVE_T bulk_queue_receive;
+
+ // Routine to report the available servers
+ VCHI_CONNECTION_SERVER_PRESENT server_present;
+
+ // Routine to report the number of RX slots available
+ VCHI_CONNECTION_RX_SLOTS_AVAILABLE connection_rx_slots_available;
+
+ // Routine to report the RX slot size
+ VCHI_CONNECTION_RX_SLOT_SIZE connection_rx_slot_size;
+
+ // Callback to indicate that the other side has added a buffer to the rx bulk DMA FIFO
+ VCHI_CONNECTION_RX_BULK_BUFFER_ADDED rx_bulk_buffer_added;
+
+ // Callback to inform a service that a Xon or Xoff message has been received
+ VCHI_CONNECTION_FLOW_CONTROL flow_control;
+
+ // Callback to inform a service that a server available reply message has been received
+ VCHI_CONNECTION_SERVER_AVAILABLE_REPLY server_available_reply;
+
+ // Callback to indicate that bulk auxiliary messages have arrived
+ VCHI_CONNECTION_BULK_AUX_RECEIVED bulk_aux_received;
+
+ // Callback to indicate that a bulk auxiliary message has been transmitted
+ VCHI_CONNECTION_BULK_AUX_TRANSMITTED bulk_aux_transmitted;
+
+ // Callback to provide information about the connection
+ VCHI_CONNECTION_INFO connection_info;
+
+ // Callback to notify that peer has requested disconnect
+ VCHI_CONNECTION_DISCONNECT disconnect;
+
+ // Callback to notify that peer has requested power change
+ VCHI_CONNECTION_POWER_CONTROL power_control;
+
+ // allocate memory suitably aligned for this connection
+ VCHI_BUFFER_ALLOCATE buffer_allocate;
+
+ // free memory allocated by buffer_allocate
+ VCHI_BUFFER_FREE buffer_free;
+
+};
+
+struct vchi_connection_t {
+ const VCHI_CONNECTION_API_T *api;
+ VCHI_CONNECTION_STATE_T *state;
+#ifdef VCHI_COARSE_LOCKING
+ struct semaphore sem;
+#endif
+};
+
+
+#endif /* CONNECTION_H_ */
+
+/****************************** End of file **********************************/
diff --git a/drivers/staging/vc04_services/interface/vchi/message_drivers/message.h b/drivers/staging/vc04_services/interface/vchi/message_drivers/message.h
new file mode 100644
index 000000000000..8b3f76735bd4
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchi/message_drivers/message.h
@@ -0,0 +1,204 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VCHI_MESSAGE_H_
+#define _VCHI_MESSAGE_H_
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/semaphore.h>
+
+#include "interface/vchi/vchi_cfg_internal.h"
+#include "interface/vchi/vchi_common.h"
+
+
+typedef enum message_event_type {
+ MESSAGE_EVENT_NONE,
+ MESSAGE_EVENT_NOP,
+ MESSAGE_EVENT_MESSAGE,
+ MESSAGE_EVENT_SLOT_COMPLETE,
+ MESSAGE_EVENT_RX_BULK_PAUSED,
+ MESSAGE_EVENT_RX_BULK_COMPLETE,
+ MESSAGE_EVENT_TX_COMPLETE,
+ MESSAGE_EVENT_MSG_DISCARDED
+} MESSAGE_EVENT_TYPE_T;
+
+typedef enum vchi_msg_flags
+{
+ VCHI_MSG_FLAGS_NONE = 0x0,
+ VCHI_MSG_FLAGS_TERMINATE_DMA = 0x1
+} VCHI_MSG_FLAGS_T;
+
+typedef enum message_tx_channel
+{
+ MESSAGE_TX_CHANNEL_MESSAGE = 0,
+ MESSAGE_TX_CHANNEL_BULK = 1 // drivers may provide multiple bulk channels, from 1 upwards
+} MESSAGE_TX_CHANNEL_T;
+
+// Macros used for cycling through bulk channels
+#define MESSAGE_TX_CHANNEL_BULK_PREV(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION-1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION)
+#define MESSAGE_TX_CHANNEL_BULK_NEXT(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION)
+
+typedef enum message_rx_channel
+{
+ MESSAGE_RX_CHANNEL_MESSAGE = 0,
+ MESSAGE_RX_CHANNEL_BULK = 1 // drivers may provide multiple bulk channels, from 1 upwards
+} MESSAGE_RX_CHANNEL_T;
+
+// Message receive slot information
+typedef struct rx_msg_slot_info {
+
+ struct rx_msg_slot_info *next;
+ //struct slot_info *prev;
+#if !defined VCHI_COARSE_LOCKING
+ struct semaphore sem;
+#endif
+
+ uint8_t *addr; // base address of slot
+ uint32_t len; // length of slot in bytes
+
+ uint32_t write_ptr; // hardware causes this to advance
+ uint32_t read_ptr; // this module does the reading
+ int active; // is this slot in the hardware dma fifo?
+ uint32_t msgs_parsed; // count how many messages are in this slot
+ uint32_t msgs_released; // how many messages have been released
+ void *state; // connection state information
+ uint8_t ref_count[VCHI_MAX_SERVICES_PER_CONNECTION]; // reference count for slots held by services
+} RX_MSG_SLOTINFO_T;
+
+// The message driver no longer needs to know about the fields of RX_BULK_SLOTINFO_T - sort this out.
+// In particular, it mustn't use addr and len - they're the client buffer, but the message
+// driver will be tasked with sending the aligned core section.
+typedef struct rx_bulk_slotinfo_t {
+ struct rx_bulk_slotinfo_t *next;
+
+ struct semaphore *blocking;
+
+ // needed by DMA
+ void *addr;
+ uint32_t len;
+
+ // needed for the callback
+ void *service;
+ void *handle;
+ VCHI_FLAGS_T flags;
+} RX_BULK_SLOTINFO_T;
+
+
+/* ----------------------------------------------------------------------
+ * each connection driver will have a pool of the following struct.
+ *
+ * the pool will be managed by vchi_qman_*
+ * this means there will be multiple queues (single linked lists)
+ * a given struct message_info will be on exactly one of these queues
+ * at any one time
+ * -------------------------------------------------------------------- */
+typedef struct rx_message_info {
+
+ struct message_info *next;
+ //struct message_info *prev;
+
+ uint8_t *addr;
+ uint32_t len;
+ RX_MSG_SLOTINFO_T *slot; // points to whichever slot contains this message
+ uint32_t tx_timestamp;
+ uint32_t rx_timestamp;
+
+} RX_MESSAGE_INFO_T;
+
+typedef struct {
+ MESSAGE_EVENT_TYPE_T type;
+
+ struct {
+ // for messages
+ void *addr; // address of message
+ uint16_t slot_delta; // whether this message indicated slot delta
+ uint32_t len; // length of message
+ RX_MSG_SLOTINFO_T *slot; // slot this message is in
+ int32_t service; // service id this message is destined for
+ uint32_t tx_timestamp; // timestamp from the header
+ uint32_t rx_timestamp; // timestamp when we parsed it
+ } message;
+
+ // FIXME: cleanup slot reporting...
+ RX_MSG_SLOTINFO_T *rx_msg;
+ RX_BULK_SLOTINFO_T *rx_bulk;
+ void *tx_handle;
+ MESSAGE_TX_CHANNEL_T tx_channel;
+
+} MESSAGE_EVENT_T;
+
+
+// callbacks
+typedef void VCHI_MESSAGE_DRIVER_EVENT_CALLBACK_T( void *state );
+
+typedef struct {
+ VCHI_MESSAGE_DRIVER_EVENT_CALLBACK_T *event_callback;
+} VCHI_MESSAGE_DRIVER_OPEN_T;
+
+
+// handle to this instance of message driver (as returned by ->open)
+typedef struct opaque_mhandle_t *VCHI_MDRIVER_HANDLE_T;
+
+struct opaque_vchi_message_driver_t {
+ VCHI_MDRIVER_HANDLE_T *(*open)( VCHI_MESSAGE_DRIVER_OPEN_T *params, void *state );
+ int32_t (*suspending)( VCHI_MDRIVER_HANDLE_T *handle );
+ int32_t (*resumed)( VCHI_MDRIVER_HANDLE_T *handle );
+ int32_t (*power_control)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T, int32_t enable );
+ int32_t (*add_msg_rx_slot)( VCHI_MDRIVER_HANDLE_T *handle, RX_MSG_SLOTINFO_T *slot ); // rx message
+ int32_t (*add_bulk_rx)( VCHI_MDRIVER_HANDLE_T *handle, void *data, uint32_t len, RX_BULK_SLOTINFO_T *slot ); // rx data (bulk)
+ int32_t (*send)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel, const void *data, uint32_t len, VCHI_MSG_FLAGS_T flags, void *send_handle ); // tx (message & bulk)
+ void (*next_event)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_EVENT_T *event ); // get the next event from message_driver
+ int32_t (*enable)( VCHI_MDRIVER_HANDLE_T *handle );
+ int32_t (*form_message)( VCHI_MDRIVER_HANDLE_T *handle, int32_t service_id, VCHI_MSG_VECTOR_T *vector, uint32_t count, void
+ *address, uint32_t length_avail, uint32_t max_total_length, int32_t pad_to_fill, int32_t allow_partial );
+
+ int32_t (*update_message)( VCHI_MDRIVER_HANDLE_T *handle, void *dest, int16_t *slot_count );
+ int32_t (*buffer_aligned)( VCHI_MDRIVER_HANDLE_T *handle, int tx, int uncached, const void *address, const uint32_t length );
+ void * (*allocate_buffer)( VCHI_MDRIVER_HANDLE_T *handle, uint32_t *length );
+ void (*free_buffer)( VCHI_MDRIVER_HANDLE_T *handle, void *address );
+ int (*rx_slot_size)( VCHI_MDRIVER_HANDLE_T *handle, int msg_size );
+ int (*tx_slot_size)( VCHI_MDRIVER_HANDLE_T *handle, int msg_size );
+
+ int32_t (*tx_supports_terminate)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel );
+ uint32_t (*tx_bulk_chunk_size)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel );
+ int (*tx_alignment)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel );
+ int (*rx_alignment)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_RX_CHANNEL_T channel );
+ void (*form_bulk_aux)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel, const void *data, uint32_t len, uint32_t chunk_size, const void **aux_data, int32_t *aux_len );
+ void (*debug)( VCHI_MDRIVER_HANDLE_T *handle );
+};
+
+
+#endif // _VCHI_MESSAGE_H_
+
+/****************************** End of file ***********************************/
diff --git a/drivers/staging/vc04_services/interface/vchi/vchi.h b/drivers/staging/vc04_services/interface/vchi/vchi.h
new file mode 100644
index 000000000000..1b17e98f7379
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchi/vchi.h
@@ -0,0 +1,378 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHI_H_
+#define VCHI_H_
+
+#include "interface/vchi/vchi_cfg.h"
+#include "interface/vchi/vchi_common.h"
+#include "interface/vchi/connections/connection.h"
+#include "vchi_mh.h"
+
+
+/******************************************************************************
+ Global defs
+ *****************************************************************************/
+
+#define VCHI_BULK_ROUND_UP(x) ((((unsigned long)(x))+VCHI_BULK_ALIGN-1) & ~(VCHI_BULK_ALIGN-1))
+#define VCHI_BULK_ROUND_DOWN(x) (((unsigned long)(x)) & ~(VCHI_BULK_ALIGN-1))
+#define VCHI_BULK_ALIGN_NBYTES(x) (VCHI_BULK_ALIGNED(x) ? 0 : (VCHI_BULK_ALIGN - ((unsigned long)(x) & (VCHI_BULK_ALIGN-1))))
+
+#ifdef USE_VCHIQ_ARM
+#define VCHI_BULK_ALIGNED(x) 1
+#else
+#define VCHI_BULK_ALIGNED(x) (((unsigned long)(x) & (VCHI_BULK_ALIGN-1)) == 0)
+#endif
+
+struct vchi_version {
+ uint32_t version;
+ uint32_t version_min;
+};
+#define VCHI_VERSION(v_) { v_, v_ }
+#define VCHI_VERSION_EX(v_, m_) { v_, m_ }
+
+typedef enum
+{
+ VCHI_VEC_POINTER,
+ VCHI_VEC_HANDLE,
+ VCHI_VEC_LIST
+} VCHI_MSG_VECTOR_TYPE_T;
+
+typedef struct vchi_msg_vector_ex {
+
+ VCHI_MSG_VECTOR_TYPE_T type;
+ union
+ {
+ // a memory handle
+ struct
+ {
+ VCHI_MEM_HANDLE_T handle;
+ uint32_t offset;
+ int32_t vec_len;
+ } handle;
+
+ // an ordinary data pointer
+ struct
+ {
+ const void *vec_base;
+ int32_t vec_len;
+ } ptr;
+
+ // a nested vector list
+ struct
+ {
+ struct vchi_msg_vector_ex *vec;
+ uint32_t vec_len;
+ } list;
+ } u;
+} VCHI_MSG_VECTOR_EX_T;
+
+
+// Construct an entry in a msg vector for a pointer (p) of length (l)
+#define VCHI_VEC_POINTER(p,l) VCHI_VEC_POINTER, { { (VCHI_MEM_HANDLE_T)(p), (l) } }
+
+// Construct an entry in a msg vector for a message handle (h), starting at offset (o) of length (l)
+#define VCHI_VEC_HANDLE(h,o,l) VCHI_VEC_HANDLE, { { (h), (o), (l) } }
+
+// Macros to manipulate 'FOURCC' values
+#define MAKE_FOURCC(x) ((int32_t)( (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3] ))
+#define FOURCC_TO_CHAR(x) (x >> 24) & 0xFF,(x >> 16) & 0xFF,(x >> 8) & 0xFF, x & 0xFF
+
+
+// Opaque service information
+struct opaque_vchi_service_t;
+
+// Descriptor for a held message. Allocated by client, initialised by vchi_msg_hold,
+// vchi_msg_iter_hold or vchi_msg_iter_hold_next. Fields are for internal VCHI use only.
+typedef struct
+{
+ struct opaque_vchi_service_t *service;
+ void *message;
+} VCHI_HELD_MSG_T;
+
+
+
+// structure used to provide the information needed to open a server or a client
+typedef struct {
+ struct vchi_version version;
+ int32_t service_id;
+ VCHI_CONNECTION_T *connection;
+ uint32_t rx_fifo_size;
+ uint32_t tx_fifo_size;
+ VCHI_CALLBACK_T callback;
+ void *callback_param;
+ /* client intends to receive bulk transfers of
+ odd lengths or into unaligned buffers */
+ int32_t want_unaligned_bulk_rx;
+ /* client intends to transmit bulk transfers of
+ odd lengths or out of unaligned buffers */
+ int32_t want_unaligned_bulk_tx;
+ /* client wants to check CRCs on (bulk) xfers.
+ Only needs to be set at 1 end - will do both directions. */
+ int32_t want_crc;
+} SERVICE_CREATION_T;
+
+// Opaque handle for a VCHI instance
+typedef struct opaque_vchi_instance_handle_t *VCHI_INSTANCE_T;
+
+// Opaque handle for a server or client
+typedef struct opaque_vchi_service_handle_t *VCHI_SERVICE_HANDLE_T;
+
+// Service registration & startup
+typedef void (*VCHI_SERVICE_INIT)(VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections);
+
+typedef struct service_info_tag {
+ const char * const vll_filename; /* VLL to load to start this service. This is an empty string if VLL is "static" */
+ VCHI_SERVICE_INIT init; /* Service initialisation function */
+ void *vll_handle; /* VLL handle; NULL when unloaded or a "static VLL" in build */
+} SERVICE_INFO_T;
+
+/******************************************************************************
+ Global funcs - implementation is specific to which side you are on (local / remote)
+ *****************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern /*@observer@*/ VCHI_CONNECTION_T * vchi_create_connection( const VCHI_CONNECTION_API_T * function_table,
+ const VCHI_MESSAGE_DRIVER_T * low_level);
+
+
+// Routine used to initialise the vchi on both local + remote connections
+extern int32_t vchi_initialise( VCHI_INSTANCE_T *instance_handle );
+
+extern int32_t vchi_exit( void );
+
+extern int32_t vchi_connect( VCHI_CONNECTION_T **connections,
+ const uint32_t num_connections,
+ VCHI_INSTANCE_T instance_handle );
+
+//When this is called, ensure that all services have no data pending.
+//Bulk transfers can remain 'queued'
+extern int32_t vchi_disconnect( VCHI_INSTANCE_T instance_handle );
+
+// Global control over bulk CRC checking
+extern int32_t vchi_crc_control( VCHI_CONNECTION_T *connection,
+ VCHI_CRC_CONTROL_T control );
+
+// helper functions
+extern void * vchi_allocate_buffer(VCHI_SERVICE_HANDLE_T handle, uint32_t *length);
+extern void vchi_free_buffer(VCHI_SERVICE_HANDLE_T handle, void *address);
+extern uint32_t vchi_current_time(VCHI_INSTANCE_T instance_handle);
+
+
+/******************************************************************************
+ Global service API
+ *****************************************************************************/
+// Routine to create a named service
+extern int32_t vchi_service_create( VCHI_INSTANCE_T instance_handle,
+ SERVICE_CREATION_T *setup,
+ VCHI_SERVICE_HANDLE_T *handle );
+
+// Routine to destory a service
+extern int32_t vchi_service_destroy( const VCHI_SERVICE_HANDLE_T handle );
+
+// Routine to open a named service
+extern int32_t vchi_service_open( VCHI_INSTANCE_T instance_handle,
+ SERVICE_CREATION_T *setup,
+ VCHI_SERVICE_HANDLE_T *handle);
+
+extern int32_t vchi_get_peer_version( const VCHI_SERVICE_HANDLE_T handle,
+ short *peer_version );
+
+// Routine to close a named service
+extern int32_t vchi_service_close( const VCHI_SERVICE_HANDLE_T handle );
+
+// Routine to increment ref count on a named service
+extern int32_t vchi_service_use( const VCHI_SERVICE_HANDLE_T handle );
+
+// Routine to decrement ref count on a named service
+extern int32_t vchi_service_release( const VCHI_SERVICE_HANDLE_T handle );
+
+// Routine to set a control option for a named service
+extern int32_t vchi_service_set_option( const VCHI_SERVICE_HANDLE_T handle,
+ VCHI_SERVICE_OPTION_T option,
+ int value);
+
+// Routine to send a message across a service
+extern int32_t vchi_msg_queue( VCHI_SERVICE_HANDLE_T handle,
+ const void *data,
+ uint32_t data_size,
+ VCHI_FLAGS_T flags,
+ void *msg_handle );
+
+// scatter-gather (vector) and send message
+int32_t vchi_msg_queuev_ex( VCHI_SERVICE_HANDLE_T handle,
+ VCHI_MSG_VECTOR_EX_T *vector,
+ uint32_t count,
+ VCHI_FLAGS_T flags,
+ void *msg_handle );
+
+// legacy scatter-gather (vector) and send message, only handles pointers
+int32_t vchi_msg_queuev( VCHI_SERVICE_HANDLE_T handle,
+ VCHI_MSG_VECTOR_T *vector,
+ uint32_t count,
+ VCHI_FLAGS_T flags,
+ void *msg_handle );
+
+// Routine to receive a msg from a service
+// Dequeue is equivalent to hold, copy into client buffer, release
+extern int32_t vchi_msg_dequeue( VCHI_SERVICE_HANDLE_T handle,
+ void *data,
+ uint32_t max_data_size_to_read,
+ uint32_t *actual_msg_size,
+ VCHI_FLAGS_T flags );
+
+// Routine to look at a message in place.
+// The message is not dequeued, so a subsequent call to peek or dequeue
+// will return the same message.
+extern int32_t vchi_msg_peek( VCHI_SERVICE_HANDLE_T handle,
+ void **data,
+ uint32_t *msg_size,
+ VCHI_FLAGS_T flags );
+
+// Routine to remove a message after it has been read in place with peek
+// The first message on the queue is dequeued.
+extern int32_t vchi_msg_remove( VCHI_SERVICE_HANDLE_T handle );
+
+// Routine to look at a message in place.
+// The message is dequeued, so the caller is left holding it; the descriptor is
+// filled in and must be released when the user has finished with the message.
+extern int32_t vchi_msg_hold( VCHI_SERVICE_HANDLE_T handle,
+ void **data, // } may be NULL, as info can be
+ uint32_t *msg_size, // } obtained from HELD_MSG_T
+ VCHI_FLAGS_T flags,
+ VCHI_HELD_MSG_T *message_descriptor );
+
+// Initialise an iterator to look through messages in place
+extern int32_t vchi_msg_look_ahead( VCHI_SERVICE_HANDLE_T handle,
+ VCHI_MSG_ITER_T *iter,
+ VCHI_FLAGS_T flags );
+
+/******************************************************************************
+ Global service support API - operations on held messages and message iterators
+ *****************************************************************************/
+
+// Routine to get the address of a held message
+extern void *vchi_held_msg_ptr( const VCHI_HELD_MSG_T *message );
+
+// Routine to get the size of a held message
+extern int32_t vchi_held_msg_size( const VCHI_HELD_MSG_T *message );
+
+// Routine to get the transmit timestamp as written into the header by the peer
+extern uint32_t vchi_held_msg_tx_timestamp( const VCHI_HELD_MSG_T *message );
+
+// Routine to get the reception timestamp, written as we parsed the header
+extern uint32_t vchi_held_msg_rx_timestamp( const VCHI_HELD_MSG_T *message );
+
+// Routine to release a held message after it has been processed
+extern int32_t vchi_held_msg_release( VCHI_HELD_MSG_T *message );
+
+// Indicates whether the iterator has a next message.
+extern int32_t vchi_msg_iter_has_next( const VCHI_MSG_ITER_T *iter );
+
+// Return the pointer and length for the next message and advance the iterator.
+extern int32_t vchi_msg_iter_next( VCHI_MSG_ITER_T *iter,
+ void **data,
+ uint32_t *msg_size );
+
+// Remove the last message returned by vchi_msg_iter_next.
+// Can only be called once after each call to vchi_msg_iter_next.
+extern int32_t vchi_msg_iter_remove( VCHI_MSG_ITER_T *iter );
+
+// Hold the last message returned by vchi_msg_iter_next.
+// Can only be called once after each call to vchi_msg_iter_next.
+extern int32_t vchi_msg_iter_hold( VCHI_MSG_ITER_T *iter,
+ VCHI_HELD_MSG_T *message );
+
+// Return information for the next message, and hold it, advancing the iterator.
+extern int32_t vchi_msg_iter_hold_next( VCHI_MSG_ITER_T *iter,
+ void **data, // } may be NULL
+ uint32_t *msg_size, // }
+ VCHI_HELD_MSG_T *message );
+
+
+/******************************************************************************
+ Global bulk API
+ *****************************************************************************/
+
+// Routine to prepare interface for a transfer from the other side
+extern int32_t vchi_bulk_queue_receive( VCHI_SERVICE_HANDLE_T handle,
+ void *data_dst,
+ uint32_t data_size,
+ VCHI_FLAGS_T flags,
+ void *transfer_handle );
+
+
+// Prepare interface for a transfer from the other side into relocatable memory.
+int32_t vchi_bulk_queue_receive_reloc( const VCHI_SERVICE_HANDLE_T handle,
+ VCHI_MEM_HANDLE_T h_dst,
+ uint32_t offset,
+ uint32_t data_size,
+ const VCHI_FLAGS_T flags,
+ void * const bulk_handle );
+
+// Routine to queue up data ready for transfer to the other (once they have signalled they are ready)
+extern int32_t vchi_bulk_queue_transmit( VCHI_SERVICE_HANDLE_T handle,
+ const void *data_src,
+ uint32_t data_size,
+ VCHI_FLAGS_T flags,
+ void *transfer_handle );
+
+
+/******************************************************************************
+ Configuration plumbing
+ *****************************************************************************/
+
+// function prototypes for the different mid layers (the state info gives the different physical connections)
+extern const VCHI_CONNECTION_API_T *single_get_func_table( void );
+//extern const VCHI_CONNECTION_API_T *local_server_get_func_table( void );
+//extern const VCHI_CONNECTION_API_T *local_client_get_func_table( void );
+
+// declare all message drivers here
+const VCHI_MESSAGE_DRIVER_T *vchi_mphi_message_driver_func_table( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+extern int32_t vchi_bulk_queue_transmit_reloc( VCHI_SERVICE_HANDLE_T handle,
+ VCHI_MEM_HANDLE_T h_src,
+ uint32_t offset,
+ uint32_t data_size,
+ VCHI_FLAGS_T flags,
+ void *transfer_handle );
+#endif /* VCHI_H_ */
+
+/****************************** End of file **********************************/
diff --git a/drivers/staging/vc04_services/interface/vchi/vchi_cfg.h b/drivers/staging/vc04_services/interface/vchi/vchi_cfg.h
new file mode 100644
index 000000000000..26bc2d38d725
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchi/vchi_cfg.h
@@ -0,0 +1,224 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHI_CFG_H_
+#define VCHI_CFG_H_
+
+/****************************************************************************************
+ * Defines in this first section are part of the VCHI API and may be examined by VCHI
+ * services.
+ ***************************************************************************************/
+
+/* Required alignment of base addresses for bulk transfer, if unaligned transfers are not enabled */
+/* Really determined by the message driver, and should be available from a run-time call. */
+#ifndef VCHI_BULK_ALIGN
+# if __VCCOREVER__ >= 0x04000000
+# define VCHI_BULK_ALIGN 32 // Allows for the need to do cache cleans
+# else
+# define VCHI_BULK_ALIGN 16
+# endif
+#endif
+
+/* Required length multiple for bulk transfers, if unaligned transfers are not enabled */
+/* May be less than or greater than VCHI_BULK_ALIGN */
+/* Really determined by the message driver, and should be available from a run-time call. */
+#ifndef VCHI_BULK_GRANULARITY
+# if __VCCOREVER__ >= 0x04000000
+# define VCHI_BULK_GRANULARITY 32 // Allows for the need to do cache cleans
+# else
+# define VCHI_BULK_GRANULARITY 16
+# endif
+#endif
+
+/* The largest possible message to be queued with vchi_msg_queue. */
+#ifndef VCHI_MAX_MSG_SIZE
+# if defined VCHI_LOCAL_HOST_PORT
+# define VCHI_MAX_MSG_SIZE 16384 // makes file transfers fast, but should they be using bulk?
+# else
+# define VCHI_MAX_MSG_SIZE 4096 // NOTE: THIS MUST BE LARGER THAN OR EQUAL TO THE SIZE OF THE KHRONOS MERGE BUFFER!!
+# endif
+#endif
+
+/******************************************************************************************
+ * Defines below are system configuration options, and should not be used by VCHI services.
+ *****************************************************************************************/
+
+/* How many connections can we support? A localhost implementation uses 2 connections,
+ * 1 for host-app, 1 for VMCS, and these are hooked together by a loopback MPHI VCFW
+ * driver. */
+#ifndef VCHI_MAX_NUM_CONNECTIONS
+# define VCHI_MAX_NUM_CONNECTIONS 3
+#endif
+
+/* How many services can we open per connection? Extending this doesn't cost processing time, just a small
+ * amount of static memory. */
+#ifndef VCHI_MAX_SERVICES_PER_CONNECTION
+# define VCHI_MAX_SERVICES_PER_CONNECTION 36
+#endif
+
+/* Adjust if using a message driver that supports more logical TX channels */
+#ifndef VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION
+# define VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION 9 // 1 MPHI + 8 CCP2 logical channels
+#endif
+
+/* Adjust if using a message driver that supports more logical RX channels */
+#ifndef VCHI_MAX_BULK_RX_CHANNELS_PER_CONNECTION
+# define VCHI_MAX_BULK_RX_CHANNELS_PER_CONNECTION 1 // 1 MPHI
+#endif
+
+/* How many receive slots do we use. This times VCHI_MAX_MSG_SIZE gives the effective
+ * receive queue space, less message headers. */
+#ifndef VCHI_NUM_READ_SLOTS
+# if defined(VCHI_LOCAL_HOST_PORT)
+# define VCHI_NUM_READ_SLOTS 4
+# else
+# define VCHI_NUM_READ_SLOTS 48
+# endif
+#endif
+
+/* Do we utilise overrun facility for receive message slots? Can aid peer transmit
+ * performance. Only define on VideoCore end, talking to host.
+ */
+//#define VCHI_MSG_RX_OVERRUN
+
+/* How many transmit slots do we use. Generally don't need many, as the hardware driver
+ * underneath VCHI will usually have its own buffering. */
+#ifndef VCHI_NUM_WRITE_SLOTS
+# define VCHI_NUM_WRITE_SLOTS 4
+#endif
+
+/* If a service has held or queued received messages in VCHI_XOFF_THRESHOLD or more slots,
+ * then it's taking up too much buffer space, and the peer service will be told to stop
+ * transmitting with an XOFF message. For this to be effective, the VCHI_NUM_READ_SLOTS
+ * needs to be considerably bigger than VCHI_NUM_WRITE_SLOTS, or the transmit latency
+ * is too high. */
+#ifndef VCHI_XOFF_THRESHOLD
+# define VCHI_XOFF_THRESHOLD (VCHI_NUM_READ_SLOTS / 2)
+#endif
+
+/* After we've sent an XOFF, the peer will be told to resume transmission once the local
+ * service has dequeued/released enough messages that it's now occupying
+ * VCHI_XON_THRESHOLD slots or fewer. */
+#ifndef VCHI_XON_THRESHOLD
+# define VCHI_XON_THRESHOLD (VCHI_NUM_READ_SLOTS / 4)
+#endif
+
+/* A size below which a bulk transfer omits the handshake completely and always goes
+ * via the message channel, if bulk auxiliary is being sent on that service. (The user
+ * can guarantee this by enabling unaligned transmits).
+ * Not API. */
+#ifndef VCHI_MIN_BULK_SIZE
+# define VCHI_MIN_BULK_SIZE ( VCHI_MAX_MSG_SIZE / 2 < 4096 ? VCHI_MAX_MSG_SIZE / 2 : 4096 )
+#endif
+
+/* Maximum size of bulk transmission chunks, for each interface type. A trade-off between
+ * speed and latency; the smaller the chunk size the better change of messages and other
+ * bulk transmissions getting in when big bulk transfers are happening. Set to 0 to not
+ * break transmissions into chunks.
+ */
+#ifndef VCHI_MAX_BULK_CHUNK_SIZE_MPHI
+# define VCHI_MAX_BULK_CHUNK_SIZE_MPHI (16 * 1024)
+#endif
+
+/* NB Chunked CCP2 transmissions violate the letter of the CCP2 spec by using "JPEG8" mode
+ * with multiple-line frames. Only use if the receiver can cope. */
+#ifndef VCHI_MAX_BULK_CHUNK_SIZE_CCP2
+# define VCHI_MAX_BULK_CHUNK_SIZE_CCP2 0
+#endif
+
+/* How many TX messages can we have pending in our transmit slots. Once exhausted,
+ * vchi_msg_queue will be blocked. */
+#ifndef VCHI_TX_MSG_QUEUE_SIZE
+# define VCHI_TX_MSG_QUEUE_SIZE 256
+#endif
+
+/* How many RX messages can we have parsed in the receive slots. Once exhausted, parsing
+ * will be suspended until older messages are dequeued/released. */
+#ifndef VCHI_RX_MSG_QUEUE_SIZE
+# define VCHI_RX_MSG_QUEUE_SIZE 256
+#endif
+
+/* Really should be able to cope if we run out of received message descriptors, by
+ * suspending parsing as the comment above says, but we don't. This sweeps the issue
+ * under the carpet. */
+#if VCHI_RX_MSG_QUEUE_SIZE < (VCHI_MAX_MSG_SIZE/16 + 1) * VCHI_NUM_READ_SLOTS
+# undef VCHI_RX_MSG_QUEUE_SIZE
+# define VCHI_RX_MSG_QUEUE_SIZE (VCHI_MAX_MSG_SIZE/16 + 1) * VCHI_NUM_READ_SLOTS
+#endif
+
+/* How many bulk transmits can we have pending. Once exhausted, vchi_bulk_queue_transmit
+ * will be blocked. */
+#ifndef VCHI_TX_BULK_QUEUE_SIZE
+# define VCHI_TX_BULK_QUEUE_SIZE 64
+#endif
+
+/* How many bulk receives can we have pending. Once exhausted, vchi_bulk_queue_receive
+ * will be blocked. */
+#ifndef VCHI_RX_BULK_QUEUE_SIZE
+# define VCHI_RX_BULK_QUEUE_SIZE 64
+#endif
+
+/* A limit on how many outstanding bulk requests we expect the peer to give us. If
+ * the peer asks for more than this, VCHI will fail and assert. The number is determined
+ * by the peer's hardware - it's the number of outstanding requests that can be queued
+ * on all bulk channels. VC3's MPHI peripheral allows 16. */
+#ifndef VCHI_MAX_PEER_BULK_REQUESTS
+# define VCHI_MAX_PEER_BULK_REQUESTS 32
+#endif
+
+/* Define VCHI_CCP2TX_MANUAL_POWER if the host tells us when to turn the CCP2
+ * transmitter on and off.
+ */
+/*#define VCHI_CCP2TX_MANUAL_POWER*/
+
+#ifndef VCHI_CCP2TX_MANUAL_POWER
+
+/* Timeout (in milliseconds) for putting the CCP2TX interface into IDLE state. Set
+ * negative for no IDLE.
+ */
+# ifndef VCHI_CCP2TX_IDLE_TIMEOUT
+# define VCHI_CCP2TX_IDLE_TIMEOUT 5
+# endif
+
+/* Timeout (in milliseconds) for putting the CCP2TX interface into OFF state. Set
+ * negative for no OFF.
+ */
+# ifndef VCHI_CCP2TX_OFF_TIMEOUT
+# define VCHI_CCP2TX_OFF_TIMEOUT 1000
+# endif
+
+#endif /* VCHI_CCP2TX_MANUAL_POWER */
+
+#endif /* VCHI_CFG_H_ */
+
+/****************************** End of file **********************************/
diff --git a/drivers/staging/vc04_services/interface/vchi/vchi_cfg_internal.h b/drivers/staging/vc04_services/interface/vchi/vchi_cfg_internal.h
new file mode 100644
index 000000000000..35dcba4837d4
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchi/vchi_cfg_internal.h
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHI_CFG_INTERNAL_H_
+#define VCHI_CFG_INTERNAL_H_
+
+/****************************************************************************************
+ * Control optimisation attempts.
+ ***************************************************************************************/
+
+// Don't use lots of short-term locks - use great long ones, reducing the overall locks-per-second
+#define VCHI_COARSE_LOCKING
+
+// Avoid lock then unlock on exit from blocking queue operations (msg tx, bulk rx/tx)
+// (only relevant if VCHI_COARSE_LOCKING)
+#define VCHI_ELIDE_BLOCK_EXIT_LOCK
+
+// Avoid lock on non-blocking peek
+// (only relevant if VCHI_COARSE_LOCKING)
+#define VCHI_AVOID_PEEK_LOCK
+
+// Use one slot-handler thread per connection, rather than 1 thread dealing with all connections in rotation.
+#define VCHI_MULTIPLE_HANDLER_THREADS
+
+// Put free descriptors onto the head of the free queue, rather than the tail, so that we don't thrash
+// our way through the pool of descriptors.
+#define VCHI_PUSH_FREE_DESCRIPTORS_ONTO_HEAD
+
+// Don't issue a MSG_AVAILABLE callback for every single message. Possibly only safe if VCHI_COARSE_LOCKING.
+#define VCHI_FEWER_MSG_AVAILABLE_CALLBACKS
+
+// Don't use message descriptors for TX messages that don't need them
+#define VCHI_MINIMISE_TX_MSG_DESCRIPTORS
+
+// Nano-locks for multiqueue
+//#define VCHI_MQUEUE_NANOLOCKS
+
+// Lock-free(er) dequeuing
+//#define VCHI_RX_NANOLOCKS
+
+#endif /*VCHI_CFG_INTERNAL_H_*/
diff --git a/drivers/staging/vc04_services/interface/vchi/vchi_common.h b/drivers/staging/vc04_services/interface/vchi/vchi_common.h
new file mode 100644
index 000000000000..d535a72970d3
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchi/vchi_common.h
@@ -0,0 +1,175 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHI_COMMON_H_
+#define VCHI_COMMON_H_
+
+
+//flags used when sending messages (must be bitmapped)
+typedef enum
+{
+ VCHI_FLAGS_NONE = 0x0,
+ VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE = 0x1, // waits for message to be received, or sent (NB. not the same as being seen on other side)
+ VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE = 0x2, // run a callback when message sent
+ VCHI_FLAGS_BLOCK_UNTIL_QUEUED = 0x4, // return once the transfer is in a queue ready to go
+ VCHI_FLAGS_ALLOW_PARTIAL = 0x8,
+ VCHI_FLAGS_BLOCK_UNTIL_DATA_READ = 0x10,
+ VCHI_FLAGS_CALLBACK_WHEN_DATA_READ = 0x20,
+
+ VCHI_FLAGS_ALIGN_SLOT = 0x000080, // internal use only
+ VCHI_FLAGS_BULK_AUX_QUEUED = 0x010000, // internal use only
+ VCHI_FLAGS_BULK_AUX_COMPLETE = 0x020000, // internal use only
+ VCHI_FLAGS_BULK_DATA_QUEUED = 0x040000, // internal use only
+ VCHI_FLAGS_BULK_DATA_COMPLETE = 0x080000, // internal use only
+ VCHI_FLAGS_INTERNAL = 0xFF0000
+} VCHI_FLAGS_T;
+
+// constants for vchi_crc_control()
+typedef enum {
+ VCHI_CRC_NOTHING = -1,
+ VCHI_CRC_PER_SERVICE = 0,
+ VCHI_CRC_EVERYTHING = 1,
+} VCHI_CRC_CONTROL_T;
+
+//callback reasons when an event occurs on a service
+typedef enum
+{
+ VCHI_CALLBACK_REASON_MIN,
+
+ //This indicates that there is data available
+ //handle is the msg id that was transmitted with the data
+ // When a message is received and there was no FULL message available previously, send callback
+ // Tasks get kicked by the callback, reset their event and try and read from the fifo until it fails
+ VCHI_CALLBACK_MSG_AVAILABLE,
+ VCHI_CALLBACK_MSG_SENT,
+ VCHI_CALLBACK_MSG_SPACE_AVAILABLE, // XXX not yet implemented
+
+ // This indicates that a transfer from the other side has completed
+ VCHI_CALLBACK_BULK_RECEIVED,
+ //This indicates that data queued up to be sent has now gone
+ //handle is the msg id that was used when sending the data
+ VCHI_CALLBACK_BULK_SENT,
+ VCHI_CALLBACK_BULK_RX_SPACE_AVAILABLE, // XXX not yet implemented
+ VCHI_CALLBACK_BULK_TX_SPACE_AVAILABLE, // XXX not yet implemented
+
+ VCHI_CALLBACK_SERVICE_CLOSED,
+
+ // this side has sent XOFF to peer due to lack of data consumption by service
+ // (suggests the service may need to take some recovery action if it has
+ // been deliberately holding off consuming data)
+ VCHI_CALLBACK_SENT_XOFF,
+ VCHI_CALLBACK_SENT_XON,
+
+ // indicates that a bulk transfer has finished reading the source buffer
+ VCHI_CALLBACK_BULK_DATA_READ,
+
+ // power notification events (currently host side only)
+ VCHI_CALLBACK_PEER_OFF,
+ VCHI_CALLBACK_PEER_SUSPENDED,
+ VCHI_CALLBACK_PEER_ON,
+ VCHI_CALLBACK_PEER_RESUMED,
+ VCHI_CALLBACK_FORCED_POWER_OFF,
+
+#ifdef USE_VCHIQ_ARM
+ // some extra notifications provided by vchiq_arm
+ VCHI_CALLBACK_SERVICE_OPENED,
+ VCHI_CALLBACK_BULK_RECEIVE_ABORTED,
+ VCHI_CALLBACK_BULK_TRANSMIT_ABORTED,
+#endif
+
+ VCHI_CALLBACK_REASON_MAX
+} VCHI_CALLBACK_REASON_T;
+
+// service control options
+typedef enum
+{
+ VCHI_SERVICE_OPTION_MIN,
+
+ VCHI_SERVICE_OPTION_TRACE,
+ VCHI_SERVICE_OPTION_SYNCHRONOUS,
+
+ VCHI_SERVICE_OPTION_MAX
+} VCHI_SERVICE_OPTION_T;
+
+
+//Callback used by all services / bulk transfers
+typedef void (*VCHI_CALLBACK_T)( void *callback_param, //my service local param
+ VCHI_CALLBACK_REASON_T reason,
+ void *handle ); //for transmitting msg's only
+
+
+
+/*
+ * Define vector struct for scatter-gather (vector) operations
+ * Vectors can be nested - if a vector element has negative length, then
+ * the data pointer is treated as pointing to another vector array, with
+ * '-vec_len' elements. Thus to append a header onto an existing vector,
+ * you can do this:
+ *
+ * void foo(const VCHI_MSG_VECTOR_T *v, int n)
+ * {
+ * VCHI_MSG_VECTOR_T nv[2];
+ * nv[0].vec_base = my_header;
+ * nv[0].vec_len = sizeof my_header;
+ * nv[1].vec_base = v;
+ * nv[1].vec_len = -n;
+ * ...
+ *
+ */
+typedef struct vchi_msg_vector {
+ const void *vec_base;
+ int32_t vec_len;
+} VCHI_MSG_VECTOR_T;
+
+// Opaque type for a connection API
+typedef struct opaque_vchi_connection_api_t VCHI_CONNECTION_API_T;
+
+// Opaque type for a message driver
+typedef struct opaque_vchi_message_driver_t VCHI_MESSAGE_DRIVER_T;
+
+
+// Iterator structure for reading ahead through received message queue. Allocated by client,
+// initialised by vchi_msg_look_ahead. Fields are for internal VCHI use only.
+// Iterates over messages in queue at the instant of the call to vchi_msg_lookahead -
+// will not proceed to messages received since. Behaviour is undefined if an iterator
+// is used again after messages for that service are removed/dequeued by any
+// means other than vchi_msg_iter_... calls on the iterator itself.
+typedef struct {
+ struct opaque_vchi_service_t *service;
+ void *last;
+ void *next;
+ void *remove;
+} VCHI_MSG_ITER_T;
+
+
+#endif // VCHI_COMMON_H_
diff --git a/drivers/staging/vc04_services/interface/vchi/vchi_mh.h b/drivers/staging/vc04_services/interface/vchi/vchi_mh.h
new file mode 100644
index 000000000000..198bd076b666
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchi/vchi_mh.h
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHI_MH_H_
+#define VCHI_MH_H_
+
+#include <linux/types.h>
+
+typedef int32_t VCHI_MEM_HANDLE_T;
+#define VCHI_MEM_HANDLE_INVALID 0
+
+#endif
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq.h
new file mode 100644
index 000000000000..ad398bae6ee4
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq.h
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_VCHIQ_H
+#define VCHIQ_VCHIQ_H
+
+#include "vchiq_if.h"
+#include "vchiq_util.h"
+
+#endif
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835.h
new file mode 100644
index 000000000000..7ea5c64d5343
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835.h
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_2835_H
+#define VCHIQ_2835_H
+
+#include "vchiq_pagelist.h"
+
+#define VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX 0
+#define VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX 1
+
+#endif /* VCHIQ_2835_H */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
new file mode 100644
index 000000000000..c29040fdf9a7
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
@@ -0,0 +1,586 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/pagemap.h>
+#include <linux/dma-mapping.h>
+#include <linux/version.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/of.h>
+#include <asm/pgtable.h>
+#include <soc/bcm2835/raspberrypi-firmware.h>
+
+#define dmac_map_area __glue(_CACHE,_dma_map_area)
+#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area)
+
+extern void dmac_map_area(const void *, size_t, int);
+extern void dmac_unmap_area(const void *, size_t, int);
+
+#define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32)
+
+#define VCHIQ_ARM_ADDRESS(x) ((void *)((char *)x + g_virt_to_bus_offset))
+
+#include "vchiq_arm.h"
+#include "vchiq_2835.h"
+#include "vchiq_connected.h"
+#include "vchiq_killable.h"
+
+#define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2)
+
+#define BELL0 0x00
+#define BELL2 0x08
+
+typedef struct vchiq_2835_state_struct {
+ int inited;
+ VCHIQ_ARM_STATE_T arm_state;
+} VCHIQ_2835_ARM_STATE_T;
+
+static void __iomem *g_regs;
+static unsigned int g_cache_line_size = sizeof(CACHE_LINE_SIZE);
+static unsigned int g_fragments_size;
+static char *g_fragments_base;
+static char *g_free_fragments;
+static struct semaphore g_free_fragments_sema;
+static unsigned long g_virt_to_bus_offset;
+
+extern int vchiq_arm_log_level;
+
+static DEFINE_SEMAPHORE(g_free_fragments_mutex);
+
+static irqreturn_t
+vchiq_doorbell_irq(int irq, void *dev_id);
+
+static int
+create_pagelist(char __user *buf, size_t count, unsigned short type,
+ struct task_struct *task, PAGELIST_T ** ppagelist);
+
+static void
+free_pagelist(PAGELIST_T *pagelist, int actual);
+
+int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state)
+{
+ struct device *dev = &pdev->dev;
+ struct rpi_firmware *fw = platform_get_drvdata(pdev);
+ VCHIQ_SLOT_ZERO_T *vchiq_slot_zero;
+ struct resource *res;
+ void *slot_mem;
+ dma_addr_t slot_phys;
+ u32 channelbase;
+ int slot_mem_size, frag_mem_size;
+ int err, irq, i;
+
+ g_virt_to_bus_offset = virt_to_dma(dev, (void *)0);
+
+ (void)of_property_read_u32(dev->of_node, "cache-line-size",
+ &g_cache_line_size);
+ g_fragments_size = 2 * g_cache_line_size;
+
+ /* Allocate space for the channels in coherent memory */
+ slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE);
+ frag_mem_size = PAGE_ALIGN(g_fragments_size * MAX_FRAGMENTS);
+
+ slot_mem = dmam_alloc_coherent(dev, slot_mem_size + frag_mem_size,
+ &slot_phys, GFP_KERNEL);
+ if (!slot_mem) {
+ dev_err(dev, "could not allocate DMA memory\n");
+ return -ENOMEM;
+ }
+
+ WARN_ON(((int)slot_mem & (PAGE_SIZE - 1)) != 0);
+
+ vchiq_slot_zero = vchiq_init_slots(slot_mem, slot_mem_size);
+ if (!vchiq_slot_zero)
+ return -EINVAL;
+
+ vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX] =
+ (int)slot_phys + slot_mem_size;
+ vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] =
+ MAX_FRAGMENTS;
+
+ g_fragments_base = (char *)slot_mem + slot_mem_size;
+ slot_mem_size += frag_mem_size;
+
+ g_free_fragments = g_fragments_base;
+ for (i = 0; i < (MAX_FRAGMENTS - 1); i++) {
+ *(char **)&g_fragments_base[i*g_fragments_size] =
+ &g_fragments_base[(i + 1)*g_fragments_size];
+ }
+ *(char **)&g_fragments_base[i * g_fragments_size] = NULL;
+ sema_init(&g_free_fragments_sema, MAX_FRAGMENTS);
+
+ if (vchiq_init_state(state, vchiq_slot_zero, 0) != VCHIQ_SUCCESS)
+ return -EINVAL;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ g_regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(g_regs))
+ return PTR_ERR(g_regs);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0) {
+ dev_err(dev, "failed to get IRQ\n");
+ return irq;
+ }
+
+ err = devm_request_irq(dev, irq, vchiq_doorbell_irq, IRQF_IRQPOLL,
+ "VCHIQ doorbell", state);
+ if (err) {
+ dev_err(dev, "failed to register irq=%d\n", irq);
+ return err;
+ }
+
+ /* Send the base address of the slots to VideoCore */
+ channelbase = slot_phys;
+ err = rpi_firmware_property(fw, RPI_FIRMWARE_VCHIQ_INIT,
+ &channelbase, sizeof(channelbase));
+ if (err || channelbase) {
+ dev_err(dev, "failed to set channelbase\n");
+ return err ? : -ENXIO;
+ }
+
+ vchiq_log_info(vchiq_arm_log_level,
+ "vchiq_init - done (slots %x, phys %pad)",
+ (unsigned int)vchiq_slot_zero, &slot_phys);
+
+ vchiq_call_connected_callbacks();
+
+ return 0;
+}
+
+VCHIQ_STATUS_T
+vchiq_platform_init_state(VCHIQ_STATE_T *state)
+{
+ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+ state->platform_state = kzalloc(sizeof(VCHIQ_2835_ARM_STATE_T), GFP_KERNEL);
+ ((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited = 1;
+ status = vchiq_arm_init_state(state, &((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->arm_state);
+ if(status != VCHIQ_SUCCESS)
+ {
+ ((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited = 0;
+ }
+ return status;
+}
+
+VCHIQ_ARM_STATE_T*
+vchiq_platform_get_arm_state(VCHIQ_STATE_T *state)
+{
+ if(!((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited)
+ {
+ BUG();
+ }
+ return &((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->arm_state;
+}
+
+void
+remote_event_signal(REMOTE_EVENT_T *event)
+{
+ wmb();
+
+ event->fired = 1;
+
+ dsb(); /* data barrier operation */
+
+ if (event->armed)
+ writel(0, g_regs + BELL2); /* trigger vc interrupt */
+}
+
+int
+vchiq_copy_from_user(void *dst, const void *src, int size)
+{
+ if ((uint32_t)src < TASK_SIZE) {
+ return copy_from_user(dst, src, size);
+ } else {
+ memcpy(dst, src, size);
+ return 0;
+ }
+}
+
+VCHIQ_STATUS_T
+vchiq_prepare_bulk_data(VCHIQ_BULK_T *bulk, VCHI_MEM_HANDLE_T memhandle,
+ void *offset, int size, int dir)
+{
+ PAGELIST_T *pagelist;
+ int ret;
+
+ WARN_ON(memhandle != VCHI_MEM_HANDLE_INVALID);
+
+ ret = create_pagelist((char __user *)offset, size,
+ (dir == VCHIQ_BULK_RECEIVE)
+ ? PAGELIST_READ
+ : PAGELIST_WRITE,
+ current,
+ &pagelist);
+ if (ret != 0)
+ return VCHIQ_ERROR;
+
+ bulk->handle = memhandle;
+ bulk->data = VCHIQ_ARM_ADDRESS(pagelist);
+
+ /* Store the pagelist address in remote_data, which isn't used by the
+ slave. */
+ bulk->remote_data = pagelist;
+
+ return VCHIQ_SUCCESS;
+}
+
+void
+vchiq_complete_bulk(VCHIQ_BULK_T *bulk)
+{
+ if (bulk && bulk->remote_data && bulk->actual)
+ free_pagelist((PAGELIST_T *)bulk->remote_data, bulk->actual);
+}
+
+void
+vchiq_transfer_bulk(VCHIQ_BULK_T *bulk)
+{
+ /*
+ * This should only be called on the master (VideoCore) side, but
+ * provide an implementation to avoid the need for ifdefery.
+ */
+ BUG();
+}
+
+void
+vchiq_dump_platform_state(void *dump_context)
+{
+ char buf[80];
+ int len;
+ len = snprintf(buf, sizeof(buf),
+ " Platform: 2835 (VC master)");
+ vchiq_dump(dump_context, buf, len + 1);
+}
+
+VCHIQ_STATUS_T
+vchiq_platform_suspend(VCHIQ_STATE_T *state)
+{
+ return VCHIQ_ERROR;
+}
+
+VCHIQ_STATUS_T
+vchiq_platform_resume(VCHIQ_STATE_T *state)
+{
+ return VCHIQ_SUCCESS;
+}
+
+void
+vchiq_platform_paused(VCHIQ_STATE_T *state)
+{
+}
+
+void
+vchiq_platform_resumed(VCHIQ_STATE_T *state)
+{
+}
+
+int
+vchiq_platform_videocore_wanted(VCHIQ_STATE_T* state)
+{
+ return 1; // autosuspend not supported - videocore always wanted
+}
+
+int
+vchiq_platform_use_suspend_timer(void)
+{
+ return 0;
+}
+void
+vchiq_dump_platform_use_state(VCHIQ_STATE_T *state)
+{
+ vchiq_log_info(vchiq_arm_log_level, "Suspend timer not in use");
+}
+void
+vchiq_platform_handle_timeout(VCHIQ_STATE_T *state)
+{
+ (void)state;
+}
+/*
+ * Local functions
+ */
+
+static irqreturn_t
+vchiq_doorbell_irq(int irq, void *dev_id)
+{
+ VCHIQ_STATE_T *state = dev_id;
+ irqreturn_t ret = IRQ_NONE;
+ unsigned int status;
+
+ /* Read (and clear) the doorbell */
+ status = readl(g_regs + BELL0);
+
+ if (status & 0x4) { /* Was the doorbell rung? */
+ remote_event_pollall(state);
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+}
+
+/* There is a potential problem with partial cache lines (pages?)
+** at the ends of the block when reading. If the CPU accessed anything in
+** the same line (page?) then it may have pulled old data into the cache,
+** obscuring the new data underneath. We can solve this by transferring the
+** partial cache lines separately, and allowing the ARM to copy into the
+** cached area.
+
+** N.B. This implementation plays slightly fast and loose with the Linux
+** driver programming rules, e.g. its use of dmac_map_area instead of
+** dma_map_single, but it isn't a multi-platform driver and it benefits
+** from increased speed as a result.
+*/
+
+static int
+create_pagelist(char __user *buf, size_t count, unsigned short type,
+ struct task_struct *task, PAGELIST_T ** ppagelist)
+{
+ PAGELIST_T *pagelist;
+ struct page **pages;
+ unsigned long *addrs;
+ unsigned int num_pages, offset, i;
+ char *addr, *base_addr, *next_addr;
+ int run, addridx, actual_pages;
+ unsigned long *need_release;
+
+ offset = (unsigned int)buf & (PAGE_SIZE - 1);
+ num_pages = (count + offset + PAGE_SIZE - 1) / PAGE_SIZE;
+
+ *ppagelist = NULL;
+
+ /* Allocate enough storage to hold the page pointers and the page
+ ** list
+ */
+ pagelist = kmalloc(sizeof(PAGELIST_T) +
+ (num_pages * sizeof(unsigned long)) +
+ sizeof(unsigned long) +
+ (num_pages * sizeof(pages[0])),
+ GFP_KERNEL);
+
+ vchiq_log_trace(vchiq_arm_log_level,
+ "create_pagelist - %x", (unsigned int)pagelist);
+ if (!pagelist)
+ return -ENOMEM;
+
+ addrs = pagelist->addrs;
+ need_release = (unsigned long *)(addrs + num_pages);
+ pages = (struct page **)(addrs + num_pages + 1);
+
+ if (is_vmalloc_addr(buf)) {
+ int dir = (type == PAGELIST_WRITE) ?
+ DMA_TO_DEVICE : DMA_FROM_DEVICE;
+ unsigned long length = count;
+ unsigned int off = offset;
+
+ for (actual_pages = 0; actual_pages < num_pages;
+ actual_pages++) {
+ struct page *pg = vmalloc_to_page(buf + (actual_pages *
+ PAGE_SIZE));
+ size_t bytes = PAGE_SIZE - off;
+
+ if (bytes > length)
+ bytes = length;
+ pages[actual_pages] = pg;
+ dmac_map_area(page_address(pg) + off, bytes, dir);
+ length -= bytes;
+ off = 0;
+ }
+ *need_release = 0; /* do not try and release vmalloc pages */
+ } else {
+ down_read(&task->mm->mmap_sem);
+ actual_pages = get_user_pages(task, task->mm,
+ (unsigned long)buf & ~(PAGE_SIZE - 1),
+ num_pages,
+ (type == PAGELIST_READ) /*Write */ ,
+ 0 /*Force */ ,
+ pages,
+ NULL /*vmas */);
+ up_read(&task->mm->mmap_sem);
+
+ if (actual_pages != num_pages) {
+ vchiq_log_info(vchiq_arm_log_level,
+ "create_pagelist - only %d/%d pages locked",
+ actual_pages,
+ num_pages);
+
+ /* This is probably due to the process being killed */
+ while (actual_pages > 0)
+ {
+ actual_pages--;
+ page_cache_release(pages[actual_pages]);
+ }
+ kfree(pagelist);
+ if (actual_pages == 0)
+ actual_pages = -ENOMEM;
+ return actual_pages;
+ }
+ *need_release = 1; /* release user pages */
+ }
+
+ pagelist->length = count;
+ pagelist->type = type;
+ pagelist->offset = offset;
+
+ /* Group the pages into runs of contiguous pages */
+
+ base_addr = VCHIQ_ARM_ADDRESS(page_address(pages[0]));
+ next_addr = base_addr + PAGE_SIZE;
+ addridx = 0;
+ run = 0;
+
+ for (i = 1; i < num_pages; i++) {
+ addr = VCHIQ_ARM_ADDRESS(page_address(pages[i]));
+ if ((addr == next_addr) && (run < (PAGE_SIZE - 1))) {
+ next_addr += PAGE_SIZE;
+ run++;
+ } else {
+ addrs[addridx] = (unsigned long)base_addr + run;
+ addridx++;
+ base_addr = addr;
+ next_addr = addr + PAGE_SIZE;
+ run = 0;
+ }
+ }
+
+ addrs[addridx] = (unsigned long)base_addr + run;
+ addridx++;
+
+ /* Partial cache lines (fragments) require special measures */
+ if ((type == PAGELIST_READ) &&
+ ((pagelist->offset & (g_cache_line_size - 1)) ||
+ ((pagelist->offset + pagelist->length) &
+ (g_cache_line_size - 1)))) {
+ char *fragments;
+
+ if (down_interruptible(&g_free_fragments_sema) != 0) {
+ kfree(pagelist);
+ return -EINTR;
+ }
+
+ WARN_ON(g_free_fragments == NULL);
+
+ down(&g_free_fragments_mutex);
+ fragments = g_free_fragments;
+ WARN_ON(fragments == NULL);
+ g_free_fragments = *(char **) g_free_fragments;
+ up(&g_free_fragments_mutex);
+ pagelist->type = PAGELIST_READ_WITH_FRAGMENTS +
+ (fragments - g_fragments_base) / g_fragments_size;
+ }
+
+ dmac_flush_range(pagelist, addrs + num_pages);
+
+ *ppagelist = pagelist;
+
+ return 0;
+}
+
+static void
+free_pagelist(PAGELIST_T *pagelist, int actual)
+{
+ unsigned long *need_release;
+ struct page **pages;
+ unsigned int num_pages, i;
+
+ vchiq_log_trace(vchiq_arm_log_level,
+ "free_pagelist - %x, %d", (unsigned int)pagelist, actual);
+
+ num_pages =
+ (pagelist->length + pagelist->offset + PAGE_SIZE - 1) /
+ PAGE_SIZE;
+
+ need_release = (unsigned long *)(pagelist->addrs + num_pages);
+ pages = (struct page **)(pagelist->addrs + num_pages + 1);
+
+ /* Deal with any partial cache lines (fragments) */
+ if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS) {
+ char *fragments = g_fragments_base +
+ (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS) *
+ g_fragments_size;
+ int head_bytes, tail_bytes;
+ head_bytes = (g_cache_line_size - pagelist->offset) &
+ (g_cache_line_size - 1);
+ tail_bytes = (pagelist->offset + actual) &
+ (g_cache_line_size - 1);
+
+ if ((actual >= 0) && (head_bytes != 0)) {
+ if (head_bytes > actual)
+ head_bytes = actual;
+
+ memcpy((char *)page_address(pages[0]) +
+ pagelist->offset,
+ fragments,
+ head_bytes);
+ }
+ if ((actual >= 0) && (head_bytes < actual) &&
+ (tail_bytes != 0)) {
+ memcpy((char *)page_address(pages[num_pages - 1]) +
+ ((pagelist->offset + actual) &
+ (PAGE_SIZE - 1) & ~(g_cache_line_size - 1)),
+ fragments + g_cache_line_size,
+ tail_bytes);
+ }
+
+ down(&g_free_fragments_mutex);
+ *(char **)fragments = g_free_fragments;
+ g_free_fragments = fragments;
+ up(&g_free_fragments_mutex);
+ up(&g_free_fragments_sema);
+ }
+
+ if (*need_release) {
+ unsigned int length = pagelist->length;
+ unsigned int offset = pagelist->offset;
+
+ for (i = 0; i < num_pages; i++) {
+ struct page *pg = pages[i];
+
+ if (pagelist->type != PAGELIST_WRITE) {
+ unsigned int bytes = PAGE_SIZE - offset;
+
+ if (bytes > length)
+ bytes = length;
+ dmac_unmap_area(page_address(pg) + offset,
+ bytes, DMA_FROM_DEVICE);
+ length -= bytes;
+ offset = 0;
+ set_page_dirty(pg);
+ }
+ page_cache_release(pg);
+ }
+ }
+
+ kfree(pagelist);
+}
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
new file mode 100644
index 000000000000..e11c0e07471b
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -0,0 +1,2903 @@
+/**
+ * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/bug.h>
+#include <linux/semaphore.h>
+#include <linux/list.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <soc/bcm2835/raspberrypi-firmware.h>
+
+#include "vchiq_core.h"
+#include "vchiq_ioctl.h"
+#include "vchiq_arm.h"
+#include "vchiq_debugfs.h"
+#include "vchiq_killable.h"
+
+#define DEVICE_NAME "vchiq"
+
+/* Override the default prefix, which would be vchiq_arm (from the filename) */
+#undef MODULE_PARAM_PREFIX
+#define MODULE_PARAM_PREFIX DEVICE_NAME "."
+
+#define VCHIQ_MINOR 0
+
+/* Some per-instance constants */
+#define MAX_COMPLETIONS 16
+#define MAX_SERVICES 64
+#define MAX_ELEMENTS 8
+#define MSG_QUEUE_SIZE 64
+
+#define KEEPALIVE_VER 1
+#define KEEPALIVE_VER_MIN KEEPALIVE_VER
+
+/* Run time control of log level, based on KERN_XXX level. */
+int vchiq_arm_log_level = VCHIQ_LOG_DEFAULT;
+int vchiq_susp_log_level = VCHIQ_LOG_ERROR;
+
+#define SUSPEND_TIMER_TIMEOUT_MS 100
+#define SUSPEND_RETRY_TIMER_TIMEOUT_MS 1000
+
+#define VC_SUSPEND_NUM_OFFSET 3 /* number of values before idle which are -ve */
+static const char *const suspend_state_names[] = {
+ "VC_SUSPEND_FORCE_CANCELED",
+ "VC_SUSPEND_REJECTED",
+ "VC_SUSPEND_FAILED",
+ "VC_SUSPEND_IDLE",
+ "VC_SUSPEND_REQUESTED",
+ "VC_SUSPEND_IN_PROGRESS",
+ "VC_SUSPEND_SUSPENDED"
+};
+#define VC_RESUME_NUM_OFFSET 1 /* number of values before idle which are -ve */
+static const char *const resume_state_names[] = {
+ "VC_RESUME_FAILED",
+ "VC_RESUME_IDLE",
+ "VC_RESUME_REQUESTED",
+ "VC_RESUME_IN_PROGRESS",
+ "VC_RESUME_RESUMED"
+};
+/* The number of times we allow force suspend to timeout before actually
+** _forcing_ suspend. This is to cater for SW which fails to release vchiq
+** correctly - we don't want to prevent ARM suspend indefinitely in this case.
+*/
+#define FORCE_SUSPEND_FAIL_MAX 8
+
+/* The time in ms allowed for videocore to go idle when force suspend has been
+ * requested */
+#define FORCE_SUSPEND_TIMEOUT_MS 200
+
+
+static void suspend_timer_callback(unsigned long context);
+
+
+typedef struct user_service_struct {
+ VCHIQ_SERVICE_T *service;
+ void *userdata;
+ VCHIQ_INSTANCE_T instance;
+ char is_vchi;
+ char dequeue_pending;
+ char close_pending;
+ int message_available_pos;
+ int msg_insert;
+ int msg_remove;
+ struct semaphore insert_event;
+ struct semaphore remove_event;
+ struct semaphore close_event;
+ VCHIQ_HEADER_T * msg_queue[MSG_QUEUE_SIZE];
+} USER_SERVICE_T;
+
+struct bulk_waiter_node {
+ struct bulk_waiter bulk_waiter;
+ int pid;
+ struct list_head list;
+};
+
+struct vchiq_instance_struct {
+ VCHIQ_STATE_T *state;
+ VCHIQ_COMPLETION_DATA_T completions[MAX_COMPLETIONS];
+ int completion_insert;
+ int completion_remove;
+ struct semaphore insert_event;
+ struct semaphore remove_event;
+ struct mutex completion_mutex;
+
+ int connected;
+ int closing;
+ int pid;
+ int mark;
+ int use_close_delivered;
+ int trace;
+
+ struct list_head bulk_waiter_list;
+ struct mutex bulk_waiter_list_mutex;
+
+ VCHIQ_DEBUGFS_NODE_T debugfs_node;
+};
+
+typedef struct dump_context_struct {
+ char __user *buf;
+ size_t actual;
+ size_t space;
+ loff_t offset;
+} DUMP_CONTEXT_T;
+
+static struct cdev vchiq_cdev;
+static dev_t vchiq_devid;
+static VCHIQ_STATE_T g_state;
+static struct class *vchiq_class;
+static struct device *vchiq_dev;
+static DEFINE_SPINLOCK(msg_queue_spinlock);
+
+static const char *const ioctl_names[] = {
+ "CONNECT",
+ "SHUTDOWN",
+ "CREATE_SERVICE",
+ "REMOVE_SERVICE",
+ "QUEUE_MESSAGE",
+ "QUEUE_BULK_TRANSMIT",
+ "QUEUE_BULK_RECEIVE",
+ "AWAIT_COMPLETION",
+ "DEQUEUE_MESSAGE",
+ "GET_CLIENT_ID",
+ "GET_CONFIG",
+ "CLOSE_SERVICE",
+ "USE_SERVICE",
+ "RELEASE_SERVICE",
+ "SET_SERVICE_OPTION",
+ "DUMP_PHYS_MEM",
+ "LIB_VERSION",
+ "CLOSE_DELIVERED"
+};
+
+vchiq_static_assert((sizeof(ioctl_names)/sizeof(ioctl_names[0])) ==
+ (VCHIQ_IOC_MAX + 1));
+
+static void
+dump_phys_mem(void *virt_addr, uint32_t num_bytes);
+
+/****************************************************************************
+*
+* add_completion
+*
+***************************************************************************/
+
+static VCHIQ_STATUS_T
+add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason,
+ VCHIQ_HEADER_T *header, USER_SERVICE_T *user_service,
+ void *bulk_userdata)
+{
+ VCHIQ_COMPLETION_DATA_T *completion;
+ DEBUG_INITIALISE(g_state.local)
+
+ while (instance->completion_insert ==
+ (instance->completion_remove + MAX_COMPLETIONS)) {
+ /* Out of space - wait for the client */
+ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+ vchiq_log_trace(vchiq_arm_log_level,
+ "add_completion - completion queue full");
+ DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT);
+ if (down_interruptible(&instance->remove_event) != 0) {
+ vchiq_log_info(vchiq_arm_log_level,
+ "service_callback interrupted");
+ return VCHIQ_RETRY;
+ } else if (instance->closing) {
+ vchiq_log_info(vchiq_arm_log_level,
+ "service_callback closing");
+ return VCHIQ_ERROR;
+ }
+ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+ }
+
+ completion =
+ &instance->completions[instance->completion_insert &
+ (MAX_COMPLETIONS - 1)];
+
+ completion->header = header;
+ completion->reason = reason;
+ /* N.B. service_userdata is updated while processing AWAIT_COMPLETION */
+ completion->service_userdata = user_service->service;
+ completion->bulk_userdata = bulk_userdata;
+
+ if (reason == VCHIQ_SERVICE_CLOSED) {
+ /* Take an extra reference, to be held until
+ this CLOSED notification is delivered. */
+ lock_service(user_service->service);
+ if (instance->use_close_delivered)
+ user_service->close_pending = 1;
+ }
+
+ /* A write barrier is needed here to ensure that the entire completion
+ record is written out before the insert point. */
+ wmb();
+
+ if (reason == VCHIQ_MESSAGE_AVAILABLE)
+ user_service->message_available_pos =
+ instance->completion_insert;
+ instance->completion_insert++;
+
+ up(&instance->insert_event);
+
+ return VCHIQ_SUCCESS;
+}
+
+/****************************************************************************
+*
+* service_callback
+*
+***************************************************************************/
+
+static VCHIQ_STATUS_T
+service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header,
+ VCHIQ_SERVICE_HANDLE_T handle, void *bulk_userdata)
+{
+ /* How do we ensure the callback goes to the right client?
+ ** The service_user data points to a USER_SERVICE_T record containing
+ ** the original callback and the user state structure, which contains a
+ ** circular buffer for completion records.
+ */
+ USER_SERVICE_T *user_service;
+ VCHIQ_SERVICE_T *service;
+ VCHIQ_INSTANCE_T instance;
+ DEBUG_INITIALISE(g_state.local)
+
+ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+
+ service = handle_to_service(handle);
+ BUG_ON(!service);
+ user_service = (USER_SERVICE_T *)service->base.userdata;
+ instance = user_service->instance;
+
+ if (!instance || instance->closing)
+ return VCHIQ_SUCCESS;
+
+ vchiq_log_trace(vchiq_arm_log_level,
+ "service_callback - service %lx(%d,%p), reason %d, header %lx, "
+ "instance %lx, bulk_userdata %lx",
+ (unsigned long)user_service,
+ service->localport, user_service->userdata,
+ reason, (unsigned long)header,
+ (unsigned long)instance, (unsigned long)bulk_userdata);
+
+ if (header && user_service->is_vchi) {
+ spin_lock(&msg_queue_spinlock);
+ while (user_service->msg_insert ==
+ (user_service->msg_remove + MSG_QUEUE_SIZE)) {
+ spin_unlock(&msg_queue_spinlock);
+ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+ DEBUG_COUNT(MSG_QUEUE_FULL_COUNT);
+ vchiq_log_trace(vchiq_arm_log_level,
+ "service_callback - msg queue full");
+ /* If there is no MESSAGE_AVAILABLE in the completion
+ ** queue, add one
+ */
+ if ((user_service->message_available_pos -
+ instance->completion_remove) < 0) {
+ VCHIQ_STATUS_T status;
+ vchiq_log_info(vchiq_arm_log_level,
+ "Inserting extra MESSAGE_AVAILABLE");
+ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+ status = add_completion(instance, reason,
+ NULL, user_service, bulk_userdata);
+ if (status != VCHIQ_SUCCESS) {
+ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+ return status;
+ }
+ }
+
+ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+ if (down_interruptible(&user_service->remove_event)
+ != 0) {
+ vchiq_log_info(vchiq_arm_log_level,
+ "service_callback interrupted");
+ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+ return VCHIQ_RETRY;
+ } else if (instance->closing) {
+ vchiq_log_info(vchiq_arm_log_level,
+ "service_callback closing");
+ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+ return VCHIQ_ERROR;
+ }
+ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+ spin_lock(&msg_queue_spinlock);
+ }
+
+ user_service->msg_queue[user_service->msg_insert &
+ (MSG_QUEUE_SIZE - 1)] = header;
+ user_service->msg_insert++;
+ spin_unlock(&msg_queue_spinlock);
+
+ up(&user_service->insert_event);
+
+ /* If there is a thread waiting in DEQUEUE_MESSAGE, or if
+ ** there is a MESSAGE_AVAILABLE in the completion queue then
+ ** bypass the completion queue.
+ */
+ if (((user_service->message_available_pos -
+ instance->completion_remove) >= 0) ||
+ user_service->dequeue_pending) {
+ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+ user_service->dequeue_pending = 0;
+ return VCHIQ_SUCCESS;
+ }
+
+ header = NULL;
+ }
+ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+
+ return add_completion(instance, reason, header, user_service,
+ bulk_userdata);
+}
+
+/****************************************************************************
+*
+* user_service_free
+*
+***************************************************************************/
+static void
+user_service_free(void *userdata)
+{
+ kfree(userdata);
+}
+
+/****************************************************************************
+*
+* close_delivered
+*
+***************************************************************************/
+static void close_delivered(USER_SERVICE_T *user_service)
+{
+ vchiq_log_info(vchiq_arm_log_level,
+ "close_delivered(handle=%x)",
+ user_service->service->handle);
+
+ if (user_service->close_pending) {
+ /* Allow the underlying service to be culled */
+ unlock_service(user_service->service);
+
+ /* Wake the user-thread blocked in close_ or remove_service */
+ up(&user_service->close_event);
+
+ user_service->close_pending = 0;
+ }
+}
+
+/****************************************************************************
+*
+* vchiq_ioctl
+*
+***************************************************************************/
+static long
+vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ VCHIQ_INSTANCE_T instance = file->private_data;
+ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+ VCHIQ_SERVICE_T *service = NULL;
+ long ret = 0;
+ int i, rc;
+ DEBUG_INITIALISE(g_state.local)
+
+ vchiq_log_trace(vchiq_arm_log_level,
+ "vchiq_ioctl - instance %x, cmd %s, arg %lx",
+ (unsigned int)instance,
+ ((_IOC_TYPE(cmd) == VCHIQ_IOC_MAGIC) &&
+ (_IOC_NR(cmd) <= VCHIQ_IOC_MAX)) ?
+ ioctl_names[_IOC_NR(cmd)] : "<invalid>", arg);
+
+ switch (cmd) {
+ case VCHIQ_IOC_SHUTDOWN:
+ if (!instance->connected)
+ break;
+
+ /* Remove all services */
+ i = 0;
+ while ((service = next_service_by_instance(instance->state,
+ instance, &i)) != NULL) {
+ status = vchiq_remove_service(service->handle);
+ unlock_service(service);
+ if (status != VCHIQ_SUCCESS)
+ break;
+ }
+ service = NULL;
+
+ if (status == VCHIQ_SUCCESS) {
+ /* Wake the completion thread and ask it to exit */
+ instance->closing = 1;
+ up(&instance->insert_event);
+ }
+
+ break;
+
+ case VCHIQ_IOC_CONNECT:
+ if (instance->connected) {
+ ret = -EINVAL;
+ break;
+ }
+ rc = mutex_lock_interruptible(&instance->state->mutex);
+ if (rc != 0) {
+ vchiq_log_error(vchiq_arm_log_level,
+ "vchiq: connect: could not lock mutex for "
+ "state %d: %d",
+ instance->state->id, rc);
+ ret = -EINTR;
+ break;
+ }
+ status = vchiq_connect_internal(instance->state, instance);
+ mutex_unlock(&instance->state->mutex);
+
+ if (status == VCHIQ_SUCCESS)
+ instance->connected = 1;
+ else
+ vchiq_log_error(vchiq_arm_log_level,
+ "vchiq: could not connect: %d", status);
+ break;
+
+ case VCHIQ_IOC_CREATE_SERVICE: {
+ VCHIQ_CREATE_SERVICE_T args;
+ USER_SERVICE_T *user_service = NULL;
+ void *userdata;
+ int srvstate;
+
+ if (copy_from_user
+ (&args, (const void __user *)arg,
+ sizeof(args)) != 0) {
+ ret = -EFAULT;
+ break;
+ }
+
+ user_service = kmalloc(sizeof(USER_SERVICE_T), GFP_KERNEL);
+ if (!user_service) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ if (args.is_open) {
+ if (!instance->connected) {
+ ret = -ENOTCONN;
+ kfree(user_service);
+ break;
+ }
+ srvstate = VCHIQ_SRVSTATE_OPENING;
+ } else {
+ srvstate =
+ instance->connected ?
+ VCHIQ_SRVSTATE_LISTENING :
+ VCHIQ_SRVSTATE_HIDDEN;
+ }
+
+ userdata = args.params.userdata;
+ args.params.callback = service_callback;
+ args.params.userdata = user_service;
+ service = vchiq_add_service_internal(
+ instance->state,
+ &args.params, srvstate,
+ instance, user_service_free);
+
+ if (service != NULL) {
+ user_service->service = service;
+ user_service->userdata = userdata;
+ user_service->instance = instance;
+ user_service->is_vchi = (args.is_vchi != 0);
+ user_service->dequeue_pending = 0;
+ user_service->close_pending = 0;
+ user_service->message_available_pos =
+ instance->completion_remove - 1;
+ user_service->msg_insert = 0;
+ user_service->msg_remove = 0;
+ sema_init(&user_service->insert_event, 0);
+ sema_init(&user_service->remove_event, 0);
+ sema_init(&user_service->close_event, 0);
+
+ if (args.is_open) {
+ status = vchiq_open_service_internal
+ (service, instance->pid);
+ if (status != VCHIQ_SUCCESS) {
+ vchiq_remove_service(service->handle);
+ service = NULL;
+ ret = (status == VCHIQ_RETRY) ?
+ -EINTR : -EIO;
+ break;
+ }
+ }
+
+ if (copy_to_user((void __user *)
+ &(((VCHIQ_CREATE_SERVICE_T __user *)
+ arg)->handle),
+ (const void *)&service->handle,
+ sizeof(service->handle)) != 0) {
+ ret = -EFAULT;
+ vchiq_remove_service(service->handle);
+ }
+
+ service = NULL;
+ } else {
+ ret = -EEXIST;
+ kfree(user_service);
+ }
+ } break;
+
+ case VCHIQ_IOC_CLOSE_SERVICE: {
+ VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg;
+
+ service = find_service_for_instance(instance, handle);
+ if (service != NULL) {
+ USER_SERVICE_T *user_service =
+ (USER_SERVICE_T *)service->base.userdata;
+ /* close_pending is false on first entry, and when the
+ wait in vchiq_close_service has been interrupted. */
+ if (!user_service->close_pending) {
+ status = vchiq_close_service(service->handle);
+ if (status != VCHIQ_SUCCESS)
+ break;
+ }
+
+ /* close_pending is true once the underlying service
+ has been closed until the client library calls the
+ CLOSE_DELIVERED ioctl, signalling close_event. */
+ if (user_service->close_pending &&
+ down_interruptible(&user_service->close_event))
+ status = VCHIQ_RETRY;
+ }
+ else
+ ret = -EINVAL;
+ } break;
+
+ case VCHIQ_IOC_REMOVE_SERVICE: {
+ VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg;
+
+ service = find_service_for_instance(instance, handle);
+ if (service != NULL) {
+ USER_SERVICE_T *user_service =
+ (USER_SERVICE_T *)service->base.userdata;
+ /* close_pending is false on first entry, and when the
+ wait in vchiq_close_service has been interrupted. */
+ if (!user_service->close_pending) {
+ status = vchiq_remove_service(service->handle);
+ if (status != VCHIQ_SUCCESS)
+ break;
+ }
+
+ /* close_pending is true once the underlying service
+ has been closed until the client library calls the
+ CLOSE_DELIVERED ioctl, signalling close_event. */
+ if (user_service->close_pending &&
+ down_interruptible(&user_service->close_event))
+ status = VCHIQ_RETRY;
+ }
+ else
+ ret = -EINVAL;
+ } break;
+
+ case VCHIQ_IOC_USE_SERVICE:
+ case VCHIQ_IOC_RELEASE_SERVICE: {
+ VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg;
+
+ service = find_service_for_instance(instance, handle);
+ if (service != NULL) {
+ status = (cmd == VCHIQ_IOC_USE_SERVICE) ?
+ vchiq_use_service_internal(service) :
+ vchiq_release_service_internal(service);
+ if (status != VCHIQ_SUCCESS) {
+ vchiq_log_error(vchiq_susp_log_level,
+ "%s: cmd %s returned error %d for "
+ "service %c%c%c%c:%03d",
+ __func__,
+ (cmd == VCHIQ_IOC_USE_SERVICE) ?
+ "VCHIQ_IOC_USE_SERVICE" :
+ "VCHIQ_IOC_RELEASE_SERVICE",
+ status,
+ VCHIQ_FOURCC_AS_4CHARS(
+ service->base.fourcc),
+ service->client_id);
+ ret = -EINVAL;
+ }
+ } else
+ ret = -EINVAL;
+ } break;
+
+ case VCHIQ_IOC_QUEUE_MESSAGE: {
+ VCHIQ_QUEUE_MESSAGE_T args;
+ if (copy_from_user
+ (&args, (const void __user *)arg,
+ sizeof(args)) != 0) {
+ ret = -EFAULT;
+ break;
+ }
+
+ service = find_service_for_instance(instance, args.handle);
+
+ if ((service != NULL) && (args.count <= MAX_ELEMENTS)) {
+ /* Copy elements into kernel space */
+ VCHIQ_ELEMENT_T elements[MAX_ELEMENTS];
+ if (copy_from_user(elements, args.elements,
+ args.count * sizeof(VCHIQ_ELEMENT_T)) == 0)
+ status = vchiq_queue_message
+ (args.handle,
+ elements, args.count);
+ else
+ ret = -EFAULT;
+ } else {
+ ret = -EINVAL;
+ }
+ } break;
+
+ case VCHIQ_IOC_QUEUE_BULK_TRANSMIT:
+ case VCHIQ_IOC_QUEUE_BULK_RECEIVE: {
+ VCHIQ_QUEUE_BULK_TRANSFER_T args;
+ struct bulk_waiter_node *waiter = NULL;
+ VCHIQ_BULK_DIR_T dir =
+ (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) ?
+ VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE;
+
+ if (copy_from_user
+ (&args, (const void __user *)arg,
+ sizeof(args)) != 0) {
+ ret = -EFAULT;
+ break;
+ }
+
+ service = find_service_for_instance(instance, args.handle);
+ if (!service) {
+ ret = -EINVAL;
+ break;
+ }
+
+ if (args.mode == VCHIQ_BULK_MODE_BLOCKING) {
+ waiter = kzalloc(sizeof(struct bulk_waiter_node),
+ GFP_KERNEL);
+ if (!waiter) {
+ ret = -ENOMEM;
+ break;
+ }
+ args.userdata = &waiter->bulk_waiter;
+ } else if (args.mode == VCHIQ_BULK_MODE_WAITING) {
+ struct list_head *pos;
+ mutex_lock(&instance->bulk_waiter_list_mutex);
+ list_for_each(pos, &instance->bulk_waiter_list) {
+ if (list_entry(pos, struct bulk_waiter_node,
+ list)->pid == current->pid) {
+ waiter = list_entry(pos,
+ struct bulk_waiter_node,
+ list);
+ list_del(pos);
+ break;
+ }
+
+ }
+ mutex_unlock(&instance->bulk_waiter_list_mutex);
+ if (!waiter) {
+ vchiq_log_error(vchiq_arm_log_level,
+ "no bulk_waiter found for pid %d",
+ current->pid);
+ ret = -ESRCH;
+ break;
+ }
+ vchiq_log_info(vchiq_arm_log_level,
+ "found bulk_waiter %x for pid %d",
+ (unsigned int)waiter, current->pid);
+ args.userdata = &waiter->bulk_waiter;
+ }
+ status = vchiq_bulk_transfer
+ (args.handle,
+ VCHI_MEM_HANDLE_INVALID,
+ args.data, args.size,
+ args.userdata, args.mode,
+ dir);
+ if (!waiter)
+ break;
+ if ((status != VCHIQ_RETRY) || fatal_signal_pending(current) ||
+ !waiter->bulk_waiter.bulk) {
+ if (waiter->bulk_waiter.bulk) {
+ /* Cancel the signal when the transfer
+ ** completes. */
+ spin_lock(&bulk_waiter_spinlock);
+ waiter->bulk_waiter.bulk->userdata = NULL;
+ spin_unlock(&bulk_waiter_spinlock);
+ }
+ kfree(waiter);
+ } else {
+ const VCHIQ_BULK_MODE_T mode_waiting =
+ VCHIQ_BULK_MODE_WAITING;
+ waiter->pid = current->pid;
+ mutex_lock(&instance->bulk_waiter_list_mutex);
+ list_add(&waiter->list, &instance->bulk_waiter_list);
+ mutex_unlock(&instance->bulk_waiter_list_mutex);
+ vchiq_log_info(vchiq_arm_log_level,
+ "saved bulk_waiter %x for pid %d",
+ (unsigned int)waiter, current->pid);
+
+ if (copy_to_user((void __user *)
+ &(((VCHIQ_QUEUE_BULK_TRANSFER_T __user *)
+ arg)->mode),
+ (const void *)&mode_waiting,
+ sizeof(mode_waiting)) != 0)
+ ret = -EFAULT;
+ }
+ } break;
+
+ case VCHIQ_IOC_AWAIT_COMPLETION: {
+ VCHIQ_AWAIT_COMPLETION_T args;
+
+ DEBUG_TRACE(AWAIT_COMPLETION_LINE);
+ if (!instance->connected) {
+ ret = -ENOTCONN;
+ break;
+ }
+
+ if (copy_from_user(&args, (const void __user *)arg,
+ sizeof(args)) != 0) {
+ ret = -EFAULT;
+ break;
+ }
+
+ mutex_lock(&instance->completion_mutex);
+
+ DEBUG_TRACE(AWAIT_COMPLETION_LINE);
+ while ((instance->completion_remove ==
+ instance->completion_insert)
+ && !instance->closing) {
+ int rc;
+ DEBUG_TRACE(AWAIT_COMPLETION_LINE);
+ mutex_unlock(&instance->completion_mutex);
+ rc = down_interruptible(&instance->insert_event);
+ mutex_lock(&instance->completion_mutex);
+ if (rc != 0) {
+ DEBUG_TRACE(AWAIT_COMPLETION_LINE);
+ vchiq_log_info(vchiq_arm_log_level,
+ "AWAIT_COMPLETION interrupted");
+ ret = -EINTR;
+ break;
+ }
+ }
+ DEBUG_TRACE(AWAIT_COMPLETION_LINE);
+
+ /* A read memory barrier is needed to stop prefetch of a stale
+ ** completion record
+ */
+ rmb();
+
+ if (ret == 0) {
+ int msgbufcount = args.msgbufcount;
+ for (ret = 0; ret < args.count; ret++) {
+ VCHIQ_COMPLETION_DATA_T *completion;
+ VCHIQ_SERVICE_T *service;
+ USER_SERVICE_T *user_service;
+ VCHIQ_HEADER_T *header;
+ if (instance->completion_remove ==
+ instance->completion_insert)
+ break;
+ completion = &instance->completions[
+ instance->completion_remove &
+ (MAX_COMPLETIONS - 1)];
+
+ service = completion->service_userdata;
+ user_service = service->base.userdata;
+ completion->service_userdata =
+ user_service->userdata;
+
+ header = completion->header;
+ if (header) {
+ void __user *msgbuf;
+ int msglen;
+
+ msglen = header->size +
+ sizeof(VCHIQ_HEADER_T);
+ /* This must be a VCHIQ-style service */
+ if (args.msgbufsize < msglen) {
+ vchiq_log_error(
+ vchiq_arm_log_level,
+ "header %x: msgbufsize"
+ " %x < msglen %x",
+ (unsigned int)header,
+ args.msgbufsize,
+ msglen);
+ WARN(1, "invalid message "
+ "size\n");
+ if (ret == 0)
+ ret = -EMSGSIZE;
+ break;
+ }
+ if (msgbufcount <= 0)
+ /* Stall here for lack of a
+ ** buffer for the message. */
+ break;
+ /* Get the pointer from user space */
+ msgbufcount--;
+ if (copy_from_user(&msgbuf,
+ (const void __user *)
+ &args.msgbufs[msgbufcount],
+ sizeof(msgbuf)) != 0) {
+ if (ret == 0)
+ ret = -EFAULT;
+ break;
+ }
+
+ /* Copy the message to user space */
+ if (copy_to_user(msgbuf, header,
+ msglen) != 0) {
+ if (ret == 0)
+ ret = -EFAULT;
+ break;
+ }
+
+ /* Now it has been copied, the message
+ ** can be released. */
+ vchiq_release_message(service->handle,
+ header);
+
+ /* The completion must point to the
+ ** msgbuf. */
+ completion->header = msgbuf;
+ }
+
+ if ((completion->reason ==
+ VCHIQ_SERVICE_CLOSED) &&
+ !instance->use_close_delivered)
+ unlock_service(service);
+
+ if (copy_to_user((void __user *)(
+ (size_t)args.buf +
+ ret * sizeof(VCHIQ_COMPLETION_DATA_T)),
+ completion,
+ sizeof(VCHIQ_COMPLETION_DATA_T)) != 0) {
+ if (ret == 0)
+ ret = -EFAULT;
+ break;
+ }
+
+ instance->completion_remove++;
+ }
+
+ if (msgbufcount != args.msgbufcount) {
+ if (copy_to_user((void __user *)
+ &((VCHIQ_AWAIT_COMPLETION_T *)arg)->
+ msgbufcount,
+ &msgbufcount,
+ sizeof(msgbufcount)) != 0) {
+ ret = -EFAULT;
+ }
+ }
+ }
+
+ if (ret != 0)
+ up(&instance->remove_event);
+ mutex_unlock(&instance->completion_mutex);
+ DEBUG_TRACE(AWAIT_COMPLETION_LINE);
+ } break;
+
+ case VCHIQ_IOC_DEQUEUE_MESSAGE: {
+ VCHIQ_DEQUEUE_MESSAGE_T args;
+ USER_SERVICE_T *user_service;
+ VCHIQ_HEADER_T *header;
+
+ DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
+ if (copy_from_user
+ (&args, (const void __user *)arg,
+ sizeof(args)) != 0) {
+ ret = -EFAULT;
+ break;
+ }
+ service = find_service_for_instance(instance, args.handle);
+ if (!service) {
+ ret = -EINVAL;
+ break;
+ }
+ user_service = (USER_SERVICE_T *)service->base.userdata;
+ if (user_service->is_vchi == 0) {
+ ret = -EINVAL;
+ break;
+ }
+
+ spin_lock(&msg_queue_spinlock);
+ if (user_service->msg_remove == user_service->msg_insert) {
+ if (!args.blocking) {
+ spin_unlock(&msg_queue_spinlock);
+ DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
+ ret = -EWOULDBLOCK;
+ break;
+ }
+ user_service->dequeue_pending = 1;
+ do {
+ spin_unlock(&msg_queue_spinlock);
+ DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
+ if (down_interruptible(
+ &user_service->insert_event) != 0) {
+ vchiq_log_info(vchiq_arm_log_level,
+ "DEQUEUE_MESSAGE interrupted");
+ ret = -EINTR;
+ break;
+ }
+ spin_lock(&msg_queue_spinlock);
+ } while (user_service->msg_remove ==
+ user_service->msg_insert);
+
+ if (ret)
+ break;
+ }
+
+ BUG_ON((int)(user_service->msg_insert -
+ user_service->msg_remove) < 0);
+
+ header = user_service->msg_queue[user_service->msg_remove &
+ (MSG_QUEUE_SIZE - 1)];
+ user_service->msg_remove++;
+ spin_unlock(&msg_queue_spinlock);
+
+ up(&user_service->remove_event);
+ if (header == NULL)
+ ret = -ENOTCONN;
+ else if (header->size <= args.bufsize) {
+ /* Copy to user space if msgbuf is not NULL */
+ if ((args.buf == NULL) ||
+ (copy_to_user((void __user *)args.buf,
+ header->data,
+ header->size) == 0)) {
+ ret = header->size;
+ vchiq_release_message(
+ service->handle,
+ header);
+ } else
+ ret = -EFAULT;
+ } else {
+ vchiq_log_error(vchiq_arm_log_level,
+ "header %x: bufsize %x < size %x",
+ (unsigned int)header, args.bufsize,
+ header->size);
+ WARN(1, "invalid size\n");
+ ret = -EMSGSIZE;
+ }
+ DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
+ } break;
+
+ case VCHIQ_IOC_GET_CLIENT_ID: {
+ VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg;
+
+ ret = vchiq_get_client_id(handle);
+ } break;
+
+ case VCHIQ_IOC_GET_CONFIG: {
+ VCHIQ_GET_CONFIG_T args;
+ VCHIQ_CONFIG_T config;
+
+ if (copy_from_user(&args, (const void __user *)arg,
+ sizeof(args)) != 0) {
+ ret = -EFAULT;
+ break;
+ }
+ if (args.config_size > sizeof(config)) {
+ ret = -EINVAL;
+ break;
+ }
+ status = vchiq_get_config(instance, args.config_size, &config);
+ if (status == VCHIQ_SUCCESS) {
+ if (copy_to_user((void __user *)args.pconfig,
+ &config, args.config_size) != 0) {
+ ret = -EFAULT;
+ break;
+ }
+ }
+ } break;
+
+ case VCHIQ_IOC_SET_SERVICE_OPTION: {
+ VCHIQ_SET_SERVICE_OPTION_T args;
+
+ if (copy_from_user(
+ &args, (const void __user *)arg,
+ sizeof(args)) != 0) {
+ ret = -EFAULT;
+ break;
+ }
+
+ service = find_service_for_instance(instance, args.handle);
+ if (!service) {
+ ret = -EINVAL;
+ break;
+ }
+
+ status = vchiq_set_service_option(
+ args.handle, args.option, args.value);
+ } break;
+
+ case VCHIQ_IOC_DUMP_PHYS_MEM: {
+ VCHIQ_DUMP_MEM_T args;
+
+ if (copy_from_user
+ (&args, (const void __user *)arg,
+ sizeof(args)) != 0) {
+ ret = -EFAULT;
+ break;
+ }
+ dump_phys_mem(args.virt_addr, args.num_bytes);
+ } break;
+
+ case VCHIQ_IOC_LIB_VERSION: {
+ unsigned int lib_version = (unsigned int)arg;
+
+ if (lib_version < VCHIQ_VERSION_MIN)
+ ret = -EINVAL;
+ else if (lib_version >= VCHIQ_VERSION_CLOSE_DELIVERED)
+ instance->use_close_delivered = 1;
+ } break;
+
+ case VCHIQ_IOC_CLOSE_DELIVERED: {
+ VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg;
+
+ service = find_closed_service_for_instance(instance, handle);
+ if (service != NULL) {
+ USER_SERVICE_T *user_service =
+ (USER_SERVICE_T *)service->base.userdata;
+ close_delivered(user_service);
+ }
+ else
+ ret = -EINVAL;
+ } break;
+
+ default:
+ ret = -ENOTTY;
+ break;
+ }
+
+ if (service)
+ unlock_service(service);
+
+ if (ret == 0) {
+ if (status == VCHIQ_ERROR)
+ ret = -EIO;
+ else if (status == VCHIQ_RETRY)
+ ret = -EINTR;
+ }
+
+ if ((status == VCHIQ_SUCCESS) && (ret < 0) && (ret != -EINTR) &&
+ (ret != -EWOULDBLOCK))
+ vchiq_log_info(vchiq_arm_log_level,
+ " ioctl instance %lx, cmd %s -> status %d, %ld",
+ (unsigned long)instance,
+ (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ?
+ ioctl_names[_IOC_NR(cmd)] :
+ "<invalid>",
+ status, ret);
+ else
+ vchiq_log_trace(vchiq_arm_log_level,
+ " ioctl instance %lx, cmd %s -> status %d, %ld",
+ (unsigned long)instance,
+ (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ?
+ ioctl_names[_IOC_NR(cmd)] :
+ "<invalid>",
+ status, ret);
+
+ return ret;
+}
+
+/****************************************************************************
+*
+* vchiq_open
+*
+***************************************************************************/
+
+static int
+vchiq_open(struct inode *inode, struct file *file)
+{
+ int dev = iminor(inode) & 0x0f;
+ vchiq_log_info(vchiq_arm_log_level, "vchiq_open");
+ switch (dev) {
+ case VCHIQ_MINOR: {
+ int ret;
+ VCHIQ_STATE_T *state = vchiq_get_state();
+ VCHIQ_INSTANCE_T instance;
+
+ if (!state) {
+ vchiq_log_error(vchiq_arm_log_level,
+ "vchiq has no connection to VideoCore");
+ return -ENOTCONN;
+ }
+
+ instance = kzalloc(sizeof(*instance), GFP_KERNEL);
+ if (!instance)
+ return -ENOMEM;
+
+ instance->state = state;
+ instance->pid = current->tgid;
+
+ ret = vchiq_debugfs_add_instance(instance);
+ if (ret != 0) {
+ kfree(instance);
+ return ret;
+ }
+
+ sema_init(&instance->insert_event, 0);
+ sema_init(&instance->remove_event, 0);
+ mutex_init(&instance->completion_mutex);
+ mutex_init(&instance->bulk_waiter_list_mutex);
+ INIT_LIST_HEAD(&instance->bulk_waiter_list);
+
+ file->private_data = instance;
+ } break;
+
+ default:
+ vchiq_log_error(vchiq_arm_log_level,
+ "Unknown minor device: %d", dev);
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+/****************************************************************************
+*
+* vchiq_release
+*
+***************************************************************************/
+
+static int
+vchiq_release(struct inode *inode, struct file *file)
+{
+ int dev = iminor(inode) & 0x0f;
+ int ret = 0;
+ switch (dev) {
+ case VCHIQ_MINOR: {
+ VCHIQ_INSTANCE_T instance = file->private_data;
+ VCHIQ_STATE_T *state = vchiq_get_state();
+ VCHIQ_SERVICE_T *service;
+ int i;
+
+ vchiq_log_info(vchiq_arm_log_level,
+ "vchiq_release: instance=%lx",
+ (unsigned long)instance);
+
+ if (!state) {
+ ret = -EPERM;
+ goto out;
+ }
+
+ /* Ensure videocore is awake to allow termination. */
+ vchiq_use_internal(instance->state, NULL,
+ USE_TYPE_VCHIQ);
+
+ mutex_lock(&instance->completion_mutex);
+
+ /* Wake the completion thread and ask it to exit */
+ instance->closing = 1;
+ up(&instance->insert_event);
+
+ mutex_unlock(&instance->completion_mutex);
+
+ /* Wake the slot handler if the completion queue is full. */
+ up(&instance->remove_event);
+
+ /* Mark all services for termination... */
+ i = 0;
+ while ((service = next_service_by_instance(state, instance,
+ &i)) != NULL) {
+ USER_SERVICE_T *user_service = service->base.userdata;
+
+ /* Wake the slot handler if the msg queue is full. */
+ up(&user_service->remove_event);
+
+ vchiq_terminate_service_internal(service);
+ unlock_service(service);
+ }
+
+ /* ...and wait for them to die */
+ i = 0;
+ while ((service = next_service_by_instance(state, instance, &i))
+ != NULL) {
+ USER_SERVICE_T *user_service = service->base.userdata;
+
+ down(&service->remove_event);
+
+ BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE);
+
+ spin_lock(&msg_queue_spinlock);
+
+ while (user_service->msg_remove !=
+ user_service->msg_insert) {
+ VCHIQ_HEADER_T *header = user_service->
+ msg_queue[user_service->msg_remove &
+ (MSG_QUEUE_SIZE - 1)];
+ user_service->msg_remove++;
+ spin_unlock(&msg_queue_spinlock);
+
+ if (header)
+ vchiq_release_message(
+ service->handle,
+ header);
+ spin_lock(&msg_queue_spinlock);
+ }
+
+ spin_unlock(&msg_queue_spinlock);
+
+ unlock_service(service);
+ }
+
+ /* Release any closed services */
+ while (instance->completion_remove !=
+ instance->completion_insert) {
+ VCHIQ_COMPLETION_DATA_T *completion;
+ VCHIQ_SERVICE_T *service;
+ completion = &instance->completions[
+ instance->completion_remove &
+ (MAX_COMPLETIONS - 1)];
+ service = completion->service_userdata;
+ if (completion->reason == VCHIQ_SERVICE_CLOSED)
+ {
+ USER_SERVICE_T *user_service =
+ service->base.userdata;
+
+ /* Wake any blocked user-thread */
+ if (instance->use_close_delivered)
+ up(&user_service->close_event);
+ unlock_service(service);
+ }
+ instance->completion_remove++;
+ }
+
+ /* Release the PEER service count. */
+ vchiq_release_internal(instance->state, NULL);
+
+ {
+ struct list_head *pos, *next;
+ list_for_each_safe(pos, next,
+ &instance->bulk_waiter_list) {
+ struct bulk_waiter_node *waiter;
+ waiter = list_entry(pos,
+ struct bulk_waiter_node,
+ list);
+ list_del(pos);
+ vchiq_log_info(vchiq_arm_log_level,
+ "bulk_waiter - cleaned up %x "
+ "for pid %d",
+ (unsigned int)waiter, waiter->pid);
+ kfree(waiter);
+ }
+ }
+
+ vchiq_debugfs_remove_instance(instance);
+
+ kfree(instance);
+ file->private_data = NULL;
+ } break;
+
+ default:
+ vchiq_log_error(vchiq_arm_log_level,
+ "Unknown minor device: %d", dev);
+ ret = -ENXIO;
+ }
+
+out:
+ return ret;
+}
+
+/****************************************************************************
+*
+* vchiq_dump
+*
+***************************************************************************/
+
+void
+vchiq_dump(void *dump_context, const char *str, int len)
+{
+ DUMP_CONTEXT_T *context = (DUMP_CONTEXT_T *)dump_context;
+
+ if (context->actual < context->space) {
+ int copy_bytes;
+ if (context->offset > 0) {
+ int skip_bytes = min(len, (int)context->offset);
+ str += skip_bytes;
+ len -= skip_bytes;
+ context->offset -= skip_bytes;
+ if (context->offset > 0)
+ return;
+ }
+ copy_bytes = min(len, (int)(context->space - context->actual));
+ if (copy_bytes == 0)
+ return;
+ if (copy_to_user(context->buf + context->actual, str,
+ copy_bytes))
+ context->actual = -EFAULT;
+ context->actual += copy_bytes;
+ len -= copy_bytes;
+
+ /* If tne terminating NUL is included in the length, then it
+ ** marks the end of a line and should be replaced with a
+ ** carriage return. */
+ if ((len == 0) && (str[copy_bytes - 1] == '\0')) {
+ char cr = '\n';
+ if (copy_to_user(context->buf + context->actual - 1,
+ &cr, 1))
+ context->actual = -EFAULT;
+ }
+ }
+}
+
+/****************************************************************************
+*
+* vchiq_dump_platform_instance_state
+*
+***************************************************************************/
+
+void
+vchiq_dump_platform_instances(void *dump_context)
+{
+ VCHIQ_STATE_T *state = vchiq_get_state();
+ char buf[80];
+ int len;
+ int i;
+
+ /* There is no list of instances, so instead scan all services,
+ marking those that have been dumped. */
+
+ for (i = 0; i < state->unused_service; i++) {
+ VCHIQ_SERVICE_T *service = state->services[i];
+ VCHIQ_INSTANCE_T instance;
+
+ if (service && (service->base.callback == service_callback)) {
+ instance = service->instance;
+ if (instance)
+ instance->mark = 0;
+ }
+ }
+
+ for (i = 0; i < state->unused_service; i++) {
+ VCHIQ_SERVICE_T *service = state->services[i];
+ VCHIQ_INSTANCE_T instance;
+
+ if (service && (service->base.callback == service_callback)) {
+ instance = service->instance;
+ if (instance && !instance->mark) {
+ len = snprintf(buf, sizeof(buf),
+ "Instance %x: pid %d,%s completions "
+ "%d/%d",
+ (unsigned int)instance, instance->pid,
+ instance->connected ? " connected, " :
+ "",
+ instance->completion_insert -
+ instance->completion_remove,
+ MAX_COMPLETIONS);
+
+ vchiq_dump(dump_context, buf, len + 1);
+
+ instance->mark = 1;
+ }
+ }
+ }
+}
+
+/****************************************************************************
+*
+* vchiq_dump_platform_service_state
+*
+***************************************************************************/
+
+void
+vchiq_dump_platform_service_state(void *dump_context, VCHIQ_SERVICE_T *service)
+{
+ USER_SERVICE_T *user_service = (USER_SERVICE_T *)service->base.userdata;
+ char buf[80];
+ int len;
+
+ len = snprintf(buf, sizeof(buf), " instance %x",
+ (unsigned int)service->instance);
+
+ if ((service->base.callback == service_callback) &&
+ user_service->is_vchi) {
+ len += snprintf(buf + len, sizeof(buf) - len,
+ ", %d/%d messages",
+ user_service->msg_insert - user_service->msg_remove,
+ MSG_QUEUE_SIZE);
+
+ if (user_service->dequeue_pending)
+ len += snprintf(buf + len, sizeof(buf) - len,
+ " (dequeue pending)");
+ }
+
+ vchiq_dump(dump_context, buf, len + 1);
+}
+
+/****************************************************************************
+*
+* dump_user_mem
+*
+***************************************************************************/
+
+static void
+dump_phys_mem(void *virt_addr, uint32_t num_bytes)
+{
+ int rc;
+ uint8_t *end_virt_addr = virt_addr + num_bytes;
+ int num_pages;
+ int offset;
+ int end_offset;
+ int page_idx;
+ int prev_idx;
+ struct page *page;
+ struct page **pages;
+ uint8_t *kmapped_virt_ptr;
+
+ /* Align virtAddr and endVirtAddr to 16 byte boundaries. */
+
+ virt_addr = (void *)((unsigned long)virt_addr & ~0x0fuL);
+ end_virt_addr = (void *)(((unsigned long)end_virt_addr + 15uL) &
+ ~0x0fuL);
+
+ offset = (int)(long)virt_addr & (PAGE_SIZE - 1);
+ end_offset = (int)(long)end_virt_addr & (PAGE_SIZE - 1);
+
+ num_pages = (offset + num_bytes + PAGE_SIZE - 1) / PAGE_SIZE;
+
+ pages = kmalloc(sizeof(struct page *) * num_pages, GFP_KERNEL);
+ if (pages == NULL) {
+ vchiq_log_error(vchiq_arm_log_level,
+ "Unable to allocation memory for %d pages\n",
+ num_pages);
+ return;
+ }
+
+ down_read(&current->mm->mmap_sem);
+ rc = get_user_pages(current, /* task */
+ current->mm, /* mm */
+ (unsigned long)virt_addr, /* start */
+ num_pages, /* len */
+ 0, /* write */
+ 0, /* force */
+ pages, /* pages (array of page pointers) */
+ NULL); /* vmas */
+ up_read(&current->mm->mmap_sem);
+
+ prev_idx = -1;
+ page = NULL;
+
+ while (offset < end_offset) {
+
+ int page_offset = offset % PAGE_SIZE;
+ page_idx = offset / PAGE_SIZE;
+
+ if (page_idx != prev_idx) {
+
+ if (page != NULL)
+ kunmap(page);
+ page = pages[page_idx];
+ kmapped_virt_ptr = kmap(page);
+
+ prev_idx = page_idx;
+ }
+
+ if (vchiq_arm_log_level >= VCHIQ_LOG_TRACE)
+ vchiq_log_dump_mem("ph",
+ (uint32_t)(unsigned long)&kmapped_virt_ptr[
+ page_offset],
+ &kmapped_virt_ptr[page_offset], 16);
+
+ offset += 16;
+ }
+ if (page != NULL)
+ kunmap(page);
+
+ for (page_idx = 0; page_idx < num_pages; page_idx++)
+ page_cache_release(pages[page_idx]);
+
+ kfree(pages);
+}
+
+/****************************************************************************
+*
+* vchiq_read
+*
+***************************************************************************/
+
+static ssize_t
+vchiq_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ DUMP_CONTEXT_T context;
+ context.buf = buf;
+ context.actual = 0;
+ context.space = count;
+ context.offset = *ppos;
+
+ vchiq_dump_state(&context, &g_state);
+
+ *ppos += context.actual;
+
+ return context.actual;
+}
+
+VCHIQ_STATE_T *
+vchiq_get_state(void)
+{
+
+ if (g_state.remote == NULL)
+ printk(KERN_ERR "%s: g_state.remote == NULL\n", __func__);
+ else if (g_state.remote->initialised != 1)
+ printk(KERN_NOTICE "%s: g_state.remote->initialised != 1 (%d)\n",
+ __func__, g_state.remote->initialised);
+
+ return ((g_state.remote != NULL) &&
+ (g_state.remote->initialised == 1)) ? &g_state : NULL;
+}
+
+static const struct file_operations
+vchiq_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = vchiq_ioctl,
+ .open = vchiq_open,
+ .release = vchiq_release,
+ .read = vchiq_read
+};
+
+/*
+ * Autosuspend related functionality
+ */
+
+int
+vchiq_videocore_wanted(VCHIQ_STATE_T *state)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ if (!arm_state)
+ /* autosuspend not supported - always return wanted */
+ return 1;
+ else if (arm_state->blocked_count)
+ return 1;
+ else if (!arm_state->videocore_use_count)
+ /* usage count zero - check for override unless we're forcing */
+ if (arm_state->resume_blocked)
+ return 0;
+ else
+ return vchiq_platform_videocore_wanted(state);
+ else
+ /* non-zero usage count - videocore still required */
+ return 1;
+}
+
+static VCHIQ_STATUS_T
+vchiq_keepalive_vchiq_callback(VCHIQ_REASON_T reason,
+ VCHIQ_HEADER_T *header,
+ VCHIQ_SERVICE_HANDLE_T service_user,
+ void *bulk_user)
+{
+ vchiq_log_error(vchiq_susp_log_level,
+ "%s callback reason %d", __func__, reason);
+ return 0;
+}
+
+static int
+vchiq_keepalive_thread_func(void *v)
+{
+ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v;
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+
+ VCHIQ_STATUS_T status;
+ VCHIQ_INSTANCE_T instance;
+ VCHIQ_SERVICE_HANDLE_T ka_handle;
+
+ VCHIQ_SERVICE_PARAMS_T params = {
+ .fourcc = VCHIQ_MAKE_FOURCC('K', 'E', 'E', 'P'),
+ .callback = vchiq_keepalive_vchiq_callback,
+ .version = KEEPALIVE_VER,
+ .version_min = KEEPALIVE_VER_MIN
+ };
+
+ status = vchiq_initialise(&instance);
+ if (status != VCHIQ_SUCCESS) {
+ vchiq_log_error(vchiq_susp_log_level,
+ "%s vchiq_initialise failed %d", __func__, status);
+ goto exit;
+ }
+
+ status = vchiq_connect(instance);
+ if (status != VCHIQ_SUCCESS) {
+ vchiq_log_error(vchiq_susp_log_level,
+ "%s vchiq_connect failed %d", __func__, status);
+ goto shutdown;
+ }
+
+ status = vchiq_add_service(instance, &params, &ka_handle);
+ if (status != VCHIQ_SUCCESS) {
+ vchiq_log_error(vchiq_susp_log_level,
+ "%s vchiq_open_service failed %d", __func__, status);
+ goto shutdown;
+ }
+
+ while (1) {
+ long rc = 0, uc = 0;
+ if (wait_for_completion_interruptible(&arm_state->ka_evt)
+ != 0) {
+ vchiq_log_error(vchiq_susp_log_level,
+ "%s interrupted", __func__);
+ flush_signals(current);
+ continue;
+ }
+
+ /* read and clear counters. Do release_count then use_count to
+ * prevent getting more releases than uses */
+ rc = atomic_xchg(&arm_state->ka_release_count, 0);
+ uc = atomic_xchg(&arm_state->ka_use_count, 0);
+
+ /* Call use/release service the requisite number of times.
+ * Process use before release so use counts don't go negative */
+ while (uc--) {
+ atomic_inc(&arm_state->ka_use_ack_count);
+ status = vchiq_use_service(ka_handle);
+ if (status != VCHIQ_SUCCESS) {
+ vchiq_log_error(vchiq_susp_log_level,
+ "%s vchiq_use_service error %d",
+ __func__, status);
+ }
+ }
+ while (rc--) {
+ status = vchiq_release_service(ka_handle);
+ if (status != VCHIQ_SUCCESS) {
+ vchiq_log_error(vchiq_susp_log_level,
+ "%s vchiq_release_service error %d",
+ __func__, status);
+ }
+ }
+ }
+
+shutdown:
+ vchiq_shutdown(instance);
+exit:
+ return 0;
+}
+
+
+
+VCHIQ_STATUS_T
+vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state)
+{
+ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+
+ if (arm_state) {
+ rwlock_init(&arm_state->susp_res_lock);
+
+ init_completion(&arm_state->ka_evt);
+ atomic_set(&arm_state->ka_use_count, 0);
+ atomic_set(&arm_state->ka_use_ack_count, 0);
+ atomic_set(&arm_state->ka_release_count, 0);
+
+ init_completion(&arm_state->vc_suspend_complete);
+
+ init_completion(&arm_state->vc_resume_complete);
+ /* Initialise to 'done' state. We only want to block on resume
+ * completion while videocore is suspended. */
+ set_resume_state(arm_state, VC_RESUME_RESUMED);
+
+ init_completion(&arm_state->resume_blocker);
+ /* Initialise to 'done' state. We only want to block on this
+ * completion while resume is blocked */
+ complete_all(&arm_state->resume_blocker);
+
+ init_completion(&arm_state->blocked_blocker);
+ /* Initialise to 'done' state. We only want to block on this
+ * completion while things are waiting on the resume blocker */
+ complete_all(&arm_state->blocked_blocker);
+
+ arm_state->suspend_timer_timeout = SUSPEND_TIMER_TIMEOUT_MS;
+ arm_state->suspend_timer_running = 0;
+ init_timer(&arm_state->suspend_timer);
+ arm_state->suspend_timer.data = (unsigned long)(state);
+ arm_state->suspend_timer.function = suspend_timer_callback;
+
+ arm_state->first_connect = 0;
+
+ }
+ return status;
+}
+
+/*
+** Functions to modify the state variables;
+** set_suspend_state
+** set_resume_state
+**
+** There are more state variables than we might like, so ensure they remain in
+** step. Suspend and resume state are maintained separately, since most of
+** these state machines can operate independently. However, there are a few
+** states where state transitions in one state machine cause a reset to the
+** other state machine. In addition, there are some completion events which
+** need to occur on state machine reset and end-state(s), so these are also
+** dealt with in these functions.
+**
+** In all states we set the state variable according to the input, but in some
+** cases we perform additional steps outlined below;
+**
+** VC_SUSPEND_IDLE - Initialise the suspend completion at the same time.
+** The suspend completion is completed after any suspend
+** attempt. When we reset the state machine we also reset
+** the completion. This reset occurs when videocore is
+** resumed, and also if we initiate suspend after a suspend
+** failure.
+**
+** VC_SUSPEND_IN_PROGRESS - This state is considered the point of no return for
+** suspend - ie from this point on we must try to suspend
+** before resuming can occur. We therefore also reset the
+** resume state machine to VC_RESUME_IDLE in this state.
+**
+** VC_SUSPEND_SUSPENDED - Suspend has completed successfully. Also call
+** complete_all on the suspend completion to notify
+** anything waiting for suspend to happen.
+**
+** VC_SUSPEND_REJECTED - Videocore rejected suspend. Videocore will also
+** initiate resume, so no need to alter resume state.
+** We call complete_all on the suspend completion to notify
+** of suspend rejection.
+**
+** VC_SUSPEND_FAILED - We failed to initiate videocore suspend. We notify the
+** suspend completion and reset the resume state machine.
+**
+** VC_RESUME_IDLE - Initialise the resume completion at the same time. The
+** resume completion is in it's 'done' state whenever
+** videcore is running. Therfore, the VC_RESUME_IDLE state
+** implies that videocore is suspended.
+** Hence, any thread which needs to wait until videocore is
+** running can wait on this completion - it will only block
+** if videocore is suspended.
+**
+** VC_RESUME_RESUMED - Resume has completed successfully. Videocore is running.
+** Call complete_all on the resume completion to unblock
+** any threads waiting for resume. Also reset the suspend
+** state machine to it's idle state.
+**
+** VC_RESUME_FAILED - Currently unused - no mechanism to fail resume exists.
+*/
+
+void
+set_suspend_state(VCHIQ_ARM_STATE_T *arm_state,
+ enum vc_suspend_status new_state)
+{
+ /* set the state in all cases */
+ arm_state->vc_suspend_state = new_state;
+
+ /* state specific additional actions */
+ switch (new_state) {
+ case VC_SUSPEND_FORCE_CANCELED:
+ complete_all(&arm_state->vc_suspend_complete);
+ break;
+ case VC_SUSPEND_REJECTED:
+ complete_all(&arm_state->vc_suspend_complete);
+ break;
+ case VC_SUSPEND_FAILED:
+ complete_all(&arm_state->vc_suspend_complete);
+ arm_state->vc_resume_state = VC_RESUME_RESUMED;
+ complete_all(&arm_state->vc_resume_complete);
+ break;
+ case VC_SUSPEND_IDLE:
+ reinit_completion(&arm_state->vc_suspend_complete);
+ break;
+ case VC_SUSPEND_REQUESTED:
+ break;
+ case VC_SUSPEND_IN_PROGRESS:
+ set_resume_state(arm_state, VC_RESUME_IDLE);
+ break;
+ case VC_SUSPEND_SUSPENDED:
+ complete_all(&arm_state->vc_suspend_complete);
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+void
+set_resume_state(VCHIQ_ARM_STATE_T *arm_state,
+ enum vc_resume_status new_state)
+{
+ /* set the state in all cases */
+ arm_state->vc_resume_state = new_state;
+
+ /* state specific additional actions */
+ switch (new_state) {
+ case VC_RESUME_FAILED:
+ break;
+ case VC_RESUME_IDLE:
+ reinit_completion(&arm_state->vc_resume_complete);
+ break;
+ case VC_RESUME_REQUESTED:
+ break;
+ case VC_RESUME_IN_PROGRESS:
+ break;
+ case VC_RESUME_RESUMED:
+ complete_all(&arm_state->vc_resume_complete);
+ set_suspend_state(arm_state, VC_SUSPEND_IDLE);
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+
+/* should be called with the write lock held */
+inline void
+start_suspend_timer(VCHIQ_ARM_STATE_T *arm_state)
+{
+ del_timer(&arm_state->suspend_timer);
+ arm_state->suspend_timer.expires = jiffies +
+ msecs_to_jiffies(arm_state->
+ suspend_timer_timeout);
+ add_timer(&arm_state->suspend_timer);
+ arm_state->suspend_timer_running = 1;
+}
+
+/* should be called with the write lock held */
+static inline void
+stop_suspend_timer(VCHIQ_ARM_STATE_T *arm_state)
+{
+ if (arm_state->suspend_timer_running) {
+ del_timer(&arm_state->suspend_timer);
+ arm_state->suspend_timer_running = 0;
+ }
+}
+
+static inline int
+need_resume(VCHIQ_STATE_T *state)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ return (arm_state->vc_suspend_state > VC_SUSPEND_IDLE) &&
+ (arm_state->vc_resume_state < VC_RESUME_REQUESTED) &&
+ vchiq_videocore_wanted(state);
+}
+
+static int
+block_resume(VCHIQ_ARM_STATE_T *arm_state)
+{
+ int status = VCHIQ_SUCCESS;
+ const unsigned long timeout_val =
+ msecs_to_jiffies(FORCE_SUSPEND_TIMEOUT_MS);
+ int resume_count = 0;
+
+ /* Allow any threads which were blocked by the last force suspend to
+ * complete if they haven't already. Only give this one shot; if
+ * blocked_count is incremented after blocked_blocker is completed
+ * (which only happens when blocked_count hits 0) then those threads
+ * will have to wait until next time around */
+ if (arm_state->blocked_count) {
+ reinit_completion(&arm_state->blocked_blocker);
+ write_unlock_bh(&arm_state->susp_res_lock);
+ vchiq_log_info(vchiq_susp_log_level, "%s wait for previously "
+ "blocked clients", __func__);
+ if (wait_for_completion_interruptible_timeout(
+ &arm_state->blocked_blocker, timeout_val)
+ <= 0) {
+ vchiq_log_error(vchiq_susp_log_level, "%s wait for "
+ "previously blocked clients failed" , __func__);
+ status = VCHIQ_ERROR;
+ write_lock_bh(&arm_state->susp_res_lock);
+ goto out;
+ }
+ vchiq_log_info(vchiq_susp_log_level, "%s previously blocked "
+ "clients resumed", __func__);
+ write_lock_bh(&arm_state->susp_res_lock);
+ }
+
+ /* We need to wait for resume to complete if it's in process */
+ while (arm_state->vc_resume_state != VC_RESUME_RESUMED &&
+ arm_state->vc_resume_state > VC_RESUME_IDLE) {
+ if (resume_count > 1) {
+ status = VCHIQ_ERROR;
+ vchiq_log_error(vchiq_susp_log_level, "%s waited too "
+ "many times for resume" , __func__);
+ goto out;
+ }
+ write_unlock_bh(&arm_state->susp_res_lock);
+ vchiq_log_info(vchiq_susp_log_level, "%s wait for resume",
+ __func__);
+ if (wait_for_completion_interruptible_timeout(
+ &arm_state->vc_resume_complete, timeout_val)
+ <= 0) {
+ vchiq_log_error(vchiq_susp_log_level, "%s wait for "
+ "resume failed (%s)", __func__,
+ resume_state_names[arm_state->vc_resume_state +
+ VC_RESUME_NUM_OFFSET]);
+ status = VCHIQ_ERROR;
+ write_lock_bh(&arm_state->susp_res_lock);
+ goto out;
+ }
+ vchiq_log_info(vchiq_susp_log_level, "%s resumed", __func__);
+ write_lock_bh(&arm_state->susp_res_lock);
+ resume_count++;
+ }
+ reinit_completion(&arm_state->resume_blocker);
+ arm_state->resume_blocked = 1;
+
+out:
+ return status;
+}
+
+static inline void
+unblock_resume(VCHIQ_ARM_STATE_T *arm_state)
+{
+ complete_all(&arm_state->resume_blocker);
+ arm_state->resume_blocked = 0;
+}
+
+/* Initiate suspend via slot handler. Should be called with the write lock
+ * held */
+VCHIQ_STATUS_T
+vchiq_arm_vcsuspend(VCHIQ_STATE_T *state)
+{
+ VCHIQ_STATUS_T status = VCHIQ_ERROR;
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+
+ if (!arm_state)
+ goto out;
+
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+ status = VCHIQ_SUCCESS;
+
+
+ switch (arm_state->vc_suspend_state) {
+ case VC_SUSPEND_REQUESTED:
+ vchiq_log_info(vchiq_susp_log_level, "%s: suspend already "
+ "requested", __func__);
+ break;
+ case VC_SUSPEND_IN_PROGRESS:
+ vchiq_log_info(vchiq_susp_log_level, "%s: suspend already in "
+ "progress", __func__);
+ break;
+
+ default:
+ /* We don't expect to be in other states, so log but continue
+ * anyway */
+ vchiq_log_error(vchiq_susp_log_level,
+ "%s unexpected suspend state %s", __func__,
+ suspend_state_names[arm_state->vc_suspend_state +
+ VC_SUSPEND_NUM_OFFSET]);
+ /* fall through */
+ case VC_SUSPEND_REJECTED:
+ case VC_SUSPEND_FAILED:
+ /* Ensure any idle state actions have been run */
+ set_suspend_state(arm_state, VC_SUSPEND_IDLE);
+ /* fall through */
+ case VC_SUSPEND_IDLE:
+ vchiq_log_info(vchiq_susp_log_level,
+ "%s: suspending", __func__);
+ set_suspend_state(arm_state, VC_SUSPEND_REQUESTED);
+ /* kick the slot handler thread to initiate suspend */
+ request_poll(state, NULL, 0);
+ break;
+ }
+
+out:
+ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, status);
+ return status;
+}
+
+void
+vchiq_platform_check_suspend(VCHIQ_STATE_T *state)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ int susp = 0;
+
+ if (!arm_state)
+ goto out;
+
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+
+ write_lock_bh(&arm_state->susp_res_lock);
+ if (arm_state->vc_suspend_state == VC_SUSPEND_REQUESTED &&
+ arm_state->vc_resume_state == VC_RESUME_RESUMED) {
+ set_suspend_state(arm_state, VC_SUSPEND_IN_PROGRESS);
+ susp = 1;
+ }
+ write_unlock_bh(&arm_state->susp_res_lock);
+
+ if (susp)
+ vchiq_platform_suspend(state);
+
+out:
+ vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__);
+ return;
+}
+
+
+static void
+output_timeout_error(VCHIQ_STATE_T *state)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ char service_err[50] = "";
+ int vc_use_count = arm_state->videocore_use_count;
+ int active_services = state->unused_service;
+ int i;
+
+ if (!arm_state->videocore_use_count) {
+ snprintf(service_err, 50, " Videocore usecount is 0");
+ goto output_msg;
+ }
+ for (i = 0; i < active_services; i++) {
+ VCHIQ_SERVICE_T *service_ptr = state->services[i];
+ if (service_ptr && service_ptr->service_use_count &&
+ (service_ptr->srvstate != VCHIQ_SRVSTATE_FREE)) {
+ snprintf(service_err, 50, " %c%c%c%c(%d) service has "
+ "use count %d%s", VCHIQ_FOURCC_AS_4CHARS(
+ service_ptr->base.fourcc),
+ service_ptr->client_id,
+ service_ptr->service_use_count,
+ service_ptr->service_use_count ==
+ vc_use_count ? "" : " (+ more)");
+ break;
+ }
+ }
+
+output_msg:
+ vchiq_log_error(vchiq_susp_log_level,
+ "timed out waiting for vc suspend (%d).%s",
+ arm_state->autosuspend_override, service_err);
+
+}
+
+/* Try to get videocore into suspended state, regardless of autosuspend state.
+** We don't actually force suspend, since videocore may get into a bad state
+** if we force suspend at a bad time. Instead, we wait for autosuspend to
+** determine a good point to suspend. If this doesn't happen within 100ms we
+** report failure.
+**
+** Returns VCHIQ_SUCCESS if videocore suspended successfully, VCHIQ_RETRY if
+** videocore failed to suspend in time or VCHIQ_ERROR if interrupted.
+*/
+VCHIQ_STATUS_T
+vchiq_arm_force_suspend(VCHIQ_STATE_T *state)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ VCHIQ_STATUS_T status = VCHIQ_ERROR;
+ long rc = 0;
+ int repeat = -1;
+
+ if (!arm_state)
+ goto out;
+
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+
+ write_lock_bh(&arm_state->susp_res_lock);
+
+ status = block_resume(arm_state);
+ if (status != VCHIQ_SUCCESS)
+ goto unlock;
+ if (arm_state->vc_suspend_state == VC_SUSPEND_SUSPENDED) {
+ /* Already suspended - just block resume and exit */
+ vchiq_log_info(vchiq_susp_log_level, "%s already suspended",
+ __func__);
+ status = VCHIQ_SUCCESS;
+ goto unlock;
+ } else if (arm_state->vc_suspend_state <= VC_SUSPEND_IDLE) {
+ /* initiate suspend immediately in the case that we're waiting
+ * for the timeout */
+ stop_suspend_timer(arm_state);
+ if (!vchiq_videocore_wanted(state)) {
+ vchiq_log_info(vchiq_susp_log_level, "%s videocore "
+ "idle, initiating suspend", __func__);
+ status = vchiq_arm_vcsuspend(state);
+ } else if (arm_state->autosuspend_override <
+ FORCE_SUSPEND_FAIL_MAX) {
+ vchiq_log_info(vchiq_susp_log_level, "%s letting "
+ "videocore go idle", __func__);
+ status = VCHIQ_SUCCESS;
+ } else {
+ vchiq_log_warning(vchiq_susp_log_level, "%s failed too "
+ "many times - attempting suspend", __func__);
+ status = vchiq_arm_vcsuspend(state);
+ }
+ } else {
+ vchiq_log_info(vchiq_susp_log_level, "%s videocore suspend "
+ "in progress - wait for completion", __func__);
+ status = VCHIQ_SUCCESS;
+ }
+
+ /* Wait for suspend to happen due to system idle (not forced..) */
+ if (status != VCHIQ_SUCCESS)
+ goto unblock_resume;
+
+ do {
+ write_unlock_bh(&arm_state->susp_res_lock);
+
+ rc = wait_for_completion_interruptible_timeout(
+ &arm_state->vc_suspend_complete,
+ msecs_to_jiffies(FORCE_SUSPEND_TIMEOUT_MS));
+
+ write_lock_bh(&arm_state->susp_res_lock);
+ if (rc < 0) {
+ vchiq_log_warning(vchiq_susp_log_level, "%s "
+ "interrupted waiting for suspend", __func__);
+ status = VCHIQ_ERROR;
+ goto unblock_resume;
+ } else if (rc == 0) {
+ if (arm_state->vc_suspend_state > VC_SUSPEND_IDLE) {
+ /* Repeat timeout once if in progress */
+ if (repeat < 0) {
+ repeat = 1;
+ continue;
+ }
+ }
+ arm_state->autosuspend_override++;
+ output_timeout_error(state);
+
+ status = VCHIQ_RETRY;
+ goto unblock_resume;
+ }
+ } while (0 < (repeat--));
+
+ /* Check and report state in case we need to abort ARM suspend */
+ if (arm_state->vc_suspend_state != VC_SUSPEND_SUSPENDED) {
+ status = VCHIQ_RETRY;
+ vchiq_log_error(vchiq_susp_log_level,
+ "%s videocore suspend failed (state %s)", __func__,
+ suspend_state_names[arm_state->vc_suspend_state +
+ VC_SUSPEND_NUM_OFFSET]);
+ /* Reset the state only if it's still in an error state.
+ * Something could have already initiated another suspend. */
+ if (arm_state->vc_suspend_state < VC_SUSPEND_IDLE)
+ set_suspend_state(arm_state, VC_SUSPEND_IDLE);
+
+ goto unblock_resume;
+ }
+
+ /* successfully suspended - unlock and exit */
+ goto unlock;
+
+unblock_resume:
+ /* all error states need to unblock resume before exit */
+ unblock_resume(arm_state);
+
+unlock:
+ write_unlock_bh(&arm_state->susp_res_lock);
+
+out:
+ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, status);
+ return status;
+}
+
+void
+vchiq_check_suspend(VCHIQ_STATE_T *state)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+
+ if (!arm_state)
+ goto out;
+
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+
+ write_lock_bh(&arm_state->susp_res_lock);
+ if (arm_state->vc_suspend_state != VC_SUSPEND_SUSPENDED &&
+ arm_state->first_connect &&
+ !vchiq_videocore_wanted(state)) {
+ vchiq_arm_vcsuspend(state);
+ }
+ write_unlock_bh(&arm_state->susp_res_lock);
+
+out:
+ vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__);
+ return;
+}
+
+
+int
+vchiq_arm_allow_resume(VCHIQ_STATE_T *state)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ int resume = 0;
+ int ret = -1;
+
+ if (!arm_state)
+ goto out;
+
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+
+ write_lock_bh(&arm_state->susp_res_lock);
+ unblock_resume(arm_state);
+ resume = vchiq_check_resume(state);
+ write_unlock_bh(&arm_state->susp_res_lock);
+
+ if (resume) {
+ if (wait_for_completion_interruptible(
+ &arm_state->vc_resume_complete) < 0) {
+ vchiq_log_error(vchiq_susp_log_level,
+ "%s interrupted", __func__);
+ /* failed, cannot accurately derive suspend
+ * state, so exit early. */
+ goto out;
+ }
+ }
+
+ read_lock_bh(&arm_state->susp_res_lock);
+ if (arm_state->vc_suspend_state == VC_SUSPEND_SUSPENDED) {
+ vchiq_log_info(vchiq_susp_log_level,
+ "%s: Videocore remains suspended", __func__);
+ } else {
+ vchiq_log_info(vchiq_susp_log_level,
+ "%s: Videocore resumed", __func__);
+ ret = 0;
+ }
+ read_unlock_bh(&arm_state->susp_res_lock);
+out:
+ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret);
+ return ret;
+}
+
+/* This function should be called with the write lock held */
+int
+vchiq_check_resume(VCHIQ_STATE_T *state)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ int resume = 0;
+
+ if (!arm_state)
+ goto out;
+
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+
+ if (need_resume(state)) {
+ set_resume_state(arm_state, VC_RESUME_REQUESTED);
+ request_poll(state, NULL, 0);
+ resume = 1;
+ }
+
+out:
+ vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__);
+ return resume;
+}
+
+void
+vchiq_platform_check_resume(VCHIQ_STATE_T *state)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ int res = 0;
+
+ if (!arm_state)
+ goto out;
+
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+
+ write_lock_bh(&arm_state->susp_res_lock);
+ if (arm_state->wake_address == 0) {
+ vchiq_log_info(vchiq_susp_log_level,
+ "%s: already awake", __func__);
+ goto unlock;
+ }
+ if (arm_state->vc_resume_state == VC_RESUME_IN_PROGRESS) {
+ vchiq_log_info(vchiq_susp_log_level,
+ "%s: already resuming", __func__);
+ goto unlock;
+ }
+
+ if (arm_state->vc_resume_state == VC_RESUME_REQUESTED) {
+ set_resume_state(arm_state, VC_RESUME_IN_PROGRESS);
+ res = 1;
+ } else
+ vchiq_log_trace(vchiq_susp_log_level,
+ "%s: not resuming (resume state %s)", __func__,
+ resume_state_names[arm_state->vc_resume_state +
+ VC_RESUME_NUM_OFFSET]);
+
+unlock:
+ write_unlock_bh(&arm_state->susp_res_lock);
+
+ if (res)
+ vchiq_platform_resume(state);
+
+out:
+ vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__);
+ return;
+
+}
+
+
+
+VCHIQ_STATUS_T
+vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
+ enum USE_TYPE_E use_type)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ VCHIQ_STATUS_T ret = VCHIQ_SUCCESS;
+ char entity[16];
+ int *entity_uc;
+ int local_uc, local_entity_uc;
+
+ if (!arm_state)
+ goto out;
+
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+
+ if (use_type == USE_TYPE_VCHIQ) {
+ sprintf(entity, "VCHIQ: ");
+ entity_uc = &arm_state->peer_use_count;
+ } else if (service) {
+ sprintf(entity, "%c%c%c%c:%03d",
+ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
+ service->client_id);
+ entity_uc = &service->service_use_count;
+ } else {
+ vchiq_log_error(vchiq_susp_log_level, "%s null service "
+ "ptr", __func__);
+ ret = VCHIQ_ERROR;
+ goto out;
+ }
+
+ write_lock_bh(&arm_state->susp_res_lock);
+ while (arm_state->resume_blocked) {
+ /* If we call 'use' while force suspend is waiting for suspend,
+ * then we're about to block the thread which the force is
+ * waiting to complete, so we're bound to just time out. In this
+ * case, set the suspend state such that the wait will be
+ * canceled, so we can complete as quickly as possible. */
+ if (arm_state->resume_blocked && arm_state->vc_suspend_state ==
+ VC_SUSPEND_IDLE) {
+ set_suspend_state(arm_state, VC_SUSPEND_FORCE_CANCELED);
+ break;
+ }
+ /* If suspend is already in progress then we need to block */
+ if (!try_wait_for_completion(&arm_state->resume_blocker)) {
+ /* Indicate that there are threads waiting on the resume
+ * blocker. These need to be allowed to complete before
+ * a _second_ call to force suspend can complete,
+ * otherwise low priority threads might never actually
+ * continue */
+ arm_state->blocked_count++;
+ write_unlock_bh(&arm_state->susp_res_lock);
+ vchiq_log_info(vchiq_susp_log_level, "%s %s resume "
+ "blocked - waiting...", __func__, entity);
+ if (wait_for_completion_killable(
+ &arm_state->resume_blocker) != 0) {
+ vchiq_log_error(vchiq_susp_log_level, "%s %s "
+ "wait for resume blocker interrupted",
+ __func__, entity);
+ ret = VCHIQ_ERROR;
+ write_lock_bh(&arm_state->susp_res_lock);
+ arm_state->blocked_count--;
+ write_unlock_bh(&arm_state->susp_res_lock);
+ goto out;
+ }
+ vchiq_log_info(vchiq_susp_log_level, "%s %s resume "
+ "unblocked", __func__, entity);
+ write_lock_bh(&arm_state->susp_res_lock);
+ if (--arm_state->blocked_count == 0)
+ complete_all(&arm_state->blocked_blocker);
+ }
+ }
+
+ stop_suspend_timer(arm_state);
+
+ local_uc = ++arm_state->videocore_use_count;
+ local_entity_uc = ++(*entity_uc);
+
+ /* If there's a pending request which hasn't yet been serviced then
+ * just clear it. If we're past VC_SUSPEND_REQUESTED state then
+ * vc_resume_complete will block until we either resume or fail to
+ * suspend */
+ if (arm_state->vc_suspend_state <= VC_SUSPEND_REQUESTED)
+ set_suspend_state(arm_state, VC_SUSPEND_IDLE);
+
+ if ((use_type != USE_TYPE_SERVICE_NO_RESUME) && need_resume(state)) {
+ set_resume_state(arm_state, VC_RESUME_REQUESTED);
+ vchiq_log_info(vchiq_susp_log_level,
+ "%s %s count %d, state count %d",
+ __func__, entity, local_entity_uc, local_uc);
+ request_poll(state, NULL, 0);
+ } else
+ vchiq_log_trace(vchiq_susp_log_level,
+ "%s %s count %d, state count %d",
+ __func__, entity, *entity_uc, local_uc);
+
+
+ write_unlock_bh(&arm_state->susp_res_lock);
+
+ /* Completion is in a done state when we're not suspended, so this won't
+ * block for the non-suspended case. */
+ if (!try_wait_for_completion(&arm_state->vc_resume_complete)) {
+ vchiq_log_info(vchiq_susp_log_level, "%s %s wait for resume",
+ __func__, entity);
+ if (wait_for_completion_killable(
+ &arm_state->vc_resume_complete) != 0) {
+ vchiq_log_error(vchiq_susp_log_level, "%s %s wait for "
+ "resume interrupted", __func__, entity);
+ ret = VCHIQ_ERROR;
+ goto out;
+ }
+ vchiq_log_info(vchiq_susp_log_level, "%s %s resumed", __func__,
+ entity);
+ }
+
+ if (ret == VCHIQ_SUCCESS) {
+ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+ long ack_cnt = atomic_xchg(&arm_state->ka_use_ack_count, 0);
+ while (ack_cnt && (status == VCHIQ_SUCCESS)) {
+ /* Send the use notify to videocore */
+ status = vchiq_send_remote_use_active(state);
+ if (status == VCHIQ_SUCCESS)
+ ack_cnt--;
+ else
+ atomic_add(ack_cnt,
+ &arm_state->ka_use_ack_count);
+ }
+ }
+
+out:
+ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret);
+ return ret;
+}
+
+VCHIQ_STATUS_T
+vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ VCHIQ_STATUS_T ret = VCHIQ_SUCCESS;
+ char entity[16];
+ int *entity_uc;
+ int local_uc, local_entity_uc;
+
+ if (!arm_state)
+ goto out;
+
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+
+ if (service) {
+ sprintf(entity, "%c%c%c%c:%03d",
+ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
+ service->client_id);
+ entity_uc = &service->service_use_count;
+ } else {
+ sprintf(entity, "PEER: ");
+ entity_uc = &arm_state->peer_use_count;
+ }
+
+ write_lock_bh(&arm_state->susp_res_lock);
+ if (!arm_state->videocore_use_count || !(*entity_uc)) {
+ /* Don't use BUG_ON - don't allow user thread to crash kernel */
+ WARN_ON(!arm_state->videocore_use_count);
+ WARN_ON(!(*entity_uc));
+ ret = VCHIQ_ERROR;
+ goto unlock;
+ }
+ local_uc = --arm_state->videocore_use_count;
+ local_entity_uc = --(*entity_uc);
+
+ if (!vchiq_videocore_wanted(state)) {
+ if (vchiq_platform_use_suspend_timer() &&
+ !arm_state->resume_blocked) {
+ /* Only use the timer if we're not trying to force
+ * suspend (=> resume_blocked) */
+ start_suspend_timer(arm_state);
+ } else {
+ vchiq_log_info(vchiq_susp_log_level,
+ "%s %s count %d, state count %d - suspending",
+ __func__, entity, *entity_uc,
+ arm_state->videocore_use_count);
+ vchiq_arm_vcsuspend(state);
+ }
+ } else
+ vchiq_log_trace(vchiq_susp_log_level,
+ "%s %s count %d, state count %d",
+ __func__, entity, *entity_uc,
+ arm_state->videocore_use_count);
+
+unlock:
+ write_unlock_bh(&arm_state->susp_res_lock);
+
+out:
+ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret);
+ return ret;
+}
+
+void
+vchiq_on_remote_use(VCHIQ_STATE_T *state)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+ atomic_inc(&arm_state->ka_use_count);
+ complete(&arm_state->ka_evt);
+}
+
+void
+vchiq_on_remote_release(VCHIQ_STATE_T *state)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+ atomic_inc(&arm_state->ka_release_count);
+ complete(&arm_state->ka_evt);
+}
+
+VCHIQ_STATUS_T
+vchiq_use_service_internal(VCHIQ_SERVICE_T *service)
+{
+ return vchiq_use_internal(service->state, service, USE_TYPE_SERVICE);
+}
+
+VCHIQ_STATUS_T
+vchiq_release_service_internal(VCHIQ_SERVICE_T *service)
+{
+ return vchiq_release_internal(service->state, service);
+}
+
+VCHIQ_DEBUGFS_NODE_T *
+vchiq_instance_get_debugfs_node(VCHIQ_INSTANCE_T instance)
+{
+ return &instance->debugfs_node;
+}
+
+int
+vchiq_instance_get_use_count(VCHIQ_INSTANCE_T instance)
+{
+ VCHIQ_SERVICE_T *service;
+ int use_count = 0, i;
+ i = 0;
+ while ((service = next_service_by_instance(instance->state,
+ instance, &i)) != NULL) {
+ use_count += service->service_use_count;
+ unlock_service(service);
+ }
+ return use_count;
+}
+
+int
+vchiq_instance_get_pid(VCHIQ_INSTANCE_T instance)
+{
+ return instance->pid;
+}
+
+int
+vchiq_instance_get_trace(VCHIQ_INSTANCE_T instance)
+{
+ return instance->trace;
+}
+
+void
+vchiq_instance_set_trace(VCHIQ_INSTANCE_T instance, int trace)
+{
+ VCHIQ_SERVICE_T *service;
+ int i;
+ i = 0;
+ while ((service = next_service_by_instance(instance->state,
+ instance, &i)) != NULL) {
+ service->trace = trace;
+ unlock_service(service);
+ }
+ instance->trace = (trace != 0);
+}
+
+static void suspend_timer_callback(unsigned long context)
+{
+ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *)context;
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ if (!arm_state)
+ goto out;
+ vchiq_log_info(vchiq_susp_log_level,
+ "%s - suspend timer expired - check suspend", __func__);
+ vchiq_check_suspend(state);
+out:
+ return;
+}
+
+VCHIQ_STATUS_T
+vchiq_use_service_no_resume(VCHIQ_SERVICE_HANDLE_T handle)
+{
+ VCHIQ_STATUS_T ret = VCHIQ_ERROR;
+ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ if (service) {
+ ret = vchiq_use_internal(service->state, service,
+ USE_TYPE_SERVICE_NO_RESUME);
+ unlock_service(service);
+ }
+ return ret;
+}
+
+VCHIQ_STATUS_T
+vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle)
+{
+ VCHIQ_STATUS_T ret = VCHIQ_ERROR;
+ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ if (service) {
+ ret = vchiq_use_internal(service->state, service,
+ USE_TYPE_SERVICE);
+ unlock_service(service);
+ }
+ return ret;
+}
+
+VCHIQ_STATUS_T
+vchiq_release_service(VCHIQ_SERVICE_HANDLE_T handle)
+{
+ VCHIQ_STATUS_T ret = VCHIQ_ERROR;
+ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ if (service) {
+ ret = vchiq_release_internal(service->state, service);
+ unlock_service(service);
+ }
+ return ret;
+}
+
+void
+vchiq_dump_service_use_state(VCHIQ_STATE_T *state)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ int i, j = 0;
+ /* Only dump 64 services */
+ static const int local_max_services = 64;
+ /* If there's more than 64 services, only dump ones with
+ * non-zero counts */
+ int only_nonzero = 0;
+ static const char *nz = "<-- preventing suspend";
+
+ enum vc_suspend_status vc_suspend_state;
+ enum vc_resume_status vc_resume_state;
+ int peer_count;
+ int vc_use_count;
+ int active_services;
+ struct service_data_struct {
+ int fourcc;
+ int clientid;
+ int use_count;
+ } service_data[local_max_services];
+
+ if (!arm_state)
+ return;
+
+ read_lock_bh(&arm_state->susp_res_lock);
+ vc_suspend_state = arm_state->vc_suspend_state;
+ vc_resume_state = arm_state->vc_resume_state;
+ peer_count = arm_state->peer_use_count;
+ vc_use_count = arm_state->videocore_use_count;
+ active_services = state->unused_service;
+ if (active_services > local_max_services)
+ only_nonzero = 1;
+
+ for (i = 0; (i < active_services) && (j < local_max_services); i++) {
+ VCHIQ_SERVICE_T *service_ptr = state->services[i];
+ if (!service_ptr)
+ continue;
+
+ if (only_nonzero && !service_ptr->service_use_count)
+ continue;
+
+ if (service_ptr->srvstate != VCHIQ_SRVSTATE_FREE) {
+ service_data[j].fourcc = service_ptr->base.fourcc;
+ service_data[j].clientid = service_ptr->client_id;
+ service_data[j++].use_count = service_ptr->
+ service_use_count;
+ }
+ }
+
+ read_unlock_bh(&arm_state->susp_res_lock);
+
+ vchiq_log_warning(vchiq_susp_log_level,
+ "-- Videcore suspend state: %s --",
+ suspend_state_names[vc_suspend_state + VC_SUSPEND_NUM_OFFSET]);
+ vchiq_log_warning(vchiq_susp_log_level,
+ "-- Videcore resume state: %s --",
+ resume_state_names[vc_resume_state + VC_RESUME_NUM_OFFSET]);
+
+ if (only_nonzero)
+ vchiq_log_warning(vchiq_susp_log_level, "Too many active "
+ "services (%d). Only dumping up to first %d services "
+ "with non-zero use-count", active_services,
+ local_max_services);
+
+ for (i = 0; i < j; i++) {
+ vchiq_log_warning(vchiq_susp_log_level,
+ "----- %c%c%c%c:%d service count %d %s",
+ VCHIQ_FOURCC_AS_4CHARS(service_data[i].fourcc),
+ service_data[i].clientid,
+ service_data[i].use_count,
+ service_data[i].use_count ? nz : "");
+ }
+ vchiq_log_warning(vchiq_susp_log_level,
+ "----- VCHIQ use count count %d", peer_count);
+ vchiq_log_warning(vchiq_susp_log_level,
+ "--- Overall vchiq instance use count %d", vc_use_count);
+
+ vchiq_dump_platform_use_state(state);
+}
+
+VCHIQ_STATUS_T
+vchiq_check_service(VCHIQ_SERVICE_T *service)
+{
+ VCHIQ_ARM_STATE_T *arm_state;
+ VCHIQ_STATUS_T ret = VCHIQ_ERROR;
+
+ if (!service || !service->state)
+ goto out;
+
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+
+ arm_state = vchiq_platform_get_arm_state(service->state);
+
+ read_lock_bh(&arm_state->susp_res_lock);
+ if (service->service_use_count)
+ ret = VCHIQ_SUCCESS;
+ read_unlock_bh(&arm_state->susp_res_lock);
+
+ if (ret == VCHIQ_ERROR) {
+ vchiq_log_error(vchiq_susp_log_level,
+ "%s ERROR - %c%c%c%c:%d service count %d, "
+ "state count %d, videocore suspend state %s", __func__,
+ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
+ service->client_id, service->service_use_count,
+ arm_state->videocore_use_count,
+ suspend_state_names[arm_state->vc_suspend_state +
+ VC_SUSPEND_NUM_OFFSET]);
+ vchiq_dump_service_use_state(service->state);
+ }
+out:
+ return ret;
+}
+
+/* stub functions */
+void vchiq_on_remote_use_active(VCHIQ_STATE_T *state)
+{
+ (void)state;
+}
+
+void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state,
+ VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate)
+{
+ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+ vchiq_log_info(vchiq_susp_log_level, "%d: %s->%s", state->id,
+ get_conn_state_name(oldstate), get_conn_state_name(newstate));
+ if (state->conn_state == VCHIQ_CONNSTATE_CONNECTED) {
+ write_lock_bh(&arm_state->susp_res_lock);
+ if (!arm_state->first_connect) {
+ char threadname[10];
+ arm_state->first_connect = 1;
+ write_unlock_bh(&arm_state->susp_res_lock);
+ snprintf(threadname, sizeof(threadname), "VCHIQka-%d",
+ state->id);
+ arm_state->ka_thread = kthread_create(
+ &vchiq_keepalive_thread_func,
+ (void *)state,
+ threadname);
+ if (arm_state->ka_thread == NULL) {
+ vchiq_log_error(vchiq_susp_log_level,
+ "vchiq: FATAL: couldn't create thread %s",
+ threadname);
+ } else {
+ wake_up_process(arm_state->ka_thread);
+ }
+ } else
+ write_unlock_bh(&arm_state->susp_res_lock);
+ }
+}
+
+static int vchiq_probe(struct platform_device *pdev)
+{
+ struct device_node *fw_node;
+ struct rpi_firmware *fw;
+ int err;
+ void *ptr_err;
+
+ fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0);
+/* Remove comment when booting without Device Tree is no longer supported
+ if (!fw_node) {
+ dev_err(&pdev->dev, "Missing firmware node\n");
+ return -ENOENT;
+ }
+*/
+ fw = rpi_firmware_get(fw_node);
+ if (!fw)
+ return -EPROBE_DEFER;
+
+ platform_set_drvdata(pdev, fw);
+
+ /* create debugfs entries */
+ err = vchiq_debugfs_init();
+ if (err != 0)
+ goto failed_debugfs_init;
+
+ err = alloc_chrdev_region(&vchiq_devid, VCHIQ_MINOR, 1, DEVICE_NAME);
+ if (err != 0) {
+ vchiq_log_error(vchiq_arm_log_level,
+ "Unable to allocate device number");
+ goto failed_alloc_chrdev;
+ }
+ cdev_init(&vchiq_cdev, &vchiq_fops);
+ vchiq_cdev.owner = THIS_MODULE;
+ err = cdev_add(&vchiq_cdev, vchiq_devid, 1);
+ if (err != 0) {
+ vchiq_log_error(vchiq_arm_log_level,
+ "Unable to register device");
+ goto failed_cdev_add;
+ }
+
+ /* create sysfs entries */
+ vchiq_class = class_create(THIS_MODULE, DEVICE_NAME);
+ ptr_err = vchiq_class;
+ if (IS_ERR(ptr_err))
+ goto failed_class_create;
+
+ vchiq_dev = device_create(vchiq_class, NULL,
+ vchiq_devid, NULL, "vchiq");
+ ptr_err = vchiq_dev;
+ if (IS_ERR(ptr_err))
+ goto failed_device_create;
+
+ err = vchiq_platform_init(pdev, &g_state);
+ if (err != 0)
+ goto failed_platform_init;
+
+ vchiq_log_info(vchiq_arm_log_level,
+ "vchiq: initialised - version %d (min %d), device %d.%d",
+ VCHIQ_VERSION, VCHIQ_VERSION_MIN,
+ MAJOR(vchiq_devid), MINOR(vchiq_devid));
+
+ return 0;
+
+failed_platform_init:
+ device_destroy(vchiq_class, vchiq_devid);
+failed_device_create:
+ class_destroy(vchiq_class);
+failed_class_create:
+ cdev_del(&vchiq_cdev);
+ err = PTR_ERR(ptr_err);
+failed_cdev_add:
+ unregister_chrdev_region(vchiq_devid, 1);
+failed_alloc_chrdev:
+ vchiq_debugfs_deinit();
+failed_debugfs_init:
+ vchiq_log_warning(vchiq_arm_log_level, "could not load vchiq");
+ return err;
+}
+
+static int vchiq_remove(struct platform_device *pdev)
+{
+ device_destroy(vchiq_class, vchiq_devid);
+ class_destroy(vchiq_class);
+ cdev_del(&vchiq_cdev);
+ unregister_chrdev_region(vchiq_devid, 1);
+
+ return 0;
+}
+
+static const struct of_device_id vchiq_of_match[] = {
+ { .compatible = "brcm,bcm2835-vchiq", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, vchiq_of_match);
+
+static struct platform_driver vchiq_driver = {
+ .driver = {
+ .name = "bcm2835_vchiq",
+ .owner = THIS_MODULE,
+ .of_match_table = vchiq_of_match,
+ },
+ .probe = vchiq_probe,
+ .remove = vchiq_remove,
+};
+module_platform_driver(vchiq_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Broadcom Corporation");
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
new file mode 100644
index 000000000000..9740e1afbc9d
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
@@ -0,0 +1,220 @@
+/**
+ * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_ARM_H
+#define VCHIQ_ARM_H
+
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/semaphore.h>
+#include <linux/atomic.h>
+#include "vchiq_core.h"
+#include "vchiq_debugfs.h"
+
+
+enum vc_suspend_status {
+ VC_SUSPEND_FORCE_CANCELED = -3, /* Force suspend canceled, too busy */
+ VC_SUSPEND_REJECTED = -2, /* Videocore rejected suspend request */
+ VC_SUSPEND_FAILED = -1, /* Videocore suspend failed */
+ VC_SUSPEND_IDLE = 0, /* VC active, no suspend actions */
+ VC_SUSPEND_REQUESTED, /* User has requested suspend */
+ VC_SUSPEND_IN_PROGRESS, /* Slot handler has recvd suspend request */
+ VC_SUSPEND_SUSPENDED /* Videocore suspend succeeded */
+};
+
+enum vc_resume_status {
+ VC_RESUME_FAILED = -1, /* Videocore resume failed */
+ VC_RESUME_IDLE = 0, /* VC suspended, no resume actions */
+ VC_RESUME_REQUESTED, /* User has requested resume */
+ VC_RESUME_IN_PROGRESS, /* Slot handler has received resume request */
+ VC_RESUME_RESUMED /* Videocore resumed successfully (active) */
+};
+
+
+enum USE_TYPE_E {
+ USE_TYPE_SERVICE,
+ USE_TYPE_SERVICE_NO_RESUME,
+ USE_TYPE_VCHIQ
+};
+
+
+
+typedef struct vchiq_arm_state_struct {
+ /* Keepalive-related data */
+ struct task_struct *ka_thread;
+ struct completion ka_evt;
+ atomic_t ka_use_count;
+ atomic_t ka_use_ack_count;
+ atomic_t ka_release_count;
+
+ struct completion vc_suspend_complete;
+ struct completion vc_resume_complete;
+
+ rwlock_t susp_res_lock;
+ enum vc_suspend_status vc_suspend_state;
+ enum vc_resume_status vc_resume_state;
+
+ unsigned int wake_address;
+
+ struct timer_list suspend_timer;
+ int suspend_timer_timeout;
+ int suspend_timer_running;
+
+ /* Global use count for videocore.
+ ** This is equal to the sum of the use counts for all services. When
+ ** this hits zero the videocore suspend procedure will be initiated.
+ */
+ int videocore_use_count;
+
+ /* Use count to track requests from videocore peer.
+ ** This use count is not associated with a service, so needs to be
+ ** tracked separately with the state.
+ */
+ int peer_use_count;
+
+ /* Flag to indicate whether resume is blocked. This happens when the
+ ** ARM is suspending
+ */
+ struct completion resume_blocker;
+ int resume_blocked;
+ struct completion blocked_blocker;
+ int blocked_count;
+
+ int autosuspend_override;
+
+ /* Flag to indicate that the first vchiq connect has made it through.
+ ** This means that both sides should be fully ready, and we should
+ ** be able to suspend after this point.
+ */
+ int first_connect;
+
+ unsigned long long suspend_start_time;
+ unsigned long long sleep_start_time;
+ unsigned long long resume_start_time;
+ unsigned long long last_wake_time;
+
+} VCHIQ_ARM_STATE_T;
+
+extern int vchiq_arm_log_level;
+extern int vchiq_susp_log_level;
+
+int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state);
+
+extern VCHIQ_STATE_T *
+vchiq_get_state(void);
+
+extern VCHIQ_STATUS_T
+vchiq_arm_vcsuspend(VCHIQ_STATE_T *state);
+
+extern VCHIQ_STATUS_T
+vchiq_arm_force_suspend(VCHIQ_STATE_T *state);
+
+extern int
+vchiq_arm_allow_resume(VCHIQ_STATE_T *state);
+
+extern VCHIQ_STATUS_T
+vchiq_arm_vcresume(VCHIQ_STATE_T *state);
+
+extern VCHIQ_STATUS_T
+vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state);
+
+extern int
+vchiq_check_resume(VCHIQ_STATE_T *state);
+
+extern void
+vchiq_check_suspend(VCHIQ_STATE_T *state);
+ VCHIQ_STATUS_T
+vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle);
+
+extern VCHIQ_STATUS_T
+vchiq_release_service(VCHIQ_SERVICE_HANDLE_T handle);
+
+extern VCHIQ_STATUS_T
+vchiq_check_service(VCHIQ_SERVICE_T *service);
+
+extern VCHIQ_STATUS_T
+vchiq_platform_suspend(VCHIQ_STATE_T *state);
+
+extern int
+vchiq_platform_videocore_wanted(VCHIQ_STATE_T *state);
+
+extern int
+vchiq_platform_use_suspend_timer(void);
+
+extern void
+vchiq_dump_platform_use_state(VCHIQ_STATE_T *state);
+
+extern void
+vchiq_dump_service_use_state(VCHIQ_STATE_T *state);
+
+extern VCHIQ_ARM_STATE_T*
+vchiq_platform_get_arm_state(VCHIQ_STATE_T *state);
+
+extern int
+vchiq_videocore_wanted(VCHIQ_STATE_T *state);
+
+extern VCHIQ_STATUS_T
+vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
+ enum USE_TYPE_E use_type);
+extern VCHIQ_STATUS_T
+vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service);
+
+extern VCHIQ_DEBUGFS_NODE_T *
+vchiq_instance_get_debugfs_node(VCHIQ_INSTANCE_T instance);
+
+extern int
+vchiq_instance_get_use_count(VCHIQ_INSTANCE_T instance);
+
+extern int
+vchiq_instance_get_pid(VCHIQ_INSTANCE_T instance);
+
+extern int
+vchiq_instance_get_trace(VCHIQ_INSTANCE_T instance);
+
+extern void
+vchiq_instance_set_trace(VCHIQ_INSTANCE_T instance, int trace);
+
+extern void
+set_suspend_state(VCHIQ_ARM_STATE_T *arm_state,
+ enum vc_suspend_status new_state);
+
+extern void
+set_resume_state(VCHIQ_ARM_STATE_T *arm_state,
+ enum vc_resume_status new_state);
+
+extern void
+start_suspend_timer(VCHIQ_ARM_STATE_T *arm_state);
+
+
+#endif /* VCHIQ_ARM_H */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_build_info.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_build_info.h
new file mode 100644
index 000000000000..df645813bdae
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_build_info.h
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+const char *vchiq_get_build_hostname(void);
+const char *vchiq_get_build_version(void);
+const char *vchiq_get_build_time(void);
+const char *vchiq_get_build_date(void);
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_cfg.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_cfg.h
new file mode 100644
index 000000000000..d2797db702f9
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_cfg.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2010-2014 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_CFG_H
+#define VCHIQ_CFG_H
+
+#define VCHIQ_MAGIC VCHIQ_MAKE_FOURCC('V', 'C', 'H', 'I')
+/* The version of VCHIQ - change with any non-trivial change */
+#define VCHIQ_VERSION 8
+/* The minimum compatible version - update to match VCHIQ_VERSION with any
+** incompatible change */
+#define VCHIQ_VERSION_MIN 3
+
+/* The version that introduced the VCHIQ_IOC_LIB_VERSION ioctl */
+#define VCHIQ_VERSION_LIB_VERSION 7
+
+/* The version that introduced the VCHIQ_IOC_CLOSE_DELIVERED ioctl */
+#define VCHIQ_VERSION_CLOSE_DELIVERED 7
+
+/* The version that made it safe to use SYNCHRONOUS mode */
+#define VCHIQ_VERSION_SYNCHRONOUS_MODE 8
+
+#define VCHIQ_MAX_STATES 1
+#define VCHIQ_MAX_SERVICES 4096
+#define VCHIQ_MAX_SLOTS 128
+#define VCHIQ_MAX_SLOTS_PER_SIDE 64
+
+#define VCHIQ_NUM_CURRENT_BULKS 32
+#define VCHIQ_NUM_SERVICE_BULKS 4
+
+#ifndef VCHIQ_ENABLE_DEBUG
+#define VCHIQ_ENABLE_DEBUG 1
+#endif
+
+#ifndef VCHIQ_ENABLE_STATS
+#define VCHIQ_ENABLE_STATS 1
+#endif
+
+#endif /* VCHIQ_CFG_H */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c
new file mode 100644
index 000000000000..5efc62ffb2f5
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "vchiq_connected.h"
+#include "vchiq_core.h"
+#include "vchiq_killable.h"
+#include <linux/module.h>
+#include <linux/mutex.h>
+
+#define MAX_CALLBACKS 10
+
+static int g_connected;
+static int g_num_deferred_callbacks;
+static VCHIQ_CONNECTED_CALLBACK_T g_deferred_callback[MAX_CALLBACKS];
+static int g_once_init;
+static struct mutex g_connected_mutex;
+
+/****************************************************************************
+*
+* Function to initialize our lock.
+*
+***************************************************************************/
+
+static void connected_init(void)
+{
+ if (!g_once_init) {
+ mutex_init(&g_connected_mutex);
+ g_once_init = 1;
+ }
+}
+
+/****************************************************************************
+*
+* This function is used to defer initialization until the vchiq stack is
+* initialized. If the stack is already initialized, then the callback will
+* be made immediately, otherwise it will be deferred until
+* vchiq_call_connected_callbacks is called.
+*
+***************************************************************************/
+
+void vchiq_add_connected_callback(VCHIQ_CONNECTED_CALLBACK_T callback)
+{
+ connected_init();
+
+ if (mutex_lock_interruptible(&g_connected_mutex) != 0)
+ return;
+
+ if (g_connected)
+ /* We're already connected. Call the callback immediately. */
+
+ callback();
+ else {
+ if (g_num_deferred_callbacks >= MAX_CALLBACKS)
+ vchiq_log_error(vchiq_core_log_level,
+ "There already %d callback registered - "
+ "please increase MAX_CALLBACKS",
+ g_num_deferred_callbacks);
+ else {
+ g_deferred_callback[g_num_deferred_callbacks] =
+ callback;
+ g_num_deferred_callbacks++;
+ }
+ }
+ mutex_unlock(&g_connected_mutex);
+}
+
+/****************************************************************************
+*
+* This function is called by the vchiq stack once it has been connected to
+* the videocore and clients can start to use the stack.
+*
+***************************************************************************/
+
+void vchiq_call_connected_callbacks(void)
+{
+ int i;
+
+ connected_init();
+
+ if (mutex_lock_interruptible(&g_connected_mutex) != 0)
+ return;
+
+ for (i = 0; i < g_num_deferred_callbacks; i++)
+ g_deferred_callback[i]();
+
+ g_num_deferred_callbacks = 0;
+ g_connected = 1;
+ mutex_unlock(&g_connected_mutex);
+}
+EXPORT_SYMBOL(vchiq_add_connected_callback);
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.h
new file mode 100644
index 000000000000..863b3e335c1a
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.h
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_CONNECTED_H
+#define VCHIQ_CONNECTED_H
+
+/* ---- Include Files ----------------------------------------------------- */
+
+/* ---- Constants and Types ---------------------------------------------- */
+
+typedef void (*VCHIQ_CONNECTED_CALLBACK_T)(void);
+
+/* ---- Variable Externs ------------------------------------------------- */
+
+/* ---- Function Prototypes ---------------------------------------------- */
+
+void vchiq_add_connected_callback(VCHIQ_CONNECTED_CALLBACK_T callback);
+void vchiq_call_connected_callbacks(void);
+
+#endif /* VCHIQ_CONNECTED_H */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
new file mode 100644
index 000000000000..2c98da4307df
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
@@ -0,0 +1,3934 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "vchiq_core.h"
+#include "vchiq_killable.h"
+
+#define VCHIQ_SLOT_HANDLER_STACK 8192
+
+#define HANDLE_STATE_SHIFT 12
+
+#define SLOT_INFO_FROM_INDEX(state, index) (state->slot_info + (index))
+#define SLOT_DATA_FROM_INDEX(state, index) (state->slot_data + (index))
+#define SLOT_INDEX_FROM_DATA(state, data) \
+ (((unsigned int)((char *)data - (char *)state->slot_data)) / \
+ VCHIQ_SLOT_SIZE)
+#define SLOT_INDEX_FROM_INFO(state, info) \
+ ((unsigned int)(info - state->slot_info))
+#define SLOT_QUEUE_INDEX_FROM_POS(pos) \
+ ((int)((unsigned int)(pos) / VCHIQ_SLOT_SIZE))
+
+#define BULK_INDEX(x) (x & (VCHIQ_NUM_SERVICE_BULKS - 1))
+
+#define SRVTRACE_LEVEL(srv) \
+ (((srv) && (srv)->trace) ? VCHIQ_LOG_TRACE : vchiq_core_msg_log_level)
+#define SRVTRACE_ENABLED(srv, lev) \
+ (((srv) && (srv)->trace) || (vchiq_core_msg_log_level >= (lev)))
+
+struct vchiq_open_payload {
+ int fourcc;
+ int client_id;
+ short version;
+ short version_min;
+};
+
+struct vchiq_openack_payload {
+ short version;
+};
+
+enum
+{
+ QMFLAGS_IS_BLOCKING = (1 << 0),
+ QMFLAGS_NO_MUTEX_LOCK = (1 << 1),
+ QMFLAGS_NO_MUTEX_UNLOCK = (1 << 2)
+};
+
+/* we require this for consistency between endpoints */
+vchiq_static_assert(sizeof(VCHIQ_HEADER_T) == 8);
+vchiq_static_assert(IS_POW2(sizeof(VCHIQ_HEADER_T)));
+vchiq_static_assert(IS_POW2(VCHIQ_NUM_CURRENT_BULKS));
+vchiq_static_assert(IS_POW2(VCHIQ_NUM_SERVICE_BULKS));
+vchiq_static_assert(IS_POW2(VCHIQ_MAX_SERVICES));
+vchiq_static_assert(VCHIQ_VERSION >= VCHIQ_VERSION_MIN);
+
+/* Run time control of log level, based on KERN_XXX level. */
+int vchiq_core_log_level = VCHIQ_LOG_DEFAULT;
+int vchiq_core_msg_log_level = VCHIQ_LOG_DEFAULT;
+int vchiq_sync_log_level = VCHIQ_LOG_DEFAULT;
+
+static atomic_t pause_bulks_count = ATOMIC_INIT(0);
+
+static DEFINE_SPINLOCK(service_spinlock);
+DEFINE_SPINLOCK(bulk_waiter_spinlock);
+DEFINE_SPINLOCK(quota_spinlock);
+
+VCHIQ_STATE_T *vchiq_states[VCHIQ_MAX_STATES];
+static unsigned int handle_seq;
+
+static const char *const srvstate_names[] = {
+ "FREE",
+ "HIDDEN",
+ "LISTENING",
+ "OPENING",
+ "OPEN",
+ "OPENSYNC",
+ "CLOSESENT",
+ "CLOSERECVD",
+ "CLOSEWAIT",
+ "CLOSED"
+};
+
+static const char *const reason_names[] = {
+ "SERVICE_OPENED",
+ "SERVICE_CLOSED",
+ "MESSAGE_AVAILABLE",
+ "BULK_TRANSMIT_DONE",
+ "BULK_RECEIVE_DONE",
+ "BULK_TRANSMIT_ABORTED",
+ "BULK_RECEIVE_ABORTED"
+};
+
+static const char *const conn_state_names[] = {
+ "DISCONNECTED",
+ "CONNECTING",
+ "CONNECTED",
+ "PAUSING",
+ "PAUSE_SENT",
+ "PAUSED",
+ "RESUMING",
+ "PAUSE_TIMEOUT",
+ "RESUME_TIMEOUT"
+};
+
+
+static void
+release_message_sync(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header);
+
+static const char *msg_type_str(unsigned int msg_type)
+{
+ switch (msg_type) {
+ case VCHIQ_MSG_PADDING: return "PADDING";
+ case VCHIQ_MSG_CONNECT: return "CONNECT";
+ case VCHIQ_MSG_OPEN: return "OPEN";
+ case VCHIQ_MSG_OPENACK: return "OPENACK";
+ case VCHIQ_MSG_CLOSE: return "CLOSE";
+ case VCHIQ_MSG_DATA: return "DATA";
+ case VCHIQ_MSG_BULK_RX: return "BULK_RX";
+ case VCHIQ_MSG_BULK_TX: return "BULK_TX";
+ case VCHIQ_MSG_BULK_RX_DONE: return "BULK_RX_DONE";
+ case VCHIQ_MSG_BULK_TX_DONE: return "BULK_TX_DONE";
+ case VCHIQ_MSG_PAUSE: return "PAUSE";
+ case VCHIQ_MSG_RESUME: return "RESUME";
+ case VCHIQ_MSG_REMOTE_USE: return "REMOTE_USE";
+ case VCHIQ_MSG_REMOTE_RELEASE: return "REMOTE_RELEASE";
+ case VCHIQ_MSG_REMOTE_USE_ACTIVE: return "REMOTE_USE_ACTIVE";
+ }
+ return "???";
+}
+
+static inline void
+vchiq_set_service_state(VCHIQ_SERVICE_T *service, int newstate)
+{
+ vchiq_log_info(vchiq_core_log_level, "%d: srv:%d %s->%s",
+ service->state->id, service->localport,
+ srvstate_names[service->srvstate],
+ srvstate_names[newstate]);
+ service->srvstate = newstate;
+}
+
+VCHIQ_SERVICE_T *
+find_service_by_handle(VCHIQ_SERVICE_HANDLE_T handle)
+{
+ VCHIQ_SERVICE_T *service;
+
+ spin_lock(&service_spinlock);
+ service = handle_to_service(handle);
+ if (service && (service->srvstate != VCHIQ_SRVSTATE_FREE) &&
+ (service->handle == handle)) {
+ BUG_ON(service->ref_count == 0);
+ service->ref_count++;
+ } else
+ service = NULL;
+ spin_unlock(&service_spinlock);
+
+ if (!service)
+ vchiq_log_info(vchiq_core_log_level,
+ "Invalid service handle 0x%x", handle);
+
+ return service;
+}
+
+VCHIQ_SERVICE_T *
+find_service_by_port(VCHIQ_STATE_T *state, int localport)
+{
+ VCHIQ_SERVICE_T *service = NULL;
+ if ((unsigned int)localport <= VCHIQ_PORT_MAX) {
+ spin_lock(&service_spinlock);
+ service = state->services[localport];
+ if (service && (service->srvstate != VCHIQ_SRVSTATE_FREE)) {
+ BUG_ON(service->ref_count == 0);
+ service->ref_count++;
+ } else
+ service = NULL;
+ spin_unlock(&service_spinlock);
+ }
+
+ if (!service)
+ vchiq_log_info(vchiq_core_log_level,
+ "Invalid port %d", localport);
+
+ return service;
+}
+
+VCHIQ_SERVICE_T *
+find_service_for_instance(VCHIQ_INSTANCE_T instance,
+ VCHIQ_SERVICE_HANDLE_T handle) {
+ VCHIQ_SERVICE_T *service;
+
+ spin_lock(&service_spinlock);
+ service = handle_to_service(handle);
+ if (service && (service->srvstate != VCHIQ_SRVSTATE_FREE) &&
+ (service->handle == handle) &&
+ (service->instance == instance)) {
+ BUG_ON(service->ref_count == 0);
+ service->ref_count++;
+ } else
+ service = NULL;
+ spin_unlock(&service_spinlock);
+
+ if (!service)
+ vchiq_log_info(vchiq_core_log_level,
+ "Invalid service handle 0x%x", handle);
+
+ return service;
+}
+
+VCHIQ_SERVICE_T *
+find_closed_service_for_instance(VCHIQ_INSTANCE_T instance,
+ VCHIQ_SERVICE_HANDLE_T handle) {
+ VCHIQ_SERVICE_T *service;
+
+ spin_lock(&service_spinlock);
+ service = handle_to_service(handle);
+ if (service &&
+ ((service->srvstate == VCHIQ_SRVSTATE_FREE) ||
+ (service->srvstate == VCHIQ_SRVSTATE_CLOSED)) &&
+ (service->handle == handle) &&
+ (service->instance == instance)) {
+ BUG_ON(service->ref_count == 0);
+ service->ref_count++;
+ } else
+ service = NULL;
+ spin_unlock(&service_spinlock);
+
+ if (!service)
+ vchiq_log_info(vchiq_core_log_level,
+ "Invalid service handle 0x%x", handle);
+
+ return service;
+}
+
+VCHIQ_SERVICE_T *
+next_service_by_instance(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance,
+ int *pidx)
+{
+ VCHIQ_SERVICE_T *service = NULL;
+ int idx = *pidx;
+
+ spin_lock(&service_spinlock);
+ while (idx < state->unused_service) {
+ VCHIQ_SERVICE_T *srv = state->services[idx++];
+ if (srv && (srv->srvstate != VCHIQ_SRVSTATE_FREE) &&
+ (srv->instance == instance)) {
+ service = srv;
+ BUG_ON(service->ref_count == 0);
+ service->ref_count++;
+ break;
+ }
+ }
+ spin_unlock(&service_spinlock);
+
+ *pidx = idx;
+
+ return service;
+}
+
+void
+lock_service(VCHIQ_SERVICE_T *service)
+{
+ spin_lock(&service_spinlock);
+ BUG_ON(!service || (service->ref_count == 0));
+ if (service)
+ service->ref_count++;
+ spin_unlock(&service_spinlock);
+}
+
+void
+unlock_service(VCHIQ_SERVICE_T *service)
+{
+ VCHIQ_STATE_T *state = service->state;
+ spin_lock(&service_spinlock);
+ BUG_ON(!service || (service->ref_count == 0));
+ if (service && service->ref_count) {
+ service->ref_count--;
+ if (!service->ref_count) {
+ BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE);
+ state->services[service->localport] = NULL;
+ } else
+ service = NULL;
+ }
+ spin_unlock(&service_spinlock);
+
+ if (service && service->userdata_term)
+ service->userdata_term(service->base.userdata);
+
+ kfree(service);
+}
+
+int
+vchiq_get_client_id(VCHIQ_SERVICE_HANDLE_T handle)
+{
+ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ int id;
+
+ id = service ? service->client_id : 0;
+ if (service)
+ unlock_service(service);
+
+ return id;
+}
+
+void *
+vchiq_get_service_userdata(VCHIQ_SERVICE_HANDLE_T handle)
+{
+ VCHIQ_SERVICE_T *service = handle_to_service(handle);
+
+ return service ? service->base.userdata : NULL;
+}
+
+int
+vchiq_get_service_fourcc(VCHIQ_SERVICE_HANDLE_T handle)
+{
+ VCHIQ_SERVICE_T *service = handle_to_service(handle);
+
+ return service ? service->base.fourcc : 0;
+}
+
+static void
+mark_service_closing_internal(VCHIQ_SERVICE_T *service, int sh_thread)
+{
+ VCHIQ_STATE_T *state = service->state;
+ VCHIQ_SERVICE_QUOTA_T *service_quota;
+
+ service->closing = 1;
+
+ /* Synchronise with other threads. */
+ mutex_lock(&state->recycle_mutex);
+ mutex_unlock(&state->recycle_mutex);
+ if (!sh_thread || (state->conn_state != VCHIQ_CONNSTATE_PAUSE_SENT)) {
+ /* If we're pausing then the slot_mutex is held until resume
+ * by the slot handler. Therefore don't try to acquire this
+ * mutex if we're the slot handler and in the pause sent state.
+ * We don't need to in this case anyway. */
+ mutex_lock(&state->slot_mutex);
+ mutex_unlock(&state->slot_mutex);
+ }
+
+ /* Unblock any sending thread. */
+ service_quota = &state->service_quotas[service->localport];
+ up(&service_quota->quota_event);
+}
+
+static void
+mark_service_closing(VCHIQ_SERVICE_T *service)
+{
+ mark_service_closing_internal(service, 0);
+}
+
+static inline VCHIQ_STATUS_T
+make_service_callback(VCHIQ_SERVICE_T *service, VCHIQ_REASON_T reason,
+ VCHIQ_HEADER_T *header, void *bulk_userdata)
+{
+ VCHIQ_STATUS_T status;
+ vchiq_log_trace(vchiq_core_log_level, "%d: callback:%d (%s, %x, %x)",
+ service->state->id, service->localport, reason_names[reason],
+ (unsigned int)header, (unsigned int)bulk_userdata);
+ status = service->base.callback(reason, header, service->handle,
+ bulk_userdata);
+ if (status == VCHIQ_ERROR) {
+ vchiq_log_warning(vchiq_core_log_level,
+ "%d: ignoring ERROR from callback to service %x",
+ service->state->id, service->handle);
+ status = VCHIQ_SUCCESS;
+ }
+ return status;
+}
+
+inline void
+vchiq_set_conn_state(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T newstate)
+{
+ VCHIQ_CONNSTATE_T oldstate = state->conn_state;
+ vchiq_log_info(vchiq_core_log_level, "%d: %s->%s", state->id,
+ conn_state_names[oldstate],
+ conn_state_names[newstate]);
+ state->conn_state = newstate;
+ vchiq_platform_conn_state_changed(state, oldstate, newstate);
+}
+
+static inline void
+remote_event_create(REMOTE_EVENT_T *event)
+{
+ event->armed = 0;
+ /* Don't clear the 'fired' flag because it may already have been set
+ ** by the other side. */
+ sema_init(event->event, 0);
+}
+
+static inline void
+remote_event_destroy(REMOTE_EVENT_T *event)
+{
+ (void)event;
+}
+
+static inline int
+remote_event_wait(REMOTE_EVENT_T *event)
+{
+ if (!event->fired) {
+ event->armed = 1;
+ dsb();
+ if (!event->fired) {
+ if (down_interruptible(event->event) != 0) {
+ event->armed = 0;
+ return 0;
+ }
+ }
+ event->armed = 0;
+ wmb();
+ }
+
+ event->fired = 0;
+ return 1;
+}
+
+static inline void
+remote_event_signal_local(REMOTE_EVENT_T *event)
+{
+ event->armed = 0;
+ up(event->event);
+}
+
+static inline void
+remote_event_poll(REMOTE_EVENT_T *event)
+{
+ if (event->fired && event->armed)
+ remote_event_signal_local(event);
+}
+
+void
+remote_event_pollall(VCHIQ_STATE_T *state)
+{
+ remote_event_poll(&state->local->sync_trigger);
+ remote_event_poll(&state->local->sync_release);
+ remote_event_poll(&state->local->trigger);
+ remote_event_poll(&state->local->recycle);
+}
+
+/* Round up message sizes so that any space at the end of a slot is always big
+** enough for a header. This relies on header size being a power of two, which
+** has been verified earlier by a static assertion. */
+
+static inline unsigned int
+calc_stride(unsigned int size)
+{
+ /* Allow room for the header */
+ size += sizeof(VCHIQ_HEADER_T);
+
+ /* Round up */
+ return (size + sizeof(VCHIQ_HEADER_T) - 1) & ~(sizeof(VCHIQ_HEADER_T)
+ - 1);
+}
+
+/* Called by the slot handler thread */
+static VCHIQ_SERVICE_T *
+get_listening_service(VCHIQ_STATE_T *state, int fourcc)
+{
+ int i;
+
+ WARN_ON(fourcc == VCHIQ_FOURCC_INVALID);
+
+ for (i = 0; i < state->unused_service; i++) {
+ VCHIQ_SERVICE_T *service = state->services[i];
+ if (service &&
+ (service->public_fourcc == fourcc) &&
+ ((service->srvstate == VCHIQ_SRVSTATE_LISTENING) ||
+ ((service->srvstate == VCHIQ_SRVSTATE_OPEN) &&
+ (service->remoteport == VCHIQ_PORT_FREE)))) {
+ lock_service(service);
+ return service;
+ }
+ }
+
+ return NULL;
+}
+
+/* Called by the slot handler thread */
+static VCHIQ_SERVICE_T *
+get_connected_service(VCHIQ_STATE_T *state, unsigned int port)
+{
+ int i;
+ for (i = 0; i < state->unused_service; i++) {
+ VCHIQ_SERVICE_T *service = state->services[i];
+ if (service && (service->srvstate == VCHIQ_SRVSTATE_OPEN)
+ && (service->remoteport == port)) {
+ lock_service(service);
+ return service;
+ }
+ }
+ return NULL;
+}
+
+inline void
+request_poll(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int poll_type)
+{
+ uint32_t value;
+
+ if (service) {
+ do {
+ value = atomic_read(&service->poll_flags);
+ } while (atomic_cmpxchg(&service->poll_flags, value,
+ value | (1 << poll_type)) != value);
+
+ do {
+ value = atomic_read(&state->poll_services[
+ service->localport>>5]);
+ } while (atomic_cmpxchg(
+ &state->poll_services[service->localport>>5],
+ value, value | (1 << (service->localport & 0x1f)))
+ != value);
+ }
+
+ state->poll_needed = 1;
+ wmb();
+
+ /* ... and ensure the slot handler runs. */
+ remote_event_signal_local(&state->local->trigger);
+}
+
+/* Called from queue_message, by the slot handler and application threads,
+** with slot_mutex held */
+static VCHIQ_HEADER_T *
+reserve_space(VCHIQ_STATE_T *state, int space, int is_blocking)
+{
+ VCHIQ_SHARED_STATE_T *local = state->local;
+ int tx_pos = state->local_tx_pos;
+ int slot_space = VCHIQ_SLOT_SIZE - (tx_pos & VCHIQ_SLOT_MASK);
+
+ if (space > slot_space) {
+ VCHIQ_HEADER_T *header;
+ /* Fill the remaining space with padding */
+ WARN_ON(state->tx_data == NULL);
+ header = (VCHIQ_HEADER_T *)
+ (state->tx_data + (tx_pos & VCHIQ_SLOT_MASK));
+ header->msgid = VCHIQ_MSGID_PADDING;
+ header->size = slot_space - sizeof(VCHIQ_HEADER_T);
+
+ tx_pos += slot_space;
+ }
+
+ /* If necessary, get the next slot. */
+ if ((tx_pos & VCHIQ_SLOT_MASK) == 0) {
+ int slot_index;
+
+ /* If there is no free slot... */
+
+ if (down_trylock(&state->slot_available_event) != 0) {
+ /* ...wait for one. */
+
+ VCHIQ_STATS_INC(state, slot_stalls);
+
+ /* But first, flush through the last slot. */
+ state->local_tx_pos = tx_pos;
+ local->tx_pos = tx_pos;
+ remote_event_signal(&state->remote->trigger);
+
+ if (!is_blocking ||
+ (down_interruptible(
+ &state->slot_available_event) != 0))
+ return NULL; /* No space available */
+ }
+
+ BUG_ON(tx_pos ==
+ (state->slot_queue_available * VCHIQ_SLOT_SIZE));
+
+ slot_index = local->slot_queue[
+ SLOT_QUEUE_INDEX_FROM_POS(tx_pos) &
+ VCHIQ_SLOT_QUEUE_MASK];
+ state->tx_data =
+ (char *)SLOT_DATA_FROM_INDEX(state, slot_index);
+ }
+
+ state->local_tx_pos = tx_pos + space;
+
+ return (VCHIQ_HEADER_T *)(state->tx_data + (tx_pos & VCHIQ_SLOT_MASK));
+}
+
+/* Called by the recycle thread. */
+static void
+process_free_queue(VCHIQ_STATE_T *state)
+{
+ VCHIQ_SHARED_STATE_T *local = state->local;
+ BITSET_T service_found[BITSET_SIZE(VCHIQ_MAX_SERVICES)];
+ int slot_queue_available;
+
+ /* Use a read memory barrier to ensure that any state that may have
+ ** been modified by another thread is not masked by stale prefetched
+ ** values. */
+ rmb();
+
+ /* Find slots which have been freed by the other side, and return them
+ ** to the available queue. */
+ slot_queue_available = state->slot_queue_available;
+
+ while (slot_queue_available != local->slot_queue_recycle) {
+ unsigned int pos;
+ int slot_index = local->slot_queue[slot_queue_available++ &
+ VCHIQ_SLOT_QUEUE_MASK];
+ char *data = (char *)SLOT_DATA_FROM_INDEX(state, slot_index);
+ int data_found = 0;
+
+ vchiq_log_trace(vchiq_core_log_level, "%d: pfq %d=%x %x %x",
+ state->id, slot_index, (unsigned int)data,
+ local->slot_queue_recycle, slot_queue_available);
+
+ /* Initialise the bitmask for services which have used this
+ ** slot */
+ BITSET_ZERO(service_found);
+
+ pos = 0;
+
+ while (pos < VCHIQ_SLOT_SIZE) {
+ VCHIQ_HEADER_T *header =
+ (VCHIQ_HEADER_T *)(data + pos);
+ int msgid = header->msgid;
+ if (VCHIQ_MSG_TYPE(msgid) == VCHIQ_MSG_DATA) {
+ int port = VCHIQ_MSG_SRCPORT(msgid);
+ VCHIQ_SERVICE_QUOTA_T *service_quota =
+ &state->service_quotas[port];
+ int count;
+ spin_lock(&quota_spinlock);
+ count = service_quota->message_use_count;
+ if (count > 0)
+ service_quota->message_use_count =
+ count - 1;
+ spin_unlock(&quota_spinlock);
+
+ if (count == service_quota->message_quota)
+ /* Signal the service that it
+ ** has dropped below its quota
+ */
+ up(&service_quota->quota_event);
+ else if (count == 0) {
+ vchiq_log_error(vchiq_core_log_level,
+ "service %d "
+ "message_use_count=%d "
+ "(header %x, msgid %x, "
+ "header->msgid %x, "
+ "header->size %x)",
+ port,
+ service_quota->
+ message_use_count,
+ (unsigned int)header, msgid,
+ header->msgid,
+ header->size);
+ WARN(1, "invalid message use count\n");
+ }
+ if (!BITSET_IS_SET(service_found, port)) {
+ /* Set the found bit for this service */
+ BITSET_SET(service_found, port);
+
+ spin_lock(&quota_spinlock);
+ count = service_quota->slot_use_count;
+ if (count > 0)
+ service_quota->slot_use_count =
+ count - 1;
+ spin_unlock(&quota_spinlock);
+
+ if (count > 0) {
+ /* Signal the service in case
+ ** it has dropped below its
+ ** quota */
+ up(&service_quota->quota_event);
+ vchiq_log_trace(
+ vchiq_core_log_level,
+ "%d: pfq:%d %x@%x - "
+ "slot_use->%d",
+ state->id, port,
+ header->size,
+ (unsigned int)header,
+ count - 1);
+ } else {
+ vchiq_log_error(
+ vchiq_core_log_level,
+ "service %d "
+ "slot_use_count"
+ "=%d (header %x"
+ ", msgid %x, "
+ "header->msgid"
+ " %x, header->"
+ "size %x)",
+ port, count,
+ (unsigned int)header,
+ msgid,
+ header->msgid,
+ header->size);
+ WARN(1, "bad slot use count\n");
+ }
+ }
+
+ data_found = 1;
+ }
+
+ pos += calc_stride(header->size);
+ if (pos > VCHIQ_SLOT_SIZE) {
+ vchiq_log_error(vchiq_core_log_level,
+ "pfq - pos %x: header %x, msgid %x, "
+ "header->msgid %x, header->size %x",
+ pos, (unsigned int)header, msgid,
+ header->msgid, header->size);
+ WARN(1, "invalid slot position\n");
+ }
+ }
+
+ if (data_found) {
+ int count;
+ spin_lock(&quota_spinlock);
+ count = state->data_use_count;
+ if (count > 0)
+ state->data_use_count =
+ count - 1;
+ spin_unlock(&quota_spinlock);
+ if (count == state->data_quota)
+ up(&state->data_quota_event);
+ }
+
+ state->slot_queue_available = slot_queue_available;
+ up(&state->slot_available_event);
+ }
+}
+
+/* Called by the slot handler and application threads */
+static VCHIQ_STATUS_T
+queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
+ int msgid, const VCHIQ_ELEMENT_T *elements,
+ int count, int size, int flags)
+{
+ VCHIQ_SHARED_STATE_T *local;
+ VCHIQ_SERVICE_QUOTA_T *service_quota = NULL;
+ VCHIQ_HEADER_T *header;
+ int type = VCHIQ_MSG_TYPE(msgid);
+
+ unsigned int stride;
+
+ local = state->local;
+
+ stride = calc_stride(size);
+
+ WARN_ON(!(stride <= VCHIQ_SLOT_SIZE));
+
+ if (!(flags & QMFLAGS_NO_MUTEX_LOCK) &&
+ (mutex_lock_interruptible(&state->slot_mutex) != 0))
+ return VCHIQ_RETRY;
+
+ if (type == VCHIQ_MSG_DATA) {
+ int tx_end_index;
+
+ BUG_ON(!service);
+ BUG_ON((flags & (QMFLAGS_NO_MUTEX_LOCK |
+ QMFLAGS_NO_MUTEX_UNLOCK)) != 0);
+
+ if (service->closing) {
+ /* The service has been closed */
+ mutex_unlock(&state->slot_mutex);
+ return VCHIQ_ERROR;
+ }
+
+ service_quota = &state->service_quotas[service->localport];
+
+ spin_lock(&quota_spinlock);
+
+ /* Ensure this service doesn't use more than its quota of
+ ** messages or slots */
+ tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(
+ state->local_tx_pos + stride - 1);
+
+ /* Ensure data messages don't use more than their quota of
+ ** slots */
+ while ((tx_end_index != state->previous_data_index) &&
+ (state->data_use_count == state->data_quota)) {
+ VCHIQ_STATS_INC(state, data_stalls);
+ spin_unlock(&quota_spinlock);
+ mutex_unlock(&state->slot_mutex);
+
+ if (down_interruptible(&state->data_quota_event)
+ != 0)
+ return VCHIQ_RETRY;
+
+ mutex_lock(&state->slot_mutex);
+ spin_lock(&quota_spinlock);
+ tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(
+ state->local_tx_pos + stride - 1);
+ if ((tx_end_index == state->previous_data_index) ||
+ (state->data_use_count < state->data_quota)) {
+ /* Pass the signal on to other waiters */
+ up(&state->data_quota_event);
+ break;
+ }
+ }
+
+ while ((service_quota->message_use_count ==
+ service_quota->message_quota) ||
+ ((tx_end_index != service_quota->previous_tx_index) &&
+ (service_quota->slot_use_count ==
+ service_quota->slot_quota))) {
+ spin_unlock(&quota_spinlock);
+ vchiq_log_trace(vchiq_core_log_level,
+ "%d: qm:%d %s,%x - quota stall "
+ "(msg %d, slot %d)",
+ state->id, service->localport,
+ msg_type_str(type), size,
+ service_quota->message_use_count,
+ service_quota->slot_use_count);
+ VCHIQ_SERVICE_STATS_INC(service, quota_stalls);
+ mutex_unlock(&state->slot_mutex);
+ if (down_interruptible(&service_quota->quota_event)
+ != 0)
+ return VCHIQ_RETRY;
+ if (service->closing)
+ return VCHIQ_ERROR;
+ if (mutex_lock_interruptible(&state->slot_mutex) != 0)
+ return VCHIQ_RETRY;
+ if (service->srvstate != VCHIQ_SRVSTATE_OPEN) {
+ /* The service has been closed */
+ mutex_unlock(&state->slot_mutex);
+ return VCHIQ_ERROR;
+ }
+ spin_lock(&quota_spinlock);
+ tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(
+ state->local_tx_pos + stride - 1);
+ }
+
+ spin_unlock(&quota_spinlock);
+ }
+
+ header = reserve_space(state, stride, flags & QMFLAGS_IS_BLOCKING);
+
+ if (!header) {
+ if (service)
+ VCHIQ_SERVICE_STATS_INC(service, slot_stalls);
+ /* In the event of a failure, return the mutex to the
+ state it was in */
+ if (!(flags & QMFLAGS_NO_MUTEX_LOCK))
+ mutex_unlock(&state->slot_mutex);
+ return VCHIQ_RETRY;
+ }
+
+ if (type == VCHIQ_MSG_DATA) {
+ int i, pos;
+ int tx_end_index;
+ int slot_use_count;
+
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: qm %s@%x,%x (%d->%d)",
+ state->id,
+ msg_type_str(VCHIQ_MSG_TYPE(msgid)),
+ (unsigned int)header, size,
+ VCHIQ_MSG_SRCPORT(msgid),
+ VCHIQ_MSG_DSTPORT(msgid));
+
+ BUG_ON(!service);
+ BUG_ON((flags & (QMFLAGS_NO_MUTEX_LOCK |
+ QMFLAGS_NO_MUTEX_UNLOCK)) != 0);
+
+ for (i = 0, pos = 0; i < (unsigned int)count;
+ pos += elements[i++].size)
+ if (elements[i].size) {
+ if (vchiq_copy_from_user
+ (header->data + pos, elements[i].data,
+ (size_t) elements[i].size) !=
+ VCHIQ_SUCCESS) {
+ mutex_unlock(&state->slot_mutex);
+ VCHIQ_SERVICE_STATS_INC(service,
+ error_count);
+ return VCHIQ_ERROR;
+ }
+ if (i == 0) {
+ if (SRVTRACE_ENABLED(service,
+ VCHIQ_LOG_INFO))
+ vchiq_log_dump_mem("Sent", 0,
+ header->data + pos,
+ min(64u,
+ elements[0].size));
+ }
+ }
+
+ spin_lock(&quota_spinlock);
+ service_quota->message_use_count++;
+
+ tx_end_index =
+ SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos - 1);
+
+ /* If this transmission can't fit in the last slot used by any
+ ** service, the data_use_count must be increased. */
+ if (tx_end_index != state->previous_data_index) {
+ state->previous_data_index = tx_end_index;
+ state->data_use_count++;
+ }
+
+ /* If this isn't the same slot last used by this service,
+ ** the service's slot_use_count must be increased. */
+ if (tx_end_index != service_quota->previous_tx_index) {
+ service_quota->previous_tx_index = tx_end_index;
+ slot_use_count = ++service_quota->slot_use_count;
+ } else {
+ slot_use_count = 0;
+ }
+
+ spin_unlock(&quota_spinlock);
+
+ if (slot_use_count)
+ vchiq_log_trace(vchiq_core_log_level,
+ "%d: qm:%d %s,%x - slot_use->%d (hdr %p)",
+ state->id, service->localport,
+ msg_type_str(VCHIQ_MSG_TYPE(msgid)), size,
+ slot_use_count, header);
+
+ VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count);
+ VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size);
+ } else {
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: qm %s@%x,%x (%d->%d)", state->id,
+ msg_type_str(VCHIQ_MSG_TYPE(msgid)),
+ (unsigned int)header, size,
+ VCHIQ_MSG_SRCPORT(msgid),
+ VCHIQ_MSG_DSTPORT(msgid));
+ if (size != 0) {
+ WARN_ON(!((count == 1) && (size == elements[0].size)));
+ memcpy(header->data, elements[0].data,
+ elements[0].size);
+ }
+ VCHIQ_STATS_INC(state, ctrl_tx_count);
+ }
+
+ header->msgid = msgid;
+ header->size = size;
+
+ {
+ int svc_fourcc;
+
+ svc_fourcc = service
+ ? service->base.fourcc
+ : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
+
+ vchiq_log_info(SRVTRACE_LEVEL(service),
+ "Sent Msg %s(%u) to %c%c%c%c s:%u d:%d len:%d",
+ msg_type_str(VCHIQ_MSG_TYPE(msgid)),
+ VCHIQ_MSG_TYPE(msgid),
+ VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
+ VCHIQ_MSG_SRCPORT(msgid),
+ VCHIQ_MSG_DSTPORT(msgid),
+ size);
+ }
+
+ /* Make sure the new header is visible to the peer. */
+ wmb();
+
+ /* Make the new tx_pos visible to the peer. */
+ local->tx_pos = state->local_tx_pos;
+ wmb();
+
+ if (service && (type == VCHIQ_MSG_CLOSE))
+ vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSESENT);
+
+ if (!(flags & QMFLAGS_NO_MUTEX_UNLOCK))
+ mutex_unlock(&state->slot_mutex);
+
+ remote_event_signal(&state->remote->trigger);
+
+ return VCHIQ_SUCCESS;
+}
+
+/* Called by the slot handler and application threads */
+static VCHIQ_STATUS_T
+queue_message_sync(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
+ int msgid, const VCHIQ_ELEMENT_T *elements,
+ int count, int size, int is_blocking)
+{
+ VCHIQ_SHARED_STATE_T *local;
+ VCHIQ_HEADER_T *header;
+
+ local = state->local;
+
+ if ((VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_RESUME) &&
+ (mutex_lock_interruptible(&state->sync_mutex) != 0))
+ return VCHIQ_RETRY;
+
+ remote_event_wait(&local->sync_release);
+
+ rmb();
+
+ header = (VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state,
+ local->slot_sync);
+
+ {
+ int oldmsgid = header->msgid;
+ if (oldmsgid != VCHIQ_MSGID_PADDING)
+ vchiq_log_error(vchiq_core_log_level,
+ "%d: qms - msgid %x, not PADDING",
+ state->id, oldmsgid);
+ }
+
+ if (service) {
+ int i, pos;
+
+ vchiq_log_info(vchiq_sync_log_level,
+ "%d: qms %s@%x,%x (%d->%d)", state->id,
+ msg_type_str(VCHIQ_MSG_TYPE(msgid)),
+ (unsigned int)header, size,
+ VCHIQ_MSG_SRCPORT(msgid),
+ VCHIQ_MSG_DSTPORT(msgid));
+
+ for (i = 0, pos = 0; i < (unsigned int)count;
+ pos += elements[i++].size)
+ if (elements[i].size) {
+ if (vchiq_copy_from_user
+ (header->data + pos, elements[i].data,
+ (size_t) elements[i].size) !=
+ VCHIQ_SUCCESS) {
+ mutex_unlock(&state->sync_mutex);
+ VCHIQ_SERVICE_STATS_INC(service,
+ error_count);
+ return VCHIQ_ERROR;
+ }
+ if (i == 0) {
+ if (vchiq_sync_log_level >=
+ VCHIQ_LOG_TRACE)
+ vchiq_log_dump_mem("Sent Sync",
+ 0, header->data + pos,
+ min(64u,
+ elements[0].size));
+ }
+ }
+
+ VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count);
+ VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size);
+ } else {
+ vchiq_log_info(vchiq_sync_log_level,
+ "%d: qms %s@%x,%x (%d->%d)", state->id,
+ msg_type_str(VCHIQ_MSG_TYPE(msgid)),
+ (unsigned int)header, size,
+ VCHIQ_MSG_SRCPORT(msgid),
+ VCHIQ_MSG_DSTPORT(msgid));
+ if (size != 0) {
+ WARN_ON(!((count == 1) && (size == elements[0].size)));
+ memcpy(header->data, elements[0].data,
+ elements[0].size);
+ }
+ VCHIQ_STATS_INC(state, ctrl_tx_count);
+ }
+
+ header->size = size;
+ header->msgid = msgid;
+
+ if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) {
+ int svc_fourcc;
+
+ svc_fourcc = service
+ ? service->base.fourcc
+ : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
+
+ vchiq_log_trace(vchiq_sync_log_level,
+ "Sent Sync Msg %s(%u) to %c%c%c%c s:%u d:%d len:%d",
+ msg_type_str(VCHIQ_MSG_TYPE(msgid)),
+ VCHIQ_MSG_TYPE(msgid),
+ VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
+ VCHIQ_MSG_SRCPORT(msgid),
+ VCHIQ_MSG_DSTPORT(msgid),
+ size);
+ }
+
+ /* Make sure the new header is visible to the peer. */
+ wmb();
+
+ remote_event_signal(&state->remote->sync_trigger);
+
+ if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_PAUSE)
+ mutex_unlock(&state->sync_mutex);
+
+ return VCHIQ_SUCCESS;
+}
+
+static inline void
+claim_slot(VCHIQ_SLOT_INFO_T *slot)
+{
+ slot->use_count++;
+}
+
+static void
+release_slot(VCHIQ_STATE_T *state, VCHIQ_SLOT_INFO_T *slot_info,
+ VCHIQ_HEADER_T *header, VCHIQ_SERVICE_T *service)
+{
+ int release_count;
+
+ mutex_lock(&state->recycle_mutex);
+
+ if (header) {
+ int msgid = header->msgid;
+ if (((msgid & VCHIQ_MSGID_CLAIMED) == 0) ||
+ (service && service->closing)) {
+ mutex_unlock(&state->recycle_mutex);
+ return;
+ }
+
+ /* Rewrite the message header to prevent a double
+ ** release */
+ header->msgid = msgid & ~VCHIQ_MSGID_CLAIMED;
+ }
+
+ release_count = slot_info->release_count;
+ slot_info->release_count = ++release_count;
+
+ if (release_count == slot_info->use_count) {
+ int slot_queue_recycle;
+ /* Add to the freed queue */
+
+ /* A read barrier is necessary here to prevent speculative
+ ** fetches of remote->slot_queue_recycle from overtaking the
+ ** mutex. */
+ rmb();
+
+ slot_queue_recycle = state->remote->slot_queue_recycle;
+ state->remote->slot_queue[slot_queue_recycle &
+ VCHIQ_SLOT_QUEUE_MASK] =
+ SLOT_INDEX_FROM_INFO(state, slot_info);
+ state->remote->slot_queue_recycle = slot_queue_recycle + 1;
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: release_slot %d - recycle->%x",
+ state->id, SLOT_INDEX_FROM_INFO(state, slot_info),
+ state->remote->slot_queue_recycle);
+
+ /* A write barrier is necessary, but remote_event_signal
+ ** contains one. */
+ remote_event_signal(&state->remote->recycle);
+ }
+
+ mutex_unlock(&state->recycle_mutex);
+}
+
+/* Called by the slot handler - don't hold the bulk mutex */
+static VCHIQ_STATUS_T
+notify_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue,
+ int retry_poll)
+{
+ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+
+ vchiq_log_trace(vchiq_core_log_level,
+ "%d: nb:%d %cx - p=%x rn=%x r=%x",
+ service->state->id, service->localport,
+ (queue == &service->bulk_tx) ? 't' : 'r',
+ queue->process, queue->remote_notify, queue->remove);
+
+ if (service->state->is_master) {
+ while (queue->remote_notify != queue->process) {
+ VCHIQ_BULK_T *bulk =
+ &queue->bulks[BULK_INDEX(queue->remote_notify)];
+ int msgtype = (bulk->dir == VCHIQ_BULK_TRANSMIT) ?
+ VCHIQ_MSG_BULK_RX_DONE : VCHIQ_MSG_BULK_TX_DONE;
+ int msgid = VCHIQ_MAKE_MSG(msgtype, service->localport,
+ service->remoteport);
+ VCHIQ_ELEMENT_T element = { &bulk->actual, 4 };
+ /* Only reply to non-dummy bulk requests */
+ if (bulk->remote_data) {
+ status = queue_message(service->state, NULL,
+ msgid, &element, 1, 4, 0);
+ if (status != VCHIQ_SUCCESS)
+ break;
+ }
+ queue->remote_notify++;
+ }
+ } else {
+ queue->remote_notify = queue->process;
+ }
+
+ if (status == VCHIQ_SUCCESS) {
+ while (queue->remove != queue->remote_notify) {
+ VCHIQ_BULK_T *bulk =
+ &queue->bulks[BULK_INDEX(queue->remove)];
+
+ /* Only generate callbacks for non-dummy bulk
+ ** requests, and non-terminated services */
+ if (bulk->data && service->instance) {
+ if (bulk->actual != VCHIQ_BULK_ACTUAL_ABORTED) {
+ if (bulk->dir == VCHIQ_BULK_TRANSMIT) {
+ VCHIQ_SERVICE_STATS_INC(service,
+ bulk_tx_count);
+ VCHIQ_SERVICE_STATS_ADD(service,
+ bulk_tx_bytes,
+ bulk->actual);
+ } else {
+ VCHIQ_SERVICE_STATS_INC(service,
+ bulk_rx_count);
+ VCHIQ_SERVICE_STATS_ADD(service,
+ bulk_rx_bytes,
+ bulk->actual);
+ }
+ } else {
+ VCHIQ_SERVICE_STATS_INC(service,
+ bulk_aborted_count);
+ }
+ if (bulk->mode == VCHIQ_BULK_MODE_BLOCKING) {
+ struct bulk_waiter *waiter;
+ spin_lock(&bulk_waiter_spinlock);
+ waiter = bulk->userdata;
+ if (waiter) {
+ waiter->actual = bulk->actual;
+ up(&waiter->event);
+ }
+ spin_unlock(&bulk_waiter_spinlock);
+ } else if (bulk->mode ==
+ VCHIQ_BULK_MODE_CALLBACK) {
+ VCHIQ_REASON_T reason = (bulk->dir ==
+ VCHIQ_BULK_TRANSMIT) ?
+ ((bulk->actual ==
+ VCHIQ_BULK_ACTUAL_ABORTED) ?
+ VCHIQ_BULK_TRANSMIT_ABORTED :
+ VCHIQ_BULK_TRANSMIT_DONE) :
+ ((bulk->actual ==
+ VCHIQ_BULK_ACTUAL_ABORTED) ?
+ VCHIQ_BULK_RECEIVE_ABORTED :
+ VCHIQ_BULK_RECEIVE_DONE);
+ status = make_service_callback(service,
+ reason, NULL, bulk->userdata);
+ if (status == VCHIQ_RETRY)
+ break;
+ }
+ }
+
+ queue->remove++;
+ up(&service->bulk_remove_event);
+ }
+ if (!retry_poll)
+ status = VCHIQ_SUCCESS;
+ }
+
+ if (status == VCHIQ_RETRY)
+ request_poll(service->state, service,
+ (queue == &service->bulk_tx) ?
+ VCHIQ_POLL_TXNOTIFY : VCHIQ_POLL_RXNOTIFY);
+
+ return status;
+}
+
+/* Called by the slot handler thread */
+static void
+poll_services(VCHIQ_STATE_T *state)
+{
+ int group, i;
+
+ for (group = 0; group < BITSET_SIZE(state->unused_service); group++) {
+ uint32_t flags;
+ flags = atomic_xchg(&state->poll_services[group], 0);
+ for (i = 0; flags; i++) {
+ if (flags & (1 << i)) {
+ VCHIQ_SERVICE_T *service =
+ find_service_by_port(state,
+ (group<<5) + i);
+ uint32_t service_flags;
+ flags &= ~(1 << i);
+ if (!service)
+ continue;
+ service_flags =
+ atomic_xchg(&service->poll_flags, 0);
+ if (service_flags &
+ (1 << VCHIQ_POLL_REMOVE)) {
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: ps - remove %d<->%d",
+ state->id, service->localport,
+ service->remoteport);
+
+ /* Make it look like a client, because
+ it must be removed and not left in
+ the LISTENING state. */
+ service->public_fourcc =
+ VCHIQ_FOURCC_INVALID;
+
+ if (vchiq_close_service_internal(
+ service, 0/*!close_recvd*/) !=
+ VCHIQ_SUCCESS)
+ request_poll(state, service,
+ VCHIQ_POLL_REMOVE);
+ } else if (service_flags &
+ (1 << VCHIQ_POLL_TERMINATE)) {
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: ps - terminate %d<->%d",
+ state->id, service->localport,
+ service->remoteport);
+ if (vchiq_close_service_internal(
+ service, 0/*!close_recvd*/) !=
+ VCHIQ_SUCCESS)
+ request_poll(state, service,
+ VCHIQ_POLL_TERMINATE);
+ }
+ if (service_flags & (1 << VCHIQ_POLL_TXNOTIFY))
+ notify_bulks(service,
+ &service->bulk_tx,
+ 1/*retry_poll*/);
+ if (service_flags & (1 << VCHIQ_POLL_RXNOTIFY))
+ notify_bulks(service,
+ &service->bulk_rx,
+ 1/*retry_poll*/);
+ unlock_service(service);
+ }
+ }
+ }
+}
+
+/* Called by the slot handler or application threads, holding the bulk mutex. */
+static int
+resolve_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue)
+{
+ VCHIQ_STATE_T *state = service->state;
+ int resolved = 0;
+ int rc;
+
+ while ((queue->process != queue->local_insert) &&
+ (queue->process != queue->remote_insert)) {
+ VCHIQ_BULK_T *bulk = &queue->bulks[BULK_INDEX(queue->process)];
+
+ vchiq_log_trace(vchiq_core_log_level,
+ "%d: rb:%d %cx - li=%x ri=%x p=%x",
+ state->id, service->localport,
+ (queue == &service->bulk_tx) ? 't' : 'r',
+ queue->local_insert, queue->remote_insert,
+ queue->process);
+
+ WARN_ON(!((int)(queue->local_insert - queue->process) > 0));
+ WARN_ON(!((int)(queue->remote_insert - queue->process) > 0));
+
+ rc = mutex_lock_interruptible(&state->bulk_transfer_mutex);
+ if (rc != 0)
+ break;
+
+ vchiq_transfer_bulk(bulk);
+ mutex_unlock(&state->bulk_transfer_mutex);
+
+ if (SRVTRACE_ENABLED(service, VCHIQ_LOG_INFO)) {
+ const char *header = (queue == &service->bulk_tx) ?
+ "Send Bulk to" : "Recv Bulk from";
+ if (bulk->actual != VCHIQ_BULK_ACTUAL_ABORTED)
+ vchiq_log_info(SRVTRACE_LEVEL(service),
+ "%s %c%c%c%c d:%d len:%d %x<->%x",
+ header,
+ VCHIQ_FOURCC_AS_4CHARS(
+ service->base.fourcc),
+ service->remoteport,
+ bulk->size,
+ (unsigned int)bulk->data,
+ (unsigned int)bulk->remote_data);
+ else
+ vchiq_log_info(SRVTRACE_LEVEL(service),
+ "%s %c%c%c%c d:%d ABORTED - tx len:%d,"
+ " rx len:%d %x<->%x",
+ header,
+ VCHIQ_FOURCC_AS_4CHARS(
+ service->base.fourcc),
+ service->remoteport,
+ bulk->size,
+ bulk->remote_size,
+ (unsigned int)bulk->data,
+ (unsigned int)bulk->remote_data);
+ }
+
+ vchiq_complete_bulk(bulk);
+ queue->process++;
+ resolved++;
+ }
+ return resolved;
+}
+
+/* Called with the bulk_mutex held */
+static void
+abort_outstanding_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue)
+{
+ int is_tx = (queue == &service->bulk_tx);
+ vchiq_log_trace(vchiq_core_log_level,
+ "%d: aob:%d %cx - li=%x ri=%x p=%x",
+ service->state->id, service->localport, is_tx ? 't' : 'r',
+ queue->local_insert, queue->remote_insert, queue->process);
+
+ WARN_ON(!((int)(queue->local_insert - queue->process) >= 0));
+ WARN_ON(!((int)(queue->remote_insert - queue->process) >= 0));
+
+ while ((queue->process != queue->local_insert) ||
+ (queue->process != queue->remote_insert)) {
+ VCHIQ_BULK_T *bulk = &queue->bulks[BULK_INDEX(queue->process)];
+
+ if (queue->process == queue->remote_insert) {
+ /* fabricate a matching dummy bulk */
+ bulk->remote_data = NULL;
+ bulk->remote_size = 0;
+ queue->remote_insert++;
+ }
+
+ if (queue->process != queue->local_insert) {
+ vchiq_complete_bulk(bulk);
+
+ vchiq_log_info(SRVTRACE_LEVEL(service),
+ "%s %c%c%c%c d:%d ABORTED - tx len:%d, "
+ "rx len:%d",
+ is_tx ? "Send Bulk to" : "Recv Bulk from",
+ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
+ service->remoteport,
+ bulk->size,
+ bulk->remote_size);
+ } else {
+ /* fabricate a matching dummy bulk */
+ bulk->data = NULL;
+ bulk->size = 0;
+ bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED;
+ bulk->dir = is_tx ? VCHIQ_BULK_TRANSMIT :
+ VCHIQ_BULK_RECEIVE;
+ queue->local_insert++;
+ }
+
+ queue->process++;
+ }
+}
+
+/* Called from the slot handler thread */
+static void
+pause_bulks(VCHIQ_STATE_T *state)
+{
+ if (unlikely(atomic_inc_return(&pause_bulks_count) != 1)) {
+ WARN_ON_ONCE(1);
+ atomic_set(&pause_bulks_count, 1);
+ return;
+ }
+
+ /* Block bulk transfers from all services */
+ mutex_lock(&state->bulk_transfer_mutex);
+}
+
+/* Called from the slot handler thread */
+static void
+resume_bulks(VCHIQ_STATE_T *state)
+{
+ int i;
+ if (unlikely(atomic_dec_return(&pause_bulks_count) != 0)) {
+ WARN_ON_ONCE(1);
+ atomic_set(&pause_bulks_count, 0);
+ return;
+ }
+
+ /* Allow bulk transfers from all services */
+ mutex_unlock(&state->bulk_transfer_mutex);
+
+ if (state->deferred_bulks == 0)
+ return;
+
+ /* Deal with any bulks which had to be deferred due to being in
+ * paused state. Don't try to match up to number of deferred bulks
+ * in case we've had something come and close the service in the
+ * interim - just process all bulk queues for all services */
+ vchiq_log_info(vchiq_core_log_level, "%s: processing %d deferred bulks",
+ __func__, state->deferred_bulks);
+
+ for (i = 0; i < state->unused_service; i++) {
+ VCHIQ_SERVICE_T *service = state->services[i];
+ int resolved_rx = 0;
+ int resolved_tx = 0;
+ if (!service || (service->srvstate != VCHIQ_SRVSTATE_OPEN))
+ continue;
+
+ mutex_lock(&service->bulk_mutex);
+ resolved_rx = resolve_bulks(service, &service->bulk_rx);
+ resolved_tx = resolve_bulks(service, &service->bulk_tx);
+ mutex_unlock(&service->bulk_mutex);
+ if (resolved_rx)
+ notify_bulks(service, &service->bulk_rx, 1);
+ if (resolved_tx)
+ notify_bulks(service, &service->bulk_tx, 1);
+ }
+ state->deferred_bulks = 0;
+}
+
+static int
+parse_open(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header)
+{
+ VCHIQ_SERVICE_T *service = NULL;
+ int msgid, size;
+ int type;
+ unsigned int localport, remoteport;
+
+ msgid = header->msgid;
+ size = header->size;
+ type = VCHIQ_MSG_TYPE(msgid);
+ localport = VCHIQ_MSG_DSTPORT(msgid);
+ remoteport = VCHIQ_MSG_SRCPORT(msgid);
+ if (size >= sizeof(struct vchiq_open_payload)) {
+ const struct vchiq_open_payload *payload =
+ (struct vchiq_open_payload *)header->data;
+ unsigned int fourcc;
+
+ fourcc = payload->fourcc;
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: prs OPEN@%x (%d->'%c%c%c%c')",
+ state->id, (unsigned int)header,
+ localport,
+ VCHIQ_FOURCC_AS_4CHARS(fourcc));
+
+ service = get_listening_service(state, fourcc);
+
+ if (service) {
+ /* A matching service exists */
+ short version = payload->version;
+ short version_min = payload->version_min;
+ if ((service->version < version_min) ||
+ (version < service->version_min)) {
+ /* Version mismatch */
+ vchiq_loud_error_header();
+ vchiq_loud_error("%d: service %d (%c%c%c%c) "
+ "version mismatch - local (%d, min %d)"
+ " vs. remote (%d, min %d)",
+ state->id, service->localport,
+ VCHIQ_FOURCC_AS_4CHARS(fourcc),
+ service->version, service->version_min,
+ version, version_min);
+ vchiq_loud_error_footer();
+ unlock_service(service);
+ service = NULL;
+ goto fail_open;
+ }
+ service->peer_version = version;
+
+ if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) {
+ struct vchiq_openack_payload ack_payload = {
+ service->version
+ };
+ VCHIQ_ELEMENT_T body = {
+ &ack_payload,
+ sizeof(ack_payload)
+ };
+
+ if (state->version_common <
+ VCHIQ_VERSION_SYNCHRONOUS_MODE)
+ service->sync = 0;
+
+ /* Acknowledge the OPEN */
+ if (service->sync &&
+ (state->version_common >=
+ VCHIQ_VERSION_SYNCHRONOUS_MODE)) {
+ if (queue_message_sync(state, NULL,
+ VCHIQ_MAKE_MSG(
+ VCHIQ_MSG_OPENACK,
+ service->localport,
+ remoteport),
+ &body, 1, sizeof(ack_payload),
+ 0) == VCHIQ_RETRY)
+ goto bail_not_ready;
+ } else {
+ if (queue_message(state, NULL,
+ VCHIQ_MAKE_MSG(
+ VCHIQ_MSG_OPENACK,
+ service->localport,
+ remoteport),
+ &body, 1, sizeof(ack_payload),
+ 0) == VCHIQ_RETRY)
+ goto bail_not_ready;
+ }
+
+ /* The service is now open */
+ vchiq_set_service_state(service,
+ service->sync ? VCHIQ_SRVSTATE_OPENSYNC
+ : VCHIQ_SRVSTATE_OPEN);
+ }
+
+ service->remoteport = remoteport;
+ service->client_id = ((int *)header->data)[1];
+ if (make_service_callback(service, VCHIQ_SERVICE_OPENED,
+ NULL, NULL) == VCHIQ_RETRY) {
+ /* Bail out if not ready */
+ service->remoteport = VCHIQ_PORT_FREE;
+ goto bail_not_ready;
+ }
+
+ /* Success - the message has been dealt with */
+ unlock_service(service);
+ return 1;
+ }
+ }
+
+fail_open:
+ /* No available service, or an invalid request - send a CLOSE */
+ if (queue_message(state, NULL,
+ VCHIQ_MAKE_MSG(VCHIQ_MSG_CLOSE, 0, VCHIQ_MSG_SRCPORT(msgid)),
+ NULL, 0, 0, 0) == VCHIQ_RETRY)
+ goto bail_not_ready;
+
+ return 1;
+
+bail_not_ready:
+ if (service)
+ unlock_service(service);
+
+ return 0;
+}
+
+/* Called by the slot handler thread */
+static void
+parse_rx_slots(VCHIQ_STATE_T *state)
+{
+ VCHIQ_SHARED_STATE_T *remote = state->remote;
+ VCHIQ_SERVICE_T *service = NULL;
+ int tx_pos;
+ DEBUG_INITIALISE(state->local)
+
+ tx_pos = remote->tx_pos;
+
+ while (state->rx_pos != tx_pos) {
+ VCHIQ_HEADER_T *header;
+ int msgid, size;
+ int type;
+ unsigned int localport, remoteport;
+
+ DEBUG_TRACE(PARSE_LINE);
+ if (!state->rx_data) {
+ int rx_index;
+ WARN_ON(!((state->rx_pos & VCHIQ_SLOT_MASK) == 0));
+ rx_index = remote->slot_queue[
+ SLOT_QUEUE_INDEX_FROM_POS(state->rx_pos) &
+ VCHIQ_SLOT_QUEUE_MASK];
+ state->rx_data = (char *)SLOT_DATA_FROM_INDEX(state,
+ rx_index);
+ state->rx_info = SLOT_INFO_FROM_INDEX(state, rx_index);
+
+ /* Initialise use_count to one, and increment
+ ** release_count at the end of the slot to avoid
+ ** releasing the slot prematurely. */
+ state->rx_info->use_count = 1;
+ state->rx_info->release_count = 0;
+ }
+
+ header = (VCHIQ_HEADER_T *)(state->rx_data +
+ (state->rx_pos & VCHIQ_SLOT_MASK));
+ DEBUG_VALUE(PARSE_HEADER, (int)header);
+ msgid = header->msgid;
+ DEBUG_VALUE(PARSE_MSGID, msgid);
+ size = header->size;
+ type = VCHIQ_MSG_TYPE(msgid);
+ localport = VCHIQ_MSG_DSTPORT(msgid);
+ remoteport = VCHIQ_MSG_SRCPORT(msgid);
+
+ if (type != VCHIQ_MSG_DATA)
+ VCHIQ_STATS_INC(state, ctrl_rx_count);
+
+ switch (type) {
+ case VCHIQ_MSG_OPENACK:
+ case VCHIQ_MSG_CLOSE:
+ case VCHIQ_MSG_DATA:
+ case VCHIQ_MSG_BULK_RX:
+ case VCHIQ_MSG_BULK_TX:
+ case VCHIQ_MSG_BULK_RX_DONE:
+ case VCHIQ_MSG_BULK_TX_DONE:
+ service = find_service_by_port(state, localport);
+ if ((!service ||
+ ((service->remoteport != remoteport) &&
+ (service->remoteport != VCHIQ_PORT_FREE))) &&
+ (localport == 0) &&
+ (type == VCHIQ_MSG_CLOSE)) {
+ /* This could be a CLOSE from a client which
+ hadn't yet received the OPENACK - look for
+ the connected service */
+ if (service)
+ unlock_service(service);
+ service = get_connected_service(state,
+ remoteport);
+ if (service)
+ vchiq_log_warning(vchiq_core_log_level,
+ "%d: prs %s@%x (%d->%d) - "
+ "found connected service %d",
+ state->id, msg_type_str(type),
+ (unsigned int)header,
+ remoteport, localport,
+ service->localport);
+ }
+
+ if (!service) {
+ vchiq_log_error(vchiq_core_log_level,
+ "%d: prs %s@%x (%d->%d) - "
+ "invalid/closed service %d",
+ state->id, msg_type_str(type),
+ (unsigned int)header,
+ remoteport, localport, localport);
+ goto skip_message;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (SRVTRACE_ENABLED(service, VCHIQ_LOG_INFO)) {
+ int svc_fourcc;
+
+ svc_fourcc = service
+ ? service->base.fourcc
+ : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
+ vchiq_log_info(SRVTRACE_LEVEL(service),
+ "Rcvd Msg %s(%u) from %c%c%c%c s:%d d:%d "
+ "len:%d",
+ msg_type_str(type), type,
+ VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
+ remoteport, localport, size);
+ if (size > 0)
+ vchiq_log_dump_mem("Rcvd", 0, header->data,
+ min(64, size));
+ }
+
+ if (((unsigned int)header & VCHIQ_SLOT_MASK) + calc_stride(size)
+ > VCHIQ_SLOT_SIZE) {
+ vchiq_log_error(vchiq_core_log_level,
+ "header %x (msgid %x) - size %x too big for "
+ "slot",
+ (unsigned int)header, (unsigned int)msgid,
+ (unsigned int)size);
+ WARN(1, "oversized for slot\n");
+ }
+
+ switch (type) {
+ case VCHIQ_MSG_OPEN:
+ WARN_ON(!(VCHIQ_MSG_DSTPORT(msgid) == 0));
+ if (!parse_open(state, header))
+ goto bail_not_ready;
+ break;
+ case VCHIQ_MSG_OPENACK:
+ if (size >= sizeof(struct vchiq_openack_payload)) {
+ const struct vchiq_openack_payload *payload =
+ (struct vchiq_openack_payload *)
+ header->data;
+ service->peer_version = payload->version;
+ }
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: prs OPENACK@%x,%x (%d->%d) v:%d",
+ state->id, (unsigned int)header, size,
+ remoteport, localport, service->peer_version);
+ if (service->srvstate ==
+ VCHIQ_SRVSTATE_OPENING) {
+ service->remoteport = remoteport;
+ vchiq_set_service_state(service,
+ VCHIQ_SRVSTATE_OPEN);
+ up(&service->remove_event);
+ } else
+ vchiq_log_error(vchiq_core_log_level,
+ "OPENACK received in state %s",
+ srvstate_names[service->srvstate]);
+ break;
+ case VCHIQ_MSG_CLOSE:
+ WARN_ON(size != 0); /* There should be no data */
+
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: prs CLOSE@%x (%d->%d)",
+ state->id, (unsigned int)header,
+ remoteport, localport);
+
+ mark_service_closing_internal(service, 1);
+
+ if (vchiq_close_service_internal(service,
+ 1/*close_recvd*/) == VCHIQ_RETRY)
+ goto bail_not_ready;
+
+ vchiq_log_info(vchiq_core_log_level,
+ "Close Service %c%c%c%c s:%u d:%d",
+ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
+ service->localport,
+ service->remoteport);
+ break;
+ case VCHIQ_MSG_DATA:
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: prs DATA@%x,%x (%d->%d)",
+ state->id, (unsigned int)header, size,
+ remoteport, localport);
+
+ if ((service->remoteport == remoteport)
+ && (service->srvstate ==
+ VCHIQ_SRVSTATE_OPEN)) {
+ header->msgid = msgid | VCHIQ_MSGID_CLAIMED;
+ claim_slot(state->rx_info);
+ DEBUG_TRACE(PARSE_LINE);
+ if (make_service_callback(service,
+ VCHIQ_MESSAGE_AVAILABLE, header,
+ NULL) == VCHIQ_RETRY) {
+ DEBUG_TRACE(PARSE_LINE);
+ goto bail_not_ready;
+ }
+ VCHIQ_SERVICE_STATS_INC(service, ctrl_rx_count);
+ VCHIQ_SERVICE_STATS_ADD(service, ctrl_rx_bytes,
+ size);
+ } else {
+ VCHIQ_STATS_INC(state, error_count);
+ }
+ break;
+ case VCHIQ_MSG_CONNECT:
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: prs CONNECT@%x",
+ state->id, (unsigned int)header);
+ state->version_common = ((VCHIQ_SLOT_ZERO_T *)
+ state->slot_data)->version;
+ up(&state->connect);
+ break;
+ case VCHIQ_MSG_BULK_RX:
+ case VCHIQ_MSG_BULK_TX: {
+ VCHIQ_BULK_QUEUE_T *queue;
+ WARN_ON(!state->is_master);
+ queue = (type == VCHIQ_MSG_BULK_RX) ?
+ &service->bulk_tx : &service->bulk_rx;
+ if ((service->remoteport == remoteport)
+ && (service->srvstate ==
+ VCHIQ_SRVSTATE_OPEN)) {
+ VCHIQ_BULK_T *bulk;
+ int resolved = 0;
+
+ DEBUG_TRACE(PARSE_LINE);
+ if (mutex_lock_interruptible(
+ &service->bulk_mutex) != 0) {
+ DEBUG_TRACE(PARSE_LINE);
+ goto bail_not_ready;
+ }
+
+ WARN_ON(!(queue->remote_insert < queue->remove +
+ VCHIQ_NUM_SERVICE_BULKS));
+ bulk = &queue->bulks[
+ BULK_INDEX(queue->remote_insert)];
+ bulk->remote_data =
+ (void *)((int *)header->data)[0];
+ bulk->remote_size = ((int *)header->data)[1];
+ wmb();
+
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: prs %s@%x (%d->%d) %x@%x",
+ state->id, msg_type_str(type),
+ (unsigned int)header,
+ remoteport, localport,
+ bulk->remote_size,
+ (unsigned int)bulk->remote_data);
+
+ queue->remote_insert++;
+
+ if (atomic_read(&pause_bulks_count)) {
+ state->deferred_bulks++;
+ vchiq_log_info(vchiq_core_log_level,
+ "%s: deferring bulk (%d)",
+ __func__,
+ state->deferred_bulks);
+ if (state->conn_state !=
+ VCHIQ_CONNSTATE_PAUSE_SENT)
+ vchiq_log_error(
+ vchiq_core_log_level,
+ "%s: bulks paused in "
+ "unexpected state %s",
+ __func__,
+ conn_state_names[
+ state->conn_state]);
+ } else if (state->conn_state ==
+ VCHIQ_CONNSTATE_CONNECTED) {
+ DEBUG_TRACE(PARSE_LINE);
+ resolved = resolve_bulks(service,
+ queue);
+ }
+
+ mutex_unlock(&service->bulk_mutex);
+ if (resolved)
+ notify_bulks(service, queue,
+ 1/*retry_poll*/);
+ }
+ } break;
+ case VCHIQ_MSG_BULK_RX_DONE:
+ case VCHIQ_MSG_BULK_TX_DONE:
+ WARN_ON(state->is_master);
+ if ((service->remoteport == remoteport)
+ && (service->srvstate !=
+ VCHIQ_SRVSTATE_FREE)) {
+ VCHIQ_BULK_QUEUE_T *queue;
+ VCHIQ_BULK_T *bulk;
+
+ queue = (type == VCHIQ_MSG_BULK_RX_DONE) ?
+ &service->bulk_rx : &service->bulk_tx;
+
+ DEBUG_TRACE(PARSE_LINE);
+ if (mutex_lock_interruptible(
+ &service->bulk_mutex) != 0) {
+ DEBUG_TRACE(PARSE_LINE);
+ goto bail_not_ready;
+ }
+ if ((int)(queue->remote_insert -
+ queue->local_insert) >= 0) {
+ vchiq_log_error(vchiq_core_log_level,
+ "%d: prs %s@%x (%d->%d) "
+ "unexpected (ri=%d,li=%d)",
+ state->id, msg_type_str(type),
+ (unsigned int)header,
+ remoteport, localport,
+ queue->remote_insert,
+ queue->local_insert);
+ mutex_unlock(&service->bulk_mutex);
+ break;
+ }
+
+ BUG_ON(queue->process == queue->local_insert);
+ BUG_ON(queue->process != queue->remote_insert);
+
+ bulk = &queue->bulks[
+ BULK_INDEX(queue->remote_insert)];
+ bulk->actual = *(int *)header->data;
+ queue->remote_insert++;
+
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: prs %s@%x (%d->%d) %x@%x",
+ state->id, msg_type_str(type),
+ (unsigned int)header,
+ remoteport, localport,
+ bulk->actual, (unsigned int)bulk->data);
+
+ vchiq_log_trace(vchiq_core_log_level,
+ "%d: prs:%d %cx li=%x ri=%x p=%x",
+ state->id, localport,
+ (type == VCHIQ_MSG_BULK_RX_DONE) ?
+ 'r' : 't',
+ queue->local_insert,
+ queue->remote_insert, queue->process);
+
+ DEBUG_TRACE(PARSE_LINE);
+ WARN_ON(queue->process == queue->local_insert);
+ vchiq_complete_bulk(bulk);
+ queue->process++;
+ mutex_unlock(&service->bulk_mutex);
+ DEBUG_TRACE(PARSE_LINE);
+ notify_bulks(service, queue, 1/*retry_poll*/);
+ DEBUG_TRACE(PARSE_LINE);
+ }
+ break;
+ case VCHIQ_MSG_PADDING:
+ vchiq_log_trace(vchiq_core_log_level,
+ "%d: prs PADDING@%x,%x",
+ state->id, (unsigned int)header, size);
+ break;
+ case VCHIQ_MSG_PAUSE:
+ /* If initiated, signal the application thread */
+ vchiq_log_trace(vchiq_core_log_level,
+ "%d: prs PAUSE@%x,%x",
+ state->id, (unsigned int)header, size);
+ if (state->conn_state == VCHIQ_CONNSTATE_PAUSED) {
+ vchiq_log_error(vchiq_core_log_level,
+ "%d: PAUSE received in state PAUSED",
+ state->id);
+ break;
+ }
+ if (state->conn_state != VCHIQ_CONNSTATE_PAUSE_SENT) {
+ /* Send a PAUSE in response */
+ if (queue_message(state, NULL,
+ VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0),
+ NULL, 0, 0, QMFLAGS_NO_MUTEX_UNLOCK)
+ == VCHIQ_RETRY)
+ goto bail_not_ready;
+ if (state->is_master)
+ pause_bulks(state);
+ }
+ /* At this point slot_mutex is held */
+ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSED);
+ vchiq_platform_paused(state);
+ break;
+ case VCHIQ_MSG_RESUME:
+ vchiq_log_trace(vchiq_core_log_level,
+ "%d: prs RESUME@%x,%x",
+ state->id, (unsigned int)header, size);
+ /* Release the slot mutex */
+ mutex_unlock(&state->slot_mutex);
+ if (state->is_master)
+ resume_bulks(state);
+ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
+ vchiq_platform_resumed(state);
+ break;
+
+ case VCHIQ_MSG_REMOTE_USE:
+ vchiq_on_remote_use(state);
+ break;
+ case VCHIQ_MSG_REMOTE_RELEASE:
+ vchiq_on_remote_release(state);
+ break;
+ case VCHIQ_MSG_REMOTE_USE_ACTIVE:
+ vchiq_on_remote_use_active(state);
+ break;
+
+ default:
+ vchiq_log_error(vchiq_core_log_level,
+ "%d: prs invalid msgid %x@%x,%x",
+ state->id, msgid, (unsigned int)header, size);
+ WARN(1, "invalid message\n");
+ break;
+ }
+
+skip_message:
+ if (service) {
+ unlock_service(service);
+ service = NULL;
+ }
+
+ state->rx_pos += calc_stride(size);
+
+ DEBUG_TRACE(PARSE_LINE);
+ /* Perform some housekeeping when the end of the slot is
+ ** reached. */
+ if ((state->rx_pos & VCHIQ_SLOT_MASK) == 0) {
+ /* Remove the extra reference count. */
+ release_slot(state, state->rx_info, NULL, NULL);
+ state->rx_data = NULL;
+ }
+ }
+
+bail_not_ready:
+ if (service)
+ unlock_service(service);
+}
+
+/* Called by the slot handler thread */
+static int
+slot_handler_func(void *v)
+{
+ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v;
+ VCHIQ_SHARED_STATE_T *local = state->local;
+ DEBUG_INITIALISE(local)
+
+ while (1) {
+ DEBUG_COUNT(SLOT_HANDLER_COUNT);
+ DEBUG_TRACE(SLOT_HANDLER_LINE);
+ remote_event_wait(&local->trigger);
+
+ rmb();
+
+ DEBUG_TRACE(SLOT_HANDLER_LINE);
+ if (state->poll_needed) {
+ /* Check if we need to suspend - may change our
+ * conn_state */
+ vchiq_platform_check_suspend(state);
+
+ state->poll_needed = 0;
+
+ /* Handle service polling and other rare conditions here
+ ** out of the mainline code */
+ switch (state->conn_state) {
+ case VCHIQ_CONNSTATE_CONNECTED:
+ /* Poll the services as requested */
+ poll_services(state);
+ break;
+
+ case VCHIQ_CONNSTATE_PAUSING:
+ if (state->is_master)
+ pause_bulks(state);
+ if (queue_message(state, NULL,
+ VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0),
+ NULL, 0, 0,
+ QMFLAGS_NO_MUTEX_UNLOCK)
+ != VCHIQ_RETRY) {
+ vchiq_set_conn_state(state,
+ VCHIQ_CONNSTATE_PAUSE_SENT);
+ } else {
+ if (state->is_master)
+ resume_bulks(state);
+ /* Retry later */
+ state->poll_needed = 1;
+ }
+ break;
+
+ case VCHIQ_CONNSTATE_PAUSED:
+ vchiq_platform_resume(state);
+ break;
+
+ case VCHIQ_CONNSTATE_RESUMING:
+ if (queue_message(state, NULL,
+ VCHIQ_MAKE_MSG(VCHIQ_MSG_RESUME, 0, 0),
+ NULL, 0, 0, QMFLAGS_NO_MUTEX_LOCK)
+ != VCHIQ_RETRY) {
+ if (state->is_master)
+ resume_bulks(state);
+ vchiq_set_conn_state(state,
+ VCHIQ_CONNSTATE_CONNECTED);
+ vchiq_platform_resumed(state);
+ } else {
+ /* This should really be impossible,
+ ** since the PAUSE should have flushed
+ ** through outstanding messages. */
+ vchiq_log_error(vchiq_core_log_level,
+ "Failed to send RESUME "
+ "message");
+ BUG();
+ }
+ break;
+
+ case VCHIQ_CONNSTATE_PAUSE_TIMEOUT:
+ case VCHIQ_CONNSTATE_RESUME_TIMEOUT:
+ vchiq_platform_handle_timeout(state);
+ break;
+ default:
+ break;
+ }
+
+
+ }
+
+ DEBUG_TRACE(SLOT_HANDLER_LINE);
+ parse_rx_slots(state);
+ }
+ return 0;
+}
+
+
+/* Called by the recycle thread */
+static int
+recycle_func(void *v)
+{
+ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v;
+ VCHIQ_SHARED_STATE_T *local = state->local;
+
+ while (1) {
+ remote_event_wait(&local->recycle);
+
+ process_free_queue(state);
+ }
+ return 0;
+}
+
+
+/* Called by the sync thread */
+static int
+sync_func(void *v)
+{
+ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v;
+ VCHIQ_SHARED_STATE_T *local = state->local;
+ VCHIQ_HEADER_T *header = (VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state,
+ state->remote->slot_sync);
+
+ while (1) {
+ VCHIQ_SERVICE_T *service;
+ int msgid, size;
+ int type;
+ unsigned int localport, remoteport;
+
+ remote_event_wait(&local->sync_trigger);
+
+ rmb();
+
+ msgid = header->msgid;
+ size = header->size;
+ type = VCHIQ_MSG_TYPE(msgid);
+ localport = VCHIQ_MSG_DSTPORT(msgid);
+ remoteport = VCHIQ_MSG_SRCPORT(msgid);
+
+ service = find_service_by_port(state, localport);
+
+ if (!service) {
+ vchiq_log_error(vchiq_sync_log_level,
+ "%d: sf %s@%x (%d->%d) - "
+ "invalid/closed service %d",
+ state->id, msg_type_str(type),
+ (unsigned int)header,
+ remoteport, localport, localport);
+ release_message_sync(state, header);
+ continue;
+ }
+
+ if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) {
+ int svc_fourcc;
+
+ svc_fourcc = service
+ ? service->base.fourcc
+ : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
+ vchiq_log_trace(vchiq_sync_log_level,
+ "Rcvd Msg %s from %c%c%c%c s:%d d:%d len:%d",
+ msg_type_str(type),
+ VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
+ remoteport, localport, size);
+ if (size > 0)
+ vchiq_log_dump_mem("Rcvd", 0, header->data,
+ min(64, size));
+ }
+
+ switch (type) {
+ case VCHIQ_MSG_OPENACK:
+ if (size >= sizeof(struct vchiq_openack_payload)) {
+ const struct vchiq_openack_payload *payload =
+ (struct vchiq_openack_payload *)
+ header->data;
+ service->peer_version = payload->version;
+ }
+ vchiq_log_info(vchiq_sync_log_level,
+ "%d: sf OPENACK@%x,%x (%d->%d) v:%d",
+ state->id, (unsigned int)header, size,
+ remoteport, localport, service->peer_version);
+ if (service->srvstate == VCHIQ_SRVSTATE_OPENING) {
+ service->remoteport = remoteport;
+ vchiq_set_service_state(service,
+ VCHIQ_SRVSTATE_OPENSYNC);
+ service->sync = 1;
+ up(&service->remove_event);
+ }
+ release_message_sync(state, header);
+ break;
+
+ case VCHIQ_MSG_DATA:
+ vchiq_log_trace(vchiq_sync_log_level,
+ "%d: sf DATA@%x,%x (%d->%d)",
+ state->id, (unsigned int)header, size,
+ remoteport, localport);
+
+ if ((service->remoteport == remoteport) &&
+ (service->srvstate ==
+ VCHIQ_SRVSTATE_OPENSYNC)) {
+ if (make_service_callback(service,
+ VCHIQ_MESSAGE_AVAILABLE, header,
+ NULL) == VCHIQ_RETRY)
+ vchiq_log_error(vchiq_sync_log_level,
+ "synchronous callback to "
+ "service %d returns "
+ "VCHIQ_RETRY",
+ localport);
+ }
+ break;
+
+ default:
+ vchiq_log_error(vchiq_sync_log_level,
+ "%d: sf unexpected msgid %x@%x,%x",
+ state->id, msgid, (unsigned int)header, size);
+ release_message_sync(state, header);
+ break;
+ }
+
+ unlock_service(service);
+ }
+
+ return 0;
+}
+
+
+static void
+init_bulk_queue(VCHIQ_BULK_QUEUE_T *queue)
+{
+ queue->local_insert = 0;
+ queue->remote_insert = 0;
+ queue->process = 0;
+ queue->remote_notify = 0;
+ queue->remove = 0;
+}
+
+
+inline const char *
+get_conn_state_name(VCHIQ_CONNSTATE_T conn_state)
+{
+ return conn_state_names[conn_state];
+}
+
+
+VCHIQ_SLOT_ZERO_T *
+vchiq_init_slots(void *mem_base, int mem_size)
+{
+ int mem_align = (VCHIQ_SLOT_SIZE - (int)mem_base) & VCHIQ_SLOT_MASK;
+ VCHIQ_SLOT_ZERO_T *slot_zero =
+ (VCHIQ_SLOT_ZERO_T *)((char *)mem_base + mem_align);
+ int num_slots = (mem_size - mem_align)/VCHIQ_SLOT_SIZE;
+ int first_data_slot = VCHIQ_SLOT_ZERO_SLOTS;
+
+ /* Ensure there is enough memory to run an absolutely minimum system */
+ num_slots -= first_data_slot;
+
+ if (num_slots < 4) {
+ vchiq_log_error(vchiq_core_log_level,
+ "vchiq_init_slots - insufficient memory %x bytes",
+ mem_size);
+ return NULL;
+ }
+
+ memset(slot_zero, 0, sizeof(VCHIQ_SLOT_ZERO_T));
+
+ slot_zero->magic = VCHIQ_MAGIC;
+ slot_zero->version = VCHIQ_VERSION;
+ slot_zero->version_min = VCHIQ_VERSION_MIN;
+ slot_zero->slot_zero_size = sizeof(VCHIQ_SLOT_ZERO_T);
+ slot_zero->slot_size = VCHIQ_SLOT_SIZE;
+ slot_zero->max_slots = VCHIQ_MAX_SLOTS;
+ slot_zero->max_slots_per_side = VCHIQ_MAX_SLOTS_PER_SIDE;
+
+ slot_zero->master.slot_sync = first_data_slot;
+ slot_zero->master.slot_first = first_data_slot + 1;
+ slot_zero->master.slot_last = first_data_slot + (num_slots/2) - 1;
+ slot_zero->slave.slot_sync = first_data_slot + (num_slots/2);
+ slot_zero->slave.slot_first = first_data_slot + (num_slots/2) + 1;
+ slot_zero->slave.slot_last = first_data_slot + num_slots - 1;
+
+ return slot_zero;
+}
+
+VCHIQ_STATUS_T
+vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero,
+ int is_master)
+{
+ VCHIQ_SHARED_STATE_T *local;
+ VCHIQ_SHARED_STATE_T *remote;
+ VCHIQ_STATUS_T status;
+ char threadname[10];
+ static int id;
+ int i;
+
+ vchiq_log_warning(vchiq_core_log_level,
+ "%s: slot_zero = 0x%08lx, is_master = %d",
+ __func__, (unsigned long)slot_zero, is_master);
+
+ /* Check the input configuration */
+
+ if (slot_zero->magic != VCHIQ_MAGIC) {
+ vchiq_loud_error_header();
+ vchiq_loud_error("Invalid VCHIQ magic value found.");
+ vchiq_loud_error("slot_zero=%x: magic=%x (expected %x)",
+ (unsigned int)slot_zero, slot_zero->magic, VCHIQ_MAGIC);
+ vchiq_loud_error_footer();
+ return VCHIQ_ERROR;
+ }
+
+ if (slot_zero->version < VCHIQ_VERSION_MIN) {
+ vchiq_loud_error_header();
+ vchiq_loud_error("Incompatible VCHIQ versions found.");
+ vchiq_loud_error("slot_zero=%x: VideoCore version=%d "
+ "(minimum %d)",
+ (unsigned int)slot_zero, slot_zero->version,
+ VCHIQ_VERSION_MIN);
+ vchiq_loud_error("Restart with a newer VideoCore image.");
+ vchiq_loud_error_footer();
+ return VCHIQ_ERROR;
+ }
+
+ if (VCHIQ_VERSION < slot_zero->version_min) {
+ vchiq_loud_error_header();
+ vchiq_loud_error("Incompatible VCHIQ versions found.");
+ vchiq_loud_error("slot_zero=%x: version=%d (VideoCore "
+ "minimum %d)",
+ (unsigned int)slot_zero, VCHIQ_VERSION,
+ slot_zero->version_min);
+ vchiq_loud_error("Restart with a newer kernel.");
+ vchiq_loud_error_footer();
+ return VCHIQ_ERROR;
+ }
+
+ if ((slot_zero->slot_zero_size != sizeof(VCHIQ_SLOT_ZERO_T)) ||
+ (slot_zero->slot_size != VCHIQ_SLOT_SIZE) ||
+ (slot_zero->max_slots != VCHIQ_MAX_SLOTS) ||
+ (slot_zero->max_slots_per_side != VCHIQ_MAX_SLOTS_PER_SIDE)) {
+ vchiq_loud_error_header();
+ if (slot_zero->slot_zero_size != sizeof(VCHIQ_SLOT_ZERO_T))
+ vchiq_loud_error("slot_zero=%x: slot_zero_size=%x "
+ "(expected %x)",
+ (unsigned int)slot_zero,
+ slot_zero->slot_zero_size,
+ sizeof(VCHIQ_SLOT_ZERO_T));
+ if (slot_zero->slot_size != VCHIQ_SLOT_SIZE)
+ vchiq_loud_error("slot_zero=%x: slot_size=%d "
+ "(expected %d",
+ (unsigned int)slot_zero, slot_zero->slot_size,
+ VCHIQ_SLOT_SIZE);
+ if (slot_zero->max_slots != VCHIQ_MAX_SLOTS)
+ vchiq_loud_error("slot_zero=%x: max_slots=%d "
+ "(expected %d)",
+ (unsigned int)slot_zero, slot_zero->max_slots,
+ VCHIQ_MAX_SLOTS);
+ if (slot_zero->max_slots_per_side != VCHIQ_MAX_SLOTS_PER_SIDE)
+ vchiq_loud_error("slot_zero=%x: max_slots_per_side=%d "
+ "(expected %d)",
+ (unsigned int)slot_zero,
+ slot_zero->max_slots_per_side,
+ VCHIQ_MAX_SLOTS_PER_SIDE);
+ vchiq_loud_error_footer();
+ return VCHIQ_ERROR;
+ }
+
+ if (VCHIQ_VERSION < slot_zero->version)
+ slot_zero->version = VCHIQ_VERSION;
+
+ if (is_master) {
+ local = &slot_zero->master;
+ remote = &slot_zero->slave;
+ } else {
+ local = &slot_zero->slave;
+ remote = &slot_zero->master;
+ }
+
+ if (local->initialised) {
+ vchiq_loud_error_header();
+ if (remote->initialised)
+ vchiq_loud_error("local state has already been "
+ "initialised");
+ else
+ vchiq_loud_error("master/slave mismatch - two %ss",
+ is_master ? "master" : "slave");
+ vchiq_loud_error_footer();
+ return VCHIQ_ERROR;
+ }
+
+ memset(state, 0, sizeof(VCHIQ_STATE_T));
+
+ state->id = id++;
+ state->is_master = is_master;
+
+ /*
+ initialize shared state pointers
+ */
+
+ state->local = local;
+ state->remote = remote;
+ state->slot_data = (VCHIQ_SLOT_T *)slot_zero;
+
+ /*
+ initialize events and mutexes
+ */
+
+ sema_init(&state->connect, 0);
+ mutex_init(&state->mutex);
+ sema_init(&state->trigger_event, 0);
+ sema_init(&state->recycle_event, 0);
+ sema_init(&state->sync_trigger_event, 0);
+ sema_init(&state->sync_release_event, 0);
+
+ mutex_init(&state->slot_mutex);
+ mutex_init(&state->recycle_mutex);
+ mutex_init(&state->sync_mutex);
+ mutex_init(&state->bulk_transfer_mutex);
+
+ sema_init(&state->slot_available_event, 0);
+ sema_init(&state->slot_remove_event, 0);
+ sema_init(&state->data_quota_event, 0);
+
+ state->slot_queue_available = 0;
+
+ for (i = 0; i < VCHIQ_MAX_SERVICES; i++) {
+ VCHIQ_SERVICE_QUOTA_T *service_quota =
+ &state->service_quotas[i];
+ sema_init(&service_quota->quota_event, 0);
+ }
+
+ for (i = local->slot_first; i <= local->slot_last; i++) {
+ local->slot_queue[state->slot_queue_available++] = i;
+ up(&state->slot_available_event);
+ }
+
+ state->default_slot_quota = state->slot_queue_available/2;
+ state->default_message_quota =
+ min((unsigned short)(state->default_slot_quota * 256),
+ (unsigned short)~0);
+
+ state->previous_data_index = -1;
+ state->data_use_count = 0;
+ state->data_quota = state->slot_queue_available - 1;
+
+ local->trigger.event = &state->trigger_event;
+ remote_event_create(&local->trigger);
+ local->tx_pos = 0;
+
+ local->recycle.event = &state->recycle_event;
+ remote_event_create(&local->recycle);
+ local->slot_queue_recycle = state->slot_queue_available;
+
+ local->sync_trigger.event = &state->sync_trigger_event;
+ remote_event_create(&local->sync_trigger);
+
+ local->sync_release.event = &state->sync_release_event;
+ remote_event_create(&local->sync_release);
+
+ /* At start-of-day, the slot is empty and available */
+ ((VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state, local->slot_sync))->msgid
+ = VCHIQ_MSGID_PADDING;
+ remote_event_signal_local(&local->sync_release);
+
+ local->debug[DEBUG_ENTRIES] = DEBUG_MAX;
+
+ status = vchiq_platform_init_state(state);
+
+ /*
+ bring up slot handler thread
+ */
+ snprintf(threadname, sizeof(threadname), "VCHIQ-%d", state->id);
+ state->slot_handler_thread = kthread_create(&slot_handler_func,
+ (void *)state,
+ threadname);
+
+ if (state->slot_handler_thread == NULL) {
+ vchiq_loud_error_header();
+ vchiq_loud_error("couldn't create thread %s", threadname);
+ vchiq_loud_error_footer();
+ return VCHIQ_ERROR;
+ }
+ set_user_nice(state->slot_handler_thread, -19);
+ wake_up_process(state->slot_handler_thread);
+
+ snprintf(threadname, sizeof(threadname), "VCHIQr-%d", state->id);
+ state->recycle_thread = kthread_create(&recycle_func,
+ (void *)state,
+ threadname);
+ if (state->recycle_thread == NULL) {
+ vchiq_loud_error_header();
+ vchiq_loud_error("couldn't create thread %s", threadname);
+ vchiq_loud_error_footer();
+ return VCHIQ_ERROR;
+ }
+ set_user_nice(state->recycle_thread, -19);
+ wake_up_process(state->recycle_thread);
+
+ snprintf(threadname, sizeof(threadname), "VCHIQs-%d", state->id);
+ state->sync_thread = kthread_create(&sync_func,
+ (void *)state,
+ threadname);
+ if (state->sync_thread == NULL) {
+ vchiq_loud_error_header();
+ vchiq_loud_error("couldn't create thread %s", threadname);
+ vchiq_loud_error_footer();
+ return VCHIQ_ERROR;
+ }
+ set_user_nice(state->sync_thread, -20);
+ wake_up_process(state->sync_thread);
+
+ BUG_ON(state->id >= VCHIQ_MAX_STATES);
+ vchiq_states[state->id] = state;
+
+ /* Indicate readiness to the other side */
+ local->initialised = 1;
+
+ return status;
+}
+
+/* Called from application thread when a client or server service is created. */
+VCHIQ_SERVICE_T *
+vchiq_add_service_internal(VCHIQ_STATE_T *state,
+ const VCHIQ_SERVICE_PARAMS_T *params, int srvstate,
+ VCHIQ_INSTANCE_T instance, VCHIQ_USERDATA_TERM_T userdata_term)
+{
+ VCHIQ_SERVICE_T *service;
+
+ service = kmalloc(sizeof(VCHIQ_SERVICE_T), GFP_KERNEL);
+ if (service) {
+ service->base.fourcc = params->fourcc;
+ service->base.callback = params->callback;
+ service->base.userdata = params->userdata;
+ service->handle = VCHIQ_SERVICE_HANDLE_INVALID;
+ service->ref_count = 1;
+ service->srvstate = VCHIQ_SRVSTATE_FREE;
+ service->userdata_term = userdata_term;
+ service->localport = VCHIQ_PORT_FREE;
+ service->remoteport = VCHIQ_PORT_FREE;
+
+ service->public_fourcc = (srvstate == VCHIQ_SRVSTATE_OPENING) ?
+ VCHIQ_FOURCC_INVALID : params->fourcc;
+ service->client_id = 0;
+ service->auto_close = 1;
+ service->sync = 0;
+ service->closing = 0;
+ service->trace = 0;
+ atomic_set(&service->poll_flags, 0);
+ service->version = params->version;
+ service->version_min = params->version_min;
+ service->state = state;
+ service->instance = instance;
+ service->service_use_count = 0;
+ init_bulk_queue(&service->bulk_tx);
+ init_bulk_queue(&service->bulk_rx);
+ sema_init(&service->remove_event, 0);
+ sema_init(&service->bulk_remove_event, 0);
+ mutex_init(&service->bulk_mutex);
+ memset(&service->stats, 0, sizeof(service->stats));
+ } else {
+ vchiq_log_error(vchiq_core_log_level,
+ "Out of memory");
+ }
+
+ if (service) {
+ VCHIQ_SERVICE_T **pservice = NULL;
+ int i;
+
+ /* Although it is perfectly possible to use service_spinlock
+ ** to protect the creation of services, it is overkill as it
+ ** disables interrupts while the array is searched.
+ ** The only danger is of another thread trying to create a
+ ** service - service deletion is safe.
+ ** Therefore it is preferable to use state->mutex which,
+ ** although slower to claim, doesn't block interrupts while
+ ** it is held.
+ */
+
+ mutex_lock(&state->mutex);
+
+ /* Prepare to use a previously unused service */
+ if (state->unused_service < VCHIQ_MAX_SERVICES)
+ pservice = &state->services[state->unused_service];
+
+ if (srvstate == VCHIQ_SRVSTATE_OPENING) {
+ for (i = 0; i < state->unused_service; i++) {
+ VCHIQ_SERVICE_T *srv = state->services[i];
+ if (!srv) {
+ pservice = &state->services[i];
+ break;
+ }
+ }
+ } else {
+ for (i = (state->unused_service - 1); i >= 0; i--) {
+ VCHIQ_SERVICE_T *srv = state->services[i];
+ if (!srv)
+ pservice = &state->services[i];
+ else if ((srv->public_fourcc == params->fourcc)
+ && ((srv->instance != instance) ||
+ (srv->base.callback !=
+ params->callback))) {
+ /* There is another server using this
+ ** fourcc which doesn't match. */
+ pservice = NULL;
+ break;
+ }
+ }
+ }
+
+ if (pservice) {
+ service->localport = (pservice - state->services);
+ if (!handle_seq)
+ handle_seq = VCHIQ_MAX_STATES *
+ VCHIQ_MAX_SERVICES;
+ service->handle = handle_seq |
+ (state->id * VCHIQ_MAX_SERVICES) |
+ service->localport;
+ handle_seq += VCHIQ_MAX_STATES * VCHIQ_MAX_SERVICES;
+ *pservice = service;
+ if (pservice == &state->services[state->unused_service])
+ state->unused_service++;
+ }
+
+ mutex_unlock(&state->mutex);
+
+ if (!pservice) {
+ kfree(service);
+ service = NULL;
+ }
+ }
+
+ if (service) {
+ VCHIQ_SERVICE_QUOTA_T *service_quota =
+ &state->service_quotas[service->localport];
+ service_quota->slot_quota = state->default_slot_quota;
+ service_quota->message_quota = state->default_message_quota;
+ if (service_quota->slot_use_count == 0)
+ service_quota->previous_tx_index =
+ SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos)
+ - 1;
+
+ /* Bring this service online */
+ vchiq_set_service_state(service, srvstate);
+
+ vchiq_log_info(vchiq_core_msg_log_level,
+ "%s Service %c%c%c%c SrcPort:%d",
+ (srvstate == VCHIQ_SRVSTATE_OPENING)
+ ? "Open" : "Add",
+ VCHIQ_FOURCC_AS_4CHARS(params->fourcc),
+ service->localport);
+ }
+
+ /* Don't unlock the service - leave it with a ref_count of 1. */
+
+ return service;
+}
+
+VCHIQ_STATUS_T
+vchiq_open_service_internal(VCHIQ_SERVICE_T *service, int client_id)
+{
+ struct vchiq_open_payload payload = {
+ service->base.fourcc,
+ client_id,
+ service->version,
+ service->version_min
+ };
+ VCHIQ_ELEMENT_T body = { &payload, sizeof(payload) };
+ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+
+ service->client_id = client_id;
+ vchiq_use_service_internal(service);
+ status = queue_message(service->state, NULL,
+ VCHIQ_MAKE_MSG(VCHIQ_MSG_OPEN, service->localport, 0),
+ &body, 1, sizeof(payload), QMFLAGS_IS_BLOCKING);
+ if (status == VCHIQ_SUCCESS) {
+ /* Wait for the ACK/NAK */
+ if (down_interruptible(&service->remove_event) != 0) {
+ status = VCHIQ_RETRY;
+ vchiq_release_service_internal(service);
+ } else if ((service->srvstate != VCHIQ_SRVSTATE_OPEN) &&
+ (service->srvstate != VCHIQ_SRVSTATE_OPENSYNC)) {
+ if (service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT)
+ vchiq_log_error(vchiq_core_log_level,
+ "%d: osi - srvstate = %s (ref %d)",
+ service->state->id,
+ srvstate_names[service->srvstate],
+ service->ref_count);
+ status = VCHIQ_ERROR;
+ VCHIQ_SERVICE_STATS_INC(service, error_count);
+ vchiq_release_service_internal(service);
+ }
+ }
+ return status;
+}
+
+static void
+release_service_messages(VCHIQ_SERVICE_T *service)
+{
+ VCHIQ_STATE_T *state = service->state;
+ int slot_last = state->remote->slot_last;
+ int i;
+
+ /* Release any claimed messages aimed at this service */
+
+ if (service->sync) {
+ VCHIQ_HEADER_T *header =
+ (VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state,
+ state->remote->slot_sync);
+ if (VCHIQ_MSG_DSTPORT(header->msgid) == service->localport)
+ release_message_sync(state, header);
+
+ return;
+ }
+
+ for (i = state->remote->slot_first; i <= slot_last; i++) {
+ VCHIQ_SLOT_INFO_T *slot_info =
+ SLOT_INFO_FROM_INDEX(state, i);
+ if (slot_info->release_count != slot_info->use_count) {
+ char *data =
+ (char *)SLOT_DATA_FROM_INDEX(state, i);
+ unsigned int pos, end;
+
+ end = VCHIQ_SLOT_SIZE;
+ if (data == state->rx_data)
+ /* This buffer is still being read from - stop
+ ** at the current read position */
+ end = state->rx_pos & VCHIQ_SLOT_MASK;
+
+ pos = 0;
+
+ while (pos < end) {
+ VCHIQ_HEADER_T *header =
+ (VCHIQ_HEADER_T *)(data + pos);
+ int msgid = header->msgid;
+ int port = VCHIQ_MSG_DSTPORT(msgid);
+ if ((port == service->localport) &&
+ (msgid & VCHIQ_MSGID_CLAIMED)) {
+ vchiq_log_info(vchiq_core_log_level,
+ " fsi - hdr %x",
+ (unsigned int)header);
+ release_slot(state, slot_info, header,
+ NULL);
+ }
+ pos += calc_stride(header->size);
+ if (pos > VCHIQ_SLOT_SIZE) {
+ vchiq_log_error(vchiq_core_log_level,
+ "fsi - pos %x: header %x, "
+ "msgid %x, header->msgid %x, "
+ "header->size %x",
+ pos, (unsigned int)header,
+ msgid, header->msgid,
+ header->size);
+ WARN(1, "invalid slot position\n");
+ }
+ }
+ }
+ }
+}
+
+static int
+do_abort_bulks(VCHIQ_SERVICE_T *service)
+{
+ VCHIQ_STATUS_T status;
+
+ /* Abort any outstanding bulk transfers */
+ if (mutex_lock_interruptible(&service->bulk_mutex) != 0)
+ return 0;
+ abort_outstanding_bulks(service, &service->bulk_tx);
+ abort_outstanding_bulks(service, &service->bulk_rx);
+ mutex_unlock(&service->bulk_mutex);
+
+ status = notify_bulks(service, &service->bulk_tx, 0/*!retry_poll*/);
+ if (status == VCHIQ_SUCCESS)
+ status = notify_bulks(service, &service->bulk_rx,
+ 0/*!retry_poll*/);
+ return (status == VCHIQ_SUCCESS);
+}
+
+static VCHIQ_STATUS_T
+close_service_complete(VCHIQ_SERVICE_T *service, int failstate)
+{
+ VCHIQ_STATUS_T status;
+ int is_server = (service->public_fourcc != VCHIQ_FOURCC_INVALID);
+ int newstate;
+
+ switch (service->srvstate) {
+ case VCHIQ_SRVSTATE_OPEN:
+ case VCHIQ_SRVSTATE_CLOSESENT:
+ case VCHIQ_SRVSTATE_CLOSERECVD:
+ if (is_server) {
+ if (service->auto_close) {
+ service->client_id = 0;
+ service->remoteport = VCHIQ_PORT_FREE;
+ newstate = VCHIQ_SRVSTATE_LISTENING;
+ } else
+ newstate = VCHIQ_SRVSTATE_CLOSEWAIT;
+ } else
+ newstate = VCHIQ_SRVSTATE_CLOSED;
+ vchiq_set_service_state(service, newstate);
+ break;
+ case VCHIQ_SRVSTATE_LISTENING:
+ break;
+ default:
+ vchiq_log_error(vchiq_core_log_level,
+ "close_service_complete(%x) called in state %s",
+ service->handle, srvstate_names[service->srvstate]);
+ WARN(1, "close_service_complete in unexpected state\n");
+ return VCHIQ_ERROR;
+ }
+
+ status = make_service_callback(service,
+ VCHIQ_SERVICE_CLOSED, NULL, NULL);
+
+ if (status != VCHIQ_RETRY) {
+ int uc = service->service_use_count;
+ int i;
+ /* Complete the close process */
+ for (i = 0; i < uc; i++)
+ /* cater for cases where close is forced and the
+ ** client may not close all it's handles */
+ vchiq_release_service_internal(service);
+
+ service->client_id = 0;
+ service->remoteport = VCHIQ_PORT_FREE;
+
+ if (service->srvstate == VCHIQ_SRVSTATE_CLOSED)
+ vchiq_free_service_internal(service);
+ else if (service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT) {
+ if (is_server)
+ service->closing = 0;
+
+ up(&service->remove_event);
+ }
+ } else
+ vchiq_set_service_state(service, failstate);
+
+ return status;
+}
+
+/* Called by the slot handler */
+VCHIQ_STATUS_T
+vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd)
+{
+ VCHIQ_STATE_T *state = service->state;
+ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+ int is_server = (service->public_fourcc != VCHIQ_FOURCC_INVALID);
+
+ vchiq_log_info(vchiq_core_log_level, "%d: csi:%d,%d (%s)",
+ service->state->id, service->localport, close_recvd,
+ srvstate_names[service->srvstate]);
+
+ switch (service->srvstate) {
+ case VCHIQ_SRVSTATE_CLOSED:
+ case VCHIQ_SRVSTATE_HIDDEN:
+ case VCHIQ_SRVSTATE_LISTENING:
+ case VCHIQ_SRVSTATE_CLOSEWAIT:
+ if (close_recvd)
+ vchiq_log_error(vchiq_core_log_level,
+ "vchiq_close_service_internal(1) called "
+ "in state %s",
+ srvstate_names[service->srvstate]);
+ else if (is_server) {
+ if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) {
+ status = VCHIQ_ERROR;
+ } else {
+ service->client_id = 0;
+ service->remoteport = VCHIQ_PORT_FREE;
+ if (service->srvstate ==
+ VCHIQ_SRVSTATE_CLOSEWAIT)
+ vchiq_set_service_state(service,
+ VCHIQ_SRVSTATE_LISTENING);
+ }
+ up(&service->remove_event);
+ } else
+ vchiq_free_service_internal(service);
+ break;
+ case VCHIQ_SRVSTATE_OPENING:
+ if (close_recvd) {
+ /* The open was rejected - tell the user */
+ vchiq_set_service_state(service,
+ VCHIQ_SRVSTATE_CLOSEWAIT);
+ up(&service->remove_event);
+ } else {
+ /* Shutdown mid-open - let the other side know */
+ status = queue_message(state, service,
+ VCHIQ_MAKE_MSG
+ (VCHIQ_MSG_CLOSE,
+ service->localport,
+ VCHIQ_MSG_DSTPORT(service->remoteport)),
+ NULL, 0, 0, 0);
+ }
+ break;
+
+ case VCHIQ_SRVSTATE_OPENSYNC:
+ mutex_lock(&state->sync_mutex);
+ /* Drop through */
+
+ case VCHIQ_SRVSTATE_OPEN:
+ if (state->is_master || close_recvd) {
+ if (!do_abort_bulks(service))
+ status = VCHIQ_RETRY;
+ }
+
+ release_service_messages(service);
+
+ if (status == VCHIQ_SUCCESS)
+ status = queue_message(state, service,
+ VCHIQ_MAKE_MSG
+ (VCHIQ_MSG_CLOSE,
+ service->localport,
+ VCHIQ_MSG_DSTPORT(service->remoteport)),
+ NULL, 0, 0, QMFLAGS_NO_MUTEX_UNLOCK);
+
+ if (status == VCHIQ_SUCCESS) {
+ if (!close_recvd) {
+ /* Change the state while the mutex is
+ still held */
+ vchiq_set_service_state(service,
+ VCHIQ_SRVSTATE_CLOSESENT);
+ mutex_unlock(&state->slot_mutex);
+ if (service->sync)
+ mutex_unlock(&state->sync_mutex);
+ break;
+ }
+ } else if (service->srvstate == VCHIQ_SRVSTATE_OPENSYNC) {
+ mutex_unlock(&state->sync_mutex);
+ break;
+ } else
+ break;
+
+ /* Change the state while the mutex is still held */
+ vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSERECVD);
+ mutex_unlock(&state->slot_mutex);
+ if (service->sync)
+ mutex_unlock(&state->sync_mutex);
+
+ status = close_service_complete(service,
+ VCHIQ_SRVSTATE_CLOSERECVD);
+ break;
+
+ case VCHIQ_SRVSTATE_CLOSESENT:
+ if (!close_recvd)
+ /* This happens when a process is killed mid-close */
+ break;
+
+ if (!state->is_master) {
+ if (!do_abort_bulks(service)) {
+ status = VCHIQ_RETRY;
+ break;
+ }
+ }
+
+ if (status == VCHIQ_SUCCESS)
+ status = close_service_complete(service,
+ VCHIQ_SRVSTATE_CLOSERECVD);
+ break;
+
+ case VCHIQ_SRVSTATE_CLOSERECVD:
+ if (!close_recvd && is_server)
+ /* Force into LISTENING mode */
+ vchiq_set_service_state(service,
+ VCHIQ_SRVSTATE_LISTENING);
+ status = close_service_complete(service,
+ VCHIQ_SRVSTATE_CLOSERECVD);
+ break;
+
+ default:
+ vchiq_log_error(vchiq_core_log_level,
+ "vchiq_close_service_internal(%d) called in state %s",
+ close_recvd, srvstate_names[service->srvstate]);
+ break;
+ }
+
+ return status;
+}
+
+/* Called from the application process upon process death */
+void
+vchiq_terminate_service_internal(VCHIQ_SERVICE_T *service)
+{
+ VCHIQ_STATE_T *state = service->state;
+
+ vchiq_log_info(vchiq_core_log_level, "%d: tsi - (%d<->%d)",
+ state->id, service->localport, service->remoteport);
+
+ mark_service_closing(service);
+
+ /* Mark the service for removal by the slot handler */
+ request_poll(state, service, VCHIQ_POLL_REMOVE);
+}
+
+/* Called from the slot handler */
+void
+vchiq_free_service_internal(VCHIQ_SERVICE_T *service)
+{
+ VCHIQ_STATE_T *state = service->state;
+
+ vchiq_log_info(vchiq_core_log_level, "%d: fsi - (%d)",
+ state->id, service->localport);
+
+ switch (service->srvstate) {
+ case VCHIQ_SRVSTATE_OPENING:
+ case VCHIQ_SRVSTATE_CLOSED:
+ case VCHIQ_SRVSTATE_HIDDEN:
+ case VCHIQ_SRVSTATE_LISTENING:
+ case VCHIQ_SRVSTATE_CLOSEWAIT:
+ break;
+ default:
+ vchiq_log_error(vchiq_core_log_level,
+ "%d: fsi - (%d) in state %s",
+ state->id, service->localport,
+ srvstate_names[service->srvstate]);
+ return;
+ }
+
+ vchiq_set_service_state(service, VCHIQ_SRVSTATE_FREE);
+
+ up(&service->remove_event);
+
+ /* Release the initial lock */
+ unlock_service(service);
+}
+
+VCHIQ_STATUS_T
+vchiq_connect_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance)
+{
+ VCHIQ_SERVICE_T *service;
+ int i;
+
+ /* Find all services registered to this client and enable them. */
+ i = 0;
+ while ((service = next_service_by_instance(state, instance,
+ &i)) != NULL) {
+ if (service->srvstate == VCHIQ_SRVSTATE_HIDDEN)
+ vchiq_set_service_state(service,
+ VCHIQ_SRVSTATE_LISTENING);
+ unlock_service(service);
+ }
+
+ if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED) {
+ if (queue_message(state, NULL,
+ VCHIQ_MAKE_MSG(VCHIQ_MSG_CONNECT, 0, 0), NULL, 0,
+ 0, QMFLAGS_IS_BLOCKING) == VCHIQ_RETRY)
+ return VCHIQ_RETRY;
+
+ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTING);
+ }
+
+ if (state->conn_state == VCHIQ_CONNSTATE_CONNECTING) {
+ if (down_interruptible(&state->connect) != 0)
+ return VCHIQ_RETRY;
+
+ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
+ up(&state->connect);
+ }
+
+ return VCHIQ_SUCCESS;
+}
+
+VCHIQ_STATUS_T
+vchiq_shutdown_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance)
+{
+ VCHIQ_SERVICE_T *service;
+ int i;
+
+ /* Find all services registered to this client and enable them. */
+ i = 0;
+ while ((service = next_service_by_instance(state, instance,
+ &i)) != NULL) {
+ (void)vchiq_remove_service(service->handle);
+ unlock_service(service);
+ }
+
+ return VCHIQ_SUCCESS;
+}
+
+VCHIQ_STATUS_T
+vchiq_pause_internal(VCHIQ_STATE_T *state)
+{
+ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+
+ switch (state->conn_state) {
+ case VCHIQ_CONNSTATE_CONNECTED:
+ /* Request a pause */
+ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSING);
+ request_poll(state, NULL, 0);
+ break;
+ default:
+ vchiq_log_error(vchiq_core_log_level,
+ "vchiq_pause_internal in state %s\n",
+ conn_state_names[state->conn_state]);
+ status = VCHIQ_ERROR;
+ VCHIQ_STATS_INC(state, error_count);
+ break;
+ }
+
+ return status;
+}
+
+VCHIQ_STATUS_T
+vchiq_resume_internal(VCHIQ_STATE_T *state)
+{
+ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+
+ if (state->conn_state == VCHIQ_CONNSTATE_PAUSED) {
+ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_RESUMING);
+ request_poll(state, NULL, 0);
+ } else {
+ status = VCHIQ_ERROR;
+ VCHIQ_STATS_INC(state, error_count);
+ }
+
+ return status;
+}
+
+VCHIQ_STATUS_T
+vchiq_close_service(VCHIQ_SERVICE_HANDLE_T handle)
+{
+ /* Unregister the service */
+ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+
+ if (!service)
+ return VCHIQ_ERROR;
+
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: close_service:%d",
+ service->state->id, service->localport);
+
+ if ((service->srvstate == VCHIQ_SRVSTATE_FREE) ||
+ (service->srvstate == VCHIQ_SRVSTATE_LISTENING) ||
+ (service->srvstate == VCHIQ_SRVSTATE_HIDDEN)) {
+ unlock_service(service);
+ return VCHIQ_ERROR;
+ }
+
+ mark_service_closing(service);
+
+ if (current == service->state->slot_handler_thread) {
+ status = vchiq_close_service_internal(service,
+ 0/*!close_recvd*/);
+ BUG_ON(status == VCHIQ_RETRY);
+ } else {
+ /* Mark the service for termination by the slot handler */
+ request_poll(service->state, service, VCHIQ_POLL_TERMINATE);
+ }
+
+ while (1) {
+ if (down_interruptible(&service->remove_event) != 0) {
+ status = VCHIQ_RETRY;
+ break;
+ }
+
+ if ((service->srvstate == VCHIQ_SRVSTATE_FREE) ||
+ (service->srvstate == VCHIQ_SRVSTATE_LISTENING) ||
+ (service->srvstate == VCHIQ_SRVSTATE_OPEN))
+ break;
+
+ vchiq_log_warning(vchiq_core_log_level,
+ "%d: close_service:%d - waiting in state %s",
+ service->state->id, service->localport,
+ srvstate_names[service->srvstate]);
+ }
+
+ if ((status == VCHIQ_SUCCESS) &&
+ (service->srvstate != VCHIQ_SRVSTATE_FREE) &&
+ (service->srvstate != VCHIQ_SRVSTATE_LISTENING))
+ status = VCHIQ_ERROR;
+
+ unlock_service(service);
+
+ return status;
+}
+
+VCHIQ_STATUS_T
+vchiq_remove_service(VCHIQ_SERVICE_HANDLE_T handle)
+{
+ /* Unregister the service */
+ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+
+ if (!service)
+ return VCHIQ_ERROR;
+
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: remove_service:%d",
+ service->state->id, service->localport);
+
+ if (service->srvstate == VCHIQ_SRVSTATE_FREE) {
+ unlock_service(service);
+ return VCHIQ_ERROR;
+ }
+
+ mark_service_closing(service);
+
+ if ((service->srvstate == VCHIQ_SRVSTATE_HIDDEN) ||
+ (current == service->state->slot_handler_thread)) {
+ /* Make it look like a client, because it must be removed and
+ not left in the LISTENING state. */
+ service->public_fourcc = VCHIQ_FOURCC_INVALID;
+
+ status = vchiq_close_service_internal(service,
+ 0/*!close_recvd*/);
+ BUG_ON(status == VCHIQ_RETRY);
+ } else {
+ /* Mark the service for removal by the slot handler */
+ request_poll(service->state, service, VCHIQ_POLL_REMOVE);
+ }
+ while (1) {
+ if (down_interruptible(&service->remove_event) != 0) {
+ status = VCHIQ_RETRY;
+ break;
+ }
+
+ if ((service->srvstate == VCHIQ_SRVSTATE_FREE) ||
+ (service->srvstate == VCHIQ_SRVSTATE_OPEN))
+ break;
+
+ vchiq_log_warning(vchiq_core_log_level,
+ "%d: remove_service:%d - waiting in state %s",
+ service->state->id, service->localport,
+ srvstate_names[service->srvstate]);
+ }
+
+ if ((status == VCHIQ_SUCCESS) &&
+ (service->srvstate != VCHIQ_SRVSTATE_FREE))
+ status = VCHIQ_ERROR;
+
+ unlock_service(service);
+
+ return status;
+}
+
+
+/* This function may be called by kernel threads or user threads.
+ * User threads may receive VCHIQ_RETRY to indicate that a signal has been
+ * received and the call should be retried after being returned to user
+ * context.
+ * When called in blocking mode, the userdata field points to a bulk_waiter
+ * structure.
+ */
+VCHIQ_STATUS_T
+vchiq_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle,
+ VCHI_MEM_HANDLE_T memhandle, void *offset, int size, void *userdata,
+ VCHIQ_BULK_MODE_T mode, VCHIQ_BULK_DIR_T dir)
+{
+ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ VCHIQ_BULK_QUEUE_T *queue;
+ VCHIQ_BULK_T *bulk;
+ VCHIQ_STATE_T *state;
+ struct bulk_waiter *bulk_waiter = NULL;
+ const char dir_char = (dir == VCHIQ_BULK_TRANSMIT) ? 't' : 'r';
+ const int dir_msgtype = (dir == VCHIQ_BULK_TRANSMIT) ?
+ VCHIQ_MSG_BULK_TX : VCHIQ_MSG_BULK_RX;
+ VCHIQ_STATUS_T status = VCHIQ_ERROR;
+
+ if (!service ||
+ (service->srvstate != VCHIQ_SRVSTATE_OPEN) ||
+ ((memhandle == VCHI_MEM_HANDLE_INVALID) && (offset == NULL)) ||
+ (vchiq_check_service(service) != VCHIQ_SUCCESS))
+ goto error_exit;
+
+ switch (mode) {
+ case VCHIQ_BULK_MODE_NOCALLBACK:
+ case VCHIQ_BULK_MODE_CALLBACK:
+ break;
+ case VCHIQ_BULK_MODE_BLOCKING:
+ bulk_waiter = (struct bulk_waiter *)userdata;
+ sema_init(&bulk_waiter->event, 0);
+ bulk_waiter->actual = 0;
+ bulk_waiter->bulk = NULL;
+ break;
+ case VCHIQ_BULK_MODE_WAITING:
+ bulk_waiter = (struct bulk_waiter *)userdata;
+ bulk = bulk_waiter->bulk;
+ goto waiting;
+ default:
+ goto error_exit;
+ }
+
+ state = service->state;
+
+ queue = (dir == VCHIQ_BULK_TRANSMIT) ?
+ &service->bulk_tx : &service->bulk_rx;
+
+ if (mutex_lock_interruptible(&service->bulk_mutex) != 0) {
+ status = VCHIQ_RETRY;
+ goto error_exit;
+ }
+
+ if (queue->local_insert == queue->remove + VCHIQ_NUM_SERVICE_BULKS) {
+ VCHIQ_SERVICE_STATS_INC(service, bulk_stalls);
+ do {
+ mutex_unlock(&service->bulk_mutex);
+ if (down_interruptible(&service->bulk_remove_event)
+ != 0) {
+ status = VCHIQ_RETRY;
+ goto error_exit;
+ }
+ if (mutex_lock_interruptible(&service->bulk_mutex)
+ != 0) {
+ status = VCHIQ_RETRY;
+ goto error_exit;
+ }
+ } while (queue->local_insert == queue->remove +
+ VCHIQ_NUM_SERVICE_BULKS);
+ }
+
+ bulk = &queue->bulks[BULK_INDEX(queue->local_insert)];
+
+ bulk->mode = mode;
+ bulk->dir = dir;
+ bulk->userdata = userdata;
+ bulk->size = size;
+ bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED;
+
+ if (vchiq_prepare_bulk_data(bulk, memhandle, offset, size, dir) !=
+ VCHIQ_SUCCESS)
+ goto unlock_error_exit;
+
+ wmb();
+
+ vchiq_log_info(vchiq_core_log_level,
+ "%d: bt (%d->%d) %cx %x@%x %x",
+ state->id,
+ service->localport, service->remoteport, dir_char,
+ size, (unsigned int)bulk->data, (unsigned int)userdata);
+
+ /* The slot mutex must be held when the service is being closed, so
+ claim it here to ensure that isn't happening */
+ if (mutex_lock_interruptible(&state->slot_mutex) != 0) {
+ status = VCHIQ_RETRY;
+ goto cancel_bulk_error_exit;
+ }
+
+ if (service->srvstate != VCHIQ_SRVSTATE_OPEN)
+ goto unlock_both_error_exit;
+
+ if (state->is_master) {
+ queue->local_insert++;
+ if (resolve_bulks(service, queue))
+ request_poll(state, service,
+ (dir == VCHIQ_BULK_TRANSMIT) ?
+ VCHIQ_POLL_TXNOTIFY : VCHIQ_POLL_RXNOTIFY);
+ } else {
+ int payload[2] = { (int)bulk->data, bulk->size };
+ VCHIQ_ELEMENT_T element = { payload, sizeof(payload) };
+
+ status = queue_message(state, NULL,
+ VCHIQ_MAKE_MSG(dir_msgtype,
+ service->localport, service->remoteport),
+ &element, 1, sizeof(payload),
+ QMFLAGS_IS_BLOCKING |
+ QMFLAGS_NO_MUTEX_LOCK |
+ QMFLAGS_NO_MUTEX_UNLOCK);
+ if (status != VCHIQ_SUCCESS) {
+ goto unlock_both_error_exit;
+ }
+ queue->local_insert++;
+ }
+
+ mutex_unlock(&state->slot_mutex);
+ mutex_unlock(&service->bulk_mutex);
+
+ vchiq_log_trace(vchiq_core_log_level,
+ "%d: bt:%d %cx li=%x ri=%x p=%x",
+ state->id,
+ service->localport, dir_char,
+ queue->local_insert, queue->remote_insert, queue->process);
+
+waiting:
+ unlock_service(service);
+
+ status = VCHIQ_SUCCESS;
+
+ if (bulk_waiter) {
+ bulk_waiter->bulk = bulk;
+ if (down_interruptible(&bulk_waiter->event) != 0)
+ status = VCHIQ_RETRY;
+ else if (bulk_waiter->actual == VCHIQ_BULK_ACTUAL_ABORTED)
+ status = VCHIQ_ERROR;
+ }
+
+ return status;
+
+unlock_both_error_exit:
+ mutex_unlock(&state->slot_mutex);
+cancel_bulk_error_exit:
+ vchiq_complete_bulk(bulk);
+unlock_error_exit:
+ mutex_unlock(&service->bulk_mutex);
+
+error_exit:
+ if (service)
+ unlock_service(service);
+ return status;
+}
+
+VCHIQ_STATUS_T
+vchiq_queue_message(VCHIQ_SERVICE_HANDLE_T handle,
+ const VCHIQ_ELEMENT_T *elements, unsigned int count)
+{
+ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ VCHIQ_STATUS_T status = VCHIQ_ERROR;
+
+ unsigned int size = 0;
+ unsigned int i;
+
+ if (!service ||
+ (vchiq_check_service(service) != VCHIQ_SUCCESS))
+ goto error_exit;
+
+ for (i = 0; i < (unsigned int)count; i++) {
+ if (elements[i].size) {
+ if (elements[i].data == NULL) {
+ VCHIQ_SERVICE_STATS_INC(service, error_count);
+ goto error_exit;
+ }
+ size += elements[i].size;
+ }
+ }
+
+ if (size > VCHIQ_MAX_MSG_SIZE) {
+ VCHIQ_SERVICE_STATS_INC(service, error_count);
+ goto error_exit;
+ }
+
+ switch (service->srvstate) {
+ case VCHIQ_SRVSTATE_OPEN:
+ status = queue_message(service->state, service,
+ VCHIQ_MAKE_MSG(VCHIQ_MSG_DATA,
+ service->localport,
+ service->remoteport),
+ elements, count, size, 1);
+ break;
+ case VCHIQ_SRVSTATE_OPENSYNC:
+ status = queue_message_sync(service->state, service,
+ VCHIQ_MAKE_MSG(VCHIQ_MSG_DATA,
+ service->localport,
+ service->remoteport),
+ elements, count, size, 1);
+ break;
+ default:
+ status = VCHIQ_ERROR;
+ break;
+ }
+
+error_exit:
+ if (service)
+ unlock_service(service);
+
+ return status;
+}
+
+void
+vchiq_release_message(VCHIQ_SERVICE_HANDLE_T handle, VCHIQ_HEADER_T *header)
+{
+ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ VCHIQ_SHARED_STATE_T *remote;
+ VCHIQ_STATE_T *state;
+ int slot_index;
+
+ if (!service)
+ return;
+
+ state = service->state;
+ remote = state->remote;
+
+ slot_index = SLOT_INDEX_FROM_DATA(state, (void *)header);
+
+ if ((slot_index >= remote->slot_first) &&
+ (slot_index <= remote->slot_last)) {
+ int msgid = header->msgid;
+ if (msgid & VCHIQ_MSGID_CLAIMED) {
+ VCHIQ_SLOT_INFO_T *slot_info =
+ SLOT_INFO_FROM_INDEX(state, slot_index);
+
+ release_slot(state, slot_info, header, service);
+ }
+ } else if (slot_index == remote->slot_sync)
+ release_message_sync(state, header);
+
+ unlock_service(service);
+}
+
+static void
+release_message_sync(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header)
+{
+ header->msgid = VCHIQ_MSGID_PADDING;
+ wmb();
+ remote_event_signal(&state->remote->sync_release);
+}
+
+VCHIQ_STATUS_T
+vchiq_get_peer_version(VCHIQ_SERVICE_HANDLE_T handle, short *peer_version)
+{
+ VCHIQ_STATUS_T status = VCHIQ_ERROR;
+ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+
+ if (!service ||
+ (vchiq_check_service(service) != VCHIQ_SUCCESS) ||
+ !peer_version)
+ goto exit;
+ *peer_version = service->peer_version;
+ status = VCHIQ_SUCCESS;
+
+exit:
+ if (service)
+ unlock_service(service);
+ return status;
+}
+
+VCHIQ_STATUS_T
+vchiq_get_config(VCHIQ_INSTANCE_T instance,
+ int config_size, VCHIQ_CONFIG_T *pconfig)
+{
+ VCHIQ_CONFIG_T config;
+
+ (void)instance;
+
+ config.max_msg_size = VCHIQ_MAX_MSG_SIZE;
+ config.bulk_threshold = VCHIQ_MAX_MSG_SIZE;
+ config.max_outstanding_bulks = VCHIQ_NUM_SERVICE_BULKS;
+ config.max_services = VCHIQ_MAX_SERVICES;
+ config.version = VCHIQ_VERSION;
+ config.version_min = VCHIQ_VERSION_MIN;
+
+ if (config_size > sizeof(VCHIQ_CONFIG_T))
+ return VCHIQ_ERROR;
+
+ memcpy(pconfig, &config,
+ min(config_size, (int)(sizeof(VCHIQ_CONFIG_T))));
+
+ return VCHIQ_SUCCESS;
+}
+
+VCHIQ_STATUS_T
+vchiq_set_service_option(VCHIQ_SERVICE_HANDLE_T handle,
+ VCHIQ_SERVICE_OPTION_T option, int value)
+{
+ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ VCHIQ_STATUS_T status = VCHIQ_ERROR;
+
+ if (service) {
+ switch (option) {
+ case VCHIQ_SERVICE_OPTION_AUTOCLOSE:
+ service->auto_close = value;
+ status = VCHIQ_SUCCESS;
+ break;
+
+ case VCHIQ_SERVICE_OPTION_SLOT_QUOTA: {
+ VCHIQ_SERVICE_QUOTA_T *service_quota =
+ &service->state->service_quotas[
+ service->localport];
+ if (value == 0)
+ value = service->state->default_slot_quota;
+ if ((value >= service_quota->slot_use_count) &&
+ (value < (unsigned short)~0)) {
+ service_quota->slot_quota = value;
+ if ((value >= service_quota->slot_use_count) &&
+ (service_quota->message_quota >=
+ service_quota->message_use_count)) {
+ /* Signal the service that it may have
+ ** dropped below its quota */
+ up(&service_quota->quota_event);
+ }
+ status = VCHIQ_SUCCESS;
+ }
+ } break;
+
+ case VCHIQ_SERVICE_OPTION_MESSAGE_QUOTA: {
+ VCHIQ_SERVICE_QUOTA_T *service_quota =
+ &service->state->service_quotas[
+ service->localport];
+ if (value == 0)
+ value = service->state->default_message_quota;
+ if ((value >= service_quota->message_use_count) &&
+ (value < (unsigned short)~0)) {
+ service_quota->message_quota = value;
+ if ((value >=
+ service_quota->message_use_count) &&
+ (service_quota->slot_quota >=
+ service_quota->slot_use_count))
+ /* Signal the service that it may have
+ ** dropped below its quota */
+ up(&service_quota->quota_event);
+ status = VCHIQ_SUCCESS;
+ }
+ } break;
+
+ case VCHIQ_SERVICE_OPTION_SYNCHRONOUS:
+ if ((service->srvstate == VCHIQ_SRVSTATE_HIDDEN) ||
+ (service->srvstate ==
+ VCHIQ_SRVSTATE_LISTENING)) {
+ service->sync = value;
+ status = VCHIQ_SUCCESS;
+ }
+ break;
+
+ case VCHIQ_SERVICE_OPTION_TRACE:
+ service->trace = value;
+ status = VCHIQ_SUCCESS;
+ break;
+
+ default:
+ break;
+ }
+ unlock_service(service);
+ }
+
+ return status;
+}
+
+void
+vchiq_dump_shared_state(void *dump_context, VCHIQ_STATE_T *state,
+ VCHIQ_SHARED_STATE_T *shared, const char *label)
+{
+ static const char *const debug_names[] = {
+ "<entries>",
+ "SLOT_HANDLER_COUNT",
+ "SLOT_HANDLER_LINE",
+ "PARSE_LINE",
+ "PARSE_HEADER",
+ "PARSE_MSGID",
+ "AWAIT_COMPLETION_LINE",
+ "DEQUEUE_MESSAGE_LINE",
+ "SERVICE_CALLBACK_LINE",
+ "MSG_QUEUE_FULL_COUNT",
+ "COMPLETION_QUEUE_FULL_COUNT"
+ };
+ int i;
+
+ char buf[80];
+ int len;
+ len = snprintf(buf, sizeof(buf),
+ " %s: slots %d-%d tx_pos=%x recycle=%x",
+ label, shared->slot_first, shared->slot_last,
+ shared->tx_pos, shared->slot_queue_recycle);
+ vchiq_dump(dump_context, buf, len + 1);
+
+ len = snprintf(buf, sizeof(buf),
+ " Slots claimed:");
+ vchiq_dump(dump_context, buf, len + 1);
+
+ for (i = shared->slot_first; i <= shared->slot_last; i++) {
+ VCHIQ_SLOT_INFO_T slot_info = *SLOT_INFO_FROM_INDEX(state, i);
+ if (slot_info.use_count != slot_info.release_count) {
+ len = snprintf(buf, sizeof(buf),
+ " %d: %d/%d", i, slot_info.use_count,
+ slot_info.release_count);
+ vchiq_dump(dump_context, buf, len + 1);
+ }
+ }
+
+ for (i = 1; i < shared->debug[DEBUG_ENTRIES]; i++) {
+ len = snprintf(buf, sizeof(buf), " DEBUG: %s = %d(%x)",
+ debug_names[i], shared->debug[i], shared->debug[i]);
+ vchiq_dump(dump_context, buf, len + 1);
+ }
+}
+
+void
+vchiq_dump_state(void *dump_context, VCHIQ_STATE_T *state)
+{
+ char buf[80];
+ int len;
+ int i;
+
+ len = snprintf(buf, sizeof(buf), "State %d: %s", state->id,
+ conn_state_names[state->conn_state]);
+ vchiq_dump(dump_context, buf, len + 1);
+
+ len = snprintf(buf, sizeof(buf),
+ " tx_pos=%x(@%x), rx_pos=%x(@%x)",
+ state->local->tx_pos,
+ (uint32_t)state->tx_data +
+ (state->local_tx_pos & VCHIQ_SLOT_MASK),
+ state->rx_pos,
+ (uint32_t)state->rx_data +
+ (state->rx_pos & VCHIQ_SLOT_MASK));
+ vchiq_dump(dump_context, buf, len + 1);
+
+ len = snprintf(buf, sizeof(buf),
+ " Version: %d (min %d)",
+ VCHIQ_VERSION, VCHIQ_VERSION_MIN);
+ vchiq_dump(dump_context, buf, len + 1);
+
+ if (VCHIQ_ENABLE_STATS) {
+ len = snprintf(buf, sizeof(buf),
+ " Stats: ctrl_tx_count=%d, ctrl_rx_count=%d, "
+ "error_count=%d",
+ state->stats.ctrl_tx_count, state->stats.ctrl_rx_count,
+ state->stats.error_count);
+ vchiq_dump(dump_context, buf, len + 1);
+ }
+
+ len = snprintf(buf, sizeof(buf),
+ " Slots: %d available (%d data), %d recyclable, %d stalls "
+ "(%d data)",
+ ((state->slot_queue_available * VCHIQ_SLOT_SIZE) -
+ state->local_tx_pos) / VCHIQ_SLOT_SIZE,
+ state->data_quota - state->data_use_count,
+ state->local->slot_queue_recycle - state->slot_queue_available,
+ state->stats.slot_stalls, state->stats.data_stalls);
+ vchiq_dump(dump_context, buf, len + 1);
+
+ vchiq_dump_platform_state(dump_context);
+
+ vchiq_dump_shared_state(dump_context, state, state->local, "Local");
+ vchiq_dump_shared_state(dump_context, state, state->remote, "Remote");
+
+ vchiq_dump_platform_instances(dump_context);
+
+ for (i = 0; i < state->unused_service; i++) {
+ VCHIQ_SERVICE_T *service = find_service_by_port(state, i);
+
+ if (service) {
+ vchiq_dump_service_state(dump_context, service);
+ unlock_service(service);
+ }
+ }
+}
+
+void
+vchiq_dump_service_state(void *dump_context, VCHIQ_SERVICE_T *service)
+{
+ char buf[80];
+ int len;
+
+ len = snprintf(buf, sizeof(buf), "Service %d: %s (ref %u)",
+ service->localport, srvstate_names[service->srvstate],
+ service->ref_count - 1); /*Don't include the lock just taken*/
+
+ if (service->srvstate != VCHIQ_SRVSTATE_FREE) {
+ char remoteport[30];
+ VCHIQ_SERVICE_QUOTA_T *service_quota =
+ &service->state->service_quotas[service->localport];
+ int fourcc = service->base.fourcc;
+ int tx_pending, rx_pending;
+ if (service->remoteport != VCHIQ_PORT_FREE) {
+ int len2 = snprintf(remoteport, sizeof(remoteport),
+ "%d", service->remoteport);
+ if (service->public_fourcc != VCHIQ_FOURCC_INVALID)
+ snprintf(remoteport + len2,
+ sizeof(remoteport) - len2,
+ " (client %x)", service->client_id);
+ } else
+ strcpy(remoteport, "n/a");
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ " '%c%c%c%c' remote %s (msg use %d/%d, slot use %d/%d)",
+ VCHIQ_FOURCC_AS_4CHARS(fourcc),
+ remoteport,
+ service_quota->message_use_count,
+ service_quota->message_quota,
+ service_quota->slot_use_count,
+ service_quota->slot_quota);
+
+ vchiq_dump(dump_context, buf, len + 1);
+
+ tx_pending = service->bulk_tx.local_insert -
+ service->bulk_tx.remote_insert;
+
+ rx_pending = service->bulk_rx.local_insert -
+ service->bulk_rx.remote_insert;
+
+ len = snprintf(buf, sizeof(buf),
+ " Bulk: tx_pending=%d (size %d),"
+ " rx_pending=%d (size %d)",
+ tx_pending,
+ tx_pending ? service->bulk_tx.bulks[
+ BULK_INDEX(service->bulk_tx.remove)].size : 0,
+ rx_pending,
+ rx_pending ? service->bulk_rx.bulks[
+ BULK_INDEX(service->bulk_rx.remove)].size : 0);
+
+ if (VCHIQ_ENABLE_STATS) {
+ vchiq_dump(dump_context, buf, len + 1);
+
+ len = snprintf(buf, sizeof(buf),
+ " Ctrl: tx_count=%d, tx_bytes=%llu, "
+ "rx_count=%d, rx_bytes=%llu",
+ service->stats.ctrl_tx_count,
+ service->stats.ctrl_tx_bytes,
+ service->stats.ctrl_rx_count,
+ service->stats.ctrl_rx_bytes);
+ vchiq_dump(dump_context, buf, len + 1);
+
+ len = snprintf(buf, sizeof(buf),
+ " Bulk: tx_count=%d, tx_bytes=%llu, "
+ "rx_count=%d, rx_bytes=%llu",
+ service->stats.bulk_tx_count,
+ service->stats.bulk_tx_bytes,
+ service->stats.bulk_rx_count,
+ service->stats.bulk_rx_bytes);
+ vchiq_dump(dump_context, buf, len + 1);
+
+ len = snprintf(buf, sizeof(buf),
+ " %d quota stalls, %d slot stalls, "
+ "%d bulk stalls, %d aborted, %d errors",
+ service->stats.quota_stalls,
+ service->stats.slot_stalls,
+ service->stats.bulk_stalls,
+ service->stats.bulk_aborted_count,
+ service->stats.error_count);
+ }
+ }
+
+ vchiq_dump(dump_context, buf, len + 1);
+
+ if (service->srvstate != VCHIQ_SRVSTATE_FREE)
+ vchiq_dump_platform_service_state(dump_context, service);
+}
+
+
+void
+vchiq_loud_error_header(void)
+{
+ vchiq_log_error(vchiq_core_log_level,
+ "============================================================"
+ "================");
+ vchiq_log_error(vchiq_core_log_level,
+ "============================================================"
+ "================");
+ vchiq_log_error(vchiq_core_log_level, "=====");
+}
+
+void
+vchiq_loud_error_footer(void)
+{
+ vchiq_log_error(vchiq_core_log_level, "=====");
+ vchiq_log_error(vchiq_core_log_level,
+ "============================================================"
+ "================");
+ vchiq_log_error(vchiq_core_log_level,
+ "============================================================"
+ "================");
+}
+
+
+VCHIQ_STATUS_T vchiq_send_remote_use(VCHIQ_STATE_T *state)
+{
+ VCHIQ_STATUS_T status = VCHIQ_RETRY;
+ if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED)
+ status = queue_message(state, NULL,
+ VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE, 0, 0),
+ NULL, 0, 0, 0);
+ return status;
+}
+
+VCHIQ_STATUS_T vchiq_send_remote_release(VCHIQ_STATE_T *state)
+{
+ VCHIQ_STATUS_T status = VCHIQ_RETRY;
+ if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED)
+ status = queue_message(state, NULL,
+ VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_RELEASE, 0, 0),
+ NULL, 0, 0, 0);
+ return status;
+}
+
+VCHIQ_STATUS_T vchiq_send_remote_use_active(VCHIQ_STATE_T *state)
+{
+ VCHIQ_STATUS_T status = VCHIQ_RETRY;
+ if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED)
+ status = queue_message(state, NULL,
+ VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE_ACTIVE, 0, 0),
+ NULL, 0, 0, 0);
+ return status;
+}
+
+void vchiq_log_dump_mem(const char *label, uint32_t addr, const void *voidMem,
+ size_t numBytes)
+{
+ const uint8_t *mem = (const uint8_t *)voidMem;
+ size_t offset;
+ char lineBuf[100];
+ char *s;
+
+ while (numBytes > 0) {
+ s = lineBuf;
+
+ for (offset = 0; offset < 16; offset++) {
+ if (offset < numBytes)
+ s += snprintf(s, 4, "%02x ", mem[offset]);
+ else
+ s += snprintf(s, 4, " ");
+ }
+
+ for (offset = 0; offset < 16; offset++) {
+ if (offset < numBytes) {
+ uint8_t ch = mem[offset];
+
+ if ((ch < ' ') || (ch > '~'))
+ ch = '.';
+ *s++ = (char)ch;
+ }
+ }
+ *s++ = '\0';
+
+ if ((label != NULL) && (*label != '\0'))
+ vchiq_log_trace(VCHIQ_LOG_TRACE,
+ "%s: %08x: %s", label, addr, lineBuf);
+ else
+ vchiq_log_trace(VCHIQ_LOG_TRACE,
+ "%08x: %s", addr, lineBuf);
+
+ addr += 16;
+ mem += 16;
+ if (numBytes > 16)
+ numBytes -= 16;
+ else
+ numBytes = 0;
+ }
+}
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
new file mode 100644
index 000000000000..9be484c776d0
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
@@ -0,0 +1,712 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_CORE_H
+#define VCHIQ_CORE_H
+
+#include <linux/mutex.h>
+#include <linux/semaphore.h>
+#include <linux/kthread.h>
+
+#include "vchiq_cfg.h"
+
+#include "vchiq.h"
+
+/* Run time control of log level, based on KERN_XXX level. */
+#define VCHIQ_LOG_DEFAULT 4
+#define VCHIQ_LOG_ERROR 3
+#define VCHIQ_LOG_WARNING 4
+#define VCHIQ_LOG_INFO 6
+#define VCHIQ_LOG_TRACE 7
+
+#define VCHIQ_LOG_PREFIX KERN_INFO "vchiq: "
+
+#ifndef vchiq_log_error
+#define vchiq_log_error(cat, fmt, ...) \
+ do { if (cat >= VCHIQ_LOG_ERROR) \
+ printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0)
+#endif
+#ifndef vchiq_log_warning
+#define vchiq_log_warning(cat, fmt, ...) \
+ do { if (cat >= VCHIQ_LOG_WARNING) \
+ printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0)
+#endif
+#ifndef vchiq_log_info
+#define vchiq_log_info(cat, fmt, ...) \
+ do { if (cat >= VCHIQ_LOG_INFO) \
+ printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0)
+#endif
+#ifndef vchiq_log_trace
+#define vchiq_log_trace(cat, fmt, ...) \
+ do { if (cat >= VCHIQ_LOG_TRACE) \
+ printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0)
+#endif
+
+#define vchiq_loud_error(...) \
+ vchiq_log_error(vchiq_core_log_level, "===== " __VA_ARGS__)
+
+#ifndef vchiq_static_assert
+#define vchiq_static_assert(cond) __attribute__((unused)) \
+ extern int vchiq_static_assert[(cond) ? 1 : -1]
+#endif
+
+#define IS_POW2(x) (x && ((x & (x - 1)) == 0))
+
+/* Ensure that the slot size and maximum number of slots are powers of 2 */
+vchiq_static_assert(IS_POW2(VCHIQ_SLOT_SIZE));
+vchiq_static_assert(IS_POW2(VCHIQ_MAX_SLOTS));
+vchiq_static_assert(IS_POW2(VCHIQ_MAX_SLOTS_PER_SIDE));
+
+#define VCHIQ_SLOT_MASK (VCHIQ_SLOT_SIZE - 1)
+#define VCHIQ_SLOT_QUEUE_MASK (VCHIQ_MAX_SLOTS_PER_SIDE - 1)
+#define VCHIQ_SLOT_ZERO_SLOTS ((sizeof(VCHIQ_SLOT_ZERO_T) + \
+ VCHIQ_SLOT_SIZE - 1) / VCHIQ_SLOT_SIZE)
+
+#define VCHIQ_MSG_PADDING 0 /* - */
+#define VCHIQ_MSG_CONNECT 1 /* - */
+#define VCHIQ_MSG_OPEN 2 /* + (srcport, -), fourcc, client_id */
+#define VCHIQ_MSG_OPENACK 3 /* + (srcport, dstport) */
+#define VCHIQ_MSG_CLOSE 4 /* + (srcport, dstport) */
+#define VCHIQ_MSG_DATA 5 /* + (srcport, dstport) */
+#define VCHIQ_MSG_BULK_RX 6 /* + (srcport, dstport), data, size */
+#define VCHIQ_MSG_BULK_TX 7 /* + (srcport, dstport), data, size */
+#define VCHIQ_MSG_BULK_RX_DONE 8 /* + (srcport, dstport), actual */
+#define VCHIQ_MSG_BULK_TX_DONE 9 /* + (srcport, dstport), actual */
+#define VCHIQ_MSG_PAUSE 10 /* - */
+#define VCHIQ_MSG_RESUME 11 /* - */
+#define VCHIQ_MSG_REMOTE_USE 12 /* - */
+#define VCHIQ_MSG_REMOTE_RELEASE 13 /* - */
+#define VCHIQ_MSG_REMOTE_USE_ACTIVE 14 /* - */
+
+#define VCHIQ_PORT_MAX (VCHIQ_MAX_SERVICES - 1)
+#define VCHIQ_PORT_FREE 0x1000
+#define VCHIQ_PORT_IS_VALID(port) (port < VCHIQ_PORT_FREE)
+#define VCHIQ_MAKE_MSG(type, srcport, dstport) \
+ ((type<<24) | (srcport<<12) | (dstport<<0))
+#define VCHIQ_MSG_TYPE(msgid) ((unsigned int)msgid >> 24)
+#define VCHIQ_MSG_SRCPORT(msgid) \
+ (unsigned short)(((unsigned int)msgid >> 12) & 0xfff)
+#define VCHIQ_MSG_DSTPORT(msgid) \
+ ((unsigned short)msgid & 0xfff)
+
+#define VCHIQ_FOURCC_AS_4CHARS(fourcc) \
+ ((fourcc) >> 24) & 0xff, \
+ ((fourcc) >> 16) & 0xff, \
+ ((fourcc) >> 8) & 0xff, \
+ (fourcc) & 0xff
+
+/* Ensure the fields are wide enough */
+vchiq_static_assert(VCHIQ_MSG_SRCPORT(VCHIQ_MAKE_MSG(0, 0, VCHIQ_PORT_MAX))
+ == 0);
+vchiq_static_assert(VCHIQ_MSG_TYPE(VCHIQ_MAKE_MSG(0, VCHIQ_PORT_MAX, 0)) == 0);
+vchiq_static_assert((unsigned int)VCHIQ_PORT_MAX <
+ (unsigned int)VCHIQ_PORT_FREE);
+
+#define VCHIQ_MSGID_PADDING VCHIQ_MAKE_MSG(VCHIQ_MSG_PADDING, 0, 0)
+#define VCHIQ_MSGID_CLAIMED 0x40000000
+
+#define VCHIQ_FOURCC_INVALID 0x00000000
+#define VCHIQ_FOURCC_IS_LEGAL(fourcc) (fourcc != VCHIQ_FOURCC_INVALID)
+
+#define VCHIQ_BULK_ACTUAL_ABORTED -1
+
+typedef uint32_t BITSET_T;
+
+vchiq_static_assert((sizeof(BITSET_T) * 8) == 32);
+
+#define BITSET_SIZE(b) ((b + 31) >> 5)
+#define BITSET_WORD(b) (b >> 5)
+#define BITSET_BIT(b) (1 << (b & 31))
+#define BITSET_ZERO(bs) memset(bs, 0, sizeof(bs))
+#define BITSET_IS_SET(bs, b) (bs[BITSET_WORD(b)] & BITSET_BIT(b))
+#define BITSET_SET(bs, b) (bs[BITSET_WORD(b)] |= BITSET_BIT(b))
+#define BITSET_CLR(bs, b) (bs[BITSET_WORD(b)] &= ~BITSET_BIT(b))
+
+#if VCHIQ_ENABLE_STATS
+#define VCHIQ_STATS_INC(state, stat) (state->stats. stat++)
+#define VCHIQ_SERVICE_STATS_INC(service, stat) (service->stats. stat++)
+#define VCHIQ_SERVICE_STATS_ADD(service, stat, addend) \
+ (service->stats. stat += addend)
+#else
+#define VCHIQ_STATS_INC(state, stat) ((void)0)
+#define VCHIQ_SERVICE_STATS_INC(service, stat) ((void)0)
+#define VCHIQ_SERVICE_STATS_ADD(service, stat, addend) ((void)0)
+#endif
+
+enum {
+ DEBUG_ENTRIES,
+#if VCHIQ_ENABLE_DEBUG
+ DEBUG_SLOT_HANDLER_COUNT,
+ DEBUG_SLOT_HANDLER_LINE,
+ DEBUG_PARSE_LINE,
+ DEBUG_PARSE_HEADER,
+ DEBUG_PARSE_MSGID,
+ DEBUG_AWAIT_COMPLETION_LINE,
+ DEBUG_DEQUEUE_MESSAGE_LINE,
+ DEBUG_SERVICE_CALLBACK_LINE,
+ DEBUG_MSG_QUEUE_FULL_COUNT,
+ DEBUG_COMPLETION_QUEUE_FULL_COUNT,
+#endif
+ DEBUG_MAX
+};
+
+#if VCHIQ_ENABLE_DEBUG
+
+#define DEBUG_INITIALISE(local) int *debug_ptr = (local)->debug;
+#define DEBUG_TRACE(d) \
+ do { debug_ptr[DEBUG_ ## d] = __LINE__; dsb(); } while (0)
+#define DEBUG_VALUE(d, v) \
+ do { debug_ptr[DEBUG_ ## d] = (v); dsb(); } while (0)
+#define DEBUG_COUNT(d) \
+ do { debug_ptr[DEBUG_ ## d]++; dsb(); } while (0)
+
+#else /* VCHIQ_ENABLE_DEBUG */
+
+#define DEBUG_INITIALISE(local)
+#define DEBUG_TRACE(d)
+#define DEBUG_VALUE(d, v)
+#define DEBUG_COUNT(d)
+
+#endif /* VCHIQ_ENABLE_DEBUG */
+
+typedef enum {
+ VCHIQ_CONNSTATE_DISCONNECTED,
+ VCHIQ_CONNSTATE_CONNECTING,
+ VCHIQ_CONNSTATE_CONNECTED,
+ VCHIQ_CONNSTATE_PAUSING,
+ VCHIQ_CONNSTATE_PAUSE_SENT,
+ VCHIQ_CONNSTATE_PAUSED,
+ VCHIQ_CONNSTATE_RESUMING,
+ VCHIQ_CONNSTATE_PAUSE_TIMEOUT,
+ VCHIQ_CONNSTATE_RESUME_TIMEOUT
+} VCHIQ_CONNSTATE_T;
+
+enum {
+ VCHIQ_SRVSTATE_FREE,
+ VCHIQ_SRVSTATE_HIDDEN,
+ VCHIQ_SRVSTATE_LISTENING,
+ VCHIQ_SRVSTATE_OPENING,
+ VCHIQ_SRVSTATE_OPEN,
+ VCHIQ_SRVSTATE_OPENSYNC,
+ VCHIQ_SRVSTATE_CLOSESENT,
+ VCHIQ_SRVSTATE_CLOSERECVD,
+ VCHIQ_SRVSTATE_CLOSEWAIT,
+ VCHIQ_SRVSTATE_CLOSED
+};
+
+enum {
+ VCHIQ_POLL_TERMINATE,
+ VCHIQ_POLL_REMOVE,
+ VCHIQ_POLL_TXNOTIFY,
+ VCHIQ_POLL_RXNOTIFY,
+ VCHIQ_POLL_COUNT
+};
+
+typedef enum {
+ VCHIQ_BULK_TRANSMIT,
+ VCHIQ_BULK_RECEIVE
+} VCHIQ_BULK_DIR_T;
+
+typedef void (*VCHIQ_USERDATA_TERM_T)(void *userdata);
+
+typedef struct vchiq_bulk_struct {
+ short mode;
+ short dir;
+ void *userdata;
+ VCHI_MEM_HANDLE_T handle;
+ void *data;
+ int size;
+ void *remote_data;
+ int remote_size;
+ int actual;
+} VCHIQ_BULK_T;
+
+typedef struct vchiq_bulk_queue_struct {
+ int local_insert; /* Where to insert the next local bulk */
+ int remote_insert; /* Where to insert the next remote bulk (master) */
+ int process; /* Bulk to transfer next */
+ int remote_notify; /* Bulk to notify the remote client of next (mstr) */
+ int remove; /* Bulk to notify the local client of, and remove,
+ ** next */
+ VCHIQ_BULK_T bulks[VCHIQ_NUM_SERVICE_BULKS];
+} VCHIQ_BULK_QUEUE_T;
+
+typedef struct remote_event_struct {
+ int armed;
+ int fired;
+ struct semaphore *event;
+} REMOTE_EVENT_T;
+
+typedef struct opaque_platform_state_t *VCHIQ_PLATFORM_STATE_T;
+
+typedef struct vchiq_state_struct VCHIQ_STATE_T;
+
+typedef struct vchiq_slot_struct {
+ char data[VCHIQ_SLOT_SIZE];
+} VCHIQ_SLOT_T;
+
+typedef struct vchiq_slot_info_struct {
+ /* Use two counters rather than one to avoid the need for a mutex. */
+ short use_count;
+ short release_count;
+} VCHIQ_SLOT_INFO_T;
+
+typedef struct vchiq_service_struct {
+ VCHIQ_SERVICE_BASE_T base;
+ VCHIQ_SERVICE_HANDLE_T handle;
+ unsigned int ref_count;
+ int srvstate;
+ VCHIQ_USERDATA_TERM_T userdata_term;
+ unsigned int localport;
+ unsigned int remoteport;
+ int public_fourcc;
+ int client_id;
+ char auto_close;
+ char sync;
+ char closing;
+ char trace;
+ atomic_t poll_flags;
+ short version;
+ short version_min;
+ short peer_version;
+
+ VCHIQ_STATE_T *state;
+ VCHIQ_INSTANCE_T instance;
+
+ int service_use_count;
+
+ VCHIQ_BULK_QUEUE_T bulk_tx;
+ VCHIQ_BULK_QUEUE_T bulk_rx;
+
+ struct semaphore remove_event;
+ struct semaphore bulk_remove_event;
+ struct mutex bulk_mutex;
+
+ struct service_stats_struct {
+ int quota_stalls;
+ int slot_stalls;
+ int bulk_stalls;
+ int error_count;
+ int ctrl_tx_count;
+ int ctrl_rx_count;
+ int bulk_tx_count;
+ int bulk_rx_count;
+ int bulk_aborted_count;
+ uint64_t ctrl_tx_bytes;
+ uint64_t ctrl_rx_bytes;
+ uint64_t bulk_tx_bytes;
+ uint64_t bulk_rx_bytes;
+ } stats;
+} VCHIQ_SERVICE_T;
+
+/* The quota information is outside VCHIQ_SERVICE_T so that it can be
+ statically allocated, since for accounting reasons a service's slot
+ usage is carried over between users of the same port number.
+ */
+typedef struct vchiq_service_quota_struct {
+ unsigned short slot_quota;
+ unsigned short slot_use_count;
+ unsigned short message_quota;
+ unsigned short message_use_count;
+ struct semaphore quota_event;
+ int previous_tx_index;
+} VCHIQ_SERVICE_QUOTA_T;
+
+typedef struct vchiq_shared_state_struct {
+
+ /* A non-zero value here indicates that the content is valid. */
+ int initialised;
+
+ /* The first and last (inclusive) slots allocated to the owner. */
+ int slot_first;
+ int slot_last;
+
+ /* The slot allocated to synchronous messages from the owner. */
+ int slot_sync;
+
+ /* Signalling this event indicates that owner's slot handler thread
+ ** should run. */
+ REMOTE_EVENT_T trigger;
+
+ /* Indicates the byte position within the stream where the next message
+ ** will be written. The least significant bits are an index into the
+ ** slot. The next bits are the index of the slot in slot_queue. */
+ int tx_pos;
+
+ /* This event should be signalled when a slot is recycled. */
+ REMOTE_EVENT_T recycle;
+
+ /* The slot_queue index where the next recycled slot will be written. */
+ int slot_queue_recycle;
+
+ /* This event should be signalled when a synchronous message is sent. */
+ REMOTE_EVENT_T sync_trigger;
+
+ /* This event should be signalled when a synchronous message has been
+ ** released. */
+ REMOTE_EVENT_T sync_release;
+
+ /* A circular buffer of slot indexes. */
+ int slot_queue[VCHIQ_MAX_SLOTS_PER_SIDE];
+
+ /* Debugging state */
+ int debug[DEBUG_MAX];
+} VCHIQ_SHARED_STATE_T;
+
+typedef struct vchiq_slot_zero_struct {
+ int magic;
+ short version;
+ short version_min;
+ int slot_zero_size;
+ int slot_size;
+ int max_slots;
+ int max_slots_per_side;
+ int platform_data[2];
+ VCHIQ_SHARED_STATE_T master;
+ VCHIQ_SHARED_STATE_T slave;
+ VCHIQ_SLOT_INFO_T slots[VCHIQ_MAX_SLOTS];
+} VCHIQ_SLOT_ZERO_T;
+
+struct vchiq_state_struct {
+ int id;
+ int initialised;
+ VCHIQ_CONNSTATE_T conn_state;
+ int is_master;
+ short version_common;
+
+ VCHIQ_SHARED_STATE_T *local;
+ VCHIQ_SHARED_STATE_T *remote;
+ VCHIQ_SLOT_T *slot_data;
+
+ unsigned short default_slot_quota;
+ unsigned short default_message_quota;
+
+ /* Event indicating connect message received */
+ struct semaphore connect;
+
+ /* Mutex protecting services */
+ struct mutex mutex;
+ VCHIQ_INSTANCE_T *instance;
+
+ /* Processes incoming messages */
+ struct task_struct *slot_handler_thread;
+
+ /* Processes recycled slots */
+ struct task_struct *recycle_thread;
+
+ /* Processes synchronous messages */
+ struct task_struct *sync_thread;
+
+ /* Local implementation of the trigger remote event */
+ struct semaphore trigger_event;
+
+ /* Local implementation of the recycle remote event */
+ struct semaphore recycle_event;
+
+ /* Local implementation of the sync trigger remote event */
+ struct semaphore sync_trigger_event;
+
+ /* Local implementation of the sync release remote event */
+ struct semaphore sync_release_event;
+
+ char *tx_data;
+ char *rx_data;
+ VCHIQ_SLOT_INFO_T *rx_info;
+
+ struct mutex slot_mutex;
+
+ struct mutex recycle_mutex;
+
+ struct mutex sync_mutex;
+
+ struct mutex bulk_transfer_mutex;
+
+ /* Indicates the byte position within the stream from where the next
+ ** message will be read. The least significant bits are an index into
+ ** the slot.The next bits are the index of the slot in
+ ** remote->slot_queue. */
+ int rx_pos;
+
+ /* A cached copy of local->tx_pos. Only write to local->tx_pos, and read
+ from remote->tx_pos. */
+ int local_tx_pos;
+
+ /* The slot_queue index of the slot to become available next. */
+ int slot_queue_available;
+
+ /* A flag to indicate if any poll has been requested */
+ int poll_needed;
+
+ /* Ths index of the previous slot used for data messages. */
+ int previous_data_index;
+
+ /* The number of slots occupied by data messages. */
+ unsigned short data_use_count;
+
+ /* The maximum number of slots to be occupied by data messages. */
+ unsigned short data_quota;
+
+ /* An array of bit sets indicating which services must be polled. */
+ atomic_t poll_services[BITSET_SIZE(VCHIQ_MAX_SERVICES)];
+
+ /* The number of the first unused service */
+ int unused_service;
+
+ /* Signalled when a free slot becomes available. */
+ struct semaphore slot_available_event;
+
+ struct semaphore slot_remove_event;
+
+ /* Signalled when a free data slot becomes available. */
+ struct semaphore data_quota_event;
+
+ /* Incremented when there are bulk transfers which cannot be processed
+ * whilst paused and must be processed on resume */
+ int deferred_bulks;
+
+ struct state_stats_struct {
+ int slot_stalls;
+ int data_stalls;
+ int ctrl_tx_count;
+ int ctrl_rx_count;
+ int error_count;
+ } stats;
+
+ VCHIQ_SERVICE_T * services[VCHIQ_MAX_SERVICES];
+ VCHIQ_SERVICE_QUOTA_T service_quotas[VCHIQ_MAX_SERVICES];
+ VCHIQ_SLOT_INFO_T slot_info[VCHIQ_MAX_SLOTS];
+
+ VCHIQ_PLATFORM_STATE_T platform_state;
+};
+
+struct bulk_waiter {
+ VCHIQ_BULK_T *bulk;
+ struct semaphore event;
+ int actual;
+};
+
+extern spinlock_t bulk_waiter_spinlock;
+
+extern int vchiq_core_log_level;
+extern int vchiq_core_msg_log_level;
+extern int vchiq_sync_log_level;
+
+extern VCHIQ_STATE_T *vchiq_states[VCHIQ_MAX_STATES];
+
+extern const char *
+get_conn_state_name(VCHIQ_CONNSTATE_T conn_state);
+
+extern VCHIQ_SLOT_ZERO_T *
+vchiq_init_slots(void *mem_base, int mem_size);
+
+extern VCHIQ_STATUS_T
+vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero,
+ int is_master);
+
+extern VCHIQ_STATUS_T
+vchiq_connect_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance);
+
+extern VCHIQ_SERVICE_T *
+vchiq_add_service_internal(VCHIQ_STATE_T *state,
+ const VCHIQ_SERVICE_PARAMS_T *params, int srvstate,
+ VCHIQ_INSTANCE_T instance, VCHIQ_USERDATA_TERM_T userdata_term);
+
+extern VCHIQ_STATUS_T
+vchiq_open_service_internal(VCHIQ_SERVICE_T *service, int client_id);
+
+extern VCHIQ_STATUS_T
+vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd);
+
+extern void
+vchiq_terminate_service_internal(VCHIQ_SERVICE_T *service);
+
+extern void
+vchiq_free_service_internal(VCHIQ_SERVICE_T *service);
+
+extern VCHIQ_STATUS_T
+vchiq_shutdown_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance);
+
+extern VCHIQ_STATUS_T
+vchiq_pause_internal(VCHIQ_STATE_T *state);
+
+extern VCHIQ_STATUS_T
+vchiq_resume_internal(VCHIQ_STATE_T *state);
+
+extern void
+remote_event_pollall(VCHIQ_STATE_T *state);
+
+extern VCHIQ_STATUS_T
+vchiq_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle,
+ VCHI_MEM_HANDLE_T memhandle, void *offset, int size, void *userdata,
+ VCHIQ_BULK_MODE_T mode, VCHIQ_BULK_DIR_T dir);
+
+extern void
+vchiq_dump_state(void *dump_context, VCHIQ_STATE_T *state);
+
+extern void
+vchiq_dump_service_state(void *dump_context, VCHIQ_SERVICE_T *service);
+
+extern void
+vchiq_loud_error_header(void);
+
+extern void
+vchiq_loud_error_footer(void);
+
+extern void
+request_poll(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int poll_type);
+
+static inline VCHIQ_SERVICE_T *
+handle_to_service(VCHIQ_SERVICE_HANDLE_T handle)
+{
+ VCHIQ_STATE_T *state = vchiq_states[(handle / VCHIQ_MAX_SERVICES) &
+ (VCHIQ_MAX_STATES - 1)];
+ if (!state)
+ return NULL;
+
+ return state->services[handle & (VCHIQ_MAX_SERVICES - 1)];
+}
+
+extern VCHIQ_SERVICE_T *
+find_service_by_handle(VCHIQ_SERVICE_HANDLE_T handle);
+
+extern VCHIQ_SERVICE_T *
+find_service_by_port(VCHIQ_STATE_T *state, int localport);
+
+extern VCHIQ_SERVICE_T *
+find_service_for_instance(VCHIQ_INSTANCE_T instance,
+ VCHIQ_SERVICE_HANDLE_T handle);
+
+extern VCHIQ_SERVICE_T *
+find_closed_service_for_instance(VCHIQ_INSTANCE_T instance,
+ VCHIQ_SERVICE_HANDLE_T handle);
+
+extern VCHIQ_SERVICE_T *
+next_service_by_instance(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance,
+ int *pidx);
+
+extern void
+lock_service(VCHIQ_SERVICE_T *service);
+
+extern void
+unlock_service(VCHIQ_SERVICE_T *service);
+
+/* The following functions are called from vchiq_core, and external
+** implementations must be provided. */
+
+extern VCHIQ_STATUS_T
+vchiq_prepare_bulk_data(VCHIQ_BULK_T *bulk,
+ VCHI_MEM_HANDLE_T memhandle, void *offset, int size, int dir);
+
+extern void
+vchiq_transfer_bulk(VCHIQ_BULK_T *bulk);
+
+extern void
+vchiq_complete_bulk(VCHIQ_BULK_T *bulk);
+
+extern VCHIQ_STATUS_T
+vchiq_copy_from_user(void *dst, const void *src, int size);
+
+extern void
+remote_event_signal(REMOTE_EVENT_T *event);
+
+void
+vchiq_platform_check_suspend(VCHIQ_STATE_T *state);
+
+extern void
+vchiq_platform_paused(VCHIQ_STATE_T *state);
+
+extern VCHIQ_STATUS_T
+vchiq_platform_resume(VCHIQ_STATE_T *state);
+
+extern void
+vchiq_platform_resumed(VCHIQ_STATE_T *state);
+
+extern void
+vchiq_dump(void *dump_context, const char *str, int len);
+
+extern void
+vchiq_dump_platform_state(void *dump_context);
+
+extern void
+vchiq_dump_platform_instances(void *dump_context);
+
+extern void
+vchiq_dump_platform_service_state(void *dump_context,
+ VCHIQ_SERVICE_T *service);
+
+extern VCHIQ_STATUS_T
+vchiq_use_service_internal(VCHIQ_SERVICE_T *service);
+
+extern VCHIQ_STATUS_T
+vchiq_release_service_internal(VCHIQ_SERVICE_T *service);
+
+extern void
+vchiq_on_remote_use(VCHIQ_STATE_T *state);
+
+extern void
+vchiq_on_remote_release(VCHIQ_STATE_T *state);
+
+extern VCHIQ_STATUS_T
+vchiq_platform_init_state(VCHIQ_STATE_T *state);
+
+extern VCHIQ_STATUS_T
+vchiq_check_service(VCHIQ_SERVICE_T *service);
+
+extern void
+vchiq_on_remote_use_active(VCHIQ_STATE_T *state);
+
+extern VCHIQ_STATUS_T
+vchiq_send_remote_use(VCHIQ_STATE_T *state);
+
+extern VCHIQ_STATUS_T
+vchiq_send_remote_release(VCHIQ_STATE_T *state);
+
+extern VCHIQ_STATUS_T
+vchiq_send_remote_use_active(VCHIQ_STATE_T *state);
+
+extern void
+vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state,
+ VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate);
+
+extern void
+vchiq_platform_handle_timeout(VCHIQ_STATE_T *state);
+
+extern void
+vchiq_set_conn_state(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T newstate);
+
+
+extern void
+vchiq_log_dump_mem(const char *label, uint32_t addr, const void *voidMem,
+ size_t numBytes);
+
+#endif
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c
new file mode 100644
index 000000000000..7e032130d967
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c
@@ -0,0 +1,383 @@
+/**
+ * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <linux/debugfs.h>
+#include "vchiq_core.h"
+#include "vchiq_arm.h"
+#include "vchiq_debugfs.h"
+
+#ifdef CONFIG_DEBUG_FS
+
+/****************************************************************************
+*
+* log category entries
+*
+***************************************************************************/
+#define DEBUGFS_WRITE_BUF_SIZE 256
+
+#define VCHIQ_LOG_ERROR_STR "error"
+#define VCHIQ_LOG_WARNING_STR "warning"
+#define VCHIQ_LOG_INFO_STR "info"
+#define VCHIQ_LOG_TRACE_STR "trace"
+
+
+/* Top-level debug info */
+struct vchiq_debugfs_info {
+ /* Global 'vchiq' debugfs entry used by all instances */
+ struct dentry *vchiq_cfg_dir;
+
+ /* one entry per client process */
+ struct dentry *clients;
+
+ /* log categories */
+ struct dentry *log_categories;
+};
+
+static struct vchiq_debugfs_info debugfs_info;
+
+/* Log category debugfs entries */
+struct vchiq_debugfs_log_entry {
+ const char *name;
+ int *plevel;
+ struct dentry *dir;
+};
+
+static struct vchiq_debugfs_log_entry vchiq_debugfs_log_entries[] = {
+ { "core", &vchiq_core_log_level },
+ { "msg", &vchiq_core_msg_log_level },
+ { "sync", &vchiq_sync_log_level },
+ { "susp", &vchiq_susp_log_level },
+ { "arm", &vchiq_arm_log_level },
+};
+static int n_log_entries =
+ sizeof(vchiq_debugfs_log_entries)/sizeof(vchiq_debugfs_log_entries[0]);
+
+
+static struct dentry *vchiq_clients_top(void);
+static struct dentry *vchiq_debugfs_top(void);
+
+static int debugfs_log_show(struct seq_file *f, void *offset)
+{
+ int *levp = f->private;
+ char *log_value = NULL;
+
+ switch (*levp) {
+ case VCHIQ_LOG_ERROR:
+ log_value = VCHIQ_LOG_ERROR_STR;
+ break;
+ case VCHIQ_LOG_WARNING:
+ log_value = VCHIQ_LOG_WARNING_STR;
+ break;
+ case VCHIQ_LOG_INFO:
+ log_value = VCHIQ_LOG_INFO_STR;
+ break;
+ case VCHIQ_LOG_TRACE:
+ log_value = VCHIQ_LOG_TRACE_STR;
+ break;
+ default:
+ break;
+ }
+
+ seq_printf(f, "%s\n", log_value ? log_value : "(null)");
+
+ return 0;
+}
+
+static int debugfs_log_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, debugfs_log_show, inode->i_private);
+}
+
+static int debugfs_log_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct seq_file *f = (struct seq_file *)file->private_data;
+ int *levp = f->private;
+ char kbuf[DEBUGFS_WRITE_BUF_SIZE + 1];
+
+ memset(kbuf, 0, DEBUGFS_WRITE_BUF_SIZE + 1);
+ if (count >= DEBUGFS_WRITE_BUF_SIZE)
+ count = DEBUGFS_WRITE_BUF_SIZE;
+
+ if (copy_from_user(kbuf, buffer, count) != 0)
+ return -EFAULT;
+ kbuf[count - 1] = 0;
+
+ if (strncmp("error", kbuf, strlen("error")) == 0)
+ *levp = VCHIQ_LOG_ERROR;
+ else if (strncmp("warning", kbuf, strlen("warning")) == 0)
+ *levp = VCHIQ_LOG_WARNING;
+ else if (strncmp("info", kbuf, strlen("info")) == 0)
+ *levp = VCHIQ_LOG_INFO;
+ else if (strncmp("trace", kbuf, strlen("trace")) == 0)
+ *levp = VCHIQ_LOG_TRACE;
+ else
+ *levp = VCHIQ_LOG_DEFAULT;
+
+ *ppos += count;
+
+ return count;
+}
+
+static const struct file_operations debugfs_log_fops = {
+ .owner = THIS_MODULE,
+ .open = debugfs_log_open,
+ .write = debugfs_log_write,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/* create an entry under <debugfs>/vchiq/log for each log category */
+static int vchiq_debugfs_create_log_entries(struct dentry *top)
+{
+ struct dentry *dir;
+ size_t i;
+ int ret = 0;
+ dir = debugfs_create_dir("log", vchiq_debugfs_top());
+ if (!dir)
+ return -ENOMEM;
+ debugfs_info.log_categories = dir;
+
+ for (i = 0; i < n_log_entries; i++) {
+ void *levp = (void *)vchiq_debugfs_log_entries[i].plevel;
+ dir = debugfs_create_file(vchiq_debugfs_log_entries[i].name,
+ 0644,
+ debugfs_info.log_categories,
+ levp,
+ &debugfs_log_fops);
+ if (!dir) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ vchiq_debugfs_log_entries[i].dir = dir;
+ }
+ return ret;
+}
+
+static int debugfs_usecount_show(struct seq_file *f, void *offset)
+{
+ VCHIQ_INSTANCE_T instance = f->private;
+ int use_count;
+
+ use_count = vchiq_instance_get_use_count(instance);
+ seq_printf(f, "%d\n", use_count);
+
+ return 0;
+}
+
+static int debugfs_usecount_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, debugfs_usecount_show, inode->i_private);
+}
+
+static const struct file_operations debugfs_usecount_fops = {
+ .owner = THIS_MODULE,
+ .open = debugfs_usecount_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int debugfs_trace_show(struct seq_file *f, void *offset)
+{
+ VCHIQ_INSTANCE_T instance = f->private;
+ int trace;
+
+ trace = vchiq_instance_get_trace(instance);
+ seq_printf(f, "%s\n", trace ? "Y" : "N");
+
+ return 0;
+}
+
+static int debugfs_trace_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, debugfs_trace_show, inode->i_private);
+}
+
+static int debugfs_trace_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct seq_file *f = (struct seq_file *)file->private_data;
+ VCHIQ_INSTANCE_T instance = f->private;
+ char firstchar;
+
+ if (copy_from_user(&firstchar, buffer, 1) != 0)
+ return -EFAULT;
+
+ switch (firstchar) {
+ case 'Y':
+ case 'y':
+ case '1':
+ vchiq_instance_set_trace(instance, 1);
+ break;
+ case 'N':
+ case 'n':
+ case '0':
+ vchiq_instance_set_trace(instance, 0);
+ break;
+ default:
+ break;
+ }
+
+ *ppos += count;
+
+ return count;
+}
+
+static const struct file_operations debugfs_trace_fops = {
+ .owner = THIS_MODULE,
+ .open = debugfs_trace_open,
+ .write = debugfs_trace_write,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/* add an instance (process) to the debugfs entries */
+int vchiq_debugfs_add_instance(VCHIQ_INSTANCE_T instance)
+{
+ char pidstr[16];
+ struct dentry *top, *use_count, *trace;
+ struct dentry *clients = vchiq_clients_top();
+
+ snprintf(pidstr, sizeof(pidstr), "%d",
+ vchiq_instance_get_pid(instance));
+
+ top = debugfs_create_dir(pidstr, clients);
+ if (!top)
+ goto fail_top;
+
+ use_count = debugfs_create_file("use_count",
+ 0444, top,
+ instance,
+ &debugfs_usecount_fops);
+ if (!use_count)
+ goto fail_use_count;
+
+ trace = debugfs_create_file("trace",
+ 0644, top,
+ instance,
+ &debugfs_trace_fops);
+ if (!trace)
+ goto fail_trace;
+
+ vchiq_instance_get_debugfs_node(instance)->dentry = top;
+
+ return 0;
+
+fail_trace:
+ debugfs_remove(use_count);
+fail_use_count:
+ debugfs_remove(top);
+fail_top:
+ return -ENOMEM;
+}
+
+void vchiq_debugfs_remove_instance(VCHIQ_INSTANCE_T instance)
+{
+ VCHIQ_DEBUGFS_NODE_T *node = vchiq_instance_get_debugfs_node(instance);
+ debugfs_remove_recursive(node->dentry);
+}
+
+
+int vchiq_debugfs_init(void)
+{
+ BUG_ON(debugfs_info.vchiq_cfg_dir != NULL);
+
+ debugfs_info.vchiq_cfg_dir = debugfs_create_dir("vchiq", NULL);
+ if (debugfs_info.vchiq_cfg_dir == NULL)
+ goto fail;
+
+ debugfs_info.clients = debugfs_create_dir("clients",
+ vchiq_debugfs_top());
+ if (!debugfs_info.clients)
+ goto fail;
+
+ if (vchiq_debugfs_create_log_entries(vchiq_debugfs_top()) != 0)
+ goto fail;
+
+ return 0;
+
+fail:
+ vchiq_debugfs_deinit();
+ vchiq_log_error(vchiq_arm_log_level,
+ "%s: failed to create debugfs directory",
+ __func__);
+
+ return -ENOMEM;
+}
+
+/* remove all the debugfs entries */
+void vchiq_debugfs_deinit(void)
+{
+ debugfs_remove_recursive(vchiq_debugfs_top());
+}
+
+static struct dentry *vchiq_clients_top(void)
+{
+ return debugfs_info.clients;
+}
+
+static struct dentry *vchiq_debugfs_top(void)
+{
+ BUG_ON(debugfs_info.vchiq_cfg_dir == NULL);
+ return debugfs_info.vchiq_cfg_dir;
+}
+
+#else /* CONFIG_DEBUG_FS */
+
+int vchiq_debugfs_init(void)
+{
+ return 0;
+}
+
+void vchiq_debugfs_deinit(void)
+{
+}
+
+int vchiq_debugfs_add_instance(VCHIQ_INSTANCE_T instance)
+{
+ return 0;
+}
+
+void vchiq_debugfs_remove_instance(VCHIQ_INSTANCE_T instance)
+{
+}
+
+#endif /* CONFIG_DEBUG_FS */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h
new file mode 100644
index 000000000000..4d6a3788e9c5
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_DEBUGFS_H
+#define VCHIQ_DEBUGFS_H
+
+#include "vchiq_core.h"
+
+typedef struct vchiq_debugfs_node_struct
+{
+ struct dentry *dentry;
+} VCHIQ_DEBUGFS_NODE_T;
+
+int vchiq_debugfs_init(void);
+
+void vchiq_debugfs_deinit(void);
+
+int vchiq_debugfs_add_instance(VCHIQ_INSTANCE_T instance);
+
+void vchiq_debugfs_remove_instance(VCHIQ_INSTANCE_T instance);
+
+#endif /* VCHIQ_DEBUGFS_H */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_genversion b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_genversion
new file mode 100644
index 000000000000..9f5b6344b9b7
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_genversion
@@ -0,0 +1,87 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+#
+# Generate a version from available information
+#
+
+my $prefix = shift @ARGV;
+my $root = shift @ARGV;
+
+
+if ( not defined $root ) {
+ die "usage: $0 prefix root-dir\n";
+}
+
+if ( ! -d $root ) {
+ die "root directory $root not found\n";
+}
+
+my $version = "unknown";
+my $tainted = "";
+
+if ( -d "$root/.git" ) {
+ # attempt to work out git version. only do so
+ # on a linux build host, as cygwin builds are
+ # already slow enough
+
+ if ( -f "/usr/bin/git" || -f "/usr/local/bin/git" ) {
+ if (not open(F, "git --git-dir $root/.git rev-parse --verify HEAD|")) {
+ $version = "no git version";
+ }
+ else {
+ $version = <F>;
+ $version =~ s/[ \r\n]*$//; # chomp may not be enough (cygwin).
+ $version =~ s/^[ \r\n]*//; # chomp may not be enough (cygwin).
+ }
+
+ if (open(G, "git --git-dir $root/.git status --porcelain|")) {
+ $tainted = <G>;
+ $tainted =~ s/[ \r\n]*$//; # chomp may not be enough (cygwin).
+ $tainted =~ s/^[ \r\n]*//; # chomp may not be enough (cygwin).
+ if (length $tainted) {
+ $version = join ' ', $version, "(tainted)";
+ }
+ else {
+ $version = join ' ', $version, "(clean)";
+ }
+ }
+ }
+}
+
+my $hostname = `hostname`;
+$hostname =~ s/[ \r\n]*$//; # chomp may not be enough (cygwin).
+$hostname =~ s/^[ \r\n]*//; # chomp may not be enough (cygwin).
+
+
+print STDERR "Version $version\n";
+print <<EOF;
+#include "${prefix}_build_info.h"
+#include <linux/broadcom/vc_debug_sym.h>
+
+VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_hostname, "$hostname" );
+VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_version, "$version" );
+VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_time, __TIME__ );
+VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_date, __DATE__ );
+
+const char *vchiq_get_build_hostname( void )
+{
+ return vchiq_build_hostname;
+}
+
+const char *vchiq_get_build_version( void )
+{
+ return vchiq_build_version;
+}
+
+const char *vchiq_get_build_date( void )
+{
+ return vchiq_build_date;
+}
+
+const char *vchiq_get_build_time( void )
+{
+ return vchiq_build_time;
+}
+EOF
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_if.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_if.h
new file mode 100644
index 000000000000..8067bbe7ce8d
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_if.h
@@ -0,0 +1,189 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_IF_H
+#define VCHIQ_IF_H
+
+#include "interface/vchi/vchi_mh.h"
+
+#define VCHIQ_SERVICE_HANDLE_INVALID 0
+
+#define VCHIQ_SLOT_SIZE 4096
+#define VCHIQ_MAX_MSG_SIZE (VCHIQ_SLOT_SIZE - sizeof(VCHIQ_HEADER_T))
+#define VCHIQ_CHANNEL_SIZE VCHIQ_MAX_MSG_SIZE /* For backwards compatibility */
+
+#define VCHIQ_MAKE_FOURCC(x0, x1, x2, x3) \
+ (((x0) << 24) | ((x1) << 16) | ((x2) << 8) | (x3))
+#define VCHIQ_GET_SERVICE_USERDATA(service) vchiq_get_service_userdata(service)
+#define VCHIQ_GET_SERVICE_FOURCC(service) vchiq_get_service_fourcc(service)
+
+typedef enum {
+ VCHIQ_SERVICE_OPENED, /* service, -, - */
+ VCHIQ_SERVICE_CLOSED, /* service, -, - */
+ VCHIQ_MESSAGE_AVAILABLE, /* service, header, - */
+ VCHIQ_BULK_TRANSMIT_DONE, /* service, -, bulk_userdata */
+ VCHIQ_BULK_RECEIVE_DONE, /* service, -, bulk_userdata */
+ VCHIQ_BULK_TRANSMIT_ABORTED, /* service, -, bulk_userdata */
+ VCHIQ_BULK_RECEIVE_ABORTED /* service, -, bulk_userdata */
+} VCHIQ_REASON_T;
+
+typedef enum {
+ VCHIQ_ERROR = -1,
+ VCHIQ_SUCCESS = 0,
+ VCHIQ_RETRY = 1
+} VCHIQ_STATUS_T;
+
+typedef enum {
+ VCHIQ_BULK_MODE_CALLBACK,
+ VCHIQ_BULK_MODE_BLOCKING,
+ VCHIQ_BULK_MODE_NOCALLBACK,
+ VCHIQ_BULK_MODE_WAITING /* Reserved for internal use */
+} VCHIQ_BULK_MODE_T;
+
+typedef enum {
+ VCHIQ_SERVICE_OPTION_AUTOCLOSE,
+ VCHIQ_SERVICE_OPTION_SLOT_QUOTA,
+ VCHIQ_SERVICE_OPTION_MESSAGE_QUOTA,
+ VCHIQ_SERVICE_OPTION_SYNCHRONOUS,
+ VCHIQ_SERVICE_OPTION_TRACE
+} VCHIQ_SERVICE_OPTION_T;
+
+typedef struct vchiq_header_struct {
+ /* The message identifier - opaque to applications. */
+ int msgid;
+
+ /* Size of message data. */
+ unsigned int size;
+
+ char data[0]; /* message */
+} VCHIQ_HEADER_T;
+
+typedef struct {
+ const void *data;
+ unsigned int size;
+} VCHIQ_ELEMENT_T;
+
+typedef unsigned int VCHIQ_SERVICE_HANDLE_T;
+
+typedef VCHIQ_STATUS_T (*VCHIQ_CALLBACK_T)(VCHIQ_REASON_T, VCHIQ_HEADER_T *,
+ VCHIQ_SERVICE_HANDLE_T, void *);
+
+typedef struct vchiq_service_base_struct {
+ int fourcc;
+ VCHIQ_CALLBACK_T callback;
+ void *userdata;
+} VCHIQ_SERVICE_BASE_T;
+
+typedef struct vchiq_service_params_struct {
+ int fourcc;
+ VCHIQ_CALLBACK_T callback;
+ void *userdata;
+ short version; /* Increment for non-trivial changes */
+ short version_min; /* Update for incompatible changes */
+} VCHIQ_SERVICE_PARAMS_T;
+
+typedef struct vchiq_config_struct {
+ unsigned int max_msg_size;
+ unsigned int bulk_threshold; /* The message size above which it
+ is better to use a bulk transfer
+ (<= max_msg_size) */
+ unsigned int max_outstanding_bulks;
+ unsigned int max_services;
+ short version; /* The version of VCHIQ */
+ short version_min; /* The minimum compatible version of VCHIQ */
+} VCHIQ_CONFIG_T;
+
+typedef struct vchiq_instance_struct *VCHIQ_INSTANCE_T;
+typedef void (*VCHIQ_REMOTE_USE_CALLBACK_T)(void *cb_arg);
+
+extern VCHIQ_STATUS_T vchiq_initialise(VCHIQ_INSTANCE_T *pinstance);
+extern VCHIQ_STATUS_T vchiq_shutdown(VCHIQ_INSTANCE_T instance);
+extern VCHIQ_STATUS_T vchiq_connect(VCHIQ_INSTANCE_T instance);
+extern VCHIQ_STATUS_T vchiq_add_service(VCHIQ_INSTANCE_T instance,
+ const VCHIQ_SERVICE_PARAMS_T *params,
+ VCHIQ_SERVICE_HANDLE_T *pservice);
+extern VCHIQ_STATUS_T vchiq_open_service(VCHIQ_INSTANCE_T instance,
+ const VCHIQ_SERVICE_PARAMS_T *params,
+ VCHIQ_SERVICE_HANDLE_T *pservice);
+extern VCHIQ_STATUS_T vchiq_close_service(VCHIQ_SERVICE_HANDLE_T service);
+extern VCHIQ_STATUS_T vchiq_remove_service(VCHIQ_SERVICE_HANDLE_T service);
+extern VCHIQ_STATUS_T vchiq_use_service(VCHIQ_SERVICE_HANDLE_T service);
+extern VCHIQ_STATUS_T vchiq_use_service_no_resume(
+ VCHIQ_SERVICE_HANDLE_T service);
+extern VCHIQ_STATUS_T vchiq_release_service(VCHIQ_SERVICE_HANDLE_T service);
+
+extern VCHIQ_STATUS_T vchiq_queue_message(VCHIQ_SERVICE_HANDLE_T service,
+ const VCHIQ_ELEMENT_T *elements, unsigned int count);
+extern void vchiq_release_message(VCHIQ_SERVICE_HANDLE_T service,
+ VCHIQ_HEADER_T *header);
+extern VCHIQ_STATUS_T vchiq_queue_bulk_transmit(VCHIQ_SERVICE_HANDLE_T service,
+ const void *data, unsigned int size, void *userdata);
+extern VCHIQ_STATUS_T vchiq_queue_bulk_receive(VCHIQ_SERVICE_HANDLE_T service,
+ void *data, unsigned int size, void *userdata);
+extern VCHIQ_STATUS_T vchiq_queue_bulk_transmit_handle(
+ VCHIQ_SERVICE_HANDLE_T service, VCHI_MEM_HANDLE_T handle,
+ const void *offset, unsigned int size, void *userdata);
+extern VCHIQ_STATUS_T vchiq_queue_bulk_receive_handle(
+ VCHIQ_SERVICE_HANDLE_T service, VCHI_MEM_HANDLE_T handle,
+ void *offset, unsigned int size, void *userdata);
+extern VCHIQ_STATUS_T vchiq_bulk_transmit(VCHIQ_SERVICE_HANDLE_T service,
+ const void *data, unsigned int size, void *userdata,
+ VCHIQ_BULK_MODE_T mode);
+extern VCHIQ_STATUS_T vchiq_bulk_receive(VCHIQ_SERVICE_HANDLE_T service,
+ void *data, unsigned int size, void *userdata,
+ VCHIQ_BULK_MODE_T mode);
+extern VCHIQ_STATUS_T vchiq_bulk_transmit_handle(VCHIQ_SERVICE_HANDLE_T service,
+ VCHI_MEM_HANDLE_T handle, const void *offset, unsigned int size,
+ void *userdata, VCHIQ_BULK_MODE_T mode);
+extern VCHIQ_STATUS_T vchiq_bulk_receive_handle(VCHIQ_SERVICE_HANDLE_T service,
+ VCHI_MEM_HANDLE_T handle, void *offset, unsigned int size,
+ void *userdata, VCHIQ_BULK_MODE_T mode);
+extern int vchiq_get_client_id(VCHIQ_SERVICE_HANDLE_T service);
+extern void *vchiq_get_service_userdata(VCHIQ_SERVICE_HANDLE_T service);
+extern int vchiq_get_service_fourcc(VCHIQ_SERVICE_HANDLE_T service);
+extern VCHIQ_STATUS_T vchiq_get_config(VCHIQ_INSTANCE_T instance,
+ int config_size, VCHIQ_CONFIG_T *pconfig);
+extern VCHIQ_STATUS_T vchiq_set_service_option(VCHIQ_SERVICE_HANDLE_T service,
+ VCHIQ_SERVICE_OPTION_T option, int value);
+
+extern VCHIQ_STATUS_T vchiq_remote_use(VCHIQ_INSTANCE_T instance,
+ VCHIQ_REMOTE_USE_CALLBACK_T callback, void *cb_arg);
+extern VCHIQ_STATUS_T vchiq_remote_release(VCHIQ_INSTANCE_T instance);
+
+extern VCHIQ_STATUS_T vchiq_dump_phys_mem(VCHIQ_SERVICE_HANDLE_T service,
+ void *ptr, size_t num_bytes);
+
+extern VCHIQ_STATUS_T vchiq_get_peer_version(VCHIQ_SERVICE_HANDLE_T handle,
+ short *peer_version);
+
+#endif /* VCHIQ_IF_H */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h
new file mode 100644
index 000000000000..6137ae9de1c1
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_ioctl.h
@@ -0,0 +1,131 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_IOCTLS_H
+#define VCHIQ_IOCTLS_H
+
+#include <linux/ioctl.h>
+#include "vchiq_if.h"
+
+#define VCHIQ_IOC_MAGIC 0xc4
+#define VCHIQ_INVALID_HANDLE (~0)
+
+typedef struct {
+ VCHIQ_SERVICE_PARAMS_T params;
+ int is_open;
+ int is_vchi;
+ unsigned int handle; /* OUT */
+} VCHIQ_CREATE_SERVICE_T;
+
+typedef struct {
+ unsigned int handle;
+ unsigned int count;
+ const VCHIQ_ELEMENT_T *elements;
+} VCHIQ_QUEUE_MESSAGE_T;
+
+typedef struct {
+ unsigned int handle;
+ void *data;
+ unsigned int size;
+ void *userdata;
+ VCHIQ_BULK_MODE_T mode;
+} VCHIQ_QUEUE_BULK_TRANSFER_T;
+
+typedef struct {
+ VCHIQ_REASON_T reason;
+ VCHIQ_HEADER_T *header;
+ void *service_userdata;
+ void *bulk_userdata;
+} VCHIQ_COMPLETION_DATA_T;
+
+typedef struct {
+ unsigned int count;
+ VCHIQ_COMPLETION_DATA_T *buf;
+ unsigned int msgbufsize;
+ unsigned int msgbufcount; /* IN/OUT */
+ void **msgbufs;
+} VCHIQ_AWAIT_COMPLETION_T;
+
+typedef struct {
+ unsigned int handle;
+ int blocking;
+ unsigned int bufsize;
+ void *buf;
+} VCHIQ_DEQUEUE_MESSAGE_T;
+
+typedef struct {
+ unsigned int config_size;
+ VCHIQ_CONFIG_T *pconfig;
+} VCHIQ_GET_CONFIG_T;
+
+typedef struct {
+ unsigned int handle;
+ VCHIQ_SERVICE_OPTION_T option;
+ int value;
+} VCHIQ_SET_SERVICE_OPTION_T;
+
+typedef struct {
+ void *virt_addr;
+ size_t num_bytes;
+} VCHIQ_DUMP_MEM_T;
+
+#define VCHIQ_IOC_CONNECT _IO(VCHIQ_IOC_MAGIC, 0)
+#define VCHIQ_IOC_SHUTDOWN _IO(VCHIQ_IOC_MAGIC, 1)
+#define VCHIQ_IOC_CREATE_SERVICE \
+ _IOWR(VCHIQ_IOC_MAGIC, 2, VCHIQ_CREATE_SERVICE_T)
+#define VCHIQ_IOC_REMOVE_SERVICE _IO(VCHIQ_IOC_MAGIC, 3)
+#define VCHIQ_IOC_QUEUE_MESSAGE \
+ _IOW(VCHIQ_IOC_MAGIC, 4, VCHIQ_QUEUE_MESSAGE_T)
+#define VCHIQ_IOC_QUEUE_BULK_TRANSMIT \
+ _IOWR(VCHIQ_IOC_MAGIC, 5, VCHIQ_QUEUE_BULK_TRANSFER_T)
+#define VCHIQ_IOC_QUEUE_BULK_RECEIVE \
+ _IOWR(VCHIQ_IOC_MAGIC, 6, VCHIQ_QUEUE_BULK_TRANSFER_T)
+#define VCHIQ_IOC_AWAIT_COMPLETION \
+ _IOWR(VCHIQ_IOC_MAGIC, 7, VCHIQ_AWAIT_COMPLETION_T)
+#define VCHIQ_IOC_DEQUEUE_MESSAGE \
+ _IOWR(VCHIQ_IOC_MAGIC, 8, VCHIQ_DEQUEUE_MESSAGE_T)
+#define VCHIQ_IOC_GET_CLIENT_ID _IO(VCHIQ_IOC_MAGIC, 9)
+#define VCHIQ_IOC_GET_CONFIG \
+ _IOWR(VCHIQ_IOC_MAGIC, 10, VCHIQ_GET_CONFIG_T)
+#define VCHIQ_IOC_CLOSE_SERVICE _IO(VCHIQ_IOC_MAGIC, 11)
+#define VCHIQ_IOC_USE_SERVICE _IO(VCHIQ_IOC_MAGIC, 12)
+#define VCHIQ_IOC_RELEASE_SERVICE _IO(VCHIQ_IOC_MAGIC, 13)
+#define VCHIQ_IOC_SET_SERVICE_OPTION \
+ _IOW(VCHIQ_IOC_MAGIC, 14, VCHIQ_SET_SERVICE_OPTION_T)
+#define VCHIQ_IOC_DUMP_PHYS_MEM \
+ _IOW(VCHIQ_IOC_MAGIC, 15, VCHIQ_DUMP_MEM_T)
+#define VCHIQ_IOC_LIB_VERSION _IO(VCHIQ_IOC_MAGIC, 16)
+#define VCHIQ_IOC_CLOSE_DELIVERED _IO(VCHIQ_IOC_MAGIC, 17)
+#define VCHIQ_IOC_MAX 17
+
+#endif
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
new file mode 100644
index 000000000000..25e7011edc50
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
@@ -0,0 +1,458 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+
+#include "vchiq_core.h"
+#include "vchiq_arm.h"
+#include "vchiq_killable.h"
+
+/* ---- Public Variables ------------------------------------------------- */
+
+/* ---- Private Constants and Types -------------------------------------- */
+
+struct bulk_waiter_node {
+ struct bulk_waiter bulk_waiter;
+ int pid;
+ struct list_head list;
+};
+
+struct vchiq_instance_struct {
+ VCHIQ_STATE_T *state;
+
+ int connected;
+
+ struct list_head bulk_waiter_list;
+ struct mutex bulk_waiter_list_mutex;
+};
+
+static VCHIQ_STATUS_T
+vchiq_blocking_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, void *data,
+ unsigned int size, VCHIQ_BULK_DIR_T dir);
+
+/****************************************************************************
+*
+* vchiq_initialise
+*
+***************************************************************************/
+#define VCHIQ_INIT_RETRIES 10
+VCHIQ_STATUS_T vchiq_initialise(VCHIQ_INSTANCE_T *instanceOut)
+{
+ VCHIQ_STATUS_T status = VCHIQ_ERROR;
+ VCHIQ_STATE_T *state;
+ VCHIQ_INSTANCE_T instance = NULL;
+ int i;
+
+ vchiq_log_trace(vchiq_core_log_level, "%s called", __func__);
+
+ /* VideoCore may not be ready due to boot up timing.
+ It may never be ready if kernel and firmware are mismatched, so don't block forever. */
+ for (i=0; i<VCHIQ_INIT_RETRIES; i++) {
+ state = vchiq_get_state();
+ if (state)
+ break;
+ udelay(500);
+ }
+ if (i==VCHIQ_INIT_RETRIES) {
+ vchiq_log_error(vchiq_core_log_level,
+ "%s: videocore not initialized\n", __func__);
+ goto failed;
+ } else if (i>0) {
+ vchiq_log_warning(vchiq_core_log_level,
+ "%s: videocore initialized after %d retries\n", __func__, i);
+ }
+
+ instance = kzalloc(sizeof(*instance), GFP_KERNEL);
+ if (!instance) {
+ vchiq_log_error(vchiq_core_log_level,
+ "%s: error allocating vchiq instance\n", __func__);
+ goto failed;
+ }
+
+ instance->connected = 0;
+ instance->state = state;
+ mutex_init(&instance->bulk_waiter_list_mutex);
+ INIT_LIST_HEAD(&instance->bulk_waiter_list);
+
+ *instanceOut = instance;
+
+ status = VCHIQ_SUCCESS;
+
+failed:
+ vchiq_log_trace(vchiq_core_log_level,
+ "%s(%p): returning %d", __func__, instance, status);
+
+ return status;
+}
+EXPORT_SYMBOL(vchiq_initialise);
+
+/****************************************************************************
+*
+* vchiq_shutdown
+*
+***************************************************************************/
+
+VCHIQ_STATUS_T vchiq_shutdown(VCHIQ_INSTANCE_T instance)
+{
+ VCHIQ_STATUS_T status;
+ VCHIQ_STATE_T *state = instance->state;
+
+ vchiq_log_trace(vchiq_core_log_level,
+ "%s(%p) called", __func__, instance);
+
+ if (mutex_lock_interruptible(&state->mutex) != 0)
+ return VCHIQ_RETRY;
+
+ /* Remove all services */
+ status = vchiq_shutdown_internal(state, instance);
+
+ mutex_unlock(&state->mutex);
+
+ vchiq_log_trace(vchiq_core_log_level,
+ "%s(%p): returning %d", __func__, instance, status);
+
+ if (status == VCHIQ_SUCCESS) {
+ struct list_head *pos, *next;
+ list_for_each_safe(pos, next,
+ &instance->bulk_waiter_list) {
+ struct bulk_waiter_node *waiter;
+ waiter = list_entry(pos,
+ struct bulk_waiter_node,
+ list);
+ list_del(pos);
+ vchiq_log_info(vchiq_arm_log_level,
+ "bulk_waiter - cleaned up %x "
+ "for pid %d",
+ (unsigned int)waiter, waiter->pid);
+ kfree(waiter);
+ }
+ kfree(instance);
+ }
+
+ return status;
+}
+EXPORT_SYMBOL(vchiq_shutdown);
+
+/****************************************************************************
+*
+* vchiq_is_connected
+*
+***************************************************************************/
+
+int vchiq_is_connected(VCHIQ_INSTANCE_T instance)
+{
+ return instance->connected;
+}
+
+/****************************************************************************
+*
+* vchiq_connect
+*
+***************************************************************************/
+
+VCHIQ_STATUS_T vchiq_connect(VCHIQ_INSTANCE_T instance)
+{
+ VCHIQ_STATUS_T status;
+ VCHIQ_STATE_T *state = instance->state;
+
+ vchiq_log_trace(vchiq_core_log_level,
+ "%s(%p) called", __func__, instance);
+
+ if (mutex_lock_interruptible(&state->mutex) != 0) {
+ vchiq_log_trace(vchiq_core_log_level,
+ "%s: call to mutex_lock failed", __func__);
+ status = VCHIQ_RETRY;
+ goto failed;
+ }
+ status = vchiq_connect_internal(state, instance);
+
+ if (status == VCHIQ_SUCCESS)
+ instance->connected = 1;
+
+ mutex_unlock(&state->mutex);
+
+failed:
+ vchiq_log_trace(vchiq_core_log_level,
+ "%s(%p): returning %d", __func__, instance, status);
+
+ return status;
+}
+EXPORT_SYMBOL(vchiq_connect);
+
+/****************************************************************************
+*
+* vchiq_add_service
+*
+***************************************************************************/
+
+VCHIQ_STATUS_T vchiq_add_service(
+ VCHIQ_INSTANCE_T instance,
+ const VCHIQ_SERVICE_PARAMS_T *params,
+ VCHIQ_SERVICE_HANDLE_T *phandle)
+{
+ VCHIQ_STATUS_T status;
+ VCHIQ_STATE_T *state = instance->state;
+ VCHIQ_SERVICE_T *service = NULL;
+ int srvstate;
+
+ vchiq_log_trace(vchiq_core_log_level,
+ "%s(%p) called", __func__, instance);
+
+ *phandle = VCHIQ_SERVICE_HANDLE_INVALID;
+
+ srvstate = vchiq_is_connected(instance)
+ ? VCHIQ_SRVSTATE_LISTENING
+ : VCHIQ_SRVSTATE_HIDDEN;
+
+ service = vchiq_add_service_internal(
+ state,
+ params,
+ srvstate,
+ instance,
+ NULL);
+
+ if (service) {
+ *phandle = service->handle;
+ status = VCHIQ_SUCCESS;
+ } else
+ status = VCHIQ_ERROR;
+
+ vchiq_log_trace(vchiq_core_log_level,
+ "%s(%p): returning %d", __func__, instance, status);
+
+ return status;
+}
+EXPORT_SYMBOL(vchiq_add_service);
+
+/****************************************************************************
+*
+* vchiq_open_service
+*
+***************************************************************************/
+
+VCHIQ_STATUS_T vchiq_open_service(
+ VCHIQ_INSTANCE_T instance,
+ const VCHIQ_SERVICE_PARAMS_T *params,
+ VCHIQ_SERVICE_HANDLE_T *phandle)
+{
+ VCHIQ_STATUS_T status = VCHIQ_ERROR;
+ VCHIQ_STATE_T *state = instance->state;
+ VCHIQ_SERVICE_T *service = NULL;
+
+ vchiq_log_trace(vchiq_core_log_level,
+ "%s(%p) called", __func__, instance);
+
+ *phandle = VCHIQ_SERVICE_HANDLE_INVALID;
+
+ if (!vchiq_is_connected(instance))
+ goto failed;
+
+ service = vchiq_add_service_internal(state,
+ params,
+ VCHIQ_SRVSTATE_OPENING,
+ instance,
+ NULL);
+
+ if (service) {
+ *phandle = service->handle;
+ status = vchiq_open_service_internal(service, current->pid);
+ if (status != VCHIQ_SUCCESS) {
+ vchiq_remove_service(service->handle);
+ *phandle = VCHIQ_SERVICE_HANDLE_INVALID;
+ }
+ }
+
+failed:
+ vchiq_log_trace(vchiq_core_log_level,
+ "%s(%p): returning %d", __func__, instance, status);
+
+ return status;
+}
+EXPORT_SYMBOL(vchiq_open_service);
+
+VCHIQ_STATUS_T
+vchiq_queue_bulk_transmit(VCHIQ_SERVICE_HANDLE_T handle,
+ const void *data, unsigned int size, void *userdata)
+{
+ return vchiq_bulk_transfer(handle,
+ VCHI_MEM_HANDLE_INVALID, (void *)data, size, userdata,
+ VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_TRANSMIT);
+}
+EXPORT_SYMBOL(vchiq_queue_bulk_transmit);
+
+VCHIQ_STATUS_T
+vchiq_queue_bulk_receive(VCHIQ_SERVICE_HANDLE_T handle, void *data,
+ unsigned int size, void *userdata)
+{
+ return vchiq_bulk_transfer(handle,
+ VCHI_MEM_HANDLE_INVALID, data, size, userdata,
+ VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_RECEIVE);
+}
+EXPORT_SYMBOL(vchiq_queue_bulk_receive);
+
+VCHIQ_STATUS_T
+vchiq_bulk_transmit(VCHIQ_SERVICE_HANDLE_T handle, const void *data,
+ unsigned int size, void *userdata, VCHIQ_BULK_MODE_T mode)
+{
+ VCHIQ_STATUS_T status;
+
+ switch (mode) {
+ case VCHIQ_BULK_MODE_NOCALLBACK:
+ case VCHIQ_BULK_MODE_CALLBACK:
+ status = vchiq_bulk_transfer(handle,
+ VCHI_MEM_HANDLE_INVALID, (void *)data, size, userdata,
+ mode, VCHIQ_BULK_TRANSMIT);
+ break;
+ case VCHIQ_BULK_MODE_BLOCKING:
+ status = vchiq_blocking_bulk_transfer(handle,
+ (void *)data, size, VCHIQ_BULK_TRANSMIT);
+ break;
+ default:
+ return VCHIQ_ERROR;
+ }
+
+ return status;
+}
+EXPORT_SYMBOL(vchiq_bulk_transmit);
+
+VCHIQ_STATUS_T
+vchiq_bulk_receive(VCHIQ_SERVICE_HANDLE_T handle, void *data,
+ unsigned int size, void *userdata, VCHIQ_BULK_MODE_T mode)
+{
+ VCHIQ_STATUS_T status;
+
+ switch (mode) {
+ case VCHIQ_BULK_MODE_NOCALLBACK:
+ case VCHIQ_BULK_MODE_CALLBACK:
+ status = vchiq_bulk_transfer(handle,
+ VCHI_MEM_HANDLE_INVALID, data, size, userdata,
+ mode, VCHIQ_BULK_RECEIVE);
+ break;
+ case VCHIQ_BULK_MODE_BLOCKING:
+ status = vchiq_blocking_bulk_transfer(handle,
+ (void *)data, size, VCHIQ_BULK_RECEIVE);
+ break;
+ default:
+ return VCHIQ_ERROR;
+ }
+
+ return status;
+}
+EXPORT_SYMBOL(vchiq_bulk_receive);
+
+static VCHIQ_STATUS_T
+vchiq_blocking_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, void *data,
+ unsigned int size, VCHIQ_BULK_DIR_T dir)
+{
+ VCHIQ_INSTANCE_T instance;
+ VCHIQ_SERVICE_T *service;
+ VCHIQ_STATUS_T status;
+ struct bulk_waiter_node *waiter = NULL;
+ struct list_head *pos;
+
+ service = find_service_by_handle(handle);
+ if (!service)
+ return VCHIQ_ERROR;
+
+ instance = service->instance;
+
+ unlock_service(service);
+
+ mutex_lock(&instance->bulk_waiter_list_mutex);
+ list_for_each(pos, &instance->bulk_waiter_list) {
+ if (list_entry(pos, struct bulk_waiter_node,
+ list)->pid == current->pid) {
+ waiter = list_entry(pos,
+ struct bulk_waiter_node,
+ list);
+ list_del(pos);
+ break;
+ }
+ }
+ mutex_unlock(&instance->bulk_waiter_list_mutex);
+
+ if (waiter) {
+ VCHIQ_BULK_T *bulk = waiter->bulk_waiter.bulk;
+ if (bulk) {
+ /* This thread has an outstanding bulk transfer. */
+ if ((bulk->data != data) ||
+ (bulk->size != size)) {
+ /* This is not a retry of the previous one.
+ ** Cancel the signal when the transfer
+ ** completes. */
+ spin_lock(&bulk_waiter_spinlock);
+ bulk->userdata = NULL;
+ spin_unlock(&bulk_waiter_spinlock);
+ }
+ }
+ }
+
+ if (!waiter) {
+ waiter = kzalloc(sizeof(struct bulk_waiter_node), GFP_KERNEL);
+ if (!waiter) {
+ vchiq_log_error(vchiq_core_log_level,
+ "%s - out of memory", __func__);
+ return VCHIQ_ERROR;
+ }
+ }
+
+ status = vchiq_bulk_transfer(handle, VCHI_MEM_HANDLE_INVALID,
+ data, size, &waiter->bulk_waiter, VCHIQ_BULK_MODE_BLOCKING,
+ dir);
+ if ((status != VCHIQ_RETRY) || fatal_signal_pending(current) ||
+ !waiter->bulk_waiter.bulk) {
+ VCHIQ_BULK_T *bulk = waiter->bulk_waiter.bulk;
+ if (bulk) {
+ /* Cancel the signal when the transfer
+ ** completes. */
+ spin_lock(&bulk_waiter_spinlock);
+ bulk->userdata = NULL;
+ spin_unlock(&bulk_waiter_spinlock);
+ }
+ kfree(waiter);
+ } else {
+ waiter->pid = current->pid;
+ mutex_lock(&instance->bulk_waiter_list_mutex);
+ list_add(&waiter->list, &instance->bulk_waiter_list);
+ mutex_unlock(&instance->bulk_waiter_list_mutex);
+ vchiq_log_info(vchiq_arm_log_level,
+ "saved bulk_waiter %x for pid %d",
+ (unsigned int)waiter, current->pid);
+ }
+
+ return status;
+}
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_killable.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_killable.h
new file mode 100644
index 000000000000..335446e05476
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_killable.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_KILLABLE_H
+#define VCHIQ_KILLABLE_H
+
+#include <linux/mutex.h>
+#include <linux/semaphore.h>
+
+#define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGTRAP) | sigmask(SIGSTOP) | sigmask(SIGCONT))
+
+static inline int __must_check down_interruptible_killable(struct semaphore *sem)
+{
+ /* Allow interception of killable signals only. We don't want to be interrupted by harmless signals like SIGALRM */
+ int ret;
+ sigset_t blocked, oldset;
+ siginitsetinv(&blocked, SHUTDOWN_SIGS);
+ sigprocmask(SIG_SETMASK, &blocked, &oldset);
+ ret = down_interruptible(sem);
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
+ return ret;
+}
+#define down_interruptible down_interruptible_killable
+
+
+static inline int __must_check mutex_lock_interruptible_killable(struct mutex *lock)
+{
+ /* Allow interception of killable signals only. We don't want to be interrupted by harmless signals like SIGALRM */
+ int ret;
+ sigset_t blocked, oldset;
+ siginitsetinv(&blocked, SHUTDOWN_SIGS);
+ sigprocmask(SIG_SETMASK, &blocked, &oldset);
+ ret = mutex_lock_interruptible(lock);
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
+ return ret;
+}
+#define mutex_lock_interruptible mutex_lock_interruptible_killable
+
+#endif
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_memdrv.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_memdrv.h
new file mode 100644
index 000000000000..d02e7764bd0d
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_memdrv.h
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_MEMDRV_H
+#define VCHIQ_MEMDRV_H
+
+/* ---- Include Files ----------------------------------------------------- */
+
+#include <linux/kernel.h>
+#include "vchiq_if.h"
+
+/* ---- Constants and Types ---------------------------------------------- */
+
+typedef struct {
+ void *armSharedMemVirt;
+ dma_addr_t armSharedMemPhys;
+ size_t armSharedMemSize;
+
+ void *vcSharedMemVirt;
+ dma_addr_t vcSharedMemPhys;
+ size_t vcSharedMemSize;
+} VCHIQ_SHARED_MEM_INFO_T;
+
+/* ---- Variable Externs ------------------------------------------------- */
+
+/* ---- Function Prototypes ---------------------------------------------- */
+
+void vchiq_get_shared_mem_info(VCHIQ_SHARED_MEM_INFO_T *info);
+
+VCHIQ_STATUS_T vchiq_memdrv_initialise(void);
+
+VCHIQ_STATUS_T vchiq_userdrv_create_instance(
+ const VCHIQ_PLATFORM_DATA_T * platform_data);
+
+VCHIQ_STATUS_T vchiq_userdrv_suspend(
+ const VCHIQ_PLATFORM_DATA_T * platform_data);
+
+VCHIQ_STATUS_T vchiq_userdrv_resume(
+ const VCHIQ_PLATFORM_DATA_T * platform_data);
+
+#endif
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_pagelist.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_pagelist.h
new file mode 100644
index 000000000000..54a3ecec69ef
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_pagelist.h
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_PAGELIST_H
+#define VCHIQ_PAGELIST_H
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
+#define CACHE_LINE_SIZE 32
+#define PAGELIST_WRITE 0
+#define PAGELIST_READ 1
+#define PAGELIST_READ_WITH_FRAGMENTS 2
+
+typedef struct pagelist_struct {
+ unsigned long length;
+ unsigned short type;
+ unsigned short offset;
+ unsigned long addrs[1]; /* N.B. 12 LSBs hold the number of following
+ pages at consecutive addresses. */
+} PAGELIST_T;
+
+typedef struct fragments_struct {
+ char headbuf[CACHE_LINE_SIZE];
+ char tailbuf[CACHE_LINE_SIZE];
+} FRAGMENTS_T;
+
+#endif /* VCHIQ_PAGELIST_H */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
new file mode 100644
index 000000000000..8072ff613636
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
@@ -0,0 +1,860 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include "interface/vchi/vchi.h"
+#include "vchiq.h"
+#include "vchiq_core.h"
+
+#include "vchiq_util.h"
+
+#include <stddef.h>
+
+#define vchiq_status_to_vchi(status) ((int32_t)status)
+
+typedef struct {
+ VCHIQ_SERVICE_HANDLE_T handle;
+
+ VCHIU_QUEUE_T queue;
+
+ VCHI_CALLBACK_T callback;
+ void *callback_param;
+} SHIM_SERVICE_T;
+
+/* ----------------------------------------------------------------------
+ * return pointer to the mphi message driver function table
+ * -------------------------------------------------------------------- */
+const VCHI_MESSAGE_DRIVER_T *
+vchi_mphi_message_driver_func_table(void)
+{
+ return NULL;
+}
+
+/* ----------------------------------------------------------------------
+ * return a pointer to the 'single' connection driver fops
+ * -------------------------------------------------------------------- */
+const VCHI_CONNECTION_API_T *
+single_get_func_table(void)
+{
+ return NULL;
+}
+
+VCHI_CONNECTION_T *vchi_create_connection(
+ const VCHI_CONNECTION_API_T *function_table,
+ const VCHI_MESSAGE_DRIVER_T *low_level)
+{
+ (void)function_table;
+ (void)low_level;
+ return NULL;
+}
+
+/***********************************************************
+ * Name: vchi_msg_peek
+ *
+ * Arguments: const VCHI_SERVICE_HANDLE_T handle,
+ * void **data,
+ * uint32_t *msg_size,
+
+
+ * VCHI_FLAGS_T flags
+ *
+ * Description: Routine to return a pointer to the current message (to allow in
+ * place processing). The message can be removed using
+ * vchi_msg_remove when you're finished
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+int32_t vchi_msg_peek(VCHI_SERVICE_HANDLE_T handle,
+ void **data,
+ uint32_t *msg_size,
+ VCHI_FLAGS_T flags)
+{
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ VCHIQ_HEADER_T *header;
+
+ WARN_ON((flags != VCHI_FLAGS_NONE) &&
+ (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
+
+ if (flags == VCHI_FLAGS_NONE)
+ if (vchiu_queue_is_empty(&service->queue))
+ return -1;
+
+ header = vchiu_queue_peek(&service->queue);
+
+ *data = header->data;
+ *msg_size = header->size;
+
+ return 0;
+}
+EXPORT_SYMBOL(vchi_msg_peek);
+
+/***********************************************************
+ * Name: vchi_msg_remove
+ *
+ * Arguments: const VCHI_SERVICE_HANDLE_T handle,
+ *
+ * Description: Routine to remove a message (after it has been read with
+ * vchi_msg_peek)
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+int32_t vchi_msg_remove(VCHI_SERVICE_HANDLE_T handle)
+{
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ VCHIQ_HEADER_T *header;
+
+ header = vchiu_queue_pop(&service->queue);
+
+ vchiq_release_message(service->handle, header);
+
+ return 0;
+}
+EXPORT_SYMBOL(vchi_msg_remove);
+
+/***********************************************************
+ * Name: vchi_msg_queue
+ *
+ * Arguments: VCHI_SERVICE_HANDLE_T handle,
+ * const void *data,
+ * uint32_t data_size,
+ * VCHI_FLAGS_T flags,
+ * void *msg_handle,
+ *
+ * Description: Thin wrapper to queue a message onto a connection
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+int32_t vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle,
+ const void *data,
+ uint32_t data_size,
+ VCHI_FLAGS_T flags,
+ void *msg_handle)
+{
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ VCHIQ_ELEMENT_T element = {data, data_size};
+ VCHIQ_STATUS_T status;
+
+ (void)msg_handle;
+
+ WARN_ON(flags != VCHI_FLAGS_BLOCK_UNTIL_QUEUED);
+
+ status = vchiq_queue_message(service->handle, &element, 1);
+
+ /* vchiq_queue_message() may return VCHIQ_RETRY, so we need to
+ ** implement a retry mechanism since this function is supposed
+ ** to block until queued
+ */
+ while (status == VCHIQ_RETRY) {
+ msleep(1);
+ status = vchiq_queue_message(service->handle, &element, 1);
+ }
+
+ return vchiq_status_to_vchi(status);
+}
+EXPORT_SYMBOL(vchi_msg_queue);
+
+/***********************************************************
+ * Name: vchi_bulk_queue_receive
+ *
+ * Arguments: VCHI_BULK_HANDLE_T handle,
+ * void *data_dst,
+ * const uint32_t data_size,
+ * VCHI_FLAGS_T flags
+ * void *bulk_handle
+ *
+ * Description: Routine to setup a rcv buffer
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+int32_t vchi_bulk_queue_receive(VCHI_SERVICE_HANDLE_T handle,
+ void *data_dst,
+ uint32_t data_size,
+ VCHI_FLAGS_T flags,
+ void *bulk_handle)
+{
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ VCHIQ_BULK_MODE_T mode;
+ VCHIQ_STATUS_T status;
+
+ switch ((int)flags) {
+ case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE
+ | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+ WARN_ON(!service->callback);
+ mode = VCHIQ_BULK_MODE_CALLBACK;
+ break;
+ case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
+ mode = VCHIQ_BULK_MODE_BLOCKING;
+ break;
+ case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+ case VCHI_FLAGS_NONE:
+ mode = VCHIQ_BULK_MODE_NOCALLBACK;
+ break;
+ default:
+ WARN(1, "unsupported message\n");
+ return vchiq_status_to_vchi(VCHIQ_ERROR);
+ }
+
+ status = vchiq_bulk_receive(service->handle, data_dst, data_size,
+ bulk_handle, mode);
+
+ /* vchiq_bulk_receive() may return VCHIQ_RETRY, so we need to
+ ** implement a retry mechanism since this function is supposed
+ ** to block until queued
+ */
+ while (status == VCHIQ_RETRY) {
+ msleep(1);
+ status = vchiq_bulk_receive(service->handle, data_dst,
+ data_size, bulk_handle, mode);
+ }
+
+ return vchiq_status_to_vchi(status);
+}
+EXPORT_SYMBOL(vchi_bulk_queue_receive);
+
+/***********************************************************
+ * Name: vchi_bulk_queue_transmit
+ *
+ * Arguments: VCHI_BULK_HANDLE_T handle,
+ * const void *data_src,
+ * uint32_t data_size,
+ * VCHI_FLAGS_T flags,
+ * void *bulk_handle
+ *
+ * Description: Routine to transmit some data
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+int32_t vchi_bulk_queue_transmit(VCHI_SERVICE_HANDLE_T handle,
+ const void *data_src,
+ uint32_t data_size,
+ VCHI_FLAGS_T flags,
+ void *bulk_handle)
+{
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ VCHIQ_BULK_MODE_T mode;
+ VCHIQ_STATUS_T status;
+
+ switch ((int)flags) {
+ case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE
+ | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+ WARN_ON(!service->callback);
+ mode = VCHIQ_BULK_MODE_CALLBACK;
+ break;
+ case VCHI_FLAGS_BLOCK_UNTIL_DATA_READ:
+ case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
+ mode = VCHIQ_BULK_MODE_BLOCKING;
+ break;
+ case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+ case VCHI_FLAGS_NONE:
+ mode = VCHIQ_BULK_MODE_NOCALLBACK;
+ break;
+ default:
+ WARN(1, "unsupported message\n");
+ return vchiq_status_to_vchi(VCHIQ_ERROR);
+ }
+
+ status = vchiq_bulk_transmit(service->handle, data_src, data_size,
+ bulk_handle, mode);
+
+ /* vchiq_bulk_transmit() may return VCHIQ_RETRY, so we need to
+ ** implement a retry mechanism since this function is supposed
+ ** to block until queued
+ */
+ while (status == VCHIQ_RETRY) {
+ msleep(1);
+ status = vchiq_bulk_transmit(service->handle, data_src,
+ data_size, bulk_handle, mode);
+ }
+
+ return vchiq_status_to_vchi(status);
+}
+EXPORT_SYMBOL(vchi_bulk_queue_transmit);
+
+/***********************************************************
+ * Name: vchi_msg_dequeue
+ *
+ * Arguments: VCHI_SERVICE_HANDLE_T handle,
+ * void *data,
+ * uint32_t max_data_size_to_read,
+ * uint32_t *actual_msg_size
+ * VCHI_FLAGS_T flags
+ *
+ * Description: Routine to dequeue a message into the supplied buffer
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+int32_t vchi_msg_dequeue(VCHI_SERVICE_HANDLE_T handle,
+ void *data,
+ uint32_t max_data_size_to_read,
+ uint32_t *actual_msg_size,
+ VCHI_FLAGS_T flags)
+{
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ VCHIQ_HEADER_T *header;
+
+ WARN_ON((flags != VCHI_FLAGS_NONE) &&
+ (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
+
+ if (flags == VCHI_FLAGS_NONE)
+ if (vchiu_queue_is_empty(&service->queue))
+ return -1;
+
+ header = vchiu_queue_pop(&service->queue);
+
+ memcpy(data, header->data, header->size < max_data_size_to_read ?
+ header->size : max_data_size_to_read);
+
+ *actual_msg_size = header->size;
+
+ vchiq_release_message(service->handle, header);
+
+ return 0;
+}
+EXPORT_SYMBOL(vchi_msg_dequeue);
+
+/***********************************************************
+ * Name: vchi_msg_queuev
+ *
+ * Arguments: VCHI_SERVICE_HANDLE_T handle,
+ * VCHI_MSG_VECTOR_T *vector,
+ * uint32_t count,
+ * VCHI_FLAGS_T flags,
+ * void *msg_handle
+ *
+ * Description: Thin wrapper to queue a message onto a connection
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+
+vchiq_static_assert(sizeof(VCHI_MSG_VECTOR_T) == sizeof(VCHIQ_ELEMENT_T));
+vchiq_static_assert(offsetof(VCHI_MSG_VECTOR_T, vec_base) ==
+ offsetof(VCHIQ_ELEMENT_T, data));
+vchiq_static_assert(offsetof(VCHI_MSG_VECTOR_T, vec_len) ==
+ offsetof(VCHIQ_ELEMENT_T, size));
+
+int32_t vchi_msg_queuev(VCHI_SERVICE_HANDLE_T handle,
+ VCHI_MSG_VECTOR_T *vector,
+ uint32_t count,
+ VCHI_FLAGS_T flags,
+ void *msg_handle)
+{
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+
+ (void)msg_handle;
+
+ WARN_ON(flags != VCHI_FLAGS_BLOCK_UNTIL_QUEUED);
+
+ return vchiq_status_to_vchi(vchiq_queue_message(service->handle,
+ (const VCHIQ_ELEMENT_T *)vector, count));
+}
+EXPORT_SYMBOL(vchi_msg_queuev);
+
+/***********************************************************
+ * Name: vchi_held_msg_release
+ *
+ * Arguments: VCHI_HELD_MSG_T *message
+ *
+ * Description: Routine to release a held message (after it has been read with
+ * vchi_msg_hold)
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+int32_t vchi_held_msg_release(VCHI_HELD_MSG_T *message)
+{
+ vchiq_release_message((VCHIQ_SERVICE_HANDLE_T)message->service,
+ (VCHIQ_HEADER_T *)message->message);
+
+ return 0;
+}
+EXPORT_SYMBOL(vchi_held_msg_release);
+
+/***********************************************************
+ * Name: vchi_msg_hold
+ *
+ * Arguments: VCHI_SERVICE_HANDLE_T handle,
+ * void **data,
+ * uint32_t *msg_size,
+ * VCHI_FLAGS_T flags,
+ * VCHI_HELD_MSG_T *message_handle
+ *
+ * Description: Routine to return a pointer to the current message (to allow
+ * in place processing). The message is dequeued - don't forget
+ * to release the message using vchi_held_msg_release when you're
+ * finished.
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+int32_t vchi_msg_hold(VCHI_SERVICE_HANDLE_T handle,
+ void **data,
+ uint32_t *msg_size,
+ VCHI_FLAGS_T flags,
+ VCHI_HELD_MSG_T *message_handle)
+{
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ VCHIQ_HEADER_T *header;
+
+ WARN_ON((flags != VCHI_FLAGS_NONE) &&
+ (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
+
+ if (flags == VCHI_FLAGS_NONE)
+ if (vchiu_queue_is_empty(&service->queue))
+ return -1;
+
+ header = vchiu_queue_pop(&service->queue);
+
+ *data = header->data;
+ *msg_size = header->size;
+
+ message_handle->service =
+ (struct opaque_vchi_service_t *)service->handle;
+ message_handle->message = header;
+
+ return 0;
+}
+EXPORT_SYMBOL(vchi_msg_hold);
+
+/***********************************************************
+ * Name: vchi_initialise
+ *
+ * Arguments: VCHI_INSTANCE_T *instance_handle
+ *
+ * Description: Initialises the hardware but does not transmit anything
+ * When run as a Host App this will be called twice hence the need
+ * to malloc the state information
+ *
+ * Returns: 0 if successful, failure otherwise
+ *
+ ***********************************************************/
+
+int32_t vchi_initialise(VCHI_INSTANCE_T *instance_handle)
+{
+ VCHIQ_INSTANCE_T instance;
+ VCHIQ_STATUS_T status;
+
+ status = vchiq_initialise(&instance);
+
+ *instance_handle = (VCHI_INSTANCE_T)instance;
+
+ return vchiq_status_to_vchi(status);
+}
+EXPORT_SYMBOL(vchi_initialise);
+
+/***********************************************************
+ * Name: vchi_connect
+ *
+ * Arguments: VCHI_CONNECTION_T **connections
+ * const uint32_t num_connections
+ * VCHI_INSTANCE_T instance_handle)
+ *
+ * Description: Starts the command service on each connection,
+ * causing INIT messages to be pinged back and forth
+ *
+ * Returns: 0 if successful, failure otherwise
+ *
+ ***********************************************************/
+int32_t vchi_connect(VCHI_CONNECTION_T **connections,
+ const uint32_t num_connections,
+ VCHI_INSTANCE_T instance_handle)
+{
+ VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
+
+ (void)connections;
+ (void)num_connections;
+
+ return vchiq_connect(instance);
+}
+EXPORT_SYMBOL(vchi_connect);
+
+
+/***********************************************************
+ * Name: vchi_disconnect
+ *
+ * Arguments: VCHI_INSTANCE_T instance_handle
+ *
+ * Description: Stops the command service on each connection,
+ * causing DE-INIT messages to be pinged back and forth
+ *
+ * Returns: 0 if successful, failure otherwise
+ *
+ ***********************************************************/
+int32_t vchi_disconnect(VCHI_INSTANCE_T instance_handle)
+{
+ VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
+ return vchiq_status_to_vchi(vchiq_shutdown(instance));
+}
+EXPORT_SYMBOL(vchi_disconnect);
+
+
+/***********************************************************
+ * Name: vchi_service_open
+ * Name: vchi_service_create
+ *
+ * Arguments: VCHI_INSTANCE_T *instance_handle
+ * SERVICE_CREATION_T *setup,
+ * VCHI_SERVICE_HANDLE_T *handle
+ *
+ * Description: Routine to open a service
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+
+static VCHIQ_STATUS_T shim_callback(VCHIQ_REASON_T reason,
+ VCHIQ_HEADER_T *header, VCHIQ_SERVICE_HANDLE_T handle, void *bulk_user)
+{
+ SHIM_SERVICE_T *service =
+ (SHIM_SERVICE_T *)VCHIQ_GET_SERVICE_USERDATA(handle);
+
+ if (!service->callback)
+ goto release;
+
+ switch (reason) {
+ case VCHIQ_MESSAGE_AVAILABLE:
+ vchiu_queue_push(&service->queue, header);
+
+ service->callback(service->callback_param,
+ VCHI_CALLBACK_MSG_AVAILABLE, NULL);
+
+ goto done;
+ break;
+
+ case VCHIQ_BULK_TRANSMIT_DONE:
+ service->callback(service->callback_param,
+ VCHI_CALLBACK_BULK_SENT, bulk_user);
+ break;
+
+ case VCHIQ_BULK_RECEIVE_DONE:
+ service->callback(service->callback_param,
+ VCHI_CALLBACK_BULK_RECEIVED, bulk_user);
+ break;
+
+ case VCHIQ_SERVICE_CLOSED:
+ service->callback(service->callback_param,
+ VCHI_CALLBACK_SERVICE_CLOSED, NULL);
+ break;
+
+ case VCHIQ_SERVICE_OPENED:
+ /* No equivalent VCHI reason */
+ break;
+
+ case VCHIQ_BULK_TRANSMIT_ABORTED:
+ service->callback(service->callback_param,
+ VCHI_CALLBACK_BULK_TRANSMIT_ABORTED,
+ bulk_user);
+ break;
+
+ case VCHIQ_BULK_RECEIVE_ABORTED:
+ service->callback(service->callback_param,
+ VCHI_CALLBACK_BULK_RECEIVE_ABORTED,
+ bulk_user);
+ break;
+
+ default:
+ WARN(1, "not supported\n");
+ break;
+ }
+
+release:
+ vchiq_release_message(service->handle, header);
+done:
+ return VCHIQ_SUCCESS;
+}
+
+static SHIM_SERVICE_T *service_alloc(VCHIQ_INSTANCE_T instance,
+ SERVICE_CREATION_T *setup)
+{
+ SHIM_SERVICE_T *service = kzalloc(sizeof(SHIM_SERVICE_T), GFP_KERNEL);
+
+ (void)instance;
+
+ if (service) {
+ if (vchiu_queue_init(&service->queue, 64)) {
+ service->callback = setup->callback;
+ service->callback_param = setup->callback_param;
+ } else {
+ kfree(service);
+ service = NULL;
+ }
+ }
+
+ return service;
+}
+
+static void service_free(SHIM_SERVICE_T *service)
+{
+ if (service) {
+ vchiu_queue_delete(&service->queue);
+ kfree(service);
+ }
+}
+
+int32_t vchi_service_open(VCHI_INSTANCE_T instance_handle,
+ SERVICE_CREATION_T *setup,
+ VCHI_SERVICE_HANDLE_T *handle)
+{
+ VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
+ SHIM_SERVICE_T *service = service_alloc(instance, setup);
+
+ *handle = (VCHI_SERVICE_HANDLE_T)service;
+
+ if (service) {
+ VCHIQ_SERVICE_PARAMS_T params;
+ VCHIQ_STATUS_T status;
+
+ memset(&params, 0, sizeof(params));
+ params.fourcc = setup->service_id;
+ params.callback = shim_callback;
+ params.userdata = service;
+ params.version = setup->version.version;
+ params.version_min = setup->version.version_min;
+
+ status = vchiq_open_service(instance, &params,
+ &service->handle);
+ if (status != VCHIQ_SUCCESS) {
+ service_free(service);
+ service = NULL;
+ *handle = NULL;
+ }
+ }
+
+ return (service != NULL) ? 0 : -1;
+}
+EXPORT_SYMBOL(vchi_service_open);
+
+int32_t vchi_service_create(VCHI_INSTANCE_T instance_handle,
+ SERVICE_CREATION_T *setup,
+ VCHI_SERVICE_HANDLE_T *handle)
+{
+ VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
+ SHIM_SERVICE_T *service = service_alloc(instance, setup);
+
+ *handle = (VCHI_SERVICE_HANDLE_T)service;
+
+ if (service) {
+ VCHIQ_SERVICE_PARAMS_T params;
+ VCHIQ_STATUS_T status;
+
+ memset(&params, 0, sizeof(params));
+ params.fourcc = setup->service_id;
+ params.callback = shim_callback;
+ params.userdata = service;
+ params.version = setup->version.version;
+ params.version_min = setup->version.version_min;
+ status = vchiq_add_service(instance, &params, &service->handle);
+
+ if (status != VCHIQ_SUCCESS) {
+ service_free(service);
+ service = NULL;
+ *handle = NULL;
+ }
+ }
+
+ return (service != NULL) ? 0 : -1;
+}
+EXPORT_SYMBOL(vchi_service_create);
+
+int32_t vchi_service_close(const VCHI_SERVICE_HANDLE_T handle)
+{
+ int32_t ret = -1;
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ if (service) {
+ VCHIQ_STATUS_T status = vchiq_close_service(service->handle);
+ if (status == VCHIQ_SUCCESS) {
+ service_free(service);
+ service = NULL;
+ }
+
+ ret = vchiq_status_to_vchi(status);
+ }
+ return ret;
+}
+EXPORT_SYMBOL(vchi_service_close);
+
+int32_t vchi_service_destroy(const VCHI_SERVICE_HANDLE_T handle)
+{
+ int32_t ret = -1;
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ if (service) {
+ VCHIQ_STATUS_T status = vchiq_remove_service(service->handle);
+ if (status == VCHIQ_SUCCESS) {
+ service_free(service);
+ service = NULL;
+ }
+
+ ret = vchiq_status_to_vchi(status);
+ }
+ return ret;
+}
+EXPORT_SYMBOL(vchi_service_destroy);
+
+int32_t vchi_service_set_option(const VCHI_SERVICE_HANDLE_T handle,
+ VCHI_SERVICE_OPTION_T option,
+ int value)
+{
+ int32_t ret = -1;
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ VCHIQ_SERVICE_OPTION_T vchiq_option;
+ switch (option) {
+ case VCHI_SERVICE_OPTION_TRACE:
+ vchiq_option = VCHIQ_SERVICE_OPTION_TRACE;
+ break;
+ case VCHI_SERVICE_OPTION_SYNCHRONOUS:
+ vchiq_option = VCHIQ_SERVICE_OPTION_SYNCHRONOUS;
+ break;
+ default:
+ service = NULL;
+ break;
+ }
+ if (service) {
+ VCHIQ_STATUS_T status =
+ vchiq_set_service_option(service->handle,
+ vchiq_option,
+ value);
+
+ ret = vchiq_status_to_vchi(status);
+ }
+ return ret;
+}
+EXPORT_SYMBOL(vchi_service_set_option);
+
+int32_t vchi_get_peer_version( const VCHI_SERVICE_HANDLE_T handle, short *peer_version )
+{
+ int32_t ret = -1;
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ if(service)
+ {
+ VCHIQ_STATUS_T status = vchiq_get_peer_version(service->handle, peer_version);
+ ret = vchiq_status_to_vchi( status );
+ }
+ return ret;
+}
+EXPORT_SYMBOL(vchi_get_peer_version);
+
+/* ----------------------------------------------------------------------
+ * read a uint32_t from buffer.
+ * network format is defined to be little endian
+ * -------------------------------------------------------------------- */
+uint32_t
+vchi_readbuf_uint32(const void *_ptr)
+{
+ const unsigned char *ptr = _ptr;
+ return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
+}
+
+/* ----------------------------------------------------------------------
+ * write a uint32_t to buffer.
+ * network format is defined to be little endian
+ * -------------------------------------------------------------------- */
+void
+vchi_writebuf_uint32(void *_ptr, uint32_t value)
+{
+ unsigned char *ptr = _ptr;
+ ptr[0] = (unsigned char)((value >> 0) & 0xFF);
+ ptr[1] = (unsigned char)((value >> 8) & 0xFF);
+ ptr[2] = (unsigned char)((value >> 16) & 0xFF);
+ ptr[3] = (unsigned char)((value >> 24) & 0xFF);
+}
+
+/* ----------------------------------------------------------------------
+ * read a uint16_t from buffer.
+ * network format is defined to be little endian
+ * -------------------------------------------------------------------- */
+uint16_t
+vchi_readbuf_uint16(const void *_ptr)
+{
+ const unsigned char *ptr = _ptr;
+ return ptr[0] | (ptr[1] << 8);
+}
+
+/* ----------------------------------------------------------------------
+ * write a uint16_t into the buffer.
+ * network format is defined to be little endian
+ * -------------------------------------------------------------------- */
+void
+vchi_writebuf_uint16(void *_ptr, uint16_t value)
+{
+ unsigned char *ptr = _ptr;
+ ptr[0] = (value >> 0) & 0xFF;
+ ptr[1] = (value >> 8) & 0xFF;
+}
+
+/***********************************************************
+ * Name: vchi_service_use
+ *
+ * Arguments: const VCHI_SERVICE_HANDLE_T handle
+ *
+ * Description: Routine to increment refcount on a service
+ *
+ * Returns: void
+ *
+ ***********************************************************/
+int32_t vchi_service_use(const VCHI_SERVICE_HANDLE_T handle)
+{
+ int32_t ret = -1;
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ if (service)
+ ret = vchiq_status_to_vchi(vchiq_use_service(service->handle));
+ return ret;
+}
+EXPORT_SYMBOL(vchi_service_use);
+
+/***********************************************************
+ * Name: vchi_service_release
+ *
+ * Arguments: const VCHI_SERVICE_HANDLE_T handle
+ *
+ * Description: Routine to decrement refcount on a service
+ *
+ * Returns: void
+ *
+ ***********************************************************/
+int32_t vchi_service_release(const VCHI_SERVICE_HANDLE_T handle)
+{
+ int32_t ret = -1;
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ if (service)
+ ret = vchiq_status_to_vchi(
+ vchiq_release_service(service->handle));
+ return ret;
+}
+EXPORT_SYMBOL(vchi_service_release);
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c
new file mode 100644
index 000000000000..384acb8d2eae
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c
@@ -0,0 +1,156 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "vchiq_util.h"
+#include "vchiq_killable.h"
+
+static inline int is_pow2(int i)
+{
+ return i && !(i & (i - 1));
+}
+
+int vchiu_queue_init(VCHIU_QUEUE_T *queue, int size)
+{
+ WARN_ON(!is_pow2(size));
+
+ queue->size = size;
+ queue->read = 0;
+ queue->write = 0;
+ queue->initialized = 1;
+
+ sema_init(&queue->pop, 0);
+ sema_init(&queue->push, 0);
+
+ queue->storage = kzalloc(size * sizeof(VCHIQ_HEADER_T *), GFP_KERNEL);
+ if (queue->storage == NULL) {
+ vchiu_queue_delete(queue);
+ return 0;
+ }
+ return 1;
+}
+
+void vchiu_queue_delete(VCHIU_QUEUE_T *queue)
+{
+ if (queue->storage != NULL)
+ kfree(queue->storage);
+}
+
+int vchiu_queue_is_empty(VCHIU_QUEUE_T *queue)
+{
+ return queue->read == queue->write;
+}
+
+int vchiu_queue_is_full(VCHIU_QUEUE_T *queue)
+{
+ return queue->write == queue->read + queue->size;
+}
+
+void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header)
+{
+ if (!queue->initialized)
+ return;
+
+ while (queue->write == queue->read + queue->size) {
+ if (down_interruptible(&queue->pop) != 0) {
+ flush_signals(current);
+ }
+ }
+
+ /*
+ * Write to queue->storage must be visible after read from
+ * queue->read
+ */
+ smp_mb();
+
+ queue->storage[queue->write & (queue->size - 1)] = header;
+
+ /*
+ * Write to queue->storage must be visible before write to
+ * queue->write
+ */
+ smp_wmb();
+
+ queue->write++;
+
+ up(&queue->push);
+}
+
+VCHIQ_HEADER_T *vchiu_queue_peek(VCHIU_QUEUE_T *queue)
+{
+ while (queue->write == queue->read) {
+ if (down_interruptible(&queue->push) != 0) {
+ flush_signals(current);
+ }
+ }
+
+ up(&queue->push); // We haven't removed anything from the queue.
+
+ /*
+ * Read from queue->storage must be visible after read from
+ * queue->write
+ */
+ smp_rmb();
+
+ return queue->storage[queue->read & (queue->size - 1)];
+}
+
+VCHIQ_HEADER_T *vchiu_queue_pop(VCHIU_QUEUE_T *queue)
+{
+ VCHIQ_HEADER_T *header;
+
+ while (queue->write == queue->read) {
+ if (down_interruptible(&queue->push) != 0) {
+ flush_signals(current);
+ }
+ }
+
+ /*
+ * Read from queue->storage must be visible after read from
+ * queue->write
+ */
+ smp_rmb();
+
+ header = queue->storage[queue->read & (queue->size - 1)];
+
+ /*
+ * Read from queue->storage must be visible before write to
+ * queue->read
+ */
+ smp_mb();
+
+ queue->read++;
+
+ up(&queue->pop);
+
+ return header;
+}
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.h
new file mode 100644
index 000000000000..4055d4bf9f74
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.h
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VCHIQ_UTIL_H
+#define VCHIQ_UTIL_H
+
+#include <linux/types.h>
+#include <linux/semaphore.h>
+#include <linux/mutex.h>
+#include <linux/bitops.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+#include <linux/vmalloc.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+#include <linux/ctype.h>
+#include <linux/uaccess.h>
+#include <linux/time.h> /* for time_t */
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include "vchiq_if.h"
+
+typedef struct {
+ int size;
+ int read;
+ int write;
+ int initialized;
+
+ struct semaphore pop;
+ struct semaphore push;
+
+ VCHIQ_HEADER_T **storage;
+} VCHIU_QUEUE_T;
+
+extern int vchiu_queue_init(VCHIU_QUEUE_T *queue, int size);
+extern void vchiu_queue_delete(VCHIU_QUEUE_T *queue);
+
+extern int vchiu_queue_is_empty(VCHIU_QUEUE_T *queue);
+extern int vchiu_queue_is_full(VCHIU_QUEUE_T *queue);
+
+extern void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header);
+
+extern VCHIQ_HEADER_T *vchiu_queue_peek(VCHIU_QUEUE_T *queue);
+extern VCHIQ_HEADER_T *vchiu_queue_pop(VCHIU_QUEUE_T *queue);
+
+#endif
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_version.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_version.c
new file mode 100644
index 000000000000..b6bfa21155e4
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_version.c
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "vchiq_build_info.h"
+#include <linux/broadcom/vc_debug_sym.h>
+
+VC_DEBUG_DECLARE_STRING_VAR( vchiq_build_hostname, "dc4-arm-01" );
+VC_DEBUG_DECLARE_STRING_VAR( vchiq_build_version, "9245b4c35b99b3870e1f7dc598c5692b3c66a6f0 (tainted)" );
+VC_DEBUG_DECLARE_STRING_VAR( vchiq_build_time, __TIME__ );
+VC_DEBUG_DECLARE_STRING_VAR( vchiq_build_date, __DATE__ );
+
+const char *vchiq_get_build_hostname( void )
+{
+ return vchiq_build_hostname;
+}
+
+const char *vchiq_get_build_version( void )
+{
+ return vchiq_build_version;
+}
+
+const char *vchiq_get_build_date( void )
+{
+ return vchiq_build_date;
+}
+
+const char *vchiq_get_build_time( void )
+{
+ return vchiq_build_time;
+}
diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c
index 28a45689e2f4..8e66a520266c 100644
--- a/drivers/staging/vme/devices/vme_pio2_core.c
+++ b/drivers/staging/vme/devices/vme_pio2_core.c
@@ -466,23 +466,23 @@ static void __exit pio2_exit(void)
/* These are required for each board */
MODULE_PARM_DESC(bus, "Enumeration of VMEbus to which the board is connected");
-module_param_array(bus, int, &bus_num, S_IRUGO);
+module_param_array(bus, int, &bus_num, 0444);
MODULE_PARM_DESC(base, "Base VME address for PIO2 Registers");
-module_param_array(base, long, &base_num, S_IRUGO);
+module_param_array(base, long, &base_num, 0444);
MODULE_PARM_DESC(vector, "VME IRQ Vector (Lower 4 bits masked)");
-module_param_array(vector, int, &vector_num, S_IRUGO);
+module_param_array(vector, int, &vector_num, 0444);
MODULE_PARM_DESC(level, "VME IRQ Level");
-module_param_array(level, int, &level_num, S_IRUGO);
+module_param_array(level, int, &level_num, 0444);
MODULE_PARM_DESC(variant, "Last 4 characters of PIO2 board variant");
-module_param_array(variant, charp, &variant_num, S_IRUGO);
+module_param_array(variant, charp, &variant_num, 0444);
/* This is for debugging */
MODULE_PARM_DESC(loopback, "Enable loopback mode on all cards");
-module_param(loopback, bool, S_IRUGO);
+module_param(loopback, bool, 0444);
MODULE_DESCRIPTION("GE PIO2 6U VME I/O Driver");
MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index b95883bc68fe..5dd430f8f921 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -773,7 +773,7 @@ static void __exit vme_user_exit(void)
}
MODULE_PARM_DESC(bus, "Enumeration of VMEbus to which the driver is connected");
-module_param_array(bus, int, &bus_num, 0);
+module_param_array(bus, int, &bus_num, 0000);
MODULE_DESCRIPTION("VME User Space Access Driver");
MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c
index 654d072bdc28..de503a316e71 100644
--- a/drivers/staging/vt6655/baseband.c
+++ b/drivers/staging/vt6655/baseband.c
@@ -1729,7 +1729,7 @@ BBuGetFrameTime(
unsigned int uFrameTime;
unsigned int uPreamble;
unsigned int uTmp;
- unsigned int uRateIdx = (unsigned int) wRate;
+ unsigned int uRateIdx = (unsigned int)wRate;
unsigned int uRate = 0;
if (uRateIdx > RATE_54M)
diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c
index afb1e8bde975..dbcea4434725 100644
--- a/drivers/staging/vt6655/card.c
+++ b/drivers/staging/vt6655/card.c
@@ -619,7 +619,7 @@ CARDvSafeResetRx(
static unsigned short CARDwGetCCKControlRate(struct vnt_private *priv,
unsigned short wRateIdx)
{
- unsigned int ui = (unsigned int) wRateIdx;
+ unsigned int ui = (unsigned int)wRateIdx;
while (ui > RATE_1M) {
if (priv->basic_rates & ((u32)0x1 << ui))
@@ -645,7 +645,7 @@ static unsigned short CARDwGetCCKControlRate(struct vnt_private *priv,
static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv,
unsigned short wRateIdx)
{
- unsigned int ui = (unsigned int) wRateIdx;
+ unsigned int ui = (unsigned int)wRateIdx;
pr_debug("BASIC RATE: %X\n", priv->basic_rates);
diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c
index b7d43a5622ba..029a8df4ca1c 100644
--- a/drivers/staging/vt6655/channel.c
+++ b/drivers/staging/vt6655/channel.c
@@ -193,7 +193,8 @@ bool set_channel(struct vnt_private *priv, struct ieee80211_channel *ch)
MACvRegBitsOn(priv->PortOffset, MAC_REG_MACCR, MACCR_CLRNAV);
/* TX_PE will reserve 3 us for MAX2829 A mode only,
- it is for better TX throughput */
+ * it is for better TX throughput
+ */
if (priv->byRFType == RF_AIROHA7230)
RFbAL7230SelectChannelPostProcess(priv, priv->byCurrentCh,
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index 494164045a0f..f109eeac358d 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -113,10 +113,10 @@ DEVICE_PARAM(ShortRetryLimit, "Short frame retry limits");
DEVICE_PARAM(LongRetryLimit, "long frame retry limits");
/* BasebandType[] baseband type selected
- 0: indicate 802.11a type
- 1: indicate 802.11b type
- 2: indicate 802.11g type
-*/
+ * 0: indicate 802.11a type
+ * 1: indicate 802.11b type
+ * 2: indicate 802.11g type
+ */
#define BBP_TYPE_MIN 0
#define BBP_TYPE_MAX 2
#define BBP_TYPE_DEF 2
@@ -477,7 +477,7 @@ static bool device_init_rings(struct vnt_private *priv)
CB_MAX_BUF_SIZE,
&priv->tx_bufs_dma0,
GFP_ATOMIC);
- if (priv->tx0_bufs == NULL) {
+ if (!priv->tx0_bufs) {
dev_err(&priv->pcid->dev, "allocate buf dma memory failed\n");
dma_free_coherent(&priv->pcid->dev,
@@ -735,7 +735,7 @@ static bool device_alloc_rx_buf(struct vnt_private *priv,
struct vnt_rd_info *rd_info = rd->rd_info;
rd_info->skb = dev_alloc_skb((int)priv->rx_buf_sz);
- if (rd_info->skb == NULL)
+ if (!rd_info->skb)
return false;
rd_info->skb_dma =
diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c
index ffcaf25fdd8b..e161d5d9aebb 100644
--- a/drivers/staging/vt6655/key.c
+++ b/drivers/staging/vt6655/key.c
@@ -31,16 +31,6 @@
#include "key.h"
#include "mac.h"
-int vnt_key_init_table(struct vnt_private *priv)
-{
- u32 i;
-
- for (i = 0; i < MAX_KEY_TABLE; i++)
- MACvDisableKeyEntry(priv, i);
-
- return 0;
-}
-
static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr,
struct ieee80211_key_conf *key, u32 key_type, u32 mode,
bool onfly_latch)
diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h
index 261f8181d410..d72719741a56 100644
--- a/drivers/staging/vt6655/key.h
+++ b/drivers/staging/vt6655/key.h
@@ -61,8 +61,6 @@
struct vnt_private;
-int vnt_key_init_table(struct vnt_private *);
-
int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
struct ieee80211_vif *vif, struct ieee80211_key_conf *key);
diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c
index bc8ca981a629..7d6e7464ae51 100644
--- a/drivers/staging/vt6655/power.c
+++ b/drivers/staging/vt6655/power.c
@@ -52,7 +52,7 @@
/*--------------------- Export Functions --------------------------*/
-/*+
+/*
*
* Routine Description:
* Enable hw power saving functions
@@ -60,7 +60,7 @@
* Return Value:
* None.
*
- -*/
+ */
void
PSvEnablePowerSaving(
@@ -104,7 +104,7 @@ PSvEnablePowerSaving(
pr_debug("PS:Power Saving Mode Enable...\n");
}
-/*+
+/*
*
* Routine Description:
* Disable hw power saving functions
@@ -112,7 +112,7 @@ PSvEnablePowerSaving(
* Return Value:
* None.
*
- -*/
+ */
void
PSvDisablePowerSaving(
@@ -134,7 +134,7 @@ PSvDisablePowerSaving(
}
-/*+
+/*
*
* Routine Description:
* Check if Next TBTT must wake up
@@ -142,7 +142,7 @@ PSvDisablePowerSaving(
* Return Value:
* None.
*
- -*/
+ */
bool
PSbIsNextTBTTWakeUp(
diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c
index ae10da21ddd0..447882c7a6be 100644
--- a/drivers/staging/vt6655/rf.c
+++ b/drivers/staging/vt6655/rf.c
@@ -169,7 +169,8 @@ static unsigned long dwAL2230PowerTable[AL2230_PWR_IDX_LEN] = {
};
/* 40MHz reference frequency
- * Need to Pull PLLON(PE3) low when writing channel registers through 3-wire.*/
+ * Need to Pull PLLON(PE3) low when writing channel registers through 3-wire.
+ */
static const unsigned long dwAL7230InitTable[CB_AL7230_INIT_SEQ] = {
0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, /* Channel1 // Need modify for 11a */
0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, /* Channel1 // Need modify for 11a */
@@ -463,7 +464,8 @@ static bool s_bAL7230Init(struct vnt_private *priv)
}
/* Need to Pull PLLON low when writing channel registers through
- * 3-wire interface */
+ * 3-wire interface
+ */
static bool s_bAL7230SelectChannel(struct vnt_private *priv, unsigned char byChannel)
{
void __iomem *dwIoBase = priv->PortOffset;
@@ -873,7 +875,8 @@ bool RFbRawSetPower(
case RF_AIROHA7230:
/* 0x080F1B00 for 3 wire control TxGain(D10)
- * and 0x31 as TX Gain value */
+ * and 0x31 as TX Gain value
+ */
dwMax7230Pwr = 0x080C0B00 | ((byPwr) << 12) |
(BY_AL7230_REG_LEN << 3) | IFREGCTL_REGW;
@@ -886,7 +889,7 @@ bool RFbRawSetPower(
return ret;
}
-/*+
+/*
*
* Routine Description:
* Translate RSSI to dBm
@@ -900,7 +903,7 @@ bool RFbRawSetPower(
*
* Return Value: none
*
- -*/
+ */
void
RFvRSSITodBm(
struct vnt_private *priv,
@@ -927,7 +930,8 @@ RFvRSSITodBm(
}
/* Post processing for the 11b/g and 11a.
- * for save time on changing Reg2,3,5,7,10,12,15 */
+ * for save time on changing Reg2,3,5,7,10,12,15
+ */
bool RFbAL7230SelectChannelPostProcess(struct vnt_private *priv,
u16 byOldChannel,
u16 byNewChannel)
@@ -938,7 +942,8 @@ bool RFbAL7230SelectChannelPostProcess(struct vnt_private *priv,
/* if change between 11 b/g and 11a need to update the following
* register
- * Channel Index 1~14 */
+ * Channel Index 1~14
+ */
if ((byOldChannel <= CB_MAX_CHANNEL_24G) && (byNewChannel > CB_MAX_CHANNEL_24G)) {
/* Change from 2.4G to 5G [Reg] */
ret &= IFRFbWriteEmbedded(priv, dwAL7230InitTableAMode[2]);
diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c
index e4c3165ae027..7e69bc99d60f 100644
--- a/drivers/staging/vt6655/rxtx.c
+++ b/drivers/staging/vt6655/rxtx.c
@@ -64,8 +64,10 @@
/*--------------------- Static Functions --------------------------*/
/*--------------------- Static Definitions -------------------------*/
-#define CRITICAL_PACKET_LEN 256 /* if packet size < 256 -> in-direct send
- packet size >= 256 -> direct send */
+/* if packet size < 256 -> in-direct send
+ * vpacket size >= 256 -> direct send
+ */
+#define CRITICAL_PACKET_LEN 256
static const unsigned short wTimeStampOff[2][MAX_RATE] = {
{384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */
@@ -158,11 +160,11 @@ static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
[rate % MAX_RATE]);
}
-/*byPktType : PK_TYPE_11A 0
- PK_TYPE_11B 1
- PK_TYPE_11GB 2
- PK_TYPE_11GA 3
-*/
+/* byPktType : PK_TYPE_11A 0
+ * PK_TYPE_11B 1
+ * PK_TYPE_11GB 2
+ * PK_TYPE_11GA 3
+ */
static
unsigned int
s_uGetTxRsvTime(
@@ -502,7 +504,7 @@ s_uFillDataHead(
)
{
- if (pTxDataHead == NULL)
+ if (!pTxDataHead)
return 0;
@@ -646,17 +648,20 @@ s_vFillRTSHead(
{
unsigned int uRTSFrameLen = 20;
- if (pvRTS == NULL)
+ if (!pvRTS)
return;
if (bDisCRC) {
- /* When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
- in this case we need to decrease its length by 4. */
+ /* When CRCDIS bit is on, H/W forgot to generate FCS for
+ * RTS frame, in this case we need to decrease its length by 4.
+ */
uRTSFrameLen -= 4;
}
- /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA, so we don't need to take them into account.
- Otherwise, we need to modify codes for them. */
+ /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
+ * so we don't need to take them into account.
+ * Otherwise, we need to modify codes for them.
+ */
if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
if (byFBOption == AUTO_FB_NONE) {
struct vnt_rts_g *buf = pvRTS;
@@ -838,12 +843,13 @@ s_vFillCTSHead(
{
unsigned int uCTSFrameLen = 14;
- if (pvCTS == NULL)
+ if (!pvCTS)
return;
if (bDisCRC) {
- /* When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
- in this case we need to decrease its length by 4. */
+ /* When CRCDIS bit is on, H/W forgot to generate FCS for
+ * CTS frame, in this case we need to decrease its length by 4.
+ */
uCTSFrameLen -= 4;
}
@@ -915,7 +921,7 @@ s_vFillCTSHead(
}
}
-/*+
+/*
*
* Description:
* Generate FIFO control for MAC & Baseband controller
@@ -937,7 +943,8 @@ s_vFillCTSHead(
* Return Value: none
*
-
- * unsigned int cbFrameSize, Hdr+Payload+FCS */
+ * unsigned int cbFrameSize, Hdr+Payload+FCS
+ */
static
void
s_vGenerateTxParameter(
@@ -972,8 +979,8 @@ s_vGenerateTxParameter(
return;
if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
- if (pvRTS != NULL) { /* RTS_need
- Fill RsvTime */
+ if (pvRTS != NULL) { /* RTS_need */
+ /* Fill RsvTime */
struct vnt_rrv_time_rts *buf = pvRrvTime;
buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
@@ -1002,7 +1009,7 @@ s_vGenerateTxParameter(
/* Fill RTS */
s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
- } else if (pvRTS == NULL) {/* RTS_needless, non PCF mode */
+ } else if (!pvRTS) {/* RTS_needless, non PCF mode */
struct vnt_rrv_time_ab *buf = pvRrvTime;
buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h
index 807a5809b5d9..7cc13874f8f1 100644
--- a/drivers/staging/vt6656/baseband.h
+++ b/drivers/staging/vt6656/baseband.h
@@ -84,10 +84,10 @@ struct vnt_phy_field {
} __packed;
unsigned int vnt_get_frame_time(u8 preamble_type, u8 pkt_type,
- unsigned int frame_length, u16 tx_rate);
+ unsigned int frame_length, u16 tx_rate);
void vnt_get_phy_field(struct vnt_private *, u32 frame_length,
- u16 tx_rate, u8 pkt_type, struct vnt_phy_field *);
+ u16 tx_rate, u8 pkt_type, struct vnt_phy_field *);
void vnt_set_short_slot_time(struct vnt_private *);
void vnt_set_vga_gain_offset(struct vnt_private *, u8);
diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c
index a382fc6aa9d3..53b469c71dc2 100644
--- a/drivers/staging/vt6656/card.c
+++ b/drivers/staging/vt6656/card.c
@@ -46,10 +46,11 @@
#include "key.h"
#include "usbpipe.h"
-/* const u16 cwRXBCNTSFOff[MAX_RATE] =
- {17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3}; */
+/* const u16 cw_rxbcntsf_off[MAX_RATE] =
+ * {17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3};
+ */
-static const u16 cwRXBCNTSFOff[MAX_RATE] = {
+static const u16 cw_rxbcntsf_off[MAX_RATE] = {
192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3
};
@@ -65,7 +66,6 @@ static const u16 cwRXBCNTSFOff[MAX_RATE] = {
*/
void vnt_set_channel(struct vnt_private *priv, u32 connection_channel)
{
-
if (connection_channel > CB_MAX_CHANNEL || !connection_channel)
return;
@@ -76,10 +76,10 @@ void vnt_set_channel(struct vnt_private *priv, u32 connection_channel)
vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL, 0xb0);
vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNEL,
- connection_channel, 0, 0, NULL);
+ connection_channel, 0, 0, NULL);
vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL,
- (u8)(connection_channel | 0x80));
+ (u8)(connection_channel | 0x80));
}
/*
@@ -126,11 +126,11 @@ static u16 vnt_get_ofdm_rate(struct vnt_private *priv, u16 rate_idx)
u16 ui = rate_idx;
dev_dbg(&priv->usb->dev, "%s basic rate: %d\n",
- __func__, priv->basic_rates);
+ __func__, priv->basic_rates);
if (!vnt_ofdm_min_rate(priv)) {
dev_dbg(&priv->usb->dev, "%s (NO OFDM) %d\n",
- __func__, rate_idx);
+ __func__, rate_idx);
if (rate_idx > RATE_24M)
rate_idx = RATE_24M;
return rate_idx;
@@ -139,7 +139,7 @@ static u16 vnt_get_ofdm_rate(struct vnt_private *priv, u16 rate_idx)
while (ui > RATE_11M) {
if (priv->basic_rates & (1 << ui)) {
dev_dbg(&priv->usb->dev, "%s rate: %d\n",
- __func__, ui);
+ __func__, ui);
return ui;
}
ui--;
@@ -165,9 +165,8 @@ static u16 vnt_get_ofdm_rate(struct vnt_private *priv, u16 rate_idx)
*
*/
static void vnt_calculate_ofdm_rate(u16 rate, u8 bb_type,
- u8 *tx_rate, u8 *rsv_time)
+ u8 *tx_rate, u8 *rsv_time)
{
-
switch (rate) {
case RATE_6M:
if (bb_type == BB_TYPE_11A) {
@@ -267,20 +266,20 @@ void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type)
int i;
/*RSPINF_b_1*/
- vnt_get_phy_field(priv, 14,
- vnt_get_cck_rate(priv, RATE_1M), PK_TYPE_11B, &phy[0]);
+ vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_1M),
+ PK_TYPE_11B, &phy[0]);
/*RSPINF_b_2*/
- vnt_get_phy_field(priv, 14,
- vnt_get_cck_rate(priv, RATE_2M), PK_TYPE_11B, &phy[1]);
+ vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_2M),
+ PK_TYPE_11B, &phy[1]);
/*RSPINF_b_5*/
- vnt_get_phy_field(priv, 14,
- vnt_get_cck_rate(priv, RATE_5M), PK_TYPE_11B, &phy[2]);
+ vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_5M),
+ PK_TYPE_11B, &phy[2]);
/*RSPINF_b_11*/
- vnt_get_phy_field(priv, 14,
- vnt_get_cck_rate(priv, RATE_11M), PK_TYPE_11B, &phy[3]);
+ vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_11M),
+ PK_TYPE_11B, &phy[3]);
/*RSPINF_a_6*/
vnt_calculate_ofdm_rate(RATE_6M, bb_type, &tx_rate[0], &rsv_time[0]);
@@ -299,19 +298,19 @@ void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type)
/*RSPINF_a_36*/
vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_36M),
- bb_type, &tx_rate[5], &rsv_time[5]);
+ bb_type, &tx_rate[5], &rsv_time[5]);
/*RSPINF_a_48*/
vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_48M),
- bb_type, &tx_rate[6], &rsv_time[6]);
+ bb_type, &tx_rate[6], &rsv_time[6]);
/*RSPINF_a_54*/
vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M),
- bb_type, &tx_rate[7], &rsv_time[7]);
+ bb_type, &tx_rate[7], &rsv_time[7]);
/*RSPINF_a_72*/
vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M),
- bb_type, &tx_rate[8], &rsv_time[8]);
+ bb_type, &tx_rate[8], &rsv_time[8]);
put_unaligned(phy[0].len, (u16 *)&data[0]);
data[2] = phy[0].signal;
@@ -334,8 +333,8 @@ void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type)
data[16 + i * 2 + 1] = rsv_time[i];
}
- vnt_control_out(priv, MESSAGE_TYPE_WRITE,
- MAC_REG_RSPINF_B_1, MESSAGE_REQUEST_MACREG, 34, &data[0]);
+ vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_B_1,
+ MESSAGE_REQUEST_MACREG, 34, &data[0]);
}
/*
@@ -429,12 +428,12 @@ void vnt_update_ifs(struct vnt_private *priv)
data[3] = (u8)priv->slot;
vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_SIFS,
- MESSAGE_REQUEST_MACREG, 4, &data[0]);
+ MESSAGE_REQUEST_MACREG, 4, &data[0]);
max_min |= 0xa0;
vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_CWMAXMIN0,
- MESSAGE_REQUEST_MACREG, 1, &max_min);
+ MESSAGE_REQUEST_MACREG, 1, &max_min);
}
void vnt_update_top_rates(struct vnt_private *priv)
@@ -478,7 +477,6 @@ int vnt_ofdm_min_rate(struct vnt_private *priv)
u8 vnt_get_pkt_type(struct vnt_private *priv)
{
-
if (priv->bb_type == BB_TYPE_11A || priv->bb_type == BB_TYPE_11B)
return (u8)priv->bb_type;
else if (vnt_ofdm_min_rate(priv))
@@ -506,7 +504,7 @@ u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2)
u64 tsf_offset = 0;
u16 rx_bcn_offset;
- rx_bcn_offset = cwRXBCNTSFOff[rx_rate % MAX_RATE];
+ rx_bcn_offset = cw_rxbcntsf_off[rx_rate % MAX_RATE];
tsf2 += (u64)rx_bcn_offset;
@@ -531,7 +529,7 @@ u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2)
*
*/
void vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate,
- u64 time_stamp, u64 local_tsf)
+ u64 time_stamp, u64 local_tsf)
{
u64 tsf_offset = 0;
u8 data[8];
@@ -548,8 +546,9 @@ void vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate,
data[7] = (u8)(tsf_offset >> 56);
vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
- MESSAGE_REQUEST_TSF, 0, 8, data);
+ MESSAGE_REQUEST_TSF, 0, 8, data);
}
+
/*
* Description: Read NIC TSF counter
* Get local TSF counter
@@ -565,7 +564,6 @@ void vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate,
*/
bool vnt_get_current_tsf(struct vnt_private *priv, u64 *current_tsf)
{
-
*current_tsf = priv->current_tsf;
return true;
@@ -584,7 +582,6 @@ bool vnt_get_current_tsf(struct vnt_private *priv, u64 *current_tsf)
*/
bool vnt_clear_current_tsf(struct vnt_private *priv)
{
-
vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
priv->current_tsf = 0;
@@ -657,7 +654,7 @@ void vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval)
data[7] = (u8)(next_tbtt >> 56);
vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
- MESSAGE_REQUEST_TBTT, 0, 8, data);
+ MESSAGE_REQUEST_TBTT, 0, 8, data);
}
/*
@@ -676,7 +673,7 @@ void vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval)
*
*/
void vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf,
- u16 beacon_interval)
+ u16 beacon_interval)
{
u8 data[8];
@@ -721,7 +718,7 @@ int vnt_radio_power_off(struct vnt_private *priv)
case RF_VT3226D0:
case RF_VT3342A0:
vnt_mac_reg_bits_off(priv, MAC_REG_SOFTPWRCTL,
- (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
+ (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
break;
}
@@ -762,7 +759,7 @@ int vnt_radio_power_on(struct vnt_private *priv)
case RF_VT3226D0:
case RF_VT3342A0:
vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL,
- (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
+ (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
break;
}
@@ -795,7 +792,7 @@ void vnt_set_bss_mode(struct vnt_private *priv)
priv->bb_vga[0] = 0x20;
vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG,
- 0xe7, priv->bb_vga[0]);
+ 0xe7, priv->bb_vga[0]);
}
priv->bb_vga[2] = 0x10;
@@ -805,7 +802,7 @@ void vnt_set_bss_mode(struct vnt_private *priv)
priv->bb_vga[0] = 0x1c;
vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG,
- 0xe7, priv->bb_vga[0]);
+ 0xe7, priv->bb_vga[0]);
}
priv->bb_vga[2] = 0x0;
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c
index 6019aac8bdd5..655f0002f880 100644
--- a/drivers/staging/vt6656/dpc.c
+++ b/drivers/staging/vt6656/dpc.c
@@ -34,7 +34,7 @@
#include "rf.h"
int vnt_rx_data(struct vnt_private *priv, struct vnt_rcb *ptr_rcb,
- unsigned long bytes_received)
+ unsigned long bytes_received)
{
struct ieee80211_hw *hw = priv->hw;
struct ieee80211_supported_band *sband;
@@ -46,7 +46,7 @@ int vnt_rx_data(struct vnt_private *priv, struct vnt_rcb *ptr_rcb,
__le64 *tsf_time;
u32 frame_size;
int ii, r;
- u8 *rx_sts, *rx_rate, *sq, *sq_3;
+ u8 *rx_rate, *sq, *sq_3;
u32 wbk_status;
u8 *skb_data;
u16 *pay_load_len;
@@ -75,22 +75,21 @@ int vnt_rx_data(struct vnt_private *priv, struct vnt_rcb *ptr_rcb,
skb_data = (u8 *)skb->data;
- rx_sts = skb_data+4;
- rx_rate = skb_data+5;
+ rx_rate = skb_data + 5;
/* real Frame Size = USBframe_size -4WbkStatus - 4RxStatus */
/* -8TSF - 4RSR - 4SQ3 - ?Padding */
/* if SQ3 the range is 24~27, if no SQ3 the range is 20~23 */
- pay_load_len = (u16 *) (skb_data + 6);
+ pay_load_len = (u16 *)(skb_data + 6);
/*Fix hardware bug => PLCP_Length error */
if (((bytes_received - (*pay_load_len)) > 27) ||
- ((bytes_received - (*pay_load_len)) < 24) ||
- (bytes_received < (*pay_load_len))) {
+ ((bytes_received - (*pay_load_len)) < 24) ||
+ (bytes_received < (*pay_load_len))) {
dev_dbg(&priv->usb->dev, "Wrong PLCP Length %x\n",
- *pay_load_len);
+ *pay_load_len);
return false;
}
diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h
index 5a92bd86cee2..ff1850c4a927 100644
--- a/drivers/staging/vt6656/dpc.h
+++ b/drivers/staging/vt6656/dpc.h
@@ -29,6 +29,6 @@
#include "device.h"
int vnt_rx_data(struct vnt_private *, struct vnt_rcb *,
- unsigned long bytes_received);
+ unsigned long bytes_received);
#endif /* __RXTX_H__ */
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index ac4fecb30d0e..0594828bdabf 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -440,10 +440,8 @@ static bool vnt_alloc_bufs(struct vnt_private *priv)
/* allocate URBs */
tx_context->urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!tx_context->urb) {
- dev_err(&priv->usb->dev, "alloc tx urb failed\n");
+ if (!tx_context->urb)
goto free_tx;
- }
tx_context->in_use = false;
}
@@ -462,10 +460,8 @@ static bool vnt_alloc_bufs(struct vnt_private *priv)
/* allocate URBs */
rcb->urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!rcb->urb) {
- dev_err(&priv->usb->dev, "Failed to alloc rx urb\n");
+ if (!rcb->urb)
goto free_rx_tx;
- }
rcb->skb = dev_alloc_skb(priv->rx_buf_sz);
if (!rcb->skb)
@@ -479,10 +475,8 @@ static bool vnt_alloc_bufs(struct vnt_private *priv)
}
priv->interrupt_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!priv->interrupt_urb) {
- dev_err(&priv->usb->dev, "Failed to alloc int urb\n");
+ if (!priv->interrupt_urb)
goto free_rx_tx;
- }
priv->int_buf.data_buf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
if (!priv->int_buf.data_buf) {
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
index f546553de66f..e9b6b21f7422 100644
--- a/drivers/staging/vt6656/usbpipe.c
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -28,8 +28,9 @@
* vnt_control_in_u8 - Read one byte from MEM/BB/MAC/EEPROM
*
* Revision History:
- * 04-05-2004 Jerry Chen: Initial release
- * 11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,ControlvMaskByte
+ * 04-05-2004 Jerry Chen: Initial release
+ * 11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,
+ * ControlvMaskByte
*
*/
diff --git a/drivers/staging/wilc1000/TODO b/drivers/staging/wilc1000/TODO
index ec93b2ee0b08..ae61b55f14fd 100644
--- a/drivers/staging/wilc1000/TODO
+++ b/drivers/staging/wilc1000/TODO
@@ -3,7 +3,6 @@ TODO:
- remove OS wrapper functions
- remove custom debug and tracing functions
- rework comments and function headers(also coding style)
-- replace all semaphores with mutexes or completions
- Move handling for each individual members of 'union message_body' out
into a separate 'struct work_struct' and completely remove the multiplexer
that is currently part of host_if_work(), allowing movement of the
diff --git a/drivers/staging/wilc1000/coreconfigurator.h b/drivers/staging/wilc1000/coreconfigurator.h
index 076e06ac0d66..cff16984167b 100644
--- a/drivers/staging/wilc1000/coreconfigurator.h
+++ b/drivers/staging/wilc1000/coreconfigurator.h
@@ -70,11 +70,11 @@ enum connect_status {
CONNECT_STS_FORCE_16_BIT = 0xFFFF
};
-typedef struct {
+struct tstrRSSI {
u8 u8Full;
u8 u8Index;
s8 as8RSSI[NUM_RSSI];
-} tstrRSSI;
+};
struct network_info {
s8 rssi;
@@ -93,7 +93,7 @@ struct network_info {
u8 *ies;
u16 ies_len;
void *join_params;
- tstrRSSI str_rssi;
+ struct tstrRSSI str_rssi;
u64 tsf_hi;
};
diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c
index 78f524fcd214..78f5613e9467 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -3279,7 +3279,6 @@ int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
int wilc_hif_set_cfg(struct wilc_vif *vif,
struct cfg_param_attr *cfg_param)
{
- int result = 0;
struct host_if_msg msg;
struct host_if_drv *hif_drv = vif->hif_drv;
@@ -3293,9 +3292,7 @@ int wilc_hif_set_cfg(struct wilc_vif *vif,
msg.body.cfg_info = *cfg_param;
msg.vif = vif;
- result = wilc_enqueue_cmd(&msg);
-
- return result;
+ return wilc_enqueue_cmd(&msg);
}
static void GetPeriodicRSSI(unsigned long arg)
@@ -3329,7 +3326,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
init_completion(&hif_wait_response);
- hif_drv = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL);
+ hif_drv = kzalloc(sizeof(*hif_drv), GFP_KERNEL);
if (!hif_drv) {
result = -ENOMEM;
goto _fail_;
@@ -3878,7 +3875,7 @@ static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo)
pu8IEs = ptstrNetworkInfo->ies;
u16IEsLen = ptstrNetworkInfo->ies_len;
- pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL);
+ pNewJoinBssParam = kzalloc(sizeof(*pNewJoinBssParam), GFP_KERNEL);
if (pNewJoinBssParam) {
pNewJoinBssParam->dtim_period = ptstrNetworkInfo->dtim_period;
pNewJoinBssParam->beacon_period = ptstrNetworkInfo->beacon_period;
diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c
index 32215110d597..6370a5efe343 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -21,7 +21,6 @@
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/mutex.h>
-#include <linux/semaphore.h>
#include <linux/completion.h>
static int dev_state_ev_handler(struct notifier_block *this,
diff --git a/drivers/staging/wilc1000/wilc_debugfs.c b/drivers/staging/wilc1000/wilc_debugfs.c
index fcbc95d19d8e..802bb1d5e207 100644
--- a/drivers/staging/wilc1000/wilc_debugfs.c
+++ b/drivers/staging/wilc1000/wilc_debugfs.c
@@ -29,7 +29,7 @@ static struct dentry *wilc_dir;
#define ERR BIT(3)
#define DBG_LEVEL_ALL (DEBUG | INFO | WRN | ERR)
-atomic_t WILC_DEBUG_LEVEL = ATOMIC_INIT(ERR);
+static atomic_t WILC_DEBUG_LEVEL = ATOMIC_INIT(ERR);
EXPORT_SYMBOL_GPL(WILC_DEBUG_LEVEL);
/*
@@ -102,35 +102,16 @@ static struct wilc_debugfs_info_t debugfs_info[] = {
static int __init wilc_debugfs_init(void)
{
int i;
-
- struct dentry *debugfs_files;
struct wilc_debugfs_info_t *info;
wilc_dir = debugfs_create_dir("wilc_wifi", NULL);
- if (wilc_dir == ERR_PTR(-ENODEV)) {
- /* it's not error. the debugfs is just not being enabled. */
- printk("ERR, kernel has built without debugfs support\n");
- return 0;
- }
-
- if (!wilc_dir) {
- printk("ERR, debugfs create dir\n");
- return -1;
- }
-
for (i = 0; i < ARRAY_SIZE(debugfs_info); i++) {
info = &debugfs_info[i];
- debugfs_files = debugfs_create_file(info->name,
- info->perm,
- wilc_dir,
- &info->data,
- &info->fops);
-
- if (!debugfs_files) {
- printk("ERR fail to create the debugfs file, %s\n", info->name);
- debugfs_remove_recursive(wilc_dir);
- return -1;
- }
+ debugfs_create_file(info->name,
+ info->perm,
+ wilc_dir,
+ &info->data,
+ &info->fops);
}
return 0;
}
diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c
index 22cf4b7857e5..f08cf6d9e1af 100644
--- a/drivers/staging/wilc1000/wilc_spi.c
+++ b/drivers/staging/wilc1000/wilc_spi.c
@@ -410,8 +410,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
if (len2 > ARRAY_SIZE(wb)) {
dev_err(&spi->dev, "spi buffer size too small (%d) (%zu)\n",
len2, ARRAY_SIZE(wb));
- result = N_FAIL;
- return result;
+ return N_FAIL;
}
/* zero spi write buffers. */
for (wix = len; wix < len2; wix++)
@@ -420,8 +419,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
if (wilc_spi_tx_rx(wilc, wb, rb, len2)) {
dev_err(&spi->dev, "Failed cmd write, bus error...\n");
- result = N_FAIL;
- return result;
+ return N_FAIL;
}
/**
@@ -442,8 +440,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
dev_err(&spi->dev,
"Failed cmd response, cmd (%02x), resp (%02x)\n",
cmd, rsp);
- result = N_FAIL;
- return result;
+ return N_FAIL;
}
/**
@@ -453,8 +450,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
if (rsp != 0x00) {
dev_err(&spi->dev, "Failed cmd state response state (%02x)\n",
rsp);
- result = N_FAIL;
- return result;
+ return N_FAIL;
}
if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)
@@ -481,8 +477,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
if (retry <= 0) {
dev_err(&spi->dev,
"Error, data read response (%02x)\n", rsp);
- result = N_RESET;
- return result;
+ return N_RESET;
}
if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) {
@@ -497,8 +492,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
} else {
dev_err(&spi->dev,
"buffer overrun when reading data.\n");
- result = N_FAIL;
- return result;
+ return N_FAIL;
}
if (!g_spi.crc_off) {
@@ -510,8 +504,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
crc[1] = rb[rix++];
} else {
dev_err(&spi->dev, "buffer overrun when reading crc.\n");
- result = N_FAIL;
- return result;
+ return N_FAIL;
}
}
} else if ((cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) {
@@ -551,7 +544,6 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
}
}
-
ix += nbytes;
sz -= nbytes;
}
@@ -587,7 +579,6 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz,
if (result == N_FAIL)
break;
-
/**
* Read bytes
**/
@@ -687,7 +678,6 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz)
sz -= nbytes;
} while (sz);
-
return result;
}
@@ -850,7 +840,6 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
static int isinit;
if (isinit) {
-
if (!wilc_spi_read_reg(wilc, 0x1000, &chipid)) {
dev_err(&spi->dev, "Fail cmd read chip id...\n");
return 0;
@@ -871,7 +860,7 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
/* Read failed. Try with CRC off. This might happen when module
* is removed but chip isn't reset*/
g_spi.crc_off = 1;
- dev_err(&spi->dev, "Failed internal read protocol with CRC on, retyring with CRC off...\n");
+ dev_err(&spi->dev, "Failed internal read protocol with CRC on, retrying with CRC off...\n");
if (!spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, &reg)) {
/* Reaad failed with both CRC on and off, something went bad */
dev_err(&spi->dev,
@@ -890,7 +879,6 @@ static int wilc_spi_init(struct wilc *wilc, bool resume)
g_spi.crc_off = 1;
}
-
/**
* make sure can read back chip id correctly
**/
@@ -931,14 +919,10 @@ static int wilc_spi_read_size(struct wilc *wilc, u32 *size)
*size = tmp;
}
-
-
_fail_:
return ret;
}
-
-
static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
{
struct spi_device *spi = to_spi_device(wilc->dev);
@@ -993,7 +977,6 @@ static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status)
}
*int_status = tmp;
-
}
_fail_:
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index 2c2e8aca8305..60d8b055bb2f 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -2200,7 +2200,7 @@ static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
return ret;
}
-static struct cfg80211_ops wilc_cfg80211_ops = {
+static const struct cfg80211_ops wilc_cfg80211_ops = {
.set_monitor_channel = set_channel,
.scan = scan,
.connect = connect,
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index 5cc6a82d8081..ec6b1674cf38 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -131,7 +131,7 @@ struct wilc_priv {
struct wilc_wfi_key *wilc_gtk[MAX_NUM_STA];
struct wilc_wfi_key *wilc_ptk[MAX_NUM_STA];
u8 wilc_groupkey;
- /* semaphores */
+ /* mutexes */
struct mutex scan_req_lock;
/* */
bool gbAutoRateAdjusted;
diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c
index 19a580939dfc..bc5ad20af0a3 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -621,9 +621,9 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
if (!ret)
break;
- if ((reg & 0x1) == 0) {
+ if ((reg & 0x1) == 0)
break;
- }
+
counter++;
if (counter > 200) {
counter = 0;
@@ -1001,8 +1001,7 @@ int wilc_wlan_start(struct wilc *wilc)
ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
if (!ret) {
release_bus(wilc, RELEASE_ONLY);
- ret = -EIO;
- return ret;
+ return -EIO;
}
reg = 0;
if (wilc->io_type == HIF_SDIO && wilc->dev_irq_num)
@@ -1034,8 +1033,7 @@ int wilc_wlan_start(struct wilc *wilc)
ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
if (!ret) {
release_bus(wilc, RELEASE_ONLY);
- ret = -EIO;
- return ret;
+ return -EIO;
}
wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT);
@@ -1043,8 +1041,7 @@ int wilc_wlan_start(struct wilc *wilc)
ret = wilc->hif_func->hif_read_reg(wilc, 0x1000, &chipid);
if (!ret) {
release_bus(wilc, RELEASE_ONLY);
- ret = -EIO;
- return ret;
+ return -EIO;
}
wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h
index 30e5312ee87e..de6c4ddbf45a 100644
--- a/drivers/staging/wilc1000/wilc_wlan.h
+++ b/drivers/staging/wilc1000/wilc_wlan.h
@@ -192,7 +192,7 @@
#define ENABLE_RX_VMM (SEL_VMM_TBL1 | EN_VMM)
#define ENABLE_TX_VMM (SEL_VMM_TBL0 | EN_VMM)
-/*time for expiring the semaphores of cfg packets*/
+/*time for expiring the completion of cfg packets*/
#define CFG_PKTS_TIMEOUT 2000
/********************************************
*
diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h
index 410bfc034319..439ac6f8d533 100644
--- a/drivers/staging/wilc1000/wilc_wlan_if.h
+++ b/drivers/staging/wilc1000/wilc_wlan_if.h
@@ -10,7 +10,6 @@
#ifndef WILC_WLAN_IF_H
#define WILC_WLAN_IF_H
-#include <linux/semaphore.h>
#include <linux/netdevice.h>
/********************************************
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c
index f46dfe6b24e8..182b2d564627 100644
--- a/drivers/staging/wlan-ng/cfg80211.c
+++ b/drivers/staging/wlan-ng/cfg80211.c
@@ -35,7 +35,7 @@ static const u32 prism2_cipher_suites[PRISM2_NUM_CIPHER_SUITES] = {
/* prism2 device private data */
struct prism2_wiphy_private {
- wlandevice_t *wlandev;
+ struct wlandevice *wlandev;
struct ieee80211_supported_band band;
struct ieee80211_channel channels[ARRAY_SIZE(prism2_channels)];
@@ -69,11 +69,11 @@ static int prism2_result2err(int prism2_result)
return err;
}
-static int prism2_domibset_uint32(wlandevice_t *wlandev, u32 did, u32 data)
+static int prism2_domibset_uint32(struct wlandevice *wlandev, u32 did, u32 data)
{
struct p80211msg_dot11req_mibset msg;
- p80211item_uint32_t *mibitem =
- (p80211item_uint32_t *)&msg.mibattribute.data;
+ struct p80211item_uint32 *mibitem =
+ (struct p80211item_uint32 *)&msg.mibattribute.data;
msg.msgcode = DIDmsg_dot11req_mibset;
mibitem->did = did;
@@ -82,12 +82,12 @@ static int prism2_domibset_uint32(wlandevice_t *wlandev, u32 did, u32 data)
return p80211req_dorequest(wlandev, (u8 *)&msg);
}
-static int prism2_domibset_pstr32(wlandevice_t *wlandev,
+static int prism2_domibset_pstr32(struct wlandevice *wlandev,
u32 did, u8 len, const u8 *data)
{
struct p80211msg_dot11req_mibset msg;
- p80211item_pstr32_t *mibitem =
- (p80211item_pstr32_t *)&msg.mibattribute.data;
+ struct p80211item_pstr32 *mibitem =
+ (struct p80211item_pstr32 *)&msg.mibattribute.data;
msg.msgcode = DIDmsg_dot11req_mibset;
mibitem->did = did;
@@ -103,7 +103,7 @@ static int prism2_change_virtual_intf(struct wiphy *wiphy,
enum nl80211_iftype type, u32 *flags,
struct vif_params *params)
{
- wlandevice_t *wlandev = dev->ml_priv;
+ struct wlandevice *wlandev = dev->ml_priv;
u32 data;
int result;
int err = 0;
@@ -144,12 +144,15 @@ static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_index, bool pairwise, const u8 *mac_addr,
struct key_params *params)
{
- wlandevice_t *wlandev = dev->ml_priv;
+ struct wlandevice *wlandev = dev->ml_priv;
u32 did;
int err = 0;
int result = 0;
+ if (key_index >= NUM_WEPKEYS)
+ return -EINVAL;
+
switch (params->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
@@ -160,27 +163,7 @@ static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
goto exit;
/* send key to driver */
- switch (key_index) {
- case 0:
- did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
- break;
-
- case 1:
- did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
- break;
-
- case 2:
- did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
- break;
-
- case 3:
- did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
- break;
-
- default:
- err = -EINVAL;
- goto exit;
- }
+ did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(key_index + 1);
result = prism2_domibset_pstr32(wlandev, did,
params->key_len, params->key);
@@ -205,7 +188,7 @@ static int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
const u8 *mac_addr, void *cookie,
void (*callback)(void *cookie, struct key_params*))
{
- wlandevice_t *wlandev = dev->ml_priv;
+ struct wlandevice *wlandev = dev->ml_priv;
struct key_params params;
int len;
@@ -233,7 +216,7 @@ static int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
static int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_index, bool pairwise, const u8 *mac_addr)
{
- wlandevice_t *wlandev = dev->ml_priv;
+ struct wlandevice *wlandev = dev->ml_priv;
u32 did;
int err = 0;
int result = 0;
@@ -242,36 +225,13 @@ static int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
* a key, so we will cheat by setting the key to a bogus value
*/
- /* send key to driver */
- switch (key_index) {
- case 0:
- did =
- DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
- break;
-
- case 1:
- did =
- DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
- break;
-
- case 2:
- did =
- DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
- break;
-
- case 3:
- did =
- DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
- break;
-
- default:
- err = -EINVAL;
- goto exit;
- }
+ if (key_index >= NUM_WEPKEYS)
+ return -EINVAL;
+ /* send key to driver */
+ did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(key_index + 1);
result = prism2_domibset_pstr32(wlandev, did, 13, "0000000000000");
-exit:
if (result)
err = -EFAULT;
@@ -281,7 +241,7 @@ exit:
static int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_index, bool unicast, bool multicast)
{
- wlandevice_t *wlandev = dev->ml_priv;
+ struct wlandevice *wlandev = dev->ml_priv;
int err = 0;
int result = 0;
@@ -299,13 +259,13 @@ static int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
static int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
const u8 *mac, struct station_info *sinfo)
{
- wlandevice_t *wlandev = dev->ml_priv;
+ struct wlandevice *wlandev = dev->ml_priv;
struct p80211msg_lnxreq_commsquality quality;
int result;
memset(sinfo, 0, sizeof(*sinfo));
- if ((wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING))
+ if (!wlandev || (wlandev->msdstate != WLAN_MSD_RUNNING))
return -EOPNOTSUPP;
/* build request message */
@@ -314,7 +274,7 @@ static int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
/* send message to nsd */
- if (wlandev->mlmerequest == NULL)
+ if (!wlandev->mlmerequest)
return -EOPNOTSUPP;
result = wlandev->mlmerequest(wlandev, (struct p80211msg *)&quality);
@@ -334,7 +294,7 @@ static int prism2_scan(struct wiphy *wiphy,
{
struct net_device *dev;
struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
- wlandevice_t *wlandev;
+ struct wlandevice *wlandev;
struct p80211msg_dot11req_scan msg1;
struct p80211msg_dot11req_scan_results msg2;
struct cfg80211_bss *bss;
@@ -374,7 +334,7 @@ static int prism2_scan(struct wiphy *wiphy,
msg1.scantype.data = P80211ENUM_scantype_active;
msg1.ssid.data.len = request->ssids->ssid_len;
memcpy(msg1.ssid.data.data,
- request->ssids->ssid, request->ssids->ssid_len);
+ request->ssids->ssid, request->ssids->ssid_len);
} else {
msg1.scantype.data = 0;
}
@@ -451,7 +411,7 @@ exit:
static int prism2_set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
- wlandevice_t *wlandev = priv->wlandev;
+ struct wlandevice *wlandev = priv->wlandev;
u32 data;
int result;
int err = 0;
@@ -493,7 +453,7 @@ exit:
static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme)
{
- wlandevice_t *wlandev = dev->ml_priv;
+ struct wlandevice *wlandev = dev->ml_priv;
struct ieee80211_channel *channel = sme->channel;
struct p80211msg_lnxreq_autojoin msg_join;
u32 did;
@@ -516,11 +476,11 @@ static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
/* Set the authorization */
if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) ||
- ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep))
- msg_join.authtype.data = P80211ENUM_authalg_opensystem;
+ ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep))
+ msg_join.authtype.data = P80211ENUM_authalg_opensystem;
else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ||
- ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
- msg_join.authtype.data = P80211ENUM_authalg_sharedkey;
+ ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
+ msg_join.authtype.data = P80211ENUM_authalg_sharedkey;
else
netdev_warn(dev,
"Unhandled authorisation type for connect (%d)\n",
@@ -529,6 +489,11 @@ static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
/* Set the encryption - we only support wep */
if (is_wep) {
if (sme->key) {
+ if (sme->key_idx >= NUM_WEPKEYS) {
+ err = -EINVAL;
+ goto exit;
+ }
+
result = prism2_domibset_uint32(wlandev,
DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
sme->key_idx);
@@ -536,28 +501,8 @@ static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
goto exit;
/* send key to driver */
- switch (sme->key_idx) {
- case 0:
- did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
- break;
-
- case 1:
- did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
- break;
-
- case 2:
- did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
- break;
-
- case 3:
- did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
- break;
-
- default:
- err = -EINVAL;
- goto exit;
- }
-
+ did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(
+ sme->key_idx + 1);
result = prism2_domibset_pstr32(wlandev,
did, sme->key_len,
(u8 *)sme->key);
@@ -618,7 +563,7 @@ exit:
static int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev,
u16 reason_code)
{
- wlandevice_t *wlandev = dev->ml_priv;
+ struct wlandevice *wlandev = dev->ml_priv;
struct p80211msg_lnxreq_autojoin msg_join;
int result;
int err = 0;
@@ -652,7 +597,7 @@ static int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
enum nl80211_tx_power_setting type, int mbm)
{
struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
- wlandevice_t *wlandev = priv->wlandev;
+ struct wlandevice *wlandev = priv->wlandev;
u32 data;
int result;
int err = 0;
@@ -679,13 +624,13 @@ static int prism2_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
int *dbm)
{
struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
- wlandevice_t *wlandev = priv->wlandev;
+ struct wlandevice *wlandev = priv->wlandev;
struct p80211msg_dot11req_mibget msg;
- p80211item_uint32_t *mibitem;
+ struct p80211item_uint32 *mibitem;
int result;
int err = 0;
- mibitem = (p80211item_uint32_t *)&msg.mibattribute.data;
+ mibitem = (struct p80211item_uint32 *)&msg.mibattribute.data;
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem->did =
DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
@@ -704,7 +649,7 @@ exit:
}
/* Interface callback functions, passing data back up to the cfg80211 layer */
-void prism2_connect_result(wlandevice_t *wlandev, u8 failed)
+void prism2_connect_result(struct wlandevice *wlandev, u8 failed)
{
u16 status = failed ?
WLAN_STATUS_UNSPECIFIED_FAILURE : WLAN_STATUS_SUCCESS;
@@ -713,13 +658,13 @@ void prism2_connect_result(wlandevice_t *wlandev, u8 failed)
NULL, 0, NULL, 0, status, GFP_KERNEL);
}
-void prism2_disconnected(wlandevice_t *wlandev)
+void prism2_disconnected(struct wlandevice *wlandev)
{
cfg80211_disconnected(wlandev->netdev, 0, NULL,
- 0, false, GFP_KERNEL);
+ 0, false, GFP_KERNEL);
}
-void prism2_roamed(wlandevice_t *wlandev)
+void prism2_roamed(struct wlandevice *wlandev)
{
cfg80211_roamed(wlandev->netdev, NULL, wlandev->bssid,
NULL, 0, NULL, 0, GFP_KERNEL);
@@ -744,7 +689,7 @@ static const struct cfg80211_ops prism2_usb_cfg_ops = {
};
/* Functions to create/free wiphy interface */
-static struct wiphy *wlan_create_wiphy(struct device *dev, wlandevice_t *wlandev)
+static struct wiphy *wlan_create_wiphy(struct device *dev, struct wlandevice *wlandev)
{
struct wiphy *wiphy;
struct prism2_wiphy_private *priv;
diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h
index cec6d0ba3b65..43c299c3b631 100644
--- a/drivers/staging/wlan-ng/hfa384x.h
+++ b/drivers/staging/wlan-ng/hfa384x.h
@@ -1,57 +1,57 @@
/* hfa384x.h
-*
-* Defines the constants and data structures for the hfa384x
-*
-* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
-* --------------------------------------------------------------------
-*
-* linux-wlan
-*
-* The contents of this file are subject to the Mozilla Public
-* License Version 1.1 (the "License"); you may not use this file
-* except in compliance with the License. You may obtain a copy of
-* the License at http://www.mozilla.org/MPL/
-*
-* Software distributed under the License is distributed on an "AS
-* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-* implied. See the License for the specific language governing
-* rights and limitations under the License.
-*
-* Alternatively, the contents of this file may be used under the
-* terms of the GNU Public License version 2 (the "GPL"), in which
-* case the provisions of the GPL are applicable instead of the
-* above. If you wish to allow the use of your version of this file
-* only under the terms of the GPL and not to allow others to use
-* your version of this file under the MPL, indicate your decision
-* by deleting the provisions above and replace them with the notice
-* and other provisions required by the GPL. If you do not delete
-* the provisions above, a recipient may use your version of this
-* file under either the MPL or the GPL.
-*
-* --------------------------------------------------------------------
-*
-* Inquiries regarding the linux-wlan Open Source project can be
-* made directly to:
-*
-* AbsoluteValue Systems Inc.
-* info@linux-wlan.com
-* http://www.linux-wlan.com
-*
-* --------------------------------------------------------------------
-*
-* Portions of the development of this software were funded by
-* Intersil Corporation as part of PRISM(R) chipset product development.
-*
-* --------------------------------------------------------------------
-*
-* [Implementation and usage notes]
-*
-* [References]
-* CW10 Programmer's Manual v1.5
-* IEEE 802.11 D10.0
-*
-* --------------------------------------------------------------------
-*/
+ *
+ * Defines the constants and data structures for the hfa384x
+ *
+ * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+ * --------------------------------------------------------------------
+ *
+ * linux-wlan
+ *
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU Public License version 2 (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of the
+ * above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use
+ * your version of this file under the MPL, indicate your decision
+ * by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete
+ * the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * --------------------------------------------------------------------
+ *
+ * Inquiries regarding the linux-wlan Open Source project can be
+ * made directly to:
+ *
+ * AbsoluteValue Systems Inc.
+ * info@linux-wlan.com
+ * http://www.linux-wlan.com
+ *
+ * --------------------------------------------------------------------
+ *
+ * Portions of the development of this software were funded by
+ * Intersil Corporation as part of PRISM(R) chipset product development.
+ *
+ * --------------------------------------------------------------------
+ *
+ * [Implementation and usage notes]
+ *
+ * [References]
+ * CW10 Programmer's Manual v1.5
+ * IEEE 802.11 D10.0
+ *
+ * --------------------------------------------------------------------
+ */
#ifndef _HFA384x_H
#define _HFA384x_H
@@ -63,7 +63,7 @@
/*--- Mins & Maxs -----------------------------------*/
#define HFA384x_PORTID_MAX ((u16)7)
-#define HFA384x_NUMPORTS_MAX ((u16)(HFA384x_PORTID_MAX+1))
+#define HFA384x_NUMPORTS_MAX ((u16)(HFA384x_PORTID_MAX + 1))
#define HFA384x_PDR_LEN_MAX ((u16)512) /* in bytes, from EK */
#define HFA384x_PDA_RECS_MAX ((u16)200) /* a guess */
#define HFA384x_PDA_LEN_MAX ((u16)1024) /* in bytes, from EK*/
@@ -110,20 +110,21 @@
#define HFA384x_ADDR_FLAT_CMD_OFF_MASK (0x0000ffff)
/* Mask bits for discarding unwanted pieces in AUX format
- 16-bit address parts */
+ * 16-bit address parts
+ */
#define HFA384x_ADDR_AUX_PAGE_MASK (0xffff)
#define HFA384x_ADDR_AUX_OFF_MASK (0x007f)
/* Make a 32-bit flat address from AUX format 16-bit page and offset */
#define HFA384x_ADDR_AUX_MKFLAT(p, o) \
- ((((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \
- ((u32)(((u16)(o))&HFA384x_ADDR_AUX_OFF_MASK)))
+ ((((u32)(((u16)(p)) & HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \
+ ((u32)(((u16)(o)) & HFA384x_ADDR_AUX_OFF_MASK)))
/* Make CMD format offset and page from a 32-bit flat address */
#define HFA384x_ADDR_CMD_MKPAGE(f) \
- ((u16)((((u32)(f))&HFA384x_ADDR_FLAT_CMD_PAGE_MASK)>>16))
+ ((u16)((((u32)(f)) & HFA384x_ADDR_FLAT_CMD_PAGE_MASK) >> 16))
#define HFA384x_ADDR_CMD_MKOFF(f) \
- ((u16)(((u32)(f))&HFA384x_ADDR_FLAT_CMD_OFF_MASK))
+ ((u16)(((u32)(f)) & HFA384x_ADDR_FLAT_CMD_OFF_MASK))
/*--- Controller Memory addresses -------------------*/
#define HFA3842_PDA_BASE (0x007f0000UL)
@@ -173,11 +174,12 @@
#define HFA384x_CMD_ERR ((u16)(0x7F))
/*--- Programming Modes --------------------------
- MODE 0: Disable programming
- MODE 1: Enable volatile memory programming
- MODE 2: Enable non-volatile memory programming
- MODE 3: Program non-volatile memory section
---------------------------------------------------*/
+ * MODE 0: Disable programming
+ * MODE 1: Enable volatile memory programming
+ * MODE 2: Enable non-volatile memory programming
+ * MODE 3: Program non-volatile memory section
+ *-------------------------------------------------
+ */
#define HFA384x_PROGMODE_DISABLE ((u16)0x00)
#define HFA384x_PROGMODE_RAM ((u16)0x01)
#define HFA384x_PROGMODE_NV ((u16)0x02)
@@ -185,8 +187,9 @@
/*--- Record ID Constants --------------------------*/
/*--------------------------------------------------------------------
-Configuration RIDs: Network Parameters, Static Configuration Entities
---------------------------------------------------------------------*/
+ * Configuration RIDs: Network Parameters, Static Configuration Entities
+ *--------------------------------------------------------------------
+ */
#define HFA384x_RID_CNFPORTTYPE ((u16)0xFC00)
#define HFA384x_RID_CNFOWNMACADDR ((u16)0xFC01)
#define HFA384x_RID_CNFDESIREDSSID ((u16)0xFC02)
@@ -195,17 +198,19 @@ Configuration RIDs: Network Parameters, Static Configuration Entities
#define HFA384x_RID_CNFMAXDATALEN ((u16)0xFC07)
/*--------------------------------------------------------------------
-Configuration RID lengths: Network Params, Static Config Entities
- This is the length of JUST the DATA part of the RID (does not
- include the len or code fields)
---------------------------------------------------------------------*/
+ * Configuration RID lengths: Network Params, Static Config Entities
+ * This is the length of JUST the DATA part of the RID (does not
+ * include the len or code fields)
+ *--------------------------------------------------------------------
+ */
#define HFA384x_RID_CNFOWNMACADDR_LEN ((u16)6)
#define HFA384x_RID_CNFDESIREDSSID_LEN ((u16)34)
#define HFA384x_RID_CNFOWNSSID_LEN ((u16)34)
/*--------------------------------------------------------------------
-Configuration RIDs: Network Parameters, Dynamic Configuration Entities
---------------------------------------------------------------------*/
+ * Configuration RIDs: Network Parameters, Dynamic Configuration Entities
+ *--------------------------------------------------------------------
+ */
#define HFA384x_RID_CREATEIBSS ((u16)0xFC81)
#define HFA384x_RID_FRAGTHRESH ((u16)0xFC82)
#define HFA384x_RID_RTSTHRESH ((u16)0xFC83)
@@ -213,8 +218,9 @@ Configuration RIDs: Network Parameters, Dynamic Configuration Entities
#define HFA384x_RID_PROMISCMODE ((u16)0xFC85)
/*----------------------------------------------------------------------
-Information RIDs: NIC Information
---------------------------------------------------------------------*/
+ * Information RIDs: NIC Information
+ *----------------------------------------------------------------------
+ */
#define HFA384x_RID_MAXLOADTIME ((u16)0xFD00)
#define HFA384x_RID_DOWNLOADBUFFER ((u16)0xFD01)
#define HFA384x_RID_PRIIDENTITY ((u16)0xFD02)
@@ -230,15 +236,17 @@ Information RIDs: NIC Information
#define HFA384x_RID_STA_CFIACTRANGES ((u16)0xFD23)
/*----------------------------------------------------------------------
-Information RID Lengths: NIC Information
- This is the length of JUST the DATA part of the RID (does not
- include the len or code fields)
---------------------------------------------------------------------*/
+ * Information RID Lengths: NIC Information
+ * This is the length of JUST the DATA part of the RID (does not
+ * include the len or code fields)
+ *---------------------------------------------------------------------
+ */
#define HFA384x_RID_NICSERIALNUMBER_LEN ((u16)12)
/*--------------------------------------------------------------------
-Information RIDs: MAC Information
---------------------------------------------------------------------*/
+ * Information RIDs: MAC Information
+ *--------------------------------------------------------------------
+ */
#define HFA384x_RID_PORTSTATUS ((u16)0xFD40)
#define HFA384x_RID_CURRENTSSID ((u16)0xFD41)
#define HFA384x_RID_CURRENTBSSID ((u16)0xFD42)
@@ -250,23 +258,26 @@ Information RIDs: MAC Information
#define HFA384x_RID_DBMCOMMSQUALITY ((u16)0xFD51)
/*--------------------------------------------------------------------
-Information RID Lengths: MAC Information
- This is the length of JUST the DATA part of the RID (does not
- include the len or code fields)
---------------------------------------------------------------------*/
+ * Information RID Lengths: MAC Information
+ * This is the length of JUST the DATA part of the RID (does not
+ * include the len or code fields)
+ *--------------------------------------------------------------------
+ */
#define HFA384x_RID_DBMCOMMSQUALITY_LEN \
- ((u16) sizeof(hfa384x_dbmcommsquality_t))
+ ((u16)sizeof(struct hfa384x_dbmcommsquality))
#define HFA384x_RID_JOINREQUEST_LEN \
- ((u16)sizeof(hfa384x_JoinRequest_data_t))
+ ((u16)sizeof(struct hfa384x_JoinRequest_data))
/*--------------------------------------------------------------------
-Information RIDs: Modem Information
---------------------------------------------------------------------*/
+ * Information RIDs: Modem Information
+ *--------------------------------------------------------------------
+ */
#define HFA384x_RID_CURRENTCHANNEL ((u16)0xFDC1)
/*--------------------------------------------------------------------
-API ENHANCEMENTS (NOT ALREADY IMPLEMENTED)
---------------------------------------------------------------------*/
+ * API ENHANCEMENTS (NOT ALREADY IMPLEMENTED)
+ *--------------------------------------------------------------------
+ */
#define HFA384x_RID_CNFWEPDEFAULTKEYID ((u16)0xFC23)
#define HFA384x_RID_CNFWEPDEFAULTKEY0 ((u16)0xFC24)
#define HFA384x_RID_CNFWEPDEFAULTKEY1 ((u16)0xFC25)
@@ -290,8 +301,9 @@ API ENHANCEMENTS (NOT ALREADY IMPLEMENTED)
#define HFA384x_RID_CNFWEP128DEFAULTKEY_LEN ((u16)14)
/*--------------------------------------------------------------------
-PD Record codes
---------------------------------------------------------------------*/
+ * PD Record codes
+ *--------------------------------------------------------------------
+ */
#define HFA384x_PDR_PCB_PARTNUM ((u16)0x0001)
#define HFA384x_PDR_PDAVER ((u16)0x0002)
#define HFA384x_PDR_NIC_SERIAL ((u16)0x0003)
@@ -355,31 +367,32 @@ struct hfa384x_bytestr {
u8 data[0];
} __packed;
-typedef struct hfa384x_bytestr32 {
+struct hfa384x_bytestr32 {
u16 len;
u8 data[32];
-} __packed hfa384x_bytestr32_t;
+} __packed;
/*--------------------------------------------------------------------
-Configuration Record Structures:
- Network Parameters, Static Configuration Entities
---------------------------------------------------------------------*/
+ * Configuration Record Structures:
+ * Network Parameters, Static Configuration Entities
+ *--------------------------------------------------------------------
+ */
/*-- Hardware/Firmware Component Information ----------*/
-typedef struct hfa384x_compident {
+struct hfa384x_compident {
u16 id;
u16 variant;
u16 major;
u16 minor;
-} __packed hfa384x_compident_t;
+} __packed;
-typedef struct hfa384x_caplevel {
+struct hfa384x_caplevel {
u16 role;
u16 id;
u16 variant;
u16 bottom;
u16 top;
-} __packed hfa384x_caplevel_t;
+} __packed;
/*-- Configuration Record: cnfAuthentication --*/
#define HFA384x_CNFAUTHENTICATION_OPENSYSTEM 0x0001
@@ -387,77 +400,81 @@ typedef struct hfa384x_caplevel {
#define HFA384x_CNFAUTHENTICATION_LEAP 0x0004
/*--------------------------------------------------------------------
-Configuration Record Structures:
- Network Parameters, Dynamic Configuration Entities
---------------------------------------------------------------------*/
+ * Configuration Record Structures:
+ * Network Parameters, Dynamic Configuration Entities
+ *--------------------------------------------------------------------
+ */
#define HFA384x_CREATEIBSS_JOINCREATEIBSS 0
/*-- Configuration Record: HostScanRequest (data portion only) --*/
-typedef struct hfa384x_HostScanRequest_data {
+struct hfa384x_HostScanRequest_data {
u16 channelList;
u16 txRate;
- hfa384x_bytestr32_t ssid;
-} __packed hfa384x_HostScanRequest_data_t;
+ struct hfa384x_bytestr32 ssid;
+} __packed;
/*-- Configuration Record: JoinRequest (data portion only) --*/
-typedef struct hfa384x_JoinRequest_data {
+struct hfa384x_JoinRequest_data {
u8 bssid[WLAN_BSSID_LEN];
u16 channel;
-} __packed hfa384x_JoinRequest_data_t;
+} __packed;
/*-- Configuration Record: authenticateStation (data portion only) --*/
-typedef struct hfa384x_authenticateStation_data {
+struct hfa384x_authenticateStation_data {
u8 address[ETH_ALEN];
u16 status;
u16 algorithm;
-} __packed hfa384x_authenticateStation_data_t;
+} __packed;
/*-- Configuration Record: WPAData (data portion only) --*/
-typedef struct hfa384x_WPAData {
+struct hfa384x_WPAData {
u16 datalen;
u8 data[0]; /* max 80 */
-} __packed hfa384x_WPAData_t;
+} __packed;
/*--------------------------------------------------------------------
-Information Record Structures: NIC Information
---------------------------------------------------------------------*/
+ * Information Record Structures: NIC Information
+ *--------------------------------------------------------------------
+ */
/*-- Information Record: DownLoadBuffer --*/
/* NOTE: The page and offset are in AUX format */
-typedef struct hfa384x_downloadbuffer {
+struct hfa384x_downloadbuffer {
u16 page;
u16 offset;
u16 len;
-} __packed hfa384x_downloadbuffer_t;
+} __packed;
/*--------------------------------------------------------------------
-Information Record Structures: NIC Information
---------------------------------------------------------------------*/
+ * Information Record Structures: NIC Information
+ *--------------------------------------------------------------------
+ */
#define HFA384x_PSTATUS_CONN_IBSS ((u16)3)
/*-- Information Record: commsquality --*/
-typedef struct hfa384x_commsquality {
+struct hfa384x_commsquality {
u16 CQ_currBSS;
u16 ASL_currBSS;
u16 ANL_currFC;
-} __packed hfa384x_commsquality_t;
+} __packed;
/*-- Information Record: dmbcommsquality --*/
-typedef struct hfa384x_dbmcommsquality {
+struct hfa384x_dbmcommsquality {
u16 CQdbm_currBSS;
u16 ASLdbm_currBSS;
u16 ANLdbm_currFC;
-} __packed hfa384x_dbmcommsquality_t;
+} __packed;
/*--------------------------------------------------------------------
-FRAME STRUCTURES: Communication Frames
-----------------------------------------------------------------------
-Communication Frames: Transmit Frames
---------------------------------------------------------------------*/
+ * FRAME STRUCTURES: Communication Frames
+ *--------------------------------------------------------------------
+ * Communication Frames: Transmit Frames
+ *--------------------------------------------------------------------
+ */
/*-- Communication Frame: Transmit Frame Structure --*/
-typedef struct hfa384x_tx_frame {
+struct hfa384x_tx_frame {
u16 status;
u16 reserved1;
u16 reserved2;
@@ -482,10 +499,11 @@ typedef struct hfa384x_tx_frame {
u8 dest_addr[6];
u8 src_addr[6];
u16 data_length; /* big endian format */
-} __packed hfa384x_tx_frame_t;
+} __packed;
/*--------------------------------------------------------------------
-Communication Frames: Field Masks for Transmit Frames
---------------------------------------------------------------------*/
+ * Communication Frames: Field Masks for Transmit Frames
+ *--------------------------------------------------------------------
+ */
/*-- Status Field --*/
#define HFA384x_TXSTATUS_ACKERR ((u16)BIT(5))
#define HFA384x_TXSTATUS_FORMERR ((u16)BIT(3))
@@ -499,16 +517,17 @@ Communication Frames: Field Masks for Transmit Frames
#define HFA384x_TX_TXEX ((u16)BIT(2))
#define HFA384x_TX_TXOK ((u16)BIT(1))
/*--------------------------------------------------------------------
-Communication Frames: Test/Get/Set Field Values for Transmit Frames
---------------------------------------------------------------------*/
+ * Communication Frames: Test/Get/Set Field Values for Transmit Frames
+ *--------------------------------------------------------------------
+ */
/*-- Status Field --*/
#define HFA384x_TXSTATUS_ISERROR(v) \
- (((u16)(v))&\
- (HFA384x_TXSTATUS_ACKERR|HFA384x_TXSTATUS_FORMERR|\
- HFA384x_TXSTATUS_DISCON|HFA384x_TXSTATUS_AGEDERR|\
+ (((u16)(v)) & \
+ (HFA384x_TXSTATUS_ACKERR | HFA384x_TXSTATUS_FORMERR | \
+ HFA384x_TXSTATUS_DISCON | HFA384x_TXSTATUS_AGEDERR | \
HFA384x_TXSTATUS_RETRYERR))
-#define HFA384x_TX_SET(v, m, s) ((((u16)(v))<<((u16)(s)))&((u16)(m)))
+#define HFA384x_TX_SET(v, m, s) ((((u16)(v)) << ((u16)(s))) & ((u16)(m)))
#define HFA384x_TX_MACPORT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_MACPORT, 8)
#define HFA384x_TX_STRUCTYPE_SET(v) HFA384x_TX_SET(v, \
@@ -516,10 +535,11 @@ Communication Frames: Test/Get/Set Field Values for Transmit Frames
#define HFA384x_TX_TXEX_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXEX, 2)
#define HFA384x_TX_TXOK_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXOK, 1)
/*--------------------------------------------------------------------
-Communication Frames: Receive Frames
---------------------------------------------------------------------*/
+ * Communication Frames: Receive Frames
+ *--------------------------------------------------------------------
+ */
/*-- Communication Frame: Receive Frame Structure --*/
-typedef struct hfa384x_rx_frame {
+struct hfa384x_rx_frame {
/*-- MAC rx descriptor (hfa384x byte order) --*/
u16 status;
u32 time;
@@ -544,10 +564,11 @@ typedef struct hfa384x_rx_frame {
u8 dest_addr[6];
u8 src_addr[6];
u16 data_length; /* IEEE? (big endian) format */
-} __packed hfa384x_rx_frame_t;
+} __packed;
/*--------------------------------------------------------------------
-Communication Frames: Field Masks for Receive Frames
---------------------------------------------------------------------*/
+ * Communication Frames: Field Masks for Receive Frames
+ *--------------------------------------------------------------------
+ */
/*-- Status Fields --*/
#define HFA384x_RXSTATUS_MACPORT ((u16)(BIT(10) | \
@@ -555,17 +576,19 @@ Communication Frames: Field Masks for Receive Frames
BIT(8)))
#define HFA384x_RXSTATUS_FCSERR ((u16)BIT(0))
/*--------------------------------------------------------------------
-Communication Frames: Test/Get/Set Field Values for Receive Frames
---------------------------------------------------------------------*/
+ * Communication Frames: Test/Get/Set Field Values for Receive Frames
+ *--------------------------------------------------------------------
+ */
#define HFA384x_RXSTATUS_MACPORT_GET(value) ((u16)((((u16)(value)) \
& HFA384x_RXSTATUS_MACPORT) >> 8))
#define HFA384x_RXSTATUS_ISFCSERR(value) ((u16)(((u16)(value)) \
& HFA384x_RXSTATUS_FCSERR))
/*--------------------------------------------------------------------
- FRAME STRUCTURES: Information Types and Information Frame Structures
-----------------------------------------------------------------------
-Information Types
---------------------------------------------------------------------*/
+ * FRAME STRUCTURES: Information Types and Information Frame Structures
+ *--------------------------------------------------------------------
+ * Information Types
+ *--------------------------------------------------------------------
+ */
#define HFA384x_IT_HANDOVERADDR ((u16)0xF000UL)
#define HFA384x_IT_COMMTALLIES ((u16)0xF100UL)
#define HFA384x_IT_SCANRESULTS ((u16)0xF101UL)
@@ -580,13 +603,14 @@ Information Types
#define HFA384x_IT_MICFAILURE ((u16)0xF206UL)
/*--------------------------------------------------------------------
-Information Frames Structures
-----------------------------------------------------------------------
-Information Frames: Notification Frame Structures
---------------------------------------------------------------------*/
+ * Information Frames Structures
+ *--------------------------------------------------------------------
+ * Information Frames: Notification Frame Structures
+ *--------------------------------------------------------------------
+ */
/*-- Inquiry Frame, Diagnose: Communication Tallies --*/
-typedef struct hfa384x_CommTallies16 {
+struct hfa384x_CommTallies16 {
u16 txunicastframes;
u16 txmulticastframes;
u16 txfragments;
@@ -608,9 +632,9 @@ typedef struct hfa384x_CommTallies16 {
u16 rxdiscardswepundecr;
u16 rxmsginmsgfrag;
u16 rxmsginbadmsgfrag;
-} __packed hfa384x_CommTallies16_t;
+} __packed;
-typedef struct hfa384x_CommTallies32 {
+struct hfa384x_CommTallies32 {
u32 txunicastframes;
u32 txmulticastframes;
u32 txfragments;
@@ -632,62 +656,62 @@ typedef struct hfa384x_CommTallies32 {
u32 rxdiscardswepundecr;
u32 rxmsginmsgfrag;
u32 rxmsginbadmsgfrag;
-} __packed hfa384x_CommTallies32_t;
+} __packed;
/*-- Inquiry Frame, Diagnose: Scan Results & Subfields--*/
-typedef struct hfa384x_ScanResultSub {
+struct hfa384x_ScanResultSub {
u16 chid;
u16 anl;
u16 sl;
u8 bssid[WLAN_BSSID_LEN];
u16 bcnint;
u16 capinfo;
- hfa384x_bytestr32_t ssid;
+ struct hfa384x_bytestr32 ssid;
u8 supprates[10]; /* 802.11 info element */
u16 proberesp_rate;
-} __packed hfa384x_ScanResultSub_t;
+} __packed;
-typedef struct hfa384x_ScanResult {
+struct hfa384x_ScanResult {
u16 rsvd;
u16 scanreason;
- hfa384x_ScanResultSub_t result[HFA384x_SCANRESULT_MAX];
-} __packed hfa384x_ScanResult_t;
+ struct hfa384x_ScanResultSub result[HFA384x_SCANRESULT_MAX];
+} __packed;
/*-- Inquiry Frame, Diagnose: ChInfo Results & Subfields--*/
-typedef struct hfa384x_ChInfoResultSub {
+struct hfa384x_ChInfoResultSub {
u16 chid;
u16 anl;
u16 pnl;
u16 active;
-} __packed hfa384x_ChInfoResultSub_t;
+} __packed;
#define HFA384x_CHINFORESULT_BSSACTIVE BIT(0)
#define HFA384x_CHINFORESULT_PCFACTIVE BIT(1)
-typedef struct hfa384x_ChInfoResult {
+struct hfa384x_ChInfoResult {
u16 scanchannels;
- hfa384x_ChInfoResultSub_t result[HFA384x_CHINFORESULT_MAX];
-} __packed hfa384x_ChInfoResult_t;
+ struct hfa384x_ChInfoResultSub result[HFA384x_CHINFORESULT_MAX];
+} __packed;
/*-- Inquiry Frame, Diagnose: Host Scan Results & Subfields--*/
-typedef struct hfa384x_HScanResultSub {
+struct hfa384x_HScanResultSub {
u16 chid;
u16 anl;
u16 sl;
u8 bssid[WLAN_BSSID_LEN];
u16 bcnint;
u16 capinfo;
- hfa384x_bytestr32_t ssid;
+ struct hfa384x_bytestr32 ssid;
u8 supprates[10]; /* 802.11 info element */
u16 proberesp_rate;
u16 atim;
-} __packed hfa384x_HScanResultSub_t;
+} __packed;
-typedef struct hfa384x_HScanResult {
+struct hfa384x_HScanResult {
u16 nresult;
u16 rsvd;
- hfa384x_HScanResultSub_t result[HFA384x_HSCANRESULT_MAX];
-} __packed hfa384x_HScanResult_t;
+ struct hfa384x_HScanResultSub result[HFA384x_HSCANRESULT_MAX];
+} __packed;
/*-- Unsolicited Frame, MAC Mgmt: LinkStatus --*/
@@ -699,9 +723,9 @@ typedef struct hfa384x_HScanResult {
#define HFA384x_LINK_AP_INRANGE ((u16)5)
#define HFA384x_LINK_ASSOCFAIL ((u16)6)
-typedef struct hfa384x_LinkStatus {
+struct hfa384x_LinkStatus {
u16 linkstatus;
-} __packed hfa384x_LinkStatus_t;
+} __packed;
/*-- Unsolicited Frame, MAC Mgmt: AssociationStatus (--*/
@@ -709,56 +733,57 @@ typedef struct hfa384x_LinkStatus {
#define HFA384x_ASSOCSTATUS_REASSOC ((u16)2)
#define HFA384x_ASSOCSTATUS_AUTHFAIL ((u16)5)
-typedef struct hfa384x_AssocStatus {
+struct hfa384x_AssocStatus {
u16 assocstatus;
u8 sta_addr[ETH_ALEN];
/* old_ap_addr is only valid if assocstatus == 2 */
u8 old_ap_addr[ETH_ALEN];
u16 reason;
u16 reserved;
-} __packed hfa384x_AssocStatus_t;
+} __packed;
/*-- Unsolicited Frame, MAC Mgmt: AuthRequest (AP Only) --*/
-typedef struct hfa384x_AuthRequest {
+struct hfa384x_AuthRequest {
u8 sta_addr[ETH_ALEN];
u16 algorithm;
-} __packed hfa384x_AuthReq_t;
+} __packed;
/*-- Unsolicited Frame, MAC Mgmt: PSUserCount (AP Only) --*/
-typedef struct hfa384x_PSUserCount {
+struct hfa384x_PSUserCount {
u16 usercnt;
-} __packed hfa384x_PSUserCount_t;
+} __packed;
-typedef struct hfa384x_KeyIDChanged {
+struct hfa384x_KeyIDChanged {
u8 sta_addr[ETH_ALEN];
u16 keyid;
-} __packed hfa384x_KeyIDChanged_t;
+} __packed;
/*-- Collection of all Inf frames ---------------*/
-typedef union hfa384x_infodata {
- hfa384x_CommTallies16_t commtallies16;
- hfa384x_CommTallies32_t commtallies32;
- hfa384x_ScanResult_t scanresult;
- hfa384x_ChInfoResult_t chinforesult;
- hfa384x_HScanResult_t hscanresult;
- hfa384x_LinkStatus_t linkstatus;
- hfa384x_AssocStatus_t assocstatus;
- hfa384x_AuthReq_t authreq;
- hfa384x_PSUserCount_t psusercnt;
- hfa384x_KeyIDChanged_t keyidchanged;
-} __packed hfa384x_infodata_t;
-
-typedef struct hfa384x_InfFrame {
+union hfa384x_infodata {
+ struct hfa384x_CommTallies16 commtallies16;
+ struct hfa384x_CommTallies32 commtallies32;
+ struct hfa384x_ScanResult scanresult;
+ struct hfa384x_ChInfoResult chinforesult;
+ struct hfa384x_HScanResult hscanresult;
+ struct hfa384x_LinkStatus linkstatus;
+ struct hfa384x_AssocStatus assocstatus;
+ struct hfa384x_AuthRequest authreq;
+ struct hfa384x_PSUserCount psusercnt;
+ struct hfa384x_KeyIDChanged keyidchanged;
+} __packed;
+
+struct hfa384x_InfFrame {
u16 framelen;
u16 infotype;
- hfa384x_infodata_t info;
-} __packed hfa384x_InfFrame_t;
+ union hfa384x_infodata info;
+} __packed;
/*--------------------------------------------------------------------
-USB Packet structures and constants.
---------------------------------------------------------------------*/
+ * USB Packet structures and constants.
+ *--------------------------------------------------------------------
+ */
/* Should be sent to the bulkout endpoint */
#define HFA384x_USB_TXFRM 0
@@ -783,143 +808,140 @@ USB Packet structures and constants.
/*------------------------------------*/
/* Request (bulk OUT) packet contents */
-typedef struct hfa384x_usb_txfrm {
- hfa384x_tx_frame_t desc;
+struct hfa384x_usb_txfrm {
+ struct hfa384x_tx_frame desc;
u8 data[WLAN_DATA_MAXLEN];
-} __packed hfa384x_usb_txfrm_t;
+} __packed;
-typedef struct hfa384x_usb_cmdreq {
+struct hfa384x_usb_cmdreq {
u16 type;
u16 cmd;
u16 parm0;
u16 parm1;
u16 parm2;
u8 pad[54];
-} __packed hfa384x_usb_cmdreq_t;
+} __packed;
-typedef struct hfa384x_usb_wridreq {
+struct hfa384x_usb_wridreq {
u16 type;
u16 frmlen;
u16 rid;
u8 data[HFA384x_RIDDATA_MAXLEN];
-} __packed hfa384x_usb_wridreq_t;
+} __packed;
-typedef struct hfa384x_usb_rridreq {
+struct hfa384x_usb_rridreq {
u16 type;
u16 frmlen;
u16 rid;
u8 pad[58];
-} __packed hfa384x_usb_rridreq_t;
+} __packed;
-typedef struct hfa384x_usb_wmemreq {
+struct hfa384x_usb_wmemreq {
u16 type;
u16 frmlen;
u16 offset;
u16 page;
u8 data[HFA384x_USB_RWMEM_MAXLEN];
-} __packed hfa384x_usb_wmemreq_t;
+} __packed;
-typedef struct hfa384x_usb_rmemreq {
+struct hfa384x_usb_rmemreq {
u16 type;
u16 frmlen;
u16 offset;
u16 page;
u8 pad[56];
-} __packed hfa384x_usb_rmemreq_t;
+} __packed;
/*------------------------------------*/
/* Response (bulk IN) packet contents */
-typedef struct hfa384x_usb_rxfrm {
- hfa384x_rx_frame_t desc;
+struct hfa384x_usb_rxfrm {
+ struct hfa384x_rx_frame desc;
u8 data[WLAN_DATA_MAXLEN];
-} __packed hfa384x_usb_rxfrm_t;
+} __packed;
-typedef struct hfa384x_usb_infofrm {
+struct hfa384x_usb_infofrm {
u16 type;
- hfa384x_InfFrame_t info;
-} __packed hfa384x_usb_infofrm_t;
+ struct hfa384x_InfFrame info;
+} __packed;
-typedef struct hfa384x_usb_statusresp {
+struct hfa384x_usb_statusresp {
u16 type;
u16 status;
u16 resp0;
u16 resp1;
u16 resp2;
-} __packed hfa384x_usb_cmdresp_t;
-
-typedef hfa384x_usb_cmdresp_t hfa384x_usb_wridresp_t;
+} __packed;
-typedef struct hfa384x_usb_rridresp {
+struct hfa384x_usb_rridresp {
u16 type;
u16 frmlen;
u16 rid;
u8 data[HFA384x_RIDDATA_MAXLEN];
-} __packed hfa384x_usb_rridresp_t;
-
-typedef hfa384x_usb_cmdresp_t hfa384x_usb_wmemresp_t;
+} __packed;
-typedef struct hfa384x_usb_rmemresp {
+struct hfa384x_usb_rmemresp {
u16 type;
u16 frmlen;
u8 data[HFA384x_USB_RWMEM_MAXLEN];
-} __packed hfa384x_usb_rmemresp_t;
+} __packed;
-typedef struct hfa384x_usb_bufavail {
+struct hfa384x_usb_bufavail {
u16 type;
u16 frmlen;
-} __packed hfa384x_usb_bufavail_t;
+} __packed;
-typedef struct hfa384x_usb_error {
+struct hfa384x_usb_error {
u16 type;
u16 errortype;
-} __packed hfa384x_usb_error_t;
+} __packed;
/*----------------------------------------------------------*/
/* Unions for packaging all the known packet types together */
-typedef union hfa384x_usbout {
+union hfa384x_usbout {
__le16 type;
- hfa384x_usb_txfrm_t txfrm;
- hfa384x_usb_cmdreq_t cmdreq;
- hfa384x_usb_wridreq_t wridreq;
- hfa384x_usb_rridreq_t rridreq;
- hfa384x_usb_wmemreq_t wmemreq;
- hfa384x_usb_rmemreq_t rmemreq;
-} __packed hfa384x_usbout_t;
-
-typedef union hfa384x_usbin {
+ struct hfa384x_usb_txfrm txfrm;
+ struct hfa384x_usb_cmdreq cmdreq;
+ struct hfa384x_usb_wridreq wridreq;
+ struct hfa384x_usb_rridreq rridreq;
+ struct hfa384x_usb_wmemreq wmemreq;
+ struct hfa384x_usb_rmemreq rmemreq;
+} __packed;
+
+union hfa384x_usbin {
__le16 type;
- hfa384x_usb_rxfrm_t rxfrm;
- hfa384x_usb_txfrm_t txfrm;
- hfa384x_usb_infofrm_t infofrm;
- hfa384x_usb_cmdresp_t cmdresp;
- hfa384x_usb_wridresp_t wridresp;
- hfa384x_usb_rridresp_t rridresp;
- hfa384x_usb_wmemresp_t wmemresp;
- hfa384x_usb_rmemresp_t rmemresp;
- hfa384x_usb_bufavail_t bufavail;
- hfa384x_usb_error_t usberror;
+ struct hfa384x_usb_rxfrm rxfrm;
+ struct hfa384x_usb_txfrm txfrm;
+ struct hfa384x_usb_infofrm infofrm;
+ struct hfa384x_usb_statusresp cmdresp;
+ struct hfa384x_usb_statusresp wridresp;
+ struct hfa384x_usb_rridresp rridresp;
+ struct hfa384x_usb_statusresp wmemresp;
+ struct hfa384x_usb_rmemresp rmemresp;
+ struct hfa384x_usb_bufavail bufavail;
+ struct hfa384x_usb_error usberror;
u8 boguspad[3000];
-} __packed hfa384x_usbin_t;
+} __packed;
/*--------------------------------------------------------------------
-PD record structures.
---------------------------------------------------------------------*/
+ * PD record structures.
+ *--------------------------------------------------------------------
+ */
-typedef struct hfa384x_pdr_pcb_partnum {
+struct hfa384x_pdr_pcb_partnum {
u8 num[8];
-} __packed hfa384x_pdr_pcb_partnum_t;
+} __packed;
-typedef struct hfa384x_pdr_pcb_tracenum {
+struct hfa384x_pdr_pcb_tracenum {
u8 num[8];
-} __packed hfa384x_pdr_pcb_tracenum_t;
+} __packed;
-typedef struct hfa384x_pdr_nic_serial {
+struct hfa384x_pdr_nic_serial {
u8 num[12];
-} __packed hfa384x_pdr_nic_serial_t;
+} __packed;
-typedef struct hfa384x_pdr_mkk_measurements {
+struct hfa384x_pdr_mkk_measurements {
double carrier_freq;
double occupied_band;
double power_density;
@@ -935,192 +957,193 @@ typedef struct hfa384x_pdr_mkk_measurements {
double rx_spur_f2;
double rx_spur_l1;
double rx_spur_l2;
-} __packed hfa384x_pdr_mkk_measurements_t;
+} __packed;
-typedef struct hfa384x_pdr_nic_ramsize {
+struct hfa384x_pdr_nic_ramsize {
u8 size[12]; /* units of KB */
-} __packed hfa384x_pdr_nic_ramsize_t;
+} __packed;
-typedef struct hfa384x_pdr_mfisuprange {
+struct hfa384x_pdr_mfisuprange {
u16 id;
u16 variant;
u16 bottom;
u16 top;
-} __packed hfa384x_pdr_mfisuprange_t;
+} __packed;
-typedef struct hfa384x_pdr_cfisuprange {
+struct hfa384x_pdr_cfisuprange {
u16 id;
u16 variant;
u16 bottom;
u16 top;
-} __packed hfa384x_pdr_cfisuprange_t;
+} __packed;
-typedef struct hfa384x_pdr_nicid {
+struct hfa384x_pdr_nicid {
u16 id;
u16 variant;
u16 major;
u16 minor;
-} __packed hfa384x_pdr_nicid_t;
+} __packed;
-typedef struct hfa384x_pdr_refdac_measurements {
+struct hfa384x_pdr_refdac_measurements {
u16 value[0];
-} __packed hfa384x_pdr_refdac_measurements_t;
+} __packed;
-typedef struct hfa384x_pdr_vgdac_measurements {
+struct hfa384x_pdr_vgdac_measurements {
u16 value[0];
-} __packed hfa384x_pdr_vgdac_measurements_t;
+} __packed;
-typedef struct hfa384x_pdr_level_comp_measurements {
+struct hfa384x_pdr_level_comp_measurements {
u16 value[0];
-} __packed hfa384x_pdr_level_compc_measurements_t;
+} __packed;
-typedef struct hfa384x_pdr_mac_address {
+struct hfa384x_pdr_mac_address {
u8 addr[6];
-} __packed hfa384x_pdr_mac_address_t;
+} __packed;
-typedef struct hfa384x_pdr_mkk_callname {
+struct hfa384x_pdr_mkk_callname {
u8 callname[8];
-} __packed hfa384x_pdr_mkk_callname_t;
+} __packed;
-typedef struct hfa384x_pdr_regdomain {
+struct hfa384x_pdr_regdomain {
u16 numdomains;
u16 domain[5];
-} __packed hfa384x_pdr_regdomain_t;
+} __packed;
-typedef struct hfa384x_pdr_allowed_channel {
+struct hfa384x_pdr_allowed_channel {
u16 ch_bitmap;
-} __packed hfa384x_pdr_allowed_channel_t;
+} __packed;
-typedef struct hfa384x_pdr_default_channel {
+struct hfa384x_pdr_default_channel {
u16 channel;
-} __packed hfa384x_pdr_default_channel_t;
+} __packed;
-typedef struct hfa384x_pdr_privacy_option {
+struct hfa384x_pdr_privacy_option {
u16 available;
-} __packed hfa384x_pdr_privacy_option_t;
+} __packed;
-typedef struct hfa384x_pdr_temptype {
+struct hfa384x_pdr_temptype {
u16 type;
-} __packed hfa384x_pdr_temptype_t;
+} __packed;
-typedef struct hfa384x_pdr_refdac_setup {
+struct hfa384x_pdr_refdac_setup {
u16 ch_value[14];
-} __packed hfa384x_pdr_refdac_setup_t;
+} __packed;
-typedef struct hfa384x_pdr_vgdac_setup {
+struct hfa384x_pdr_vgdac_setup {
u16 ch_value[14];
-} __packed hfa384x_pdr_vgdac_setup_t;
+} __packed;
-typedef struct hfa384x_pdr_level_comp_setup {
+struct hfa384x_pdr_level_comp_setup {
u16 ch_value[14];
-} __packed hfa384x_pdr_level_comp_setup_t;
+} __packed;
-typedef struct hfa384x_pdr_trimdac_setup {
+struct hfa384x_pdr_trimdac_setup {
u16 trimidac;
u16 trimqdac;
-} __packed hfa384x_pdr_trimdac_setup_t;
+} __packed;
-typedef struct hfa384x_pdr_ifr_setting {
+struct hfa384x_pdr_ifr_setting {
u16 value[3];
-} __packed hfa384x_pdr_ifr_setting_t;
+} __packed;
-typedef struct hfa384x_pdr_rfr_setting {
+struct hfa384x_pdr_rfr_setting {
u16 value[3];
-} __packed hfa384x_pdr_rfr_setting_t;
+} __packed;
-typedef struct hfa384x_pdr_hfa3861_baseline {
+struct hfa384x_pdr_hfa3861_baseline {
u16 value[50];
-} __packed hfa384x_pdr_hfa3861_baseline_t;
+} __packed;
-typedef struct hfa384x_pdr_hfa3861_shadow {
+struct hfa384x_pdr_hfa3861_shadow {
u32 value[32];
-} __packed hfa384x_pdr_hfa3861_shadow_t;
+} __packed;
-typedef struct hfa384x_pdr_hfa3861_ifrf {
+struct hfa384x_pdr_hfa3861_ifrf {
u32 value[20];
-} __packed hfa384x_pdr_hfa3861_ifrf_t;
+} __packed;
-typedef struct hfa384x_pdr_hfa3861_chcalsp {
+struct hfa384x_pdr_hfa3861_chcalsp {
u16 value[14];
-} __packed hfa384x_pdr_hfa3861_chcalsp_t;
+} __packed;
-typedef struct hfa384x_pdr_hfa3861_chcali {
+struct hfa384x_pdr_hfa3861_chcali {
u16 value[17];
-} __packed hfa384x_pdr_hfa3861_chcali_t;
+} __packed;
-typedef struct hfa384x_pdr_hfa3861_nic_config {
+struct hfa384x_pdr_hfa3861_nic_config {
u16 config_bitmap;
-} __packed hfa384x_pdr_nic_config_t;
+} __packed;
-typedef struct hfa384x_pdr_hfo_delay {
+struct hfa384x_pdr_hfo_delay {
u8 hfo_delay;
-} __packed hfa384x_hfo_delay_t;
+} __packed;
-typedef struct hfa384x_pdr_hfa3861_manf_testsp {
+struct hfa384x_pdr_hfa3861_manf_testsp {
u16 value[30];
-} __packed hfa384x_pdr_hfa3861_manf_testsp_t;
+} __packed;
-typedef struct hfa384x_pdr_hfa3861_manf_testi {
+struct hfa384x_pdr_hfa3861_manf_testi {
u16 value[30];
-} __packed hfa384x_pdr_hfa3861_manf_testi_t;
+} __packed;
-typedef struct hfa384x_end_of_pda {
+struct hfa384x_pdr_end_of_pda {
u16 crc;
-} __packed hfa384x_pdr_end_of_pda_t;
+} __packed;
-typedef struct hfa384x_pdrec {
+struct hfa384x_pdrec {
u16 len; /* in words */
u16 code;
union pdr {
- hfa384x_pdr_pcb_partnum_t pcb_partnum;
- hfa384x_pdr_pcb_tracenum_t pcb_tracenum;
- hfa384x_pdr_nic_serial_t nic_serial;
- hfa384x_pdr_mkk_measurements_t mkk_measurements;
- hfa384x_pdr_nic_ramsize_t nic_ramsize;
- hfa384x_pdr_mfisuprange_t mfisuprange;
- hfa384x_pdr_cfisuprange_t cfisuprange;
- hfa384x_pdr_nicid_t nicid;
- hfa384x_pdr_refdac_measurements_t refdac_measurements;
- hfa384x_pdr_vgdac_measurements_t vgdac_measurements;
- hfa384x_pdr_level_compc_measurements_t level_compc_measurements;
- hfa384x_pdr_mac_address_t mac_address;
- hfa384x_pdr_mkk_callname_t mkk_callname;
- hfa384x_pdr_regdomain_t regdomain;
- hfa384x_pdr_allowed_channel_t allowed_channel;
- hfa384x_pdr_default_channel_t default_channel;
- hfa384x_pdr_privacy_option_t privacy_option;
- hfa384x_pdr_temptype_t temptype;
- hfa384x_pdr_refdac_setup_t refdac_setup;
- hfa384x_pdr_vgdac_setup_t vgdac_setup;
- hfa384x_pdr_level_comp_setup_t level_comp_setup;
- hfa384x_pdr_trimdac_setup_t trimdac_setup;
- hfa384x_pdr_ifr_setting_t ifr_setting;
- hfa384x_pdr_rfr_setting_t rfr_setting;
- hfa384x_pdr_hfa3861_baseline_t hfa3861_baseline;
- hfa384x_pdr_hfa3861_shadow_t hfa3861_shadow;
- hfa384x_pdr_hfa3861_ifrf_t hfa3861_ifrf;
- hfa384x_pdr_hfa3861_chcalsp_t hfa3861_chcalsp;
- hfa384x_pdr_hfa3861_chcali_t hfa3861_chcali;
- hfa384x_pdr_nic_config_t nic_config;
- hfa384x_hfo_delay_t hfo_delay;
- hfa384x_pdr_hfa3861_manf_testsp_t hfa3861_manf_testsp;
- hfa384x_pdr_hfa3861_manf_testi_t hfa3861_manf_testi;
- hfa384x_pdr_end_of_pda_t end_of_pda;
+ struct hfa384x_pdr_pcb_partnum pcb_partnum;
+ struct hfa384x_pdr_pcb_tracenum pcb_tracenum;
+ struct hfa384x_pdr_nic_serial nic_serial;
+ struct hfa384x_pdr_mkk_measurements mkk_measurements;
+ struct hfa384x_pdr_nic_ramsize nic_ramsize;
+ struct hfa384x_pdr_mfisuprange mfisuprange;
+ struct hfa384x_pdr_cfisuprange cfisuprange;
+ struct hfa384x_pdr_nicid nicid;
+ struct hfa384x_pdr_refdac_measurements refdac_measurements;
+ struct hfa384x_pdr_vgdac_measurements vgdac_measurements;
+ struct hfa384x_pdr_level_comp_measurements level_compc_measurements;
+ struct hfa384x_pdr_mac_address mac_address;
+ struct hfa384x_pdr_mkk_callname mkk_callname;
+ struct hfa384x_pdr_regdomain regdomain;
+ struct hfa384x_pdr_allowed_channel allowed_channel;
+ struct hfa384x_pdr_default_channel default_channel;
+ struct hfa384x_pdr_privacy_option privacy_option;
+ struct hfa384x_pdr_temptype temptype;
+ struct hfa384x_pdr_refdac_setup refdac_setup;
+ struct hfa384x_pdr_vgdac_setup vgdac_setup;
+ struct hfa384x_pdr_level_comp_setup level_comp_setup;
+ struct hfa384x_pdr_trimdac_setup trimdac_setup;
+ struct hfa384x_pdr_ifr_setting ifr_setting;
+ struct hfa384x_pdr_rfr_setting rfr_setting;
+ struct hfa384x_pdr_hfa3861_baseline hfa3861_baseline;
+ struct hfa384x_pdr_hfa3861_shadow hfa3861_shadow;
+ struct hfa384x_pdr_hfa3861_ifrf hfa3861_ifrf;
+ struct hfa384x_pdr_hfa3861_chcalsp hfa3861_chcalsp;
+ struct hfa384x_pdr_hfa3861_chcali hfa3861_chcali;
+ struct hfa384x_pdr_hfa3861_nic_config nic_config;
+ struct hfa384x_pdr_hfo_delay hfo_delay;
+ struct hfa384x_pdr_hfa3861_manf_testsp hfa3861_manf_testsp;
+ struct hfa384x_pdr_hfa3861_manf_testi hfa3861_manf_testi;
+ struct hfa384x_pdr_end_of_pda end_of_pda;
} data;
-} __packed hfa384x_pdrec_t;
+} __packed;
#ifdef __KERNEL__
/*--------------------------------------------------------------------
---- MAC state structure, argument to all functions --
---- Also, a collection of support types --
---------------------------------------------------------------------*/
-typedef struct hfa384x_statusresult {
+ * --- MAC state structure, argument to all functions --
+ * --- Also, a collection of support types --
+ *--------------------------------------------------------------------
+ */
+struct hfa384x_cmdresult {
u16 status;
u16 resp0;
u16 resp1;
u16 resp2;
-} hfa384x_cmdresult_t;
+};
/* USB Control Exchange (CTLX):
* A queue of the structure below is maintained for all of the
@@ -1129,11 +1152,11 @@ typedef struct hfa384x_statusresult {
/* The following hfa384x_* structures are arguments to
* the usercb() for the different CTLX types.
*/
-typedef struct hfa384x_rridresult {
+struct hfa384x_rridresult {
u16 rid;
const void *riddata;
unsigned int riddata_len;
-} hfa384x_rridresult_t;
+};
enum ctlx_state {
CTLX_START = 0, /* Start state, not queued */
@@ -1156,12 +1179,12 @@ typedef void (*ctlx_cmdcb_t) (struct hfa384x *, const struct hfa384x_usbctlx *);
typedef void (*ctlx_usercb_t) (struct hfa384x *hw,
void *ctlxresult, void *usercb_data);
-typedef struct hfa384x_usbctlx {
+struct hfa384x_usbctlx {
struct list_head list;
size_t outbufsize;
- hfa384x_usbout_t outbuf; /* pkt buf for OUT */
- hfa384x_usbin_t inbuf; /* pkt buf for IN(a copy) */
+ union hfa384x_usbout outbuf; /* pkt buf for OUT */
+ union hfa384x_usbin inbuf; /* pkt buf for IN(a copy) */
CTLX_STATE state; /* Tracks running state */
@@ -1173,25 +1196,25 @@ typedef struct hfa384x_usbctlx {
void *usercb_data; /* at CTLX completion */
int variant; /* Identifies cmd variant */
-} hfa384x_usbctlx_t;
+};
-typedef struct hfa384x_usbctlxq {
+struct hfa384x_usbctlxq {
spinlock_t lock;
struct list_head pending;
struct list_head active;
struct list_head completing;
struct list_head reapable;
-} hfa384x_usbctlxq_t;
+};
-typedef struct hfa484x_metacmd {
+struct hfa384x_metacmd {
u16 cmd;
u16 parm0;
u16 parm1;
u16 parm2;
- hfa384x_cmdresult_t result;
-} hfa384x_metacmd_t;
+ struct hfa384x_cmdresult result;
+};
#define MAX_GRP_ADDR 32
#define WLAN_COMMENT_MAX 80 /* Max. length of user comment string. */
@@ -1218,15 +1241,15 @@ struct prism2sta_accesslist {
u8 addr1[WLAN_ACCESS_MAX][ETH_ALEN];
};
-typedef struct hfa384x {
+struct hfa384x {
/* USB support data */
struct usb_device *usb;
struct urb rx_urb;
struct sk_buff *rx_urb_skb;
struct urb tx_urb;
struct urb ctlx_urb;
- hfa384x_usbout_t txbuff;
- hfa384x_usbctlxq_t ctlxq;
+ union hfa384x_usbout txbuff;
+ struct hfa384x_usbctlxq ctlxq;
struct timer_list reqtimer;
struct timer_list resptimer;
@@ -1265,20 +1288,20 @@ typedef struct hfa384x {
/* Download support */
unsigned int dlstate;
- hfa384x_downloadbuffer_t bufinfo;
+ struct hfa384x_downloadbuffer bufinfo;
u16 dltimeout;
int scanflag; /* to signal scan complete */
int join_ap; /* are we joined to a specific ap */
int join_retries; /* number of join retries till we fail */
- hfa384x_JoinRequest_data_t joinreq; /* join request saved data */
+ struct hfa384x_JoinRequest_data joinreq; /* join request saved data */
- wlandevice_t *wlandev;
+ struct wlandevice *wlandev;
/* Timer to allow for the deferred processing of linkstatus messages */
struct work_struct link_bh;
struct work_struct commsqual_bh;
- hfa384x_commsquality_t qual;
+ struct hfa384x_commsquality qual;
struct timer_list commsqual_timer;
u16 link_status;
@@ -1297,92 +1320,93 @@ typedef struct hfa384x {
int dbmadjust;
/* Group Addresses - right now, there are up to a total
- of MAX_GRP_ADDR group addresses */
+ * of MAX_GRP_ADDR group addresses
+ */
u8 dot11_grp_addr[MAX_GRP_ADDR][ETH_ALEN];
unsigned int dot11_grpcnt;
/* Component Identities */
- hfa384x_compident_t ident_nic;
- hfa384x_compident_t ident_pri_fw;
- hfa384x_compident_t ident_sta_fw;
- hfa384x_compident_t ident_ap_fw;
+ struct hfa384x_compident ident_nic;
+ struct hfa384x_compident ident_pri_fw;
+ struct hfa384x_compident ident_sta_fw;
+ struct hfa384x_compident ident_ap_fw;
u16 mm_mods;
/* Supplier compatibility ranges */
- hfa384x_caplevel_t cap_sup_mfi;
- hfa384x_caplevel_t cap_sup_cfi;
- hfa384x_caplevel_t cap_sup_pri;
- hfa384x_caplevel_t cap_sup_sta;
- hfa384x_caplevel_t cap_sup_ap;
+ struct hfa384x_caplevel cap_sup_mfi;
+ struct hfa384x_caplevel cap_sup_cfi;
+ struct hfa384x_caplevel cap_sup_pri;
+ struct hfa384x_caplevel cap_sup_sta;
+ struct hfa384x_caplevel cap_sup_ap;
/* Actor compatibility ranges */
- hfa384x_caplevel_t cap_act_pri_cfi; /*
- * pri f/w to controller
- * interface
- */
+ struct hfa384x_caplevel cap_act_pri_cfi; /*
+ * pri f/w to controller
+ * interface
+ */
- hfa384x_caplevel_t cap_act_sta_cfi; /*
- * sta f/w to controller
- * interface
- */
+ struct hfa384x_caplevel cap_act_sta_cfi; /*
+ * sta f/w to controller
+ * interface
+ */
- hfa384x_caplevel_t cap_act_sta_mfi; /* sta f/w to modem interface */
+ struct hfa384x_caplevel cap_act_sta_mfi; /* sta f/w to modem interface */
- hfa384x_caplevel_t cap_act_ap_cfi; /*
+ struct hfa384x_caplevel cap_act_ap_cfi; /*
* ap f/w to controller
* interface
*/
- hfa384x_caplevel_t cap_act_ap_mfi; /* ap f/w to modem interface */
+ struct hfa384x_caplevel cap_act_ap_mfi; /* ap f/w to modem interface */
u32 psusercount; /* Power save user count. */
- hfa384x_CommTallies32_t tallies; /* Communication tallies. */
+ struct hfa384x_CommTallies32 tallies; /* Communication tallies. */
u8 comment[WLAN_COMMENT_MAX + 1]; /* User comment */
/* Channel Info request results (AP only) */
struct {
atomic_t done;
u8 count;
- hfa384x_ChInfoResult_t results;
+ struct hfa384x_ChInfoResult results;
} channel_info;
- hfa384x_InfFrame_t *scanresults;
+ struct hfa384x_InfFrame *scanresults;
struct prism2sta_authlist authlist; /* Authenticated station list. */
unsigned int accessmode; /* Access mode. */
struct prism2sta_accesslist allow; /* Allowed station list. */
struct prism2sta_accesslist deny; /* Denied station list. */
-} hfa384x_t;
+};
-void hfa384x_create(hfa384x_t *hw, struct usb_device *usb);
-void hfa384x_destroy(hfa384x_t *hw);
+void hfa384x_create(struct hfa384x *hw, struct usb_device *usb);
+void hfa384x_destroy(struct hfa384x *hw);
int
-hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis);
-int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport);
-int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport);
-int hfa384x_drvr_flashdl_enable(hfa384x_t *hw);
-int hfa384x_drvr_flashdl_disable(hfa384x_t *hw);
-int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len);
-int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
-int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr);
-int hfa384x_drvr_ramdl_disable(hfa384x_t *hw);
-int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len);
-int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len);
-int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
-
-static inline int hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val)
+hfa384x_corereset(struct hfa384x *hw, int holdtime, int settletime, int genesis);
+int hfa384x_drvr_disable(struct hfa384x *hw, u16 macport);
+int hfa384x_drvr_enable(struct hfa384x *hw, u16 macport);
+int hfa384x_drvr_flashdl_enable(struct hfa384x *hw);
+int hfa384x_drvr_flashdl_disable(struct hfa384x *hw);
+int hfa384x_drvr_flashdl_write(struct hfa384x *hw, u32 daddr, void *buf, u32 len);
+int hfa384x_drvr_getconfig(struct hfa384x *hw, u16 rid, void *buf, u16 len);
+int hfa384x_drvr_ramdl_enable(struct hfa384x *hw, u32 exeaddr);
+int hfa384x_drvr_ramdl_disable(struct hfa384x *hw);
+int hfa384x_drvr_ramdl_write(struct hfa384x *hw, u32 daddr, void *buf, u32 len);
+int hfa384x_drvr_readpda(struct hfa384x *hw, void *buf, unsigned int len);
+int hfa384x_drvr_setconfig(struct hfa384x *hw, u16 rid, void *buf, u16 len);
+
+static inline int hfa384x_drvr_getconfig16(struct hfa384x *hw, u16 rid, void *val)
{
int result = 0;
result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16));
if (result == 0)
- *((u16 *) val) = le16_to_cpu(*((u16 *) val));
+ *((u16 *)val) = le16_to_cpu(*((u16 *)val));
return result;
}
-static inline int hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val)
+static inline int hfa384x_drvr_setconfig16(struct hfa384x *hw, u16 rid, u16 val)
{
u16 value = cpu_to_le16(val);
@@ -1390,13 +1414,13 @@ static inline int hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val)
}
int
-hfa384x_drvr_setconfig_async(hfa384x_t *hw,
+hfa384x_drvr_setconfig_async(struct hfa384x *hw,
u16 rid,
void *buf,
u16 len, ctlx_usercb_t usercb, void *usercb_data);
static inline int
-hfa384x_drvr_setconfig16_async(hfa384x_t *hw, u16 rid, u16 val)
+hfa384x_drvr_setconfig16_async(struct hfa384x *hw, u16 rid, u16 val)
{
u16 value = cpu_to_le16(val);
@@ -1404,21 +1428,21 @@ hfa384x_drvr_setconfig16_async(hfa384x_t *hw, u16 rid, u16 val)
NULL, NULL);
}
-int hfa384x_drvr_start(hfa384x_t *hw);
-int hfa384x_drvr_stop(hfa384x_t *hw);
+int hfa384x_drvr_start(struct hfa384x *hw);
+int hfa384x_drvr_stop(struct hfa384x *hw);
int
-hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
+hfa384x_drvr_txframe(struct hfa384x *hw, struct sk_buff *skb,
union p80211_hdr *p80211_hdr,
struct p80211_metawep *p80211_wep);
-void hfa384x_tx_timeout(wlandevice_t *wlandev);
+void hfa384x_tx_timeout(struct wlandevice *wlandev);
-int hfa384x_cmd_initialize(hfa384x_t *hw);
-int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport);
-int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport);
-int hfa384x_cmd_allocate(hfa384x_t *hw, u16 len);
-int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable);
+int hfa384x_cmd_initialize(struct hfa384x *hw);
+int hfa384x_cmd_enable(struct hfa384x *hw, u16 macport);
+int hfa384x_cmd_disable(struct hfa384x *hw, u16 macport);
+int hfa384x_cmd_allocate(struct hfa384x *hw, u16 len);
+int hfa384x_cmd_monitor(struct hfa384x *hw, u16 enable);
int
-hfa384x_cmd_download(hfa384x_t *hw,
+hfa384x_cmd_download(struct hfa384x *hw,
u16 mode, u16 lowaddr, u16 highaddr, u16 codelen);
#endif /*__KERNEL__ */
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
index 337810750f2b..6a107f8a06e2 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -154,13 +154,13 @@ static void dbprint_urb(struct urb *urb);
#endif
static void
-hfa384x_int_rxmonitor(wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *rxfrm);
+hfa384x_int_rxmonitor(struct wlandevice *wlandev, struct hfa384x_usb_rxfrm *rxfrm);
static void hfa384x_usb_defer(struct work_struct *data);
-static int submit_rx_urb(hfa384x_t *hw, gfp_t flags);
+static int submit_rx_urb(struct hfa384x *hw, gfp_t flags);
-static int submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t flags);
+static int submit_tx_urb(struct hfa384x *hw, struct urb *tx_urb, gfp_t flags);
/*---------------------------------------------------*/
/* Callbacks */
@@ -169,19 +169,19 @@ static void hfa384x_ctlxout_callback(struct urb *urb);
static void hfa384x_usbin_callback(struct urb *urb);
static void
-hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
+hfa384x_usbin_txcompl(struct wlandevice *wlandev, union hfa384x_usbin *usbin);
-static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+static void hfa384x_usbin_rx(struct wlandevice *wlandev, struct sk_buff *skb);
-static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
+static void hfa384x_usbin_info(struct wlandevice *wlandev, union hfa384x_usbin *usbin);
-static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
+static void hfa384x_usbin_ctlx(struct hfa384x *hw, union hfa384x_usbin *usbin,
int urb_status);
/*---------------------------------------------------*/
/* Functions to support the prism2 usb command queue */
-static void hfa384x_usbctlxq_run(hfa384x_t *hw);
+static void hfa384x_usbctlxq_run(struct hfa384x *hw);
static void hfa384x_usbctlx_reqtimerfn(unsigned long data);
@@ -193,42 +193,42 @@ static void hfa384x_usbctlx_completion_task(unsigned long data);
static void hfa384x_usbctlx_reaper_task(unsigned long data);
-static int hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
+static int hfa384x_usbctlx_submit(struct hfa384x *hw, struct hfa384x_usbctlx *ctlx);
-static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
+static void unlocked_usbctlx_complete(struct hfa384x *hw, struct hfa384x_usbctlx *ctlx);
struct usbctlx_completor {
int (*complete)(struct usbctlx_completor *);
};
static int
-hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
- hfa384x_usbctlx_t *ctlx,
+hfa384x_usbctlx_complete_sync(struct hfa384x *hw,
+ struct hfa384x_usbctlx *ctlx,
struct usbctlx_completor *completor);
static int
-unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
+unlocked_usbctlx_cancel_async(struct hfa384x *hw, struct hfa384x_usbctlx *ctlx);
-static void hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
+static void hfa384x_cb_status(struct hfa384x *hw, const struct hfa384x_usbctlx *ctlx);
static int
-usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
- hfa384x_cmdresult_t *result);
+usbctlx_get_status(const struct hfa384x_usb_statusresp *cmdresp,
+ struct hfa384x_cmdresult *result);
static void
-usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
- hfa384x_rridresult_t *result);
+usbctlx_get_rridresult(const struct hfa384x_usb_rridresp *rridresp,
+ struct hfa384x_rridresult *result);
/*---------------------------------------------------*/
/* Low level req/resp CTLX formatters and submitters */
static int
-hfa384x_docmd(hfa384x_t *hw,
+hfa384x_docmd(struct hfa384x *hw,
enum cmd_mode mode,
- hfa384x_metacmd_t *cmd,
+ struct hfa384x_metacmd *cmd,
ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
static int
-hfa384x_dorrid(hfa384x_t *hw,
+hfa384x_dorrid(struct hfa384x *hw,
enum cmd_mode mode,
u16 rid,
void *riddata,
@@ -236,7 +236,7 @@ hfa384x_dorrid(hfa384x_t *hw,
ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
static int
-hfa384x_dowrid(hfa384x_t *hw,
+hfa384x_dowrid(struct hfa384x *hw,
enum cmd_mode mode,
u16 rid,
void *riddata,
@@ -244,7 +244,7 @@ hfa384x_dowrid(hfa384x_t *hw,
ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
static int
-hfa384x_dormem(hfa384x_t *hw,
+hfa384x_dormem(struct hfa384x *hw,
enum cmd_mode mode,
u16 page,
u16 offset,
@@ -253,7 +253,7 @@ hfa384x_dormem(hfa384x_t *hw,
ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
static int
-hfa384x_dowmem(hfa384x_t *hw,
+hfa384x_dowmem(struct hfa384x *hw,
enum cmd_mode mode,
u16 page,
u16 offset,
@@ -278,9 +278,9 @@ static inline const char *ctlxstr(CTLX_STATE s)
return ctlx_str[s];
};
-static inline hfa384x_usbctlx_t *get_active_ctlx(hfa384x_t *hw)
+static inline struct hfa384x_usbctlx *get_active_ctlx(struct hfa384x *hw)
{
- return list_entry(hw->ctlxq.active.next, hfa384x_usbctlx_t, list);
+ return list_entry(hw->ctlxq.active.next, struct hfa384x_usbctlx, list);
}
#ifdef DEBUG_USB
@@ -322,12 +322,12 @@ void dbprint_urb(struct urb *urb)
* Call context:
* Any
----------------------------------------------------------------*/
-static int submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
+static int submit_rx_urb(struct hfa384x *hw, gfp_t memflags)
{
struct sk_buff *skb;
int result;
- skb = dev_alloc_skb(sizeof(hfa384x_usbin_t));
+ skb = dev_alloc_skb(sizeof(union hfa384x_usbin));
if (!skb) {
result = -ENOMEM;
goto done;
@@ -336,7 +336,7 @@ static int submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
/* Post the IN urb */
usb_fill_bulk_urb(&hw->rx_urb, hw->usb,
hw->endp_in,
- skb->data, sizeof(hfa384x_usbin_t),
+ skb->data, sizeof(union hfa384x_usbin),
hfa384x_usbin_callback, hw->wlandev);
hw->rx_urb_skb = skb;
@@ -384,7 +384,7 @@ done:
* Call context:
* Any
----------------------------------------------------------------*/
-static int submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
+static int submit_tx_urb(struct hfa384x *hw, struct urb *tx_urb, gfp_t memflags)
{
struct net_device *netdev = hw->wlandev->netdev;
int result;
@@ -429,7 +429,7 @@ static int submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
----------------------------------------------------------------*/
static void hfa384x_usb_defer(struct work_struct *data)
{
- hfa384x_t *hw = container_of(data, struct hfa384x, usb_work);
+ struct hfa384x *hw = container_of(data, struct hfa384x, usb_work);
struct net_device *netdev = hw->wlandev->netdev;
/* Don't bother trying to reset anything if the plug
@@ -503,7 +503,7 @@ static void hfa384x_usb_defer(struct work_struct *data)
/*----------------------------------------------------------------
* hfa384x_create
*
-* Sets up the hfa384x_t data structure for use. Note this
+* Sets up the struct hfa384x data structure for use. Note this
* does _not_ initialize the actual hardware, just the data structures
* we use to keep track of its state.
*
@@ -521,9 +521,9 @@ static void hfa384x_usb_defer(struct work_struct *data)
* Call context:
* process
----------------------------------------------------------------*/
-void hfa384x_create(hfa384x_t *hw, struct usb_device *usb)
+void hfa384x_create(struct hfa384x *hw, struct usb_device *usb)
{
- memset(hw, 0, sizeof(hfa384x_t));
+ memset(hw, 0, sizeof(struct hfa384x));
hw->usb = usb;
/* set up the endpoints */
@@ -592,7 +592,7 @@ void hfa384x_create(hfa384x_t *hw, struct usb_device *usb)
* Call context:
* process
----------------------------------------------------------------*/
-void hfa384x_destroy(hfa384x_t *hw)
+void hfa384x_destroy(struct hfa384x *hw)
{
struct sk_buff *skb;
@@ -608,9 +608,9 @@ void hfa384x_destroy(hfa384x_t *hw)
dev_kfree_skb(skb);
}
-static hfa384x_usbctlx_t *usbctlx_alloc(void)
+static struct hfa384x_usbctlx *usbctlx_alloc(void)
{
- hfa384x_usbctlx_t *ctlx;
+ struct hfa384x_usbctlx *ctlx;
ctlx = kzalloc(sizeof(*ctlx),
in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
@@ -621,8 +621,8 @@ static hfa384x_usbctlx_t *usbctlx_alloc(void)
}
static int
-usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
- hfa384x_cmdresult_t *result)
+usbctlx_get_status(const struct hfa384x_usb_statusresp *cmdresp,
+ struct hfa384x_cmdresult *result)
{
result->status = le16_to_cpu(cmdresp->status);
result->resp0 = le16_to_cpu(cmdresp->resp0);
@@ -636,8 +636,8 @@ usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
}
static void
-usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
- hfa384x_rridresult_t *result)
+usbctlx_get_rridresult(const struct hfa384x_usb_rridresp *rridresp,
+ struct hfa384x_rridresult *result)
{
result->rid = le16_to_cpu(rridresp->rid);
result->riddata = rridresp->data;
@@ -647,13 +647,13 @@ usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
/*----------------------------------------------------------------
* Completor object:
* This completor must be passed to hfa384x_usbctlx_complete_sync()
-* when processing a CTLX that returns a hfa384x_cmdresult_t structure.
+* when processing a CTLX that returns a struct hfa384x_cmdresult structure.
----------------------------------------------------------------*/
struct usbctlx_cmd_completor {
struct usbctlx_completor head;
- const hfa384x_usb_cmdresp_t *cmdresp;
- hfa384x_cmdresult_t *result;
+ const struct hfa384x_usb_statusresp *cmdresp;
+ struct hfa384x_cmdresult *result;
};
static inline int usbctlx_cmd_completor_fn(struct usbctlx_completor *head)
@@ -667,9 +667,9 @@ static inline int usbctlx_cmd_completor_fn(struct usbctlx_completor *head)
static inline struct usbctlx_completor *init_cmd_completor(
struct usbctlx_cmd_completor
*completor,
- const hfa384x_usb_cmdresp_t
+ const struct hfa384x_usb_statusresp
*cmdresp,
- hfa384x_cmdresult_t *result)
+ struct hfa384x_cmdresult *result)
{
completor->head.complete = usbctlx_cmd_completor_fn;
completor->cmdresp = cmdresp;
@@ -685,7 +685,7 @@ static inline struct usbctlx_completor *init_cmd_completor(
struct usbctlx_rrid_completor {
struct usbctlx_completor head;
- const hfa384x_usb_rridresp_t *rridresp;
+ const struct hfa384x_usb_rridresp *rridresp;
void *riddata;
unsigned int riddatalen;
};
@@ -693,7 +693,7 @@ struct usbctlx_rrid_completor {
static int usbctlx_rrid_completor_fn(struct usbctlx_completor *head)
{
struct usbctlx_rrid_completor *complete;
- hfa384x_rridresult_t rridresult;
+ struct hfa384x_rridresult rridresult;
complete = (struct usbctlx_rrid_completor *)head;
usbctlx_get_rridresult(complete->rridresp, &rridresult);
@@ -713,7 +713,7 @@ static int usbctlx_rrid_completor_fn(struct usbctlx_completor *head)
static inline struct usbctlx_completor *init_rrid_completor(
struct usbctlx_rrid_completor
*completor,
- const hfa384x_usb_rridresp_t
+ const struct hfa384x_usb_rridresp
*rridresp,
void *riddata,
unsigned int riddatalen)
@@ -744,7 +744,7 @@ static inline struct usbctlx_completor *init_rrid_completor(
struct usbctlx_rmem_completor {
struct usbctlx_completor head;
- const hfa384x_usb_rmemresp_t *rmemresp;
+ const struct hfa384x_usb_rmemresp *rmemresp;
void *data;
unsigned int len;
};
@@ -762,7 +762,7 @@ static int usbctlx_rmem_completor_fn(struct usbctlx_completor *head)
static inline struct usbctlx_completor *init_rmem_completor(
struct usbctlx_rmem_completor
*completor,
- hfa384x_usb_rmemresp_t
+ struct hfa384x_usb_rmemresp
*rmemresp,
void *data,
unsigned int len)
@@ -795,10 +795,10 @@ static inline struct usbctlx_completor *init_rmem_completor(
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
+static void hfa384x_cb_status(struct hfa384x *hw, const struct hfa384x_usbctlx *ctlx)
{
if (ctlx->usercb) {
- hfa384x_cmdresult_t cmdresult;
+ struct hfa384x_cmdresult cmdresult;
if (ctlx->state != CTLX_COMPLETE) {
memset(&cmdresult, 0, sizeof(cmdresult));
@@ -812,21 +812,21 @@ static void hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
}
}
-static inline int hfa384x_docmd_wait(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
+static inline int hfa384x_docmd_wait(struct hfa384x *hw, struct hfa384x_metacmd *cmd)
{
return hfa384x_docmd(hw, DOWAIT, cmd, NULL, NULL, NULL);
}
static inline int
-hfa384x_docmd_async(hfa384x_t *hw,
- hfa384x_metacmd_t *cmd,
+hfa384x_docmd_async(struct hfa384x *hw,
+ struct hfa384x_metacmd *cmd,
ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
return hfa384x_docmd(hw, DOASYNC, cmd, cmdcb, usercb, usercb_data);
}
static inline int
-hfa384x_dorrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
+hfa384x_dorrid_wait(struct hfa384x *hw, u16 rid, void *riddata,
unsigned int riddatalen)
{
return hfa384x_dorrid(hw, DOWAIT,
@@ -834,7 +834,7 @@ hfa384x_dorrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
}
static inline int
-hfa384x_dorrid_async(hfa384x_t *hw,
+hfa384x_dorrid_async(struct hfa384x *hw,
u16 rid, void *riddata, unsigned int riddatalen,
ctlx_cmdcb_t cmdcb,
ctlx_usercb_t usercb, void *usercb_data)
@@ -845,7 +845,7 @@ hfa384x_dorrid_async(hfa384x_t *hw,
}
static inline int
-hfa384x_dowrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
+hfa384x_dowrid_wait(struct hfa384x *hw, u16 rid, void *riddata,
unsigned int riddatalen)
{
return hfa384x_dowrid(hw, DOWAIT,
@@ -853,7 +853,7 @@ hfa384x_dowrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
}
static inline int
-hfa384x_dowrid_async(hfa384x_t *hw,
+hfa384x_dowrid_async(struct hfa384x *hw,
u16 rid, void *riddata, unsigned int riddatalen,
ctlx_cmdcb_t cmdcb,
ctlx_usercb_t usercb, void *usercb_data)
@@ -864,7 +864,7 @@ hfa384x_dowrid_async(hfa384x_t *hw,
}
static inline int
-hfa384x_dormem_wait(hfa384x_t *hw,
+hfa384x_dormem_wait(struct hfa384x *hw,
u16 page, u16 offset, void *data, unsigned int len)
{
return hfa384x_dormem(hw, DOWAIT,
@@ -872,7 +872,7 @@ hfa384x_dormem_wait(hfa384x_t *hw,
}
static inline int
-hfa384x_dormem_async(hfa384x_t *hw,
+hfa384x_dormem_async(struct hfa384x *hw,
u16 page, u16 offset, void *data, unsigned int len,
ctlx_cmdcb_t cmdcb,
ctlx_usercb_t usercb, void *usercb_data)
@@ -883,7 +883,7 @@ hfa384x_dormem_async(hfa384x_t *hw,
}
static inline int
-hfa384x_dowmem_wait(hfa384x_t *hw,
+hfa384x_dowmem_wait(struct hfa384x *hw,
u16 page, u16 offset, void *data, unsigned int len)
{
return hfa384x_dowmem(hw, DOWAIT,
@@ -891,7 +891,7 @@ hfa384x_dowmem_wait(hfa384x_t *hw,
}
static inline int
-hfa384x_dowmem_async(hfa384x_t *hw,
+hfa384x_dowmem_async(struct hfa384x *hw,
u16 page,
u16 offset,
void *data,
@@ -923,11 +923,11 @@ hfa384x_dowmem_async(hfa384x_t *hw,
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_cmd_initialize(hfa384x_t *hw)
+int hfa384x_cmd_initialize(struct hfa384x *hw)
{
int result = 0;
int i;
- hfa384x_metacmd_t cmd;
+ struct hfa384x_metacmd cmd;
cmd.cmd = HFA384x_CMDCODE_INIT;
cmd.parm0 = 0;
@@ -969,9 +969,9 @@ int hfa384x_cmd_initialize(hfa384x_t *hw)
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport)
+int hfa384x_cmd_disable(struct hfa384x *hw, u16 macport)
{
- hfa384x_metacmd_t cmd;
+ struct hfa384x_metacmd cmd;
cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) |
HFA384x_CMD_MACPORT_SET(macport);
@@ -1002,9 +1002,9 @@ int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport)
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport)
+int hfa384x_cmd_enable(struct hfa384x *hw, u16 macport)
{
- hfa384x_metacmd_t cmd;
+ struct hfa384x_metacmd cmd;
cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) |
HFA384x_CMD_MACPORT_SET(macport);
@@ -1044,9 +1044,9 @@ int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport)
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable)
+int hfa384x_cmd_monitor(struct hfa384x *hw, u16 enable)
{
- hfa384x_metacmd_t cmd;
+ struct hfa384x_metacmd cmd;
cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) |
HFA384x_CMD_AINFO_SET(enable);
@@ -1095,10 +1095,10 @@ int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable)
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_cmd_download(hfa384x_t *hw, u16 mode, u16 lowaddr,
+int hfa384x_cmd_download(struct hfa384x *hw, u16 mode, u16 lowaddr,
u16 highaddr, u16 codelen)
{
- hfa384x_metacmd_t cmd;
+ struct hfa384x_metacmd cmd;
pr_debug("mode=%d, lowaddr=0x%04x, highaddr=0x%04x, codelen=%d\n",
mode, lowaddr, highaddr, codelen);
@@ -1136,7 +1136,7 @@ int hfa384x_cmd_download(hfa384x_t *hw, u16 mode, u16 lowaddr,
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
+int hfa384x_corereset(struct hfa384x *hw, int holdtime, int settletime, int genesis)
{
int result;
@@ -1173,8 +1173,8 @@ int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
* Call context:
* process
----------------------------------------------------------------*/
-static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
- hfa384x_usbctlx_t *ctlx,
+static int hfa384x_usbctlx_complete_sync(struct hfa384x *hw,
+ struct hfa384x_usbctlx *ctlx,
struct usbctlx_completor *completor)
{
unsigned long flags;
@@ -1289,13 +1289,13 @@ cleanup:
* process
----------------------------------------------------------------*/
static int
-hfa384x_docmd(hfa384x_t *hw,
+hfa384x_docmd(struct hfa384x *hw,
enum cmd_mode mode,
- hfa384x_metacmd_t *cmd,
+ struct hfa384x_metacmd *cmd,
ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
int result;
- hfa384x_usbctlx_t *ctlx;
+ struct hfa384x_usbctlx *ctlx;
ctlx = usbctlx_alloc();
if (!ctlx) {
@@ -1377,7 +1377,7 @@ done:
* process (DOWAIT or DOASYNC)
----------------------------------------------------------------*/
static int
-hfa384x_dorrid(hfa384x_t *hw,
+hfa384x_dorrid(struct hfa384x *hw,
enum cmd_mode mode,
u16 rid,
void *riddata,
@@ -1385,7 +1385,7 @@ hfa384x_dorrid(hfa384x_t *hw,
ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
int result;
- hfa384x_usbctlx_t *ctlx;
+ struct hfa384x_usbctlx *ctlx;
ctlx = usbctlx_alloc();
if (!ctlx) {
@@ -1458,7 +1458,7 @@ done:
* process (DOWAIT or DOASYNC)
----------------------------------------------------------------*/
static int
-hfa384x_dowrid(hfa384x_t *hw,
+hfa384x_dowrid(struct hfa384x *hw,
enum cmd_mode mode,
u16 rid,
void *riddata,
@@ -1466,7 +1466,7 @@ hfa384x_dowrid(hfa384x_t *hw,
ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
int result;
- hfa384x_usbctlx_t *ctlx;
+ struct hfa384x_usbctlx *ctlx;
ctlx = usbctlx_alloc();
if (!ctlx) {
@@ -1497,7 +1497,7 @@ hfa384x_dowrid(hfa384x_t *hw,
kfree(ctlx);
} else if (mode == DOWAIT) {
struct usbctlx_cmd_completor completor;
- hfa384x_cmdresult_t wridresult;
+ struct hfa384x_cmdresult wridresult;
result = hfa384x_usbctlx_complete_sync(hw,
ctlx,
@@ -1545,7 +1545,7 @@ done:
* process (DOWAIT or DOASYNC)
----------------------------------------------------------------*/
static int
-hfa384x_dormem(hfa384x_t *hw,
+hfa384x_dormem(struct hfa384x *hw,
enum cmd_mode mode,
u16 page,
u16 offset,
@@ -1554,7 +1554,7 @@ hfa384x_dormem(hfa384x_t *hw,
ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
int result;
- hfa384x_usbctlx_t *ctlx;
+ struct hfa384x_usbctlx *ctlx;
ctlx = usbctlx_alloc();
if (!ctlx) {
@@ -1636,7 +1636,7 @@ done:
* process (DOWAIT or DOASYNC)
----------------------------------------------------------------*/
static int
-hfa384x_dowmem(hfa384x_t *hw,
+hfa384x_dowmem(struct hfa384x *hw,
enum cmd_mode mode,
u16 page,
u16 offset,
@@ -1645,7 +1645,7 @@ hfa384x_dowmem(hfa384x_t *hw,
ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
int result;
- hfa384x_usbctlx_t *ctlx;
+ struct hfa384x_usbctlx *ctlx;
pr_debug("page=0x%04x offset=0x%04x len=%d\n", page, offset, len);
@@ -1679,7 +1679,7 @@ hfa384x_dowmem(hfa384x_t *hw,
kfree(ctlx);
} else if (mode == DOWAIT) {
struct usbctlx_cmd_completor completor;
- hfa384x_cmdresult_t wmemresult;
+ struct hfa384x_cmdresult wmemresult;
result = hfa384x_usbctlx_complete_sync(hw,
ctlx,
@@ -1715,7 +1715,7 @@ done:
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport)
+int hfa384x_drvr_disable(struct hfa384x *hw, u16 macport)
{
int result = 0;
@@ -1753,7 +1753,7 @@ int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport)
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport)
+int hfa384x_drvr_enable(struct hfa384x *hw, u16 macport)
{
int result = 0;
@@ -1790,7 +1790,7 @@ int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport)
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
+int hfa384x_drvr_flashdl_enable(struct hfa384x *hw)
{
int result = 0;
int i;
@@ -1849,7 +1849,7 @@ int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
+int hfa384x_drvr_flashdl_disable(struct hfa384x *hw)
{
/* Check that we're already in the download state */
if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
@@ -1894,7 +1894,7 @@ int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
+int hfa384x_drvr_flashdl_write(struct hfa384x *hw, u32 daddr, void *buf, u32 len)
{
int result = 0;
u32 dlbufaddr;
@@ -2032,7 +2032,7 @@ exit_proc:
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
+int hfa384x_drvr_getconfig(struct hfa384x *hw, u16 rid, void *buf, u16 len)
{
return hfa384x_dorrid_wait(hw, rid, buf, len);
}
@@ -2061,7 +2061,7 @@ int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
* process
----------------------------------------------------------------*/
int
-hfa384x_drvr_setconfig_async(hfa384x_t *hw,
+hfa384x_drvr_setconfig_async(struct hfa384x *hw,
u16 rid,
void *buf,
u16 len, ctlx_usercb_t usercb, void *usercb_data)
@@ -2088,7 +2088,7 @@ hfa384x_drvr_setconfig_async(hfa384x_t *hw,
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
+int hfa384x_drvr_ramdl_disable(struct hfa384x *hw)
{
/* Check that we're already in the download state */
if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
@@ -2128,7 +2128,7 @@ int hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
+int hfa384x_drvr_ramdl_enable(struct hfa384x *hw, u32 exeaddr)
{
int result = 0;
u16 lowaddr;
@@ -2196,7 +2196,7 @@ int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
+int hfa384x_drvr_ramdl_write(struct hfa384x *hw, u32 daddr, void *buf, u32 len)
{
int result = 0;
int nwrites;
@@ -2276,7 +2276,7 @@ int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
* Call context:
* process or non-card interrupt.
----------------------------------------------------------------*/
-int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len)
+int hfa384x_drvr_readpda(struct hfa384x *hw, void *buf, unsigned int len)
{
int result = 0;
u16 *pda = buf;
@@ -2386,7 +2386,7 @@ int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len)
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
+int hfa384x_drvr_setconfig(struct hfa384x *hw, u16 rid, void *buf, u16 len)
{
return hfa384x_dowrid_wait(hw, rid, buf, len);
}
@@ -2411,7 +2411,7 @@ int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_start(hfa384x_t *hw)
+int hfa384x_drvr_start(struct hfa384x *hw)
{
int result, result1, result2;
u16 status;
@@ -2512,7 +2512,7 @@ done:
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_stop(hfa384x_t *hw)
+int hfa384x_drvr_stop(struct hfa384x *hw)
{
int i;
@@ -2562,11 +2562,11 @@ int hfa384x_drvr_stop(hfa384x_t *hw)
* Call context:
* interrupt
----------------------------------------------------------------*/
-int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
+int hfa384x_drvr_txframe(struct hfa384x *hw, struct sk_buff *skb,
union p80211_hdr *p80211_hdr,
struct p80211_metawep *p80211_wep)
{
- int usbpktlen = sizeof(hfa384x_tx_frame_t);
+ int usbpktlen = sizeof(struct hfa384x_tx_frame);
int result;
int ret;
char *ptr;
@@ -2656,9 +2656,9 @@ exit:
return result;
}
-void hfa384x_tx_timeout(wlandevice_t *wlandev)
+void hfa384x_tx_timeout(struct wlandevice *wlandev)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
unsigned long flags;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -2681,7 +2681,7 @@ void hfa384x_tx_timeout(wlandevice_t *wlandev)
* Tasklet to delete dead CTLX objects
*
* Arguments:
-* data ptr to a hfa384x_t
+* data ptr to a struct hfa384x
*
* Returns:
*
@@ -2690,8 +2690,8 @@ void hfa384x_tx_timeout(wlandevice_t *wlandev)
----------------------------------------------------------------*/
static void hfa384x_usbctlx_reaper_task(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t *)data;
- hfa384x_usbctlx_t *ctlx, *temp;
+ struct hfa384x *hw = (struct hfa384x *)data;
+ struct hfa384x_usbctlx *ctlx, *temp;
unsigned long flags;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -2713,7 +2713,7 @@ static void hfa384x_usbctlx_reaper_task(unsigned long data)
* Tasklet to call completion handlers for returned CTLXs
*
* Arguments:
-* data ptr to hfa384x_t
+* data ptr to struct hfa384x
*
* Returns:
* Nothing
@@ -2723,8 +2723,8 @@ static void hfa384x_usbctlx_reaper_task(unsigned long data)
----------------------------------------------------------------*/
static void hfa384x_usbctlx_completion_task(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t *)data;
- hfa384x_usbctlx_t *ctlx, *temp;
+ struct hfa384x *hw = (struct hfa384x *)data;
+ struct hfa384x_usbctlx *ctlx, *temp;
unsigned long flags;
int reap = 0;
@@ -2787,7 +2787,7 @@ static void hfa384x_usbctlx_completion_task(unsigned long data)
* next command on the queue is run afterwards.
*
* Arguments:
-* hw ptr to the hfa384x_t structure
+* hw ptr to the struct hfa384x structure
* ctlx ptr to a CTLX structure
*
* Returns:
@@ -2797,8 +2797,8 @@ static void hfa384x_usbctlx_completion_task(unsigned long data)
* Call context:
* Either process or interrupt, but presumably interrupt
----------------------------------------------------------------*/
-static int unlocked_usbctlx_cancel_async(hfa384x_t *hw,
- hfa384x_usbctlx_t *ctlx)
+static int unlocked_usbctlx_cancel_async(struct hfa384x *hw,
+ struct hfa384x_usbctlx *ctlx)
{
int ret;
@@ -2836,7 +2836,7 @@ static int unlocked_usbctlx_cancel_async(hfa384x_t *hw,
* tasklet is scheduled.
*
* Arguments:
-* hw ptr to a hfa384x_t structure
+* hw ptr to a struct hfa384x structure
* ctlx ptr to a ctlx structure
*
* Returns:
@@ -2847,7 +2847,7 @@ static int unlocked_usbctlx_cancel_async(hfa384x_t *hw,
* Call context:
* Either, assume interrupt
----------------------------------------------------------------*/
-static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
+static void unlocked_usbctlx_complete(struct hfa384x *hw, struct hfa384x_usbctlx *ctlx)
{
/* Timers have been stopped, and ctlx should be in
* a terminal state. Retire it from the "active"
@@ -2876,7 +2876,7 @@ static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
* Checks to see if the head item is running. If not, starts it.
*
* Arguments:
-* hw ptr to hfa384x_t
+* hw ptr to struct hfa384x
*
* Returns:
* nothing
@@ -2886,7 +2886,7 @@ static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
* Call context:
* any
----------------------------------------------------------------*/
-static void hfa384x_usbctlxq_run(hfa384x_t *hw)
+static void hfa384x_usbctlxq_run(struct hfa384x *hw)
{
unsigned long flags;
@@ -2905,12 +2905,12 @@ static void hfa384x_usbctlxq_run(hfa384x_t *hw)
goto unlock;
while (!list_empty(&hw->ctlxq.pending)) {
- hfa384x_usbctlx_t *head;
+ struct hfa384x_usbctlx *head;
int result;
/* This is the first pending command */
head = list_entry(hw->ctlxq.pending.next,
- hfa384x_usbctlx_t, list);
+ struct hfa384x_usbctlx, list);
/* We need to split this off to avoid a race condition */
list_move_tail(&head->list, &hw->ctlxq.active);
@@ -2988,9 +2988,9 @@ unlock:
----------------------------------------------------------------*/
static void hfa384x_usbin_callback(struct urb *urb)
{
- wlandevice_t *wlandev = urb->context;
- hfa384x_t *hw;
- hfa384x_usbin_t *usbin = (hfa384x_usbin_t *)urb->transfer_buffer;
+ struct wlandevice *wlandev = urb->context;
+ struct hfa384x *hw;
+ union hfa384x_usbin *usbin = (union hfa384x_usbin *)urb->transfer_buffer;
struct sk_buff *skb = NULL;
int result;
int urb_status;
@@ -3154,7 +3154,7 @@ exit:
* queue and our state updated accordingly.
*
* Arguments:
-* hw ptr to hfa384x_t
+* hw ptr to struct hfa384x
* usbin ptr to USB IN packet
* urb_status status of this Bulk-In URB
*
@@ -3166,10 +3166,10 @@ exit:
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
+static void hfa384x_usbin_ctlx(struct hfa384x *hw, union hfa384x_usbin *usbin,
int urb_status)
{
- hfa384x_usbctlx_t *ctlx;
+ struct hfa384x_usbctlx *ctlx;
int run_queue = 0;
unsigned long flags;
@@ -3285,8 +3285,8 @@ unlock:
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void hfa384x_usbin_txcompl(wlandevice_t *wlandev,
- hfa384x_usbin_t *usbin)
+static void hfa384x_usbin_txcompl(struct wlandevice *wlandev,
+ union hfa384x_usbin *usbin)
{
u16 status;
@@ -3316,10 +3316,10 @@ static void hfa384x_usbin_txcompl(wlandevice_t *wlandev,
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
+static void hfa384x_usbin_rx(struct wlandevice *wlandev, struct sk_buff *skb)
{
- hfa384x_usbin_t *usbin = (hfa384x_usbin_t *)skb->data;
- hfa384x_t *hw = wlandev->priv;
+ union hfa384x_usbin *usbin = (union hfa384x_usbin *)skb->data;
+ struct hfa384x *hw = wlandev->priv;
int hdrlen;
struct p80211_rxmeta *rxmeta;
u16 data_len;
@@ -3346,7 +3346,7 @@ static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
hdrlen = p80211_headerlen(fc);
/* Pull off the descriptor */
- skb_pull(skb, sizeof(hfa384x_rx_frame_t));
+ skb_pull(skb, sizeof(struct hfa384x_rx_frame));
/* Now shunt the header block up against the data block
* with an "overlapping" copy
@@ -3416,17 +3416,17 @@ static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
- hfa384x_usb_rxfrm_t *rxfrm)
+static void hfa384x_int_rxmonitor(struct wlandevice *wlandev,
+ struct hfa384x_usb_rxfrm *rxfrm)
{
- hfa384x_rx_frame_t *rxdesc = &(rxfrm->desc);
+ struct hfa384x_rx_frame *rxdesc = &(rxfrm->desc);
unsigned int hdrlen = 0;
unsigned int datalen = 0;
unsigned int skblen = 0;
u8 *datap;
u16 fc;
struct sk_buff *skb;
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
/* Remember the status, time, and data_len fields are in host order */
/* Figure out how big the frame is */
@@ -3517,7 +3517,8 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
+static void hfa384x_usbin_info(struct wlandevice *wlandev,
+ union hfa384x_usbin *usbin)
{
usbin->infofrm.info.framelen =
le16_to_cpu(usbin->infofrm.info.framelen);
@@ -3542,7 +3543,7 @@ static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
----------------------------------------------------------------*/
static void hfa384x_usbout_callback(struct urb *urb)
{
- wlandevice_t *wlandev = urb->context;
+ struct wlandevice *wlandev = urb->context;
#ifdef DEBUG_USB
dbprint_urb(urb);
@@ -3556,7 +3557,7 @@ static void hfa384x_usbout_callback(struct urb *urb)
case -EPIPE:
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
netdev_warn(hw->wlandev->netdev,
"%s tx pipe stalled: requesting reset\n",
@@ -3572,7 +3573,7 @@ static void hfa384x_usbout_callback(struct urb *urb)
case -ETIMEDOUT:
case -EILSEQ:
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
if (!test_and_set_bit
(THROTTLE_TX, &hw->usb_flags) &&
@@ -3617,11 +3618,11 @@ static void hfa384x_usbout_callback(struct urb *urb)
----------------------------------------------------------------*/
static void hfa384x_ctlxout_callback(struct urb *urb)
{
- hfa384x_t *hw = urb->context;
+ struct hfa384x *hw = urb->context;
int delete_resptimer = 0;
int timer_ok = 1;
int run_queue = 0;
- hfa384x_usbctlx_t *ctlx;
+ struct hfa384x_usbctlx *ctlx;
unsigned long flags;
pr_debug("urb->status=%d\n", urb->status);
@@ -3736,7 +3737,7 @@ delresp:
* URB containing a Prism2.x XXX_Request was never called.
*
* Arguments:
-* data a ptr to the hfa384x_t
+* data a ptr to the struct hfa384x
*
* Returns:
* nothing
@@ -3748,7 +3749,7 @@ delresp:
----------------------------------------------------------------*/
static void hfa384x_usbctlx_reqtimerfn(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t *)data;
+ struct hfa384x *hw = (struct hfa384x *)data;
unsigned long flags;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3765,7 +3766,7 @@ static void hfa384x_usbctlx_reqtimerfn(unsigned long data)
*/
hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK;
if (usb_unlink_urb(&hw->ctlx_urb) == -EINPROGRESS) {
- hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
+ struct hfa384x_usbctlx *ctlx = get_active_ctlx(hw);
ctlx->state = CTLX_REQ_FAILED;
@@ -3794,7 +3795,7 @@ static void hfa384x_usbctlx_reqtimerfn(unsigned long data)
* URB containing a Prism2.x XXX_Response was never called.
*
* Arguments:
-* data a ptr to the hfa384x_t
+* data a ptr to the struct hfa384x
*
* Returns:
* nothing
@@ -3806,7 +3807,7 @@ static void hfa384x_usbctlx_reqtimerfn(unsigned long data)
----------------------------------------------------------------*/
static void hfa384x_usbctlx_resptimerfn(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t *)data;
+ struct hfa384x *hw = (struct hfa384x *)data;
unsigned long flags;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3817,7 +3818,7 @@ static void hfa384x_usbctlx_resptimerfn(unsigned long data)
* adapter has been unplugged ...
*/
if (!list_empty(&hw->ctlxq.active)) {
- hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
+ struct hfa384x_usbctlx *ctlx = get_active_ctlx(hw);
if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) {
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
@@ -3845,7 +3846,7 @@ static void hfa384x_usbctlx_resptimerfn(unsigned long data)
----------------------------------------------------------------*/
static void hfa384x_usb_throttlefn(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t *)data;
+ struct hfa384x *hw = (struct hfa384x *)data;
unsigned long flags;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3885,7 +3886,7 @@ static void hfa384x_usb_throttlefn(unsigned long data)
* Call context:
* process or interrupt
----------------------------------------------------------------*/
-static int hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
+static int hfa384x_usbctlx_submit(struct hfa384x *hw, struct hfa384x_usbctlx *ctlx)
{
unsigned long flags;
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
index 6354036ffb42..0247cbc29145 100644
--- a/drivers/staging/wlan-ng/p80211conv.c
+++ b/drivers/staging/wlan-ng/p80211conv.c
@@ -104,7 +104,7 @@ static const u8 oui_8021h[] = { 0x00, 0x00, 0xf8 };
* May be called in interrupt or non-interrupt context
*----------------------------------------------------------------
*/
-int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
+int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv,
struct sk_buff *skb, union p80211_hdr *p80211_hdr,
struct p80211_metawep *p80211_wep)
{
@@ -232,7 +232,7 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
}
/* jkriegl: from orinoco, modified */
-static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac,
+static void orinoco_spy_gather(struct wlandevice *wlandev, char *mac,
struct p80211_rxmeta *rxmeta)
{
int i;
@@ -274,10 +274,10 @@ static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac,
* May be called in interrupt or non-interrupt context
*----------------------------------------------------------------
*/
-int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
+int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv,
struct sk_buff *skb)
{
- netdevice_t *netdev = wlandev->netdev;
+ struct net_device *netdev = wlandev->netdev;
u16 fc;
unsigned int payload_length;
unsigned int payload_offset;
diff --git a/drivers/staging/wlan-ng/p80211metadef.h b/drivers/staging/wlan-ng/p80211metadef.h
index 0ccfba1294de..b0d3567ca0ad 100644
--- a/drivers/staging/wlan-ng/p80211metadef.h
+++ b/drivers/staging/wlan-ng/p80211metadef.h
@@ -155,22 +155,9 @@
#define DIDmib_dot11smt_dot11WEPDefaultKeysTable \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4))
-#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(1) | 0x0c000000)
-#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(2) | 0x0c000000)
-#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(3) | 0x0c000000)
-#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(4) | 0x0c000000)
+#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(_i) \
+ (DIDmib_dot11smt_dot11WEPDefaultKeysTable | \
+ P80211DID_MKITEM(_i) | 0x0c000000)
#define DIDmib_dot11smt_dot11PrivacyTable \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6))
diff --git a/drivers/staging/wlan-ng/p80211metastruct.h b/drivers/staging/wlan-ng/p80211metastruct.h
index c501162c3020..850d897fc163 100644
--- a/drivers/staging/wlan-ng/p80211metastruct.h
+++ b/drivers/staging/wlan-ng/p80211metastruct.h
@@ -51,221 +51,221 @@ struct p80211msg_dot11req_mibget {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_unk392_t mibattribute;
- p80211item_uint32_t resultcode;
+ struct p80211item_unk392 mibattribute;
+ struct p80211item_uint32 resultcode;
} __packed;
struct p80211msg_dot11req_mibset {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_unk392_t mibattribute;
- p80211item_uint32_t resultcode;
+ struct p80211item_unk392 mibattribute;
+ struct p80211item_uint32 resultcode;
} __packed;
struct p80211msg_dot11req_scan {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_uint32_t bsstype;
- p80211item_pstr6_t bssid;
+ struct p80211item_uint32 bsstype;
+ struct p80211item_pstr6 bssid;
u8 pad_0C[1];
- p80211item_pstr32_t ssid;
+ struct p80211item_pstr32 ssid;
u8 pad_1D[3];
- p80211item_uint32_t scantype;
- p80211item_uint32_t probedelay;
- p80211item_pstr14_t channellist;
+ struct p80211item_uint32 scantype;
+ struct p80211item_uint32 probedelay;
+ struct p80211item_pstr14 channellist;
u8 pad_2C[1];
- p80211item_uint32_t minchanneltime;
- p80211item_uint32_t maxchanneltime;
- p80211item_uint32_t resultcode;
- p80211item_uint32_t numbss;
- p80211item_uint32_t append;
+ struct p80211item_uint32 minchanneltime;
+ struct p80211item_uint32 maxchanneltime;
+ struct p80211item_uint32 resultcode;
+ struct p80211item_uint32 numbss;
+ struct p80211item_uint32 append;
} __packed;
struct p80211msg_dot11req_scan_results {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_uint32_t bssindex;
- p80211item_uint32_t resultcode;
- p80211item_uint32_t signal;
- p80211item_uint32_t noise;
- p80211item_pstr6_t bssid;
+ struct p80211item_uint32 bssindex;
+ struct p80211item_uint32 resultcode;
+ struct p80211item_uint32 signal;
+ struct p80211item_uint32 noise;
+ struct p80211item_pstr6 bssid;
u8 pad_3C[1];
- p80211item_pstr32_t ssid;
+ struct p80211item_pstr32 ssid;
u8 pad_4D[3];
- p80211item_uint32_t bsstype;
- p80211item_uint32_t beaconperiod;
- p80211item_uint32_t dtimperiod;
- p80211item_uint32_t timestamp;
- p80211item_uint32_t localtime;
- p80211item_uint32_t fhdwelltime;
- p80211item_uint32_t fhhopset;
- p80211item_uint32_t fhhoppattern;
- p80211item_uint32_t fhhopindex;
- p80211item_uint32_t dschannel;
- p80211item_uint32_t cfpcount;
- p80211item_uint32_t cfpperiod;
- p80211item_uint32_t cfpmaxduration;
- p80211item_uint32_t cfpdurremaining;
- p80211item_uint32_t ibssatimwindow;
- p80211item_uint32_t cfpollable;
- p80211item_uint32_t cfpollreq;
- p80211item_uint32_t privacy;
- p80211item_uint32_t capinfo;
- p80211item_uint32_t basicrate1;
- p80211item_uint32_t basicrate2;
- p80211item_uint32_t basicrate3;
- p80211item_uint32_t basicrate4;
- p80211item_uint32_t basicrate5;
- p80211item_uint32_t basicrate6;
- p80211item_uint32_t basicrate7;
- p80211item_uint32_t basicrate8;
- p80211item_uint32_t supprate1;
- p80211item_uint32_t supprate2;
- p80211item_uint32_t supprate3;
- p80211item_uint32_t supprate4;
- p80211item_uint32_t supprate5;
- p80211item_uint32_t supprate6;
- p80211item_uint32_t supprate7;
- p80211item_uint32_t supprate8;
+ struct p80211item_uint32 bsstype;
+ struct p80211item_uint32 beaconperiod;
+ struct p80211item_uint32 dtimperiod;
+ struct p80211item_uint32 timestamp;
+ struct p80211item_uint32 localtime;
+ struct p80211item_uint32 fhdwelltime;
+ struct p80211item_uint32 fhhopset;
+ struct p80211item_uint32 fhhoppattern;
+ struct p80211item_uint32 fhhopindex;
+ struct p80211item_uint32 dschannel;
+ struct p80211item_uint32 cfpcount;
+ struct p80211item_uint32 cfpperiod;
+ struct p80211item_uint32 cfpmaxduration;
+ struct p80211item_uint32 cfpdurremaining;
+ struct p80211item_uint32 ibssatimwindow;
+ struct p80211item_uint32 cfpollable;
+ struct p80211item_uint32 cfpollreq;
+ struct p80211item_uint32 privacy;
+ struct p80211item_uint32 capinfo;
+ struct p80211item_uint32 basicrate1;
+ struct p80211item_uint32 basicrate2;
+ struct p80211item_uint32 basicrate3;
+ struct p80211item_uint32 basicrate4;
+ struct p80211item_uint32 basicrate5;
+ struct p80211item_uint32 basicrate6;
+ struct p80211item_uint32 basicrate7;
+ struct p80211item_uint32 basicrate8;
+ struct p80211item_uint32 supprate1;
+ struct p80211item_uint32 supprate2;
+ struct p80211item_uint32 supprate3;
+ struct p80211item_uint32 supprate4;
+ struct p80211item_uint32 supprate5;
+ struct p80211item_uint32 supprate6;
+ struct p80211item_uint32 supprate7;
+ struct p80211item_uint32 supprate8;
} __packed;
struct p80211msg_dot11req_start {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_pstr32_t ssid;
+ struct p80211item_pstr32 ssid;
u8 pad_12D[3];
- p80211item_uint32_t bsstype;
- p80211item_uint32_t beaconperiod;
- p80211item_uint32_t dtimperiod;
- p80211item_uint32_t cfpperiod;
- p80211item_uint32_t cfpmaxduration;
- p80211item_uint32_t fhdwelltime;
- p80211item_uint32_t fhhopset;
- p80211item_uint32_t fhhoppattern;
- p80211item_uint32_t dschannel;
- p80211item_uint32_t ibssatimwindow;
- p80211item_uint32_t probedelay;
- p80211item_uint32_t cfpollable;
- p80211item_uint32_t cfpollreq;
- p80211item_uint32_t basicrate1;
- p80211item_uint32_t basicrate2;
- p80211item_uint32_t basicrate3;
- p80211item_uint32_t basicrate4;
- p80211item_uint32_t basicrate5;
- p80211item_uint32_t basicrate6;
- p80211item_uint32_t basicrate7;
- p80211item_uint32_t basicrate8;
- p80211item_uint32_t operationalrate1;
- p80211item_uint32_t operationalrate2;
- p80211item_uint32_t operationalrate3;
- p80211item_uint32_t operationalrate4;
- p80211item_uint32_t operationalrate5;
- p80211item_uint32_t operationalrate6;
- p80211item_uint32_t operationalrate7;
- p80211item_uint32_t operationalrate8;
- p80211item_uint32_t resultcode;
+ struct p80211item_uint32 bsstype;
+ struct p80211item_uint32 beaconperiod;
+ struct p80211item_uint32 dtimperiod;
+ struct p80211item_uint32 cfpperiod;
+ struct p80211item_uint32 cfpmaxduration;
+ struct p80211item_uint32 fhdwelltime;
+ struct p80211item_uint32 fhhopset;
+ struct p80211item_uint32 fhhoppattern;
+ struct p80211item_uint32 dschannel;
+ struct p80211item_uint32 ibssatimwindow;
+ struct p80211item_uint32 probedelay;
+ struct p80211item_uint32 cfpollable;
+ struct p80211item_uint32 cfpollreq;
+ struct p80211item_uint32 basicrate1;
+ struct p80211item_uint32 basicrate2;
+ struct p80211item_uint32 basicrate3;
+ struct p80211item_uint32 basicrate4;
+ struct p80211item_uint32 basicrate5;
+ struct p80211item_uint32 basicrate6;
+ struct p80211item_uint32 basicrate7;
+ struct p80211item_uint32 basicrate8;
+ struct p80211item_uint32 operationalrate1;
+ struct p80211item_uint32 operationalrate2;
+ struct p80211item_uint32 operationalrate3;
+ struct p80211item_uint32 operationalrate4;
+ struct p80211item_uint32 operationalrate5;
+ struct p80211item_uint32 operationalrate6;
+ struct p80211item_uint32 operationalrate7;
+ struct p80211item_uint32 operationalrate8;
+ struct p80211item_uint32 resultcode;
} __packed;
struct p80211msg_lnxreq_ifstate {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_uint32_t ifstate;
- p80211item_uint32_t resultcode;
+ struct p80211item_uint32 ifstate;
+ struct p80211item_uint32 resultcode;
} __packed;
struct p80211msg_lnxreq_wlansniff {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_uint32_t enable;
- p80211item_uint32_t channel;
- p80211item_uint32_t prismheader;
- p80211item_uint32_t wlanheader;
- p80211item_uint32_t keepwepflags;
- p80211item_uint32_t stripfcs;
- p80211item_uint32_t packet_trunc;
- p80211item_uint32_t resultcode;
+ struct p80211item_uint32 enable;
+ struct p80211item_uint32 channel;
+ struct p80211item_uint32 prismheader;
+ struct p80211item_uint32 wlanheader;
+ struct p80211item_uint32 keepwepflags;
+ struct p80211item_uint32 stripfcs;
+ struct p80211item_uint32 packet_trunc;
+ struct p80211item_uint32 resultcode;
} __packed;
struct p80211msg_lnxreq_hostwep {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_uint32_t resultcode;
- p80211item_uint32_t decrypt;
- p80211item_uint32_t encrypt;
+ struct p80211item_uint32 resultcode;
+ struct p80211item_uint32 decrypt;
+ struct p80211item_uint32 encrypt;
} __packed;
struct p80211msg_lnxreq_commsquality {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_uint32_t resultcode;
- p80211item_uint32_t dbm;
- p80211item_uint32_t link;
- p80211item_uint32_t level;
- p80211item_uint32_t noise;
- p80211item_uint32_t txrate;
+ struct p80211item_uint32 resultcode;
+ struct p80211item_uint32 dbm;
+ struct p80211item_uint32 link;
+ struct p80211item_uint32 level;
+ struct p80211item_uint32 noise;
+ struct p80211item_uint32 txrate;
} __packed;
struct p80211msg_lnxreq_autojoin {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_pstr32_t ssid;
+ struct p80211item_pstr32 ssid;
u8 pad_19D[3];
- p80211item_uint32_t authtype;
- p80211item_uint32_t resultcode;
+ struct p80211item_uint32 authtype;
+ struct p80211item_uint32 resultcode;
} __packed;
struct p80211msg_p2req_readpda {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_unk1024_t pda;
- p80211item_uint32_t resultcode;
+ struct p80211item_unk1024 pda;
+ struct p80211item_uint32 resultcode;
} __packed;
struct p80211msg_p2req_ramdl_state {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_uint32_t enable;
- p80211item_uint32_t exeaddr;
- p80211item_uint32_t resultcode;
+ struct p80211item_uint32 enable;
+ struct p80211item_uint32 exeaddr;
+ struct p80211item_uint32 resultcode;
} __packed;
struct p80211msg_p2req_ramdl_write {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_uint32_t addr;
- p80211item_uint32_t len;
- p80211item_unk4096_t data;
- p80211item_uint32_t resultcode;
+ struct p80211item_uint32 addr;
+ struct p80211item_uint32 len;
+ struct p80211item_unk4096 data;
+ struct p80211item_uint32 resultcode;
} __packed;
struct p80211msg_p2req_flashdl_state {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_uint32_t enable;
- p80211item_uint32_t resultcode;
+ struct p80211item_uint32 enable;
+ struct p80211item_uint32 resultcode;
} __packed;
struct p80211msg_p2req_flashdl_write {
u32 msgcode;
u32 msglen;
u8 devname[WLAN_DEVNAMELEN_MAX];
- p80211item_uint32_t addr;
- p80211item_uint32_t len;
- p80211item_unk4096_t data;
- p80211item_uint32_t resultcode;
+ struct p80211item_uint32 addr;
+ struct p80211item_uint32 len;
+ struct p80211item_unk4096 data;
+ struct p80211item_uint32 resultcode;
} __packed;
#endif
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
index 90cc8cdcf969..825a63a7c0e3 100644
--- a/drivers/staging/wlan-ng/p80211netdev.c
+++ b/drivers/staging/wlan-ng/p80211netdev.c
@@ -91,17 +91,17 @@
#include "cfg80211.c"
/* netdevice method functions */
-static int p80211knetdev_init(netdevice_t *netdev);
-static int p80211knetdev_open(netdevice_t *netdev);
-static int p80211knetdev_stop(netdevice_t *netdev);
+static int p80211knetdev_init(struct net_device *netdev);
+static int p80211knetdev_open(struct net_device *netdev);
+static int p80211knetdev_stop(struct net_device *netdev);
static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
- netdevice_t *netdev);
-static void p80211knetdev_set_multicast_list(netdevice_t *dev);
-static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr,
+ struct net_device *netdev);
+static void p80211knetdev_set_multicast_list(struct net_device *dev);
+static int p80211knetdev_do_ioctl(struct net_device *dev, struct ifreq *ifr,
int cmd);
-static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr);
-static void p80211knetdev_tx_timeout(netdevice_t *netdev);
-static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc);
+static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr);
+static void p80211knetdev_tx_timeout(struct net_device *netdev);
+static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc);
int wlan_watchdog = 5000;
module_param(wlan_watchdog, int, 0644);
@@ -123,7 +123,7 @@ MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions");
* Returns:
* nothing
----------------------------------------------------------------*/
-static int p80211knetdev_init(netdevice_t *netdev)
+static int p80211knetdev_init(struct net_device *netdev)
{
/* Called in response to register_netdev */
/* This is usually the probe function, but the probe has */
@@ -146,10 +146,10 @@ static int p80211knetdev_init(netdevice_t *netdev)
* Returns:
* zero on success, non-zero otherwise
----------------------------------------------------------------*/
-static int p80211knetdev_open(netdevice_t *netdev)
+static int p80211knetdev_open(struct net_device *netdev)
{
int result = 0; /* success */
- wlandevice_t *wlandev = netdev->ml_priv;
+ struct wlandevice *wlandev = netdev->ml_priv;
/* Check to make sure the MSD is running */
if (wlandev->msdstate != WLAN_MSD_RUNNING)
@@ -181,10 +181,10 @@ static int p80211knetdev_open(netdevice_t *netdev)
* Returns:
* zero on success, non-zero otherwise
----------------------------------------------------------------*/
-static int p80211knetdev_stop(netdevice_t *netdev)
+static int p80211knetdev_stop(struct net_device *netdev)
{
int result = 0;
- wlandevice_t *wlandev = netdev->ml_priv;
+ struct wlandevice *wlandev = netdev->ml_priv;
if (wlandev->close)
result = wlandev->close(wlandev);
@@ -208,7 +208,7 @@ static int p80211knetdev_stop(netdevice_t *netdev)
* Side effects:
*
----------------------------------------------------------------*/
-void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
+void p80211netdev_rx(struct wlandevice *wlandev, struct sk_buff *skb)
{
/* Enqueue for post-irq processing */
skb_queue_tail(&wlandev->nsd_rxq, skb);
@@ -227,11 +227,11 @@ void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
* CONV_TO_ETHER_FAILED if conversion failed
* CONV_TO_ETHER_SKIPPED if frame is ignored
*/
-static int p80211_convert_to_ether(wlandevice_t *wlandev, struct sk_buff *skb)
+static int p80211_convert_to_ether(struct wlandevice *wlandev, struct sk_buff *skb)
{
struct p80211_hdr_a3 *hdr;
- hdr = (struct p80211_hdr_a3 *) skb->data;
+ hdr = (struct p80211_hdr_a3 *)skb->data;
if (p80211_rx_typedrop(wlandev, hdr->fc))
return CONV_TO_ETHER_SKIPPED;
@@ -265,9 +265,9 @@ static int p80211_convert_to_ether(wlandevice_t *wlandev, struct sk_buff *skb)
*/
static void p80211netdev_rx_bh(unsigned long arg)
{
- wlandevice_t *wlandev = (wlandevice_t *) arg;
+ struct wlandevice *wlandev = (struct wlandevice *)arg;
struct sk_buff *skb = NULL;
- netdevice_t *dev = wlandev->netdev;
+ struct net_device *dev = wlandev->netdev;
/* Let's empty our our queue */
while ((skb = skb_dequeue(&wlandev->nsd_rxq))) {
@@ -318,11 +318,11 @@ static void p80211netdev_rx_bh(unsigned long arg)
* zero on success, non-zero on failure.
----------------------------------------------------------------*/
static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
- netdevice_t *netdev)
+ struct net_device *netdev)
{
int result = 0;
int txresult = -1;
- wlandevice_t *wlandev = netdev->ml_priv;
+ struct wlandevice *wlandev = netdev->ml_priv;
union p80211_hdr p80211_hdr;
struct p80211_metawep p80211_wep;
@@ -446,9 +446,9 @@ failed:
* Returns:
* nothing
----------------------------------------------------------------*/
-static void p80211knetdev_set_multicast_list(netdevice_t *dev)
+static void p80211knetdev_set_multicast_list(struct net_device *dev)
{
- wlandevice_t *wlandev = dev->ml_priv;
+ struct wlandevice *wlandev = dev->ml_priv;
/* TODO: real multicast support as well */
@@ -459,7 +459,7 @@ static void p80211knetdev_set_multicast_list(netdevice_t *dev)
#ifdef SIOCETHTOOL
-static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
+static int p80211netdev_ethtool(struct wlandevice *wlandev, void __user *useraddr)
{
u32 ethcmd;
struct ethtool_drvinfo info;
@@ -531,11 +531,11 @@ static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
* Process thread (ioctl caller). TODO: SMP support may require
* locks.
----------------------------------------------------------------*/
-static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
+static int p80211knetdev_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
int result = 0;
- struct p80211ioctl_req *req = (struct p80211ioctl_req *) ifr;
- wlandevice_t *wlandev = dev->ml_priv;
+ struct p80211ioctl_req *req = (struct p80211ioctl_req *)ifr;
+ struct wlandevice *wlandev = dev->ml_priv;
u8 *msgbuf;
netdev_dbg(dev, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
@@ -610,13 +610,13 @@ bail:
*
* by: Collin R. Mulliner <collin@mulliner.org>
----------------------------------------------------------------*/
-static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
+static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr)
{
struct sockaddr *new_addr = addr;
struct p80211msg_dot11req_mibset dot11req;
- p80211item_unk392_t *mibattr;
- p80211item_pstr6_t *macaddr;
- p80211item_uint32_t *resultcode;
+ struct p80211item_unk392 *mibattr;
+ struct p80211item_pstr6 *macaddr;
+ struct p80211item_uint32 *resultcode;
int result;
/* If we're running, we don't allow MAC address changes */
@@ -625,7 +625,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
/* Set up some convenience pointers. */
mibattr = &dot11req.mibattribute;
- macaddr = (p80211item_pstr6_t *) &mibattr->data;
+ macaddr = (struct p80211item_pstr6 *)&mibattr->data;
resultcode = &dot11req.resultcode;
/* Set up a dot11req_mibset */
@@ -633,7 +633,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
dot11req.msgcode = DIDmsg_dot11req_mibset;
dot11req.msglen = sizeof(struct p80211msg_dot11req_mibset);
memcpy(dot11req.devname,
- ((wlandevice_t *) dev->ml_priv)->name, WLAN_DEVNAMELEN_MAX - 1);
+ ((struct wlandevice *)dev->ml_priv)->name, WLAN_DEVNAMELEN_MAX - 1);
/* Set up the mibattribute argument */
mibattr->did = DIDmsg_dot11req_mibset_mibattribute;
@@ -653,7 +653,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
resultcode->data = 0;
/* now fire the request */
- result = p80211req_dorequest(dev->ml_priv, (u8 *) &dot11req);
+ result = p80211req_dorequest(dev->ml_priv, (u8 *)&dot11req);
/* If the request wasn't successful, report an error and don't
* change the netdev address
@@ -669,7 +669,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
return result;
}
-static int wlan_change_mtu(netdevice_t *dev, int new_mtu)
+static int wlan_change_mtu(struct net_device *dev, int new_mtu)
{
/* 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap)
and another 8 for wep. */
@@ -717,10 +717,10 @@ static const struct net_device_ops p80211_netdev_ops = {
* compiled drivers, this function will be called in the
* context of the kernel startup code.
----------------------------------------------------------------*/
-int wlan_setup(wlandevice_t *wlandev, struct device *physdev)
+int wlan_setup(struct wlandevice *wlandev, struct device *physdev)
{
int result = 0;
- netdevice_t *netdev;
+ struct net_device *netdev;
struct wiphy *wiphy;
struct wireless_dev *wdev;
@@ -783,7 +783,7 @@ int wlan_setup(wlandevice_t *wlandev, struct device *physdev)
* compiled drivers, this function will be called in the
* context of the kernel startup code.
----------------------------------------------------------------*/
-void wlan_unsetup(wlandevice_t *wlandev)
+void wlan_unsetup(struct wlandevice *wlandev)
{
struct wireless_dev *wdev;
@@ -817,7 +817,7 @@ void wlan_unsetup(wlandevice_t *wlandev)
* Call Context:
* Can be either interrupt or not.
----------------------------------------------------------------*/
-int register_wlandev(wlandevice_t *wlandev)
+int register_wlandev(struct wlandevice *wlandev)
{
return register_netdev(wlandev->netdev);
}
@@ -839,7 +839,7 @@ int register_wlandev(wlandevice_t *wlandev)
* Call Context:
* Can be either interrupt or not.
----------------------------------------------------------------*/
-int unregister_wlandev(wlandevice_t *wlandev)
+int unregister_wlandev(struct wlandevice *wlandev)
{
struct sk_buff *skb;
@@ -882,7 +882,7 @@ int unregister_wlandev(wlandevice_t *wlandev)
* Call context:
* Usually interrupt.
----------------------------------------------------------------*/
-void p80211netdev_hwremoved(wlandevice_t *wlandev)
+void p80211netdev_hwremoved(struct wlandevice *wlandev)
{
wlandev->hwremoved = 1;
if (wlandev->state == WLAN_DEVICE_OPEN)
@@ -912,7 +912,7 @@ void p80211netdev_hwremoved(wlandevice_t *wlandev)
* Call context:
* interrupt
----------------------------------------------------------------*/
-static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc)
+static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc)
{
u16 ftype;
u16 fstype;
@@ -1071,9 +1071,9 @@ static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc)
return drop;
}
-static void p80211knetdev_tx_timeout(netdevice_t *netdev)
+static void p80211knetdev_tx_timeout(struct net_device *netdev)
{
- wlandevice_t *wlandev = netdev->ml_priv;
+ struct wlandevice *wlandev = netdev->ml_priv;
if (wlandev->tx_timeout) {
wlandev->tx_timeout(wlandev);
diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h
index 820a0e20a941..1e6a774fc7c5 100644
--- a/drivers/staging/wlan-ng/p80211netdev.h
+++ b/drivers/staging/wlan-ng/p80211netdev.h
@@ -57,9 +57,6 @@
#include <linux/wireless.h>
#include <linux/netdevice.h>
-#undef netdevice_t
-typedef struct net_device netdevice_t;
-
#define WLAN_RELEASE "0.3.0-staging"
#define WLAN_DEVICE_CLOSED 0
@@ -101,7 +98,7 @@ typedef struct net_device netdevice_t;
#define P80211_NSDCAP_NOSCAN 0x200 /* nsd can scan */
/* Received frame statistics */
-typedef struct p80211_frmrx_t {
+struct p80211_frmrx {
u32 mgmt;
u32 assocreq;
u32 assocresp;
@@ -135,10 +132,10 @@ typedef struct p80211_frmrx_t {
u32 data_unknown;
u32 decrypt;
u32 decrypt_err;
-} p80211_frmrx_t;
+};
/* called by /proc/net/wireless */
-struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t *dev);
+struct iw_statistics *p80211wext_get_wireless_stats(struct net_device *dev);
/* wireless extensions' ioctls */
extern struct iw_handler_def p80211wext_handler_def;
@@ -157,7 +154,7 @@ extern int wlan_watchdog;
extern int wlan_wext_write;
/* WLAN device type */
-typedef struct wlandevice {
+struct wlandevice {
void *priv; /* private data for MSD */
/* Subsystem State */
@@ -186,12 +183,12 @@ typedef struct wlandevice {
struct p80211_metawep *p80211_wep);
int (*mlmerequest)(struct wlandevice *wlandev, struct p80211msg *msg);
int (*set_multicast_list)(struct wlandevice *wlandev,
- netdevice_t *dev);
+ struct net_device *dev);
void (*tx_timeout)(struct wlandevice *wlandev);
/* 802.11 State */
u8 bssid[WLAN_BSSID_LEN];
- p80211pstr32_t ssid;
+ struct p80211pstr32 ssid;
u32 macmode;
int linkstatus;
@@ -206,7 +203,7 @@ typedef struct wlandevice {
/* netlink socket */
/* queue for indications waiting for cmd completion */
/* Linux netdevice and support */
- netdevice_t *netdev; /* ptr to linux netdevice */
+ struct net_device *netdev; /* ptr to linux netdevice */
/* Rx bottom half */
struct tasklet_struct rx_bh;
@@ -214,7 +211,7 @@ typedef struct wlandevice {
struct sk_buff_head nsd_rxq;
/* 802.11 device statistics */
- struct p80211_frmrx_t rx;
+ struct p80211_frmrx rx;
struct iw_statistics wstats;
@@ -222,19 +219,19 @@ typedef struct wlandevice {
u8 spy_number;
char spy_address[IW_MAX_SPY][ETH_ALEN];
struct iw_quality spy_stat[IW_MAX_SPY];
-} wlandevice_t;
+};
/* WEP stuff */
-int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen);
-int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
- u8 *iv, u8 *icv);
-int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
+int wep_change_key(struct wlandevice *wlandev, int keynum, u8 *key, int keylen);
+int wep_decrypt(struct wlandevice *wlandev, u8 *buf, u32 len, int key_override,
u8 *iv, u8 *icv);
-
-int wlan_setup(wlandevice_t *wlandev, struct device *physdev);
-void wlan_unsetup(wlandevice_t *wlandev);
-int register_wlandev(wlandevice_t *wlandev);
-int unregister_wlandev(wlandevice_t *wlandev);
-void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
-void p80211netdev_hwremoved(wlandevice_t *wlandev);
+int wep_encrypt(struct wlandevice *wlandev, u8 *buf, u8 *dst, u32 len,
+ int keynum, u8 *iv, u8 *icv);
+
+int wlan_setup(struct wlandevice *wlandev, struct device *physdev);
+void wlan_unsetup(struct wlandevice *wlandev);
+int register_wlandev(struct wlandevice *wlandev);
+int unregister_wlandev(struct wlandevice *wlandev);
+void p80211netdev_rx(struct wlandevice *wlandev, struct sk_buff *skb);
+void p80211netdev_hwremoved(struct wlandevice *wlandev);
#endif
diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c
index 4b84b568f6ca..d43e85b5d49b 100644
--- a/drivers/staging/wlan-ng/p80211req.c
+++ b/drivers/staging/wlan-ng/p80211req.c
@@ -72,11 +72,26 @@
#include "p80211metastruct.h"
#include "p80211req.h"
-static void p80211req_handlemsg(wlandevice_t *wlandev, struct p80211msg *msg);
-static void p80211req_mibset_mibget(wlandevice_t *wlandev,
+static void p80211req_handlemsg(struct wlandevice *wlandev, struct p80211msg *msg);
+static void p80211req_mibset_mibget(struct wlandevice *wlandev,
struct p80211msg_dot11req_mibget *mib_msg,
int isget);
+static void p80211req_handle_action(struct wlandevice *wlandev, u32 *data,
+ int isget, u32 flag)
+{
+ if (isget) {
+ if (wlandev->hostwep & flag)
+ *data = P80211ENUM_truth_true;
+ else
+ *data = P80211ENUM_truth_false;
+ } else {
+ wlandev->hostwep &= ~flag;
+ if (*data == P80211ENUM_truth_true)
+ wlandev->hostwep |= flag;
+ }
+}
+
/*----------------------------------------------------------------
* p80211req_dorequest
*
@@ -93,9 +108,9 @@ static void p80211req_mibset_mibget(wlandevice_t *wlandev,
* Potentially blocks the caller, so it's a good idea to
* not call this function from an interrupt context.
----------------------------------------------------------------*/
-int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf)
+int p80211req_dorequest(struct wlandevice *wlandev, u8 *msgbuf)
{
- struct p80211msg *msg = (struct p80211msg *) msgbuf;
+ struct p80211msg *msg = (struct p80211msg *)msgbuf;
/* Check to make sure the MSD is running */
if (!((wlandev->msdstate == WLAN_MSD_HWPRESENT &&
@@ -149,13 +164,13 @@ int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf)
* Call context:
* Process thread
----------------------------------------------------------------*/
-static void p80211req_handlemsg(wlandevice_t *wlandev, struct p80211msg *msg)
+static void p80211req_handlemsg(struct wlandevice *wlandev, struct p80211msg *msg)
{
switch (msg->msgcode) {
case DIDmsg_lnxreq_hostwep:{
struct p80211msg_lnxreq_hostwep *req =
- (struct p80211msg_lnxreq_hostwep *) msg;
+ (struct p80211msg_lnxreq_hostwep *)msg;
wlandev->hostwep &=
~(HOSTWEP_DECRYPT | HOSTWEP_ENCRYPT);
if (req->decrypt.data == P80211ENUM_truth_true)
@@ -169,44 +184,34 @@ static void p80211req_handlemsg(wlandevice_t *wlandev, struct p80211msg *msg)
case DIDmsg_dot11req_mibset:{
int isget = (msg->msgcode == DIDmsg_dot11req_mibget);
struct p80211msg_dot11req_mibget *mib_msg =
- (struct p80211msg_dot11req_mibget *) msg;
+ (struct p80211msg_dot11req_mibget *)msg;
p80211req_mibset_mibget(wlandev, mib_msg, isget);
break;
}
} /* switch msg->msgcode */
}
-static void p80211req_mibset_mibget(wlandevice_t *wlandev,
+static void p80211req_mibset_mibget(struct wlandevice *wlandev,
struct p80211msg_dot11req_mibget *mib_msg,
int isget)
{
- p80211itemd_t *mibitem = (p80211itemd_t *) mib_msg->mibattribute.data;
- p80211pstrd_t *pstr = (p80211pstrd_t *) mibitem->data;
- u8 *key = mibitem->data + sizeof(p80211pstrd_t);
+ struct p80211itemd *mibitem = (struct p80211itemd *)mib_msg->mibattribute.data;
+ struct p80211pstrd *pstr = (struct p80211pstrd *)mibitem->data;
+ u8 *key = mibitem->data + sizeof(struct p80211pstrd);
switch (mibitem->did) {
- case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0:{
- if (!isget)
- wep_change_key(wlandev, 0, key, pstr->len);
- break;
- }
- case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1:{
- if (!isget)
- wep_change_key(wlandev, 1, key, pstr->len);
- break;
- }
- case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2:{
- if (!isget)
- wep_change_key(wlandev, 2, key, pstr->len);
- break;
- }
- case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3:{
+ case DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(1):
+ case DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(2):
+ case DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(3):
+ case DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(4):
if (!isget)
- wep_change_key(wlandev, 3, key, pstr->len);
- break;
- }
+ wep_change_key(wlandev,
+ P80211DID_ITEM(mibitem->did) - 1,
+ key, pstr->len);
+ break;
+
case DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID:{
- u32 *data = (u32 *) mibitem->data;
+ u32 *data = (u32 *)mibitem->data;
if (isget) {
*data = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
@@ -217,33 +222,17 @@ static void p80211req_mibset_mibget(wlandevice_t *wlandev,
break;
}
case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked:{
- u32 *data = (u32 *) mibitem->data;
+ u32 *data = (u32 *)mibitem->data;
- if (isget) {
- if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
- *data = P80211ENUM_truth_true;
- else
- *data = P80211ENUM_truth_false;
- } else {
- wlandev->hostwep &= ~(HOSTWEP_PRIVACYINVOKED);
- if (*data == P80211ENUM_truth_true)
- wlandev->hostwep |= HOSTWEP_PRIVACYINVOKED;
- }
+ p80211req_handle_action(wlandev, data, isget,
+ HOSTWEP_PRIVACYINVOKED);
break;
}
case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted:{
- u32 *data = (u32 *) mibitem->data;
+ u32 *data = (u32 *)mibitem->data;
- if (isget) {
- if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)
- *data = P80211ENUM_truth_true;
- else
- *data = P80211ENUM_truth_false;
- } else {
- wlandev->hostwep &= ~(HOSTWEP_EXCLUDEUNENCRYPTED);
- if (*data == P80211ENUM_truth_true)
- wlandev->hostwep |= HOSTWEP_EXCLUDEUNENCRYPTED;
- }
+ p80211req_handle_action(wlandev, data, isget,
+ HOSTWEP_EXCLUDEUNENCRYPTED);
break;
}
}
diff --git a/drivers/staging/wlan-ng/p80211req.h b/drivers/staging/wlan-ng/p80211req.h
index a95a45a6814d..8d3054c22a05 100644
--- a/drivers/staging/wlan-ng/p80211req.h
+++ b/drivers/staging/wlan-ng/p80211req.h
@@ -48,6 +48,6 @@
#ifndef _LINUX_P80211REQ_H
#define _LINUX_P80211REQ_H
-int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf);
+int p80211req_dorequest(struct wlandevice *wlandev, u8 *msgbuf);
#endif
diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h
index 8cb4fc6448a0..263ef2ddb197 100644
--- a/drivers/staging/wlan-ng/p80211types.h
+++ b/drivers/staging/wlan-ng/p80211types.h
@@ -1,58 +1,59 @@
-/* p80211types.h
-*
-* Macros, constants, types, and funcs for p80211 data types
-*
-* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
-* --------------------------------------------------------------------
-*
-* linux-wlan
-*
-* The contents of this file are subject to the Mozilla Public
-* License Version 1.1 (the "License"); you may not use this file
-* except in compliance with the License. You may obtain a copy of
-* the License at http://www.mozilla.org/MPL/
-*
-* Software distributed under the License is distributed on an "AS
-* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-* implied. See the License for the specific language governing
-* rights and limitations under the License.
-*
-* Alternatively, the contents of this file may be used under the
-* terms of the GNU Public License version 2 (the "GPL"), in which
-* case the provisions of the GPL are applicable instead of the
-* above. If you wish to allow the use of your version of this file
-* only under the terms of the GPL and not to allow others to use
-* your version of this file under the MPL, indicate your decision
-* by deleting the provisions above and replace them with the notice
-* and other provisions required by the GPL. If you do not delete
-* the provisions above, a recipient may use your version of this
-* file under either the MPL or the GPL.
-*
-* --------------------------------------------------------------------
-*
-* Inquiries regarding the linux-wlan Open Source project can be
-* made directly to:
-*
-* AbsoluteValue Systems Inc.
-* info@linux-wlan.com
-* http://www.linux-wlan.com
-*
-* --------------------------------------------------------------------
-*
-* Portions of the development of this software were funded by
-* Intersil Corporation as part of PRISM(R) chipset product development.
-*
-* --------------------------------------------------------------------
-*
-* This file declares some of the constants and types used in various
-* parts of the linux-wlan system.
-*
-* Notes:
-* - Constant values are always in HOST byte order.
-*
-* All functions and statics declared here are implemented in p80211types.c
-* --------------------------------------------------------------------
-*/
+/*
+ * p80211types.h
+ *
+ * Macros, constants, types, and funcs for p80211 data types
+ *
+ * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+ * --------------------------------------------------------------------
+ *
+ * linux-wlan
+ *
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU Public License version 2 (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of the
+ * above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use
+ * your version of this file under the MPL, indicate your decision
+ * by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete
+ * the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * --------------------------------------------------------------------
+ *
+ * Inquiries regarding the linux-wlan Open Source project can be
+ * made directly to:
+ *
+ * AbsoluteValue Systems Inc.
+ * info@linux-wlan.com
+ * http://www.linux-wlan.com
+ *
+ * --------------------------------------------------------------------
+ *
+ * Portions of the development of this software were funded by
+ * Intersil Corporation as part of PRISM(R) chipset product development.
+ *
+ * --------------------------------------------------------------------
+ *
+ * This file declares some of the constants and types used in various
+ * parts of the linux-wlan system.
+ *
+ * Notes:
+ * - Constant values are always in HOST byte order.
+ *
+ * All functions and statics declared here are implemented in p80211types.c
+ * --------------------------------------------------------------------
+ */
#ifndef _P80211TYPES_H
#define _P80211TYPES_H
@@ -123,18 +124,18 @@
#define MKENUMNAME(name) p80211enum_ ## name
/*----------------------------------------------------------------
-* The following constants and macros are used to construct and
-* deconstruct the Data ID codes. The coding is as follows:
-*
-* ...rwtnnnnnnnniiiiiiggggggssssss s - Section
-* g - Group
-* i - Item
-* n - Index
-* t - Table flag
-* w - Write flag
-* r - Read flag
-* . - Unused
-*/
+ * The following constants and macros are used to construct and
+ * deconstruct the Data ID codes. The coding is as follows:
+ *
+ * ...rwtnnnnnnnniiiiiiggggggssssss s - Section
+ * g - Group
+ * i - Item
+ * n - Index
+ * t - Table flag
+ * w - Write flag
+ * r - Read flag
+ * . - Unused
+ */
#define P80211DID_LSB_SECTION (0)
#define P80211DID_LSB_GROUP (6)
@@ -200,138 +201,138 @@
/* The following structure types are used for the representation */
/* of ENUMint type metadata. */
-typedef struct p80211enumpair {
+struct p80211enumpair {
u32 val;
char *name;
-} p80211enumpair_t;
+};
-typedef struct p80211enum {
+struct p80211enum {
int nitems;
- p80211enumpair_t *list;
-} p80211enum_t;
+ struct p80211enumpair *list;
+};
/*----------------------------------------------------------------*/
/* The following structure types are used to store data items in */
/* messages. */
/* Template pascal string */
-typedef struct p80211pstr {
+struct p80211pstr {
u8 len;
-} __packed p80211pstr_t;
+} __packed;
-typedef struct p80211pstrd {
+struct p80211pstrd {
u8 len;
u8 data[0];
-} __packed p80211pstrd_t;
+} __packed;
/* Maximum pascal string */
-typedef struct p80211pstr255 {
+struct p80211pstr255 {
u8 len;
u8 data[MAXLEN_PSTR255];
-} __packed p80211pstr255_t;
+} __packed;
/* pascal string for macaddress and bssid */
-typedef struct p80211pstr6 {
+struct p80211pstr6 {
u8 len;
u8 data[MAXLEN_PSTR6];
-} __packed p80211pstr6_t;
+} __packed;
/* pascal string for channel list */
-typedef struct p80211pstr14 {
+struct p80211pstr14 {
u8 len;
u8 data[MAXLEN_PSTR14];
-} __packed p80211pstr14_t;
+} __packed;
/* pascal string for ssid */
-typedef struct p80211pstr32 {
+struct p80211pstr32 {
u8 len;
u8 data[MAXLEN_PSTR32];
-} __packed p80211pstr32_t;
+} __packed;
/* MAC address array */
-typedef struct p80211macarray {
+struct p80211macarray {
u32 cnt;
u8 data[1][MAXLEN_PSTR6];
-} __packed p80211macarray_t;
+} __packed;
/* prototype template */
-typedef struct p80211item {
+struct p80211item {
u32 did;
u16 status;
u16 len;
-} __packed p80211item_t;
+} __packed;
/* prototype template w/ data item */
-typedef struct p80211itemd {
+struct p80211itemd {
u32 did;
u16 status;
u16 len;
u8 data[0];
-} __packed p80211itemd_t;
+} __packed;
/* message data item for int, BOUNDEDINT, ENUMINT */
-typedef struct p80211item_uint32 {
+struct p80211item_uint32 {
u32 did;
u16 status;
u16 len;
u32 data;
-} __packed p80211item_uint32_t;
+} __packed;
/* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr6 {
+struct p80211item_pstr6 {
u32 did;
u16 status;
u16 len;
- p80211pstr6_t data;
-} __packed p80211item_pstr6_t;
+ struct p80211pstr6 data;
+} __packed;
/* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr14 {
+struct p80211item_pstr14 {
u32 did;
u16 status;
u16 len;
- p80211pstr14_t data;
-} __packed p80211item_pstr14_t;
+ struct p80211pstr14 data;
+} __packed;
/* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr32 {
+struct p80211item_pstr32 {
u32 did;
u16 status;
u16 len;
- p80211pstr32_t data;
-} __packed p80211item_pstr32_t;
+ struct p80211pstr32 data;
+} __packed;
/* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr255 {
+struct p80211item_pstr255 {
u32 did;
u16 status;
u16 len;
- p80211pstr255_t data;
-} __packed p80211item_pstr255_t;
+ struct p80211pstr255 data;
+} __packed;
/* message data item for UNK 392, namely mib items */
-typedef struct p80211item_unk392 {
+struct p80211item_unk392 {
u32 did;
u16 status;
u16 len;
u8 data[MAXLEN_MIBATTRIBUTE];
-} __packed p80211item_unk392_t;
+} __packed;
/* message data item for UNK 1025, namely p2 pdas */
-typedef struct p80211item_unk1024 {
+struct p80211item_unk1024 {
u32 did;
u16 status;
u16 len;
u8 data[1024];
-} __packed p80211item_unk1024_t;
+} __packed;
/* message data item for UNK 4096, namely p2 download chunks */
-typedef struct p80211item_unk4096 {
+struct p80211item_unk4096 {
u32 did;
u16 status;
u16 len;
u8 data[4096];
-} __packed p80211item_unk4096_t;
+} __packed;
struct catlistitem;
@@ -351,25 +352,25 @@ typedef u32(*p80211_valid_t) (struct catlistitem *, u32 did, u8 *itembuf);
/* The following are the external declarations */
/* for all enumerations */
-extern p80211enum_t MKENUMNAME(truth);
-extern p80211enum_t MKENUMNAME(ifstate);
-extern p80211enum_t MKENUMNAME(powermgmt);
-extern p80211enum_t MKENUMNAME(bsstype);
-extern p80211enum_t MKENUMNAME(authalg);
-extern p80211enum_t MKENUMNAME(phytype);
-extern p80211enum_t MKENUMNAME(temptype);
-extern p80211enum_t MKENUMNAME(regdomain);
-extern p80211enum_t MKENUMNAME(ccamode);
-extern p80211enum_t MKENUMNAME(diversity);
-extern p80211enum_t MKENUMNAME(scantype);
-extern p80211enum_t MKENUMNAME(resultcode);
-extern p80211enum_t MKENUMNAME(reason);
-extern p80211enum_t MKENUMNAME(status);
-extern p80211enum_t MKENUMNAME(msgcode);
-extern p80211enum_t MKENUMNAME(msgitem_status);
-
-extern p80211enum_t MKENUMNAME(lnxroam_reason);
-
-extern p80211enum_t MKENUMNAME(p2preamble);
+extern struct p80211enum MKENUMNAME(truth);
+extern struct p80211enum MKENUMNAME(ifstate);
+extern struct p80211enum MKENUMNAME(powermgmt);
+extern struct p80211enum MKENUMNAME(bsstype);
+extern struct p80211enum MKENUMNAME(authalg);
+extern struct p80211enum MKENUMNAME(phytype);
+extern struct p80211enum MKENUMNAME(temptype);
+extern struct p80211enum MKENUMNAME(regdomain);
+extern struct p80211enum MKENUMNAME(ccamode);
+extern struct p80211enum MKENUMNAME(diversity);
+extern struct p80211enum MKENUMNAME(scantype);
+extern struct p80211enum MKENUMNAME(resultcode);
+extern struct p80211enum MKENUMNAME(reason);
+extern struct p80211enum MKENUMNAME(status);
+extern struct p80211enum MKENUMNAME(msgcode);
+extern struct p80211enum MKENUMNAME(msgitem_status);
+
+extern struct p80211enum MKENUMNAME(lnxroam_reason);
+
+extern struct p80211enum MKENUMNAME(p2preamble);
#endif /* _P80211TYPES_H */
diff --git a/drivers/staging/wlan-ng/p80211wep.c b/drivers/staging/wlan-ng/p80211wep.c
index 22c79703e328..23b183738037 100644
--- a/drivers/staging/wlan-ng/p80211wep.c
+++ b/drivers/staging/wlan-ng/p80211wep.c
@@ -119,7 +119,7 @@ static const u32 wep_crc32_table[256] = {
/* keylen in bytes! */
-int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen)
+int wep_change_key(struct wlandevice *wlandev, int keynum, u8 *key, int keylen)
{
if (keylen < 0)
return -1;
@@ -143,7 +143,7 @@ int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen)
* 4-byte IV at start of buffer, 4-byte ICV at end of buffer.
* if successful, buf start is payload begin, length -= 8;
*/
-int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
+int wep_decrypt(struct wlandevice *wlandev, u8 *buf, u32 len, int key_override,
u8 *iv, u8 *icv)
{
u32 i, j, k, crc, keylen;
@@ -217,7 +217,7 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
}
/* encrypts in-place. */
-int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
+int wep_encrypt(struct wlandevice *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
u8 *iv, u8 *icv)
{
u32 i, j, k, crc, keylen;
diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c
index 56bffd93c982..96aa21188669 100644
--- a/drivers/staging/wlan-ng/prism2fw.c
+++ b/drivers/staging/wlan-ng/prism2fw.c
@@ -96,16 +96,16 @@ struct s3inforec {
u16 len;
u16 type;
union {
- hfa384x_compident_t version;
- hfa384x_caplevel_t compat;
+ struct hfa384x_compident version;
+ struct hfa384x_caplevel compat;
u16 buildseq;
- hfa384x_compident_t platform;
+ struct hfa384x_compident platform;
} info;
};
struct pda {
u8 buf[HFA384x_PDA_LEN_MAX];
- hfa384x_pdrec_t *rec[HFA384x_PDA_RECS_MAX];
+ struct hfa384x_pdrec *rec[HFA384x_PDA_RECS_MAX];
unsigned int nrec;
};
@@ -152,22 +152,22 @@ static struct imgchunk fchunk[CHUNKS_MAX];
/* PDA, built from [card|newfile]+[addfile1+addfile2...] */
static struct pda pda;
-static hfa384x_compident_t nicid;
-static hfa384x_caplevel_t rfid;
-static hfa384x_caplevel_t macid;
-static hfa384x_caplevel_t priid;
+static struct hfa384x_compident nicid;
+static struct hfa384x_caplevel rfid;
+static struct hfa384x_caplevel macid;
+static struct hfa384x_caplevel priid;
/*================================================================*/
/* Local Function Declarations */
static int prism2_fwapply(const struct ihex_binrec *rfptr,
-wlandevice_t *wlandev);
+struct wlandevice *wlandev);
static int read_fwfile(const struct ihex_binrec *rfptr);
static int mkimage(struct imgchunk *clist, unsigned int *ccnt);
-static int read_cardpda(struct pda *pda, wlandevice_t *wlandev);
+static int read_cardpda(struct pda *pda, struct wlandevice *wlandev);
static int mkpdrlist(struct pda *pda);
@@ -177,7 +177,7 @@ static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks,
static int crcimage(struct imgchunk *fchunk, unsigned int nfchunks,
struct s3crcrec *s3crc, unsigned int ns3crc);
-static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk,
+static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk,
unsigned int nfchunks);
static void free_chunks(struct imgchunk *fchunk, unsigned int *nfchunks);
@@ -201,7 +201,7 @@ static int validate_identity(void);
* 0 - success
* ~0 - failure
----------------------------------------------------------------*/
-static int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev)
+static int prism2_fwtry(struct usb_device *udev, struct wlandevice *wlandev)
{
const struct firmware *fw_entry = NULL;
@@ -239,11 +239,11 @@ static int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev)
* ~0 - failure
----------------------------------------------------------------*/
static int prism2_fwapply(const struct ihex_binrec *rfptr,
- wlandevice_t *wlandev)
+ struct wlandevice *wlandev)
{
signed int result = 0;
struct p80211msg_dot11req_mibget getmsg;
- p80211itemd_t *item;
+ struct p80211itemd *item;
u32 *data;
/* Initialize the data structures */
@@ -266,7 +266,7 @@ static int prism2_fwapply(const struct ihex_binrec *rfptr,
/* clear the pda and add an initial END record */
memset(&pda, 0, sizeof(pda));
- pda.rec[0] = (hfa384x_pdrec_t *) pda.buf;
+ pda.rec[0] = (struct hfa384x_pdrec *)pda.buf;
pda.rec[0]->len = cpu_to_le16(2); /* len in words */
pda.rec[0]->code = cpu_to_le16(HFA384x_PDR_END_OF_PDA);
pda.nrec = 1;
@@ -293,11 +293,11 @@ static int prism2_fwapply(const struct ihex_binrec *rfptr,
getmsg.resultcode.did = DIDmsg_dot11req_mibget_resultcode;
getmsg.resultcode.status = P80211ENUM_msgitem_status_no_value;
- item = (p80211itemd_t *) getmsg.mibattribute.data;
+ item = (struct p80211itemd *)getmsg.mibattribute.data;
item->did = DIDmib_p2_p2NIC_p2PRISupRange;
item->status = P80211ENUM_msgitem_status_no_value;
- data = (u32 *) item->data;
+ data = (u32 *)item->data;
/* DIDmsg_dot11req_mibget */
prism2mgmt_mibset_mibget(wlandev, &getmsg);
@@ -592,14 +592,14 @@ static int mkimage(struct imgchunk *clist, unsigned int *ccnt)
----------------------------------------------------------------*/
static int mkpdrlist(struct pda *pda)
{
- u16 *pda16 = (u16 *) pda->buf;
+ u16 *pda16 = (u16 *)pda->buf;
int curroff; /* in 'words' */
pda->nrec = 0;
curroff = 0;
while (curroff < (HFA384x_PDA_LEN_MAX / 2 - 1) &&
le16_to_cpu(pda16[curroff + 1]) != HFA384x_PDR_END_OF_PDA) {
- pda->rec[pda->nrec] = (hfa384x_pdrec_t *) &(pda16[curroff]);
+ pda->rec[pda->nrec] = (struct hfa384x_pdrec *)&(pda16[curroff]);
if (le16_to_cpu(pda->rec[pda->nrec]->code) ==
HFA384x_PDR_NICID) {
@@ -638,7 +638,7 @@ static int mkpdrlist(struct pda *pda)
curroff, pda->nrec);
return 1;
}
- pda->rec[pda->nrec] = (hfa384x_pdrec_t *) &(pda16[curroff]);
+ pda->rec[pda->nrec] = (struct hfa384x_pdrec *)&(pda16[curroff]);
(pda->nrec)++;
return 0;
}
@@ -766,7 +766,7 @@ static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks,
* 0 - success
* ~0 - failure (probably an errno)
----------------------------------------------------------------*/
-static int read_cardpda(struct pda *pda, wlandevice_t *wlandev)
+static int read_cardpda(struct pda *pda, struct wlandevice *wlandev)
{
int result = 0;
struct p80211msg_p2req_readpda *msg;
@@ -879,8 +879,8 @@ static int read_fwfile(const struct ihex_binrec *record)
addr = be32_to_cpu(record->addr);
/* Point into data for different word lengths */
- ptr32 = (u32 *) record->data;
- ptr16 = (u16 *) record->data;
+ ptr32 = (u32 *)record->data;
+ ptr16 = (u16 *)record->data;
/* parse what was an S3 srec and put it in the right array */
switch (addr) {
@@ -954,7 +954,7 @@ static int read_fwfile(const struct ihex_binrec *record)
default: /* Data record */
s3data[ns3data].addr = addr;
s3data[ns3data].len = len;
- s3data[ns3data].data = (uint8_t *) record->data;
+ s3data[ns3data].data = (uint8_t *)record->data;
ns3data++;
if (ns3data == S3DATA_MAX) {
pr_err("S3 datarec limit reached - aborting\n");
@@ -982,7 +982,7 @@ static int read_fwfile(const struct ihex_binrec *record)
* 0 success
* ~0 failure
----------------------------------------------------------------*/
-static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk,
+static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk,
unsigned int nfchunks)
{
int result = 0;
diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c
index d8ed9a05789c..170de1c9eac4 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.c
+++ b/drivers/staging/wlan-ng/prism2mgmt.c
@@ -113,16 +113,16 @@
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
-int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
+int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp)
{
int result = 0;
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
struct p80211msg_dot11req_scan *msg = msgp;
u16 roamingmode, word;
int i, timeout;
int istmpenable = 0;
- hfa384x_HostScanRequest_data_t scanreq;
+ struct hfa384x_HostScanRequest_data scanreq;
/* gatekeeper check */
if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
@@ -292,7 +292,7 @@ int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
result = hfa384x_drvr_setconfig(hw,
HFA384x_RID_HOSTSCAN, &scanreq,
- sizeof(hfa384x_HostScanRequest_data_t));
+ sizeof(struct hfa384x_HostScanRequest_data));
if (result) {
netdev_err(wlandev->netdev,
"setconfig(SCANREQUEST) failed. result=%d\n",
@@ -366,12 +366,12 @@ exit:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
-int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
+int prism2mgmt_scan_results(struct wlandevice *wlandev, void *msgp)
{
int result = 0;
struct p80211msg_dot11req_scan_results *req;
- hfa384x_t *hw = wlandev->priv;
- hfa384x_HScanResultSub_t *item = NULL;
+ struct hfa384x *hw = wlandev->priv;
+ struct hfa384x_HScanResultSub *item = NULL;
int count;
@@ -525,15 +525,15 @@ exit:
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
-int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
+int prism2mgmt_start(struct wlandevice *wlandev, void *msgp)
{
int result = 0;
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
struct p80211msg_dot11req_start *msg = msgp;
- p80211pstrd_t *pstr;
+ struct p80211pstrd *pstr;
u8 bytebuf[80];
- struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *) bytebuf;
+ struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *)bytebuf;
u16 word;
wlandev->macmode = WLAN_MACMODE_NONE;
@@ -558,7 +558,7 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
/*** STATION ***/
/* Set the REQUIRED config items */
/* SSID */
- pstr = (p80211pstrd_t *) &(msg->ssid.data);
+ pstr = (struct p80211pstrd *)&(msg->ssid.data);
prism2mgmt_pstr2bytestr(p2bytestr, pstr);
result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
@@ -685,9 +685,7 @@ failed:
msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
done:
- result = 0;
-
- return result;
+ return 0;
}
/*----------------------------------------------------------------
@@ -708,9 +706,9 @@ done:
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
-int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
+int prism2mgmt_readpda(struct wlandevice *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
struct p80211msg_p2req_readpda *msg = msgp;
int result;
@@ -774,9 +772,9 @@ int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
-int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
+int prism2mgmt_ramdl_state(struct wlandevice *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
struct p80211msg_p2req_ramdl_state *msg = msgp;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
@@ -829,9 +827,9 @@ int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
-int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
+int prism2mgmt_ramdl_write(struct wlandevice *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
struct p80211msg_p2req_ramdl_write *msg = msgp;
u32 addr;
u32 len;
@@ -890,10 +888,10 @@ int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
-int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
+int prism2mgmt_flashdl_state(struct wlandevice *wlandev, void *msgp)
{
int result = 0;
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
struct p80211msg_p2req_flashdl_state *msg = msgp;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
@@ -961,9 +959,9 @@ int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
* Call context:
* process thread (usually)
----------------------------------------------------------------*/
-int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
+int prism2mgmt_flashdl_write(struct wlandevice *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
struct p80211msg_p2req_flashdl_write *msg = msgp;
u32 addr;
u32 len;
@@ -1021,16 +1019,16 @@ int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
-int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
+int prism2mgmt_autojoin(struct wlandevice *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
int result = 0;
u16 reg;
u16 port_type;
struct p80211msg_lnxreq_autojoin *msg = msgp;
- p80211pstrd_t *pstr;
+ struct p80211pstrd *pstr;
u8 bytebuf[256];
- struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *) bytebuf;
+ struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *)bytebuf;
wlandev->macmode = WLAN_MACMODE_NONE;
@@ -1054,7 +1052,7 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
/* Set the ssid */
memset(bytebuf, 0, 256);
- pstr = (p80211pstrd_t *) &(msg->ssid.data);
+ pstr = (struct p80211pstrd *)&(msg->ssid.data);
prism2mgmt_pstr2bytestr(p2bytestr, pstr);
result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
bytebuf,
@@ -1092,12 +1090,12 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
* process thread (usually)
* interrupt
----------------------------------------------------------------*/
-int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
+int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp)
{
int result = 0;
struct p80211msg_lnxreq_wlansniff *msg = msgp;
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
u16 word;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h
index e6472034da33..cc1ac7a60dfe 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.h
+++ b/drivers/staging/wlan-ng/prism2mgmt.h
@@ -63,43 +63,44 @@
extern int prism2_reset_holdtime;
extern int prism2_reset_settletime;
-u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate);
+u32 prism2sta_ifstate(struct wlandevice *wlandev, u32 ifstate);
-void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status);
-void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status);
-void prism2sta_ev_alloc(wlandevice_t *wlandev);
+void prism2sta_ev_info(struct wlandevice *wlandev, struct hfa384x_InfFrame *inf);
+void prism2sta_ev_txexc(struct wlandevice *wlandev, u16 status);
+void prism2sta_ev_tx(struct wlandevice *wlandev, u16 status);
+void prism2sta_ev_alloc(struct wlandevice *wlandev);
-int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp);
-int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp);
-int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp);
-int prism2mgmt_start(wlandevice_t *wlandev, void *msgp);
-int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp);
-int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp);
-int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp);
-int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp);
-int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp);
-int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp);
-int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_mibset_mibget(struct wlandevice *wlandev, void *msgp);
+int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp);
+int prism2mgmt_scan_results(struct wlandevice *wlandev, void *msgp);
+int prism2mgmt_start(struct wlandevice *wlandev, void *msgp);
+int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp);
+int prism2mgmt_readpda(struct wlandevice *wlandev, void *msgp);
+int prism2mgmt_ramdl_state(struct wlandevice *wlandev, void *msgp);
+int prism2mgmt_ramdl_write(struct wlandevice *wlandev, void *msgp);
+int prism2mgmt_flashdl_state(struct wlandevice *wlandev, void *msgp);
+int prism2mgmt_flashdl_write(struct wlandevice *wlandev, void *msgp);
+int prism2mgmt_autojoin(struct wlandevice *wlandev, void *msgp);
/*---------------------------------------------------------------
* conversion functions going between wlan message data types and
* Prism2 data types
---------------------------------------------------------------*/
/* byte area conversion functions*/
-void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len);
+void prism2mgmt_bytearea2pstr(u8 *bytearea, struct p80211pstrd *pstr, int len);
/* byte string conversion functions*/
void prism2mgmt_pstr2bytestr(struct hfa384x_bytestr *bytestr,
- p80211pstrd_t *pstr);
+ struct p80211pstrd *pstr);
void prism2mgmt_bytestr2pstr(struct hfa384x_bytestr *bytestr,
- p80211pstrd_t *pstr);
+ struct p80211pstrd *pstr);
/* functions to convert Group Addresses */
-void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t *pstr, hfa384x_t *priv);
+void prism2mgmt_get_grpaddr(u32 did, struct p80211pstrd *pstr,
+ struct hfa384x *priv);
int prism2mgmt_set_grpaddr(u32 did,
- u8 *prism2buf, p80211pstrd_t *pstr,
- hfa384x_t *priv);
+ u8 *prism2buf, struct p80211pstrd *pstr,
+ struct hfa384x *priv);
int prism2mgmt_get_grpaddr_index(u32 did);
void prism2sta_processing_defer(struct work_struct *data);
@@ -108,8 +109,8 @@ void prism2sta_commsqual_defer(struct work_struct *data);
void prism2sta_commsqual_timer(unsigned long data);
/* Interface callback functions, passing data back up to the cfg80211 layer */
-void prism2_connect_result(wlandevice_t *wlandev, u8 failed);
-void prism2_disconnected(wlandevice_t *wlandev);
-void prism2_roamed(wlandevice_t *wlandev);
+void prism2_connect_result(struct wlandevice *wlandev, u8 failed);
+void prism2_disconnected(struct wlandevice *wlandev);
+void prism2_roamed(struct wlandevice *wlandev);
#endif
diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c
index fe914b1f904b..63ab6bc88654 100644
--- a/drivers/staging/wlan-ng/prism2mib.c
+++ b/drivers/staging/wlan-ng/prism2mib.c
@@ -87,80 +87,80 @@ struct mibrec {
u16 parm3;
int (*func)(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg, void *data);
};
static int prism2mib_bytearea2pstr(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg,
void *data);
static int prism2mib_uint32(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg, void *data);
static int prism2mib_flag(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg, void *data);
static int prism2mib_wepdefaultkey(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg,
void *data);
static int prism2mib_privacyinvoked(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg,
void *data);
static int prism2mib_excludeunencrypted(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg,
void *data);
static int prism2mib_fragmentationthreshold(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg,
void *data);
static int prism2mib_priv(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg, void *data);
static struct mibrec mibtab[] = {
/* dot11smt MIB's */
- {DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0,
+ {DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(1),
F_STA | F_WRITE,
HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
prism2mib_wepdefaultkey},
- {DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1,
+ {DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(2),
F_STA | F_WRITE,
HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
prism2mib_wepdefaultkey},
- {DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2,
+ {DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(3),
F_STA | F_WRITE,
HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
prism2mib_wepdefaultkey},
- {DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3,
+ {DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(4),
F_STA | F_WRITE,
HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
prism2mib_wepdefaultkey},
@@ -237,36 +237,36 @@ static struct mibrec mibtab[] = {
{0, 0, 0, 0, 0, NULL}
};
-/*----------------------------------------------------------------
-* prism2mgmt_mibset_mibget
-*
-* Set the value of a mib item.
-*
-* Arguments:
-* wlandev wlan device structure
-* msgp ptr to msg buffer
-*
-* Returns:
-* 0 success and done
-* <0 success, but we're waiting for something to finish.
-* >0 an error occurred while handling the message.
-* Side effects:
-*
-* Call context:
-* process thread (usually)
-* interrupt
-----------------------------------------------------------------*/
-
-int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp)
+/*
+ * prism2mgmt_mibset_mibget
+ *
+ * Set the value of a mib item.
+ *
+ * Arguments:
+ * wlandev wlan device structure
+ * msgp ptr to msg buffer
+ *
+ * Returns:
+ * 0 success and done
+ * <0 success, but we're waiting for something to finish.
+ * >0 an error occurred while handling the message.
+ * Side effects:
+ *
+ * Call context:
+ * process thread (usually)
+ * interrupt
+ */
+
+int prism2mgmt_mibset_mibget(struct wlandevice *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
int result, isget;
struct mibrec *mib;
u16 which;
struct p80211msg_dot11req_mibset *msg = msgp;
- p80211itemd_t *mibitem;
+ struct p80211itemd *mibitem;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
@@ -284,7 +284,7 @@ int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp)
** MIB table.
*/
- mibitem = (p80211itemd_t *) msg->mibattribute.data;
+ mibitem = (struct p80211itemd *)msg->mibattribute.data;
for (mib = mibtab; mib->did != 0; mib++)
if (mib->did == mibitem->did && (mib->flag & which))
@@ -346,40 +346,40 @@ done:
return 0;
}
-/*----------------------------------------------------------------
-* prism2mib_bytearea2pstr
-*
-* Get/set pstr data to/from a byte area.
-*
-* MIB record parameters:
-* parm1 Prism2 RID value.
-* parm2 Number of bytes of RID data.
-* parm3 Not used.
-*
-* Arguments:
-* mib MIB record.
-* isget MIBGET/MIBSET flag.
-* wlandev wlan device structure.
-* priv "priv" structure.
-* hw "hw" structure.
-* msg Message structure.
-* data Data buffer.
-*
-* Returns:
-* 0 - Success.
-* ~0 - Error.
-*
-----------------------------------------------------------------*/
+/*
+ * prism2mib_bytearea2pstr
+ *
+ * Get/set pstr data to/from a byte area.
+ *
+ * MIB record parameters:
+ * parm1 Prism2 RID value.
+ * parm2 Number of bytes of RID data.
+ * parm3 Not used.
+ *
+ * Arguments:
+ * mib MIB record.
+ * isget MIBGET/MIBSET flag.
+ * wlandev wlan device structure.
+ * priv "priv" structure.
+ * hw "hw" structure.
+ * msg Message structure.
+ * data Data buffer.
+ *
+ * Returns:
+ * 0 - Success.
+ * ~0 - Error.
+ *
+ */
static int prism2mib_bytearea2pstr(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg,
void *data)
{
int result;
- p80211pstrd_t *pstr = data;
+ struct p80211pstrd *pstr = data;
u8 bytebuf[MIB_TMP_MAXLEN];
if (isget) {
@@ -396,41 +396,41 @@ static int prism2mib_bytearea2pstr(struct mibrec *mib,
return result;
}
-/*----------------------------------------------------------------
-* prism2mib_uint32
-*
-* Get/set uint32 data.
-*
-* MIB record parameters:
-* parm1 Prism2 RID value.
-* parm2 Not used.
-* parm3 Not used.
-*
-* Arguments:
-* mib MIB record.
-* isget MIBGET/MIBSET flag.
-* wlandev wlan device structure.
-* priv "priv" structure.
-* hw "hw" structure.
-* msg Message structure.
-* data Data buffer.
-*
-* Returns:
-* 0 - Success.
-* ~0 - Error.
-*
-----------------------------------------------------------------*/
+/*
+ * prism2mib_uint32
+ *
+ * Get/set uint32 data.
+ *
+ * MIB record parameters:
+ * parm1 Prism2 RID value.
+ * parm2 Not used.
+ * parm3 Not used.
+ *
+ * Arguments:
+ * mib MIB record.
+ * isget MIBGET/MIBSET flag.
+ * wlandev wlan device structure.
+ * priv "priv" structure.
+ * hw "hw" structure.
+ * msg Message structure.
+ * data Data buffer.
+ *
+ * Returns:
+ * 0 - Success.
+ * ~0 - Error.
+ *
+ */
static int prism2mib_uint32(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg, void *data)
{
int result;
u32 *uint32 = data;
u8 bytebuf[MIB_TMP_MAXLEN];
- u16 *wordbuf = (u16 *) bytebuf;
+ u16 *wordbuf = (u16 *)bytebuf;
if (isget) {
result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
@@ -443,41 +443,41 @@ static int prism2mib_uint32(struct mibrec *mib,
return result;
}
-/*----------------------------------------------------------------
-* prism2mib_flag
-*
-* Get/set a flag.
-*
-* MIB record parameters:
-* parm1 Prism2 RID value.
-* parm2 Bit to get/set.
-* parm3 Not used.
-*
-* Arguments:
-* mib MIB record.
-* isget MIBGET/MIBSET flag.
-* wlandev wlan device structure.
-* priv "priv" structure.
-* hw "hw" structure.
-* msg Message structure.
-* data Data buffer.
-*
-* Returns:
-* 0 - Success.
-* ~0 - Error.
-*
-----------------------------------------------------------------*/
+/*
+ * prism2mib_flag
+ *
+ * Get/set a flag.
+ *
+ * MIB record parameters:
+ * parm1 Prism2 RID value.
+ * parm2 Bit to get/set.
+ * parm3 Not used.
+ *
+ * Arguments:
+ * mib MIB record.
+ * isget MIBGET/MIBSET flag.
+ * wlandev wlan device structure.
+ * priv "priv" structure.
+ * hw "hw" structure.
+ * msg Message structure.
+ * data Data buffer.
+ *
+ * Returns:
+ * 0 - Success.
+ * ~0 - Error.
+ *
+ */
static int prism2mib_flag(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg, void *data)
{
int result;
u32 *uint32 = data;
u8 bytebuf[MIB_TMP_MAXLEN];
- u16 *wordbuf = (u16 *) bytebuf;
+ u16 *wordbuf = (u16 *)bytebuf;
u32 flags;
result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
@@ -500,40 +500,40 @@ static int prism2mib_flag(struct mibrec *mib,
return result;
}
-/*----------------------------------------------------------------
-* prism2mib_wepdefaultkey
-*
-* Get/set WEP default keys.
-*
-* MIB record parameters:
-* parm1 Prism2 RID value.
-* parm2 Number of bytes of RID data.
-* parm3 Not used.
-*
-* Arguments:
-* mib MIB record.
-* isget MIBGET/MIBSET flag.
-* wlandev wlan device structure.
-* priv "priv" structure.
-* hw "hw" structure.
-* msg Message structure.
-* data Data buffer.
-*
-* Returns:
-* 0 - Success.
-* ~0 - Error.
-*
-----------------------------------------------------------------*/
+/*
+ * prism2mib_wepdefaultkey
+ *
+ * Get/set WEP default keys.
+ *
+ * MIB record parameters:
+ * parm1 Prism2 RID value.
+ * parm2 Number of bytes of RID data.
+ * parm3 Not used.
+ *
+ * Arguments:
+ * mib MIB record.
+ * isget MIBGET/MIBSET flag.
+ * wlandev wlan device structure.
+ * priv "priv" structure.
+ * hw "hw" structure.
+ * msg Message structure.
+ * data Data buffer.
+ *
+ * Returns:
+ * 0 - Success.
+ * ~0 - Error.
+ *
+ */
static int prism2mib_wepdefaultkey(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg,
void *data)
{
int result;
- p80211pstrd_t *pstr = data;
+ struct p80211pstrd *pstr = data;
u8 bytebuf[MIB_TMP_MAXLEN];
u16 len;
@@ -550,35 +550,35 @@ static int prism2mib_wepdefaultkey(struct mibrec *mib,
return result;
}
-/*----------------------------------------------------------------
-* prism2mib_privacyinvoked
-*
-* Get/set the dot11PrivacyInvoked value.
-*
-* MIB record parameters:
-* parm1 Prism2 RID value.
-* parm2 Bit value for PrivacyInvoked flag.
-* parm3 Not used.
-*
-* Arguments:
-* mib MIB record.
-* isget MIBGET/MIBSET flag.
-* wlandev wlan device structure.
-* priv "priv" structure.
-* hw "hw" structure.
-* msg Message structure.
-* data Data buffer.
-*
-* Returns:
-* 0 - Success.
-* ~0 - Error.
-*
-----------------------------------------------------------------*/
+/*
+ * prism2mib_privacyinvoked
+ *
+ * Get/set the dot11PrivacyInvoked value.
+ *
+ * MIB record parameters:
+ * parm1 Prism2 RID value.
+ * parm2 Bit value for PrivacyInvoked flag.
+ * parm3 Not used.
+ *
+ * Arguments:
+ * mib MIB record.
+ * isget MIBGET/MIBSET flag.
+ * wlandev wlan device structure.
+ * priv "priv" structure.
+ * hw "hw" structure.
+ * msg Message structure.
+ * data Data buffer.
+ *
+ * Returns:
+ * 0 - Success.
+ * ~0 - Error.
+ *
+ */
static int prism2mib_privacyinvoked(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg,
void *data)
{
@@ -592,35 +592,35 @@ static int prism2mib_privacyinvoked(struct mibrec *mib,
return prism2mib_flag(mib, isget, wlandev, hw, msg, data);
}
-/*----------------------------------------------------------------
-* prism2mib_excludeunencrypted
-*
-* Get/set the dot11ExcludeUnencrypted value.
-*
-* MIB record parameters:
-* parm1 Prism2 RID value.
-* parm2 Bit value for ExcludeUnencrypted flag.
-* parm3 Not used.
-*
-* Arguments:
-* mib MIB record.
-* isget MIBGET/MIBSET flag.
-* wlandev wlan device structure.
-* priv "priv" structure.
-* hw "hw" structure.
-* msg Message structure.
-* data Data buffer.
-*
-* Returns:
-* 0 - Success.
-* ~0 - Error.
-*
-----------------------------------------------------------------*/
+/*
+ * prism2mib_excludeunencrypted
+ *
+ * Get/set the dot11ExcludeUnencrypted value.
+ *
+ * MIB record parameters:
+ * parm1 Prism2 RID value.
+ * parm2 Bit value for ExcludeUnencrypted flag.
+ * parm3 Not used.
+ *
+ * Arguments:
+ * mib MIB record.
+ * isget MIBGET/MIBSET flag.
+ * wlandev wlan device structure.
+ * priv "priv" structure.
+ * hw "hw" structure.
+ * msg Message structure.
+ * data Data buffer.
+ *
+ * Returns:
+ * 0 - Success.
+ * ~0 - Error.
+ *
+ */
static int prism2mib_excludeunencrypted(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg,
void *data)
{
@@ -628,35 +628,35 @@ static int prism2mib_excludeunencrypted(struct mibrec *mib,
return prism2mib_flag(mib, isget, wlandev, hw, msg, data);
}
-/*----------------------------------------------------------------
-* prism2mib_fragmentationthreshold
-*
-* Get/set the fragmentation threshold.
-*
-* MIB record parameters:
-* parm1 Prism2 RID value.
-* parm2 Not used.
-* parm3 Not used.
-*
-* Arguments:
-* mib MIB record.
-* isget MIBGET/MIBSET flag.
-* wlandev wlan device structure.
-* priv "priv" structure.
-* hw "hw" structure.
-* msg Message structure.
-* data Data buffer.
-*
-* Returns:
-* 0 - Success.
-* ~0 - Error.
-*
-----------------------------------------------------------------*/
+/*
+ * prism2mib_fragmentationthreshold
+ *
+ * Get/set the fragmentation threshold.
+ *
+ * MIB record parameters:
+ * parm1 Prism2 RID value.
+ * parm2 Not used.
+ * parm3 Not used.
+ *
+ * Arguments:
+ * mib MIB record.
+ * isget MIBGET/MIBSET flag.
+ * wlandev wlan device structure.
+ * priv "priv" structure.
+ * hw "hw" structure.
+ * msg Message structure.
+ * data Data buffer.
+ *
+ * Returns:
+ * 0 - Success.
+ * ~0 - Error.
+ *
+ */
static int prism2mib_fragmentationthreshold(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg,
void *data)
{
@@ -674,47 +674,47 @@ static int prism2mib_fragmentationthreshold(struct mibrec *mib,
return prism2mib_uint32(mib, isget, wlandev, hw, msg, data);
}
-/*----------------------------------------------------------------
-* prism2mib_priv
-*
-* Get/set values in the "priv" data structure.
-*
-* MIB record parameters:
-* parm1 Not used.
-* parm2 Not used.
-* parm3 Not used.
-*
-* Arguments:
-* mib MIB record.
-* isget MIBGET/MIBSET flag.
-* wlandev wlan device structure.
-* priv "priv" structure.
-* hw "hw" structure.
-* msg Message structure.
-* data Data buffer.
-*
-* Returns:
-* 0 - Success.
-* ~0 - Error.
-*
-----------------------------------------------------------------*/
+/*
+ * prism2mib_priv
+ *
+ * Get/set values in the "priv" data structure.
+ *
+ * MIB record parameters:
+ * parm1 Not used.
+ * parm2 Not used.
+ * parm3 Not used.
+ *
+ * Arguments:
+ * mib MIB record.
+ * isget MIBGET/MIBSET flag.
+ * wlandev wlan device structure.
+ * priv "priv" structure.
+ * hw "hw" structure.
+ * msg Message structure.
+ * data Data buffer.
+ *
+ * Returns:
+ * 0 - Success.
+ * ~0 - Error.
+ *
+ */
static int prism2mib_priv(struct mibrec *mib,
int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
+ struct wlandevice *wlandev,
+ struct hfa384x *hw,
struct p80211msg_dot11req_mibset *msg, void *data)
{
- p80211pstrd_t *pstr = data;
+ struct p80211pstrd *pstr = data;
switch (mib->did) {
case DIDmib_lnx_lnxConfigTable_lnxRSNAIE:{
- hfa384x_WPAData_t wpa;
+ struct hfa384x_WPAData wpa;
if (isget) {
hfa384x_drvr_getconfig(hw,
HFA384x_RID_CNFWPADATA,
- (u8 *) &wpa,
+ (u8 *)&wpa,
sizeof(wpa));
pstr->len = le16_to_cpu(wpa.datalen);
memcpy(pstr->data, wpa.data, pstr->len);
@@ -724,7 +724,7 @@ static int prism2mib_priv(struct mibrec *mib,
hfa384x_drvr_setconfig(hw,
HFA384x_RID_CNFWPADATA,
- (u8 *) &wpa,
+ (u8 *)&wpa,
sizeof(wpa));
}
break;
@@ -736,67 +736,67 @@ static int prism2mib_priv(struct mibrec *mib,
return 0;
}
-/*----------------------------------------------------------------
-* prism2mgmt_pstr2bytestr
-*
-* Convert the pstr data in the WLAN message structure into an hfa384x
-* byte string format.
-*
-* Arguments:
-* bytestr hfa384x byte string data type
-* pstr wlan message data
-*
-* Returns:
-* Nothing
-*
-----------------------------------------------------------------*/
+/*
+ * prism2mgmt_pstr2bytestr
+ *
+ * Convert the pstr data in the WLAN message structure into an hfa384x
+ * byte string format.
+ *
+ * Arguments:
+ * bytestr hfa384x byte string data type
+ * pstr wlan message data
+ *
+ * Returns:
+ * Nothing
+ *
+ */
void prism2mgmt_pstr2bytestr(struct hfa384x_bytestr *bytestr,
- p80211pstrd_t *pstr)
+ struct p80211pstrd *pstr)
{
- bytestr->len = cpu_to_le16((u16) (pstr->len));
+ bytestr->len = cpu_to_le16((u16)(pstr->len));
memcpy(bytestr->data, pstr->data, pstr->len);
}
-/*----------------------------------------------------------------
-* prism2mgmt_bytestr2pstr
-*
-* Convert the data in an hfa384x byte string format into a
-* pstr in the WLAN message.
-*
-* Arguments:
-* bytestr hfa384x byte string data type
-* msg wlan message
-*
-* Returns:
-* Nothing
-*
-----------------------------------------------------------------*/
+/*
+ * prism2mgmt_bytestr2pstr
+ *
+ * Convert the data in an hfa384x byte string format into a
+ * pstr in the WLAN message.
+ *
+ * Arguments:
+ * bytestr hfa384x byte string data type
+ * msg wlan message
+ *
+ * Returns:
+ * Nothing
+ *
+ */
void prism2mgmt_bytestr2pstr(struct hfa384x_bytestr *bytestr,
- p80211pstrd_t *pstr)
+ struct p80211pstrd *pstr)
{
- pstr->len = (u8) (le16_to_cpu((u16) (bytestr->len)));
+ pstr->len = (u8)(le16_to_cpu((u16)(bytestr->len)));
memcpy(pstr->data, bytestr->data, pstr->len);
}
-/*----------------------------------------------------------------
-* prism2mgmt_bytearea2pstr
-*
-* Convert the data in an hfa384x byte area format into a pstr
-* in the WLAN message.
-*
-* Arguments:
-* bytearea hfa384x byte area data type
-* msg wlan message
-*
-* Returns:
-* Nothing
-*
-----------------------------------------------------------------*/
-
-void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len)
+/*
+ * prism2mgmt_bytearea2pstr
+ *
+ * Convert the data in an hfa384x byte area format into a pstr
+ * in the WLAN message.
+ *
+ * Arguments:
+ * bytearea hfa384x byte area data type
+ * msg wlan message
+ *
+ * Returns:
+ * Nothing
+ *
+ */
+
+void prism2mgmt_bytearea2pstr(u8 *bytearea, struct p80211pstrd *pstr, int len)
{
- pstr->len = (u8) len;
+ pstr->len = (u8)len;
memcpy(pstr->data, bytearea, len);
}
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c
index 64f90722b01b..e1b4a94292ff 100644
--- a/drivers/staging/wlan-ng/prism2sta.c
+++ b/drivers/staging/wlan-ng/prism2sta.c
@@ -81,7 +81,7 @@
#include "prism2mgmt.h"
static char *dev_info = "prism2_usb";
-static wlandevice_t *create_wlan(void);
+static struct wlandevice *create_wlan(void);
int prism2_reset_holdtime = 30; /* Reset hold time in ms */
int prism2_reset_settletime = 100; /* Reset settle time in ms */
@@ -98,37 +98,38 @@ MODULE_PARM_DESC(prism2_reset_settletime, "reset settle time in ms");
MODULE_LICENSE("Dual MPL/GPL");
-static int prism2sta_open(wlandevice_t *wlandev);
-static int prism2sta_close(wlandevice_t *wlandev);
-static void prism2sta_reset(wlandevice_t *wlandev);
-static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
+static int prism2sta_open(struct wlandevice *wlandev);
+static int prism2sta_close(struct wlandevice *wlandev);
+static void prism2sta_reset(struct wlandevice *wlandev);
+static int prism2sta_txframe(struct wlandevice *wlandev, struct sk_buff *skb,
union p80211_hdr *p80211_hdr,
struct p80211_metawep *p80211_wep);
-static int prism2sta_mlmerequest(wlandevice_t *wlandev, struct p80211msg *msg);
-static int prism2sta_getcardinfo(wlandevice_t *wlandev);
-static int prism2sta_globalsetup(wlandevice_t *wlandev);
-static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev);
-
-static void prism2sta_inf_handover(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_tallies(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_authreq(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf);
+static int prism2sta_mlmerequest(struct wlandevice *wlandev, struct p80211msg *msg);
+static int prism2sta_getcardinfo(struct wlandevice *wlandev);
+static int prism2sta_globalsetup(struct wlandevice *wlandev);
+static int prism2sta_setmulticast(struct wlandevice *wlandev,
+ struct net_device *dev);
+
+static void prism2sta_inf_handover(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf);
+static void prism2sta_inf_tallies(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf);
+static void prism2sta_inf_hostscanresults(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf);
+static void prism2sta_inf_scanresults(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf);
+static void prism2sta_inf_chinforesults(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf);
+static void prism2sta_inf_linkstatus(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf);
+static void prism2sta_inf_assocstatus(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf);
+static void prism2sta_inf_authreq(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf);
+static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf);
+static void prism2sta_inf_psusercnt(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf);
/*
* prism2sta_open
@@ -151,7 +152,7 @@ static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
* Call context:
* process thread
*/
-static int prism2sta_open(wlandevice_t *wlandev)
+static int prism2sta_open(struct wlandevice *wlandev)
{
/* We don't currently have to do anything else.
* The setup of the MAC should be subsequently completed via
@@ -185,7 +186,7 @@ static int prism2sta_open(wlandevice_t *wlandev)
* Call context:
* process thread
*/
-static int prism2sta_close(wlandevice_t *wlandev)
+static int prism2sta_close(struct wlandevice *wlandev)
{
/* We don't currently have to do anything else.
* Higher layers know we're not ready from dev->start==0 and
@@ -213,7 +214,7 @@ static int prism2sta_close(wlandevice_t *wlandev)
* Call context:
* process thread
*/
-static void prism2sta_reset(wlandevice_t *wlandev)
+static void prism2sta_reset(struct wlandevice *wlandev)
{
}
@@ -238,11 +239,11 @@ static void prism2sta_reset(wlandevice_t *wlandev)
* Call context:
* process thread
*/
-static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
+static int prism2sta_txframe(struct wlandevice *wlandev, struct sk_buff *skb,
union p80211_hdr *p80211_hdr,
struct p80211_metawep *p80211_wep)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
/* If necessary, set the 802.11 WEP bit */
if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) ==
@@ -277,9 +278,9 @@ static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
* Call context:
* process thread
*/
-static int prism2sta_mlmerequest(wlandevice_t *wlandev, struct p80211msg *msg)
+static int prism2sta_mlmerequest(struct wlandevice *wlandev, struct p80211msg *msg)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
int result = 0;
@@ -337,7 +338,7 @@ static int prism2sta_mlmerequest(wlandevice_t *wlandev, struct p80211msg *msg)
struct p80211msg_lnxreq_ifstate *ifstatemsg;
pr_debug("Received mlme ifstate request\n");
- ifstatemsg = (struct p80211msg_lnxreq_ifstate *) msg;
+ ifstatemsg = (struct p80211msg_lnxreq_ifstate *)msg;
result =
prism2sta_ifstate(wlandev,
ifstatemsg->ifstate.data);
@@ -360,7 +361,7 @@ static int prism2sta_mlmerequest(wlandevice_t *wlandev, struct p80211msg *msg)
pr_debug("Received commsquality request\n");
- qualmsg = (struct p80211msg_lnxreq_commsquality *) msg;
+ qualmsg = (struct p80211msg_lnxreq_commsquality *)msg;
qualmsg->link.status =
P80211ENUM_msgitem_status_data_ok;
@@ -407,9 +408,9 @@ static int prism2sta_mlmerequest(wlandevice_t *wlandev, struct p80211msg *msg)
* process thread (usually)
* interrupt
*/
-u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
+u32 prism2sta_ifstate(struct wlandevice *wlandev, u32 ifstate)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
u32 result;
result = P80211ENUM_resultcode_implementation_failure;
@@ -580,10 +581,10 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
* Call context:
* Either.
*/
-static int prism2sta_getcardinfo(wlandevice_t *wlandev)
+static int prism2sta_getcardinfo(struct wlandevice *wlandev)
{
int result = 0;
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
u16 temp;
u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN];
@@ -592,7 +593,7 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
/* NIC identity */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICIDENTITY,
&hw->ident_nic,
- sizeof(hfa384x_compident_t));
+ sizeof(struct hfa384x_compident));
if (result) {
netdev_err(wlandev->netdev, "Failed to retrieve NICIDENTITY\n");
goto failed;
@@ -611,7 +612,7 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
/* Primary f/w identity */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRIIDENTITY,
&hw->ident_pri_fw,
- sizeof(hfa384x_compident_t));
+ sizeof(struct hfa384x_compident));
if (result) {
netdev_err(wlandev->netdev, "Failed to retrieve PRIIDENTITY\n");
goto failed;
@@ -630,7 +631,7 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
/* Station (Secondary?) f/w identity */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STAIDENTITY,
&hw->ident_sta_fw,
- sizeof(hfa384x_compident_t));
+ sizeof(struct hfa384x_compident));
if (result) {
netdev_err(wlandev->netdev, "Failed to retrieve STAIDENTITY\n");
goto failed;
@@ -651,7 +652,7 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
/* strip out the 'special' variant bits */
hw->mm_mods = hw->ident_sta_fw.variant & (BIT(14) | BIT(15));
- hw->ident_sta_fw.variant &= ~((u16) (BIT(14) | BIT(15)));
+ hw->ident_sta_fw.variant &= ~((u16)(BIT(14) | BIT(15)));
if (hw->ident_sta_fw.id == 0x1f) {
netdev_info(wlandev->netdev,
@@ -670,7 +671,7 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
/* Compatibility range, Modem supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_MFISUPRANGE,
&hw->cap_sup_mfi,
- sizeof(hfa384x_caplevel_t));
+ sizeof(struct hfa384x_caplevel));
if (result) {
netdev_err(wlandev->netdev, "Failed to retrieve MFISUPRANGE\n");
goto failed;
@@ -694,7 +695,7 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
/* Compatibility range, Controller supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CFISUPRANGE,
&hw->cap_sup_cfi,
- sizeof(hfa384x_caplevel_t));
+ sizeof(struct hfa384x_caplevel));
if (result) {
netdev_err(wlandev->netdev, "Failed to retrieve CFISUPRANGE\n");
goto failed;
@@ -718,7 +719,7 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
/* Compatibility range, Primary f/w supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRISUPRANGE,
&hw->cap_sup_pri,
- sizeof(hfa384x_caplevel_t));
+ sizeof(struct hfa384x_caplevel));
if (result) {
netdev_err(wlandev->netdev, "Failed to retrieve PRISUPRANGE\n");
goto failed;
@@ -742,7 +743,7 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
/* Compatibility range, Station f/w supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STASUPRANGE,
&hw->cap_sup_sta,
- sizeof(hfa384x_caplevel_t));
+ sizeof(struct hfa384x_caplevel));
if (result) {
netdev_err(wlandev->netdev, "Failed to retrieve STASUPRANGE\n");
goto failed;
@@ -774,7 +775,7 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
/* Compatibility range, primary f/w actor, CFI supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRI_CFIACTRANGES,
&hw->cap_act_pri_cfi,
- sizeof(hfa384x_caplevel_t));
+ sizeof(struct hfa384x_caplevel));
if (result) {
netdev_err(wlandev->netdev, "Failed to retrieve PRI_CFIACTRANGES\n");
goto failed;
@@ -798,7 +799,7 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
/* Compatibility range, sta f/w actor, CFI supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_CFIACTRANGES,
&hw->cap_act_sta_cfi,
- sizeof(hfa384x_caplevel_t));
+ sizeof(struct hfa384x_caplevel));
if (result) {
netdev_err(wlandev->netdev, "Failed to retrieve STA_CFIACTRANGES\n");
goto failed;
@@ -822,7 +823,7 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
/* Compatibility range, sta f/w actor, MFI supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_MFIACTRANGES,
&hw->cap_act_sta_mfi,
- sizeof(hfa384x_caplevel_t));
+ sizeof(struct hfa384x_caplevel));
if (result) {
netdev_err(wlandev->netdev, "Failed to retrieve STA_MFIACTRANGES\n");
goto failed;
@@ -909,19 +910,20 @@ done:
* Call context:
* process thread
*/
-static int prism2sta_globalsetup(wlandevice_t *wlandev)
+static int prism2sta_globalsetup(struct wlandevice *wlandev)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
/* Set the maximum frame size */
return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN,
WLAN_DATA_MAXLEN);
}
-static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev)
+static int prism2sta_setmulticast(struct wlandevice *wlandev,
+ struct net_device *dev)
{
int result = 0;
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
u16 promisc;
@@ -959,8 +961,8 @@ exit:
* Call context:
* interrupt
*/
-static void prism2sta_inf_handover(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_handover(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf)
{
pr_debug("received infoframe:HANDOVER (unhandled)\n");
}
@@ -982,10 +984,10 @@ static void prism2sta_inf_handover(wlandevice_t *wlandev,
* Call context:
* interrupt
*/
-static void prism2sta_inf_tallies(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_tallies(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
u16 *src16;
u32 *dst;
u32 *src32;
@@ -997,15 +999,15 @@ static void prism2sta_inf_tallies(wlandevice_t *wlandev,
* record length of the info record.
*/
- cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(u32);
+ cnt = sizeof(struct hfa384x_CommTallies32) / sizeof(u32);
if (inf->framelen > 22) {
- dst = (u32 *) &hw->tallies;
- src32 = (u32 *) &inf->info.commtallies32;
+ dst = (u32 *)&hw->tallies;
+ src32 = (u32 *)&inf->info.commtallies32;
for (i = 0; i < cnt; i++, dst++, src32++)
*dst += le32_to_cpu(*src32);
} else {
- dst = (u32 *) &hw->tallies;
- src16 = (u16 *) &inf->info.commtallies16;
+ dst = (u32 *)&hw->tallies;
+ src16 = (u16 *)&inf->info.commtallies16;
for (i = 0; i < cnt; i++, dst++, src16++)
*dst += le16_to_cpu(*src16);
}
@@ -1028,21 +1030,20 @@ static void prism2sta_inf_tallies(wlandevice_t *wlandev,
* Call context:
* interrupt
*/
-static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_scanresults(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf)
{
-
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
int nbss;
- hfa384x_ScanResult_t *sr = &(inf->info.scanresult);
+ struct hfa384x_ScanResult *sr = &(inf->info.scanresult);
int i;
- hfa384x_JoinRequest_data_t joinreq;
+ struct hfa384x_JoinRequest_data joinreq;
int result;
/* Get the number of results, first in bytes, then in results */
nbss = (inf->framelen * sizeof(u16)) -
sizeof(inf->infotype) - sizeof(inf->info.scanresult.scanreason);
- nbss /= sizeof(hfa384x_ScanResultSub_t);
+ nbss /= sizeof(struct hfa384x_ScanResultSub);
/* Print em */
pr_debug("rx scanresults, reason=%d, nbss=%d:\n",
@@ -1084,10 +1085,10 @@ static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
* Call context:
* interrupt
*/
-static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_hostscanresults(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
int nbss;
nbss = (inf->framelen - 3) / 32;
@@ -1098,7 +1099,7 @@ static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
kfree(hw->scanresults);
- hw->scanresults = kmemdup(inf, sizeof(hfa384x_InfFrame_t), GFP_ATOMIC);
+ hw->scanresults = kmemdup(inf, sizeof(struct hfa384x_InfFrame), GFP_ATOMIC);
if (nbss == 0)
nbss = -1;
@@ -1125,18 +1126,18 @@ static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
* Call context:
* interrupt
*/
-static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_chinforesults(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
unsigned int i, n;
hw->channel_info.results.scanchannels =
le16_to_cpu(inf->info.chinforesult.scanchannels);
for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) {
- hfa384x_ChInfoResultSub_t *result;
- hfa384x_ChInfoResultSub_t *chinforesult;
+ struct hfa384x_ChInfoResultSub *result;
+ struct hfa384x_ChInfoResultSub *chinforesult;
int chan;
if (!(hw->channel_info.results.scanchannels & (1 << i)))
@@ -1170,18 +1171,18 @@ static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
void prism2sta_processing_defer(struct work_struct *data)
{
- hfa384x_t *hw = container_of(data, struct hfa384x, link_bh);
- wlandevice_t *wlandev = hw->wlandev;
- hfa384x_bytestr32_t ssid;
+ struct hfa384x *hw = container_of(data, struct hfa384x, link_bh);
+ struct wlandevice *wlandev = hw->wlandev;
+ struct hfa384x_bytestr32 ssid;
int result;
/* First let's process the auth frames */
{
struct sk_buff *skb;
- hfa384x_InfFrame_t *inf;
+ struct hfa384x_InfFrame *inf;
while ((skb = skb_dequeue(&hw->authq))) {
- inf = (hfa384x_InfFrame_t *) skb->data;
+ inf = (struct hfa384x_InfFrame *)skb->data;
prism2sta_inf_authreq_defer(wlandev, inf);
}
@@ -1256,8 +1257,8 @@ void prism2sta_processing_defer(struct work_struct *data)
return;
}
prism2mgmt_bytestr2pstr(
- (struct hfa384x_bytestr *) &ssid,
- (p80211pstrd_t *) &wlandev->ssid);
+ (struct hfa384x_bytestr *)&ssid,
+ (struct p80211pstrd *)&wlandev->ssid);
/* Collect the port status */
result = hfa384x_drvr_getconfig16(hw,
@@ -1337,8 +1338,8 @@ void prism2sta_processing_defer(struct work_struct *data)
HFA384x_RID_CURRENTSSID, result);
return;
}
- prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *) &ssid,
- (p80211pstrd_t *) &wlandev->ssid);
+ prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid,
+ (struct p80211pstrd *)&wlandev->ssid);
hw->link_status = HFA384x_LINK_CONNECTED;
netif_carrier_on(wlandev->netdev);
@@ -1390,7 +1391,7 @@ void prism2sta_processing_defer(struct work_struct *data)
* Disable Transmits, Ignore receives of data frames
*/
if (hw->join_ap && --hw->join_retries > 0) {
- hfa384x_JoinRequest_data_t joinreq;
+ struct hfa384x_JoinRequest_data joinreq;
joinreq = hw->joinreq;
/* Send the join request */
@@ -1438,10 +1439,10 @@ void prism2sta_processing_defer(struct work_struct *data)
* Call context:
* interrupt
*/
-static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_linkstatus(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
hw->link_status_new = le16_to_cpu(inf->info.linkstatus.linkstatus);
@@ -1466,11 +1467,11 @@ static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
* Call context:
* interrupt
*/
-static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_assocstatus(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf)
{
- hfa384x_t *hw = wlandev->priv;
- hfa384x_AssocStatus_t rec;
+ struct hfa384x *hw = wlandev->priv;
+ struct hfa384x_AssocStatus rec;
int i;
memcpy(&rec, &inf->info.assocstatus, sizeof(rec));
@@ -1527,10 +1528,10 @@ static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
* interrupt
*
*/
-static void prism2sta_inf_authreq(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_authreq(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
struct sk_buff *skb;
skb = dev_alloc_skb(sizeof(*inf));
@@ -1542,11 +1543,11 @@ static void prism2sta_inf_authreq(wlandevice_t *wlandev,
}
}
-static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf)
{
- hfa384x_t *hw = wlandev->priv;
- hfa384x_authenticateStation_data_t rec;
+ struct hfa384x *hw = wlandev->priv;
+ struct hfa384x_authenticateStation_data rec;
int i, added, result, cnt;
u8 *addr;
@@ -1716,10 +1717,10 @@ static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
* Call context:
* interrupt
*/
-static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
- hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_psusercnt(struct wlandevice *wlandev,
+ struct hfa384x_InfFrame *inf)
{
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
hw->psusercount = le16_to_cpu(inf->info.psusercnt.usercnt);
}
@@ -1741,7 +1742,7 @@ static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
* Call context:
* interrupt
*/
-void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
+void prism2sta_ev_info(struct wlandevice *wlandev, struct hfa384x_InfFrame *inf)
{
inf->infotype = le16_to_cpu(inf->infotype);
/* Dispatch */
@@ -1808,7 +1809,7 @@ void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
* Call context:
* interrupt
*/
-void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status)
+void prism2sta_ev_txexc(struct wlandevice *wlandev, u16 status)
{
pr_debug("TxExc status=0x%x.\n", status);
}
@@ -1829,7 +1830,7 @@ void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status)
* Call context:
* interrupt
*/
-void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status)
+void prism2sta_ev_tx(struct wlandevice *wlandev, u16 status)
{
pr_debug("Tx Complete, status=0x%04x\n", status);
/* update linux network stats */
@@ -1852,7 +1853,7 @@ void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status)
* Call context:
* interrupt
*/
-void prism2sta_ev_alloc(wlandevice_t *wlandev)
+void prism2sta_ev_alloc(struct wlandevice *wlandev)
{
netif_wake_queue(wlandev->netdev);
}
@@ -1860,14 +1861,14 @@ void prism2sta_ev_alloc(wlandevice_t *wlandev)
/*
* create_wlan
*
-* Called at module init time. This creates the wlandevice_t structure
+* Called at module init time. This creates the struct wlandevice structure
* and initializes it with relevant bits.
*
* Arguments:
* none
*
* Returns:
-* the created wlandevice_t structure.
+* the created struct wlandevice structure.
*
* Side effects:
* also allocates the priv/hw structures.
@@ -1876,14 +1877,14 @@ void prism2sta_ev_alloc(wlandevice_t *wlandev)
* process thread
*
*/
-static wlandevice_t *create_wlan(void)
+static struct wlandevice *create_wlan(void)
{
- wlandevice_t *wlandev = NULL;
- hfa384x_t *hw = NULL;
+ struct wlandevice *wlandev = NULL;
+ struct hfa384x *hw = NULL;
/* Alloc our structures */
- wlandev = kzalloc(sizeof(wlandevice_t), GFP_KERNEL);
- hw = kzalloc(sizeof(hfa384x_t), GFP_KERNEL);
+ wlandev = kzalloc(sizeof(struct wlandevice), GFP_KERNEL);
+ hw = kzalloc(sizeof(struct hfa384x), GFP_KERNEL);
if (!wlandev || !hw) {
kfree(wlandev);
@@ -1913,11 +1914,11 @@ static wlandevice_t *create_wlan(void)
void prism2sta_commsqual_defer(struct work_struct *data)
{
- hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh);
- wlandevice_t *wlandev = hw->wlandev;
- hfa384x_bytestr32_t ssid;
+ struct hfa384x *hw = container_of(data, struct hfa384x, commsqual_bh);
+ struct wlandevice *wlandev = hw->wlandev;
+ struct hfa384x_bytestr32 ssid;
struct p80211msg_dot11req_mibget msg;
- p80211item_uint32_t *mibitem = (p80211item_uint32_t *)
+ struct p80211item_uint32 *mibitem = (struct p80211item_uint32 *)
&msg.mibattribute.data;
int result = 0;
@@ -1950,7 +1951,7 @@ void prism2sta_commsqual_defer(struct work_struct *data)
/* Get the signal rate */
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem->did = DIDmib_p2_p2MAC_p2CurrentTxRate;
- result = p80211req_dorequest(wlandev, (u8 *) &msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
pr_debug("get signal rate failed, result = %d\n",
@@ -1993,8 +1994,8 @@ void prism2sta_commsqual_defer(struct work_struct *data)
HFA384x_RID_CURRENTSSID, result);
return;
}
- prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *) &ssid,
- (p80211pstrd_t *) &wlandev->ssid);
+ prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid,
+ (struct p80211pstrd *)&wlandev->ssid);
/* Reschedule timer */
mod_timer(&hw->commsqual_timer, jiffies + HZ);
@@ -2002,7 +2003,7 @@ void prism2sta_commsqual_defer(struct work_struct *data)
void prism2sta_commsqual_timer(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t *) data;
+ struct hfa384x *hw = (struct hfa384x *)data;
schedule_work(&hw->commsqual_bh);
}
diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c
index b26d09ff840c..bfb6b0a6528d 100644
--- a/drivers/staging/wlan-ng/prism2usb.c
+++ b/drivers/staging/wlan-ng/prism2usb.c
@@ -47,11 +47,11 @@ static const struct usb_device_id usb_prism_tbl[] = {
PRISM_DEV(0x0bb2, 0x0302, "Ambit Microsystems Corp."),
PRISM_DEV(0x9016, 0x182d, "Sitecom WL-022 802.11b USB Adapter"),
PRISM_DEV(0x0543, 0x0f01,
- "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)"),
+ "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)"),
PRISM_DEV(0x067c, 0x1022,
- "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter"),
+ "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter"),
PRISM_DEV(0x049f, 0x0033,
- "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter"),
+ "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter"),
{ } /* terminator */
};
MODULE_DEVICE_TABLE(usb, usb_prism_tbl);
@@ -61,8 +61,8 @@ static int prism2sta_probe_usb(struct usb_interface *interface,
{
struct usb_device *dev;
- wlandevice_t *wlandev = NULL;
- hfa384x_t *hw = NULL;
+ struct wlandevice *wlandev = NULL;
+ struct hfa384x *hw = NULL;
int result = 0;
dev = interface_to_usbdev(interface);
@@ -74,7 +74,7 @@ static int prism2sta_probe_usb(struct usb_interface *interface,
}
hw = wlandev->priv;
- if (wlan_setup(wlandev, &(interface->dev)) != 0) {
+ if (wlan_setup(wlandev, &interface->dev) != 0) {
dev_err(&interface->dev, "wlan_setup() failed.\n");
result = -EIO;
goto failed;
@@ -87,7 +87,7 @@ static int prism2sta_probe_usb(struct usb_interface *interface,
/* Register the wlandev, this gets us a name and registers the
* linux netdevice.
*/
- SET_NETDEV_DEV(wlandev->netdev, &(interface->dev));
+ SET_NETDEV_DEV(wlandev->netdev, &interface->dev);
/* Do a chip-level reset on the MAC */
if (prism2_doreset) {
@@ -134,15 +134,15 @@ done:
static void prism2sta_disconnect_usb(struct usb_interface *interface)
{
- wlandevice_t *wlandev;
+ struct wlandevice *wlandev;
- wlandev = (wlandevice_t *)usb_get_intfdata(interface);
- if (wlandev != NULL) {
+ wlandev = (struct wlandevice *)usb_get_intfdata(interface);
+ if (wlandev) {
LIST_HEAD(cleanlist);
- hfa384x_usbctlx_t *ctlx, *temp;
+ struct hfa384x_usbctlx *ctlx, *temp;
unsigned long flags;
- hfa384x_t *hw = wlandev->priv;
+ struct hfa384x *hw = wlandev->priv;
if (!hw)
goto exit;
@@ -216,12 +216,12 @@ exit:
#ifdef CONFIG_PM
static int prism2sta_suspend(struct usb_interface *interface,
- pm_message_t message)
+ pm_message_t message)
{
- hfa384x_t *hw = NULL;
- wlandevice_t *wlandev;
+ struct hfa384x *hw = NULL;
+ struct wlandevice *wlandev;
- wlandev = (wlandevice_t *)usb_get_intfdata(interface);
+ wlandev = (struct wlandevice *)usb_get_intfdata(interface);
if (!wlandev)
return -ENODEV;
@@ -241,10 +241,10 @@ static int prism2sta_suspend(struct usb_interface *interface,
static int prism2sta_resume(struct usb_interface *interface)
{
int result = 0;
- hfa384x_t *hw = NULL;
- wlandevice_t *wlandev;
+ struct hfa384x *hw = NULL;
+ struct wlandevice *wlandev;
- wlandev = (wlandevice_t *)usb_get_intfdata(interface);
+ wlandev = (struct wlandevice *)usb_get_intfdata(interface);
if (!wlandev)
return -ENODEV;
diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c
index d56ef1425f6b..0c78491ff5a1 100644
--- a/drivers/staging/xgifb/XGI_main_26.c
+++ b/drivers/staging/xgifb/XGI_main_26.c
@@ -62,7 +62,6 @@ static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
unsigned short ModeNo = modeno;
unsigned short ModeIdIndex = 0, ClockIndex = 0;
unsigned short RefreshRateTableIndex = 0;
- int Clock;
InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
@@ -73,9 +72,7 @@ static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
ClockIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
- Clock = XGI_VCLKData[ClockIndex].CLOCK * 1000;
-
- return Clock;
+ return XGI_VCLKData[ClockIndex].CLOCK * 1000;
}
static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
@@ -1227,7 +1224,7 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
unsigned int vtotal = 0;
unsigned int drate = 0, hrate = 0;
int found_mode = 0;
- int refresh_rate, search_idx;
+ int search_idx;
if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
vtotal = var->upper_margin + var->yres + var->lower_margin
@@ -1263,10 +1260,6 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
xgifb_info->refresh_rate = 60;
}
- /* Calculation wrong for 1024x600 - force it to 60Hz */
- if ((var->xres == 1024) && (var->yres == 600))
- refresh_rate = 60;
-
search_idx = 0;
while ((XGIbios_mode[search_idx].mode_no != 0) &&
(XGIbios_mode[search_idx].xres <= var->xres)) {
@@ -2085,7 +2078,7 @@ static int __init xgifb_init(void)
{
char *option = NULL;
- if (forcecrt2type != NULL)
+ if (forcecrt2type)
XGIfb_search_crt2type(forcecrt2type);
if (fb_get_options("xgifb", &option))
return -ENODEV;
diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c
index 50c8ea4f5ab7..d8010c5c1a70 100644
--- a/drivers/staging/xgifb/vb_setmode.c
+++ b/drivers/staging/xgifb/vb_setmode.c
@@ -214,7 +214,7 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeIdIndex,
if (!(pVBInfo->VBInfo & TVSetPAL) &&
(modeflag & NoSupportSimuTV) &&
(pVBInfo->VBInfo & SetInSlaveMode) &&
- (!(pVBInfo->VBInfo & SetNotSimuMode)))
+ !(pVBInfo->VBInfo & SetNotSimuMode))
return 0;
}
@@ -1647,7 +1647,6 @@ static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
{
-
unsigned short index, modeflag;
unsigned char tempal;
@@ -1655,7 +1654,7 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
if ((pVBInfo->SetFlag & ProgrammingCRT2) &&
- (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */
+ !(pVBInfo->LCDInfo & EnableScalingLCD)) { /* {LCDA/LCDB} */
index = XGI_GetLCDCapPtr(pVBInfo);
tempal = pVBInfo->LCDCapList[index].LCD_VCLK;
@@ -1678,7 +1677,6 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
if (!(modeflag & Charx8Dot))
tempal = TVCLKBASE_315 +
HiTVTextVCLK;
-
}
return tempal;
}
@@ -1716,7 +1714,7 @@ static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
{
if (pVBInfo->VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B
| VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
- if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) &&
+ if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
(pVBInfo->SetFlag & ProgrammingCRT2)) {
*di_0 = XGI_VBVCLKData[tempal].Part4_A;
*di_1 = XGI_VBVCLKData[tempal].Part4_B;
@@ -1741,8 +1739,8 @@ static void XGI_SetCRT2ECLK(unsigned short ModeIdIndex,
for (i = 0; i < 4; i++) {
xgifb_reg_and_or(pVBInfo->P3d4, 0x31, ~0x30,
(unsigned short) (0x10 * i));
- if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
- && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
+ if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
+ !(pVBInfo->VBInfo & SetInSlaveMode)) {
xgifb_reg_set(pVBInfo->P3c4, 0x2e, di_0);
xgifb_reg_set(pVBInfo->P3c4, 0x2f, di_1);
} else {
@@ -1915,7 +1913,7 @@ static void XGI_GetVBInfo(unsigned short ModeIdIndex,
}
}
- if (pVBInfo->VBType & (VB_SIS301LV|VB_SIS302LV|VB_XGI301C)) {
+ if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
if (temp & SetYPbPr) {
/* shampoo add for new scratch */
temp = xgifb_reg_get(pVBInfo->P3d4, 0x35);
@@ -1986,7 +1984,7 @@ static void XGI_GetVBInfo(unsigned short ModeIdIndex,
}
if (!(tempbx & DisableCRT2Display)) {
- if ((!(tempbx & DriverMode)) || (!(modeflag & CRT2Mode))) {
+ if (!(tempbx & DriverMode) || !(modeflag & CRT2Mode)) {
if (!(tempbx & XGI_SetCRT2ToLCDA))
tempbx |= (SetInSlaveMode | SetSimuScanMode);
}
@@ -2132,7 +2130,7 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeIdIndex,
if ((pVBInfo->LCDResInfo == Panel_1400x1050) &&
(pVBInfo->VBInfo & SetCRT2ToLCD) && (resinfo == 9) &&
- (!(tempbx & EnableScalingLCD)))
+ !(tempbx & EnableScalingLCD))
/*
* set to center in 1280x1024 LCDB
* for Panel_1400x1050
@@ -2245,7 +2243,6 @@ static void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
/* CR B4[1] */
xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
-
}
temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
@@ -2274,7 +2271,6 @@ static void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
/* CR B4[1] */
xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
-
}
xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0);
@@ -2291,7 +2287,6 @@ static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info,
struct xgi_hw_device_info *pXGIHWDE,
struct vb_device_info *pVBInfo)
{
-
xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x00);
if (pXGIHWDE->jChipType == XG21) {
if (pVBInfo->IF_DEF_LVDS == 1) {
@@ -2310,7 +2305,6 @@ static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info,
/* DVO/DVI signal on */
XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
}
-
}
if (pXGIHWDE->jChipType == XG27) {
@@ -2330,7 +2324,6 @@ static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info,
/* DVO/DVI signal on */
XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
}
-
}
}
@@ -2338,7 +2331,6 @@ void XGI_DisplayOff(struct xgifb_video_info *xgifb_info,
struct xgi_hw_device_info *pXGIHWDE,
struct vb_device_info *pVBInfo)
{
-
if (pXGIHWDE->jChipType == XG21) {
if (pVBInfo->IF_DEF_LVDS == 1) {
/* LVDS backlight off */
@@ -2455,7 +2447,6 @@ exit:
static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
{
-
if ((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) &&
(pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
return 1;
@@ -3922,7 +3913,7 @@ static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
- (!(pVBInfo->VBInfo & SetCRT2ToHiVision))) {
+ !(pVBInfo->VBInfo & SetCRT2ToHiVision)) {
/* Set Vertical Scaling */
Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo);
for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
@@ -3932,7 +3923,7 @@ static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
}
if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
- (!(pVBInfo->VBInfo & SetCRT2ToHiVision)))
+ !(pVBInfo->VBInfo & SetCRT2ToHiVision))
/* Enable V.Scaling */
xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04);
else
@@ -4132,7 +4123,6 @@ static void XGI_SetGroup4(unsigned short ModeIdIndex,
if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVision)) {
if (pVBInfo->VGAHDE > 800)
xgifb_reg_or(pVBInfo->Part4Port, 0x1E, 0x08);
-
}
temp = 0x0036;
@@ -4141,9 +4131,9 @@ static void XGI_SetGroup4(unsigned short ModeIdIndex,
| TVSetYPbPr525p | TVSetYPbPr750p
| TVSetHiVision))) {
temp |= 0x0001;
- if ((pVBInfo->VBInfo & SetInSlaveMode)
- && (!(pVBInfo->TVInfo
- & TVSimuMode)))
+ if ((pVBInfo->VBInfo & SetInSlaveMode) &&
+ !(pVBInfo->TVInfo
+ & TVSimuMode))
temp &= (~0x0001);
}
}
@@ -4389,7 +4379,6 @@ static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info,
(value << 2) & 0x7C);
for (temp = 0, value = 0; temp < 3; temp++) {
-
xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value);
xgifb_reg_set(pVBInfo->P3c4,
0x2B, xgifb_info->lvds_data.VCLKData1);
@@ -4409,7 +4398,6 @@ static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info,
inb(pVBInfo->P3da); /* reset 3da */
}
-
}
/* --------------------------------------------------------------------- */
@@ -4476,7 +4464,7 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
if ((pVBInfo->VBInfo &
(DisableCRT2Display | SetSimuScanMode)) ||
- ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) &&
+ (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
(pVBInfo->VBInfo &
(SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
@@ -4587,7 +4575,7 @@ static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
| VB_SIS302LV | VB_XGI301C)) {
- if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo
+ if (!(pVBInfo->VBInfo & SetInSlaveMode) || (pVBInfo->TVInfo
& TVSimuMode)) {
*tempbx += 8;
*tempcl += 1;
@@ -4988,8 +4976,8 @@ reg_and_or:
if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD
| XGI_SetCRT2ToLCDA)) {
tempah &= (~0x08);
- if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo
- & SetInSlaveMode))) {
+ if ((pVBInfo->ModeType == ModeVGA) && !(pVBInfo->VBInfo
+ & SetInSlaveMode)) {
tempah |= 0x010;
}
tempah |= 0x080;
@@ -5416,7 +5404,6 @@ static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info,
if (HwDeviceExtension->jChipType >= XG21) {
temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
if (temp & 0xA0) {
-
if (HwDeviceExtension->jChipType == XG27)
XGI_SetXG27CRTC(RefreshRateTableIndex, pVBInfo);
else
@@ -5486,7 +5473,7 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
XGI_DisableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA) ||
- (!(pVBInfo->VBInfo & SwitchCRT2))) {
+ !(pVBInfo->VBInfo & SwitchCRT2)) {
XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
ModeIdIndex, pVBInfo);
diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h
index c02b5ce6c5cd..dd85f3503410 100644
--- a/include/linux/hid-sensor-hub.h
+++ b/include/linux/hid-sensor-hub.h
@@ -236,6 +236,7 @@ struct hid_sensor_common {
struct hid_sensor_hub_attribute_info report_state;
struct hid_sensor_hub_attribute_info power_state;
struct hid_sensor_hub_attribute_info sensitivity;
+ struct work_struct work;
};
/* Convert from hid unit expo to regular exponent */
diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
index 3d672f72e7ec..9edccfba1ffb 100644
--- a/include/linux/iio/consumer.h
+++ b/include/linux/iio/consumer.h
@@ -165,6 +165,18 @@ struct iio_channel
*iio_channel_cb_get_channels(const struct iio_cb_buffer *cb_buffer);
/**
+ * iio_channel_cb_get_iio_dev() - get access to the underlying device.
+ * @cb_buffer: The callback buffer from whom we want the device
+ * information.
+ *
+ * This function allows one to obtain information about the device.
+ * The primary aim is to allow drivers that are consuming a device to query
+ * things like current trigger.
+ */
+struct iio_dev
+*iio_channel_cb_get_iio_dev(const struct iio_cb_buffer *cb_buffer);
+
+/**
* iio_read_channel_raw() - read from a given channel
* @chan: The channel being queried.
* @val: Value read back.
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 854e2dad1e0d..b4a0679e4a49 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -483,6 +483,7 @@ struct iio_buffer_setup_ops {
* @scan_timestamp: [INTERN] set if any buffers have requested timestamp
* @scan_index_timestamp:[INTERN] cache of the index to the timestamp
* @trig: [INTERN] current device trigger (buffer modes)
+ * @trig_readonly [INTERN] mark the current trigger immutable
* @pollfunc: [DRIVER] function run on trigger being received
* @pollfunc_event: [DRIVER] function run on events trigger being received
* @channels: [DRIVER] channel specification structure table
@@ -523,6 +524,7 @@ struct iio_dev {
bool scan_timestamp;
unsigned scan_index_timestamp;
struct iio_trigger *trig;
+ bool trig_readonly;
struct iio_poll_func *pollfunc;
struct iio_poll_func *pollfunc_event;
@@ -642,6 +644,7 @@ static inline struct iio_dev *iio_priv_to_dev(void *priv)
}
void iio_device_free(struct iio_dev *indio_dev);
+int devm_iio_device_match(struct device *dev, void *res, void *data);
struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv);
void devm_iio_device_free(struct device *dev, struct iio_dev *indio_dev);
struct iio_trigger *devm_iio_trigger_alloc(struct device *dev,
diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h
index 1c9e028e0d4a..4f1154f7a33c 100644
--- a/include/linux/iio/trigger.h
+++ b/include/linux/iio/trigger.h
@@ -56,6 +56,9 @@ struct iio_trigger_ops {
* @subirqs: [INTERN] information about the 'child' irqs.
* @pool: [INTERN] bitmap of irqs currently in use.
* @pool_lock: [INTERN] protection of the irq pool.
+ * @attached_own_device:[INTERN] if we are using our own device as trigger,
+ * i.e. if we registered a poll function to the same
+ * device as the one providing the trigger.
**/
struct iio_trigger {
const struct iio_trigger_ops *ops;
@@ -73,6 +76,7 @@ struct iio_trigger {
struct iio_subirq subirqs[CONFIG_IIO_CONSUMERS_PER_TRIGGER];
unsigned long pool[BITS_TO_LONGS(CONFIG_IIO_CONSUMERS_PER_TRIGGER)];
struct mutex pool_lock;
+ bool attached_own_device;
};
@@ -125,12 +129,27 @@ static inline void *iio_trigger_get_drvdata(struct iio_trigger *trig)
**/
int iio_trigger_register(struct iio_trigger *trig_info);
+int devm_iio_trigger_register(struct device *dev,
+ struct iio_trigger *trig_info);
+
/**
* iio_trigger_unregister() - unregister a trigger from the core
* @trig_info: trigger to be unregistered
**/
void iio_trigger_unregister(struct iio_trigger *trig_info);
+void devm_iio_trigger_unregister(struct device *dev,
+ struct iio_trigger *trig_info);
+
+/**
+ * iio_trigger_set_immutable() - set an immutable trigger on destination
+ *
+ * @indio_dev - IIO device structure containing the device
+ * @trig - trigger to assign to device
+ *
+ **/
+int iio_trigger_set_immutable(struct iio_dev *indio_dev, struct iio_trigger *trig);
+
/**
* iio_trigger_poll() - called on a trigger occurring
* @trig: trigger which occurred
@@ -145,6 +164,13 @@ irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private);
__printf(1, 2) struct iio_trigger *iio_trigger_alloc(const char *fmt, ...);
void iio_trigger_free(struct iio_trigger *trig);
+/**
+ * iio_trigger_using_own() - tells us if we use our own HW trigger ourselves
+ * @indio_dev: device to check
+ */
+bool iio_trigger_using_own(struct iio_dev *indio_dev);
+
+
#else
struct iio_trigger;
struct iio_trigger_ops;
diff --git a/include/linux/iio/triggered_buffer.h b/include/linux/iio/triggered_buffer.h
index f72f70d5a97b..30145616773d 100644
--- a/include/linux/iio/triggered_buffer.h
+++ b/include/linux/iio/triggered_buffer.h
@@ -12,4 +12,12 @@ int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
const struct iio_buffer_setup_ops *setup_ops);
void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev);
+int devm_iio_triggered_buffer_setup(struct device *dev,
+ struct iio_dev *indio_dev,
+ irqreturn_t (*h)(int irq, void *p),
+ irqreturn_t (*thread)(int irq, void *p),
+ const struct iio_buffer_setup_ops *ops);
+void devm_iio_triggered_buffer_cleanup(struct device *dev,
+ struct iio_dev *indio_dev);
+
#endif
diff --git a/tools/iio/iio_utils.c b/tools/iio/iio_utils.c
index 5eb6793f3972..7a6d61c6c012 100644
--- a/tools/iio/iio_utils.c
+++ b/tools/iio/iio_utils.c
@@ -121,10 +121,6 @@ int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used,
ret = -ENOENT;
while (ent = readdir(dp), ent)
- /*
- * Do we allow devices to override a generic name with
- * a specific one?
- */
if ((strcmp(builtname, ent->d_name) == 0) ||
(strcmp(builtname_generic, ent->d_name) == 0)) {
ret = asprintf(&filename,
@@ -178,6 +174,13 @@ int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used,
sysfsfp = 0;
free(filename);
filename = 0;
+
+ /*
+ * Avoid having a more generic entry overwriting
+ * the settings.
+ */
+ if (strcmp(builtname, ent->d_name) == 0)
+ break;
}
error_close_sysfsfp:
diff --git a/tools/iio/lsiio.c b/tools/iio/lsiio.c
index 3d650e668252..ab0f5cf16025 100644
--- a/tools/iio/lsiio.c
+++ b/tools/iio/lsiio.c
@@ -51,7 +51,8 @@ static int dump_channels(const char *dev_dir_name)
while (ent = readdir(dp), ent)
if (check_prefix(ent->d_name, "in_") &&
- check_postfix(ent->d_name, "_raw"))
+ (check_postfix(ent->d_name, "_raw") ||
+ check_postfix(ent->d_name, "_input")))
printf(" %-10s\n", ent->d_name);
return (closedir(dp) == -1) ? -errno : 0;